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

ESP32 IRQ - самопроизвольное срабатывание обработчика

max_mazur

New member
Доброго дня!

Я новичек в работе с контроллерами, и потому если вдруг написал глупости - ткните носом в документацию.

Проблема

- хочу детектировать сработку инфракрасного сенсора который в отсутвие отраженного сигнала выдает логичискую "1" (3.3V) а при наличии - "0"

- Плата прошита под micropython

- Код обработчика (тестовый)
Python:
def ir_sensor_irq_handler(pin):

    IRQ_COUNTER = IRQ_COUNTER +1.
    print("IRQ CALL number {IRQ_COUNTER}".format(IRQ_COUNTER=IRQ_COUNTER))
    # Detect if it was rise or fall
    status = "uncknown"
    pin_id = T._get_pin_id(pin)
    print(pin.value())
    if pin.value() == 0:
        print("changed from 1 to 0 on pin {pin_id}".format(pin_id=pin_id))
        status = "falling"
    else:
        print("changed from 0 to 1 on pin {pin_id}".format(pin_id=pin_id))
        status = "rising"
    print(status)

pin_irq = machine.Pin(SENSOR_DIGIT_PINS["left"], machine.Pin.IN, machine.Pin.PULL_UP)

pin_irq.irq(trigger=(machine.Pin.IRQ_RISING|machine.Pin.IRQ_FALLING), handler=ir_sensor_irq_handler)

К 25 пину подключен цифровой вывод сенсора

я наблюдаю в логах периодическое срабатывание прерывания

Python:
changed from 0 to 1 on pin 25
rising
IRQ CALL number 74
- всегда именно такое и не могу пока понять как это происходит

при эт ом на осцилографе я не вижу никаких импульсов, светодиод на самом датчике не моргает

возможно какой-то дребезг (но откуда когда есть PULL_UP? )
Буду благодарен за любой совет
 

CodeNameHawk

Moderator
Команда форума
возможно какой-то дребезг (но откуда когда есть PULL_UP? )
Буду благодарен за любой совет
Не ясно что за датчик и по какой схеме подключен.
Если схема с открытым коллектором внутреннего PULL_UP не хватит.
Разобраться, что к чему просто, вместо датчика поставьте резистор, посмотрите как себя ведет схема ( сперва не землю, потом на +3,3В).
Возможно сам датчик принимает что то с "эфира", положите датчик в непрозрачную металлическую(для экранирования эл. наводок) коробку .
 

=AK=

New member
Доброго дня!

- хочу детектировать сработку инфракрасного сенсора который в отсутвие отраженного сигнала выдает логичискую "1" (3.3V) а при наличии - "0"

pin_irq = machine.Pin(SENSOR_DIGIT_PINS["left"], machine.Pin.IN, machine.Pin.PULL_UP)

pin_irq.irq(trigger=(machine.Pin.IRQ_RISING|machine.Pin.IRQ_FALLING), handler=ir_sensor_irq_handler)[/code]

К 25 пину подключен цифровой вывод сенсора

я наблюдаю в логах периодическое срабатывание прерывания

при этом на осцилографе я не вижу никаких импульсов, светодиод на самом датчике не моргает

Вход прерывания - быстродействующий, прерывание может сработать от импульса длительностью в несколько наносекунд. А ваш осциллограф может увидеть импульс длительностью в несколько наносекунд, пробегающий, скажем, раз в час? Боюсь что нет.

И зачем вам, спрашивается, такое быстродействие? Зачем прерывание? У вас что, быстродействующий инфракрасный сенсор, который выдает короткие импулсы, настолько короткие, что их нельзя простым опросом пина поймать?

Забейте на прерывание, вы неправильно решаете задачу, неверными средствами. От этого и проблемы. Почти наверняка у вас сенсор с ESP соединен достаточно длинным проводом, на который наводятся помехи. Может, он у вас вообще рядом с какими-нибудь сетевыми проводами лежит, тогда на него из сети что угодно может навестись.

Любой внешний сигнал надо заводить на вход ESP через резистор, расположенный рядом с ESP, хотя бы 100 Ом, чтобы защититься от наведенных помех. Сигнал надо обрабатывать как можно медленннее, настолько медленно, насколько позволяет задача. В вашем случае - лучше всего многократным опросом и тем или иным усреднением сигнала на пине, чтобы никакая одиночная помеха не приводила к ложному срабатыванию.
 

max_mazur

New member
Доброго дня!

Огромное спасибо за ответы!

Не ясно что за датчик и по какой схеме подключен.
Если схема с открытым коллектором внутреннего PULL_UP не хватит.
Разобраться, что к чему просто, вместо датчика поставьте резистор, посмотрите как себя ведет схема ( сперва не землю, потом на +3,3В).
Возможно сам датчик принимает что то с "эфира", положите датчик в непрозрачную металлическую(для экранирования эл. наводок) коробку .

1 - я новичек и не совсем понимаю что такое "схема с открытым коллектором"
2 - Я провел следующие "исследования"
- добавил резистор в 10К между выходом датчика и 3В - случайных срабатываний стало в разы меньше но до конца они не пропали
- добавил 100 Ом резистор возле ноги ESP настолько близко насколько позволяет макетная плата, визуально это не дало никакого эффекта (по совету выше)

Номиналы резисторов выбраны "от балды" (по советам гугла) и если есть методика их рассчета то поделитесь плз

Вход прерывания - быстродействующий, прерывание может сработать от импульса длительностью в несколько наносекунд. А ваш осциллограф может увидеть импульс длительностью в несколько наносекунд, пробегающий, скажем, раз в час? Боюсь что нет.
Абсолютно верно - осциллограф у меня самый простой и дешевый, для обучения и я уверен что наносекундные импульсы он не видет
Спасибо, самому это в голову сразу не пришло

И зачем вам, спрашивается, такое быстродействие? Зачем прерывание? У вас что, быстродействующий инфракрасный сенсор, который выдает короткие импулсы, настолько короткие, что их нельзя простым опросом пина поймать?
Опрос пина это ресурсы процессора, и усложнение логики программы а я хочу (как новичек, возможно не понимаю что то) делать код максимально простым

Думал что прерывания это "бесплатный" способ сделать опрос


Забейте на прерывание, вы неправильно решаете задачу, неверными средствами. От этого и проблемы. Почти наверняка у вас сенсор с ESP соединен достаточно длинным проводом, на который наводятся помехи. Может, он у вас вообще рядом с какими-нибудь сетевыми проводами лежит, тогда на него из сети что угодно может навестись.
Все именно так как Вы пишете - устройство это контроллер стрелки для макета железной дороги и на рельсах там меандр 16В который питает локомотив

Задача датчика многогранна
- определить занятость линии и отрепортить это на главную станцию
- включить светодиод имитируюший красный сигнал светофора
- запустить поток чтения RFID что б если на локомотиве есть метка то прочитать ее
- блокировать исполнение команд на переключение стрелки (что б не сработало переключение когда состав проходит стрелку)

Отсюда и желание использовать прерывания так как все эти действия должны быть строго асинхронны что бы например медленное чтение RFID не заблокировало включение светодиода


Любой внешний сигнал надо заводить на вход ESP через резистор, расположенный рядом с ESP, хотя бы 100 Ом, чтобы защититься от наведенных помех. Сигнал надо обрабатывать как можно медленннее, настолько медленно, насколько позволяет задача. В вашем случае - лучше всего многократным опросом и тем или иным усреднением сигнала на пине, чтобы никакая одиночная помеха не приводила к ложному срабатыванию.
К сожалению такой простой способ не помог

Думаете мне действительно стоит "забить" на прерывания? или есть какие-то доступные способы отфильтровать импульсы длительностью короче N ms ?
 

max_mazur

New member
В голову приходит мысль что можно попробовать включить емкость (LC фильтр) ?
или это глупость для цифровой схемы?


Код:
---Pin25 ---R1---*---R2---Sensor
                 |
                ---
             C1 ___
                 |
                 |
            GRD ___
Идея в том что C1 не даст быстро измениться напряжению на пластинах, но я даже примерно не представляю методику расчета номиналов, то что учил в универе забыл начисто

Возможно что и сама идея полная глупость
 

nikolz

Well-known member
Доброго дня!

Я новичек в работе с контроллерами, и потому если вдруг написал глупости - ткните носом в документацию.

Проблема

- хочу детектировать сработку инфракрасного сенсора который в отсутвие отраженного сигнала выдает логичискую "1" (3.3V) а при наличии - "0"

- Плата прошита под micropython

- Код обработчика (тестовый)
Python:
def ir_sensor_irq_handler(pin):

    IRQ_COUNTER = IRQ_COUNTER +1.
    print("IRQ CALL number {IRQ_COUNTER}".format(IRQ_COUNTER=IRQ_COUNTER))
    # Detect if it was rise or fall
    status = "uncknown"
    pin_id = T._get_pin_id(pin)
    print(pin.value())
    if pin.value() == 0:
        print("changed from 1 to 0 on pin {pin_id}".format(pin_id=pin_id))
        status = "falling"
    else:
        print("changed from 0 to 1 on pin {pin_id}".format(pin_id=pin_id))
        status = "rising"
    print(status)

pin_irq = machine.Pin(SENSOR_DIGIT_PINS["left"], machine.Pin.IN, machine.Pin.PULL_UP)

pin_irq.irq(trigger=(machine.Pin.IRQ_RISING|machine.Pin.IRQ_FALLING), handler=ir_sensor_irq_handler)

К 25 пину подключен цифровой вывод сенсора

я наблюдаю в логах периодическое срабатывание прерывания

Python:
changed from 0 to 1 on pin 25
rising
IRQ CALL number 74
- всегда именно такое и не могу пока понять как это происходит

при эт ом на осцилографе я не вижу никаких импульсов, светодиод на самом датчике не моргает

возможно какой-то дребезг (но откуда когда есть PULL_UP? )
Буду благодарен за любой совет
у вас не правильно написана логика обработки
поэтому и ерунда получается
никаких помех нет ищите ошибке в логике вашей программы
----------------
напишите на СИ я проверю и исправлю
 

max_mazur

New member
у вас не правильно написана логика обработки
поэтому и ерунда получается
никаких помех нет ищите ошибке в логике вашей программы
----------------
напишите на СИ я проверю и исправлю
Спасибо за ответ, но мне кажется (ещё раз, я новичек и мне надо пояснять очевидное) не так важно что написано в обработчике прерывания, важен сам факт его возникновения


На С я пишу сильно хуже чем на питоне, по тому и взял этот контроллер (
 

nikolz

Well-known member
Спасибо за ответ, но мне кажется (ещё раз, я новичек и мне надо пояснять очевидное) не так важно что написано в обработчике прерывания, важен сам факт его возникновения


На С я пишу сильно хуже чем на питоне, по тому и взял этот контроллер (
пишите на си, если хотите помощи. Заодно и СИ освоите Вы же новичок
учится надо тому что более эффективно работает на системах с ограниченными ресурсами
а для ESP это СИ или в крайнем случае луа.
питон не для ESP
на си будет компактно и быстро работать
и ошибок ву библиотеках нет берите док по SDK и вперед
 

nikolz

Well-known member
У вас скорее всего классическая ошибка
прога просто долбит одно и тоже условие и печатает вам про него
но вы думаете иначе
 

max_mazur

New member
пишите на си, если хотите помощи. Заодно и СИ освоите Вы же новичок
учится надо тому что более эффективно работает на системах с ограниченными ресурсами
а для ESP это СИ или в крайнем случае луа.
питон не для ESP
Я согласен на 100 процентов, но пока что вопрос в срабатывании прерывания.

Питон пока мне кажется достаточным для прототипа, пока вопрос производительности не стоит. Для первого опыта я решил что учить схемотехнику и новый язык многовато ;)
 

max_mazur

New member
У вас скорее всего классическая ошибка
прога просто долбит одно и тоже условие и печатает вам про него
но вы думаете иначе
Код срабатывает иногда через разные промежутки времени, случайно, и пока мне кажется что Вы не правы, но я перепроверю
 

CodeNameHawk

Moderator
Команда форума
Возле вывода есп поставьте резистор 470 ом на землю, чем ближе к есп тем лучше, провод к датчику минимальной длины ( скажем 5см), если нужен более длинный,
используйте экранированный (например так называемый микрофонный провод, н.п. хороший провод фирмы TASKER).
Через центральный провод передавайте сигнал, а экран подсоедините на землю возле есп. (второй конец экранного провода, возле датчика, будет висеть в воздухе.)
Сам датчик поместите в металлический экран, который подключите к земле. Параллельно питанию датчика поставьте конденсатор н.п. 470 мкф.
 

max_mazur

New member
Возле вывода есп поставьте резистор 470 ом на землю, чем ближе к есп тем лучше, провод к датчику минимальной длины ( скажем 5см), если нужен более длинный,
используйте экранированный (например так называемый микрофонный провод, н.п. хороший провод фирмы TASKER).
Через центральный провод передавайте сигнал, а экран подсоедините на землю возле есп. (второй конец экранного провода, возле датчика, будет висеть в воздухе.)
Сам датчик поместите в металлический экран, который подключите к земле. Параллельно питанию датчика поставьте конденсатор н.п. 470 мкф.
Спасибо за ответ, проверю

Новичка вопрос -номиналы откуда взяты?
Я хочу понимать что делаю что б не быть адептом карго культа
 

CodeNameHawk

Moderator
Команда форума
Новичка вопрос -номиналы откуда взяты?
Из опыта.
Расчет минимального значения резистора, 3,3В делите на максимальный ток, который может выдержать вывод есп и или выход датчика.
(В описании датчика написано 15 ма, а ток есп может быть, если правильно помню 20 ма)
В данном случае 3,3 / 0,015 А = 220 ом, 470 ом меньше нагружает выход датчика и достаточен для подавления помех.
 

=AK=

New member
Опрос пина это ресурсы процессора, и усложнение логики программы а я хочу (как новичек, возможно не понимаю что то) делать код максимально простым
Какая вам разница, будет ваша программа использовать 0.01% или 0.001% процессорного времени и памяти. И перестаньте как попугай повторять что вы "новичок". Кстати, новичок пишется через о.

Думаете мне действительно стоит "забить" на прерывания? или есть какие-то доступные способы отфильтровать импульсы длительностью короче N ms ?
Заведите программный 8-битный сдвиговый регистр и через равные промежутки времени вдвигайте в него значение, прочитанное с пина. Если в регистре 0x00 - считаете что на пине 0, если 0xFF - считаете что 1, все другие значения игнорируете.

А прерывания не трогайте. Все равно вы ими пользоваться не умеете. Например, обработка прерывания должна быть максимально быстрой, а вы туда медленную отладочную печать лепите.
 

nikolz

Well-known member
для проверки работы пина сделайте простейшую программу
в цикле вывод значения пина в терминал
на пин поставьте кнопку к земле а резистор 10-100 ком к питанию
и нажал отжался
нажал отжался
в результате вы выясните все о сигналах на пине
после этого перейдете к работе с прерываниями
все понятно?
 
Сверху Снизу