У меня возникла проблема с техникой тайм-аута, которая по какой-то причине не работает
Я пишу IoT-вещь, и проблема, с которой я сталкиваюсь, заключается в том, что техника, которую я использую для тайм-аута, а затем сбрасываю этот тайм-аут, не работает. Это метод, который я использовал много раз в прошлом, и я публикую здесь только для того, чтобы исключить, что у меня что-то не так в этом коде. Поведение, которое я получаю, является неожиданным.
То, что я делаю, - это использование
millis()
который возвращает количество миллисекунд, прошедших с момента загрузки машины. Я сохраняю это в метке времени, а затем в своем loop()
функция, которая вызывается для каждой итерации плотного цикла, процессор вращается для меня в основном я вижу, если число разницы между настоящим моментом и моментом, когда была взята временная метка, составляет более 1000 миллисекунд (1 секунда)У меня есть
callback()
метод, который вызывается в любое время, когда конец провода физически соприкасается. Это работает, как и в обычных пожарах, но он ведет себя так, как будто я не сбросил метку времени внутри функции.Может ли кто-нибудь сказать мне, где я ошибся?
(См. раздел "Что вы пробовали?" Раздел для получения дополнительной информации)
Что я уже пробовал:
uint32_t _timestamp; // gets called when wire is touched void callback() { // millis() won't advance in interrupt routines _timestamp = 0; // reset the timeout // equiv of _timestamp=millis(); Serial.println("Callback"); } // runs once on CPU startup void setup() { Serial.begin(115200); // attach interrupt on GPIO15 touchpad // with to 40 sensitivity. callback() // gets fired when wire is touched touchAttachInterrupt(T3, callback, 40); // reset the timeout _timestamp = millis(); } // called for each iteration of the CPU's loop void loop() { // for callback(): if (!_timestamp) _timestamp = millis(); // if more than a second has elapsed write it if (millis() - _timestamp > 1000) { // and reset the timestamp _timestamp = millis(); Serial.println("Time elapsed"); } }
Выше я выделил жирным шрифтом критическую линию, которая, похоже, не работает. Я также пробовал делать
_timestamp
volatile
но безрезультатно.Последовательный выход (с метками времени) выглядит следующим образом
Это дает
15:29:56.544 -> Time elapsed 15:29:57.537 -> Time elapsed ... (i'm pressing the touch sensor wire now) 15:29:59.755 -> Callback 15:29:59.755 -> Time elapsed 15:29:59.788 -> Callback 15:29:59.788 -> Time elapsed 15:29:59.821 -> Callback .... (i've released the touch sensor wire) 15:30:00.186 -> Time elapsed 15:30:01.179 -> Time elapsed ...
Я выделил жирным шрифтом некоторые фрагменты, чтобы подчеркнуть, как быстро это происходит.
но в любом случае я ожидаю чего-то подобного
Time elapsed Time elapsed Time elapsed (I've held the wire) Callback Callback Callback Callback (I've released the wire) Time elapsed Time elapsed
Rick York
Это однопоточный процесс? У меня сложилось впечатление, что это так, но я хотел проверить.
honey the codewitch
Эээ, ишь? Насколько я понимаю, весь код, кажется, чтобы быть в одном потоке, и все же вещь двухъядерный. Кроме того, было сказано, что мне нужно использовать volatile на глобальных vars, доступных в прерываниях, таких как callback, что предполагает какой-то параллельный доступ, я думаю. Я не отмечал _timestamp с volatile выше, но у меня нет никакого результата.
Rick York
Похоже, атомный замок помог все исправить. Моей первой мыслью была проблема "потоковой передачи" и параллельного доступа. Отсюда и мой вопрос.
markkuk
Вы можете попробовать официальный форум ESP32 Arduino: https://esp32.com/viewforum.php?f=19 для получения дополнительной экспертизы.
honey the codewitch
Я являюсь членом форума ESP32 на reddit. Сначала я заглянул туда, но не увидел ни одного почтового кода, поэтому решил сначала попробовать здесь. Я не был уверен, как они отнесутся к тому, чтобы взорвать свой форум со всем этим источником.