Программа не видит значение кнопки
- Войдите на сайт для отправки комментариев
Пишу программу для автополива с управлением через bluetooth. Использую библиотеку и приложение RemoteXY. Имеется два режима: первый по датчику, второй по задержке. Проблема такая: когда виртуальный переключатель в приложении находится в положении А (первый режим, значение mode=0) и датчик на 11 пине возвращает значение LOW (недостаточно влаги, включается насос через драйвер) программа не видит переключение в другой режим работы, иногда отрубается блютуз. То есть насос продолжает качать, пока датчик не окажется мокрым. Только тогда происходит переключение в другой режим работы. Что может быть не так? С питанием проблем нет, БП даёт 3А. С переключением из второго режима в первый проблем почему-то нет.
#define REMOTEXY_MODE__SOFTSERIAL #include <SoftwareSerial.h> #include <RemoteXY.h> #define REMOTEXY_SERIAL_RX 2 #define REMOTEXY_SERIAL_TX 3 #define REMOTEXY_SERIAL_SPEED 9600 #pragma pack(push, 1) uint8_t RemoteXY_CONF[] = { 255,5,0,0,0,76,0,8,24,1, 3,135,0,25,63,10,16,26,3,130, 21,50,21,12,16,26,2,1,21,80, 22,11,16,26,1,31,79,78,0,79, 70,70,0,1,0,2,3,10,10,16, 28,208,161,208,145,208,160,208,158,208, 161,0,1,0,51,3,10,10,16,28, 208,159,208,158,208,155,208,152,208,162, 208,172,0 }; struct { uint8_t day; uint8_t mode; uint8_t onoff; uint8_t reset; uint8_t button_1; uint8_t connect_flag; } RemoteXY; #pragma pack(pop) unsigned long timing; int del; void setup() { RemoteXY_Init (); } void loop() { RemoteXY_Handler (); if(RemoteXY.onoff!=0) { if (RemoteXY.button_1!=0) { digitalWrite(13,HIGH); } else { digitalWrite(13,LOW); } if(RemoteXY.reset!=0) { timing = millis(); } if (RemoteXY.mode!=0) { if (RemoteXY.day==0) del=3000; if (RemoteXY.day==1) del=6000; if (RemoteXY.day==2) del=9000; if (RemoteXY.day==3) del=12000; if (RemoteXY.day==4) del=15000; if (RemoteXY.day==5) del=18000; if (RemoteXY.day==6) del=21000; if(RemoteXY.reset!=0) del=0; if (millis() - timing > del) { tone(8, 1720); delay(300); tone(8, 1318); delay(300); tone(8, 1720); delay(300); tone(8, 1318); delay(300); tone(8, 1720); delay(300); tone(8, 1661); delay(300); noTone(8); delay(10); tone(8, 1661); delay(300); noTone(8); digitalWrite(13,HIGH); delay(4000); digitalWrite(13,LOW); timing = millis(); } } else { if (digitalRead(11)==HIGH) { tone(8, 1396); delay(150); tone(8, 2093); delay(300); noTone(8); delay(10); tone(8, 1396); delay(150); tone(8, 2093); delay(300); tone(8, 1396); delay(400); noTone(8); digitalWrite(13,HIGH); delay(4000); digitalWrite(13,LOW); delay(2000); } } } }
delay() - достаточная причина для того, чтобы программа не реагировала на любые внешние события.
Без delay всё то же самое, ничего не меняется. Программа даже после делэй должна пойти по новому циклу и опросить кнопки. Там в начале для этого Handler поставлен. И куча If.
1. Искать другие возможные причины неисправности при наличии неисправленных очевидных считаю пустой тратой времени.
2. В тексте Вы пишете "первый режим", "второй режим", "положение А", а чему они соответствуют в коде без комментариев непонятно.
3. Вы, хотя и не совсем внятно, описали, как работает программа, но забыли упомянуть, как, по Вашему мнению, она должна работать. Если первое (как на самом деле работает) еще можно догадаться из кода, то второе (как должна работать) никто кроме Вас не знает.
4. Опять же, не приведено схемы. У Вас в голове она есть, а у читателя?
Как должна работать программа: если кнопка RemoteXY.onoff нажата, то разрешить выполнение дальнейших задач. Дальше программа опрашивает переключатель RemoteXY.mode. Если переключатель в положении B (RemoteXY.mode!=0) опрашиваем второй переключатель RemoteXY.day. Он задает задержку. Дальше контроллер включает мотор через заданные промежутки времени. Эта часть программы работает идеально. Но если переключатель RemoteXY.mode в положении А (это последний else в програме), начинает опрашиваться датчик влажности почвы. Если датчик выдает LOW, включить насос на 4 секунды. Но нужно, чтобы из этого режима можно было выйти в любой момент. Это у меня и не получается. Пока датчик не выдаст HIGH, режим не переключится. А если долго не давать значение HIGH, отрубается блютуз.
Подключение такое
Без delay всё то же самое, ничего не меняется.
Хотите верьте, хотите нет - но, как Вам уже сказали, программу нужно реализовать без delay. Во-первых, чтобы была реакция на кнопки. Во-вторых, проверьте инструкцию к RemoteXY, может к нему нужно обращаться не реже чем ... иначе связь обрывается?
Выкинте на время отладки всю музыку - текст в два раза короче станет, самому же читать удобнее будет.
Сформулируйте алгоритм работы программы обычным человеческим языком (сейчас Вы всё время сбиваетесь с описания алгоритма на уже написанный текст программы). Мне кажется, что у Вас не всё реализовано так, как задумывалось.
Ну и совсем "по науке" будет реализовать конечный автомат. Есть соответствующие темы с теорией и примерами и на этом форуме.
Да, на сайте действительно написано, что лучше обойтись без задержек вообще. Переписал цикл датчика без задержки, всё работает. Спасибо.