Форум РадиоКот https://radiokot.ru/forum/ |
|
Как на ESP восстановить прерывание после light sleep? https://radiokot.ru/forum/viewtopic.php?f=66&t=183922 |
Страница 1 из 1 |
Автор: | Andrey5945 [ Вс июл 31, 2022 12:29:43 ] |
Заголовок сообщения: | Как на ESP восстановить прерывание после light sleep? |
Добрый день. Подскажите пожалуйста как правильно сделать прерывание на ESP-07s: есть само прерывание обрабатывающее сигнал с приемника 433МГц СпойлерIRAM_ATTR void ANT() { // прерывание по сигналу с антенныvolatile int num = (micros() - tmr7); // вычисляем время между сигналами tmr7 = micros(); // сброс таймера if (num > 4650 && num < 4800) dann = true; if (dann == 1){ if (num > 600) err++; // проверяем нет ли символа разделителя if (err > 1) { // перезаписываем если принято что то кроме символа разделителя DataNumber = 0; err = 1; } myDATA[DataNumber] = num; // записываем время сигнала в массив DataNumber++; if (num < 50) { // если в процессе принят мусор начинаем все заново dann = false; DataNumber = 0; err = 0; } if (DataNumber > 17 && dann) { // если принят последний символ и нет ошибок отправляем на расшифровку detachInterrupt(13); DataReady = true; } } } чтобы уйти в сон по light sleep я отключаю прерывание detachInterrupt(13); иначе они не дают уйти в сон т.к. срабатывают слишком часто, сам сон: Спойлерvoid light_sleep(){digitalWrite(2, 1); // оставляем включенным пин А, так тратиться меньше энергии (примерно 0,4 мА) digitalWrite(4, 0); // выключаем пин В digitalWrite(12, 0); // выключаем пин С1 digitalWrite(14, 0); // выключаем пин С2 wifi_station_disconnect(); wifi_set_opmode_current(NULL_MODE); wifi_fpm_set_sleep_type(LIGHT_SLEEP_T); wifi_fpm_open(); // Enables force sleep gpio_pin_wakeup_enable(GPIO_ID_PIN(5), GPIO_PIN_INTR_HILEVEL); // пин и состояние при котором проснемся wifi_fpm_do_sleep(0xFFFFFFF); // Спим максимальное время delay(5); digitalWrite(4, 1); // выключаем канал В modplus = 1; } А далее после просыпания если попробовать опять повесить прерывание на пин attachInterrupt(13, ANT, CHANGE); ESP зависает и перезапускается по ватчдогу: Спойлерets Jan 8 2013,rst cause:4, boot mode:(3,6)wdt reset load 0x4010f000, len 3460, room 16 tail 4 chksum 0xcc load 0x3fff20b8, len 40, room 4 tail 4 chksum 0xc9 csum 0xc9 v00042da0 ~ld Как правильно восстановить прерывание после light sleep? весь код: Спойлер#include <ESP8266WiFi.h>#include <ESP8266mDNS.h> volatile uint32_t tmr7; // таймер 1 volatile bool dann = false; volatile int myDATA[19]; volatile byte DataNumber = 0; volatile byte err = 0; volatile bool DataReady = false; bool modplus = 0; // переменная смена режима byte buttn = 0; // кнопки пульта uint32_t tmr1; // таймер 1 uint32_t tmr3; // таймер 3 uint32_t tmr5; // таймер 5 byte mod = 0; byte modC = 9; // режим свечения канала C bool AntEnable = 0; // включены ли сигналы с антенны bool sig1 = 0; bool sig2 = 1; void setup() { Serial.begin(115200); pinMode(2, OUTPUT); // пин канала А pinMode(4, OUTPUT); // пин канала В pinMode(12, OUTPUT); // пин С1 pinMode(14, OUTPUT); // пин С2 pinMode(5, INPUT); // пин отслеживающий наличие питания через делитель напряжения 12в в 3в digitalWrite(2, 1); // выключаем канал А digitalWrite(4, 1); // выключаем канал В digitalWrite(12, 0); // выключаем канал С1 digitalWrite(14, 0); // выключаем канал С2 attachInterrupt(13, ANT, CHANGE); // прерывание по сигналу антенны analogWriteResolution(12); // 12 бит (0-4095) analogWriteFreq(900); // Гц шим Serial.println("Start"); } IRAM_ATTR void ANT() { // прерывание по сигналу с антенны volatile int num = (micros() - tmr7); // вычисляем время между сигналами tmr7 = micros(); // сброс таймера if (num > 4650 && num < 4800) dann = true; if (dann == 1){ if (num > 600) err++; // проверяем нет ли символа разделителя if (err > 1) { // перезаписываем если принято что то кроме символа разделителя DataNumber = 0; err = 1; } myDATA[DataNumber] = num; // записываем время сигнала в массив DataNumber++; if (num < 50) { // если в процессе принят мусор начинаем все заново dann = false; DataNumber = 0; err = 0; } if (DataNumber > 17 && dann) { // если принят последний символ и нет ошибок отправляем на расшифровку detachInterrupt(13); DataReady = true; } } } void light_sleep(){ digitalWrite(2, 1); // оставляем включенным пин А, так тратиться меньше энергии (примерно 0,4 мА) digitalWrite(4, 0); // выключаем пин В digitalWrite(12, 0); // выключаем пин С1 digitalWrite(14, 0); // выключаем пин С2 wifi_station_disconnect(); wifi_set_opmode_current(NULL_MODE); wifi_fpm_set_sleep_type(LIGHT_SLEEP_T); wifi_fpm_open(); // Enables force sleep gpio_pin_wakeup_enable(GPIO_ID_PIN(5), GPIO_PIN_INTR_HILEVEL); // пин и состояние при котором проснемся wifi_fpm_do_sleep(0xFFFFFFF); // Спим максимальное время delay(5); digitalWrite(4, 1); // выключаем канал В modplus = 1; } void DataOK(){ // расшифровка сигнала с антенны DataReady = false; int CodeButtonA[] = {4750, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0,}; // код кнопки A int CodeButtonB[] = {4750, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0,}; // код кнопки B int CodeButtonC[] = {4750, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0,}; // код кнопки C int CodeButtonD[] = {4750, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0,}; // код кнопки D int cod[19]; bool ButtonA = true; bool ButtonB = true; bool ButtonC = true; bool ButtonD = true; for (byte n = 1; n < 19; n++) { if (myDATA[n] < 400) { cod[n] = 0; } else cod[n] = 1; if (cod[n] != CodeButtonA[n]) { ButtonA = false; } if (cod[n] != CodeButtonB[n]) { ButtonB = false; } if (cod[n] != CodeButtonC[n]) { ButtonC = false; } if (cod[n] != CodeButtonD[n]) { ButtonD = false; } } if (ButtonA) buttn = 1; if (ButtonB) buttn = 2; if (ButtonC) buttn = 3; if (ButtonD) buttn = 4; attachInterrupt(13, ANT, CHANGE); } void loop() { if (digitalRead(5) == 0) { detachInterrupt(13); // отключаем прерывания на антенне tmr5 = millis(); // сброс таймера AntEnable = 1; light_sleep(); } if (DataReady) DataOK(); if (millis() - tmr5 >= 5000 && AntEnable == 1) { // включаем сигнал с антенны спустя задержку tmr5 = millis(); // сброс таймера AntEnable = 0; attachInterrupt(13, ANT, CHANGE); } if (modplus == 1){ // переключение основных режимов при восстановлении питания modplus = 0; mod++; if (mod > 1) mod = 0; // сбрасываем режим в ноль при переполнении if (mod == 0){ modC = 3; } if (mod == 1){ modC = 9; } } if (buttn == 3){ buttn = 0; if (millis() - tmr3 >= 300) { // ищем разницу tmr3 = millis(); // сброс таймера modplus = 1; } } if (modC == 3){ digitalWrite(12, 1); // включаем канал С1 digitalWrite(14, 0); // выключаем канал С2 } if (modC == 9){ if (millis() - tmr1 >= 1000) { // ищем разницу tmr1 = millis(); // сброс таймера sig1 = !sig1; sig2 = !sig1; digitalWrite(12, 0); digitalWrite(14, 0); delayMicroseconds(20); digitalWrite(12, sig1); digitalWrite(14, sig2); Serial.println("Work OK"); } } } |
Автор: | JackSmith [ Вс июл 31, 2022 17:31:49 ] |
Заголовок сообщения: | Re: Как на ESP восстановить прерывание после light sleep? |
Я думаю, что следует отказаться от спящего режима. Esp8266 все равно на автономное питание не посадить. Разве только на powerbank. |
Автор: | Andrey5945 [ Вс июл 31, 2022 18:47:16 ] |
Заголовок сообщения: | Re: Как на ESP восстановить прерывание после light sleep? |
Я думаю, что следует отказаться от спящего режима. Esp8266 все равно на автономное питание не посадить. Разве только на powerbank. Мне нужна автономность только на пару секунд и её вполне успешно обеспечивает конденсатор, но вот без light sleep потребление тока возрастет в 200 раз и эт уже нужна батарея из ионисторов наверн. Неужели нет какого то способа попроще? |
Автор: | JackSmith [ Вс июл 31, 2022 21:58:28 ] |
Заголовок сообщения: | Re: Как на ESP восстановить прерывание после light sleep? |
Цитата: потребление тока возрастет в 200 раз реальное потребление меряли? можно попробовать поменять SDK через менеджер плат, возможно на каком-нибудь заработает корректно. |
Автор: | Andrey5945 [ Пн авг 01, 2022 00:02:37 ] |
Заголовок сообщения: | Re: Как на ESP восстановить прерывание после light sleep? |
Цитата: потребление тока возрастет в 200 раз реальное потребление меряли? можно попробовать поменять SDK через менеджер плат, возможно на каком-нибудь заработает корректно. В режиме работы без вайфай около 70мА, в light slep 0,4мА. То есть в коде менять что то бесполезно — странно я думал я где то накосячил и чего то не учел( |
Автор: | JackSmith [ Пн авг 01, 2022 06:08:23 ] |
Заголовок сообщения: | Re: Как на ESP восстановить прерывание после light sleep? |
Вы цифры из даташит на ЧИП приводите, который без флешки без обвязки и где измерения были сделаны в сферическом вакуме. Я же спрашивал цифры реального потребления вашего МОДУЛЯ. Сделайте замеры. |
Автор: | Andrey5945 [ Пн авг 01, 2022 09:19:33 ] |
Заголовок сообщения: | Re: Как на ESP восстановить прерывание после light sleep? |
Вы цифры из даташит на ЧИП приводите, который без флешки без обвязки и где измерения были сделаны в сферическом вакуме. Я же спрашивал цифры реального потребления вашего МОДУЛЯ. Сделайте замеры. Это реальные цифры для моей кастомной платы на esp07s: в легком сне 0,415мА, в работе с вайфай примерно 80-87мА, если попытаться выключить вайфай 70-75мА (хотя по инструкциям должно быть 15мА, но у меня чет больше, но даже 15 это в 30 раз больше). Емкости в ~1500мкф хватает на 5-10сек работы в зависимости от того на какой кусок кода попало отключение питания. |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |