Witam,
Posiada ktoś może gotowy wsad do Arduino MEGA 2560 z Mysensors do sterowania oświetleniem na HA?
// Wlacz wydruki debugowania na monitorze szeregowym #define MY_DEBUG // Wlacz i wybierz dolaczony typ radia //#define MY_RADIO_NRF24 //#define MY_RADIO_RFM69 // Ustaw NISKI poziom mocy nadawania jako domyslny, jesli masz wzmocniony modul NRF i // zasilaj radio oddzielnie za pomoca dobrego regulatora, ktory mozesz podniesc poziom PA. //#define MY_RF24_PA_LEVEL RF24_PA_LOW // Wlacz brame szeregowa #define MY_GATEWAY_SERIAL // Okresl nizsza szybkosc transmisji dla Arduino dzialajacego na czestotliwosci 8 MHz // (Arduino Pro Mini 3.3V i SenseBender) #if F_CPU == 8000000L #define MY_BAUD_RATE 38400 #endif // Flash leds on rx/tx/err // #define MY_LEDS_BLINKING_FEATURE // Ustaw okres migania // #define MY_DEFAULT_LED_BLINK_PERIOD 300 // Odwraca zachowanie diod LED // #define MY_WITH_LEDS_BLINKING_INVERSE // Enable inclusion mode #define MY_INCLUSION_MODE_FEATURE // Wlacz przycisk trybu wlaczenia na bramie #define MY_INCLUSION_BUTTON_FEATURE // Odwraca zachowanie przycisku wlaczenia (jesli uzywasz zewnetrznego pullup) //#define MY_INCLUSION_BUTTON_EXTERNAL_PULLUP // Ustaw czas trwania trybu wlaczenia (w sekundach) #define MY_INCLUSION_MODE_DURATION 60 // Cyfrowy pin uzywany do przycisku trybu wlaczenia #define MY_INCLUSION_MODE_BUTTON_PIN 3 // Nie mozna zastepowac domyslnych konfiguracji sprzetu //#define MY_DEFAULT_ERR_LED_PIN 4 // Error led pin //#define MY_DEFAULT_RX_LED_PIN 6 // Receive led pin //#define MY_DEFAULT_TX_LED_PIN 5 // the PCB, on board LED #include <SPI.h> #include <MySensors.h> #include <Bounce2.h> // Wlacz funkcje repeatera dla tego wezla #define MY_REPEATER_FEATURE #define RELAY_1 16 // Numer styku we/wy cyfrowego Arduino dla pierwszego przekaznika (drugi na styku + 1 itd.) #define RELAY_2 17 #define RELAY_3 18 #define RELAY_4 19 #define RELAY_5 20 #define RELAY_6 21 #define RELAY_7 22 #define RELAY_8 23 #define RELAY_9 24 #define RELAY_10 25 #define RELAY_11 26 #define RELAY_12 27 #define RELAY_13 28 #define RELAY_14 29 #define RELAY_15 30 #define RELAY_16 31 #define RELAY_17 32 #define RELAY_18 33 #define RELAY_19 34 #define RELAY_20 35 #define RELAY_21 36 #define RELAY_22 37 #define RELAY_23 38 #define RELAY_24 39 #define RELAY_25 40 #define RELAY_26 41 #define RELAY_27 42 #define RELAY_28 43 #define RELAY_29 44 #define RELAY_30 45 #define RELAY_31 46 #define RELAY_32 47 #define NUMBER_OF_RELAYS 32 // Calkowita liczba podlaczonych przekaznikow #define RELAY_ON 1 // GPIO wartosc do zapisania, aby wlaczyc podlaczony przekaznik #define RELAY_OFF 0 // GPIO wartosc do zapisania, aby wylaczyc podlaczony przekaznik #define BUTTON_PIN A0 #define BUTTON2_PIN A1 #define BUTTON3_PIN A2 #define BUTTON4_PIN A3 #define BUTTON5_PIN A4 #define BUTTON6_PIN A5 #define BUTTON7_PIN A6 #define BUTTON8_PIN A7 #define BUTTON9_PIN A8 #define BUTTON10_PIN A9 #define BUTTON11_PIN A10 #define BUTTON12_PIN A11 #define BUTTON13_PIN A12 #define BUTTON14_PIN A13 #define BUTTON15_PIN A14 #define BUTTON16_PIN A15 #define BUTTON17_PIN 0 #define BUTTON18_PIN 1 #define BUTTON19_PIN 2 #define BUTTON20_PIN 3 #define BUTTON21_PIN 4 #define BUTTON22_PIN 5 #define BUTTON23_PIN 6 #define BUTTON24_PIN 7 #define BUTTON25_PIN 8 #define BUTTON26_PIN 9 #define BUTTON27_PIN 10 #define BUTTON28_PIN 11 #define BUTTON29_PIN 12 #define BUTTON30_PIN 13 #define BUTTON31_PIN 14 #define BUTTON32_PIN 15 void before() { for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS;sensor++, pin++) { // Nastepnie ustaw styki przekaznika w tryb wyjsciowy pinMode(pin, OUTPUT); // Ustaw przekaznik na ostatni znany stan (uzywajac pamieci eeprom) digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF); } } Bounce debouncer = Bounce(); Bounce debouncer2 = Bounce(); Bounce debouncer3 = Bounce(); Bounce debouncer4 = Bounce(); Bounce debouncer5 = Bounce(); Bounce debouncer6 = Bounce(); Bounce debouncer7 = Bounce(); Bounce debouncer8 = Bounce(); Bounce debouncer9 = Bounce(); Bounce debouncer10 = Bounce(); Bounce debouncer11 = Bounce(); Bounce debouncer12 = Bounce(); Bounce debouncer13 = Bounce(); Bounce debouncer14 = Bounce(); Bounce debouncer15 = Bounce(); Bounce debouncer16 = Bounce(); Bounce debouncer17 = Bounce(); Bounce debouncer18 = Bounce(); Bounce debouncer19 = Bounce(); Bounce debouncer20 = Bounce(); Bounce debouncer21 = Bounce(); Bounce debouncer22 = Bounce(); Bounce debouncer23 = Bounce(); Bounce debouncer24 = Bounce(); Bounce debouncer25 = Bounce(); Bounce debouncer26 = Bounce(); Bounce debouncer27 = Bounce(); Bounce debouncer28 = Bounce(); Bounce debouncer29 = Bounce(); Bounce debouncer30 = Bounce(); Bounce debouncer31 = Bounce(); Bounce debouncer32 = Bounce(); void setup() { // Ustaw lokalnie podlaczone czujniki delay(10000); // Ustaw przyciski pinMode(BUTTON_PIN, INPUT_PULLUP); pinMode(BUTTON2_PIN, INPUT_PULLUP); pinMode(BUTTON3_PIN, INPUT_PULLUP); pinMode(BUTTON4_PIN, INPUT_PULLUP); pinMode(BUTTON5_PIN, INPUT_PULLUP); pinMode(BUTTON6_PIN, INPUT_PULLUP); pinMode(BUTTON7_PIN, INPUT_PULLUP); pinMode(BUTTON8_PIN, INPUT_PULLUP); pinMode(BUTTON9_PIN, INPUT_PULLUP); pinMode(BUTTON10_PIN, INPUT_PULLUP); pinMode(BUTTON11_PIN, INPUT_PULLUP); pinMode(BUTTON12_PIN, INPUT_PULLUP); pinMode(BUTTON13_PIN, INPUT_PULLUP); pinMode(BUTTON14_PIN, INPUT_PULLUP); pinMode(BUTTON15_PIN, INPUT_PULLUP); pinMode(BUTTON16_PIN, INPUT_PULLUP); pinMode(BUTTON17_PIN, INPUT_PULLUP); pinMode(BUTTON18_PIN, INPUT_PULLUP); pinMode(BUTTON19_PIN, INPUT_PULLUP); pinMode(BUTTON20_PIN, INPUT_PULLUP); pinMode(BUTTON21_PIN, INPUT_PULLUP); pinMode(BUTTON22_PIN, INPUT_PULLUP); pinMode(BUTTON23_PIN, INPUT_PULLUP); pinMode(BUTTON24_PIN, INPUT_PULLUP); pinMode(BUTTON25_PIN, INPUT_PULLUP); pinMode(BUTTON26_PIN, INPUT_PULLUP); pinMode(BUTTON27_PIN, INPUT_PULLUP); pinMode(BUTTON28_PIN, INPUT_PULLUP); pinMode(BUTTON29_PIN, INPUT_PULLUP); pinMode(BUTTON30_PIN, INPUT_PULLUP); pinMode(BUTTON31_PIN, INPUT_PULLUP); pinMode(BUTTON32_PIN, INPUT_PULLUP); // Po skonfigurowaniu przycisku ustaw debugera. debouncer.attach(BUTTON_PIN); debouncer.interval(5); //przerwanie w ms debouncer2.attach(BUTTON2_PIN); debouncer2.interval(5); debouncer3.attach(BUTTON3_PIN); debouncer3.interval(5); debouncer4.attach(BUTTON4_PIN); debouncer4.interval(5); debouncer5.attach(BUTTON5_PIN); debouncer5.interval(5); debouncer6.attach(BUTTON6_PIN); debouncer6.interval(5); debouncer7.attach(BUTTON7_PIN); debouncer7.interval(5); debouncer8.attach(BUTTON8_PIN); debouncer8.interval(5); debouncer9.attach(BUTTON9_PIN); debouncer9.interval(5); debouncer10.attach(BUTTON10_PIN); debouncer10.interval(5); debouncer11.attach(BUTTON11_PIN); debouncer11.interval(5); debouncer12.attach(BUTTON12_PIN); debouncer12.interval(5); debouncer13.attach(BUTTON13_PIN); debouncer13.interval(5); debouncer14.attach(BUTTON14_PIN); debouncer14.interval(5); debouncer15.attach(BUTTON15_PIN); debouncer15.interval(5); debouncer16.attach(BUTTON16_PIN); debouncer16.interval(5); debouncer17.attach(BUTTON17_PIN); debouncer17.interval(5); debouncer18.attach(BUTTON18_PIN); debouncer18.interval(5); debouncer19.attach(BUTTON19_PIN); debouncer19.interval(5); debouncer20.attach(BUTTON20_PIN); debouncer20.interval(5); debouncer21.attach(BUTTON21_PIN); debouncer21.interval(5); debouncer22.attach(BUTTON22_PIN); debouncer22.interval(5); debouncer23.attach(BUTTON23_PIN); debouncer23.interval(5); debouncer24.attach(BUTTON24_PIN); debouncer24.interval(5); debouncer25.attach(BUTTON25_PIN); debouncer25.interval(5); debouncer26.attach(BUTTON26_PIN); debouncer26.interval(5); debouncer27.attach(BUTTON27_PIN); debouncer27.interval(5); debouncer28.attach(BUTTON28_PIN); debouncer28.interval(5); debouncer29.attach(BUTTON29_PIN); debouncer29.interval(5); debouncer30.attach(BUTTON30_PIN); debouncer30.interval(5); debouncer31.attach(BUTTON31_PIN); debouncer31.interval(5); debouncer32.attach(BUTTON32_PIN); debouncer32.interval(5); //presentation(); } void presentation() { // Wyslij informacje o wersji szkicu do bramy i kontrolera sendSketchInfo("Relay", "1.0"); for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS;sensor++, pin++) { // Zarejestruj wszystkie czujniki do gw (zostana utworzone jako urzadzenia potomne) present(sensor, S_LIGHT); } } MyMessage msg(1, V_LIGHT); MyMessage msg2(2, V_LIGHT); MyMessage msg3(3, V_LIGHT); MyMessage msg4(4, V_LIGHT); MyMessage msg5(5, V_LIGHT); MyMessage msg6(6, V_LIGHT); MyMessage msg7(7, V_LIGHT); MyMessage msg8(8, V_LIGHT); MyMessage msg9(9, V_LIGHT); MyMessage msg10(10, V_LIGHT); MyMessage msg11(11, V_LIGHT); MyMessage msg12(12, V_LIGHT); MyMessage msg13(13, V_LIGHT); MyMessage msg14(14, V_LIGHT); MyMessage msg15(15, V_LIGHT); MyMessage msg16(16, V_LIGHT); MyMessage msg17(17, V_LIGHT); MyMessage msg18(18, V_LIGHT); MyMessage msg19(19, V_LIGHT); MyMessage msg20(20, V_LIGHT); MyMessage msg21(21, V_LIGHT); MyMessage msg22(22, V_LIGHT); MyMessage msg23(23, V_LIGHT); MyMessage msg24(24, V_LIGHT); MyMessage msg25(25, V_LIGHT); MyMessage msg26(26, V_LIGHT); MyMessage msg27(27, V_LIGHT); MyMessage msg28(28, V_LIGHT); MyMessage msg29(29, V_LIGHT); MyMessage msg30(30, V_LIGHT); MyMessage msg31(31, V_LIGHT); MyMessage msg32(32, V_LIGHT); void loop() { // Aktualizujemy status przycisku if (debouncer.update()) { // Pobieramy stan przycisku. int value = debouncer.read(); // Wyslij nowa wartosc. if(value == LOW){ saveState(1, !loadState(1)); digitalWrite(RELAY_1, loadState(1)?RELAY_ON:RELAY_OFF); send(msg.set(loadState(1))); } } if (debouncer2.update()) { int value2 = debouncer2.read(); if(value2 == LOW){ saveState(2, !loadState(2)); digitalWrite(RELAY_2, loadState(2)?RELAY_ON:RELAY_OFF); send(msg2.set(loadState(2))); } } if (debouncer3.update()) { int value3 = debouncer3.read(); if(value3 == LOW){ saveState(3, !loadState(3)); digitalWrite(RELAY_3, loadState(3)?RELAY_ON:RELAY_OFF); send(msg3.set(loadState(3))); } } if (debouncer4.update()) { int value4 = debouncer4.read(); if(value4 == LOW){ saveState(4, !loadState(4)); digitalWrite(RELAY_4, loadState(4)?RELAY_ON:RELAY_OFF); send(msg4.set(loadState(4))); } } if (debouncer5.update()) { int value5 = debouncer5.read(); if(value5 == LOW){ saveState(5, !loadState(5)); digitalWrite(RELAY_5, loadState(5)?RELAY_ON:RELAY_OFF); send(msg5.set(loadState(5))); } } if (debouncer6.update()) { int value6 = debouncer6.read(); if(value6 == LOW){ saveState(6, !loadState(6)); digitalWrite(RELAY_6, loadState(6)?RELAY_ON:RELAY_OFF); send(msg6.set(loadState(6))); } } if (debouncer7.update()) { int value7 = debouncer7.read(); if(value7 == LOW){ saveState(7, !loadState(7)); digitalWrite(RELAY_7, loadState(7)?RELAY_ON:RELAY_OFF); send(msg7.set(loadState(7))); } } if (debouncer8.update()) { int value8 = debouncer8.read(); if(value8 == LOW){ saveState(8, !loadState(8)); digitalWrite(RELAY_8, loadState(8)?RELAY_ON:RELAY_OFF); send(msg8.set(loadState(8))); } } if (debouncer9.update()) { int value9 = debouncer9.read(); if(value9 == LOW){ saveState(9, !loadState(9)); digitalWrite(RELAY_9, loadState(9)?RELAY_ON:RELAY_OFF); send(msg9.set(loadState(9))); } } if (debouncer10.update()) { int value10 = debouncer10.read(); if(value10 == LOW){ saveState(10, !loadState(10)); digitalWrite(RELAY_10, loadState(10)?RELAY_ON:RELAY_OFF); send(msg10.set(loadState(10))); } } if (debouncer11.update()) { int value11 = debouncer11.read(); if(value11 == LOW){ saveState(11, !loadState(11)); digitalWrite(RELAY_11, loadState(11)?RELAY_ON:RELAY_OFF); send(msg11.set(loadState(11))); } } if (debouncer12.update()) { int value12 = debouncer12.read(); if(value12 == LOW){ saveState(12, !loadState(12)); digitalWrite(RELAY_12, loadState(12)?RELAY_ON:RELAY_OFF); send(msg12.set(loadState(12))); } } if (debouncer13.update()) { int value13 = debouncer13.read(); if(value13 == LOW){ saveState(13, !loadState(13)); digitalWrite(RELAY_13, loadState(13)?RELAY_ON:RELAY_OFF); send(msg13.set(loadState(13))); } } if (debouncer14.update()) { int value14 = debouncer14.read(); if(value14 == LOW){ saveState(14, !loadState(14)); digitalWrite(RELAY_14, loadState(14)?RELAY_ON:RELAY_OFF); send(msg14.set(loadState(14))); } } if (debouncer15.update()) { int value15 = debouncer15.read(); if(value15 == LOW){ saveState(15, !loadState(15)); digitalWrite(RELAY_15, loadState(15)?RELAY_ON:RELAY_OFF); send(msg15.set(loadState(15))); } } if (debouncer16.update()) { int value16 = debouncer16.read(); if(value16 == LOW){ saveState(16, !loadState(16)); digitalWrite(RELAY_16, loadState(16)?RELAY_ON:RELAY_OFF); send(msg16.set(loadState(16))); } } if (debouncer17.update()) { int value17 = debouncer17.read(); if(value17 == LOW){ saveState(17, !loadState(17)); digitalWrite(RELAY_17, loadState(17)?RELAY_ON:RELAY_OFF); send(msg17.set(loadState(17))); } } if (debouncer18.update()) { int value18 = debouncer18.read(); if(value18 == LOW){ saveState(18, !loadState(18)); digitalWrite(RELAY_18, loadState(18)?RELAY_ON:RELAY_OFF); send(msg18.set(loadState(18))); } } if (debouncer19.update()) { int value19 = debouncer19.read(); if(value19 == LOW){ saveState(19, !loadState(19)); digitalWrite(RELAY_19, loadState(19)?RELAY_ON:RELAY_OFF); send(msg19.set(loadState(19))); } } if (debouncer20.update()) { int value20 = debouncer20.read(); if(value20 == LOW){ saveState(20, !loadState(20)); digitalWrite(RELAY_20, loadState(20)?RELAY_ON:RELAY_OFF); send(msg20.set(loadState(20))); } } if (debouncer21.update()) { int value21 = debouncer21.read(); if(value21 == LOW){ saveState(21, !loadState(21)); digitalWrite(RELAY_21, loadState(21)?RELAY_ON:RELAY_OFF); send(msg21.set(loadState(21))); } } if (debouncer22.update()) { int value22 = debouncer22.read(); if(value22 == LOW){ saveState(22, !loadState(22)); digitalWrite(RELAY_22, loadState(22)?RELAY_ON:RELAY_OFF); send(msg22.set(loadState(22))); } } if (debouncer23.update()) { int value23 = debouncer23.read(); if(value23 == LOW){ saveState(23, !loadState(23)); digitalWrite(RELAY_23, loadState(23)?RELAY_ON:RELAY_OFF); send(msg23.set(loadState(23))); } } if (debouncer24.update()) { int value24 = debouncer24.read(); if(value24 == LOW){ saveState(24, !loadState(24)); digitalWrite(RELAY_24, loadState(24)?RELAY_ON:RELAY_OFF); send(msg24.set(loadState(24))); } } if (debouncer25.update()) { int value25 = debouncer25.read(); if(value25 == LOW){ saveState(25, !loadState(25)); digitalWrite(RELAY_25, loadState(25)?RELAY_ON:RELAY_OFF); send(msg25.set(loadState(25))); } } if (debouncer26.update()) { int value26 = debouncer26.read(); if(value26 == LOW){ saveState(26, !loadState(26)); digitalWrite(RELAY_26, loadState(26)?RELAY_ON:RELAY_OFF); send(msg26.set(loadState(26))); } } if (debouncer27.update()) { int value27 = debouncer27.read(); if(value27 == LOW){ saveState(27, !loadState(27)); digitalWrite(RELAY_27, loadState(27)?RELAY_ON:RELAY_OFF); send(msg27.set(loadState(27))); } } if (debouncer28.update()) { int value28 = debouncer28.read(); if(value28 == LOW){ saveState(28, !loadState(28)); digitalWrite(RELAY_28, loadState(28)?RELAY_ON:RELAY_OFF); send(msg28.set(loadState(28))); } } if (debouncer29.update()) { int value29 = debouncer29.read(); if(value29 == LOW){ saveState(29, !loadState(29)); digitalWrite(RELAY_29, loadState(29)?RELAY_ON:RELAY_OFF); send(msg29.set(loadState(29))); } } if (debouncer30.update()) { int value30 = debouncer30.read(); if(value30 == LOW){ saveState(30, !loadState(30)); digitalWrite(RELAY_30, loadState(30)?RELAY_ON:RELAY_OFF); send(msg30.set(loadState(30))); } } if (debouncer31.update()) { int value31 = debouncer31.read(); if(value31 == LOW){ saveState(31, !loadState(31)); digitalWrite(RELAY_31, loadState(31)?RELAY_ON:RELAY_OFF); send(msg31.set(loadState(31))); } } if (debouncer32.update()) { int value32 = debouncer32.read(); if(value32 == LOW){ saveState(32, !loadState(32)); digitalWrite(RELAY_32, loadState(32)?RELAY_ON:RELAY_OFF); send(msg32.set(loadState(32))); } } } void receive(const MyMessage &message) { // Oczekujemy tylko jednego rodzaju wiadomosci od kontrolera. Ale i tak lepiej to sprawdzimy. if (message.type==V_LIGHT) { // Zmien stan przekaznika digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF); // Przechowuj stan w eeprom saveState(message.sensor, message.getBool()); // Napisz informacje o debugowaniu Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); } }
Powyżej znajduje się wersja wsadu do obsługiwania 32 przekaźników, czyli maksimum jakie można wycisnąć z arduino mega. Wersja ta działała mi pod domoticzem bezproblemowo, fizycznie z przycisków, programowo z domoticza oraz poprawnie zmieniała stany w domoticzu. W HA dodaję kolejne przyciski poprzez "uczenie" tj. zwieram przyciski i dodaję encję już z odpowiednią nazwą. Do pewnego momentu wszystko działa dobrze, tzn. po wciśnieciu fizycznie przycisku lub po włączeniu przez HA światło się zapala/gasi, a stan w HA się zmienia. Niestety po nauczeniu kolejnego (nie sprawdziłem po którym już powstaje problem) przestają się aktualizować stany w HA. Tzn. w momencie "uczenia" miałem zapalone światło tylko w wiatrołapie i jadalni i te stany pozostały na on, a reszta pozostała na off. Światło idzie zgasić/zapalić z poziomu fizycznych przełączników (przełączniki dzwonkowe) oraz z poziomu HA, ale stany pozostają "sztywne" z dnia uczenia. W jadalni i wiatrołapie jeżeli chcę zapalić światło to muszę kliknąć dwa razy tzn. wyłączyć "włączony" przełącznik i zaraz po tym szybko włączyć. To samo tyczy się reszty na stałe "wyłączonych" obwodów. Żeby zgasić muszę na chwilę włączyć zapalone już światło i zaraz zgasić, aby zdążyć przed nadpisaniem sztywnego stanu. Na chwilę obecną da się z tym żyć, ale jakakolwiek automatyzacja nie jest możliwa. W domoticz wszystko działało bezproblemowo, ale z tego co kojarzę to nie musiałem dodawać kolejnych obwodów poprzez uczenie, ale miałem już je dostępne z poziomu urządzenia. W HA nie umiem dodać ich w inny sposób niż poprzez "uczenie".