Как завести сигнал в Arduino от зубцового датчика двигателя

Здравствуйте, уважаемые, форумчане
Есть двигатель, который был создан по специальному заказу (поэтому название не могу привести)
Управляю двигателем при помощи ШИМ-сигнала, который приходит с драйвера двигателя BTS7960. В сам двигатель встроен зубцовый датчик, который имеет 4 выхода (с 2 запитывается, остальные выход), подключать пробую при помощи оптопары 6N137 (перед подключением стоит резистор на 2,6 кОм, который помогает понизить значение сигнала (-15В-+15В), на оптопару приходит 1,3-1,7 В, на выходе получаю 0,2-0,3 В (такое ощущение, что сигнал постоянен), далее подключаю ко 2 пину Arduino Uno, и на выходе ничего не вижу.
Вопросы в следующем:

  1. Как лучше снять сигнал (вообще нужно завести в ESP32 WeMos LOLIN32 Lite)
    2.Как правильно снять сигнал
    С помощью сигнала должен происходить подсчет оборотов двигателя.
    Новичок в среде Arduino IDE, поэтому сильно не ругайте.

Дополнение:
Подаёте напряжение, при вращении ротора на выводном проводе появляется меандр. Питается от биполярного источника (+15…-15 В). Были куплены два источника по 15 В и они соединены последовательно.

Текущая задача - завести этот меандр в ESP32. Разумеется, что просто подключить его к ножке нельзя (он имеет размах в те самые +15…-15 В). Были куплены оптопары (6N137M и HCPL-3120-000E).
Нужно использовать только счётчик импульсов (PCNT).

На осциллограмму полюбоваться можно?

Google Photos

Код:

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

const int sensorPin = 2; // Пин, к которому подключен датчик оборотов
volatile unsigned long lastflash, flash;
volatile unsigned int revolutions = 0;
unsigned long lastTime = 0;
unsigned int rpm = 0;
float radius = 0.00125; // Предположим, оценочный радиус тела (в метрах)
bool signalReceived = false; // Переменная для отслеживания прихода сигнала

LiquidCrystal_I2C lcd(0x27, 20, 4); // Инициализация ЖК-дисплея 2004 (адрес 0x27, 20 символов в строке, 4 строки)

void setup() {
  Serial.begin(9600); // открыть порт
  pinMode(3, OUTPUT); // 3 пин как выход
  digitalWrite(3, HIGH); // подать 5 вольт на 3 пин

  attachInterrupt(digitalPinToInterrupt(sensorPin), sens, RISING); // подключить прерывание к пину датчика при повышении сигнала

  lcd.init(); // инициализация дисплея
  lcd.backlight(); // включить подсветку
  Serial.flush();
  Serial.println("RPM"); // Заголовок для графика RPM
  Serial.println("Speed"); // Заголовок для графика скорости
}

void sens() {
  revolutions++; // увеличить счетчик оборотов на 1
  signalReceived = true; // Устанавливаем флаг прихода сигнала
}

void loop() {
  unsigned long currentTime = millis();
  if (currentTime - lastflash > 1000) { // если прошла секунда с последнего срабатывания
    lastflash = currentTime; // обновляем временную метку последнего срабатывания
    unsigned long elapsedTime = currentTime - lastTime;
    if (elapsedTime != 0) {
      rpm = (revolutions * 60000) / elapsedTime; // Вычисляем обороты в минуту
      float circumference = 2 * PI * radius; // Вычисляем длину окружности
      float speed = rpm * circumference / 60; // Вычисляем скорость в м/с
      lastTime = currentTime; // обновляем временную метку последнего измерения
      revolutions = 0;

      // Выводим информацию о приходе сигнала
      lcd.clear(); // Очищаем экран перед выводом новой информации
      lcd.setCursor(0, 0); // курсор в начало первой строки
      lcd.print("Signal: ");
      lcd.print(signalReceived ? "Received" : "Not received"); // Выводим сообщение о приходе сигнала
      signalReceived = false; // Сбрасываем флаг прихода сигнала

      // Отправляем названия графиков
      Serial.println("RPM:");
      Serial.println("Speed:");

      // Выводим значения RPM и скорости для построения графиков
      Serial.println(rpm); // Отправляем значение RPM на новой строке
      Serial.println(speed); // Отправляем значение скорости на новой строке

      // Выводим значения на дисплей
      lcd.setCursor(0, 1); // курсор в начало второй строки
      lcd.print("RPM: ");
      lcd.print(rpm); // выводим обороты в минуту на второй строке
      lcd.setCursor(0, 2); // курсор в начало третьей строки
      lcd.print("Speed: ");
      lcd.print(speed, 2); // выводим скорость в м/с на третьей строке с двумя знаками после запятой
      lcd.print(" m/s");
      lcd.setCursor(0, 3); // курсор в начало четвертой строки
      lcd.print("Radius: "); 
      lcd.print(radius, 4); // выводим радиус на четвертой строке с четырьмя знаками после запятой
      lcd.print(" m"); // добавляем единицы измерения
    }
  }
}

резистор и стабилитрон кс133 спасут отца русской демократии )))

Не нужен, защита уже есть в пине.

Подключить через резистор к пину и все?

Нет, не всё. С пониманием подключить. После составления схемы, просчета величин, и осознания почему так.

вот, а ставишь стабилитрон, через резистор 5.6к мощностью 0.25 и ничего считать не надо, это я так навскидку сказал
ну или открывать даташит и смотреть что там по пину, какие токи втекающие допустимы и т.д.

Если тебе дают на форуме совет, и говорят что не надо считать, то считать надо два раза.

Есть сотни ситуаций, когда “можно посчитать, а можно 1к поставить” :slight_smile:

тока вот когда по входу ± 15 В явно не из тех сотен.

а резистор или что-то более сложное ставить опять от той же дальности и внешних условий зависит

Прибить диодом -15 В, останется чистые 0 - 15. А потом или через делитель напрямую на пин, или через оптопару.

не факт, что они с питанием связаны

Есть еще пара вариантов (навскидку). Но для уверовавших в катушку - трансформатор.

1 лайк

ждём что скажет TC, связан выход с питанием али нет

Зачем? Для того, чтобы опять?!
Давай обсудим предложенные (в т. ч. и тобой) варианты.

а что обсуждать, на отрицательном импульсе диод в прямом включении, там будет от 0.5 до 1 вольта

Зачем прописные истины? чтобы что?

Неужели нужен более толстый намек?