Имеется: Плата ESP32 + обвес (оптопары PC817, питание, RF-модули и т.п.) Трехфазный асинхронный двигатель, с установленной на шкиве пластиной и вырезами Два индуктивных датчика PR12-4DN2, установленных со смещением относительно друг-друга Двигатель управляется частотником, команды на частотник идут с платы ESP32. Датчиками определяется дистанция, направление вращения и скорость. Фрагмент схемы: Фрагменты программы: Код (C++): #define PIN_SENSOR1 GPIO_NUM_34 // Вход датчика двигателя 1 #define PIN_SENSOR2 GPIO_NUM_35 // Вход датчика двигателя 2 unsigned long sens1, sens2; // Для отладки (счетчик кол-ва срабатывания прерываний от датчика) uint8_t debounce = 10; // Дребезг датчиков, для примера. В основной программе достается с EEPROM/Wi-Fi void setup(void) { attachInterrupt(PIN_SENSOR1, sens1_signal, FALLING); attachInterrupt(PIN_SENSOR2, sens2_signal, FALLING); } void loop(void){ #ifdef DEBUG_ENABLE if (millis() - timing > 1000) { Serial.print("s1: "); Serial.print(String(sens1)); Serial.print(", s2: "); Serial.print(String(sens2)); } } } void sens1_signal() { if (millis() - ms_debounce1 >= debounce && gpio_get_level(PIN_SENSOR2)) { sens1++; cnt_motor++; // Дистанция + cur_rot = ROT_FORW; // Направление вращения - вперед } ms_debounce1 = millis(); } void sens2_signal() { if (millis() - ms_debounce2 >= debounce && gpio_get_level(PIN_SENSOR1)) { sens2++; cnt_motor--; // Дистанция - cur_rot = ROT_BACK; // Направление вращения - назад } ms_debounce2 = millis(); } Проблема в том, что при вращении в одну сторону (например - вперед когда у нас увеличиваются sens1 и cnt_motor) происходит иногда срабатывание второго условия: т.е. увеличивается sens2 и соотв-но уменьшается cnt_motor. Примерно 5-10%. Т.е. если кол-во sens1 будет 500, то кол-вл sens2 будет 30-50. А должно быть 0. Думал дело в наводках или датчиках. Снял всю систему. На Arduino собрал и запрограммировал генератор с частотой 20 Гц и примерно таким же сдвигом как с реальных датчиков. Через резистивный делитель подключил в ESP32. Осциллограмма с Arduino выглядит так: И все равно то же самое. В программе видно, что счетчик увеличивается только когда условия gpio_get_level(PIN_SENSOR1) истинно. Фильтр дребезга там в принципе не работает, можно его убрать, результат такой же. Есть какие-то мысли куда копать?
ESP32 из каропки работает на FreeRTOS. Скорость реакции на прерывание у неё совсем не такая, как у нативного программирования.
Если устройство собрано на ESP32, то с большой долей вероятности у вас задействован wi-fi. Запретите его полностью и посмотрите что изменится. По коду вот какая мысль. Вы считаете состояния двух входов. Сделать это можно несколько по-иному. Регистрируете прерывания на этих входах. Как только прерывание срабатывает - запрещаете его на время дребезга и затем вновь разрешаете. Тогда это все должно работать более эффективно, ИМХО. Подумайте в эту сторону.
Забыл написать, что максимальная частота опроса - до 25 Гц. Т.е. рабочая частота меняется примерно в диапазоне 5-25 Гц. Не сильно большая. Wi-Fi и все прочее отключал на период выявления глюков, т.е. код минимальный с прерыванием и выводом как выше - эффекта не дало. По поводу запрета прерываний, вчера вечером тоже подумал в эту сторону. В коде прерываний прописал при сработке noInterrupts(), при выходе interrupts(). Но камень после этого постоянно перезагружался. Копать дальше не стал, видимо на ESP32 надо в IDF все же с прерываниями работать. А я в VSCode, но Arduino IDE. Из-за того, что какой то нужной мне либы (уже не помню) в IDF нет. Пока все же копаю в сторону дребезга. Все же беру слова обратно, дребезг влияет. Правда при разной частоте надо разные параметры дребезга, вот думаю теперь как правильно определить частоту, чтобы гибко настраивать дребезг.
индуктивный датчик даёт дребезг? Раз есть дребезг, то опрашивать входы следует по таймеру. Например, с частотой 200-400 Гц.
На осциллограмме я дребезга честно говоря не видел. На днях поеду с осциллографом, попробую более развернуть посмотреть на фронты сигналов. Мне скорость замерить не главное. Главное дистанция. Т.к. каждый "левый" импульс дает сдвиг, из-за чего перемещаемый объект может вьехать куда не надо А по таймеру мне тогда не очень понятно как считать импульсы. Здесь я по фронту или спаду считаю. За один оборот у меня 2 импульса должно быть. Далее вычисляется дистанция после которой включается реверс двигателя и т.д. по кругу. На всю дистанцию примерно 440 импульсов в одну сторону.
Два импульса по одному с каждого датчика или с одного? Тогда попробуйте считать данные только с одного датчика. Если это сработает - сделайте метки для каждого датчика свои - то есть на разном расстоянии от оси. Читайте в каждую сторону только один датчик. Надо же методом инженерного тыка понять в чем дело
В общем на шкиве стоит металлическая пластина с вырезами. Выглядит примерно так: За 1 оборот шкива, если считать по фронту или спаду импульса, у меня приходит по 2 сигнала с каждого датчика.
Проверьте как будет работать по одному. Разнесите датчики. Не исключено, что здесь возникают небольшие индукционные токи, и, как следствие, магнитные поля. У вас есть осциллограф - понаблюдайте за сигналами от датчиков, авось что обнаружите.
прощения прошу, но вы не предоставили часть схемы связи датчиков именно с вашей схемой.Что касается программы, то надо, фиксировать первый (из двух) импульсов и ожидать прихода второго (из двух) при движении. Ещё удаление пластины от датчиков(у Вас PR12-4DN2 - значит 4мм но это крайняя дистанция, значит вам надо миллиметра 2-3 и без вибрации - точность механики). Любая вибрация при ненадёжно работе датчиков проблема. Близко ставить можно разбить датчики, далеко ставить будет геморрой что у Вас. А программу всё же пересмотрите. PS: начальник взял датчик расхода воды энкодерный с 0.1имп/литр и потом потребовал повысить расход (оптимизация) и контроллер Дельта измерял непонятно что. стоило уменьшить расход всё стало корректным. Потом взяли 1имп/литр всё стало нормально. Емкость всё равно литров 100-200 и если по 0.1 имп/литр какое количество импульсов надо получить при наполнении? И что 200литров с точностью 0.1литр при изготовлении бетона обязательно? PS: и ещё: индуктивные датчики построены на основе блокинг-генератора, а это значит что при поднесении к нему металла генерация срывается, а при удалении восстанавливается - меняется ток потребления это для датчиков с двухпроводной схемой (контроль потребления). Для распространённой трёхпроводной схемы использование проще - там есть ключ. Но всё равно скорость срыва и восстановления генерации относительно небольшая. Для таких как у Вас применений обычно применяют щелевые датчики и они как правило оптические. Вы тут говорили про 25 Гц, для датчиков такого типа это тяжко. У нас применяются ручной станок порезки кабеля, то там 5 отверстий на диске и этот диск имеет некий радиус(мерное колесо), так все равно там не так часто идут импульсы и всё равно поменяли на энкодер(при модернизации), а для определения длины применили счётчик от ОВЕН. И если контролер сам будет считать, то он ничего больше делать не должен.
классический энкодер. В сети есть как минимум 2 или даже 3 примера алгоритма, как обрабатывать такие сигналы.
Пластина от датчиков на расстоянии примерно 1-2 мм. По поводу оптических датчиков думал. Но вся установка находится под открытым воздухом. Т.е. солнце может попадать на датчики. Не будет ли проблем? Дома тестировал на небольшом DC-моторчике с датчиками Холла, и таких проблем не наблюдалось. Возможно подумаю чтобы и туда как-то магниты закрепить.
Если у Вас не самоделки, а промышленные изделия проблем не будет. В моём случае утром в цехе солнце светит почти напрямую в датчик (работает на отражение от специальной маски) проблем нет - этот датчик излучает и принимает - по ходу ловит только свою модуляцию. Не мучайтесь и возьмите энкодер и забейте на всё. Что касается контроллера, то как говорил, так и есть - даже буржуи из SIEMENS делают устройство ввода с функцией работы с энкодерами, а уж логический контроллер работает с алгоритмом. Я это к тому что в вашем случае один контроллер должен принимать данные с датчиков(и больше ничего не делать), а другой работать с данными от первого. Иначе можно только с медленными параметрами.
Это к ESP32 фраза? Сколько там частота у автора? 160 или 240 МГц? Такими мощностями разбрасываться совсем не рационально.
Если постараться, то конечно можно сделать можно всё - оптимизировать до идеала и т.п. Но видно, что до этого далековато. Кроме того, даже если использовать прерывания, то разве не будут другие прерывания, да хоть от таймера. И если прерывания будут только выставлять флаги а, обрабатывать их основной процесс, то это не станет очередной проблемой или вопросом? Я конечно не знаток в ESP32, но если он умеет как Cortex/ARM, который позволяет не только назначать приоритеты прерываний, но ещё и переход из низко приоритетного прерывания в более высоко приоритетное, а потом возвращаться обратно в низко приоритетное и так далее, то это совсем меняет картину. Думаю проще сделать один простой контроллер который занимается сбором и систематизацией данных, а другой просто пользуется этими данными. Простите, но могут появиться потом еще вопросы по связи между МК. PS: Вспомнилась фраза : "Я на ардуино собрал MP3 плейер...", а на самом деле надо говорить "Я к MP3 плейеру прикрутил ардуину...". Ведь кто такой тот же MP3 плайер, а кто ардуино? Первый - сложная система с множеством функций, а второй просто микроконтроллер с обвязкой в тысячи раз проще первого.
станет. Поэтому не надо лезть в прерывания, а обрабатывать всё в цикле. Это же поможет с дребезгом. Хотя в индуктивных датчиках дребезг не по электрической части, а из-за механической вибрации. Т.е. вопросы к креплению датчиков. Espressif не предоставляет инструмент для нативного программирования. Только FreeRTOS.
Именно Вас спрашивают. Именно Вы даёте советы. Именно Вы критикуете чужие ответы. Но именно Вы и не предоставляете хоть какой-нибудь пример ответа. PS: Извините, если что не так.