BT-выключатель. Помогите с кодом, зависает Адруина
- Войдите на сайт для отправки комментариев
Всем здрасьте.
На даче есть 4 прожектора, установленные вокруг дома. Раньше они "окучивались" китайский радио-выключателем с Алиэкспресса, но пережив одну зиму сдох. Решил сделать тоже самое на Ардуине (дальше буду допиливать функционал погодной станции)
Итак имею: Arduino Nano v.3, релейный модуль на 4 реле, bt-модуль hc-05, модуль расширения портов на PCF8574, два БП (1А и 2А), 5 кнопок и 6 светодиодов.
Arduino питается от БП на 1А (длина соединительных проводов ~10см), все остальное питается от второго БП на 2А. GNDестетсвенно соединены.
Релейный модуль подключен к Ардуино витой парой (~10 см) по паре на каждый канал реле, bt-модуль - витой парой ~ 8 метров (по паре на GND, +5, RX и TX), модуль расширения портов на PCF8574 - витой парой ~ 3 метра (по паре на GND, +5, SDA и SCL), диоды подключены к PCF8574, кнопки - витой парой ~ 3 метра к Ардуино с подтяжкой к GND
Проблема в том, что поработав от 30 минут до часа Ардуина вешается.
Вот код. Помогите разобраться почему
byte RELAY[4] = {9, 10, 11, 12}; // пины к которым подключены Реле byte LED[6] = {0, 1, 2, 3, 6, 7}; // пины PCF8574 0x3F к которым подключены LEDы //___ все для работы с кнопками и LED'ами __________________________________________ #include <PCF8574.h> // Библиотека для PCF8574 #include <Wire.h> PCF8574 LEDs; #include <Button.h> // титановый велосипед для тактовой кнопки by Клапауций Button Keys; void setup() { Serial.begin(57600); //___ все для работы с реле ______________________________________________________ for (byte i = 0; i < sizeof (RELAY - 1); i++) // указываем пины, к которым подключены Relay как вывод и выкл их { pinMode (RELAY[i], OUTPUT); // Инициализируем пин как выход digitalWrite (RELAY[i], HIGH); // Выключаем Реле } pinMode(13, OUTPUT); //___ все для работы с LED'ами через PCF8574 _____________________________________ LEDs.begin(0x3F); // Инициализируем PCF8574 по адресу 0x3F с именем LEDs for (byte i = 0; i < sizeof (LED); i++) // указываем пины, к которым подключены LED как вывод и выкл их { LEDs.pinMode (LED[i], OUTPUT); // Инициализируем пин как выход LEDs.digitalWrite (LED[i], HIGH); // Выключаем LED } LEDs.digitalWrite (LED[4], LOW); //___ все для работы с кнопками __________________________________________________ Keys.button (4, 5, 6, 7, 8); // Указываем пины, к которым подключены кнопки Keys.duration_bounce (5); Keys.duration_click_Db (250); Keys.duration_inactivity_Up(5000); Keys.duration_inactivity_Dn(1000); } void loop() { Use_Keys(); // Использование кнопок Use_Bluetooth(); // Получение комманд по Bluetooth'У } //////////////////////////////////////////////////////////////////////////////////// // Использование кнопок // //////////////////////////////////////////////////////////////////////////////////// void Use_Keys() { Keys.read(); if (Keys.button[0].event_click_Up() == 1) DoIt (0); if (Keys.button[1].event_click_Up() == 1) DoIt (1); if (Keys.button[2].event_click_Up() == 1) DoIt (2); if (Keys.button[3].event_click_Up() == 1) DoIt (3); if (Keys.button[4].event_click_Up() == 1) { if (digitalRead (RELAY[0]) == HIGH && digitalRead (RELAY[1]) == HIGH && digitalRead (RELAY[2]) == HIGH && digitalRead (RELAY[3]) == HIGH) { // Если ВСЕ реле были выключены, то включаем ВСЕ for (byte i = 0; i < sizeof (RELAY - 1); i++) { digitalWrite (RELAY[i], LOW); // включи RELAY LEDs.digitalWrite (LED[i], LOW); // включи LED } LEDs.digitalWrite(6, HIGH); // Выключаем LED_Wait_1 LEDs.digitalWrite(7, HIGH); // Выключаем LED_Wait_2 } else { if (digitalRead (RELAY[0]) == LOW || digitalRead (RELAY[1]) == LOW || digitalRead (RELAY[2]) == LOW || digitalRead (RELAY[3]) == LOW) { // если ХОТЯ БЫ ОДНО реле было включено, то выключаем ВСЕ for (byte i = 0; i < sizeof (RELAY - 1); i++) { digitalWrite (RELAY[i], HIGH); // выключи RELAY LEDs.digitalWrite (LED[i], HIGH); // выключи LED } LEDs.digitalWrite(6, LOW); // Включаем LED_Wait_1 LEDs.digitalWrite(7, LOW); // Включаем LED_Wait_2 } } } } //////////////////////////////////////////////////////////////////////////////////// // Получение комманд по Bluetooth'у // //////////////////////////////////////////////////////////////////////////////////// void Use_Bluetooth() { if (Serial.available() > 0) { switch (Serial.read()) { case '1': // Если прилетела '1' DoIt (0); break; case '2': // Если прилетела '2' DoIt (1); break; case '3': // Если прилетела '3' DoIt (2); break; case '4': // Если прилетела '4' digitalWrite (PIN_RELAY_4, !digitalRead (PIN_RELAY_4)); // Переключи РЕЛЕ_4 // LEDs.digitalWrite (3, digitalRead (PIN_RELAY_4)); // включи/выключи LED_4 // Wait_LEDs(); break; case '0': // Если прилетел '0' if (digitalRead (RELAY[0]) == HIGH && digitalRead (RELAY[1]) == HIGH && digitalRead (RELAY[2]) == HIGH && digitalRead (RELAY[3]) == HIGH) { // Если ВСЕ реле были выключены, то включаем ВСЕ for (byte i = 0; i < sizeof (RELAY - 1); i++) { digitalWrite (RELAY[i], LOW); // включи RELAY LEDs.digitalWrite (LED[i], LOW); // включи LED } LEDs.digitalWrite(6, HIGH); // Выключаем LED_Wait_1 //LEDs.digitalWrite(7, HIGH); // Выключаем LED_Wait_2 } else { if (digitalRead (RELAY[0]) == LOW || digitalRead (RELAY[1]) == LOW || digitalRead (RELAY[2]) == LOW || digitalRead (RELAY[3]) == LOW) { // если ХОТЯ БЫ ОДНО реле было включено, то выключаем ВСЕ for (byte i = 0; i < sizeof (RELAY - 1); i++) { digitalWrite (RELAY[i], HIGH); // выключи RELAY LEDs.digitalWrite (LED[i], HIGH); // выключи LED } LEDs.digitalWrite(6, LOW); // Включаем LED_Wait_1 //LEDs.digitalWrite(7, LOW); // Включаем LED_Wait_2 } } break; } } } void DoIt (byte PIN) { digitalWrite (RELAY[PIN], !digitalRead (RELAY[PIN])); // Переключи РЕЛЕ[pin] LEDs.digitalWrite (LED[PIN], digitalRead (RELAY[PIN])); // Включи/выключи LED[pin] // Если ВСЕ реле выключены, то включаем Wait_LED'ы if (digitalRead (RELAY[0]) == HIGH && digitalRead (RELAY[1]) == HIGH && digitalRead (RELAY[2]) == HIGH && digitalRead (RELAY[3]) == HIGH) { LEDs.digitalWrite(6, LOW); // Выключаем LED_Wait_1 // LEDs.digitalWrite(7, LOW); // Выключаем LED_Wait_2 } // Если ХОТЯ БЫ ОДНО реле включено, то выключаем Wait_LED'ы if (digitalRead (RELAY[0]) == LOW || digitalRead (RELAY[1]) == LOW || digitalRead (RELAY[2]) == LOW || digitalRead (RELAY[3]) == LOW) { LEDs.digitalWrite(6, HIGH); // Включаем LED_Wait_1 // LEDs.digitalWrite(7, HIGH); // Включаем LED_Wait_2 } }
еще немного вводных:
Есть пульт, на котором расположены 5 кнопок и 6 диодов. Четыре кнопки (button[0], [1], [2] и [3]) и четыре LEDa (LED[0], [1], [2] и [3]) соответствуют релешкам RELAY[0], [1], [2] и [3]. Еще два LEDa (LED[4] и [5]) работают как "ночник". Если выключены все реле, то LEDы 4 и 5 включены, если включено хотя бы одно реле, то включен соответствующий ему LEDa, а LEDы 4 и 5 - выключены. Нажание кнопок 0, 1, 2 и 3 меняет состояние соответствующего реле и соответствующего LEDa. Нажатие кнопки 4 вЫключает ВСЕ реле если было включено ХОТЯ БЫ одно из них или включает все реле, если НИ одно из них не было включено.
Команды по блютусу работают так же.
Почти наверняка наводки по длинной витой паре.
Собственно, тут два пути. Можно лечить болезнь, а можно последствия.
Более правильно, конечно, болезнь - ставить фильтры на кабели и фильтровать помехи. Сложно и муторно.
Можно пойти по более легкому пути - лечить зависание ардуины. Ставите вотчдог и как только МК подвисает, он тут же рестартится автоматом. Вы даже не будете этого замечать, для вас контроллер будет работать без сбоев.
ЗЫ - сорри, код не смотрел
1. Непонятно, что означает "(по паре на GND, +5, RX и TX)". Пара - это два провода, куда один, куда другой?
2. При передачи сигнала на расстояние, исчисляемое метрами, обычно используют не напряжение, а токовую петлю.
Так какой тогда смысл в витой паре?
Обычно как раз один из проводов пары используется для каких-либо целей, а второй - для заземления. Тогда уровень помех существенно ниже.
Так какой тогда смысл в витой паре?
Обычно как раз один из проводов пары используется для каких-либо целей, а второй - для заземления. Тогда уровень помех существенно ниже.