├── .gitignore ├── .vscode └── settings.json ├── AcControl ├── AcControl.ino ├── Docs │ └── 1469565493670-gree.pdf ├── Hvac │ └── Hvac.ino └── Library │ ├── Examples │ └── Test │ │ └── Test.ino │ ├── Tadiran.cpp │ └── Tadiran.h ├── BoilerSwitch └── BoilerSwitch.ino ├── Cover └── Cover.ino ├── LightSwitch └── LightSwitch.ino ├── README.md ├── RollerShutter └── RollerShutter.ino ├── Switch └── Switch.ino └── tempSensor └── tempSensor.ino /.gitignore: -------------------------------------------------------------------------------- 1 | .build/* 2 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | } -------------------------------------------------------------------------------- /AcControl/AcControl.ino: -------------------------------------------------------------------------------- 1 | // Enable debug prints to serial monitor 2 | #define MY_DEBUG 3 | 4 | // Enable and select radio type attached 5 | #define MY_RADIO_NRF24 6 | 7 | // #define MY_RF24_PA_LEVEL RF24_PA_HIGH 8 | // uncomment if we want to manually assign an ID 9 | //#define MY_NODE_ID 1 / 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #define SKETCH_NAME "AC Control" 17 | #define SKETCH_VER "1.0" 18 | #define CHILD_ID 1 // sensor Id of the sensor child 19 | #define PRESENT_MESSAGE "sensor for AC control" 20 | 21 | bool codeReady = false; 22 | const bool IS_ACK = false; //is to acknowlage 23 | IRsend irsend; 24 | Tadiran tadiran(MODE_auto, FAN_auto, 26, STATE_off); 25 | 26 | // MyMessage msgUp(CHILD_ID, V_UP); 27 | 28 | void receive(const MyMessage &message) { 29 | Serial.println("recieved incomming message"); 30 | switch (message.type) { 31 | case V_VAR1: 32 | Serial.print("Incoming change for CHILD_ID:"); 33 | Serial.print(message.sensor); 34 | Serial.print(", New status: V_VAR1, with payload: "); 35 | Serial.print(message.getInt()); 36 | tadiran.setTemeprature(message.getInt()); 37 | codeReady = true; 38 | break; 39 | case V_VAR2: 40 | Serial.print("Incoming change for CHILD_ID:"); 41 | Serial.print(message.sensor); 42 | Serial.print(", New status: V_VAR2, with payload: "); 43 | Serial.print(message.getInt()); 44 | tadiran.setMode(message.getInt()); 45 | codeReady = true; 46 | break; 47 | case V_VAR3: 48 | Serial.print("Incoming change for CHILD_ID:"); 49 | Serial.print(message.sensor); 50 | Serial.print(", New status: V_VAR3, with payload: "); 51 | Serial.print(message.getInt()); 52 | codeReady = true; 53 | break; 54 | case V_VAR4: 55 | Serial.print("Incoming change for CHILD_ID:"); 56 | Serial.print(message.sensor); 57 | Serial.print(", New status: V_VAR4, with payload: "); 58 | Serial.print(message.getBool()); 59 | if (message.getBool()) { 60 | tadiran.setState(STATE_on); 61 | } else { 62 | tadiran.setState(STATE_off); 63 | } 64 | codeReady = true; 65 | break; 66 | } 67 | Serial.println("exiting incoming message"); 68 | } 69 | 70 | void presentation() 71 | { 72 | // Send the sketch version information to the gateway and Controller 73 | sendSketchInfo(SKETCH_NAME, SKETCH_VER); 74 | // Register all sensors to gw (they will be created as child devices) 75 | present(CHILD_ID, S_CUSTOM, PRESENT_MESSAGE, IS_ACK); 76 | } 77 | 78 | void setup(void) 79 | { 80 | Serial.begin(115200); 81 | Serial.println("StartUP"); 82 | } 83 | 84 | void loop(void) { 85 | if (codeReady) { 86 | Serial.println("Sending code..."); 87 | irsend.sendRaw(tadiran.codes, TADIRAN_BUFFER_SIZE, 38); 88 | codeReady = false; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /AcControl/Docs/1469565493670-gree.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpressle/MySensors/b149d39c22c16c31accedcd456cfe262bc4a75de/AcControl/Docs/1469565493670-gree.pdf -------------------------------------------------------------------------------- /AcControl/Hvac/Hvac.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Documentation: http://www.mysensors.org 3 | * Support Forum: http://forum.mysensors.org 4 | */ 5 | 6 | // Enable debug prints to serial monitor 7 | //#define MY_DEBUG 8 | 9 | // Enable and select radio type attached 10 | #define MY_RADIO_NRF24 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | IRsend irsend; 20 | Tadiran hvac(MODE_cold, FAN_auto, 26, STATE_off); 21 | bool initial_state_sent = false; 22 | 23 | #define ONE_WIRE_BUS 2 // Pin where dallase sensor is connected 24 | //#define MAX_ATTACHED_DS18B20 1 25 | unsigned long SLEEP_TIME = 60000; // Sleep time between reads (in milliseconds) 1 minute 26 | OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) 27 | DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 28 | float lastTemperature; 29 | 30 | #define CHILD_ID_HVAC 0 // childId 31 | #define CHILD_ID_MODE 1 32 | #define CHILD_ID_SPEED 2 33 | #define CHILD_ID_SET_POINT 3 34 | 35 | MyMessage msgHVACSetPointC(CHILD_ID_HVAC, V_HVAC_SETPOINT_COOL); 36 | MyMessage msgHVACSpeed(CHILD_ID_HVAC, V_HVAC_SPEED); 37 | MyMessage msgHVACFlowState(CHILD_ID_HVAC, V_HVAC_FLOW_STATE); 38 | MyMessage msgHVACTemperature(CHILD_ID_HVAC, V_TEMP); 39 | 40 | /* 41 | * Include all the other Necessary code here. 42 | * The example code is limited to message exchange for mysensors 43 | * with the controller (ha). 44 | */ 45 | 46 | void sendState() { 47 | if (hvac.getState() == STATE_off) send(msgHVACFlowState.set("Off")); 48 | else if (hvac.getMode() == MODE_cold) send(msgHVACFlowState.set("CoolOn")); 49 | else send(msgHVACFlowState.set("HeatOn")); 50 | wait(50); 51 | if (hvac.getFan() == FAN_auto) send(msgHVACSpeed.set("Auto")); 52 | else if (hvac.getFan() == FAN_1) send(msgHVACSpeed.set("Min")); 53 | else if(hvac.getFan() == FAN_2) send(msgHVACSpeed.set("Normal")); 54 | else if(hvac.getFan() == FAN_3) send(msgHVACSpeed.set("Max")); 55 | wait(50); 56 | send(msgHVACSetPointC.set(hvac.getTemeprature())); 57 | } 58 | 59 | void processHVAC(){ 60 | #ifdef MY_DEBUG 61 | Serial.println("Sending code..."); 62 | #endif 63 | irsend.sendRaw(hvac.codes, TADIRAN_BUFFER_SIZE, 38); 64 | } 65 | 66 | void before() { 67 | sensors.begin(); 68 | } 69 | 70 | void presentation() 71 | { 72 | // Send the sketch version information to the gateway and Controller 73 | sendSketchInfo("HVAC", "1.0"); 74 | // Register all sensors to gw (they will be created as child devices) 75 | present(CHILD_ID_HVAC, S_HVAC, "Thermostat"); 76 | } 77 | 78 | void setup() { 79 | sensors.setWaitForConversion(false); 80 | int state = loadState(CHILD_ID_HVAC); 81 | #ifdef MY_DEBUG 82 | Serial.println("state is: "); 83 | Serial.println(state); 84 | #endif 85 | if (state != 0Xff) { 86 | hvac.setState(state); 87 | } 88 | state = loadState(CHILD_ID_MODE); 89 | if (state != 0Xff) { 90 | hvac.setMode(state); 91 | } 92 | state = loadState(CHILD_ID_SPEED); 93 | if (state != 0Xff) { 94 | hvac.setFan(state); 95 | } 96 | state = loadState(CHILD_ID_SET_POINT); 97 | if (state != 0Xff) { 98 | hvac.setTemeprature(state); 99 | } 100 | } 101 | 102 | void loop() { 103 | if (!initial_state_sent) { 104 | #ifdef MY_DEBUG 105 | Serial.println("Sending initial value"); 106 | #endif 107 | sendState(); 108 | initial_state_sent = true; 109 | } 110 | // Fetch temperatures from Dallas sensors 111 | sensors.requestTemperatures(); 112 | 113 | // query conversion time and sleep until conversion completed 114 | int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution()); 115 | // sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater) 116 | wait(conversionTime); 117 | 118 | // Read temperatures and send them to controller 119 | //for (int i=0; i(static_cast((getConfig().isMetric?sensors.getTempCByIndex(0):sensors.getTempFByIndex(0)) * 10.)) / 10.; 123 | //float temperature = 22.1; 124 | #ifdef MY_DEBUG 125 | Serial.println(temperature); 126 | #endif 127 | // Only send data if temperature has changed and no error 128 | if (lastTemperature != temperature && temperature != -127.00 && temperature != 85.00) { 129 | // Send in the new temperature 130 | send(msgHVACTemperature.set(temperature,1)); 131 | // Save new temperatures for next compare 132 | lastTemperature = temperature; 133 | } 134 | // } 135 | wait(SLEEP_TIME); 136 | } 137 | 138 | void receive(const MyMessage &message) { 139 | String recvData = message.data; 140 | recvData.trim(); 141 | switch (message.type) { 142 | case V_HVAC_FLOW_STATE: 143 | if(recvData.equalsIgnoreCase("coolon")){ 144 | hvac.setState(STATE_on); 145 | hvac.setMode(MODE_cold); 146 | processHVAC(); 147 | saveState(CHILD_ID_HVAC, STATE_on); 148 | saveState(CHILD_ID_MODE, MODE_cold); 149 | sendState(); 150 | } else if(recvData.equalsIgnoreCase("heaton")){ 151 | hvac.setState(STATE_on); 152 | hvac.setMode(MODE_heat); 153 | processHVAC(); 154 | saveState(CHILD_ID_HVAC, STATE_on); 155 | saveState(CHILD_ID_MODE, MODE_heat); 156 | sendState(); 157 | } else if(recvData.equalsIgnoreCase("off") && ( hvac.getState() == STATE_on ) ){ 158 | hvac.setState(STATE_off); 159 | processHVAC(); 160 | saveState(CHILD_ID_HVAC, STATE_off); 161 | sendState(); 162 | } 163 | break; 164 | case V_HVAC_SPEED: 165 | if (recvData.equalsIgnoreCase("auto")) hvac.setFan(FAN_auto); 166 | else if (recvData.equalsIgnoreCase("min")) hvac.setFan(FAN_1); 167 | else if (recvData.equalsIgnoreCase("normal")) hvac.setFan(FAN_2); 168 | else if (recvData.equalsIgnoreCase("max")) hvac.setFan(FAN_3); 169 | if (hvac.getState() == STATE_on) 170 | processHVAC(); 171 | saveState(CHILD_ID_SPEED, hvac.getFan()); 172 | sendState(); 173 | break; 174 | case V_HVAC_SETPOINT_COOL: 175 | int target_temp = message.getInt(); 176 | hvac.setTemeprature(target_temp); 177 | if (hvac.getState() == STATE_on) 178 | processHVAC(); 179 | saveState(CHILD_ID_SET_POINT, hvac.getTemeprature()); 180 | sendState(); 181 | break; 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /AcControl/Library/Examples/Test/Test.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | 6 | // the IR emitter object 7 | IRsend irsend; 8 | int incomingByte = 0; 9 | // A/C Settings 10 | int temperature = 26; 11 | int mode = MODE_auto; // 0-Auto | 1-Cold | 2-Dry | 3-Fan | 4-Heat 12 | int fanspeed = FAN_auto; //0-Auto | 1-Low | 2-Medium | 3-High 13 | //A/C Toggles 14 | boolean power = false; 15 | 16 | // the Tairan code generator object 17 | Tadiran tadiran(mode, fanspeed, temperature, STATE_off); 18 | 19 | void setup() 20 | { 21 | Serial.begin(115200); 22 | Serial.println("Commands: +/- Temperature | m - Mode | f - fanspeed | p - Power"); 23 | } 24 | 25 | void loop() { 26 | 27 | if (Serial.available() > 0) { 28 | //Serial.write(27); // ESC command 29 | //Serial.print("[2J"); 30 | // read the incoming byte: 31 | incomingByte = Serial.read(); 32 | 33 | // say what you got: 34 | Serial.print("Command: "); 35 | if(incomingByte == 43){ 36 | Serial.print("Temperature +"); 37 | if(temperature +1 <=30){ 38 | temperature++; 39 | } 40 | tadiran.setTemeprature(temperature); 41 | } 42 | if(incomingByte == 45){ 43 | Serial.print("Temperature -"); 44 | if(temperature -1 >=16){ 45 | temperature--; 46 | } 47 | tadiran.setTemeprature(temperature); 48 | } 49 | if(incomingByte == 109){ //mode 50 | Serial.print("Mode"); 51 | if(mode+1 <=4) { 52 | mode++; 53 | } else { 54 | mode=0; 55 | } 56 | tadiran.setMode(mode); 57 | } 58 | if(incomingByte == 102) { //fan 59 | Serial.print("Fan"); 60 | if(fanspeed+1 <=3) { 61 | fanspeed++; 62 | } else { 63 | fanspeed=0; 64 | } 65 | tadiran.setFan(fanspeed); 66 | } 67 | if(incomingByte == 112){ //power 68 | Serial.print("Power"); 69 | tadiran.setState(STATE_on); 70 | } 71 | Serial.println(""); 72 | 73 | tadiran.print(); 74 | 75 | Serial.println(""); 76 | Serial.println("Commands: +/- Temperature | m - Mode | f - fanspeed | p - Power"); 77 | irsend.sendRaw(tadiran.codes, TADIRAN_BUFFER_SIZE, 38); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /AcControl/Library/Tadiran.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Tadiran(gree) AC IR library - for remotes YAA1FB, FAA1FB1, YB1F2, YB1FA, YAG1FB 3 | * Version 1.00 July, 2016 4 | * Copyright 2016 dpressle 5 | * 6 | * Library to generate IR codes for a Tadiran air conditionner. 7 | * 8 | * Based on http://arduino.fisch.lu library 9 | */ 10 | 11 | #include "Tadiran.h" 12 | 13 | /** 14 | * set the given temperature and updates the codes 15 | * @param _value the new value [16..30] 16 | */ 17 | void Tadiran::setTemeprature(uint8_t _value) 18 | { 19 | temperature=_value; 20 | 21 | if (temperature & 8) codes[25]=CODE_high; 22 | else codes[25]=CODE_low; 23 | if (temperature & 4) codes[23]=CODE_high; 24 | else codes[23]=CODE_low; 25 | if (temperature & 2) codes[21]=CODE_high; 26 | else codes[21]=CODE_low; 27 | if (temperature & 1) codes[19]=CODE_high; 28 | else codes[19]=CODE_low; 29 | 30 | setChecksum(); 31 | } 32 | 33 | /** 34 | * set the given mode and updates the codes 35 | * @param _value the new mode {MODE_auto,MODE_cold,MODE_dry,MODE_fan,MODE_heat} 36 | */ 37 | void Tadiran::setMode(uint8_t _value) 38 | { 39 | mode=_value; 40 | 41 | if (mode & 4) codes[7]=CODE_high; 42 | else codes[7]=CODE_low; 43 | if (mode & 2) codes[5]=CODE_high; 44 | else codes[5]=CODE_low; 45 | if (mode & 1) codes[3]=CODE_high; 46 | else codes[3]=CODE_low; 47 | 48 | setChecksum(); 49 | } 50 | 51 | /** 52 | * set the given fan and updates the codes 53 | * @param _value the new fan speed {FAN_auto, FAN_1, FAN_2, FAN_3} 54 | */ 55 | void Tadiran::setFan(uint8_t _value) 56 | { 57 | fan=_value; 58 | 59 | if (fan & 2) codes[13]=CODE_high; 60 | else codes[13]=CODE_low; 61 | if (fan & 1) codes[11]=CODE_high; 62 | else codes[11]=CODE_low; 63 | 64 | setChecksum(); 65 | } 66 | 67 | /** 68 | * set the given state and updates the codes 69 | * @param _value the new state {STATE_on,STATE_off} 70 | */ 71 | void Tadiran::setState(uint8_t _value) 72 | { 73 | state=_value; 74 | 75 | if (state & 1) codes[9] = CODE_high; 76 | else codes[9] = CODE_low; 77 | 78 | setChecksum(); 79 | } 80 | 81 | uint8_t Tadiran::getTemeprature() 82 | { 83 | return temperature; 84 | } 85 | 86 | uint8_t Tadiran::getMode() 87 | { 88 | return mode; 89 | } 90 | 91 | uint8_t Tadiran::getState() 92 | { 93 | return state; 94 | } 95 | 96 | uint8_t Tadiran::getFan() 97 | { 98 | return fan; 99 | } 100 | 101 | /** 102 | * calculates the checksum and updates the codes 103 | */ 104 | void Tadiran::setChecksum() 105 | { 106 | // generate the checksum 107 | uint8_t crc = 0; 108 | 109 | //for(uint8_t b=0;b<1;b++) 110 | //{ 111 | uint8_t block = 0; 112 | for(uint8_t i=3;i<=17;i=i+2) 113 | { 114 | if(codes[i] > CODE_threshold) block++; 115 | if (i <= 15) block <<= 1; 116 | } 117 | 118 | uint8_t b1 = block; 119 | //Serial.print(b1, DEC); 120 | b1 = bitReverse(b1); 121 | //Serial.println(b1, DEC); 122 | b1 = b1 & 0x0F; 123 | //Serial.println(b1, DEC); 124 | //Serial.println(""); 125 | block = 0; 126 | for(uint8_t i=19;i<=33;i=i+2) 127 | { 128 | if(codes[i] > CODE_threshold) block++; 129 | if (i <= 31) block <<= 1; 130 | } 131 | 132 | uint8_t b2 = block; 133 | //Serial.println(b2, BIN); 134 | b2 = bitReverse(b2); 135 | //Serial.println(b2, BIN); 136 | b2 = b2 & 0x0F; 137 | //Serial.print(b2, DEC); 138 | //Serial.println(""); 139 | /* 140 | checksum function: 141 | ((byte(0) & 0x0F) + (byte(1) & 0x0F) + 142 | (byte(2) & 0x0F) + (byte(3) & 0x0F) + 143 | ((byte(5) & 0xF0) >> 4 ) + ((byte(6) & 0xF0) >> 4 ) + 144 | ((byte(7) & 0xF0) >> 4 ) + 10) & 0xF0 145 | 2 is for byte 2 with light on 146 | */ 147 | uint8_t bitSum = b1 + b2 + 2 + 10; 148 | //Serial.print(bitSum, DEC); 149 | //Serial.println(""); 150 | crc = bitSum & 0xF; 151 | //Serial.print(crc, DEC); 152 | //Serial.println(""); 153 | //crc = bitReverse(crc); 154 | //Serial.print(crc); 155 | //Serial.println(""); 156 | //} 157 | 158 | // if (crc & 128) codes[123]=CODE_high; 159 | // else codes[123]=CODE_low; 160 | // if (crc & 64) codes[125]=CODE_high; 161 | // else codes[125]=CODE_low; 162 | // if (crc & 32) codes[127]=CODE_high; 163 | // else codes[127]=CODE_low; 164 | // if (crc & 16) codes[129]=CODE_high; 165 | // else codes[129]=CODE_low; 166 | if (crc & 1) codes[131]=CODE_high; 167 | else codes[131]=CODE_low; 168 | if (crc & 2) codes[133]=CODE_high; 169 | else codes[133]=CODE_low; 170 | if (crc & 4) codes[135]=CODE_high; 171 | else codes[135]=CODE_low; 172 | if (crc & 8) codes[137]=CODE_high; 173 | else codes[137]=CODE_low; 174 | } 175 | 176 | /** 177 | 178 | **/ 179 | uint8_t Tadiran::bitReverse(uint8_t _value) 180 | { 181 | _value = ((_value >> 1) & 0x55) | ((_value << 1) & 0xaa); 182 | _value = ((_value >> 2) & 0x33) | ((_value << 2) & 0xcc); 183 | _value = ((_value >> 4) & 0x0f) | ((_value << 4) & 0xf0); 184 | return _value; 185 | } 186 | 187 | /** 188 | * initialiases a new code object 189 | */ 190 | Tadiran::Tadiran(uint8_t _mode, 191 | uint8_t _fan, 192 | uint8_t _temperature, 193 | uint8_t _state) { 194 | // init the codes with the fillers and default values 195 | for(uint8_t i=0;iCODE_threshold) 243 | Serial.print(1); 244 | else 245 | Serial.print(0); 246 | 247 | // Serial.print(","); 248 | } 249 | } 250 | Serial.println(""); 251 | for(uint8_t i=0;i 19 | 20 | // Values for STATE 21 | #define STATE_off 0 22 | #define STATE_on 1 23 | 24 | // Values for MODE 25 | #define MODE_auto 0 26 | #define MODE_cold 1 27 | #define MODE_dry 2 28 | #define MODE_fan 3 29 | #define MODE_heat 4 30 | 31 | // Values for FAN 32 | #define FAN_auto 0 33 | #define FAN_1 1 34 | #define FAN_2 2 35 | #define FAN_3 3 36 | 37 | // the length of the buffer 38 | #define TADIRAN_BUFFER_SIZE 139 39 | 40 | // Values for the codes 41 | #define CODE_filler 620 42 | #define CODE_high 1600 43 | #define CODE_low 540 44 | #define CODE_first 9000 45 | #define CODE_second 4000 46 | #define CODE_threshold 700 47 | #define CODE_pause 19000 48 | 49 | // main class for manipulating a TADIRAN buffer 50 | class Tadiran 51 | { 52 | public: 53 | // fields 54 | unsigned int codes[TADIRAN_BUFFER_SIZE]; 55 | // methods 56 | // setter 57 | Tadiran(uint8_t _mode, 58 | uint8_t _fan, 59 | uint8_t _temperature, 60 | uint8_t _state); 61 | void setTemeprature(uint8_t _value); 62 | void setMode(uint8_t _value); 63 | void setState(uint8_t _value); 64 | void setFan(uint8_t _value); 65 | // getter 66 | uint8_t getTemeprature(); 67 | uint8_t getMode(); 68 | uint8_t getState(); 69 | uint8_t getFan(); 70 | // debugging 71 | void debug(); 72 | void print(); 73 | private: 74 | // fields 75 | uint8_t mode; 76 | uint8_t fan; 77 | uint8_t temperature; 78 | uint8_t state; 79 | uint8_t counter; 80 | // methods 81 | void setChecksum(); 82 | uint8_t bitReverse(uint8_t _value); 83 | }; 84 | 85 | #endif; 86 | -------------------------------------------------------------------------------- /BoilerSwitch/BoilerSwitch.ino: -------------------------------------------------------------------------------- 1 | // Enable debug prints to serial monitor 2 | #define MY_DEBUG 3 | //#define MY_NODE_ID 6 4 | // Enable and select radio type attached 5 | #define MY_RADIO_NRF24 6 | //#define MY_RADIO_RFM69 7 | // #define MY_RF24_CE_PIN 7 8 | // #define MY_RF24_CS_PIN 8 9 | // Enabled repeater feature for this node 10 | #define MY_REPEATER_FEATURE 11 | 12 | #include 13 | #include 14 | // #include 15 | #include 16 | #include 17 | 18 | #define RELAY_PIN1 3 // Arduino Digital I/O pin number for relay 19 | #define RELAY_PIN2 4 // Arduino Digital I/O pin number for relay 20 | 21 | #define ONE_WIRE_BUS 5 // Pin where dallase sensor is connected 22 | #define MAX_ATTACHED_DS18B20 16 23 | 24 | //#define CHILD_ID_TEMP 0 // Id of the temp sensor child 25 | #define CHILD_ID_SWITCH 0 // Id of the switch sensor child 26 | 27 | #define RELAY_ON 1 28 | #define RELAY_OFF 0 29 | 30 | OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) 31 | DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 32 | float lastTemperature[MAX_ATTACHED_DS18B20]; 33 | int numSensors=0; 34 | int state; 35 | bool initial_state_sent; 36 | 37 | MyMessage switchMsg(CHILD_ID_SWITCH, V_STATUS); 38 | MyMessage tempMsg(1,V_TEMP); 39 | 40 | void changeState(int newState) 41 | { 42 | saveState(CHILD_ID_SWITCH, newState); 43 | digitalWrite(RELAY_PIN1, newState); 44 | digitalWrite(RELAY_PIN2, newState); 45 | send(switchMsg.set(newState)); 46 | } 47 | 48 | void before() 49 | { 50 | // Startup up the OneWire library 51 | sensors.begin(); 52 | 53 | // Make sure relays are off when starting up 54 | digitalWrite(RELAY_PIN1, RELAY_OFF); 55 | // Then set relay pins in output mode 56 | pinMode(RELAY_PIN1, OUTPUT); 57 | // Make sure relays are off when starting up 58 | digitalWrite(RELAY_PIN2, RELAY_OFF); 59 | // Then set relay pins in output mode 60 | pinMode(RELAY_PIN2, OUTPUT); 61 | } 62 | 63 | void setup() 64 | { 65 | // requestTemperatures() will not block current thread 66 | sensors.setWaitForConversion(false); 67 | 68 | int newState = loadState(CHILD_ID_SWITCH); 69 | if (newState == 0Xff) {//if eeprom is empty 70 | newState = RELAY_OFF; 71 | } 72 | changeState(newState); 73 | } 74 | 75 | void presentation() { 76 | // Send the sketch version information to the gateway and Controller 77 | sendSketchInfo("BoilerSwitch", "1.0"); 78 | 79 | // Register all sensors to gw (they will be created as child devices) 80 | present(CHILD_ID_SWITCH, S_BINARY); 81 | 82 | numSensors = sensors.getDeviceCount(); 83 | Serial.println("numSensors: "); 84 | Serial.println(numSensors); 85 | 86 | // Present all sensors to controller 87 | for (int i=0; i(static_cast((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.; 112 | #ifdef MY_DEBUG 113 | Serial.println(temperature); 114 | #endif 115 | // Only send data if temperature has changed and no error 116 | if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) { 117 | // Send in the new temperature 118 | send(tempMsg.setSensor(i + 1).set(temperature,1)); 119 | // Save new temperatures for next compare 120 | lastTemperature[i]=temperature; 121 | } 122 | } 123 | wait(60000);//wait for 1 minute before checking again 124 | } 125 | 126 | void receive(const MyMessage &message) 127 | { 128 | // We only expect one type of message from controller. But we better check anyway. 129 | if (message.isAck()) 130 | { 131 | #ifdef MY_DEBUG 132 | Serial.println("This is an ack from gateway"); 133 | #endif 134 | } 135 | 136 | if (message.type == V_LIGHT) 137 | { 138 | #ifdef MY_DEBUG 139 | Serial.print("Incoming change for sensor:"); 140 | Serial.print(message.sensor); 141 | Serial.print(", New status: "); 142 | Serial.println(message.getBool()); 143 | #endif 144 | // chnage the state of the related sensor 145 | changeState(message.getBool() ? RELAY_ON : RELAY_OFF); 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /Cover/Cover.ino: -------------------------------------------------------------------------------- 1 | // Enable debug prints to serial monitor 2 | #define MY_DEBUG 3 | 4 | // Enable and select radio type attached 5 | #define MY_RADIO_NRF24 6 | 7 | //#define MY_RF24_PA_LEVEL RF24_PA_LOW 8 | 9 | //#define MY_REPEATER_FEATURE 10 | 11 | // uncomment if we want to manually assign an ID 12 | //#define MY_NODE_ID 1 / 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #define BUTTON_UP_PIN 3 // Arduino Digital I/O pin number for up button 19 | #define BUTTON_DOWN_PIN 4 // Arduino Digital I/O pin number for down button 20 | #define BUTTON_STOP_PIN 5 // Arduino Digital I/O pin number for stop button 21 | #define RELAY_DIR_PIN 6 // Arduino Digital I/O pin number for direction relay 22 | #define RELAY_POWER_PIN 7 // Arduino Digital I/O pin number for power relay 23 | #define RELAY_ON 1 24 | #define RELAY_OFF 0 25 | #define RELAY_DOWN 1 26 | #define RELAY_UP 0 27 | #define DIRECTION_DOWN 1 28 | #define DIRECTION_UP 0 29 | #define SKETCH_NAME "Cover" 30 | #define SKETCH_VER "2.0" 31 | #define CHILD_ID_COVER 0 // sensor Id of the sensor child 32 | #define STATE_UP 100 // 100 is open - up 33 | #define STATE_DOWN 0 // 0 is closed - down 34 | //#define CHILD_ID_CALIBRATE 1 // sensor Id of the sensor child to calibrate 35 | #define CHILD_ID_SET 1 // sensor Id of the sensor child to init the roll time 36 | #define PRESENT_MESSAGE "Cover sensor for hass" 37 | const int LEVELS = 100; //the number of levels 38 | float rollTime = 20.0; //the overall rolling time of the shutter 39 | const bool IS_ACK = false; //is to acknowlage 40 | static bool initial_state_sent = false;//for hass we need at list one state send at begining 41 | 42 | // debouncing parameters 43 | int value = 0; 44 | int oldValueUp = 0; 45 | int oldValueDown = 0; 46 | int oldValueStop = 0; 47 | //static unsigned long last_interrupt_time_up = 0; 48 | //static unsigned long last_interrupt_time_down = 0; 49 | //static unsigned long debounce_time = 200; 50 | 51 | Bounce debouncerUp = Bounce(); 52 | Bounce debouncerDown = Bounce(); 53 | Bounce debouncerStop = Bounce(); 54 | 55 | // shutter position parameters 56 | float timeOneLevel = rollTime / LEVELS; 57 | int requestedShutterLevel = 0; 58 | int currentShutterLevel = 0; 59 | unsigned long lastLevelTime = 0; 60 | bool isMoving = false; 61 | int directionUpDown; 62 | 63 | enum CoverState { 64 | STOP, 65 | UP, // Window covering. Up. 66 | DOWN, // Window covering. Down. 67 | }; 68 | 69 | static int coverState = STOP; 70 | 71 | MyMessage msgUp(CHILD_ID_COVER, V_UP); 72 | MyMessage msgDown(CHILD_ID_COVER, V_DOWN); 73 | MyMessage msgStop(CHILD_ID_COVER, V_STOP); 74 | MyMessage msgPercentage(CHILD_ID_COVER, V_PERCENTAGE); 75 | //MyMessage msgCode(CHILD_ID_SET, V_IR_SEND); 76 | 77 | void sendState() { 78 | // Send current state and status to gateway. 79 | send(msgUp.set(coverState == UP)); 80 | send(msgDown.set(coverState == DOWN)); 81 | send(msgStop.set(coverState == STOP)); 82 | send(msgPercentage.set(currentShutterLevel)); 83 | } 84 | 85 | void shuttersUp(void) { 86 | #ifdef MY_DEBUG 87 | Serial.println("Shutters going up"); 88 | #endif 89 | if (digitalRead(RELAY_POWER_PIN) == RELAY_ON) { 90 | digitalWrite(RELAY_POWER_PIN, RELAY_OFF); 91 | delay(20); 92 | } 93 | digitalWrite(RELAY_DIR_PIN, RELAY_UP); 94 | delay(20); 95 | digitalWrite(RELAY_POWER_PIN, RELAY_ON); 96 | 97 | directionUpDown = DIRECTION_UP; 98 | isMoving = true; 99 | coverState = UP; 100 | sendState(); 101 | } 102 | 103 | void shuttersDown(void) { 104 | #ifdef MY_DEBUG 105 | Serial.println("Shutters going down"); 106 | #endif 107 | if (digitalRead(RELAY_POWER_PIN) == RELAY_ON) { 108 | digitalWrite(RELAY_POWER_PIN, RELAY_OFF); 109 | delay(20); 110 | } 111 | digitalWrite(RELAY_DIR_PIN, RELAY_DOWN); 112 | delay(20); 113 | digitalWrite(RELAY_POWER_PIN, RELAY_ON); 114 | 115 | directionUpDown = DIRECTION_DOWN; 116 | isMoving = true; 117 | coverState = DOWN; 118 | sendState(); 119 | } 120 | 121 | void shuttersHalt(void) { 122 | #ifdef MY_DEBUG 123 | Serial.println("Shutters halted"); 124 | #endif 125 | digitalWrite(RELAY_POWER_PIN, RELAY_OFF); 126 | delay(20); 127 | digitalWrite(RELAY_DIR_PIN, RELAY_UP); 128 | 129 | isMoving = false; 130 | requestedShutterLevel = currentShutterLevel; 131 | #ifdef MY_DEBUG 132 | Serial.println("saving state to: "); 133 | Serial.println(String(currentShutterLevel)); 134 | #endif 135 | saveState(CHILD_ID_COVER, currentShutterLevel); 136 | coverState = STOP; 137 | sendState(); 138 | } 139 | 140 | void changeShuttersLevel(int level) { 141 | int dir = (level > currentShutterLevel) ? DIRECTION_UP : DIRECTION_DOWN; 142 | if (isMoving && dir != directionUpDown) { 143 | shuttersHalt(); 144 | } 145 | requestedShutterLevel = level; 146 | } 147 | 148 | void initShutters() { 149 | #ifdef MY_DEBUG 150 | Serial.println("Init Cover"); 151 | #endif 152 | shuttersUp(); 153 | delay((rollTime + timeOneLevel * LEVELS) * 1000); 154 | currentShutterLevel = STATE_UP; 155 | requestedShutterLevel = currentShutterLevel; 156 | } 157 | 158 | void receive(const MyMessage &message) { 159 | #ifdef MY_DEBUG 160 | Serial.println("recieved incomming message"); 161 | Serial.println("Recieved message for sensor: "); 162 | Serial.println(String(message.sensor)); 163 | Serial.println("Recieved message with type: "); 164 | Serial.println(String(message.type)); 165 | #endif 166 | if (message.sensor == CHILD_ID_COVER) { 167 | switch (message.type) { 168 | case V_UP: 169 | //Serial.println(", New status: V_UP"); 170 | changeShuttersLevel(STATE_UP); 171 | //state = UP; 172 | //sendState(); 173 | break; 174 | 175 | case V_DOWN: 176 | //Serial.println(", New status: V_DOWN"); 177 | changeShuttersLevel(STATE_DOWN); 178 | //state = DOWN; 179 | //sendState(); 180 | break; 181 | 182 | case V_STOP: 183 | //Serial.println(", New status: V_STOP"); 184 | shuttersHalt(); 185 | //state = IDLE; 186 | //sendState(); 187 | break; 188 | 189 | case V_PERCENTAGE: 190 | //Serial.println(", New status: V_PERCENTAGE"); 191 | // if (!initial_state_sent) { 192 | // #ifdef MY_DEBUG 193 | // Serial.println("Receiving initial value from controller"); 194 | // #endif 195 | // initial_state_sent = true; 196 | // } 197 | int per = message.getInt(); 198 | if (per > STATE_UP) { 199 | per = STATE_UP; 200 | } 201 | changeShuttersLevel(per); 202 | //InitShutters(message.getInt());//send value < 0 or > 100 to calibrate 203 | //sendState(); 204 | break; 205 | } 206 | } 207 | else if (message.sensor == CHILD_ID_SET) { 208 | 209 | if (message.type == V_VAR1) { 210 | Serial.println(", New status: V_VAR1, with payload: "); 211 | String strRollTime = message.getString(); 212 | rollTime = strRollTime.toFloat(); 213 | Serial.println("rolltime value: "); 214 | Serial.println(String(rollTime)); 215 | saveState(CHILD_ID_SET, rollTime); 216 | } 217 | } 218 | #ifdef MY_DEBUG 219 | Serial.println("exiting incoming message"); 220 | #endif 221 | return; 222 | } 223 | 224 | void before() { 225 | 226 | // Setup the button 227 | pinMode(BUTTON_UP_PIN, INPUT_PULLUP); 228 | // Activate internal pull-up 229 | digitalWrite(BUTTON_UP_PIN, HIGH); 230 | // attachInterrupt(digitalPinToInterrupt(BUTTON_UP_PIN), upButtonPress, FALLING); 231 | 232 | pinMode(BUTTON_DOWN_PIN, INPUT_PULLUP); 233 | // Activate internal pull-up 234 | digitalWrite(BUTTON_DOWN_PIN, HIGH); 235 | // attachInterrupt(digitalPinToInterrupt(BUTTON_DOWN_PIN), downButtonPress, FALLING); 236 | 237 | pinMode(BUTTON_STOP_PIN, INPUT_PULLUP); 238 | // Activate internal pull-up 239 | digitalWrite(BUTTON_STOP_PIN, HIGH); 240 | 241 | // After setting up the button, setup debouncer 242 | debouncerUp.attach(BUTTON_UP_PIN); 243 | debouncerUp.interval(5); 244 | // After setting up the button, setup debouncer 245 | debouncerDown.attach(BUTTON_DOWN_PIN); 246 | debouncerDown.interval(5); 247 | // After setting up the button, setup debouncer 248 | debouncerStop.attach(BUTTON_STOP_PIN); 249 | debouncerStop.interval(5); 250 | 251 | // Make sure relays are off when starting up 252 | digitalWrite(RELAY_DIR_PIN, RELAY_OFF); 253 | // Then set relay pins in output mode 254 | pinMode(RELAY_DIR_PIN, OUTPUT); 255 | 256 | // Make sure relays are off when starting up 257 | digitalWrite(RELAY_POWER_PIN, RELAY_OFF); 258 | // Then set relay pins in output mode 259 | pinMode(RELAY_POWER_PIN, OUTPUT); 260 | } 261 | 262 | void presentation() { 263 | // Send the sketch version information to the gateway and Controller 264 | sendSketchInfo(SKETCH_NAME, SKETCH_VER); 265 | // Register all sensors to gw (they will be created as child devices) 266 | present(CHILD_ID_COVER, S_COVER, PRESENT_MESSAGE, IS_ACK); 267 | //present(CHILD_ID_SET, S_CUSTOM); 268 | } 269 | 270 | void setup(void) { 271 | //set up roll time if the saved value is not 255 272 | Serial.println("getting rolltime from eeprom: "); 273 | float tmpRollTime = loadState(CHILD_ID_SET); 274 | if (tmpRollTime != 0xff) { 275 | rollTime = tmpRollTime; 276 | } 277 | Serial.println(String(rollTime)); 278 | 279 | int state = loadState(CHILD_ID_COVER); 280 | #ifdef MY_DEBUG 281 | Serial.println("getting state from eeprom: "); 282 | Serial.println(String(state)); 283 | #endif 284 | if (state == 0xff) { 285 | initShutters(); 286 | } else { 287 | changeShuttersLevel(state); 288 | } 289 | } 290 | 291 | void loop(void) { 292 | if (!initial_state_sent) { 293 | #ifdef MY_DEBUG 294 | Serial.println("Sending initial value"); 295 | #endif 296 | sendState(); 297 | 298 | // send(msgCode.set('20.0')); 299 | // #ifdef MY_DEBUG 300 | // Serial.println("Requesting initial value from controller"); 301 | // #endif 302 | // request(CHILD_ID_COVER, V_PERCENTAGE); 303 | // wait(2000, C_SET, V_PERCENTAGE); 304 | initial_state_sent = true; 305 | } 306 | 307 | debouncerUp.update(); 308 | value = debouncerUp.read(); 309 | if (value == 0 && value != oldValueUp) { 310 | changeShuttersLevel(STATE_UP); 311 | //state = UP; 312 | //sendState(); 313 | } 314 | oldValueUp = value; 315 | 316 | debouncerDown.update(); 317 | value = debouncerDown.read(); 318 | if (value == 0 && value != oldValueDown) { 319 | changeShuttersLevel(STATE_DOWN); 320 | //state = DOWN; 321 | //sendState(); 322 | } 323 | oldValueDown = value; 324 | 325 | debouncerStop.update(); 326 | value = debouncerStop.read(); 327 | if (value == 0 && value != oldValueStop) { 328 | shuttersHalt(); 329 | //state = IDLE; 330 | //sendState(); 331 | } 332 | oldValueStop = value; 333 | 334 | 335 | if (isMoving) { 336 | unsigned long _now = millis(); 337 | if (_now - lastLevelTime >= timeOneLevel * 1000) { 338 | if (directionUpDown == DIRECTION_UP) { 339 | currentShutterLevel += 1; 340 | } else { 341 | currentShutterLevel -= 1; 342 | } 343 | #ifdef MY_DEBUG 344 | Serial.println(String(requestedShutterLevel)); 345 | Serial.println(String(currentShutterLevel)); 346 | #endif 347 | lastLevelTime = millis(); 348 | //send(msgPercentage.set(currentShutterLevel)); 349 | } 350 | if (currentShutterLevel == requestedShutterLevel) { 351 | shuttersHalt(); 352 | } 353 | } else if (requestedShutterLevel != currentShutterLevel) { 354 | if (requestedShutterLevel > currentShutterLevel) { 355 | shuttersUp(); 356 | } 357 | else { 358 | shuttersDown(); 359 | } 360 | lastLevelTime = millis(); 361 | } 362 | } 363 | 364 | -------------------------------------------------------------------------------- /LightSwitch/LightSwitch.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * The MySensors Arduino library handles the wireless radio link and protocol 3 | * between your home built sensors/actuators and HA controller of choice. 4 | * The sensors forms a self healing radio network with optional repeaters. Each 5 | * repeater and gateway builds a routing tables in EEPROM which keeps track of the 6 | * network topology allowing messages to be routed to nodes. 7 | * 8 | * Created by Henrik Ekblad 9 | * Copyright (C) 2013-2015 Sensnology AB 10 | * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors 11 | * 12 | * Documentation: http://www.mysensors.org 13 | * Support Forum: http://forum.mysensors.org 14 | * 15 | * This program is free software; you can redistribute it and/or 16 | * modify it under the terms of the GNU General Public License 17 | * version 2 as published by the Free Software Foundation. 18 | * 19 | ******************************* 20 | * 21 | * REVISION HISTORY 22 | * Version 1.0 - Henrik Ekblad 23 | * Version 2.0 - dpressle 24 | * 25 | * DESCRIPTION 26 | * Example sketch for a "light switch" where you can control light or something 27 | * else from both HA controller and a local physical button 28 | * (connected between digital pin 3 and GND). 29 | * This node also works as a repeader for other nodes 30 | * http://www.mysensors.org/build/relay 31 | */ 32 | 33 | // Enable debug prints to serial monitor 34 | #define MY_DEBUG 35 | // Enable and select radio type attached 36 | #define MY_RADIO_NRF24 37 | //#define MY_RADIO_RFM69 38 | 39 | // Enabled repeater feature for this node 40 | #define MY_REPEATER_FEATURE 41 | 42 | #include 43 | #include 44 | #include 45 | 46 | #define RELAY_PIN1 A0 // Arduino Digital I/O pin number for relay 47 | #define RELAY_PIN2 A1 // Arduino Digital I/O pin number for relay 48 | #define RELAY_PIN3 A2 // Arduino Digital I/O pin number for relay 49 | 50 | #define BUTTON_PIN1 5 // Arduino Digital I/O pin number for button 51 | #define BUTTON_PIN2 6 // Arduino Digital I/O pin number for button 52 | #define BUTTON_PIN3 7 // Arduino Digital I/O pin number for button 53 | 54 | //#define LED_PIN 6 // Arduino Digital I/O pin number for led 55 | 56 | #define CHILD_ID1 0 // Id of the sensor child 57 | #define CHILD_ID2 1 // Id of the sensor child 58 | #define CHILD_ID3 2 // Id of the sensor child 59 | 60 | #define RELAY_ON 1 61 | #define RELAY_OFF 0 62 | 63 | Bounce debouncer1 = Bounce(); 64 | Bounce debouncer2 = Bounce(); 65 | Bounce debouncer3 = Bounce(); 66 | 67 | int oldValue1 = 0; 68 | int oldValue2 = 0; 69 | int oldValue3 = 0; 70 | 71 | int state; 72 | bool initial_state_sent; 73 | 74 | MyMessage msg1(CHILD_ID1, V_STATUS); 75 | MyMessage msg2(CHILD_ID2, V_STATUS); 76 | MyMessage msg3(CHILD_ID3, V_STATUS); 77 | 78 | void changeState(int chiled, int newState) { 79 | //state = newState; 80 | //digitalWrite(pin, newState); 81 | 82 | saveState(chiled, newState); 83 | switch(chiled){ 84 | case CHILD_ID1: 85 | digitalWrite(RELAY_PIN1, newState); 86 | send(msg1.set(newState)); 87 | break; 88 | case CHILD_ID2: 89 | digitalWrite(RELAY_PIN2, newState); 90 | send(msg2.set(newState)); 91 | break; 92 | case CHILD_ID3: 93 | digitalWrite(RELAY_PIN3, newState); 94 | send(msg3.set(newState)); 95 | break; 96 | default: 97 | break; 98 | } 99 | 100 | } 101 | 102 | void before() { 103 | // Setup the button 104 | pinMode(BUTTON_PIN1, INPUT_PULLUP); 105 | pinMode(BUTTON_PIN2, INPUT_PULLUP); 106 | pinMode(BUTTON_PIN3, INPUT_PULLUP); 107 | // Activate internal pull-up 108 | digitalWrite(BUTTON_PIN1, HIGH); 109 | digitalWrite(BUTTON_PIN2, HIGH); 110 | digitalWrite(BUTTON_PIN3, HIGH); 111 | 112 | // After setting up the button, setup debouncer 113 | debouncer1.attach(BUTTON_PIN1); 114 | debouncer1.interval(5); 115 | debouncer2.attach(BUTTON_PIN2); 116 | debouncer2.interval(5); 117 | debouncer3.attach(BUTTON_PIN3); 118 | debouncer3.interval(5); 119 | 120 | // Make sure relays are off when starting up 121 | digitalWrite(RELAY_PIN1, RELAY_OFF); 122 | // Then set relay pins in output mode 123 | pinMode(RELAY_PIN1, OUTPUT); 124 | // Make sure relays are off when starting up 125 | digitalWrite(RELAY_PIN2, RELAY_OFF); 126 | // Then set relay pins in output mode 127 | pinMode(RELAY_PIN2, OUTPUT); 128 | // Make sure relays are off when starting up 129 | digitalWrite(RELAY_PIN3, RELAY_OFF); 130 | // Then set relay pins in output mode 131 | pinMode(RELAY_PIN3, OUTPUT); 132 | 133 | // digitalWrite(LED_PIN, RELAY_OFF); 134 | // // Then set relay pins in output mode 135 | // pinMode(LED_PIN, OUTPUT); 136 | } 137 | 138 | void setup() { 139 | // Set relay to last known state (using eeprom storage) 140 | int newState = loadState(CHILD_ID1); 141 | if (newState == 0Xff) {//if eeprom is empty 142 | newState = RELAY_OFF; 143 | } 144 | changeState(CHILD_ID1, newState); 145 | 146 | newState = loadState(CHILD_ID2); 147 | if (newState == 0Xff) {//if eeprom is empty 148 | newState = RELAY_OFF; 149 | } 150 | changeState(CHILD_ID2, newState); 151 | 152 | newState = loadState(CHILD_ID3); 153 | if (newState == 0Xff) {//if eeprom is empty 154 | newState = RELAY_OFF; 155 | } 156 | changeState(CHILD_ID3, newState); 157 | } 158 | 159 | void presentation() { 160 | // Send the sketch version information to the gateway and Controller 161 | sendSketchInfo("LightSwitch", "2.0"); 162 | 163 | // Register all sensors to gw (they will be created as child devices) 164 | present(CHILD_ID1, S_BINARY); 165 | present(CHILD_ID2, S_BINARY); 166 | present(CHILD_ID3, S_BINARY); 167 | } 168 | 169 | void loop() { 170 | if (!initial_state_sent) { 171 | Serial.println("Sending initial value"); 172 | send(msg1.set(loadState(CHILD_ID1) ? true : false)); 173 | send(msg2.set(loadState(CHILD_ID2) ? true : false)); 174 | send(msg3.set(loadState(CHILD_ID3) ? true : false)); 175 | 176 | initial_state_sent = true; 177 | } 178 | 179 | debouncer1.update(); 180 | // Get the update value 181 | int value = debouncer1.read(); 182 | if (value != oldValue1 && value==0) { 183 | //toggle switch state 184 | changeState(CHILD_ID1, value); 185 | //digitalWrite(RELAY_PIN, state ? RELAY_OFF : RELAY_ON); 186 | //send(msg.set(state?false:true)); // Send new state and request ack back 187 | } 188 | oldValue1 = value; 189 | 190 | debouncer2.update(); 191 | // Get the update value 192 | value = debouncer2.read(); 193 | if (value != oldValue2 && value==0) { 194 | //toggle switch state 195 | changeState(CHILD_ID2, value); 196 | //digitalWrite(RELAY_PIN, state ? RELAY_OFF : RELAY_ON); 197 | //send(msg.set(state?false:true)); // Send new state and request ack back 198 | } 199 | oldValue2 = value; 200 | 201 | debouncer3.update(); 202 | // Get the update value 203 | value = debouncer3.read(); 204 | if (value != oldValue3 && value==0) { 205 | //toggle switch state 206 | changeState(CHILD_ID3, value); 207 | //state = loadState(CHILD_ID3); 208 | //digitalWrite(RELAY_PIN3, state ? RELAY_OFF : RELAY_ON); 209 | //send(msg.set(state?false:true)); // Send new state and request ack back 210 | } 211 | oldValue3 = value; 212 | } 213 | 214 | void receive(const MyMessage &message) { 215 | // We only expect one type of message from controller. But we better check anyway. 216 | if (message.isAck()) { 217 | #ifdef MY_DEBUG 218 | Serial.println("This is an ack from gateway"); 219 | #endif 220 | } 221 | 222 | if (message.type == V_LIGHT) { 223 | #ifdef MY_DEBUG 224 | Serial.print("Incoming change for sensor:"); 225 | Serial.print(message.sensor); 226 | Serial.print(", New status: "); 227 | Serial.println(message.getBool()); 228 | #endif 229 | // chnage the state of the related sensor 230 | changeState(message.sensor, message.getBool() ? RELAY_ON : RELAY_OFF); 231 | // state = message.getBool(); 232 | // switch(message.sensor) { 233 | // case CHILD_ID1: 234 | // changeState(CHILD_ID1, state ? RELAY_ON : RELAY_OFF); 235 | // break; 236 | // case CHILD_ID2: 237 | // changeState(CHILD_ID2, state ? RELAY_ON : RELAY_OFF); 238 | // break; 239 | // case CHILD_ID3: 240 | // changeState(CHILD_ID3, state ? RELAY_ON : RELAY_OFF); 241 | // break; 242 | // default: 243 | // break; 244 | // } 245 | // Change relay state 246 | 247 | 248 | // Write some debug info 249 | 250 | 251 | } 252 | } 253 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MySensors 2 | MySensors repository 3 | aaa 4 | -------------------------------------------------------------------------------- /RollerShutter/RollerShutter.ino: -------------------------------------------------------------------------------- 1 | // Enable debug prints to serial monitor 2 | #define MY_DEBUG 3 | 4 | // Enable and select radio type attached 5 | #define MY_RADIO_NRF24 6 | 7 | //#define MY_RF24_PA_LEVEL RF24_PA_LOW 8 | 9 | //#define MY_REPEATER_FEATURE 10 | 11 | // uncomment if we want to manually assign an ID 12 | //#define MY_NODE_ID 1 / 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #define BUTTON_UP_PIN 2 // Arduino Digital I/O pin number for up button 19 | #define BUTTON_DOWN_PIN 3 // Arduino Digital I/O pin number for down button 20 | #define BUTTON_STOP_PIN 4 // Arduino Digital I/O pin number for stop button 21 | #define RELAY_DIR_PIN 5 // Arduino Digital I/O pin number for direction relay 22 | #define RELAY_POWER_PIN 6 // Arduino Digital I/O pin number for power relay 23 | #define RELAY_ON 1 24 | #define RELAY_OFF 0 25 | #define DIRECTION_DOWN 1 26 | #define DIRECTION_UP 0 27 | #define SKETCH_NAME "roller shutter" 28 | #define SKETCH_VER "2.1" 29 | #define CHILD_ID 1 // sensor Id of the sensor child 30 | //#define CHILD_ID_CALIBRATE 2 // sensor Id of the sensor child to calibrate 31 | #define CHILD_ID_SET 2 // sensor Id of the sensor child to init the roll time 32 | #define PRESENT_MESSAGE "sensor for roller shutter" 33 | const int LEVELS = 100; //the number of levels 34 | float rollTime = 15.0; //the overall rolling time of the shutter 35 | const bool IS_ACK = false; //is to acknowlage 36 | 37 | // debouncing parameters 38 | int value = 0; 39 | int oldValueUp = 0; 40 | int oldValueDown = 0; 41 | int oldValueStop = 0; 42 | //static unsigned long last_interrupt_time_up = 0; 43 | //static unsigned long last_interrupt_time_down = 0; 44 | //static unsigned long debounce_time = 200; 45 | 46 | Bounce debouncerUp = Bounce(); 47 | Bounce debouncerDown = Bounce(); 48 | Bounce debouncerStop = Bounce(); 49 | 50 | // shutter position parameters 51 | float timeOneLevel = rollTime / LEVELS; 52 | int requestedShutterLevel = 0; 53 | int currentShutterLevel = 0; 54 | unsigned long lastLevelTime = 0; 55 | bool isMoving = false; 56 | int directionUpDown; 57 | 58 | MyMessage msgUp(CHILD_ID, V_UP); 59 | MyMessage msgDown(CHILD_ID, V_DOWN); 60 | MyMessage msgStop(CHILD_ID, V_STOP); 61 | MyMessage msgPercentage(CHILD_ID, V_PERCENTAGE); 62 | 63 | void print_debug(String message) { 64 | #ifdef MY_DEBUG 65 | Serial.println(message); 66 | #endif 67 | } 68 | 69 | void shuttersUp(void) { 70 | print_debug("Shutters going up."); 71 | directionUpDown = DIRECTION_UP; 72 | isMoving = true; 73 | digitalWrite(RELAY_DIR_PIN, RELAY_OFF); 74 | delay(20); 75 | digitalWrite(RELAY_POWER_PIN, RELAY_ON); 76 | } 77 | 78 | void shuttersDown(void) { 79 | print_debug("Shutters going down."); 80 | directionUpDown = DIRECTION_DOWN; 81 | isMoving = true; 82 | digitalWrite(RELAY_DIR_PIN, RELAY_ON); 83 | delay(20); 84 | digitalWrite(RELAY_POWER_PIN, RELAY_ON); 85 | 86 | } 87 | 88 | void shuttersHalt(void) { 89 | isMoving = false; 90 | requestedShutterLevel = currentShutterLevel; 91 | digitalWrite(RELAY_POWER_PIN, RELAY_OFF); 92 | delay(20); 93 | digitalWrite(RELAY_DIR_PIN, RELAY_OFF); 94 | print_debug("Shutters halted."); 95 | saveState(CHILD_ID, currentShutterLevel); 96 | print_debug("saving level to: "); 97 | print_debug(String(currentShutterLevel)); 98 | } 99 | 100 | void changeShuttersLevel(int level) { 101 | if (level < 0 || level > 100) { 102 | print_debug("level is out of range calling InitShutters: "); 103 | print_debug(String(level)); 104 | InitShutters(); 105 | level = 0; 106 | } else { 107 | int dir = (level > currentShutterLevel) ? DIRECTION_DOWN : DIRECTION_UP; 108 | if (isMoving && dir != directionUpDown) { 109 | shuttersHalt(); 110 | } 111 | print_debug("setting requested level to:"); 112 | print_debug(String(level)); 113 | requestedShutterLevel = level; 114 | } 115 | } 116 | 117 | void InitShutters() { 118 | // if (level < 0 || level > 100) 119 | // { 120 | //print_debug("Current level unsure, calibrating..."); 121 | print_debug("Init Shutters"); 122 | shuttersUp(); 123 | print_debug("delaying for: "); 124 | print_debug(String((rollTime + timeOneLevel * LEVELS) * 1000)); 125 | delay((rollTime + timeOneLevel * LEVELS) * 1000); 126 | print_debug("ended delay rolltime"); 127 | currentShutterLevel = 0; 128 | requestedShutterLevel = currentShutterLevel; 129 | //return true; 130 | // } 131 | // else 132 | // { 133 | // print_debug("No clibration needed. setting to: "); 134 | // print_debug(level); 135 | // currentShutterLevel = level; 136 | // changeShuttersLevel(currentShutterLevel); 137 | // return false; 138 | // } 139 | } 140 | 141 | void receive(const MyMessage &message) { 142 | print_debug("recieved incomming message"); 143 | print_debug("Recieved message for sensor: "); 144 | print_debug(String(message.sensor)); 145 | switch (message.sensor) { 146 | case CHILD_ID: 147 | switch (message.type) { 148 | case V_UP: 149 | print_debug(", New status: V_UP"); 150 | changeShuttersLevel(0); 151 | print_debug("Done shutterAction procedure"); 152 | break; 153 | 154 | case V_DOWN: 155 | print_debug(", New status: V_DOWN"); 156 | changeShuttersLevel(100); 157 | print_debug("Done shutterAction procedure"); 158 | break; 159 | 160 | case V_STOP: 161 | print_debug(", New status: V_STOP"); 162 | shuttersHalt(); 163 | print_debug("Done shutterAction procedure"); 164 | break; 165 | 166 | case V_PERCENTAGE: 167 | print_debug(", New status: V_PERCENTAGE"); 168 | changeShuttersLevel(message.getInt()); 169 | //InitShutters(message.getInt());//send value < 0 or > 100 to calibrate 170 | print_debug("Done shutterAction procedure"); 171 | break; 172 | } 173 | case CHILD_ID_SET: 174 | switch (message.type) { 175 | case V_VAR1: 176 | print_debug(", New status: V_VAR1, with payload: "); 177 | rollTime = message.getFloat(); 178 | print_debug("rolltime value: "); 179 | print_debug(String(rollTime)); 180 | saveState(CHILD_ID_SET, rollTime); 181 | break; 182 | case V_VAR2: 183 | print_debug(", New status: "); 184 | print_debug("V_VAR2, with payload: "); 185 | print_debug(String(message.getInt())); 186 | InitShutters(); 187 | break; 188 | } 189 | } 190 | print_debug("exiting incoming message"); 191 | return; 192 | } 193 | 194 | void presentation() { 195 | // Send the sketch version information to the gateway and Controller 196 | sendSketchInfo(SKETCH_NAME, SKETCH_VER); 197 | // Register all sensors to gw (they will be created as child devices) 198 | present(CHILD_ID, S_COVER, PRESENT_MESSAGE, IS_ACK); 199 | present(CHILD_ID_SET, S_CUSTOM, PRESENT_MESSAGE, IS_ACK); 200 | } 201 | 202 | void before() { 203 | 204 | // Setup the button 205 | pinMode(BUTTON_UP_PIN, INPUT_PULLUP); 206 | // Activate internal pull-up 207 | digitalWrite(BUTTON_UP_PIN, HIGH); 208 | // attachInterrupt(digitalPinToInterrupt(BUTTON_UP_PIN), upButtonPress, FALLING); 209 | 210 | pinMode(BUTTON_DOWN_PIN, INPUT_PULLUP); 211 | // Activate internal pull-up 212 | digitalWrite(BUTTON_DOWN_PIN, HIGH); 213 | // attachInterrupt(digitalPinToInterrupt(BUTTON_DOWN_PIN), downButtonPress, FALLING); 214 | 215 | pinMode(BUTTON_STOP_PIN, INPUT_PULLUP); 216 | // Activate internal pull-up 217 | digitalWrite(BUTTON_STOP_PIN, HIGH); 218 | 219 | // After setting up the button, setup debouncer 220 | debouncerUp.attach(BUTTON_UP_PIN); 221 | debouncerUp.interval(5); 222 | // After setting up the button, setup debouncer 223 | debouncerDown.attach(BUTTON_DOWN_PIN); 224 | debouncerDown.interval(5); 225 | // After setting up the button, setup debouncer 226 | debouncerStop.attach(BUTTON_STOP_PIN); 227 | debouncerStop.interval(5); 228 | 229 | // Make sure relays are off when starting up 230 | digitalWrite(RELAY_DIR_PIN, RELAY_OFF); 231 | // Then set relay pins in output mode 232 | pinMode(RELAY_DIR_PIN, OUTPUT); 233 | 234 | // Make sure relays are off when starting up 235 | digitalWrite(RELAY_POWER_PIN, RELAY_OFF); 236 | // Then set relay pins in output mode 237 | pinMode(RELAY_POWER_PIN, OUTPUT); 238 | 239 | 240 | } 241 | 242 | void setup(void) { 243 | Serial.begin(115200); 244 | Serial.println("StartUP"); 245 | //set up roll time if the saved value is not 255 246 | print_debug("getting rolltime from eeprom: "); 247 | int tmpRollTime = loadState(CHILD_ID_SET); 248 | if (tmpRollTime < 255) { 249 | rollTime = tmpRollTime; 250 | } 251 | print_debug(String(rollTime)); 252 | 253 | print_debug("getting state from eeprom: "); 254 | int state = loadState(CHILD_ID); 255 | print_debug(String(state)); 256 | changeShuttersLevel(state); 257 | } 258 | 259 | void loop(void) { 260 | debouncerUp.update(); 261 | value = debouncerUp.read(); 262 | if (value == 0 && value != oldValueUp) { 263 | changeShuttersLevel(0); 264 | send(msgUp, IS_ACK); 265 | } 266 | oldValueUp = value; 267 | 268 | debouncerDown.update(); 269 | value = debouncerDown.read(); 270 | if (value == 0 && value != oldValueDown) { 271 | changeShuttersLevel(100); 272 | send(msgDown, IS_ACK); 273 | } 274 | oldValueDown = value; 275 | 276 | debouncerStop.update(); 277 | value = debouncerStop.read(); 278 | if (value == 0 && value != oldValueStop) { 279 | shuttersHalt(); 280 | send(msgStop, IS_ACK); 281 | } 282 | oldValueStop = value; 283 | 284 | 285 | if (isMoving) 286 | { 287 | //print_debug("1"); 288 | unsigned long _now = millis(); 289 | if (_now - lastLevelTime >= timeOneLevel * 1000) 290 | { 291 | //print_debug("2"); 292 | if (directionUpDown == DIRECTION_DOWN) 293 | { 294 | //print_debug("3"); 295 | currentShutterLevel += 1; 296 | } 297 | else 298 | { 299 | //print_debug("4"); 300 | currentShutterLevel -= 1; 301 | } 302 | lastLevelTime = millis(); 303 | } 304 | 305 | if (currentShutterLevel == requestedShutterLevel) 306 | { 307 | //print_debug("5"); 308 | shuttersHalt(); 309 | } 310 | } 311 | else if (requestedShutterLevel != currentShutterLevel) 312 | { 313 | //print_debug("6"); 314 | if (requestedShutterLevel < currentShutterLevel) 315 | { 316 | //print_debug("7"); 317 | shuttersUp(); 318 | } 319 | else 320 | { 321 | // print_debug("8"); 322 | shuttersDown(); 323 | } 324 | lastLevelTime = millis(); 325 | } 326 | } 327 | 328 | //void upButtonPress() { 329 | // unsigned long interrupt_time = millis(); 330 | // // If interrupts come faster than 200ms, assume it's a bounce and ignore 331 | // if (interrupt_time - last_interrupt_time_up > debounce_time) 332 | // { 333 | // changeShuttersLevel(0); 334 | // send(msgUp, IS_ACK); 335 | // } 336 | // last_interrupt_time_up = interrupt_time; 337 | //} 338 | // 339 | //void downButtonPress() { 340 | // unsigned long interrupt_time = millis(); 341 | // // If interrupts come faster than 200ms, assume it's a bounce and ignore 342 | // if (interrupt_time - last_interrupt_time_down > debounce_time) 343 | // { 344 | // changeShuttersLevel(100); 345 | // send(msgDown, IS_ACK); 346 | // } 347 | // last_interrupt_time_down = interrupt_time; 348 | //} 349 | -------------------------------------------------------------------------------- /Switch/Switch.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * The MySensors Arduino library handles the wireless radio link and protocol 3 | * between your home built sensors/actuators and HA controller of choice. 4 | * The sensors forms a self healing radio network with optional repeaters. Each 5 | * repeater and gateway builds a routing tables in EEPROM which keeps track of the 6 | * network topology allowing messages to be routed to nodes. 7 | * 8 | * Created by Henrik Ekblad 9 | * Copyright (C) 2013-2015 Sensnology AB 10 | * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors 11 | * 12 | * Documentation: http://www.mysensors.org 13 | * Support Forum: http://forum.mysensors.org 14 | * 15 | * This program is free software; you can redistribute it and/or 16 | * modify it under the terms of the GNU General Public License 17 | * version 2 as published by the Free Software Foundation. 18 | * 19 | ******************************* 20 | * 21 | * REVISION HISTORY 22 | * Version 1.0 - Henrik Ekblad 23 | * 24 | * DESCRIPTION 25 | * Example sketch for a "light switch" where you can control light or something 26 | * else from both HA controller and a local physical button 27 | * (connected between digital pin 3 and GND). 28 | * This node also works as a repeader for other nodes 29 | * http://www.mysensors.org/build/relay 30 | */ 31 | 32 | // Enable debug prints to serial monitor 33 | //#define MY_DEBUG 34 | //#define MY_NODE_ID 6 35 | // Enable and select radio type attached 36 | #define MY_RADIO_NRF24 37 | //#define MY_RADIO_RFM69 38 | 39 | // Enabled repeater feature for this node 40 | #define MY_REPEATER_FEATURE 41 | 42 | #include 43 | #include 44 | #include 45 | 46 | #define RELAY_PIN1 A0 // Arduino Digital I/O pin number for relay 47 | #define RELAY_PIN2 A1 // Arduino Digital I/O pin number for relay 48 | #define RELAY_PIN3 A2 // Arduino Digital I/O pin number for relay 49 | 50 | #define BUTTON_PIN1 5 // Arduino Digital I/O pin number for button 51 | #define BUTTON_PIN2 6 // Arduino Digital I/O pin number for button 52 | #define BUTTON_PIN3 7 // Arduino Digital I/O pin number for button 53 | 54 | //#define LED_PIN 6 // Arduino Digital I/O pin number for led 55 | 56 | #define CHILD_ID1 0 // Id of the sensor child 57 | #define CHILD_ID2 1 // Id of the sensor child 58 | #define CHILD_ID3 2 // Id of the sensor child 59 | 60 | #define RELAY_ON 1 61 | #define RELAY_OFF 0 62 | 63 | Bounce debouncer1 = Bounce(); 64 | Bounce debouncer2 = Bounce(); 65 | Bounce debouncer3 = Bounce(); 66 | 67 | int oldValue1 = 0; 68 | int oldValue2 = 0; 69 | int oldValue3 = 0; 70 | 71 | int state; 72 | bool initial_state_sent; 73 | 74 | MyMessage msg1(CHILD_ID1, V_STATUS); 75 | MyMessage msg2(CHILD_ID2, V_STATUS); 76 | MyMessage msg3(CHILD_ID3, V_STATUS); 77 | 78 | void changeState(int chiled, int newState) { 79 | //state = newState; 80 | //digitalWrite(pin, newState); 81 | 82 | saveState(chiled, newState); 83 | switch(chiled){ 84 | case CHILD_ID1: 85 | digitalWrite(RELAY_PIN1, newState); 86 | send(msg1.set(newState)); 87 | break; 88 | case CHILD_ID2: 89 | digitalWrite(RELAY_PIN2, newState); 90 | send(msg2.set(newState)); 91 | break; 92 | case CHILD_ID3: 93 | digitalWrite(RELAY_PIN3, newState); 94 | send(msg3.set(newState)); 95 | break; 96 | default: 97 | break; 98 | } 99 | 100 | } 101 | 102 | void before() { 103 | // Setup the button 104 | pinMode(BUTTON_PIN1, INPUT_PULLUP); 105 | pinMode(BUTTON_PIN2, INPUT_PULLUP); 106 | pinMode(BUTTON_PIN3, INPUT_PULLUP); 107 | // Activate internal pull-up 108 | digitalWrite(BUTTON_PIN1, HIGH); 109 | digitalWrite(BUTTON_PIN2, HIGH); 110 | digitalWrite(BUTTON_PIN3, HIGH); 111 | 112 | // After setting up the button, setup debouncer 113 | debouncer1.attach(BUTTON_PIN1); 114 | debouncer1.interval(5); 115 | debouncer2.attach(BUTTON_PIN2); 116 | debouncer2.interval(5); 117 | debouncer3.attach(BUTTON_PIN3); 118 | debouncer3.interval(5); 119 | 120 | // Make sure relays are off when starting up 121 | digitalWrite(RELAY_PIN1, RELAY_OFF); 122 | // Then set relay pins in output mode 123 | pinMode(RELAY_PIN1, OUTPUT); 124 | // Make sure relays are off when starting up 125 | digitalWrite(RELAY_PIN2, RELAY_OFF); 126 | // Then set relay pins in output mode 127 | pinMode(RELAY_PIN2, OUTPUT); 128 | // Make sure relays are off when starting up 129 | digitalWrite(RELAY_PIN3, RELAY_OFF); 130 | // Then set relay pins in output mode 131 | pinMode(RELAY_PIN3, OUTPUT); 132 | 133 | // digitalWrite(LED_PIN, RELAY_OFF); 134 | // // Then set relay pins in output mode 135 | // pinMode(LED_PIN, OUTPUT); 136 | } 137 | 138 | void setup() { 139 | // Set relay to last known state (using eeprom storage) 140 | int newState = loadState(CHILD_ID1); 141 | if (newState == 0Xff) {//if eeprom is empty 142 | newState = RELAY_OFF; 143 | } 144 | changeState(CHILD_ID1, newState); 145 | 146 | newState = loadState(CHILD_ID2); 147 | if (newState == 0Xff) {//if eeprom is empty 148 | newState = RELAY_OFF; 149 | } 150 | changeState(CHILD_ID2, newState); 151 | 152 | newState = loadState(CHILD_ID3); 153 | if (newState == 0Xff) {//if eeprom is empty 154 | newState = RELAY_OFF; 155 | } 156 | changeState(CHILD_ID3, newState); 157 | } 158 | 159 | void presentation() { 160 | // Send the sketch version information to the gateway and Controller 161 | sendSketchInfo("RelayButton", "1.0"); 162 | 163 | // Register all sensors to gw (they will be created as child devices) 164 | present(CHILD_ID1, S_BINARY); 165 | present(CHILD_ID2, S_BINARY); 166 | present(CHILD_ID3, S_BINARY); 167 | } 168 | 169 | void loop() { 170 | if (!initial_state_sent) { 171 | Serial.println("Sending initial value"); 172 | send(msg1.set(loadState(CHILD_ID1) ? false : true)); 173 | initial_state_sent = true; 174 | } 175 | 176 | debouncer1.update(); 177 | // Get the update value 178 | int value = debouncer1.read(); 179 | if (value != oldValue1 && value==0) { 180 | //toggle switch state 181 | changeState(CHILD_ID1, loadState(CHILD_ID1) ? RELAY_OFF : RELAY_ON); 182 | //digitalWrite(RELAY_PIN, state ? RELAY_OFF : RELAY_ON); 183 | //send(msg.set(state?false:true)); // Send new state and request ack back 184 | } 185 | oldValue1 = value; 186 | 187 | debouncer2.update(); 188 | // Get the update value 189 | value = debouncer2.read(); 190 | if (value != oldValue2 && value==0) { 191 | //toggle switch state 192 | changeState(CHILD_ID2, loadState(CHILD_ID2) ? RELAY_OFF : RELAY_ON); 193 | //digitalWrite(RELAY_PIN, state ? RELAY_OFF : RELAY_ON); 194 | //send(msg.set(state?false:true)); // Send new state and request ack back 195 | } 196 | oldValue2 = value; 197 | 198 | debouncer3.update(); 199 | // Get the update value 200 | value = debouncer3.read(); 201 | if (value != oldValue3 && value==0) { 202 | //toggle switch state 203 | changeState(CHILD_ID3, loadState(CHILD_ID3) ? RELAY_OFF : RELAY_ON); 204 | //state = loadState(CHILD_ID3); 205 | //digitalWrite(RELAY_PIN3, state ? RELAY_OFF : RELAY_ON); 206 | //send(msg.set(state?false:true)); // Send new state and request ack back 207 | } 208 | oldValue3 = value; 209 | } 210 | 211 | void receive(const MyMessage &message) { 212 | // We only expect one type of message from controller. But we better check anyway. 213 | if (message.isAck()) { 214 | #ifdef MY_DEBUG 215 | Serial.println("This is an ack from gateway"); 216 | #endif 217 | } 218 | 219 | if (message.type == V_LIGHT) { 220 | #ifdef MY_DEBUG 221 | Serial.print("Incoming change for sensor:"); 222 | Serial.print(message.sensor); 223 | Serial.print(", New status: "); 224 | Serial.println(message.getBool()); 225 | #endif 226 | // chnage the state of the related sensor 227 | changeState(message.sensor, message.getBool() ? RELAY_ON : RELAY_OFF); 228 | // state = message.getBool(); 229 | // switch(message.sensor) { 230 | // case CHILD_ID1: 231 | // changeState(CHILD_ID1, state ? RELAY_ON : RELAY_OFF); 232 | // break; 233 | // case CHILD_ID2: 234 | // changeState(CHILD_ID2, state ? RELAY_ON : RELAY_OFF); 235 | // break; 236 | // case CHILD_ID3: 237 | // changeState(CHILD_ID3, state ? RELAY_ON : RELAY_OFF); 238 | // break; 239 | // default: 240 | // break; 241 | // } 242 | // Change relay state 243 | 244 | 245 | // Write some debug info 246 | 247 | 248 | } 249 | } 250 | -------------------------------------------------------------------------------- /tempSensor/tempSensor.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * The MySensors Arduino library handles the wireless radio link and protocol 3 | * between your home built sensors/actuators and HA controller of choice. 4 | * The sensors forms a self healing radio network with optional repeaters. Each 5 | * repeater and gateway builds a routing tables in EEPROM which keeps track of the 6 | * network topology allowing messages to be routed to nodes. 7 | * 8 | * Created by Henrik Ekblad 9 | * Copyright (C) 2013-2015 Sensnology AB 10 | * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors 11 | * 12 | * Documentation: http://www.mysensors.org 13 | * Support Forum: http://forum.mysensors.org 14 | * 15 | * This program is free software; you can redistribute it and/or 16 | * modify it under the terms of the GNU General Public License 17 | * version 2 as published by the Free Software Foundation. 18 | * 19 | ******************************* 20 | * 21 | * DESCRIPTION 22 | * 23 | * Example sketch showing how to send in DS1820B OneWire temperature readings back to the controller 24 | * http://www.mysensors.org/build/temp 25 | */ 26 | 27 | 28 | // Enable debug prints to serial monitor 29 | //#define MY_DEBUG 30 | 31 | // Enable and select radio type attached 32 | #define MY_RADIO_NRF24 33 | //#define MY_RADIO_RFM69 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | #define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No 42 | #define SENSOR_OUTPUT 3 43 | #define ONE_WIRE_BUS 2 // Pin where dallase sensor is connected 44 | #define MAX_ATTACHED_DS18B20 16 45 | unsigned long SLEEP_TIME = 60000; // Sleep time between reads (in milliseconds) 46 | OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) 47 | DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 48 | float lastTemperature[MAX_ATTACHED_DS18B20]; 49 | int numSensors=0; 50 | bool receivedConfig = false; 51 | bool metric = true; 52 | // Initialize temperature message 53 | MyMessage msg(0,V_TEMP); 54 | const float VccMin = 2.0; // Minimum expected Vcc level, in Volts. 55 | const float VccMax = 3.0; // Maximum expected Vcc level, in Volts. 56 | const float VccCorrection = 1.0/1.0; // Measured Vcc by multimeter divided by reported Vcc 57 | float vccLast = 0.0; 58 | 59 | Vcc vcc(VccCorrection); 60 | void before() 61 | { 62 | pinMode(SENSOR_OUTPUT, OUTPUT); 63 | digitalWrite(SENSOR_OUTPUT, LOW); 64 | // Startup up the OneWire library 65 | sensors.begin(); 66 | } 67 | 68 | void setup() 69 | { 70 | 71 | // requestTemperatures() will not block current thread 72 | sensors.setWaitForConversion(false); 73 | } 74 | 75 | void presentation() { 76 | // Send the sketch version information to the gateway and Controller 77 | sendSketchInfo("Temperature Sensor", "1.1"); 78 | 79 | // Fetch the number of attached temperature sensors 80 | numSensors = sensors.getDeviceCount(); 81 | 82 | // Present all sensors to controller 83 | for (int i=0; i(static_cast((getConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.; 114 | #ifdef MY_DEBUG 115 | Serial.print(temperature); 116 | #endif 117 | // Only send data if temperature has changed and no error 118 | #if COMPARE_TEMP == 1 119 | if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) { 120 | #else 121 | if (temperature != -127.00 && temperature != 85.00) { 122 | #endif 123 | 124 | // Send in the new temperature 125 | send(msg.setSensor(i).set(temperature,1)); 126 | // Save new temperatures for next compare 127 | lastTemperature[i]=temperature; 128 | } 129 | } 130 | 131 | if (!isTransportOK()){ 132 | #ifdef MY_DEBUG 133 | Serial.print("Transport ERROR. Waiting for a proper transport reconnect"); 134 | #endif 135 | wait(1000); 136 | } 137 | 138 | wait(100); 139 | digitalWrite(SENSOR_OUTPUT, LOW); 140 | sleep(SLEEP_TIME); 141 | } 142 | 143 | --------------------------------------------------------------------------------