Problem with multiple relays and delays
-
Hi, I am building shutters controler.
My motorized shutters are very basics. There are 3 cables for each motors.
One hot for the ascend the second hot for descent and the neutral.To automate shutters I have an opening delay.
When I command the opening, the relay is operated until the opening delay is ended.This works well when I command one shutter. But in this room there are 3 shutters on the same sensors node.
When I use several shutters at the same time there is problems (it seems like delays were added together ).
Some relays are activated during too much time.Should i use some kind of threads for each shutter?
Cheers
/* =============================================================== Project: Store Test Author: Lucas van Rossum Created: 14/02/2016 Arduino IDE: 1.7.8 ================================================================== */ #include <MySensor.h> #include <SPI.h> #include <Bounce2.h> #define RELAY_ON 0 #define RELAY_OFF 1 // relay shutter pin #define RELAY_UP1 2 #define RELAY_DWN1 3 #define RELAY_UP2 4 #define RELAY_DWN2 5 #define RELAY_UP3 6 #define RELAY_DWN3 7 //button pin #define BUTUP1 8 #define BUTDWN1 A5 #define BUTUP2 A4 #define BUTDWN2 A6 #define BUTUP3 A7 #define BUTDWN3 A0 //switch door pin #define DOORSWITCH1 A3 #define DOORSWITCH2 A2 // CHILD ID #define CHILD_ID_STORE1 1 #define CHILD_ID_STORE2 2 #define CHILD_ID_STORE3 3 #define CHILD_ID_WINDOWS1 4 #define CHILD_ID_WINDOWS2 5 //Secure delay int securedelay=0; //openclose delay int ouverturedelay=10000; // to store button value int ValBUTUP1=0; int ValBUTDWN1=0; int ValBUTUP2=0; int ValBUTDWN2=0; int ValBUTUP3=0; int ValBUTDWN3=0; //to store last shutter action int oldActionA=0; int oldActionB=0; int oldActionC=0; bool state; //// Construct MySensors library MySensor gw; MyMessage msgAUp(CHILD_ID_STORE1,V_UP); MyMessage msgADwn(CHILD_ID_STORE1,V_DOWN); MyMessage msgAStp(CHILD_ID_STORE1,V_STOP); MyMessage msgApor(CHILD_ID_STORE1,V_PERCENTAGE); MyMessage msgBUp(CHILD_ID_STORE2,V_UP); MyMessage msgBDwn(CHILD_ID_STORE2,V_DOWN); MyMessage msgBStp(CHILD_ID_STORE2,V_STOP); MyMessage msgBpor(CHILD_ID_STORE2,V_PERCENTAGE); MyMessage msgCUp(CHILD_ID_STORE3,V_UP); MyMessage msgCDwn(CHILD_ID_STORE3,V_DOWN); MyMessage msgCStp(CHILD_ID_STORE3,V_STOP); MyMessage msgCpor(CHILD_ID_STORE3,V_PERCENTAGE); //switch Bounce debouncer1 = Bounce(); Bounce debouncer2 = Bounce(); int oldValDOORSWITCH1=-1; int oldValDOORSWITCH2=-1; MyMessage msgSWITCH1(CHILD_ID_WINDOWS1,V_TRIPPED); MyMessage msgSWITCH2(CHILD_ID_WINDOWS2,V_TRIPPED); void setup(){ // Initialize library and add callback for incoming messages gw.begin(incomingMessage, AUTO, true); // Send the sketch version information to the gateway and Controller gw.sendSketchInfo("Store_Salon ", "1.0"); // Register all sensors to gw (they will be created as child devices) gw.present(CHILD_ID_STORE1, S_COVER); gw.present(CHILD_ID_STORE2, S_COVER); gw.present(CHILD_ID_STORE3, S_COVER); gw.present(CHILD_ID_WINDOWS1, S_BINARY); gw.present(CHILD_ID_WINDOWS2, S_BINARY); //Setup all the Arduino Pins //relay pinMode(RELAY_UP1, OUTPUT); pinMode(RELAY_DWN1, OUTPUT); pinMode(RELAY_UP2, OUTPUT); pinMode(RELAY_DWN2, OUTPUT); pinMode(RELAY_UP3, OUTPUT); pinMode(RELAY_DWN3, OUTPUT); //switch pinMode(DOORSWITCH1,INPUT); pinMode(DOORSWITCH2,INPUT); // pullup digitalWrite(DOORSWITCH1,HIGH); digitalWrite(DOORSWITCH2,HIGH); debouncer1.attach(DOORSWITCH1); debouncer2.attach(DOORSWITCH2); debouncer1.interval(5); debouncer2.interval(5); //Turn OFF any power to the Relay channels digitalWrite(RELAY_UP1,RELAY_OFF); digitalWrite(RELAY_DWN1,RELAY_OFF); digitalWrite(RELAY_UP2,RELAY_OFF); digitalWrite(RELAY_DWN2,RELAY_OFF); digitalWrite(RELAY_UP3,RELAY_OFF); digitalWrite(RELAY_DWN3,RELAY_OFF); pinMode(BUTUP1, INPUT); pinMode(BUTDWN1, INPUT); pinMode(BUTUP2, INPUT); pinMode(BUTDWN2, INPUT); pinMode(BUTUP3, INPUT); pinMode(BUTDWN3, INPUT); // pullup digitalWrite(BUTUP1,HIGH); digitalWrite(BUTDWN1,HIGH); digitalWrite(BUTUP2,HIGH); //digitalWrite(BUTDWN2,HIGH); only analog A6 //digitalWrite(BUTUP3,HIGH); only analog A7 digitalWrite(BUTDWN3,HIGH); } void loop(){ // Alway process incoming messages whenever possible gw.process(); //Get buton value ValBUTUP1 = digitalRead(BUTUP1); ValBUTDWN1 = digitalRead(BUTDWN1); ValBUTUP2 = digitalRead(BUTUP2); ValBUTDWN2 = analogRead(BUTDWN2) < 500 ? LOW : HIGH; ValBUTUP3 = analogRead(BUTUP3) < 500 ? LOW : HIGH; ValBUTDWN3 = digitalRead(BUTDWN3); //Get Magnetic Door Switch Sensor debouncer1.update(); // Get the update value int value1 = debouncer1.read(); if (value1 != oldValDOORSWITCH1) { // Send in the new value gw.send(msgSWITCH1.set(value1==HIGH ? 1 : 0)); oldValDOORSWITCH1 = value1; } debouncer2.update(); // Get the update value int value2 = debouncer2.read(); if (value2 != oldValDOORSWITCH2) { // Send in the new value gw.send(msgSWITCH2.set(value2==HIGH ? 1 : 0)); oldValDOORSWITCH2 = value2; } ////////// button //shutter1 //UP if (ValBUTUP1 == LOW && ValBUTDWN1 == HIGH ){ int action=1; //action: 1 up,2 down, 0 stop if (action!=oldActionA) { //if (oldAction==2){ digitalWrite(RELAY_DWN1, RELAY_OFF); digitalWrite(RELAY_UP1, RELAY_OFF); gw.wait(securedelay);//} Serial.print(", up relay1 "); digitalWrite(RELAY_UP1,RELAY_ON); digitalWrite(RELAY_DWN1,RELAY_OFF); gw.send(msgAUp.set(1), false);} // back to domoticz oldActionA=action;} //DOWN if (ValBUTDWN1 == LOW && ValBUTUP1 == HIGH ){ int action=2; //1 monté,2descente, 0stop if (action!=oldActionA) { //if (oldAction==1){ digitalWrite(RELAY_DWN1, RELAY_OFF); digitalWrite(RELAY_UP1, RELAY_OFF); gw.wait(securedelay);//} Serial.print(", down relay1 "); digitalWrite(RELAY_DWN1,RELAY_ON); digitalWrite(RELAY_UP1,RELAY_OFF); gw.send(msgADwn.set(1), false);} // back to domoticz oldActionA=action; } //OFF if (ValBUTDWN1 == HIGH && ValBUTUP1 == HIGH ){ int action=0; //action: 1 up,2 down, 0 stop if (action!=oldActionA){ Serial.print(", none "); digitalWrite(RELAY_UP1,RELAY_OFF); digitalWrite(RELAY_DWN1,RELAY_OFF); gw.send(msgAStp.set(1), false);} // back to domoticz oldActionA=action; } if (ValBUTDWN1 == LOW && ValBUTUP1 == LOW ){ int action=0; //action: 1 up,2 down, 0 stop if (action!=oldActionA){ Serial.print(", none "); digitalWrite(RELAY_UP1,RELAY_OFF); digitalWrite(RELAY_DWN1,RELAY_OFF); gw.send(msgAStp.set(1), false);} // back to domoticz oldActionA=action; } //shutter2 //UP if (ValBUTUP2 == LOW && ValBUTDWN2 == HIGH ){ int action=1; //action: 1 up,2 down, 0 stop if (action!=oldActionB) { //if (oldAction==2){ digitalWrite(RELAY_DWN2, RELAY_OFF); digitalWrite(RELAY_UP2, RELAY_OFF); gw.wait(securedelay);//} Serial.print(", up relay2 "); digitalWrite(RELAY_UP2,RELAY_ON); digitalWrite(RELAY_DWN2,RELAY_OFF); gw.send(msgBUp.set(1), false);} // back to domoticz oldActionB=action;} //DOWN if (ValBUTDWN2 == LOW && ValBUTUP2 == HIGH ){ int action=2; //action: 1 up,2 down, 0 stop if (action!=oldActionB) { //if (oldAction==1){ digitalWrite(RELAY_DWN2, RELAY_OFF); digitalWrite(RELAY_UP2, RELAY_OFF); gw.wait(securedelay);//} Serial.print(", down relay2 "); digitalWrite(RELAY_DWN2,RELAY_ON); digitalWrite(RELAY_UP2,RELAY_OFF); gw.send(msgBDwn.set(1), false);} // back to domoticz oldActionB=action; } //OFF if (ValBUTDWN2 == HIGH && ValBUTUP2 == HIGH ){ int action=0; //1 monté,2descente, 0stop if (action!=oldActionB){ Serial.print(", stop Stor2 2b "); digitalWrite(RELAY_UP2,RELAY_OFF); digitalWrite(RELAY_DWN2,RELAY_OFF); gw.send(msgBStp.set(1), false);} // back to domoticz oldActionB=action; } if (ValBUTDWN2 == LOW && ValBUTUP2 == LOW ){ int action=0; //action: 1 up,2 down, 0 stop if (action!=oldActionB){ Serial.print(", stop Stor2 0b "); digitalWrite(RELAY_UP2,RELAY_OFF); digitalWrite(RELAY_DWN2,RELAY_OFF); gw.send(msgBStp.set(1), false);} // back to domoticz oldActionB=action; } //shutter3 //UP if (ValBUTUP3 == LOW && ValBUTDWN3 == HIGH ){ int action=1; //action: 1 up,2 down, 0 stop if (action!=oldActionC) { //if (oldAction==2){ digitalWrite(RELAY_DWN3, RELAY_OFF); digitalWrite(RELAY_UP3, RELAY_OFF); gw.wait(securedelay);//} Serial.print(", up relay3 "); digitalWrite(RELAY_UP3,RELAY_ON); digitalWrite(RELAY_DWN3,RELAY_OFF); gw.send(msgCUp.set(1), false);} // back to domoticz oldActionC=action;} //DOWN if (ValBUTDWN3 == LOW && ValBUTUP3 == HIGH ){ int action=2; //action: 1 up,2 down, 0 stop if (action!=oldActionC) { //if (oldAction==1){ digitalWrite(RELAY_DWN3, RELAY_OFF); digitalWrite(RELAY_UP3, RELAY_OFF); gw.wait(securedelay);//} Serial.print(", down relay3 "); digitalWrite(RELAY_DWN3,RELAY_ON); digitalWrite(RELAY_UP3,RELAY_OFF); gw.send(msgCDwn.set(1), false);} // back to domoticz oldActionC=action; } //OFF if (ValBUTDWN3 == HIGH && ValBUTUP3 == HIGH ){ int action=0; //action: 1 up,2 down, 0 stop if (action!=oldActionC){ Serial.print(", none "); digitalWrite(RELAY_UP3,RELAY_OFF); digitalWrite(RELAY_DWN3,RELAY_OFF); gw.send(msgCStp.set(1), false);} //back to domoticz oldActionC=action; } if (ValBUTDWN3 == LOW && ValBUTUP3 == LOW ){ int action=0; //action: 1 up,2 down, 0 stop if (action!=oldActionC){ Serial.print(", none "); digitalWrite(RELAY_UP3,RELAY_OFF); digitalWrite(RELAY_DWN3,RELAY_OFF); gw.send(msgCStp.set(1), false);} //back to domoticz oldActionC=action; } } void incomingMessage(const MyMessage &message) { // Write some debug info Serial.println("[incomingMessage]"); Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print("messagetype"); Serial.print(message.type); Serial.print(", New status: "); Serial.println(message.getBool()); // shutter1 if (message.sensor ==1){ if (message.type == 29) { // open shutter state = message.getBool(); if(state == 0){ digitalWrite(RELAY_DWN1, RELAY_OFF); digitalWrite(RELAY_UP1, RELAY_OFF); gw.wait(securedelay); digitalWrite(RELAY_UP1, RELAY_ON); digitalWrite(RELAY_DWN1, RELAY_OFF); gw.wait(ouverturedelay); digitalWrite(RELAY_DWN1, RELAY_OFF); digitalWrite(RELAY_UP1, RELAY_OFF); } } if (message.type == 30) { // close shutter state = message.getBool(); if(state == 0){ digitalWrite(RELAY_DWN1, RELAY_OFF); digitalWrite(RELAY_UP1, RELAY_OFF); gw.wait(securedelay); digitalWrite(RELAY_DWN1, RELAY_ON); digitalWrite(RELAY_UP1, RELAY_OFF); gw.wait(ouverturedelay); digitalWrite(RELAY_DWN1, RELAY_OFF); digitalWrite(RELAY_UP1, RELAY_OFF); } } if (message.type == 31) { // stop shutter state = message.getBool(); if(state == 0){ digitalWrite(RELAY_DWN1, RELAY_OFF); digitalWrite(RELAY_UP1, RELAY_OFF); } } } // shutter2 if (message.sensor ==2){ if (message.type == 29) { // open shutter state = message.getBool(); if(state == 0){ digitalWrite(RELAY_DWN2, RELAY_OFF); digitalWrite(RELAY_UP2, RELAY_OFF); gw.wait(securedelay); digitalWrite(RELAY_UP2, RELAY_ON); digitalWrite(RELAY_DWN2, RELAY_OFF); gw.wait(ouverturedelay); digitalWrite(RELAY_DWN2, RELAY_OFF); digitalWrite(RELAY_UP2, RELAY_OFF); } } if (message.type == 30) { // close shutter state = message.getBool(); if(state == 0){ digitalWrite(RELAY_DWN2, RELAY_OFF); digitalWrite(RELAY_UP2, RELAY_OFF); gw.wait(securedelay); digitalWrite(RELAY_DWN2, RELAY_ON); digitalWrite(RELAY_UP2, RELAY_OFF); gw.wait(ouverturedelay); digitalWrite(RELAY_DWN2, RELAY_OFF); digitalWrite(RELAY_UP2, RELAY_OFF); } } if (message.type == 31) { // stop shutter state = message.getBool(); if(state == 0){ digitalWrite(RELAY_DWN2, RELAY_OFF); digitalWrite(RELAY_UP2, RELAY_OFF); } } } // shutter3 if (message.sensor ==3){ if (message.type == 29) { // open shutter state = message.getBool(); if(state == 0){ digitalWrite(RELAY_DWN3, RELAY_OFF); digitalWrite(RELAY_UP3, RELAY_OFF); gw.wait(securedelay); digitalWrite(RELAY_UP3, RELAY_ON); digitalWrite(RELAY_DWN3, RELAY_OFF); gw.wait(ouverturedelay); digitalWrite(RELAY_DWN3, RELAY_OFF); digitalWrite(RELAY_UP3, RELAY_OFF); } } if (message.type == 30) { // close shutter state = message.getBool(); if(state == 0){ digitalWrite(RELAY_DWN3, RELAY_OFF); digitalWrite(RELAY_UP3, RELAY_OFF); gw.wait(securedelay); digitalWrite(RELAY_DWN3, RELAY_ON); digitalWrite(RELAY_UP3, RELAY_OFF); gw.wait(ouverturedelay); digitalWrite(RELAY_DWN3, RELAY_OFF); digitalWrite(RELAY_UP3, RELAY_OFF); } } if (message.type == 31) { // stop shutter state = message.getBool(); if(state == 0){ digitalWrite(RELAY_DWN3, RELAY_OFF); digitalWrite(RELAY_UP3, RELAY_OFF); } } } }
-
hi.
It's maybe not the best section, hardware section is better...
you should use asynchronous coding, sort of "thread" if you prefer. you could use millis, timer, and "if" statement for this..here your code is using gw.wait but it's blocking if you want to use multiple relays at same time.
For learning : https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
or use this lib : https://github.com/marvinroger/arduino-shutters
and create multiple shutters objects for your shutters if there are on same node. I don't know what you will get for memory usage but if you have not too much shutters by node that should work I guess..
-
Thank you that's exactly what i am looking for!
-
Hi, I'm very intersted in your project, because the mine is the same. I have 12 shutters ton control with an arduino Mega.
I 've read marvinroger's sketch, but how to make the link with the relays ?
I did not see where/how to do that.@Lucas-van-rossum Would you mind sharing the progress of your work, so I can progress too ?
-
@Poupoune1974 no problems, i will post my progress here...
-
@Lucas-van-rossum
Hi,
I had a similar challenge with my rollershutters and I think most standard ones do exactly the same, they have one neutral pin and two for the directions (up, down). I started a few months ago building the first prototype which was controlled via WIFI and worked very well. I did not find much examples and all was build up myself. However WIFI didn't seem to be the best and I did not want to pollute my wireless therefore I searched for alternatives which I found here. Still struggling with the stability of the sensor network but besides that I am very happy with my solution.
I also thought that I need to build an intelligent device which drives the shutters up, down and to intermediate positions. Played a lot with timers and stuff and eventually found the arduino-shutters of marvinroger with which I wasted another few days until I gave up and found out the code does not work for me - at least the latest version. Someone (I guess it was you) pointed out that earlier release seems to be working.
By the time I decided, that I do not want any intelligence in my hardware and instead put the logic into the controller (I am using openhab). There it is quite easy to work with threads and move one down for 20 sec and then stop. It even shows me the position where it is when driving from the physical buttons. Another point which played a role, my shutters need different time for up and down (up mostly 54sec, down 50) and I do have various variations. some of the rollos only take 35 sec and my automated windows even just 25 sec for a full cycle. And instead of making the code more complicated and potentially send an update or setup parameter via the air to the note, I maintain it centrally in the controller.I have build shutter controllers for 1, 2 and 3 shutters on one board and all have the same logic.
I do need to have full control via the physical buttons all the time. So when the controller decides to send them down and I do not want, I can go to the swich and stop it immediately. So basically, my logic is checking the pysical state of the swiches and what is sent from contoller and whatever is latest wins.
I also thought maybe I should implement a possibility to block the controller from activation and overrule it by e.g. having the physical button pressed in but then I did not want to have them all the time in neutral or blocking the controller activation.
Anyhow, my code is based on the relay example. It needs some cleanup for the physical button evaluations but I was too lazy to do this as most of my shutters are single nodes anyway and I have only 2 with 2 shutters on one board and 1 with 3. So for the moment there is some spaghettiy code.
I am not working with timers, delays etc. in order to find the end spots, the shutters stop anyway at their end if properly installed and the physical buttons do not do anything differently - so why bother? I only have delays of 200ms when going from up to down etc. So basically before I trigger the relay for "down" I disable the one for "up" wait for 200ms and then trigger "down" just making sure there will never be power on both directions to save my motors.
And finally, in order to "save" my relays I trigger from my controller a "stop" every now and then to all shutters in the house. In worst case, it might interfere with one rule but I can live with that.Here is the code based on mysensors for a node with 6 relays for 3 rollershutters attached to physical buttons:
/** The MySensors Arduino library handles the wireless radio link and protocol between your home built sensors/actuators and HA controller of choice. The sensors forms a self healing radio network with optional repeaters. Each repeater and gateway builds a routing tables in EEPROM which keeps track of the network topology allowing messages to be routed to nodes. Created by Henrik Ekblad <henrik.ekblad@mysensors.org> Copyright (C) 2013-2015 Sensnology AB Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors Documentation: http://www.mysensors.org Support Forum: http://forum.mysensors.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. ******************************* REVISION HISTORY Version 1.0 - Henrik Ekblad DESCRIPTION Example sketch showing how to control physical relays. This example will remember relay state after power failure. http://www.mysensors.org/build/relay */ #include <MySigningNone.h> #include <MyTransportNRF24.h> #include <MyTransportRFM69.h> #include <MyHwATMega328.h> #include <MySensor.h> #include <SPI.h> #define RELAY_1 3 // Arduino Digital I/O pin number for first relay (second on pin+1 etc) #define NUMBER_OF_RELAYS 6 // Total number of attached relays #define RELAY_ON 1 // GPIO value to write to turn on attached relay #define RELAY_OFF 0 // GPIO value to write to turn off attached relay MyMessage sensorMsg0(0, V_DIMMER); MyMessage sensorMsg1(1, V_DIMMER); MyMessage sensorMsg2(2, V_DIMMER); static int currentLevel0 = 0; // Current dim level... static int currentLevel1 = 0; // Current dim level... int upPin0 = 14; // choose the input pin (for a up) int downPin0 = 15; // choose the input pin (for a down) int motorUp0 = 0; // variable for reading the pin status int motorDown0 = 0; // variable for reading the pin status int upPin1 = 16; // choose the input pin (for a up) int downPin1 = 17; // choose the input pin (for a down) int motorUp1 = 0; // variable for reading the pin status int motorDown1 = 0; // variable for reading the pin status int upPin2 = 18; // choose the input pin (for a up) int downPin2 = 19; // choose the input pin (for a down) int motorUp2 = 0; // variable for reading the pin status int motorDown2 = 0; // variable for reading the pin status int switchState0 = 0; //0=off, 1=up, 2=down int tempSwitchState0 = 0; //0=off, 1=up, 2=down int rUnitPos0 = 0; int switchState1 = 0; //0=off, 1=up, 2=down int tempSwitchState1 = 0; //0=off, 1=up, 2=down int rUnitPos1 = 0; int switchState2 = 0; //0=off, 1=up, 2=down int tempSwitchState2 = 0; //0=off, 1=up, 2=down int rUnitPos2 = 0; // NRFRF24L01 radio driver (set low transmit power by default) MyTransportNRF24 radio(RF24_CE_PIN, RF24_CS_PIN, RF24_PA_LEVEL_GW); //MyTransportRFM69 radio; // Message signing driver (none default) //MySigningNone signer; // Select AtMega328 hardware profile MyHwATMega328 hw; // Construct MySensors library MySensor gw(radio, hw); void shuttersUp(int shutter) { if (shutter == 0) { Serial.println("A Shutter 0 going up."); digitalWrite (RELAY_1 + 1, LOW); delay(100); digitalWrite (RELAY_1, HIGH); gw.send( sensorMsg0.set(0) ); } else if (shutter == 1){ Serial.println("A Shutter 1 going up."); digitalWrite (RELAY_1 + 3, LOW); delay(100); digitalWrite (RELAY_1 + 2, HIGH); gw.send( sensorMsg1.set(0) ); } else if (shutter == 2){ Serial.println("A Shutter 2 going up."); digitalWrite (RELAY_1 + 5, LOW); delay(100); digitalWrite (RELAY_1 + 4, HIGH); gw.send( sensorMsg2.set(0) ); } } void shuttersDown(int shutter) { if (shutter == 0) { Serial.println("A Shutter 0 going down."); digitalWrite (RELAY_1, LOW); delay(100); digitalWrite (RELAY_1 + 1, HIGH); gw.send( sensorMsg0.set(100) ); } else if (shutter == 1){ Serial.println("A Shutter 1 going down."); digitalWrite (RELAY_1 + 2, LOW); delay(100); digitalWrite (RELAY_1 + 3, HIGH); gw.send( sensorMsg1.set(100) ); } else if (shutter == 2){ Serial.println("A Shutter 2 going down."); digitalWrite (RELAY_1 + 4, LOW); delay(100); digitalWrite (RELAY_1 + 5, HIGH); gw.send( sensorMsg2.set(100) ); } } void shuttersStop(int shutter) { if (shutter == 0) { Serial.println("A Shutter 0 halted."); digitalWrite (RELAY_1, LOW); digitalWrite (RELAY_1 + 1, LOW); } else if (shutter == 1){ Serial.println("A Shutter 1 halted."); digitalWrite (RELAY_1 + 2, LOW); digitalWrite (RELAY_1 + 3, LOW); } else if (shutter == 2){ Serial.println("A Shutter 2 halted."); digitalWrite (RELAY_1 + 4, LOW); digitalWrite (RELAY_1 + 5, LOW); } } void setup() { pinMode(upPin0, INPUT); // declare pushbutton as input pinMode(downPin0, INPUT); // declare pushbutton as input pinMode(upPin1, INPUT); // declare pushbutton as input pinMode(downPin1, INPUT); // declare pushbutton as input pinMode(upPin2, INPUT); // declare pushbutton as input pinMode(downPin2, INPUT); // declare pushbutton as input // Initialize library and add callback for incoming messages gw.begin(incomingMessage, AUTO, true); // Send the sketch version information to the gateway and Controller gw.sendSketchInfo("RollerShutter Atrium", "1.0"); // Fetch relay status for (int sensor = 1, pin = RELAY_1; sensor <= NUMBER_OF_RELAYS; sensor++, pin++) { // Register all sensors to gw (they will be created as child devices) gw.present(sensor, S_COVER); // Then set relay pins in output mode pinMode(pin, OUTPUT); } } void loop() { // Alway process incoming messages whenever possible gw.process(); motorUp0 = digitalRead(upPin0); // read input value motorDown0 = digitalRead(downPin0); // read input value //relay 2 motorUp1 = digitalRead(upPin1); // read input value motorDown1 = digitalRead(downPin1); // read input value motorUp2 = digitalRead(upPin2); // read input value motorDown2 = digitalRead(downPin2); // read input value //evaluate switch positions // GROUP 0 if (motorUp0 == LOW && motorDown0 == HIGH) { switchState0 = 1; //Serial.println("SWITCH: " + String(switchState0)); //switch position } else if (motorDown0 == LOW && motorUp0 == HIGH) { switchState0 = 2; //Serial.println("SWITCH: " + String(switchState0)); //switch position } else if (motorDown0 == HIGH && motorUp0 == HIGH) { switchState0 = 0; //Serial.println("SWITCH: " + String(switchState0)); //switch position } // GROUP 1 if (motorUp1 == LOW && motorDown1 == HIGH) { switchState1 = 1; //Serial.println("SWITCH: " + String(switchState1)); //switch position } else if (motorDown1 == LOW && motorUp1 == HIGH) { switchState1 = 2; //Serial.println("SWITCH: " + String(switchState1)); //switch position } else if (motorDown1 == HIGH && motorUp1 == HIGH) { switchState1 = 0; //Serial.println("SWITCH: " + String(switchState1)); //switch position } // GROUP 2 if (motorUp2 == LOW && motorDown2 == HIGH) { switchState2 = 1; //Serial.println("SWITCH: " + String(switchState2)); //switch position } else if (motorDown2 == LOW && motorUp2 == HIGH) { switchState2 = 2; //Serial.println("SWITCH: " + String(switchState2)); //switch position } else if (motorDown2 == HIGH && motorUp2 == HIGH) { switchState2 = 0; //Serial.println("SWITCH: " + String(switchState2)); //switch position } //GROUP 0 if (tempSwitchState0 != switchState0) //man only needed in case of changed switch state { if (motorUp0 == LOW && rUnitPos0 != 1) //man up { switchState0 = 1; tempSwitchState0 = 1; delay(200); shuttersUp(0); rUnitPos0 = 1; Serial.println("//////////////man 0 up"); gw.send( sensorMsg0.set(0) ); } if (motorDown0 == LOW && rUnitPos0 != 2) // man down { switchState0 = 2; tempSwitchState0 = 2; delay(200); shuttersDown(0); rUnitPos0 = 2; Serial.println("//////////////man 0 down"); gw.send( sensorMsg0.set(100) ); } if (motorUp0 == HIGH && motorDown0 == HIGH && rUnitPos0 != 0) //man stopp { switchState0 = 0; tempSwitchState0 = 0; delay(200); shuttersStop(0); rUnitPos0 = 0; Serial.println("//////////////man 0 stopp"); } } //GROUP 1 if (tempSwitchState1 != switchState1) //man only needed in case of changed switch state { if (motorUp1 == LOW && rUnitPos1 != 1) //man up { switchState1 = 1; tempSwitchState1 = 1; shuttersUp(1); rUnitPos1 = 1; Serial.println("//////////////man 1 up"); gw.send( sensorMsg1.set(0) ); } if (motorDown1 == LOW && rUnitPos1 != 2) // man down { switchState1 = 2; tempSwitchState1 = 2; shuttersDown(1); rUnitPos1 = 2; Serial.println("//////////////man 1 down"); gw.send( sensorMsg1.set(100) ); } if (motorUp1 == HIGH && motorDown1 == HIGH && rUnitPos1 != 0) //man stopp { switchState1 = 0; tempSwitchState1 = 0; shuttersStop(1); rUnitPos1 = 0; Serial.println("//////////////man 1 stopp"); } } //GROUP 2 if (tempSwitchState2 != switchState2) //man only needed in case of changed switch state { if (motorUp2 == LOW && rUnitPos2 != 1) //man up { switchState2 = 1; tempSwitchState2 = 1; shuttersUp(2); rUnitPos2 = 1; Serial.println("//////////////man 2 up"); gw.send( sensorMsg2.set(0) ); } if (motorDown2 == LOW && rUnitPos2 != 2) // man down { switchState2 = 2; tempSwitchState2 = 2; shuttersDown(2); rUnitPos2 = 2; Serial.println("//////////////man 2 down"); gw.send( sensorMsg2.set(100) ); } if (motorUp2 == HIGH && motorDown2 == HIGH && rUnitPos2 != 0) //man stop { switchState2 = 0; tempSwitchState2 = 0; shuttersStop(2); rUnitPos2 = 0; Serial.println("//////////////man 2 stopp"); } } } void incomingMessage(const MyMessage &message) { // Let's check for the message type. if (message.type == V_DIMMER) { // Retrieve the power or dim level from the incoming request message int requestedLevel = atoi( message.data ); // Adjust incoming level if this is a V_LIGHT variable update [0 == off, 1 == on] requestedLevel *= ( message.type == V_LIGHT ? 100 : 1 ); // Clip incoming level to valid range of 0 to 100 requestedLevel = requestedLevel > 100 ? 100 : requestedLevel; requestedLevel = requestedLevel < 0 ? 0 : requestedLevel; Serial.print( "Changing level to " ); Serial.print( requestedLevel ); Serial.print( ", from " ); Serial.println("NodeID:" + String(message.sensor) + " " + currentLevel0 ); if (requestedLevel == 0) { // move up shuttersUp(message.sensor); } else if (requestedLevel == 100) { // move down shuttersDown(message.sensor); } else { // move percentage // Serial.println("currentLevel" + String(shutters.currentLevel())); Serial.println("move to desired postion"); //NOT IMPLEMENTED HERE } currentLevel0 = requestedLevel; } else if (message.type == V_UP) { shuttersUp(message.sensor); Serial.println("going up:" + String(message.type)); } else if (message.type == V_DOWN) { shuttersDown(message.sensor); Serial.println("going down:" + String(message.type)); } else if (message.type == V_STOP) { shuttersStop(message.sensor); Serial.println("stopping:" + String(message.type)); } else { Serial.println("wrong data received:" + String(message.type)); } }
Cheers
SJ
-
hi friends which works for 3 motorized shutters and how Arduino thank you
-
@zrom69 is this a question or statement?
-
I'm sorry for my English, I'm French
I try to control node 3 and motorized shutters which card must be used aduino thank you
-
@zrom69 no worries.
I am using arduino Nano but others will work too. The Nano is small enough and easy to program (it has USB). The Pro Mini is also a good option, but needs extra programer (it has only serial connectors).
I am using those and all work very well:
http://www.banggood.com/5Pcs-ATmega328P-Nano-V3-Controller-Board-For-Arduino-Improved-Version-p-951797.html
In addition you need the relays - you either could build that yourself or use ready to use ones:
http://www.banggood.com/5V-4-Channel-Relay-Module-For-Arduino-PIC-ARM-DSP-AVR-MSP430-Blue-p-87987.htmlIf you want to control shutters, you usually need 1 relay per direction. so for your 3 shutters it would be 6 relays. I am not sure if there are products out there, you could take one with 8 relays if you do have the space or make them yourself.
The code I posted above is "ready" for 3 shutters (up/down each) and manual control buttons on an Arduino Nano.
you need to connect the relays on digital pins 3/4 & 5/6 & 7/8 and the manual inputs on analog A0/A1, A2/A3, A4/A5 (note: pin 14 makes out of Analog A0, a digital D14)
Besides this, connect the radio and power and you should be ready to go.
-
Hi friends
thank you for your help I have try the code on Arduino pro mini touts the relay they work or even monument must change something in the code Arduino
I am newbie in Arduino
there is detection of door opening
thanks for the help
-
hi @parachutesj hi @all
i tried the sketch posted above. it works but my relay board is active low and the relays are on when they should be off. #define RELAY_ON 0 and #define RELAY_OFF 1 do not change the behavior. the relays stay on. do you have an idea what is happening? thx
-
@ihtgtwtd
change in the code in the routines shutters UP/DOWN/STOPthe parts
digitalWrite(RELAYxxx, HIGH);
HIGH to LOW and vice versa
SJ
-
thanks for the quick reply. I did what you suggested and the switches work the right way but when I reset the arduino all relay contacts turn on and stay on until I give a command. this is a major problem, it will destroy the shutter motor. i think there is no defined case when the arduino powers on.
-
@ihtgtwtd
put this into the setup routine within the "for"digitalWrite (pin, HIGH);
e.g. like this:
for (int sensor = 1, pin = RELAY_1; sensor <= NUMBER_OF_RELAYS; sensor++, pin++) { // Register all sensors to gw (they will be created as child devices) gw.present(sensor, S_COVER); // Then set relay pins in output mode pinMode(pin, OUTPUT); digitalWrite (pin, HIGH); }
-
@parachutesj
thank you very much. looks good now.