• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Использование ESP-12 в связке с DRV8833 и электромоторчиком, и ITR9606

MeMagic

New member
Есть такое задание: управление электромоторчиком используя в том числе и ограничитель.
В качестве элементов используются перечисленные в заголовке, плюс два понижающих резистора для оптопары - 100Ohm последовательно с диодом и 10kOhm развязка от эмиттера на землю, параллельно входу в ESP. Питание: для двигателя и DRV8833 - 12V через преобразователь в 5V, для ESP и оптопары - 3.3V от nodeMCU. Всё это разложено на печеньке небольшой макетки.
IMG_20200516_211840.jpg
Стоит заметить, что электродвигатель мелкий и оснащён редуктором примерно 1:1000, один оборот происходит в течении около 4-5 секунд. Оптопара у меня вскрыта, так как я её готовлю для установки в ограниченное пространство, однако опыты были проведены так же и с оригинальной оптопарой.

Задача: произвести калибровку двигателя путём вращения двигателя в одну сторону до перекрытия оптопары; вращение в другую сторону до перекрытия оптопары с регистрацией времени от старта до останова; ещё одна смена направления и снова вращение до перекрытия оптопары с регистрацией времени от старта до останова; вычисление среднего времени для одного цикла; очередная (на этот раз, демонстрационная) смена направления и вращение в течение 1/4 времени полного цикла. Цель - вращение грубо на четверть оборота.

Код следующий:
Код:
byte FwdPin = 12;
byte BkwPin = 13;
byte OpcPin = 14;
unsigned long TargetTimer = 0;

byte System_NonCalibrated = 0;
byte System_CalibrationStarted = 1;
byte System_InitExtremeFound = 2;
byte System_FindFwdExtreme = 3;
byte System_ForwExtremeFound = 4;
byte System_FindBkwExtreme = 5;
byte System_BckwExtremeFound = 6;
byte System_AvgCcleTimeFound = 7;
byte System_Calibrated = 8;

byte System_State = 0;
byte System_PrevState = -1;
byte OC_State = 0;
byte OC_Prev = -1;
byte Motor_State = 0;
unsigned long System_StartFwdMtn = -1;
unsigned long System_EndFwdMtn = -1;
unsigned long System_StartBkwMtn = -1;
unsigned long System_EndBkwMtn = -1;

byte Motor_StopSignal = LOW;
byte Motor_RunSignal = HIGH;
byte Motor_RunForwd = 2;
byte Motor_RunBackw = 3;

byte OC_Covered = LOW;
byte OC_NonCovered = HIGH;
byte OC_CoverCount = 0;

unsigned long Motor_AvgCcleTime = 0;

bool debug = true;

void setup() {
  // put your setup code here, to run once:
  pinMode(OpcPin, INPUT);
  pinMode(FwdPin, OUTPUT);
  pinMode(BkwPin, OUTPUT);
  Serial.begin(115200);
  Serial.println();
  Serial.println("   Let's ROCK!");
  Serial.println();
  Serial.println();
}

void debug_print(char str1[], unsigned long str2, char str3[]) {
  if (!debug) return;
  if (str1 != "") Serial.print(str1);
  if (str2 != 0) Serial.print(str2);
  if (str3 != "") Serial.print(str3);
  Serial.println();
}

void Motor_Stop()
{
  digitalWrite(FwdPin, Motor_StopSignal);
  digitalWrite(BkwPin, Motor_StopSignal); 
  Motor_State = Motor_StopSignal;
}

void Motor_StartForward()
{
  Motor_Stop();
  digitalWrite(FwdPin, Motor_RunSignal);
  Motor_State = Motor_RunForwd;
}

void Motor_StartBackward()
{
  Motor_Stop();
  digitalWrite(BkwPin, Motor_RunSignal);
  Motor_State = Motor_RunBackw;
}

void System_Calibration()
{
  switch (System_State) {
    case 0:
      debug_print("System not calibrated. Starting initial rotation backward.", 0, "");
      Motor_StartBackward();
      System_State = System_CalibrationStarted;
      System_StartFwdMtn = 0;
      System_StartBkwMtn = 0;
      System_EndFwdMtn = 0;
      System_EndBkwMtn = 0;
      break;
    case 1:
      if (OC_State == OC_Covered) {
        Motor_Stop();
        System_State = System_InitExtremeFound;
        TargetTimer = millis() + 2000;
        debug_print("Initial extreme found. What next?", 0, "");
      }
      break;
    case 2:
      TargetTimer = millis() + 400;
      Motor_StartForward();
      System_StartFwdMtn = millis();
      System_State = System_FindFwdExtreme;
      debug_print("Started measurement rotation forward. Start forward time = ", System_StartFwdMtn, "");
      break;
    case 3:
      if (OC_State == OC_Covered) {
        System_EndFwdMtn = millis();
        Motor_Stop();
        System_State = System_ForwExtremeFound;
        TargetTimer = millis() + 2000;
        debug_print("Measurement rotation forward stopped. End forward time = ", System_EndFwdMtn, "");
      }
      break;
    case 4:
      TargetTimer = millis() + 400;
      Motor_StartBackward();
      System_StartBkwMtn = millis();
      System_State = System_FindBkwExtreme;
      debug_print("Started measurement rotation backward. Start backward time = ", System_StartBkwMtn, "");
      break;
    case 5:
      if (OC_State == OC_Covered) {
        System_EndBkwMtn = millis();
        Motor_Stop();
        System_State = System_BckwExtremeFound;
        debug_print("Measurement rotation backward stopped. End backward time = ", System_EndBkwMtn, "");
      }
      break;
    case 6:
      Motor_AvgCcleTime = (System_EndFwdMtn - System_StartFwdMtn + System_EndBkwMtn - System_StartBkwMtn) / 2;
      TargetTimer = millis() + int(Motor_AvgCcleTime / 4);
      Motor_StartForward();
      System_State = System_AvgCcleTimeFound;
      debug_print("Average circle time calculated - ", Motor_AvgCcleTime, " millisecs.");
      break;
    case 7:
      System_State = System_Calibrated;
      debug_print("System calibrated?", 0, "");
      break;
  }
}

void loop() {
  OC_State = digitalRead(OpcPin);
 
  if (System_State < 0 or System_State > 8) System_State = System_NonCalibrated;
  if (System_State != System_PrevState) {
      debug_print("Current system state - ", System_State, "");
      System_PrevState = System_State;
  }
  if (OC_Prev != OC_State) {
    if (OC_State == OC_Covered) {
      debug_print("Opto interrupter covered. Time: ", millis(), "");
      if (System_State == System_Calibrated) OC_CoverCount++;
      if (OC_CoverCount > 5) {
        OC_CoverCount = 0;
        if (System_State == System_Calibrated) System_State = System_NonCalibrated;
      }
    }
    else {
      debug_print("Opto interrupter not covered. Time: ", millis(), "");
    }
    OC_Prev = OC_State;
  }
  if (TargetTimer < millis()) if (System_State < System_Calibrated) {
    System_Calibration();
  }
  if (System_State == System_Calibrated and Motor_AvgCcleTime <= 0) {
    System_State = System_NonCalibrated;
    debug_print("Average circle time corrupted, going to run calibration. Average circle: ", Motor_AvgCcleTime, ".");
  }

  yield();
}
При полностью отключенном питании на двигатель, после заливки кода получаем следующий аутпут:
Let's ROCK!


Current system state -
Opto interrupter not covered. Time: 61
System not calibrated. Starting initial rotation backward.
Current system state - 1
Opto interrupter covered. Time: 4927
Initial extreme found. What next?
Current system state - 2
Opto interrupter not covered. Time: 4927
Opto interrupter covered. Time: 4928
Started measurement rotation forward. Start forward time = 6928
Current system state - 3
Measurement rotation forward stopped. End forward time = 7329
Current system state - 4
Opto interrupter not covered. Time: 7678
Started measurement rotation backward. Start backward time = 9330
Current system state - 5
Opto interrupter covered. Time: 11689
Measurement rotation backward stopped. End backward time = 11689
Current system state - 6
Average circle time calculated - 1380 millisecs.
Current system state - 7
System calibrated?
Current system state - 8
Opto interrupter not covered. Time: 17653
Opto interrupter covered. Time: 20302
Opto interrupter not covered. Time: 20302
Opto interrupter covered. Time: 20302
Opto interrupter not covered. Time: 22919

После окончания калибровки происходит просто регистрация факта закрытия/открытия оптопары. Однако, если система в состоянии "Откалибровано", после пятого открытия оптопары происходит сброс состояния и снова производится калибровка. Это сделано для проверки многократной системной отработки (короче, - для пущего тестирования).
Можно заметить в окне вывода, что открытие/закрытие оптопары происходит до странности многократно при одном движении флажка (флажок в данном случае кусочек картонки подносимый рукой). Почему это происходит следует понять, потому что это никак не сходится с задачей.

Далее, если подать питание на цепь управления двигателя, происходят чудеса - оптопара сама по себе срабатывает по многу раз в секунду, двигатель крутит то туда, то сюда вообще бессистемно.

Прошу просветить: Что я делаю не так?

ПЫС. Изначально код имел совсем другую структуру и включал переизбыток пауз. После указания со стороны о недопустимости перехвата цепи обработки процессов на долгое время, было решено перевести в формат отработки как можно меньших шагов и их обработки в дискретные значения времени. Таким образом получилось избавиться от постоянных перезагрузок контроллера. С той же целью был включен оператор yield(), но при текущем построении алгоритма, его использование оказалось избыточным.
 

MeMagic

New member
Ну, уважаемые, нет никого-никого, кто разбирается в электротехнике ESP8266. Аж неловко стало, что задаю такие вопросы... :)))
Мне-то всего-то надо, чтобы кто-то подсказал как правильно подключать между собой следующие компоненты:
1589826602241.png 1589826700572.png 1589826777174.png

Исходя из моих нескромных опыта и знаний электроники, я вышел на следующую схему:
1589827398173.png

Вот здесь я застрял. Так как при вместе подключенных оптопаре и драйвера мотора у меня дребезг на входе ESP12 со стороны оптопары, и как следствие код исполняется абсолютно невпопад. На данный момент с оптопары приходят совсем неправильные сигналы. А именно, если я просто отслеживаю оптопару, я получаю открыто/закрыто. Если же я отправляю сигнал на соседние GPIO 12 и/или 13 (управление мотором вперёд/назад), у меня начинается котовасия на входе с оптопары (GPIO14).
Что я делаю не так?
ЗЫ. Не знаю правильно ли я отобразил схему подключения оптопары, но согласно её лэйауту (на втором рисунке) я подключил масу к катоду и к эмиттеру, к эмиттеру через резистор 10к. К эмиттеру же подключил ногу ESP.
 

MeMagic

New member
Подайте питание на мотор от другого источника питания.
Питание на мотор подаётся с источника питания в 12В, пониженного до 5В через Kis-3r33. Питание на ESP и соответственно оптопару подаётся от компьютера через microUSB.
 

CodeNameHawk

Moderator
Команда форума
Далее, если подать питание на цепь управления двигателя, происходят чудеса - оптопара сама по себе срабатывает по многу раз в секунду,
Вы уверены, что она срабатывает по многу раз в секунду, а не вы просто успеваете столько раз ее считать.
Смотреть на код, в котором нет коментариев для чего нужна каждая переменная, что должен делать этот код, нет желания.
 

A_D

Active member
Ну, уважаемые, нет никого-никого, кто разбирается в электротехнике ESP8266. Аж неловко стало, что задаю такие вопросы... :)))
Мне-то всего-то надо, чтобы кто-то подсказал как правильно подключать между собой следующие компоненты:
Посмотреть вложение 9225 Посмотреть вложение 9226 Посмотреть вложение 9227

Исходя из моих нескромных опыта и знаний электроники, я вышел на следующую схему:
Посмотреть вложение 9229

Вот здесь я застрял. Так как при вместе подключенных оптопаре и драйвера мотора у меня дребезг на входе ESP12 со стороны оптопары, и как следствие код исполняется абсолютно невпопад. На данный момент с оптопары приходят совсем неправильные сигналы. А именно, если я просто отслеживаю оптопару, я получаю открыто/закрыто. Если же я отправляю сигнал на соседние GPIO 12 и/или 13 (управление мотором вперёд/назад), у меня начинается котовасия на входе с оптопары (GPIO14).
Что я делаю не так?
ЗЫ. Не знаю правильно ли я отобразил схему подключения оптопары, но согласно её лэйауту (на втором рисунке) я подключил масу к катоду и к эмиттеру, к эмиттеру через резистор 10к. К эмиттеру же подключил ногу ESP.
у оптопары поменяйте местами 3 \ 4 выводы, так она работать не будет.
 

MeMagic

New member
Вы уверены, что она срабатывает по многу раз в секунду, а не вы просто успеваете столько раз ее считать.
Смотреть на код, в котором нет коментариев для чего нужна каждая переменная, что должен делать этот код, нет желания.
Здесь привожу адаптированную выдержку из кода. Адаптированную, чтобы выделить только искомый момент.
Код:
int OpcPin = 14;      //   адрес GPIO для входа с оптопары
int OC_State = 0;     //   переменная для считывания сигнала с оптопары
int OC_Prev = 0;      //   вспомогательная переменная для хранения сигнала с оптопары независимо от цикла
int OC_Covered = HIGH;   //   константа для контроля значения сигнала оптопары  -  удобочитаемый флаг, избыточная переменная

void loop() {
  OC_State = digitalRead(OpcPin);    //  Здесь у нас считывание входа с оптопары

  if (OC_Prev != OC_State) {       //  Здесь у нас контроль изменения состояния. Вывод на печать производится только при переключении, а не в каждом цикле

    if (OC_State == OC_Covered) {       //  Здесь мы просто определяем состояние по значению флага int OC_Covered = HIGH;
      Serial.println("Opto interrupter covered. Time: ", millis(), "");     //   Вывод на печать времени от начала исполнения 
                                                                            //    кода до текущего переключения сигнала оптопары
    }
    else {
      Serial.println("Opto interrupter not covered. Time: ", millis(), "");     //   Вывод на печать времени от начала исполнения 
                                                                                //   кода до текущего переключения сигнала оптопары
    }
    OC_Prev = OC_State;   //   установка значения предыдущей величины, логический результат = переключение отработано
  }
}    //    Здесь у нас заканчивается код и происходит выход из программы.
А здесь у нас вывод.
Код:
Opto interrupter not covered. Time: 141525
Opto interrupter covered. Time: 141525
Opto interrupter not covered. Time: 141525
Opto interrupter covered. Time: 141525
Opto interrupter not covered. Time: 141528
Opto interrupter covered. Time: 141573
Opto interrupter not covered. Time: 141606
Opto interrupter covered. Time: 141628
Opto interrupter not covered. Time: 150657
Из вывода следует, что срабатывание происходит не просто по многу раз в секунду, а по многу раз за тысячную секунды.
 

MeMagic

New member
у оптопары поменяйте местами 3 \ 4 выводы, так она работать не будет.
Я попробую поменять и отпишусь.
Но меня всё же гложет другое. А именно то, что дребезг происходит тогда, когда я шлю сигнал на ноги управления мотором. Как пример:
Код:
   Let's ROCK!


1. Current system state - 
2. Opto interrupter not covered. Time: 61
3. System not calibrated. Starting initial rotation backward.
4. Current system state - 1
5. Opto interrupter covered. Time: 4927
6. Initial extreme found. What next?
7. Current system state - 2
8. Opto interrupter not covered. Time: 4927
9. Opto interrupter covered. Time: 4928
10. Started measurement rotation forward. Start forward time = 6928
11. Current system state - 3
12. Measurement rotation forward stopped. End forward time = 7329
13. Current system state - 4
14. Opto interrupter not covered. Time: 7678
15. Started measurement rotation backward. Start backward time = 9330
16. Current system state - 5
17. Opto interrupter covered. Time: 11689
18. Measurement rotation backward stopped. End backward time = 11689
19. Current system state - 6
20. Average circle time calculated - 1380 millisecs.
21. Current system state - 7
22. System calibrated?
23. Current system state - 8
24. Opto interrupter not covered. Time: 17653
25. Opto interrupter covered. Time: 20302
26. Opto interrupter not covered. Time: 20302
27. Opto interrupter covered. Time: 20302
28. Opto interrupter not covered. Time: 22919
Алгоритм должен быть таким:
1. Шаги 1-2. Система не откалибрована. Запускаем процесс калибровки.
2. Шаги 3-9. Вращаем моторчик назад (вперёд и назад условные направления, просто противоположные друг другу) до закрытия оптопары (таким образом эмулируем срабатывание ограничителя).
3. Шаги 10-11. Выжидаем 2с. и запускаем вращение вперёд. Выжидаем 0,4с и начинаем мониторить оптопару на предмет срабатывания ограничителя. 0,4с - время в течение которого оптопара должна стать открытой, чтобы был смысл отслеживать её закрытие.
4. Шаги 12-13. При закрытии оптопары фиксируется время и останавливается мотор.
5. Шаги 14-16. Выжидаем 2с и запускаем движение назад: 7329 - 9330 мс.
6. Шаги 17-19. Через 0.4с после запуска мотора назад начинается отслеживание флаг закрытия оптопары. На 11689 мс оптопара закрылась. Мотор остановлен.
7. Шаги 20-21. Вычисление срднего времени вращения между срабатываниями оптопары - почти одного оборота.
8. Шаги 22-23. Вращение двигателя вперёд на четверть одного полного вращения - 90 градусов.
9. Шаг 23. Установка системы в значение откалибровано.
Шаги 24-28 - произвольное закрытие/открытие оптопары рукой. Как видно, на шагах 25, 26 и 27 одно и то же значение времени в мс что может быть следствием либо дребезга (шумов) в системе, либо некачественного закрытия транзистора оптопары, что вообще нонсенс.

Если система некоторое время стоит без сигналов на ного управления мотором, вигнал идущий с оптопары в общем случае стабилен.
 

CodeNameHawk

Moderator
Команда форума
Скорее всего у вас наводки на провода.
Попробуйте земли есп, платы управления и оптопары соединить в одной точке.
Все провода минимальной длины.
Резистор возле оптопары, который на землю, замените на 470 ом.
 

CodeNameHawk

Moderator
Команда форума
Код:
int OpcPin = 14;      //   адрес GPIO для входа с оптопары
int OC_State = 0;     //   переменная для считывания сигнала с оптопары
int OC_Prev = 0;      //   вспомогательная переменная для хранения сигнала с оптопары независимо от цикла
int OC_Covered = HIGH;   //   константа для контроля значения сигнала оптопары  -  удобочитаемый флаг, избыточная переменная

void loop()
{
  OC_State = digitalRead(OpcPin);    //  Здесь у нас считывание входа с оптопары

  if (OC_Prev == HIGH)
  {       //  Здесь у нас контроль изменения состояния. Вывод на печать производится только при переключении, а не в каждом цикле
      Serial.println("Opto HIGH: ", millis(), "");     //   Вывод на печать времени от начала исполнения
  }
  else
  {
      Serial.println("Opto  LOW: ", millis(), "");     //   Вывод на печать времени от начала исполнения
   }
}    //    Здесь у нас заканчивается код и происходит выход из программы.
Покажите, что этот код выдает.
 

MeMagic

New member
Скорее всего у вас наводки на провода.
Попробуйте земли есп, платы управления и оптопары соединить в одной точке.
Все провода минимальной длины.
Резистор возле оптопары, который на землю, замените на 470 ом.
Если исходить из следующего, у меня подключение было катод на землю и эмиттер через 10к на землю и на МК.
1589914495751.png
Сейчас мне порекомендовали подключить таким образом:
1589915118183.png или 1589915142285.png

Товарищ, который это порекомендовал, сослался на то, что внутренние транзисторы микроконтроллера надо учитывать и оберегать. Правда, опыта с Ардуино или ESP у него нет. Даже не знаю, что пробовать.
Кстати, сам по себе концепт макеток слегка пижонистый - дюпон провода болтаются как в проруби, а длина почти 20см каждого. Это то, что касается соединить земли в одной точке.
 

MeMagic

New member
Код:
int OpcPin = 14;      //   адрес GPIO для входа с оптопары
int OC_State = 0;     //   переменная для считывания сигнала с оптопары
int OC_Prev = 0;      //   вспомогательная переменная для хранения сигнала с оптопары независимо от цикла
int OC_Covered = HIGH;   //   константа для контроля значения сигнала оптопары  -  удобочитаемый флаг, избыточная переменная

void loop()
{
  OC_State = digitalRead(OpcPin);    //  Здесь у нас считывание входа с оптопары

  if (OC_Prev == HIGH)
  {       //  Здесь у нас контроль изменения состояния. Вывод на печать производится только при переключении, а не в каждом цикле
      Serial.println("Opto HIGH: ", millis(), "");     //   Вывод на печать времени от начала исполнения
  }
  else
  {
      Serial.println("Opto  LOW: ", millis(), "");     //   Вывод на печать времени от начала исполнения
   }
}    //    Здесь у нас заканчивается код и происходит выход из программы.
Покажите, что этот код выдает.
Серьёзно? Результат следующий:
Код:
бесконечное 
"Opto  LOW: nnnnnn"
Ничего другого не может быть, т.к. из кода исполняется только считывание, сравнение HIGH и HIGH и печать одного и того же.
Интересно было бы узнать, какова была цель, но опыт интересный.

Изменил предложенный вами код на что-то более смысловое для меня:
C:
int OpcPin = 14;      //   адрес GPIO для входа с оптопары
int OC_State = 0;     //   переменная для считывания сигнала с оптопары
int OC_Prev = 0;      //   вспомогательная переменная для хранения сигнала с оптопары независимо от цикла
int OC_Covered = HIGH;   //   константа для контроля значения сигнала оптопары  -  удобочитаемый флаг, избыточная переменная

void setup() {
  Serial.begin(74880); 
}

void loop()
{
  OC_State = digitalRead(OpcPin);    //  Здесь у нас считывание входа с оптопары

  if (OC_Prev == OC_State) return;

  if (OC_State == HIGH)
  {       //  Здесь у нас контроль изменения состояния. Вывод на печать производится только при переключении, а не в каждом цикле
      Serial.print("Opto HIGH: ");
      Serial.println(millis());     //   Вывод на печать времени от начала исполнения
  }
  else
  {
      Serial.print("Opto  LOW: ");
      Serial.println(millis());     //   Вывод на печать времени от начала исполнения
   }
   OC_Prev = OC_State;
}    //    Здесь у нас заканчивается код и происходит выход из программы.
Результат совсем другой!
Opto HIGH: 61
Opto LOW: 48802
Opto HIGH: 50763
Opto LOW: 53562
Opto HIGH: 54916
Opto LOW: 56203
Opto HIGH: 57154
Opto LOW: 59147
Opto HIGH: 59148
Opto LOW: 59149
Opto HIGH: 64017
Opto LOW: 65428
Opto HIGH: 66881
Opto LOW: 68306
Opto HIGH: 69869
Opto LOW: 71451
Opto HIGH: 72661
Opto LOW: 73790
Opto HIGH: 74503
Opto LOW: 75578
Opto HIGH: 75853
Opto LOW: 85949
Opto HIGH: 85949
Opto LOW: 85950
Opto HIGH: 85950
Opto LOW: 85950
Opto HIGH: 85950
Opto LOW: 85950
Opto HIGH: 85951
Opto LOW: 85953
Opto HIGH: 85955
Opto LOW: 85958
Opto HIGH: 86052
Opto LOW: 86052
............
Opto LOW: 581609
Opto HIGH: 582937
Opto LOW: 583969
Opto HIGH: 584865
Opto LOW: 585732
Opto HIGH: 586704
Opto LOW: 587614
Opto HIGH: 588670
Opto LOW: 589487
Opto HIGH: 590525
Opto LOW: 591332
Opto HIGH: 592380
Opto LOW: 593130
Opto HIGH: 594128
Opto LOW: 594953
Opto HIGH: 595872
....................

Поначалу, оптопара срабатывала (почти, за одним исключением) чётко на каждом шагу. Вплоть до 86-й секунды.... Что там произошло?
Далее попробовал снова. Как видно, дребезга почти нет. Правда, я так же старался чётко открывать/закрывать оптопару. Когда это случилось слегка небрежно, появилось ложное срабатывание.
Полагаю, мне надо пересмотреть значение сопротивления на диоде - думаю, надо уменьшить ток. Нет? Или схема с делителем на коллекторе будет лучше?
 

MeMagic

New member
Предыдущий код с делителем до 2,8В результат (напряжение 0.002 - 2.76В):
Opto LOW: 156021
Opto HIGH: 156021
Opto LOW: 156021
Opto HIGH: 162530
Opto LOW: 178265
Opto HIGH: 178265
Opto LOW: 178266
Opto HIGH: 183626
Opto LOW: 186943
Opto HIGH: 186943
Opto LOW: 186943
Opto HIGH: 189781

Теперь с сопротивлением 430Ом вместо отсутствующего 470Ом (напряжение 0.001 - 2.33В):
Opto LOW: 62076
Opto HIGH: 62076
Opto LOW: 62076
Opto HIGH: 62076
Opto LOW: 62076
Opto HIGH: 63852
Opto LOW: 66170
Opto HIGH: 67233
Opto LOW: 67233
Opto HIGH: 67233
Opto LOW: 68464
Opto HIGH: 69765
Opto LOW: 69765
Opto HIGH: 69765
Opto LOW: 69765
Opto HIGH: 69765
Opto LOW: 72181
Opto HIGH: 72181
Opto LOW: 72181
Opto HIGH: 73357
Opto LOW: 74655
Opto HIGH: 75846
Opto LOW: 77102
Opto HIGH: 77102
Opto LOW: 77102
Opto HIGH: 78242
Opto LOW: 79522
Opto HIGH: 79523
Opto LOW: 79523
Opto HIGH: 80750
Opto LOW: 80750
Opto HIGH: 80750
Opto LOW: 80750
Opto HIGH: 80750
Кажется, ложных срабатываний одинаково. Однако, вариант, когда я пытался воспроизвести горизонтальное движение флажка, вроде как чище отрабатывает.
В общем так, я построю прототип с электромотором с флажком, закреплённом жестко, с пропаянными проводниками и т.д. Тогда уже буду тестировать на живую.
Всё же, может есть вариант изолировать выходные ноги в сторону модуля DRV8833, чтоб не было случайных внутренних шумов?
 

A_D

Active member
Я не особо шарю в ESP, но, думаю, надо копать в сторону прерываний и измерении периода с помощью них - https://circuits4you.com/2017/12/08/esp8266-external-interrupt-example/ , по идее идеально с таймером и в целом, посмотрели бы осциллографом сигналы, убедились сначала в их периодичности и не зашумлёности, а потом отлаживались с кодом уже, если есть сомнения в "ложных срабатываниях".
 

CodeNameHawk

Moderator
Команда форума
В коде должно было быть
Код:
  OC_State = digitalRead(OpcPin);    //  Здесь у нас считывание входа с оптопары

  if (OC_State == HIGH)
 

CodeNameHawk

Moderator
Команда форума
Правда, я так же старался чётко открывать/закрывать оптопару. Когда это случилось слегка небрежно, появилось ложное срабатывание.
Важно, что бы не было ложных срабатываний от наводок.
Вам важно поймать первое срабатывание датчика и остановить двигатель, а потом, если программа составлена грамотно, дребезг не должен мешать. От обычной кнопки куча срабатываний и никому особо не мешает.

Или схема с делителем на коллекторе будет лучше?
Можете оставить схему с делителем, а можете верхний выкинуть и сделать так
1589915142285.png
Это обережет есп, если вход есп окажется выходом с низким уровнем, а транзистор будет открыт.
 

MeMagic

New member
В коде должно было быть
Код:
  OC_State = digitalRead(OpcPin);    //  Здесь у нас считывание входа с оптопары

  if (OC_State == HIGH)
Вечером попробую, выпишу результаты. Кстати, а за чем наблюдать при воспроизведении кода? В идеале получится тот же результат, что и в случае с моим кодом. Разве, что не будет фильтра состяния, и "каждый Божий" цикл будет отработан, а это огромное кол-во записей вывода за парочку секунд. Если это и есть то, что мы хотим выследить - не вопрос. Результат чего выписать сюда?
Надо посмотреть в описании какой надо пускать ток через светодиод и рассчитать резистор.
В описании оптопары смотрел, падение напряжения на диоде - 1,2В при токе 20мА. Соответственно и был выбран резистор 100Ом при условии питания 3,3В.
При необходимости, описание можно посмотреть в этом документе.
Важно, что бы не было ложных срабатываний от наводок.
Вам важно поймать первое срабатывание датчика и остановить двигатель, а потом, если программа составлена грамотно, дребезг не должен мешать. От обычной кнопки куча срабатываний и никому особо не мешает.
То есть, в принципе доступно такое поведение и следует всё это ловить и исключать на уровне кода? Програмные паузы я уже исключил, наверное и с этим смогу справиться. Но самый важный момент - ложные срабатывания, то есть дребезг, при подаче сигнала на управление мотором. Конкретно – из-за дребезга я буду ловить первое срабатывание в середине оборота, а не там где оно должно быть, и моя схема окажется неработоспособной.
Можете оставить схему с делителем, а можете верхний выкинуть и сделать так
Посмотреть вложение 9233
Это обережет есп, если вход есп окажется выходом с низким уровнем, а транзистор будет открыт.
Приблизительно это и было задумано. Из-за усталости была допущена ошибка - резистор в последовательности с транзистором должен был быть 100Ом, а суммарно с транзистором - 200Ом. И почему "вход есп окажется выходом с низким уровнем", разве он может быть либо с высоким, либо с низким? Для меня, образно, либо нужное сопротивление есть, либо оно вовсе сгорело.

CodeNameHawk, вам спасибо за участие. Мне очень важно завершить этот проект успешно. Поэтому я благодарен за любую помощь. Лишь бы двигаться вперёд, а не танцевать вокруг макетки.
 

MeMagic

New member
Я не особо шарю в ESP, но, думаю, надо копать в сторону прерываний и измерении периода с помощью них - https://circuits4you.com/2017/12/08/esp8266-external-interrupt-example/ , по идее идеально с таймером и в целом, посмотрели бы осциллографом сигналы, убедились сначала в их периодичности и не зашумлёности, а потом отлаживались с кодом уже, если есть сомнения в "ложных срабатываниях".
Я думал, что работа с данным типом микроконтроллеров будет гораздо проще для той части публики, которая не владеет углублёнными знаниями в электронике и схемотехнике.
Может, если использовать оригинальный Ардуино будет проще? Но ESP в любом случае нужно для включения удалённого управления.
 
Сверху Снизу