├── 433Mhz ├── Arduino │ └── Clap_sensor │ │ ├── Clap_sensor.ino │ │ └── readme.md └── Attiny │ ├── KAKU_PIR │ ├── KAKU_PIR.ino │ └── readme.md │ ├── KAKU_PIR_LDR │ ├── KAKU_PIR_LDR.ino │ └── readme.md │ ├── KAKU_dual_digital_sensor │ ├── KAKU_dual_digital_sensor.ino │ └── readme.md │ └── readme.md ├── MySensors 1.5 ├── Arduino │ ├── DHTSensor │ │ └── DHTSensor.ino │ ├── LEDDimmer │ │ └── LEDDimmer.ino │ ├── LightSensor │ │ └── lightSensor.ino │ ├── Moodlight │ │ └── Moodlight.ino │ ├── N3ro_sketch │ │ └── N3ro_sketch.ino │ ├── N3ro_sketch_ori │ │ └── N3ro_sketch_ori.ino │ ├── PIRLightSensor │ │ └── PIRLightSensor.ino │ ├── PIRSensor │ │ └── PIRSensor.ino │ ├── PIRSensorResend │ │ └── PIRSensorResend.ino │ ├── Repeater │ │ └── Repeater.ino │ ├── TempHumiditySensor │ │ └── TempHumiditySensor.ino │ ├── alarmSirene │ │ └── alarmSirene.ino │ ├── alarmSwitch │ │ └── alarmSwitch.ino │ ├── alarmSwitchLCD │ │ └── alarmSwitchLCD.ino │ ├── multiSensor │ │ └── multiSensor.ino │ ├── pulseMeter │ │ └── pulseMeter.ino │ ├── pulsereset │ │ └── pulsereset.ino │ ├── testSensor │ │ └── testSensor.ino │ └── voorbeeld │ │ └── voorbeeld.ino └── Attiny │ ├── button-switch │ ├── button-switch.ino │ └── readme.md │ └── readme.md ├── MySensors 2.0 ├── KaKuTransmitter │ └── KaKuTransmitter.ino ├── LEDDimmer │ └── LEDDimmer.ino ├── MotionSensor │ └── MotionSensor.ino ├── WallRemoteSingle │ └── WallRemoteSingle.ino ├── kWhSensor │ └── kWhSensor.ino └── lightSensor │ └── lightSensor.ino ├── attinypins.png ├── libraries ├── MySensors │ ├── MyConfig.h │ ├── MyGateway.cpp │ ├── MyGateway.h │ ├── MyMQTT.cpp │ ├── MyMQTT.h │ ├── MyMessage.cpp │ ├── MyMessage.h │ ├── MySensor.cpp │ ├── MySensor.h │ ├── Version.h │ ├── examples │ │ ├── AirQualitySensor │ │ │ └── AirQualitySensor.ino │ │ ├── BatteryPoweredSensor │ │ │ └── BatteryPoweredSensor.ino │ │ ├── BinarySwitchSensor │ │ │ └── BinarySwitchSensor.ino │ │ ├── BinarySwitchSleepSensor │ │ │ └── BinarySwitchSleepSensor.ino │ │ ├── ClearEepromConfig │ │ │ └── ClearEepromConfig.ino │ │ ├── DallasTemperatureSensor │ │ │ └── DallasTemperatureSensor.ino │ │ ├── DimmableLEDActuator │ │ │ └── DimmableLEDActuator.ino │ │ ├── DimmableLight │ │ │ └── DimmableLight.ino │ │ ├── DistanceSensor │ │ │ └── DistanceSensor.ino │ │ ├── DustSensor │ │ │ └── DustSensor.ino │ │ ├── EnergyMeterPulseSensor │ │ │ └── EnergyMeterPulseSensor.ino │ │ ├── EthernetGateway │ │ │ └── EthernetGateway.ino │ │ ├── HumiditySensor │ │ │ └── HumiditySensor.ino │ │ ├── IrSensor │ │ │ └── IrSensor.ino │ │ ├── LightLuxSensor │ │ │ └── LightLuxSensor.ino │ │ ├── LightSensor │ │ │ └── LightSensor.ino │ │ ├── MAX6875TemperatureSensor │ │ │ └── MAX6875TemperatureSensor.ino │ │ ├── MQTTGateway │ │ │ └── MQTTGateway.ino │ │ ├── MotionSensor │ │ │ └── MotionSensor.ino │ │ ├── MysensorMicro │ │ │ └── MysensorMicro.ino │ │ ├── PressureSensor │ │ │ └── PressureSensor.ino │ │ ├── RF433MhzSensor │ │ │ └── RF433MhzSensor.ino │ │ ├── RFIDLockSensor │ │ │ └── RFIDLockSensor.ino │ │ ├── RealTimeClockDisplaySensor │ │ │ └── RealTimeClockDisplaySensor.ino │ │ ├── RelayActuator │ │ │ └── RelayActuator.ino │ │ ├── RelayWithButtonActuator │ │ │ └── RelayWithButtonActuator.ino │ │ ├── RepeaterNode │ │ │ └── RepeaterNode.ino │ │ ├── SecretKnockSensor │ │ │ └── SecretKnockSensor.ino │ │ ├── SerialGateway │ │ │ └── SerialGateway.ino │ │ ├── ServoActuator │ │ │ └── ServoActuator.ino │ │ ├── SoilMoistSensor │ │ │ └── SoilMoistSensor.ino │ │ ├── TimeAwareSensor │ │ │ └── TimeAwareSensor.ino │ │ ├── TouchDisplaySceneControllerSensor │ │ │ ├── ArialNumFontPlus.c │ │ │ ├── TouchDisplaySceneControllerSensor.ino │ │ │ ├── Ubuntu.c │ │ │ ├── arial_bold.c │ │ │ └── logo.c │ │ ├── UVSensor │ │ │ └── UVSensor.ino │ │ └── WaterMeterPulseSensor │ │ │ └── WaterMeterPulseSensor.ino │ └── utility │ │ ├── LowPower.cpp │ │ ├── LowPower.h │ │ ├── MsTimer2.cpp │ │ ├── MsTimer2.h │ │ ├── PinChangeInt.h │ │ ├── RF24.cpp │ │ ├── RF24.h │ │ ├── RF24_config.h │ │ └── nRF24L01.h └── readVcc │ ├── readVcc.h │ └── readme.md └── readme.md /433Mhz/Arduino/Clap_sensor/Clap_sensor.ino: -------------------------------------------------------------------------------- 1 | // Clap sensor to 433Mhz 2 | // Control your lights with your hands 3 | // Author: Wiebe Nieuwenhuis 4 | // Based on: http://en.code-bude.net/2014/12/08/how-to-build-a-clap-switch-using-arduino/ 5 | 6 | #include 7 | 8 | int txPin = 4; // 433Mhz TX pin 9 | int ID = 123456; // KAKU address 10 | int soundPin = 3; // Mic sensor pin 11 | 12 | int claps = 0; 13 | long detectionSpanInitial = 0; 14 | long detectionSpan = 0; 15 | boolean lightState = false; 16 | 17 | NewRemoteTransmitter transmitter(ID, txPin, 260, 5); // Set-up transmitter 18 | 19 | void setup() { 20 | pinMode(soundPin, INPUT); 21 | digitalWrite (soundPin, HIGH); // internal pull-up 22 | } 23 | 24 | void loop() { 25 | 26 | int sensorState = digitalRead(soundPin); 27 | 28 | if (sensorState == 0) { 29 | if (claps == 0) { 30 | detectionSpanInitial = detectionSpan = millis(); 31 | claps++; 32 | } 33 | else if (claps > 0 && millis()-detectionSpan >= 50) { 34 | detectionSpan = millis(); 35 | claps++; 36 | } 37 | } 38 | 39 | if (millis()-detectionSpanInitial >= 400) { 40 | if (claps == 2) { 41 | if (!lightState) { 42 | lightState = true; 43 | transmitter.sendUnit(1, true); 44 | } 45 | else if (lightState) { 46 | lightState = false; 47 | transmitter.sendUnit(1, false); 48 | } 49 | } 50 | claps = 0; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /433Mhz/Arduino/Clap_sensor/readme.md: -------------------------------------------------------------------------------- 1 | Clap to switch on the lights via 433Mhz. 2 | 3 | Clap 3 times to switch on/off. 4 | -------------------------------------------------------------------------------- /433Mhz/Attiny/KAKU_PIR/KAKU_PIR.ino: -------------------------------------------------------------------------------- 1 | // KlikAanKlikUit PIR sensor 2 | // Uses sleep to reduce power consumption 3 | // Based on AttinyX5 4 | // Author: Wiebe Nieuwenhuis 5 | // 6 | // +-\/-+ 7 | // RST 1|o |8 Vcc 2,7 - 5,5V 8 | // (3) 2| |7 (2) 9 | // PIR SENSOR (4) 3| |6 (1) 10 | // GND 4| |5 (0) 433Mhz Transmitter 11 | // +----+ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #define ID 27951 // KAKU address 18 | #define txPin 0 // 433Mhz TX pin 19 | #define sensorPin 4 // PIR sensor pin 20 | 21 | boolean input = false; 22 | boolean sendInput; 23 | 24 | NewRemoteTransmitter transmitter(ID, txPin, 260, 5); // Set-up transmitter 25 | 26 | ISR (PCINT0_vect) { 27 | 28 | } 29 | 30 | void setup () { 31 | 32 | pinMode (txPin, OUTPUT); 33 | pinMode (sensorPin, INPUT); 34 | digitalWrite (sensorPin, HIGH); // internal pull-up 35 | 36 | // pin change interrupt 37 | PCMSK |= bit (PCINT4); // want pin D4 / pin 3 38 | GIFR |= bit (PCIF); // clear any outstanding interrupts 39 | GIMSK |= bit (PCIE); // enable pin change interrupts 40 | 41 | } 42 | 43 | void loop () { 44 | 45 | 46 | transmitter.sendUnit(1,true); 47 | 48 | goToSleep (); 49 | 50 | } 51 | 52 | // SLEEP FUNCTION 53 | void goToSleep () { 54 | set_sleep_mode(SLEEP_MODE_PWR_DOWN); 55 | ADCSRA = 0; // turn off ADC 56 | power_all_disable (); // power off ADC, Timer 0 and 1, serial interface 57 | sleep_enable(); 58 | sleep_cpu(); 59 | sleep_disable(); 60 | power_all_enable(); // power everything back on 61 | } 62 | -------------------------------------------------------------------------------- /433Mhz/Attiny/KAKU_PIR/readme.md: -------------------------------------------------------------------------------- 1 | A simple KAKU Pir like the AWST-6000. 2 | 3 | Sends a TRUE signal if motion is detected. If there's no more motion it sends a FALSE signal after the timer has finished. 4 | 5 | Attiny sleeps by default and wakes from the interrupt pin where the PIR is connected. 6 | -------------------------------------------------------------------------------- /433Mhz/Attiny/KAKU_PIR_LDR/KAKU_PIR_LDR.ino: -------------------------------------------------------------------------------- 1 | // KlikAanKlikUit PIR sensor with LDR to measure the light 2 | // Will only transmit if its darker than a certain value 3 | // Uses sleep to reduce power consumption 4 | // Based on AttinyX5 5 | // Author: Wiebe Nieuwenhuis 6 | // 7 | // +-\/-+ 8 | // RST 1|o |8 Vcc 2,7 - 5,5V 9 | // LDR SENSOR (3) 2| |7 (2) 10 | // PIR SENSOR (4) 3| |6 (1) 11 | // GND 4| |5 (0) 433Mhz Transmitter 12 | // +----+ 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #define ID 123456 // KAKU address 19 | #define ldrSp 600 // Trigger value of the LDR 20 | #define txPin 0 // 433Mhz TX pin 21 | #define ldrPin 3 // LDR sensor pin 22 | #define pirPin 4 // PIR sensor pin 23 | 24 | int ldr = 0; 25 | boolean input = false; 26 | boolean state = false; 27 | 28 | NewRemoteTransmitter transmitter(ID, txPin, 260, 5); // Set-up transmitter 29 | 30 | ISR (PCINT0_vect) { 31 | 32 | } 33 | 34 | void setup () { 35 | 36 | pinMode (txPin, OUTPUT); 37 | pinMode (ldrPin, INPUT); 38 | pinMode (pirPin, INPUT); 39 | digitalWrite (pirPin, HIGH); // internal pull-up 40 | 41 | // pin change interrupt 42 | PCMSK |= bit (PCINT4); // want pin D4 / pin 3 43 | GIFR |= bit (PCIF); // clear any outstanding interrupts 44 | GIMSK |= bit (PCIE); // enable pin change interrupts 45 | 46 | } 47 | 48 | void loop () { 49 | 50 | input = digitalRead(pirPin); // read the input pin 51 | ldr = analogRead(ldrPin); // read the input pin 52 | 53 | if(input == true && state == false) { 54 | if(ldr < ldrSp){ 55 | transmitter.sendUnit(1, true); 56 | } 57 | state = true; 58 | } 59 | 60 | if(input == false && state == true) { 61 | transmitter.sendUnit(1, false); 62 | state = false; 63 | } 64 | 65 | delay (10); 66 | goToSleep (); 67 | 68 | } 69 | 70 | // SLEEP FUNCTION 71 | void goToSleep () { 72 | set_sleep_mode(SLEEP_MODE_PWR_DOWN); 73 | ADCSRA = 0; // turn off ADC 74 | power_all_disable (); // power off ADC, Timer 0 and 1, serial interface 75 | sleep_enable(); 76 | sleep_cpu(); 77 | sleep_disable(); 78 | power_all_enable(); // power everything back on 79 | } 80 | -------------------------------------------------------------------------------- /433Mhz/Attiny/KAKU_PIR_LDR/readme.md: -------------------------------------------------------------------------------- 1 | A simple KAKU Pir with a LDR to measure the light. If its darker than a certain value the pir will trigger. If its lighter than a certain value the pir won't trigger. 2 | 3 | Sends a TRUE signal if motion is detected. If there's no more motion it sends a FALSE signal after the timer has finished. 4 | 5 | Attiny sleeps by default and wakes from the interrupt pin where the PIR is connected. 6 | -------------------------------------------------------------------------------- /433Mhz/Attiny/KAKU_dual_digital_sensor/KAKU_dual_digital_sensor.ino: -------------------------------------------------------------------------------- 1 | // 2 digital input sensor with sleep/interrupt 2 | // This sketch reads 2 digital sensors and sends true or false over 433mhz (seperate) 3 | // Based on AttinyX5 4 | // Author: Wiebe Nieuwenhuis 5 | // 6 | // +-\/-+ 7 | // RESET 1|o |8 Vcc 2,7 - 5,5V 8 | // SENSOR 1 (3) 2| |7 (2) 9 | // SENSOR 2 (4) 3| |6 (1) 10 | // GND 4| |5 (0) 433Mhz Transmitter 11 | // +----+ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #define ID 123456 // KAKU address 18 | #define txPin 0 // 433Mhz Transmitter pin 19 | #define sensor1Pin 3 // Sensor 1 pin 20 | #define sensor2Pin 4 // Sensor 2 pin 21 | 22 | boolean sensor1Value = false; 23 | boolean sensor2Value = false; 24 | boolean state = false; 25 | boolean state2 = false; 26 | 27 | NewRemoteTransmitter transmitter(ID, txPin, 260, 5); // Set-up transmitter 28 | 29 | ISR (PCINT0_vect) 30 | { 31 | 32 | } 33 | 34 | void setup() { 35 | pinMode (txPin, OUTPUT); 36 | pinMode (sensor1Pin, INPUT); 37 | digitalWrite (sensor1Pin, HIGH); // internal pull-up 38 | pinMode (sensor2Pin, INPUT); 39 | digitalWrite (sensor2Pin, HIGH); // internal pull-up 40 | 41 | // pin change interrupt 42 | PCMSK |= bit (PCINT3); // want pin D3 / pin 2 43 | PCMSK |= bit (PCINT4); // want pin D4 / pin 3 44 | GIFR |= bit (PCIF); // clear any outstanding interrupts 45 | GIMSK |= bit (PCIE); // enable pin change interrupts 46 | 47 | } 48 | 49 | void loop() { 50 | 51 | sensor2Value = digitalRead(sensor1Pin); // Read value of sensor 1 52 | sensor1Value = digitalRead(sensor2Pin); // Read value of sensor 2 53 | 54 | 55 | if(sensor1Value == true && state == false) { 56 | transmitter.sendUnit(1, true); // If door is open send TRUE signal over 433Mhz 57 | state = true; 58 | 59 | } 60 | 61 | if(sensor1Value == false && state == true) { 62 | transmitter.sendUnit(1, false); // If door is closed send FALSE signal over 433Mhz 63 | state = false; 64 | 65 | } 66 | 67 | if(sensor2Value == true && state2 == false) { 68 | transmitter.sendUnit(2, true); // If its raining send TRUE signal over 433Mhz 69 | state2 = true; 70 | 71 | } 72 | 73 | if(sensor2Value == false && state2 == true) { 74 | transmitter.sendUnit(2, false); // If its not raining send FALSE signal over 433Mhz 75 | state2 = false; 76 | 77 | } 78 | 79 | delay(10); // Wait 80 | 81 | goToSleep (); 82 | } 83 | 84 | void goToSleep () { 85 | 86 | set_sleep_mode(SLEEP_MODE_PWR_DOWN); 87 | ADCSRA = 0; // turn off ADC 88 | power_all_disable (); // power off ADC, Timer 0 and 1, serial interface 89 | sleep_enable(); 90 | sleep_cpu(); 91 | sleep_disable(); 92 | power_all_enable(); // power everything back on 93 | 94 | } 95 | -------------------------------------------------------------------------------- /433Mhz/Attiny/KAKU_dual_digital_sensor/readme.md: -------------------------------------------------------------------------------- 1 | Connect 2 digital sensors to the attiny, like a rain sensor (humidity) and a door sensor. Each sensor sends his own 433Mhz signal. 2 | 3 | Attiny sleeps by default and wakes by iterrupts from the sensors. 4 | -------------------------------------------------------------------------------- /433Mhz/Attiny/readme.md: -------------------------------------------------------------------------------- 1 | ATTINY sketches for sensors on 433Mhz. These sketches use the [NewRemoteSwitch](https://github.com/hjgode/homewatch/tree/master/arduino/libraries/NewRemoteSwitch) as 433Mhz library. All these sketches use the sleep function in the ATTINY to reduce power consumption. So you can run them on batteries. 2 | 3 | ATTINY pin number for arduino: 4 | 5 | ![](https://github.com/sweebee/Arduino-home-automation/blob/master/attinypins.png) 6 | -------------------------------------------------------------------------------- /MySensors 1.5/Arduino/DHTSensor/DHTSensor.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "DHT.h" 4 | 5 | // ********** CONFIG ********************************** 6 | 7 | #define NODE_ID 11 8 | #define CHILD_ID_HUM 0 9 | #define CHILD_ID_TEMP 1 10 | #define DHT_PIN 3 11 | #define SLEEP_TIME 60000 12 | 13 | // **************************************************** 14 | 15 | 16 | MySensor gw; 17 | float hum; 18 | float temp; 19 | float lastHum; 20 | float lastTemp; 21 | int force; 22 | MyMessage msgHum(CHILD_ID_HUM, V_HUM); 23 | MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); 24 | 25 | DHT dht(DHT_PIN, DHT22); 26 | 27 | void setup() { 28 | gw.begin(NULL, NODE_ID, false); 29 | dht.begin(); 30 | gw.sendSketchInfo("Temp/Hum sensor", "1.0"); 31 | gw.present(CHILD_ID_HUM, S_HUM); 32 | gw.present(CHILD_ID_TEMP, S_TEMP); 33 | } 34 | 35 | void loop() { 36 | delay(500); 37 | hum = dht.readHumidity(); 38 | temp = dht.readTemperature(); 39 | 40 | if(hum != lastHum || force == 5){ 41 | gw.send(msgHum.set(hum, 1)); 42 | lastHum = hum; 43 | } 44 | 45 | if(temp != lastTemp || force == 5){ 46 | gw.send(msgTemp.set(temp, 1)); 47 | lastTemp = temp; 48 | } 49 | 50 | if(force == 5){ 51 | force = 0; 52 | } else { 53 | force++; 54 | } 55 | 56 | Serial.print("Humidity: "); 57 | Serial.print(hum); 58 | Serial.println("%"); 59 | Serial.print("Temperature: "); 60 | Serial.print(temp); 61 | Serial.println("*C"); 62 | 63 | gw.sleep(SLEEP_TIME); 64 | } 65 | -------------------------------------------------------------------------------- /MySensors 1.5/Arduino/LEDDimmer/LEDDimmer.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // ********** CONFIG ********************************** 5 | 6 | #define NODE_ID AUTO // ID of node 7 | #define CHILD_ID 1 // ID of sensor 8 | #define LED_PIN 3 // Arduino pin attached to MOSFET Gate pin 9 | 10 | #define FADE_DELAY 6 // Delay in ms for each percentage fade up/down (10ms = 1s full-range dim) 11 | #define REPEATER true // Enable repeater mode 12 | 13 | // **************************************************** 14 | 15 | static int currentLevel = 0; // Current dim level... 16 | int requestedLevel = 0; 17 | int fadeDelay = FADE_DELAY; 18 | boolean done = true; 19 | 20 | MySensor node; 21 | MyMessage dimmerMsg(CHILD_ID, V_DIMMER); 22 | MyMessage lightMsg(CHILD_ID, V_LIGHT); 23 | 24 | 25 | 26 | void setup() 27 | { 28 | requestedLevel = node.loadState(0); // Load last dimlevel 29 | node.begin( incomingMessage, NODE_ID, REPEATER ); 30 | node.sendSketchInfo("LED Dimmer", "1.1"); 31 | node.present( CHILD_ID, S_DIMMER ); 32 | node.present(CHILD_ID, S_CUSTOM); 33 | 34 | Serial.print( "Last dimlevel: " ); 35 | Serial.println( requestedLevel ); 36 | 37 | } 38 | 39 | void loop() 40 | { 41 | node.process(); 42 | if(currentLevel != requestedLevel){ 43 | if(requestedLevel > currentLevel){ 44 | currentLevel++; 45 | } else { 46 | currentLevel--; 47 | } 48 | analogWrite( LED_PIN, (int)(currentLevel) ); 49 | delay( fadeDelay ); 50 | if(currentLevel == requestedLevel){ 51 | done = true; 52 | } 53 | } else { 54 | if(fadeDelay != FADE_DELAY && done == true){ 55 | fadeDelay = FADE_DELAY; 56 | } 57 | } 58 | } 59 | 60 | 61 | void incomingMessage(const MyMessage &message) { 62 | if (message.type == V_LIGHT || message.type == V_DIMMER) { 63 | 64 | // Retrieve the power or dim level from the incoming request message 65 | requestedLevel = atoi( message.data ); 66 | 67 | // Adjust incoming level if this is a V_LIGHT variable update [0 == off, 1 == on] 68 | requestedLevel *= ( message.type == V_LIGHT ? 100 : 1 ); 69 | 70 | // Clip incoming level to valid range of 0 to 100 71 | requestedLevel = requestedLevel > 100 ? 100 : requestedLevel; 72 | requestedLevel = requestedLevel < 0 ? 0 : requestedLevel; 73 | requestedLevel = requestedLevel * 255 / 100; 74 | 75 | Serial.print( "Changing level from " ); 76 | Serial.print( currentLevel ); 77 | Serial.print( ", to " ); 78 | Serial.println( requestedLevel ); 79 | 80 | node.saveState(0, requestedLevel); // Save last dimlevel 81 | int fadeDelay = FADE_DELAY; 82 | // Inform the gateway of the current DimmableLED's SwitchPower1 and LoadLevelStatus value... 83 | node.send(lightMsg.set(currentLevel > 0 ? 1 : 0)); 84 | 85 | } 86 | if(message.type == V_VAR1){ 87 | fadeDelay = atoi( message.data ); 88 | done = false; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /MySensors 1.5/Arduino/LightSensor/lightSensor.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | //********** CONFIG ********************************** 6 | 7 | #define NODE_ID AUTO // ID of node 8 | #define CHILD_ID 1 // ID of sensor 9 | #define LIGHT_PIN A0 // Pin connected to the PIR 10 | 11 | #define MAX_LIGHT 500 // Max light value of LDR (100%) 12 | #define INT_PULL false // Use internal Pull-up resistor 13 | #define SLEEP_TIME 60000 // Sleep time between reads 14 | 15 | #define MIN_V 2000 // empty voltage (0%) 16 | #define MAX_V 3200 // full voltage (100%) 17 | 18 | //**************************************************** 19 | 20 | MySensor node; 21 | MyMessage msg(CHILD_ID, V_LIGHT_LEVEL); 22 | 23 | int lastLightLevel; 24 | int oldBatteryPcnt = 0; 25 | int forceCnt = 0; 26 | boolean forceSend = false; 27 | 28 | void setup() 29 | { 30 | node.begin(NULL, NODE_ID, false); 31 | node.sendSketchInfo("Light sensor","1.1"); 32 | node.present(CHILD_ID, S_LIGHT_LEVEL); 33 | if(INT_PULL){ 34 | pinMode(LIGHT_PIN, HIGH); 35 | } 36 | } 37 | 38 | void loop() 39 | { 40 | if(forceCnt < 30){ 41 | forceCnt++; 42 | forceSend = false; 43 | } else { 44 | forceCnt = 0; 45 | forceSend = true; 46 | } 47 | sendLight(forceSend); 48 | sendBattery(forceSend); 49 | node.sleep(SLEEP_TIME); 50 | } 51 | 52 | // FUNCTIONS 53 | 54 | void sendLight(boolean forceSend) // SEND LIGHT LEVEL 55 | { 56 | float light = analogRead(LIGHT_PIN); 57 | int lightLevel = max(map(light, MAX_LIGHT, 0, 0, 100), 0); // Convert light to percentage 58 | if (lightLevel != lastLightLevel || forceSend) { 59 | node.send(msg.set(lightLevel)); 60 | lastLightLevel = lightLevel; 61 | } 62 | } 63 | 64 | void sendBattery(boolean forceSend) // SEND BATTERYLEVEL 65 | { 66 | int batteryPcnt = min(map(readVcc(), MIN_V, MAX_V, 0, 100), 100); // Get VCC and convert to percentage 67 | if (batteryPcnt != oldBatteryPcnt || forceSend) { // If battery percentage has changed 68 | node.sendBatteryLevel(batteryPcnt); // Send battery percentage to gateway 69 | oldBatteryPcnt = batteryPcnt; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /MySensors 1.5/Arduino/Moodlight/Moodlight.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define LED_PIN 4 6 | #define NODE_ID 50 7 | 8 | Adafruit_NeoPixel strip = Adafruit_NeoPixel(16, LED_PIN, NEO_GRB + NEO_KHZ800); 9 | 10 | int R; 11 | int G; 12 | int B; 13 | 14 | int Rold; 15 | int Gold; 16 | int Bold; 17 | 18 | 19 | 20 | int currentLevel = 0; // Dimlevel 21 | long RGB_values[3] = {0, 0, 0}; // Colors 22 | 23 | MySensor gw; 24 | MyMessage dimmerMsg(0, V_DIMMER); 25 | 26 | void setup() { 27 | strip.begin(); 28 | strip.show(); 29 | 30 | gw.begin(incomingMessage, NODE_ID, false); 31 | gw.sendSketchInfo("Mood Light", "3.0"); 32 | gw.present(0, S_CUSTOM); 33 | gw.present( 0, S_DIMMER ); 34 | // colorChange(RED, GREEN, BUE, FADE) 35 | colorChange(255, 0, 255, true); // Purple 36 | colorChange(0, 0, 0, true); // Off 37 | } 38 | 39 | void loop() { 40 | gw.process(); 41 | } 42 | 43 | void incomingMessage(const MyMessage &message) { 44 | 45 | if (message.type == V_VAR1) { 46 | String hexstring = message.getString(); 47 | 48 | // Check if contains hex character 49 | 50 | // Remove the character 51 | hexstring.remove(0, 1); 52 | 53 | Serial.println(hexstring); 54 | long number = (long) strtol( &hexstring[0], NULL, 16); 55 | RGB_values[0] = number >> 16; 56 | RGB_values[1] = number >> 8 & 0xFF; 57 | RGB_values[2] = number & 0xFF; 58 | 59 | R = RGB_values[0]; 60 | G = RGB_values[1]; 61 | B = RGB_values[2]; 62 | colorChange(R, G, B, true); 63 | 64 | // Write some debug info 65 | Serial.print("Red is " ); 66 | Serial.println(RGB_values[0]); 67 | Serial.print("Green is " ); 68 | Serial.println(RGB_values[1]); 69 | Serial.print("Blue is " ); 70 | Serial.println(RGB_values[2]); 71 | } 72 | 73 | if (message.type == V_DIMMER) { 74 | // Get the dimlevel 75 | int reqLevel = atoi( message.data ); 76 | // Clip incoming level to valid range of 0 to 100 77 | reqLevel = reqLevel > 100 ? 100 : reqLevel; 78 | reqLevel = reqLevel < 0 ? 0 : reqLevel; 79 | 80 | // Set brightness 81 | Serial.print("Dimming to "); 82 | Serial.println(reqLevel); 83 | fadeToLevel(reqLevel); 84 | 85 | } 86 | 87 | } 88 | 89 | // CHANGE TO COLOR 90 | void colorChange(uint32_t R, uint32_t G, uint32_t B, uint32_t fade) { 91 | if (!fade) { 92 | Rold = R; 93 | Bold = B; 94 | Gold = G; 95 | for (int i = 0; i < 16; i++) { 96 | strip.setPixelColor(i, strip.Color(Rold, Gold, Bold)); 97 | } 98 | strip.show(); 99 | } else { 100 | for (int t = 0; t < 256; t++) { 101 | if (R > Rold) { 102 | Rold++; 103 | } 104 | if (R < Rold) { 105 | Rold--; 106 | } 107 | if (G > Gold) { 108 | Gold++; 109 | } 110 | if (G < Gold) { 111 | Gold--; 112 | } 113 | if (B > Bold) { 114 | Bold++; 115 | } 116 | if (B < Bold) { 117 | Bold--; 118 | } 119 | for (int i = 0; i < 16; i++) { 120 | strip.setPixelColor(i, strip.Color(Rold, Gold, Bold)); 121 | } 122 | strip.show(); 123 | delay(2); 124 | } 125 | } 126 | } 127 | 128 | // DIMMER FADE 129 | void fadeToLevel( int toLevel ) { 130 | 131 | int delta = ( toLevel - currentLevel ) < 0 ? -1 : 1; 132 | 133 | while ( currentLevel != toLevel ) { 134 | currentLevel += delta; 135 | strip.setBrightness(currentLevel); 136 | if(currentLevel == 1){ 137 | for (int i = 0; i < 16; i++) { 138 | strip.setPixelColor(i, strip.Color(Rold, Gold, Bold)); 139 | } 140 | } 141 | strip.show(); 142 | delay(15); 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /MySensors 1.5/Arduino/N3ro_sketch/N3ro_sketch.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define NODE_ID 100 // ID of node 7 | #define SLEEP_TIME 10000 // Sleep time between reports (in milliseconds) 8 | 9 | #define CHILD_ID_PIR 1 // ID of the sensor PIR 10 | #define CHILD_ID_HUM 2 // ID of the sensor HUM 11 | #define CHILD_ID_TEMP 3 // ID of the sensor TEMP 12 | #define CHILD_ID_LIGHT 4 // ID of the sensor LIGHT 13 | 14 | #define PIR_SENSOR_DIGITAL 3 // PIR pin 15 | #define HUMIDITY_SENSOR_DIGITAL_PIN 4 // DHT pin 16 | #define LIGHT_SENSOR_ANALOG_PIN 0 // LDR pin 17 | 18 | #define MIN_V 2700 // empty voltage (0%) 19 | #define MAX_V 3200 // full voltage (100%) 20 | 21 | MySensor gw; 22 | // Initialize Variables 23 | MyMessage msgPir(CHILD_ID_PIR, V_TRIPPED); 24 | MyMessage msgHum(CHILD_ID_HUM, V_HUM); 25 | MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); 26 | MyMessage msgLight(CHILD_ID_LIGHT, V_LIGHT_LEVEL); 27 | 28 | DHT dht; 29 | float lastTemp; 30 | float lastHum; 31 | boolean metric = true; 32 | int oldBatteryPcnt; 33 | int lastLightLevel; 34 | int sentValue; 35 | 36 | void setup() 37 | { 38 | gw.begin(NULL, NODE_ID, false); 39 | 40 | // Register all sensors to gateway (they will be created as child devices) 41 | gw.present(CHILD_ID_PIR, S_MOTION); 42 | gw.present(CHILD_ID_HUM, S_HUM); 43 | gw.present(CHILD_ID_TEMP, S_TEMP); 44 | gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL); 45 | 46 | pinMode(PIR_SENSOR_DIGITAL, INPUT); 47 | digitalWrite(PIR_SENSOR_DIGITAL, HIGH); 48 | 49 | dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); 50 | } 51 | 52 | void loop() 53 | { 54 | Serial.println("Waking up..."); 55 | sendBattery(); 56 | sendPir(); 57 | sendTemp(); 58 | sendHum(); 59 | sendLight(); 60 | Serial.println("Going to sleep..."); 61 | Serial.println(""); 62 | gw.sleep(PIR_SENSOR_DIGITAL-2, CHANGE, SLEEP_TIME); 63 | } 64 | 65 | 66 | void sendBattery() // Measure battery 67 | { 68 | int batteryPcnt = min(map(readVcc(), MIN_V, MAX_V, 0, 100), 100); 69 | if (batteryPcnt != oldBatteryPcnt) { 70 | gw.sendBatteryLevel(batteryPcnt); // Send battery percentage 71 | oldBatteryPcnt = batteryPcnt; 72 | } 73 | Serial.print("---------- Battery: "); 74 | Serial.println(batteryPcnt); 75 | } 76 | 77 | 78 | 79 | void sendPir() // Get value of PIR 80 | { 81 | int value = digitalRead(PIR_SENSOR_DIGITAL); // Get value of PIR 82 | if (value != sentValue) { // If status of PIR has changed 83 | gw.send(msgPir.set(value == HIGH ? 1 : 0)); // Send PIR status to gateway 84 | sentValue = value; 85 | } 86 | Serial.print("---------- PIR: "); 87 | Serial.println(value); 88 | } 89 | 90 | 91 | 92 | void sendTemp() // Get temperature 93 | { 94 | float temperature = dht.getTemperature(); 95 | if (isnan(temperature)) { 96 | Serial.println("Failed reading temperature from DHT"); 97 | } else { 98 | if (temperature != lastTemp) { 99 | gw.send(msgTemp.set(temperature, 1)); 100 | lastTemp = temperature; 101 | } 102 | Serial.print("---------- Temp: "); 103 | Serial.println(temperature); 104 | } 105 | } 106 | 107 | 108 | void sendHum() // Get humidity 109 | { 110 | float humidity = dht.getHumidity(); 111 | if (isnan(humidity)) { 112 | Serial.println("Failed reading humidity from DHT"); 113 | } else { 114 | if (humidity != lastHum) { 115 | gw.send(msgHum.set(humidity, 1)); 116 | lastHum = humidity; 117 | } 118 | Serial.print("---------- Humidity: "); 119 | Serial.println(humidity); 120 | } 121 | } 122 | 123 | 124 | void sendLight() // Get light level 125 | { 126 | int lightLevel = (1023 - analogRead(LIGHT_SENSOR_ANALOG_PIN)) / 10.23; 127 | if (lightLevel != lastLightLevel) { 128 | gw.send(msgLight.set(lightLevel)); 129 | lastLightLevel = lightLevel; 130 | } 131 | Serial.print("---------- Light: "); 132 | Serial.println(lightLevel); 133 | } 134 | -------------------------------------------------------------------------------- /MySensors 1.5/Arduino/N3ro_sketch_ori/N3ro_sketch_ori.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | #define NODE_ID 100 // ID of node 8 | unsigned long SLEEP_TIME = 60000; // Sleep time between reports (in milliseconds) 9 | 10 | #define CHILD_ID_PIR 1 // Id of the sensor PIR 11 | #define CHILD_ID_HUM 2 // Id of the sensor HUM 12 | #define CHILD_ID_TEMP 3 // Id of the sensor TEMP 13 | #define CHILD_ID_LIGHT 4 // Id of the sensor LIGHT 14 | 15 | #define PIR_SENSOR_DIGITAL 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!) 16 | #define INTERRUPT PIR_SENSOR_DIGITAL-2 // Usually the interrupt = pin -2 (on uno/nano anyway) 17 | #define HUMIDITY_SENSOR_DIGITAL_PIN 4 18 | #define LIGHT_SENSOR_ANALOG_PIN 0 19 | 20 | MySensor gw; 21 | // Initialize Variables 22 | MyMessage msgPir(CHILD_ID_PIR, V_TRIPPED); 23 | MyMessage msgHum(CHILD_ID_HUM, V_HUM); 24 | MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); 25 | MyMessage msgLight(CHILD_ID_LIGHT, V_LIGHT_LEVEL); 26 | 27 | DHT dht; 28 | float lastTemp; 29 | float lastHum; 30 | boolean metric = true; 31 | int oldBatteryPcnt; 32 | int lastLightLevel; 33 | 34 | 35 | int MIN_V = 2700; // empty voltage (0%) 36 | int MAX_V = 3200; // full voltage (100%) 37 | 38 | void setup() 39 | { 40 | gw.begin(NULL, NODE_ID, false); 41 | 42 | //PIR 43 | // Send the sketch version information to the gateway and Controller 44 | gw.sendSketchInfo("Motion Sensor", "1.0"); 45 | 46 | pinMode(PIR_SENSOR_DIGITAL, INPUT); // sets the motion sensor digital pin as input 47 | digitalWrite(PIR_SENSOR_DIGITAL, HIGH); 48 | // Register all sensors to gw (they will be created as child devices) 49 | gw.present(CHILD_ID_PIR, S_MOTION); 50 | 51 | //DHT 52 | dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); 53 | 54 | // Send the Sketch Version Information to the Gateway 55 | gw.sendSketchInfo("Humidity", "1.0"); 56 | 57 | // Register all sensors to gw (they will be created as child devices) 58 | gw.present(CHILD_ID_HUM, S_HUM); 59 | gw.present(CHILD_ID_TEMP, S_TEMP); 60 | 61 | metric = gw.getConfig().isMetric; 62 | 63 | //LIGHT 64 | // Send the sketch version information to the gateway and Controller 65 | gw.sendSketchInfo("Light Sensor", "1.0"); 66 | 67 | // Register all sensors to gateway (they will be created as child devices) 68 | gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL); 69 | 70 | } 71 | 72 | void loop() 73 | { 74 | 75 | // Measure battery 76 | float batteryV = readVcc(); 77 | int batteryPcnt = (((batteryV - MIN_V) / (MAX_V - MIN_V)) * 100 ); 78 | if (batteryPcnt > 100) { 79 | batteryPcnt = 100; 80 | } 81 | 82 | if (batteryPcnt != oldBatteryPcnt) { 83 | gw.sendBatteryLevel(batteryPcnt); // Send battery percentage 84 | oldBatteryPcnt = batteryPcnt; 85 | } 86 | Serial.print("---------- Battery: "); 87 | Serial.println(batteryPcnt); 88 | 89 | // Read digital motion value 90 | boolean tripped = digitalRead(PIR_SENSOR_DIGITAL) == HIGH; 91 | Serial.print("---------- PIR: "); 92 | Serial.println(tripped); 93 | gw.send(msgPir.set(tripped ? "1" : "0")); // Send tripped value to gw 94 | 95 | float temperature = dht.getTemperature(); 96 | if (isnan(temperature)) { 97 | Serial.println("Failed reading temperature from DHT"); 98 | } 99 | 100 | if (!metric) { 101 | temperature = dht.toFahrenheit(temperature); 102 | } 103 | 104 | if (temperature != lastTemp) { 105 | gw.send(msgTemp.set(temperature, 1)); 106 | Serial.print("---------- Temp: "); 107 | Serial.println(temperature); 108 | lastTemp = temperature; 109 | } 110 | 111 | float humidity = dht.getHumidity(); 112 | if (isnan(humidity)) { 113 | Serial.println("Failed reading humidity from DHT"); 114 | } 115 | 116 | if (humidity != lastHum) { 117 | gw.send(msgHum.set(humidity, 1)); 118 | Serial.print("---------- Humidity: "); 119 | Serial.println(humidity); 120 | lastHum = humidity; 121 | } 122 | // Light 123 | int lightLevel = (1023 - analogRead(LIGHT_SENSOR_ANALOG_PIN)) / 10.23; 124 | //Serial.println(lightLevel); 125 | if (lightLevel != lastLightLevel) { 126 | gw.send(msgLight.set(lightLevel)); 127 | lastLightLevel = lightLevel; 128 | Serial.print("---------- Light: "); 129 | Serial.println(lightLevel); 130 | } 131 | // Sleep until interrupt comes in on motion sensor. Send update every two minute. 132 | gw.sleep(INTERRUPT, CHANGE, SLEEP_TIME); 133 | } 134 | -------------------------------------------------------------------------------- /MySensors 1.5/Arduino/PIRLightSensor/PIRLightSensor.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // ********** CONFIG ********************************** 6 | 7 | #define NODE_ID AUTO // ID of node 8 | 9 | #define PIR_ID 1 // ID of sensor 10 | #define PIR_PIN 3 // Pin connected to the PIR 11 | 12 | #define LIGHT_ID 2 // ID of light 13 | #define LIGHT_PIN A2 // Pin connected to the LDR 14 | 15 | #define MIN_V 2000 // empty voltage (0%) 16 | #define MAX_V 3200 // full voltage (100%) 17 | 18 | // **************************************************** 19 | 20 | MySensor node; 21 | MyMessage PIRMsg(PIR_ID, V_TRIPPED); 22 | MyMessage lightMsg(LIGHT_ID, V_LIGHT_LEVEL); 23 | 24 | int oldBatteryPcnt; 25 | int tripped; 26 | int sentTripped; 27 | int lastLightLevel = -1; 28 | 29 | void setup() 30 | { 31 | node.begin(NULL, NODE_ID, false); 32 | 33 | // Register all sensors to gateway (they will be created as child devices) 34 | node.present(PIR_ID, S_MOTION); 35 | node.present(LIGHT_ID, S_LIGHT_LEVEL); 36 | 37 | pinMode(PIR_PIN, INPUT); 38 | digitalWrite(PIR_PIN, HIGH); 39 | digitalWrite(LIGHT_PIN, HIGH); 40 | } 41 | 42 | 43 | void loop() 44 | { 45 | 46 | tripped = digitalRead(PIR_PIN); // Get value of PIR 47 | if(tripped == HIGH) { 48 | sendLight(); // Send lightlevel 49 | } 50 | sendPIR(); // Send PIR state 51 | sendBattery(); // Send batterylevel 52 | node.sleep(PIR_PIN - 2, CHANGE); // Sleep until something happens with the sensor 53 | } 54 | 55 | 56 | 57 | // FUNCTIONS 58 | 59 | void sendBattery() // SEND BATTERYLEVEL 60 | { 61 | int batteryPcnt = constrain(map(readVcc(), MIN_V, MAX_V, 0, 100), 0, 100); // Get VCC and convert to percentage 62 | if (batteryPcnt != oldBatteryPcnt) { // If battery percentage has changed 63 | node.sendBatteryLevel(batteryPcnt); // Send battery percentage to gateway 64 | oldBatteryPcnt = batteryPcnt; 65 | } 66 | } 67 | 68 | void sendPIR() // SEND PIR STATUS 69 | { 70 | if (tripped != sentTripped) { // If status of PIR has changed 71 | node.send(PIRMsg.set(tripped == HIGH ? 1 : 0)); // Send PIR status to gateway 72 | sentTripped = tripped; 73 | } 74 | } 75 | 76 | void sendLight() // SEND LIGHTLEVEL 77 | { 78 | int MAX_LIGHT = 1023; 79 | int MIN_LIGHT = 400; 80 | float light = analogRead(LIGHT_PIN); // Get value of the LDR 81 | 82 | int lightLevel = constrain(map(light, MAX_LIGHT, MIN_LIGHT, 0, 100), 0, 100); // Convert light to percentage 83 | Serial.println("Lightlevel: "); 84 | Serial.print(lightlevel); 85 | if (lightLevel != lastLightLevel) { // If value of LDR has changed 86 | node.send(lightMsg.set(lightLevel)); // Send value of LDR to gateway 87 | lastLightLevel = lightLevel; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /MySensors 1.5/Arduino/PIRSensor/PIRSensor.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // ********** CONFIG ********************************** 6 | 7 | #define NODE_ID AUTO // ID of node 8 | #define CHILD_ID 1 // ID of sensor 9 | #define PIR_PIN 3 // Pin connected to the PIR 10 | 11 | #define MIN_V 2000 // empty voltage (0%) 12 | #define MAX_V 3200 // full voltage (100%) 13 | 14 | // **************************************************** 15 | 16 | MyMessage msg(CHILD_ID, V_TRIPPED); 17 | MySensor node; 18 | 19 | int oldBatteryPcnt; 20 | int sentValue; 21 | int forceSend = 0; 22 | 23 | void setup() 24 | { 25 | node.begin(NULL, NODE_ID, false); 26 | node.sendSketchInfo("PIR sensor", "1.1"); 27 | node.present(CHILD_ID, S_MOTION); 28 | pinMode(PIR_PIN, INPUT); 29 | digitalWrite(PIR_PIN, HIGH); 30 | } 31 | 32 | void loop() 33 | { 34 | sendPIR(); // Send PIR value 35 | sendBattery(); // Send batterylevel 36 | node.sleep(PIR_PIN-2, CHANGE); // Sleep until something happens with the sensor 37 | } 38 | 39 | // FUNCTIONS 40 | 41 | void sendPIR() // SEND PIR STATUS 42 | { 43 | int value = digitalRead(PIR_PIN); // Get value of PIR 44 | if (value != sentValue) { // If status of PIR has changed 45 | node.send(msg.set(value)); // Send PIR status to gateway 46 | sentValue = value; 47 | } 48 | } 49 | 50 | void sendBattery() // SEND BATTERYLEVEL 51 | { 52 | forceSend++; 53 | int batteryPcnt = min(map(readVcc(), MIN_V, MAX_V, 0, 100), 100); // Get VCC and convert to percentage 54 | if (batteryPcnt != oldBatteryPcnt || forceSend >= 20) { // If battery percentage has changed 55 | node.sendBatteryLevel(batteryPcnt); // Send battery percentage to gateway 56 | oldBatteryPcnt = batteryPcnt; 57 | forceSend = 0; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /MySensors 1.5/Arduino/PIRSensorResend/PIRSensorResend.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // ********** CONFIG ********************************** 6 | 7 | #define NODE_ID AUTO // ID of node 8 | #define CHILD_ID 1 // ID of sensor 9 | #define PIR_PIN 3 // Pin connected to the PIR 10 | 11 | #define MIN_V 2000 // empty voltage (0%) 12 | #define MAX_V 3200 // full voltage (100%) 13 | 14 | // **************************************************** 15 | 16 | MyMessage msg(CHILD_ID, V_TRIPPED); 17 | MySensor node; 18 | 19 | int oldBatteryPcnt; 20 | int sentValue; 21 | int forceSend = 0; 22 | 23 | void setup() 24 | { 25 | node.begin(NULL, NODE_ID, false); 26 | node.sendSketchInfo("PIR Sensor", "1.2"); 27 | node.present(CHILD_ID, S_MOTION); 28 | pinMode(PIR_PIN, INPUT); 29 | digitalWrite(PIR_PIN, HIGH); 30 | } 31 | 32 | void loop() 33 | { 34 | 35 | // Get PIR 36 | int value = digitalRead(PIR_PIN); // Get value of PIR 37 | if (value != sentValue) { // If status of PIR has changed 38 | resend(msg.set(value), 5); // Send PIR status to gateway 39 | sentValue = value; 40 | } 41 | 42 | // Send batterylevel 43 | sendBattery(); 44 | 45 | // Sleep until something happens with the sensor 46 | node.sleep(PIR_PIN-2, CHANGE); 47 | } 48 | 49 | // FUNCTIONS 50 | 51 | void sendBattery() // Send battery percentage to GW 52 | { 53 | forceSend++; 54 | int batteryPcnt = min(map(readVcc(), MIN_V, MAX_V, 0, 100), 100); // Get VCC and convert to percentage 55 | if (batteryPcnt != oldBatteryPcnt || forceSend >= 20) { // If battery percentage has changed 56 | node.sendBatteryLevel(batteryPcnt); // Send battery percentage to gateway 57 | oldBatteryPcnt = batteryPcnt; 58 | forceSend = 0; 59 | } 60 | } 61 | 62 | void resend(MyMessage &msg, int repeats) // Resend messages if not received by GW 63 | { 64 | int repeat = 0; 65 | int repeatDelay = 0; 66 | boolean ack = false; 67 | 68 | while ((ack == false) and (repeat < repeats)) { 69 | if (node.send(msg)) { 70 | ack = true; 71 | } else { 72 | ack = false; 73 | repeatDelay += 100; 74 | } 75 | repeat++; 76 | delay(repeatDelay); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /MySensors 1.5/Arduino/Repeater/Repeater.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | //********** CONFIG ********************************** 5 | 6 | #define NODE_ID AUTO 7 | 8 | // **************************************************** 9 | 10 | MySensor gw; 11 | 12 | void setup() 13 | { 14 | // The third argument enables repeater mode. 15 | gw.begin(NULL, NODE_ID, true); 16 | 17 | //Send the sensor node sketch version information to the gateway 18 | gw.sendSketchInfo("Repeater", "1.0"); 19 | } 20 | 21 | void loop() 22 | { 23 | // By calling process() you route messages in the background 24 | gw.process(); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /MySensors 1.5/Arduino/TempHumiditySensor/TempHumiditySensor.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | //********** CONFIG ********************************** 7 | 8 | #define NODE_ID 210 // ID of node 9 | #define CHILD_ID_HUM 0 // ID of humidity 10 | #define CHILD_ID_TEMP 1 // ID of temperature 11 | #define SENSOR_PIN 3 // Pin connected to the sensor 12 | 13 | #define SLEEP_TIME 60000 // Sleep time between reads 14 | 15 | #define MIN_V 2000 // empty voltage (0%) 16 | #define MAX_V 3200 // full voltage (100%) 17 | 18 | 19 | //**************************************************** 20 | 21 | MySensor node; 22 | int oldBatteryPcnt = 0; 23 | DHT dht; 24 | float lastTemp; 25 | float lastHum; 26 | boolean metric = true; 27 | MyMessage msgHum(CHILD_ID_HUM, V_HUM); 28 | MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); 29 | 30 | 31 | void setup() 32 | { 33 | node.begin(NULL,NODE_ID,false); 34 | dht.setup(SENSOR_PIN); 35 | 36 | // Register all sensors to node (they will be created as child devices) 37 | node.present(CHILD_ID_HUM, S_HUM); 38 | node.present(CHILD_ID_TEMP, S_TEMP); 39 | 40 | metric = node.getConfig().isMetric; 41 | } 42 | 43 | void loop() 44 | { 45 | 46 | // Measure battery 47 | int batteryPcnt = min(map(readVcc(), MIN_V, MAX_V, 0, 100), 100); // Convert voltage to percentage 48 | 49 | if (batteryPcnt != oldBatteryPcnt) { // If battery percentage has changed 50 | node.sendBatteryLevel(batteryPcnt); // Send battery percentage to gateway 51 | oldBatteryPcnt = batteryPcnt; 52 | } 53 | 54 | // Do sensor things 55 | delay(dht.getMinimumSamplingPeriod()); 56 | 57 | float temperature = dht.getTemperature(); 58 | if (isnan(temperature)) { 59 | Serial.println("Failed reading temperature from DHT"); 60 | } else if (temperature != lastTemp) { 61 | lastTemp = temperature; 62 | if (!metric) { 63 | temperature = dht.toFahrenheit(temperature); 64 | } 65 | node.send(msgTemp.set(temperature, 1)); 66 | Serial.print("T: "); 67 | Serial.println(temperature); 68 | } 69 | 70 | float humidity = dht.getHumidity(); 71 | if (isnan(humidity)) { 72 | Serial.println("Failed reading humidity from DHT"); 73 | } else if (humidity != lastHum) { 74 | lastHum = humidity; 75 | node.send(msgHum.set(humidity, 1)); 76 | Serial.print("H: "); 77 | Serial.println(humidity); 78 | } 79 | 80 | node.sleep(SLEEP_TIME); //sleep a bit 81 | } 82 | -------------------------------------------------------------------------------- /MySensors 1.5/Arduino/alarmSirene/alarmSirene.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define NODE_ID 52 5 | #define CHILD_ID 1 6 | #define ALARM_PIN 3 // Arduino Digital I/O pin number for first relay (second on pin+1 etc) 7 | #define ON 1 // GPIO value to write to turn on attached relay 8 | #define OFF 0 // GPIO value to write to turn off attached relay 9 | 10 | MySensor node; 11 | 12 | void setup() 13 | { 14 | node.begin(incomingMessage, NODE_ID, false); 15 | node.present(CHILD_ID, S_LIGHT); 16 | pinMode(ALARM_PIN, OUTPUT); 17 | } 18 | 19 | 20 | void loop() 21 | { 22 | node.process(); 23 | } 24 | 25 | void incomingMessage(const MyMessage &message) { 26 | if (message.type==V_LIGHT && message.sensor == CHILD_ID) { 27 | digitalWrite(ALARM_PIN, message.getBool()?ON:OFF); 28 | Serial.print("Alarm: "); 29 | Serial.println(message.getBool()); 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /MySensors 1.5/Arduino/alarmSwitch/alarmSwitch.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define NODE_ID 53 7 | #define CHILD_ID 1 8 | #define LED_OFF A0 9 | #define LED_ON A1 10 | #define ON 1 11 | #define OFF 0 12 | 13 | Password password = Password( "1463" ); 14 | long previousMillis = 0; 15 | long interval = 1000; 16 | boolean ALARM; 17 | int LED_STATE; 18 | int FALSE = 0; 19 | const byte ROWS = 4; //four rows 20 | const byte COLS = 3; //three columns 21 | char keys[ROWS][COLS] = { 22 | {'1','2','3'}, 23 | {'4','5','6'}, 24 | {'7','8','9'}, 25 | {'*','0','#'} 26 | }; 27 | byte rowPins[ROWS] = {8, 7, 6, 5}; //connect to the row pinouts of the keypad 28 | byte colPins[COLS] = {4, 3, 2}; //connect to the column pinouts of the keypad 29 | 30 | Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); 31 | MySensor node; 32 | MyMessage msg(CHILD_ID, V_LIGHT); 33 | 34 | void setup() { 35 | node.begin(incomingMessage, NODE_ID, false); 36 | node.present(CHILD_ID, S_LIGHT); 37 | pinMode(LED_ON,OUTPUT); 38 | pinMode(LED_OFF,OUTPUT); 39 | digitalWrite(LED_ON, node.loadState(0)); 40 | digitalWrite(LED_OFF, node.loadState(1)); 41 | ALARM = node.loadState(2); 42 | keypad.addEventListener(keypadEvent); //add an event listener for this keypad 43 | } 44 | 45 | void loop() { 46 | node.process(); 47 | keypad.getKey(); 48 | blink(); 49 | } 50 | 51 | void incomingMessage(const MyMessage &message) { 52 | if (message.type==V_LIGHT && message.sensor == CHILD_ID) { 53 | turnAlarm(message.getBool()); 54 | } 55 | } 56 | 57 | void keypadEvent(KeypadEvent eKey){ 58 | switch (keypad.getState()){ 59 | case PRESSED: 60 | Serial.print("Pressed: "); 61 | Serial.println(eKey); 62 | switch (eKey){ 63 | case '*': checkPassword(); password.reset(); break; 64 | case '#': password.reset(); break; 65 | default: password.append(eKey); 66 | } 67 | } 68 | } 69 | 70 | void checkPassword(){ 71 | if (password.evaluate()){ 72 | Serial.println("Success"); 73 | FALSE = 0; 74 | if(ALARM == ON) { 75 | ALARM = OFF; 76 | } else { 77 | ALARM = ON; 78 | } 79 | turnAlarm(ALARM); 80 | node.send(msg.set(ALARM)); 81 | }else{ 82 | Serial.println("Wrong"); 83 | FALSE++; 84 | if(FALSE > 5) { 85 | Serial.println("To many tries"); 86 | digitalWrite(LED_ON, LOW); 87 | digitalWrite(LED_OFF, LOW); 88 | delay(200); 89 | for (int i=0; i <= 3; i++){ 90 | digitalWrite(LED_ON, HIGH); 91 | delay(200); 92 | digitalWrite(LED_ON, LOW); 93 | delay(200); 94 | } 95 | setLed(); 96 | } else { 97 | digitalWrite(LED_ON, LOW); 98 | digitalWrite(LED_OFF, LOW); 99 | delay(50); 100 | for (int i=0; i <= 3; i++){ 101 | digitalWrite(LED_ON, HIGH); 102 | delay(50); 103 | digitalWrite(LED_ON, LOW); 104 | delay(50); 105 | } 106 | setLed(); 107 | } 108 | } 109 | } 110 | 111 | void turnAlarm(boolean STATE) { 112 | Serial.print("Alarm: "); 113 | Serial.println(STATE); 114 | ALARM = STATE; 115 | node.saveState(2, ALARM); 116 | setLed(); 117 | } 118 | 119 | void setLed() { 120 | if(ALARM == true) { 121 | digitalWrite(LED_OFF, LOW); 122 | node.saveState(0, 1); 123 | node.saveState(1, 0); 124 | } else { 125 | digitalWrite(LED_OFF, HIGH); 126 | digitalWrite(LED_ON, LOW); 127 | node.saveState(0, 0); 128 | node.saveState(1, 1); 129 | } 130 | } 131 | 132 | void blink() { 133 | unsigned long currentMillis = millis(); 134 | if(currentMillis - previousMillis > interval) { 135 | previousMillis = currentMillis; 136 | if(ALARM == true) { 137 | if(LED_STATE == 0){ 138 | LED_STATE = 1; 139 | } else { 140 | LED_STATE = 0; 141 | } 142 | digitalWrite(LED_ON, LED_STATE); 143 | } 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /MySensors 1.5/Arduino/alarmSwitchLCD/alarmSwitchLCD.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address 10 | 11 | 12 | const byte ROWS = 4; //four rows 13 | const byte COLS = 3; //three columns 14 | char keys[ROWS][COLS] = { 15 | {'1', '2', '3'}, 16 | {'4', '5', '6'}, 17 | {'7', '8', '9'}, 18 | {'*', '0', '#'} 19 | }; 20 | byte rowPins[ROWS] = {8, 7, 6, 5}; //connect to the row pinouts of the keypad 21 | byte colPins[COLS] = {4, 3, 2}; //connect to the column pinouts of the keypad 22 | Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); 23 | 24 | 25 | Password password = Password( "1463" ); // Password 26 | 27 | 28 | #define NODE_ID 53 29 | MySensor node; 30 | MyMessage msg(1, V_LIGHT); // Alarm switch 31 | MyMessage msg2(2, V_TRIPPED); // Sends if password was wrong after 5 time 32 | MyMessage msg3(3, V_LIGHT); // Buzzer 33 | #define ON 1 34 | #define OFF 0 35 | #define BEEPER A0 // Buzzer pin 36 | 37 | 38 | 39 | long previousMillis = 0; 40 | unsigned long currentMillis = millis(); 41 | long interval = 10000; // Turn the backlight off after ... seconds when nothing is touched 42 | boolean ALARM; 43 | boolean FIRST_INPUT = true; 44 | int TRIES = 0; 45 | boolean LCD_LED; 46 | 47 | void setup() { 48 | node.begin(incomingMessage, NODE_ID, false); 49 | lcd.begin(16, 2); 50 | lcd.print("Opstarten..."); 51 | pinMode(BEEPER, OUTPUT); 52 | node.present(1, S_LIGHT); 53 | node.present(2, S_MOTION); 54 | node.present(3, S_LIGHT); 55 | ALARM = node.loadState(0); 56 | keypad.addEventListener(keypadEvent); //add an event listener for this keypad 57 | lcd.clear(); 58 | if (ALARM == ON) { 59 | lcd.print("Alarm: actief "); 60 | } else { 61 | lcd.print("Alarm: uit "); 62 | } 63 | } 64 | 65 | void loop() { 66 | currentMillis = millis(); 67 | node.process(); 68 | keypad.getKey(); 69 | timer(); 70 | } 71 | 72 | void incomingMessage(const MyMessage &message) { 73 | if (message.type == V_LIGHT && message.sensor == 1) { 74 | lcd.backlight(); 75 | LCD_LED = true; 76 | turnAlarm(message.getBool()); 77 | } 78 | 79 | if (message.type == V_LIGHT && message.sensor == 3) { 80 | digitalWrite(BEEPER, message.getBool()); 81 | } 82 | } 83 | 84 | void keypadEvent(KeypadEvent eKey) { 85 | if (LCD_LED == true) { // Do something if LCD backlight is on 86 | switch (keypad.getState()) { 87 | case PRESSED: 88 | previousMillis = currentMillis; 89 | analogWrite(BEEPER, 150); 90 | delay(50); 91 | analogWrite(BEEPER, 0); 92 | Serial.print("Pressed: "); 93 | Serial.println(eKey); 94 | if (FIRST_INPUT == true) { 95 | lcd.clear(); 96 | lcd.print("Pincode:"); 97 | lcd.setCursor ( 0, 1 ); 98 | FIRST_INPUT = false; 99 | } 100 | switch (eKey) { 101 | case '*': 102 | checkPassword(); 103 | password.reset(); 104 | break; 105 | case '#': 106 | password.reset(); 107 | lcd.clear(); 108 | lcd.print("Pincode:"); 109 | FIRST_INPUT == true; 110 | lcd.setCursor ( 0, 1 ); 111 | break; 112 | default: 113 | password.append(eKey); 114 | lcd.print("*"); 115 | } 116 | } 117 | } else { // Turn backlight on first 118 | lcd.backlight(); 119 | LCD_LED = true; 120 | } 121 | } 122 | 123 | void checkPassword() { 124 | FIRST_INPUT = true; 125 | if (password.evaluate()) { // IF PASSWORD IS CORRECT 126 | Serial.println("Success"); 127 | node.send(msg3.set(LOW)); 128 | digitalWrite(BEEPER, LOW); 129 | TRIES = 0; 130 | if (ALARM == ON) { 131 | ALARM = OFF; 132 | } else { 133 | ALARM = ON; 134 | } 135 | turnAlarm(ALARM); 136 | node.send(msg.set(ALARM)); 137 | analogWrite(BEEPER, 150); 138 | delay(50); 139 | analogWrite(BEEPER, 0); 140 | delay(50); 141 | analogWrite(BEEPER, 150); 142 | delay(50); 143 | analogWrite(BEEPER, 0); 144 | 145 | } else { // IF PASSWORD IS WRONG 146 | Serial.println("Wrong"); 147 | analogWrite(BEEPER, 150); 148 | delay(500); 149 | analogWrite(BEEPER, 0); 150 | lcd.clear(); 151 | lcd.print("Foute pincode"); 152 | TRIES++; 153 | if (TRIES > 5 && ALARM == ON) { 154 | Serial.println("To many tries"); 155 | lcd.setCursor ( 0, 1 ); 156 | lcd.print("Alarm gaat af "); 157 | node.send(msg2.set(HIGH)); 158 | } 159 | } 160 | } 161 | 162 | 163 | void turnAlarm(boolean STATE) { 164 | Serial.print("Alarm: "); 165 | Serial.println(STATE); 166 | ALARM = STATE; 167 | node.saveState(0, ALARM); 168 | FIRST_INPUT = true; 169 | //LCD 170 | lcd.clear(); 171 | if (ALARM == ON) { 172 | lcd.print("Alarm: actief"); 173 | } else { 174 | lcd.print("Alarm: uit"); 175 | } 176 | } 177 | 178 | 179 | 180 | void timer() { 181 | if (currentMillis - previousMillis > interval) { 182 | FIRST_INPUT = true; 183 | lcd.clear(); 184 | if (ALARM == ON) { 185 | lcd.print("Alarm: actief"); 186 | } else { 187 | lcd.print("Alarm: uit"); 188 | } 189 | previousMillis = currentMillis; 190 | lcd.noBacklight(); 191 | LCD_LED = false; 192 | Serial.println("Standby"); 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /MySensors 1.5/Arduino/multiSensor/multiSensor.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | /* MySensors multisensor 7 | 8 | Batterylevel 9 | Humidity 10 | Temperature 11 | Motion 12 | Light 13 | 14 | */ 15 | 16 | //********** CONFIG ********************************** 17 | 18 | #define NODE_ID 100 // ID of node 19 | 20 | #define HUM_ID 0 // ID of HUM 21 | #define TEMP_ID 1 // ID of TEMP 22 | // 27-4-2016 swap the pin of the pir and dht 23 | #define DHT_PIN 4 // Pin of DHT 24 | 25 | #define PIR_ID 2 // ID of PIR 26 | // 27-4-2016 Better to keep the pir on a official interupt pin otherwise it might not wake up the pro mini 27 | #define PIR_PIN 3 // Pin of PIR 28 | 29 | #define LIGHT_ID 3 // ID of LDR 30 | #define LIGHT_PIN A0 // Pin of LDR 31 | #define LIGHT_PWR 5 // Power (Vcc) pin of LDR 32 | 33 | unsigned long SLEEP_TIME = 300000; // Sleep time between reads 34 | 35 | boolean BATTERY_SENSOR = true; // Set to false to disable the battery sensor 36 | int MIN_V = 2400; // empty voltage (0%) 37 | int MAX_V = 3200; // full voltage (100%) 38 | 39 | //**************************************************** 40 | 41 | MySensor node; 42 | MyMessage HUMmsg(HUM_ID, V_HUM); 43 | MyMessage TEMPmsg(TEMP_ID, V_TEMP); 44 | MyMessage PIRmsg(PIR_ID, V_TRIPPED); 45 | MyMessage LIGHTmsg(LIGHT_ID, V_LIGHT_LEVEL); 46 | 47 | int batteryPcnt; 48 | int oldBatteryPcnt; 49 | DHT dht; 50 | float lastTemp; 51 | float lastHum; 52 | int lastPIR = 2; 53 | int lastLightLevel; 54 | 55 | void setup() { 56 | node.begin(NULL, NODE_ID, false); 57 | pinMode(PIR_PIN, INPUT); 58 | pinMode(LIGHT_PWR, OUTPUT); 59 | 60 | // Register all sensors to gateway 61 | node.present(HUM_ID, S_HUM); 62 | node.present(TEMP_ID, S_TEMP); 63 | node.present(PIR_ID, S_DOOR); 64 | node.present(LIGHT_ID, S_LIGHT_LEVEL); 65 | 66 | } 67 | 68 | void loop() { 69 | 70 | 71 | // *** BATTERY SENSOR ********************************************** 72 | 73 | 74 | if(BATTERY_SENSOR == true) { 75 | batteryPcnt = min(map(readVcc(), MIN_V, MAX_V, 0, 100), 100); // Convert voltage to percentage 76 | 77 | if (batteryPcnt != oldBatteryPcnt) { // If battery percentage has changed 78 | node.sendBatteryLevel(batteryPcnt); // Send battery percentage to gateway 79 | oldBatteryPcnt = batteryPcnt; 80 | } 81 | } 82 | 83 | 84 | // *** HUMIDITY SENSOR *********************************************** 85 | 86 | 87 | float humidity = dht.getHumidity(); 88 | if (isnan(humidity)) { 89 | Serial.println("Failed reading humidity from DHT"); 90 | } else if (humidity != lastHum) { 91 | lastHum = humidity; 92 | node.send(HUMmsg.set(humidity, 1)); 93 | } 94 | 95 | 96 | // *** TEMPERATURE SENSOR ******************************************** 97 | 98 | 99 | float temperature = dht.getTemperature(); 100 | if (isnan(temperature)) { 101 | Serial.println("Failed reading temperature from DHT"); 102 | } else if (temperature != lastTemp) { 103 | lastTemp = temperature; 104 | node.send(TEMPmsg.set(temperature, 1)); 105 | } 106 | 107 | 108 | // *** PIR SENSOR **************************************************** 109 | 110 | 111 | int PIR = digitalRead(PIR_PIN); 112 | if (PIR != lastPIR) { 113 | lastPIR = PIR; 114 | node.send(PIRmsg.set(PIR == HIGH ? 1 : 0)); 115 | } 116 | 117 | 118 | // *** LIGHT SENSOR ************************************************* 119 | 120 | digitalWrite(LIGHT_PWR, HIGH); // Power up the LDR 121 | float light = analogRead(LIGHT_PIN); // Read LDR 122 | digitalWrite(LIGHT_PWR, LOW); // Power down the LDR 123 | if(light > 500) {light = 500;} 124 | int lightLevel = 100 - (light / 5); 125 | if (lightLevel != lastLightLevel) { 126 | lastLightLevel = lightLevel; 127 | node.send(LIGHTmsg.set(lightLevel)); 128 | } 129 | 130 | // *** PRINT SENSOR VALUES ******************************************* 131 | 132 | Serial.println(); 133 | 134 | Serial.print("Battery: "); 135 | Serial.print(batteryPcnt); 136 | Serial.println("%"); 137 | 138 | Serial.print("Humidity: "); 139 | Serial.print(humidity); 140 | Serial.println("%"); 141 | 142 | Serial.print("Temperature: "); 143 | Serial.print(temperature); 144 | Serial.println("°C"); 145 | 146 | Serial.print("Motion: "); 147 | if (PIR == HIGH) { 148 | Serial.println("true"); 149 | } else { 150 | Serial.println("false"); 151 | } 152 | 153 | Serial.print("Light: "); 154 | Serial.print(lightLevel); 155 | Serial.println("%"); 156 | 157 | node.sleep(PIR_PIN-2, CHANGE, SLEEP_TIME); 158 | } 159 | -------------------------------------------------------------------------------- /MySensors 1.5/Arduino/pulseMeter/pulseMeter.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | //********** CONFIG ********************************** 5 | 6 | #define NODE_ID AUTO // ID of node 7 | #define CHILD_ID 1 // ID of sensor 8 | #define SENSOR_PIN 3 // The digital input you attached your (light) sensor. 9 | 10 | #define PULSE_FACTOR 800 // Number of blinks per KWH of your meter. 11 | #define MAX_WATT 10000 // Max watt value to report. This filters outliers. 12 | #define SEND_FREQUENCY 20000 // Minimum time between send (in milliseconds). 13 | 14 | #define REPEATER true // Enable repeater mode 15 | 16 | // **************************************************** 17 | 18 | int COUNT = 0; 19 | 20 | MySensor node; 21 | double ppwh = ((double)PULSE_FACTOR)/1000; // Pulses per watt hour 22 | boolean pcReceived = false; 23 | volatile unsigned long pulseCount = 0; 24 | volatile unsigned long lastBlink = 0; 25 | volatile unsigned long watt = 0; 26 | volatile unsigned long oldPulseCount = 0; 27 | volatile unsigned long oldWatt = 0; 28 | double oldKwh; 29 | unsigned long lastSend; 30 | MyMessage wattMsg(CHILD_ID,V_WATT); 31 | MyMessage kwhMsg(CHILD_ID,V_KWH); 32 | MyMessage pcMsg(CHILD_ID,V_VAR1); 33 | 34 | void setup() 35 | { 36 | node.begin(incomingMessage, NODE_ID, REPEATER); 37 | node.sendSketchInfo("kWh meter", "1.1"); 38 | node.present(CHILD_ID, S_POWER); 39 | 40 | // Fetch last known pulse count value from gw 41 | node.request(CHILD_ID, V_VAR1); 42 | 43 | attachInterrupt(SENSOR_PIN-2, onPulse, RISING); 44 | lastSend=millis(); 45 | } 46 | 47 | 48 | void loop() 49 | { 50 | node.process(); 51 | unsigned long now = millis(); 52 | // Only send values at a maximum frequency or woken up from sleep 53 | bool sendTime = now - lastSend > SEND_FREQUENCY; 54 | if (pcReceived && sendTime) { 55 | // New watt value has been calculated 56 | if (watt != oldWatt) { 57 | // Check that we dont get unresonable large watt value. 58 | // could hapen when long wraps or false interrupt triggered 59 | if (watt<((unsigned long)MAX_WATT)) { 60 | node.send(wattMsg.set(watt)); // Send watt value to gw 61 | } 62 | Serial.print("Watt:"); 63 | Serial.println(watt); 64 | oldWatt = watt; 65 | } 66 | 67 | // Pulse count has changed 68 | if (pulseCount != oldPulseCount) { 69 | node.send(pcMsg.set(pulseCount)); // Send pulse count value to gw 70 | double kwh = ((double)pulseCount/((double)PULSE_FACTOR)); 71 | oldPulseCount = pulseCount; 72 | if (kwh != oldKwh) { 73 | node.send(kwhMsg.set(kwh, 4)); // Send kwh value to gw 74 | oldKwh = kwh; 75 | } 76 | } 77 | lastSend = now; 78 | } else if (sendTime && !pcReceived) { 79 | // No count received. Try requesting it again 80 | node.request(CHILD_ID, V_VAR1); 81 | } 82 | } 83 | 84 | void incomingMessage(const MyMessage &message) { 85 | if (message.type==V_VAR1) { 86 | pulseCount = oldPulseCount = message.getLong(); 87 | node.saveState(0, message.getLong()); 88 | Serial.print("Received last pulse count from gw:"); 89 | Serial.println(pulseCount); 90 | pcReceived = true; 91 | } 92 | } 93 | 94 | void onPulse() 95 | { 96 | unsigned long newBlink = micros(); 97 | unsigned long interval = newBlink-lastBlink; 98 | if (interval<10000L) { // Sometimes we get interrupt on RISING 99 | return; 100 | } 101 | watt = (3600000000.0 / interval) / ppwh; 102 | lastBlink = newBlink; 103 | 104 | Serial.println("Pulse"); 105 | COUNT++; 106 | pulseCount++; 107 | if(COUNT == 10){ 108 | if(node.loadState(0) > pulseCount) { 109 | pulseCount = node.loadState(0); 110 | } else { 111 | node.saveState(0, pulseCount); 112 | } 113 | COUNT = 0; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /MySensors 1.5/Arduino/pulsereset/pulsereset.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define SENSOR_INFO "Test sensor" 5 | #define NODE_ID 8 6 | #define CHILD_ID 1 7 | #define pulseCount 614826 8 | 9 | MySensor gw; 10 | MyMessage pcMsg(CHILD_ID,V_VAR1); 11 | 12 | void setup() 13 | { 14 | gw.begin(NULL, NODE_ID, false); 15 | gw.sendSketchInfo(SENSOR_INFO, "1.0"); 16 | gw.present(CHILD_ID, S_DOOR); 17 | } 18 | 19 | void loop() 20 | { 21 | gw.send(pcMsg.set(pulseCount)); 22 | gw.sleep(10000); 23 | } 24 | -------------------------------------------------------------------------------- /MySensors 1.5/Arduino/testSensor/testSensor.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define SENSOR_INFO "Test sensor" 5 | #define NODE_ID 100 6 | #define FORECAST "Zonnig" 7 | #define TEMP 10.2 8 | #define HUM 56 9 | #define PRESSURE 1045 10 | #define RAIN 1.8 11 | #define LUX 854 12 | 13 | MySensor gw; 14 | MyMessage msg0(0, V_FORECAST); 15 | MyMessage msg1(1, V_TEMP); 16 | MyMessage msg2(2, V_HUM); 17 | MyMessage msg3(3, V_PRESSURE); 18 | MyMessage msg4(4, V_LIGHT_LEVEL); 19 | MyMessage msg5(5, V_LIGHT_LEVEL); 20 | 21 | void setup() 22 | { 23 | gw.begin(NULL, NODE_ID, false); 24 | } 25 | 26 | void loop() 27 | { 28 | gw.send(msg0.set(FORECAST)); 29 | gw.send(msg1.set(TEMP,1)); 30 | gw.send(msg2.set(HUM)); 31 | gw.send(msg3.set(PRESSURE)); 32 | gw.send(msg4.set(RAIN,1)); 33 | gw.send(msg5.set(LUX)); 34 | gw.sleep(10000); 35 | } 36 | -------------------------------------------------------------------------------- /MySensors 1.5/Arduino/voorbeeld/voorbeeld.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | //********** CONFIG ********************************** 5 | 6 | #define SENSOR_INFO "Test sensor" 7 | #define NODE_ID 100 8 | #define CHILD_ID 1 9 | #define OPEN 1 10 | #define CLOSE 0 11 | 12 | // **************************************************** 13 | 14 | MySensor gw; 15 | MyMessage msg(CHILD_ID, V_TRIPPED); 16 | 17 | void setup() 18 | { 19 | gw.begin(NULL, NODE_ID, false); 20 | gw.sendSketchInfo(SENSOR_INFO, NULL); 21 | gw.present(CHILD_ID, S_DOOR); 22 | } 23 | 24 | void loop() 25 | { 26 | gw.send(msg.set(OPEN),true); 27 | gw.sleep(2000); 28 | 29 | gw.send(msg.set(CLOSE),false); 30 | gw.sleep(2000); 31 | } 32 | -------------------------------------------------------------------------------- /MySensors 1.5/Attiny/button-switch/button-switch.ino: -------------------------------------------------------------------------------- 1 | // MySensors PIR sensor 2 | // Based on Attiny85 3 | // Author: Wiebe Nieuwenhuis 4 | // 5 | // +-\/-+ 6 | // ORANGE CE 1|o |8 VCC RED 7 | // YELLOW CSN 2| |7 SCK GREEN 8 | // - SENSOR 3| |6 MOSI BLUE 9 | // BLACK GND 4| |5 MISO VIOLET 10 | // +----+ 11 | 12 | #include 13 | #include 14 | 15 | #define SENSOR_INFO "PIR sensor" 16 | #define NODE_ID 1 17 | #define CHILD_ID 1 18 | #define INPUT_PIN 4 19 | 20 | MySensor gw; 21 | Bounce debouncer = Bounce(); 22 | int oldValue = -1; 23 | 24 | MyMessage msg(NODE_ID, V_TRIPPED); 25 | 26 | void setup() 27 | { 28 | pinMode(INPUT_PIN, INPUT); 29 | digitalWrite(INPUT_PIN, HIGH); 30 | 31 | debouncer.attach(INPUT_PIN); 32 | debouncer.interval(5); 33 | 34 | gw.begin(NULL, NODE_ID, false, 0); 35 | gw.sendSketchInfo(SENSOR_INFO, "1.0"); 36 | gw.present(CHILD_ID, S_DOOR); 37 | } 38 | 39 | 40 | void loop() 41 | { 42 | debouncer.update(); 43 | int value = debouncer.read(); 44 | if (value != oldValue) { 45 | gw.send(msg.set(value==HIGH ? 1 : 0)); 46 | oldValue = value; 47 | } 48 | } 49 | 50 | 51 | -------------------------------------------------------------------------------- /MySensors 1.5/Attiny/button-switch/readme.md: -------------------------------------------------------------------------------- 1 | A simple button switch sensor. You'll need [this (custom) MySensors library](https://github.com/sweebee/Arduino-home-automation/tree/master/libraries/MySensors). 2 | 3 | #Wiring: 4 | ``` 5 | // +-\/-+ 6 | // ORANGE CE 1|o |8 VCC RED 7 | // YELLOW CSN 2| |7 SCK GREEN 8 | // - SENSOR 3| |6 MOSI BLUE 9 | // BLACK GND 4| |5 MISO VIOLET 10 | // +----+ 11 | ``` 12 | -------------------------------------------------------------------------------- /MySensors 1.5/Attiny/readme.md: -------------------------------------------------------------------------------- 1 | These sketches are for MySensor nodes based on an Attiny85. You'll need [this (custom) MySensors library](https://github.com/sweebee/Arduino-home-automation/tree/master/libraries/MySensors). -------------------------------------------------------------------------------- /MySensors 2.0/KaKuTransmitter/KaKuTransmitter.ino: -------------------------------------------------------------------------------- 1 | // ********** CONFIG ********************************** 2 | 3 | #define MY_NODE_ID 16 // ID of node 4 | #define TX_PIN 8 // Pin connected to the 433MHz transmitter 5 | #define ADDRESS 38484 // KaKu ID 6 | 7 | #define MY_DEBUG // Debug 8 | #define MY_REPEATER_FEATURE // Repeater 9 | 10 | // **************************************************** 11 | 12 | #define MY_RADIO_NRF24 13 | #include 14 | #include 15 | #include 16 | 17 | NewRemoteTransmitter transmitter(ADDRESS, TX_PIN, 260, 3); 18 | 19 | void setup() { 20 | sendSketchInfo("KaKu transmitter", "1.0"); 21 | } 22 | 23 | void loop() { 24 | } 25 | 26 | void receive(const MyMessage &message) { 27 | // If switch 28 | if (message.type==V_STATUS) { 29 | Serial.print("Switching to "); 30 | Serial.println(message.getBool()); 31 | transmitter.sendUnit(message.sensor, message.getBool()); 32 | } 33 | // If dimmer 34 | if (message.type==V_PERCENTAGE) { 35 | int dimlevel = round(0.15 * atoi(message.data)); 36 | Serial.print("Dimming to "); 37 | Serial.println(dimlevel); 38 | transmitter.sendDim(message.sensor, dimlevel); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /MySensors 2.0/LEDDimmer/LEDDimmer.ino: -------------------------------------------------------------------------------- 1 | // ********** CONFIG ********************************** 2 | 3 | // #define MY_NODE_ID AUTO // ID of node 4 | #define CHILD_ID 1 // ID of sensor 5 | #define LED_PIN 3 // Arduino pin attached to MOSFET Gate pin 6 | 7 | #define FADE_DELAY 6 // Delay in ms for each percentage fade up/down (10ms = 1s full-range dim) 8 | 9 | #define MY_REPEATER_FEATURE // Repeater 10 | //#define MY_DEBUG // Debug messages 11 | 12 | // **************************************************** 13 | 14 | #define MY_RADIO_NRF24 15 | #include 16 | #include 17 | 18 | static int currentLevel = 100; // Current dim level... 19 | int requestedLevel; 20 | int fadeDelay = FADE_DELAY; 21 | boolean done = true; 22 | MyMessage dimmerMsg(CHILD_ID, V_PERCENTAGE); 23 | MyMessage lightMsg(CHILD_ID, V_LIGHT); 24 | 25 | 26 | 27 | void setup() { 28 | 29 | sendSketchInfo("LED Dimmer", "2.0"); 30 | present(CHILD_ID, S_DIMMER); 31 | present(CHILD_ID, S_CUSTOM); 32 | 33 | } 34 | 35 | void loop() { 36 | } 37 | 38 | void receive(const MyMessage &message) { 39 | if ((message.type == V_LIGHT || message.type == V_PERCENTAGE) && done) { 40 | 41 | // Retrieve the power or dim level from the incoming request message 42 | requestedLevel = atoi(message.data); 43 | 44 | // Adjust incoming level if this is a V_LIGHT variable update [0 == off, 1 == on] 45 | requestedLevel *= (message.type == V_LIGHT ? 100 : 1); 46 | 47 | // Clip incoming level to valid range of 0 to 100 48 | requestedLevel = requestedLevel > 100 ? 100 : requestedLevel; 49 | requestedLevel = requestedLevel < 0 ? 0 : requestedLevel; 50 | requestedLevel = requestedLevel * 255 / 100; 51 | 52 | Serial.print("Changing level from "); 53 | Serial.print(currentLevel ); 54 | Serial.print(", to "); 55 | Serial.println(requestedLevel); 56 | fadeToLevel(requestedLevel, fadeDelay); 57 | int fadeDelay = FADE_DELAY; 58 | // Inform the gateway of the current DimmableLED's SwitchPower1 and LoadLevelStatus value... 59 | send(lightMsg.set(currentLevel > 0 ? 1 : 0)); 60 | 61 | } 62 | if(message.type == V_VAR1){ 63 | fadeDelay = atoi(message.data); 64 | } 65 | } 66 | 67 | void fadeToLevel(int toLevel, int fadeTime) { 68 | done = false; 69 | int delta = (toLevel - currentLevel) < 0 ? -1 : 1; 70 | 71 | while (currentLevel != toLevel) { 72 | currentLevel += delta; 73 | analogWrite(LED_PIN, (int)(currentLevel)); 74 | wait(fadeTime); 75 | } 76 | done = true; 77 | } 78 | -------------------------------------------------------------------------------- /MySensors 2.0/MotionSensor/MotionSensor.ino: -------------------------------------------------------------------------------- 1 | // ********** CONFIG ********************************** 2 | 3 | //#define MY_NODE_ID 99 // ID of node 4 | #define CHILD_ID 1 // ID of sensor 5 | #define PIR_PIN 3 // Pin connected to the PIR 6 | 7 | #define MIN_V 2000 // empty voltage (0%) 8 | #define MAX_V 3200 // full voltage (100%) 9 | 10 | #define MY_DEBUG // Debug 11 | 12 | // **************************************************** 13 | 14 | #define MY_RADIO_NRF24 15 | #include 16 | #include 17 | #include 18 | 19 | MyMessage msg(CHILD_ID, V_TRIPPED); 20 | int oldBatteryPcnt = -1; 21 | int forceSend = 0; 22 | 23 | void setup() 24 | { 25 | sendSketchInfo("PIR Sensor", "2.0"); 26 | present(CHILD_ID, S_MOTION); 27 | pinMode(PIR_PIN, INPUT); 28 | } 29 | 30 | void loop() 31 | { 32 | 33 | // Get PIR status and send to the gateway 34 | resend(msg.set(digitalRead(PIR_PIN)),6); 35 | 36 | // Send batterylevel 37 | sendBattery(); 38 | 39 | // Sleep until something happens with the PIR 40 | sleep(PIR_PIN-2, CHANGE); 41 | } 42 | 43 | // FUNCTIONS 44 | 45 | void sendBattery() // Send battery percentage to GW 46 | { 47 | forceSend++; 48 | int batteryPcnt = min(map(readVcc(), MIN_V, MAX_V, 0, 100), 100); // Get VCC and convert to percentage 49 | if (batteryPcnt != oldBatteryPcnt || forceSend >= 20) { // If battery percentage has changed 50 | sendBatteryLevel(batteryPcnt); // Send battery percentage to gateway 51 | oldBatteryPcnt = batteryPcnt; 52 | forceSend = 0; 53 | } 54 | } 55 | 56 | void resend(MyMessage &msg, int repeats) // Resend messages if not received by GW 57 | { 58 | int repeat = 1; 59 | int repeatDelay = 0; 60 | 61 | while ((!send(msg)) and (repeat < repeats)) { 62 | repeatDelay += 100; 63 | repeat++; 64 | delay(repeatDelay); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /MySensors 2.0/WallRemoteSingle/WallRemoteSingle.ino: -------------------------------------------------------------------------------- 1 | // ********** CONFIG ********************************** 2 | 3 | #define MY_NODE_ID 16 // ID of node 4 | #define CHILD_ID 1 // ID of sensor 5 | #define SWITCH_PIN 3 // Pin connected to the PIR 6 | 7 | #define MIN_V 2000 // empty voltage (0%) 8 | #define MAX_V 3200 // full voltage (100%) 9 | 10 | #define SLEEP_TIME 3600000 // Sleep 1h 11 | 12 | #define MY_DEBUG // Debug 13 | 14 | // **************************************************** 15 | 16 | #define MY_RADIO_NRF24 17 | #include 18 | #include 19 | #include 20 | 21 | MyMessage msg(CHILD_ID, V_TRIPPED); 22 | int oldBatteryPcnt = -1; 23 | boolean oldValue; 24 | int forceSend = 0; 25 | 26 | void setup() 27 | { 28 | sendSketchInfo("Wall switch", "2.0"); 29 | present(CHILD_ID, S_MOTION); 30 | pinMode(SWITCH_PIN, INPUT); 31 | } 32 | 33 | void loop() 34 | { 35 | 36 | // Switch changed 37 | boolean value = digitalRead(SWITCH_PIN); 38 | if(value != oldValue){ 39 | resend(msg.set(1),6); 40 | oldValue = value; 41 | } 42 | // Send batterylevel 43 | sendBattery(); 44 | 45 | // Sleep until something happens with the switch 46 | sleep(SWITCH_PIN-2, CHANGE, SLEEP_TIME); 47 | } 48 | 49 | // FUNCTIONS 50 | 51 | void sendBattery() // Send battery percentage to GW 52 | { 53 | forceSend++; 54 | int batteryPcnt = min(map(readVcc(), MIN_V, MAX_V, 0, 100), 100); // Get VCC and convert to percentage 55 | if (batteryPcnt != oldBatteryPcnt || forceSend >= 23) { // If battery percentage has changed 56 | sendBatteryLevel(batteryPcnt); // Send battery percentage to gateway 57 | oldBatteryPcnt = batteryPcnt; 58 | forceSend = 0; 59 | } 60 | } 61 | 62 | void resend(MyMessage &msg, int repeats) // Resend messages if not received by GW 63 | { 64 | int repeat = 1; 65 | int repeatDelay = 0; 66 | 67 | while ((!send(msg)) and (repeat < repeats)) { 68 | repeatDelay += 100; 69 | repeat++; 70 | delay(repeatDelay); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /MySensors 2.0/kWhSensor/kWhSensor.ino: -------------------------------------------------------------------------------- 1 | // ********** CONFIG ********************************** 2 | 3 | #define MY_NODE_ID 99 // ID of node 4 | #define KWH_ID 1 // ID of pulse meter 5 | #define PIR_ID 2 // ID of the PIR 6 | 7 | #define KWH_PIN 3 // Pin connected to the pulse meter 8 | #define PIR_PIN 5 // Pin connected to the PIR 9 | 10 | #define PULSE_FACTOR 800 // Nummber of blinks per KWH of your meeter 11 | #define MAX_WATT 15000 // Max watt value to report. This filetrs outliers. 12 | #define SLEEP_MODE false // Watt-value can only be reported when sleep mode is false. 13 | 14 | //#define MY_DEBUG // Debug 15 | 16 | // **************************************************** 17 | 18 | #define MY_RADIO_NRF24 19 | #include 20 | #include 21 | 22 | #define INTERRUPT KWH_PIN-2 // Usually the interrupt = pin -2 (on uno/nano anyway) 23 | 24 | 25 | unsigned long SEND_FREQUENCY = 20000; // Minimum time between send (in milliseconds). We don't wnat to spam the gateway. 26 | double ppwh = ((double)PULSE_FACTOR)/1000; // Pulses per watt hour 27 | boolean pcReceived = false; 28 | boolean sentDoorbell; 29 | volatile unsigned long pulseCount = 0; 30 | volatile unsigned long lastBlink = 0; 31 | volatile unsigned long watt = 0; 32 | unsigned long oldPulseCount = 0; 33 | unsigned long oldWatt = 0; 34 | double oldKwh; 35 | unsigned long lastSend; 36 | MyMessage wattMsg(KWH_ID,V_WATT); 37 | MyMessage kwhMsg(KWH_ID,V_KWH); 38 | MyMessage pcMsg(KWH_ID,V_VAR1); 39 | MyMessage msg(PIR_ID,V_TRIPPED); 40 | 41 | 42 | void setup() 43 | { 44 | // Fetch last known pulse count value from gw 45 | request(KWH_ID, V_VAR1); 46 | pinMode(PIR_PIN, INPUT); 47 | digitalWrite(PIR_PIN,HIGH); 48 | 49 | // Use the internal pullup to be able to hook up this sketch directly to an energy meter with S0 output 50 | // If no pullup is used, the reported usage will be too high because of the floating pin 51 | 52 | attachInterrupt(INTERRUPT, onPulse, RISING); 53 | lastSend=millis(); 54 | } 55 | 56 | void presentation() { 57 | // Send the sketch version information to the gateway and Controller 58 | sendSketchInfo("Energy Meter", "1.0"); 59 | 60 | // Register this device as power sensor 61 | present(KWH_ID, S_POWER); 62 | present(PIR_ID, S_MOTION); 63 | } 64 | 65 | void loop() 66 | { 67 | boolean doorbell = digitalRead(PIR_PIN); 68 | if(doorbell != sentDoorbell){ 69 | if(doorbell){ 70 | resend(msg.set(1),5); 71 | } 72 | sentDoorbell = doorbell; 73 | } 74 | unsigned long now = millis(); 75 | // Only send values at a maximum frequency or woken up from sleep 76 | bool sendTime = now - lastSend > SEND_FREQUENCY; 77 | if (pcReceived && (SLEEP_MODE || sendTime)) { 78 | // New watt value has been calculated 79 | if (!SLEEP_MODE && watt != oldWatt) { 80 | // Check that we dont get unresonable large watt value. 81 | // could hapen when long wraps or false interrupt triggered 82 | if (watt<((unsigned long)MAX_WATT)) { 83 | resend(wattMsg.set(watt),5); // Send watt value to gw 84 | } 85 | Serial.print("Watt:"); 86 | Serial.println(watt); 87 | oldWatt = watt; 88 | } 89 | 90 | // Pulse cout has changed 91 | if (pulseCount != oldPulseCount) { 92 | resend(pcMsg.set(pulseCount),5); // Send pulse count value to gw 93 | double kwh = ((double)pulseCount/((double)PULSE_FACTOR)); 94 | oldPulseCount = pulseCount; 95 | if (kwh != oldKwh) { 96 | send(kwhMsg.set(kwh, 4)); // Send kwh value to gw 97 | oldKwh = kwh; 98 | } 99 | } 100 | lastSend = now; 101 | } else if (sendTime && !pcReceived) { 102 | // No count received. Try requesting it again 103 | request(KWH_ID, V_VAR1); 104 | lastSend=now; 105 | } 106 | 107 | if (SLEEP_MODE) { 108 | sleep(SEND_FREQUENCY); 109 | } 110 | } 111 | 112 | void receive(const MyMessage &message) { 113 | if (message.type==V_VAR1) { 114 | pulseCount = oldPulseCount = message.getLong(); 115 | Serial.print("Received last pulse count from gw:"); 116 | Serial.println(pulseCount); 117 | pcReceived = true; 118 | } 119 | } 120 | 121 | void onPulse() 122 | { 123 | if (!SLEEP_MODE) { 124 | Serial.println("Pulse!"); 125 | unsigned long newBlink = micros(); 126 | unsigned long interval = newBlink-lastBlink; 127 | if (interval<10000L) { // Sometimes we get interrupt on RISING 128 | return; 129 | } 130 | watt = (3600000000.0 /interval) / ppwh; 131 | lastBlink = newBlink; 132 | } 133 | pulseCount++; 134 | } 135 | 136 | void resend(MyMessage &msg, int repeats) // Resend messages if not received by GW 137 | { 138 | int repeat = 1; 139 | int repeatDelay = 0; 140 | 141 | while ((!send(msg)) and (repeat < repeats)) { 142 | repeatDelay += 100; 143 | repeat++; 144 | delay(repeatDelay); 145 | } 146 | } 147 | 148 | -------------------------------------------------------------------------------- /MySensors 2.0/lightSensor/lightSensor.ino: -------------------------------------------------------------------------------- 1 | //********** CONFIG ********************************** 2 | 3 | #define MY_NODE_ID AUTO // ID of node 4 | #define CHILD_ID 1 // ID of sensor 5 | #define LIGHT_PIN A0 // Pin connected to the PIR 6 | 7 | #define MAX_LIGHT 750 // Max light value of LDR (0%) 8 | 9 | #define SLEEP_TIME 60000 // Sleep time between reads (seconds) 10 | 11 | #define MIN_V 2000 // empty voltage (0%) 12 | #define MAX_V 3200 // full voltage (100%) 13 | 14 | //#define MY_DEBUG // Debug 15 | 16 | //**************************************************** 17 | 18 | #define MY_RADIO_NRF24 19 | #include 20 | #include 21 | #include 22 | 23 | MyMessage msg(CHILD_ID, V_LIGHT_LEVEL); 24 | 25 | int lastLightLevel = -1; 26 | int oldBatteryPcnt = -1; 27 | int forceCnt = 0; 28 | boolean forceSend = false; 29 | 30 | void setup() 31 | { 32 | sendSketchInfo("Light sensor","2.0"); 33 | present(CHILD_ID, S_LIGHT_LEVEL); 34 | } 35 | 36 | void loop() 37 | { 38 | if(forceCnt < 29){ 39 | forceCnt++; 40 | forceSend = false; 41 | } else { 42 | forceCnt = 0; 43 | forceSend = true; 44 | } 45 | sendLight(forceSend); 46 | sendBattery(forceSend); 47 | sleep(SLEEP_TIME); 48 | } 49 | 50 | // FUNCTIONS 51 | 52 | void sendLight(boolean forceSend) // SEND LIGHT LEVEL 53 | { 54 | digitalWrite(LIGHT_PIN, HIGH); 55 | int light = analogRead(LIGHT_PIN); 56 | Serial.print("Light: "); 57 | Serial.println(light); 58 | digitalWrite(LIGHT_PIN, LOW); 59 | int lightLevel = max(map(light, MAX_LIGHT, 0, 0, 100), 0); // Convert light to percentage 60 | if (lightLevel != lastLightLevel || forceSend) { 61 | resend(msg.set(lightLevel), 5); 62 | lastLightLevel = lightLevel; 63 | } 64 | } 65 | 66 | void sendBattery(boolean forceSend) // SEND BATTERYLEVEL 67 | { 68 | int batteryPcnt = min(map(readVcc(), MIN_V, MAX_V, 0, 100), 100); // Get VCC and convert to percentage 69 | if (batteryPcnt != oldBatteryPcnt || forceSend) { // If battery percentage has changed 70 | sendBatteryLevel(batteryPcnt); // Send battery percentage to gateway 71 | oldBatteryPcnt = batteryPcnt; 72 | } 73 | } 74 | 75 | void resend(MyMessage &msg, int repeats) // Resend messages if not received by GW 76 | { 77 | int repeat = 0; 78 | int repeatDelay = 0; 79 | boolean ack = false; 80 | 81 | while ((ack == false) and (repeat < repeats)) { 82 | if (send(msg)) { 83 | ack = true; 84 | } else { 85 | ack = false; 86 | repeatDelay += 100; 87 | } 88 | repeat++; 89 | delay(repeatDelay); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /attinypins.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sweebee/Arduino-home-automation/10fb941aad9c3d82e2a1eef7390801f0300a4236/attinypins.png -------------------------------------------------------------------------------- /libraries/MySensors/MyConfig.h: -------------------------------------------------------------------------------- 1 | #ifndef MyConfig_h 2 | #define MyConfig_h 3 | 4 | /*** 5 | * Configure Sensor Network 6 | */ 7 | #define RF24_CHANNEL 76 //RF channel for the sensor net, 0-127 8 | #define RF24_DATARATE RF24_250KBPS //RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps 9 | #define RF24_PA_LEVEL RF24_PA_MAX //Sensor PA Level == RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBM, and RF24_PA_MAX=0dBm 10 | #define RF24_PA_LEVEL_GW RF24_PA_LOW //Gateway PA Level, defaults to Sensor net PA Level. Tune here if using an amplified nRF2401+ in your gateway. 11 | #define BASE_RADIO_ID ((uint64_t)0xA8A8E1FC00LL) // This is also act as base value for sensor nodeId addresses. Change this (or channel) if you have more than one sensor network. 12 | 13 | // MySensors online examples defaults 14 | #define DEFAULT_CE_PIN 9 15 | #define DEFAULT_CS_PIN 10 16 | 17 | /*** 18 | * Enable/Disable debug logging 19 | */ 20 | #define DEBUG 21 | 22 | /*** 23 | * attiny support 24 | */ 25 | 26 | #if defined (ARDUINO) && !defined (__arm__) 27 | #if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) 28 | #define TINY 29 | #define NO_SERIAL 30 | #define NO_REPEATER 31 | #define NO_AUTO 32 | #undef DEBUG 33 | #define TINY_DEBUG 34 | #define DEFAULT_CE_PIN 0 35 | #define DEFAULT_CS_PIN 3 36 | #endif 37 | #endif 38 | 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /libraries/MySensors/MyGateway.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MySensors library adds a new layer on top of the RF24 library. 3 | It handles radio network routing, relaying and ids. 4 | 5 | Created by Henrik Ekblad 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | version 2 as published by the Free Software Foundation. 10 | */ 11 | 12 | #ifndef MyGateway_h 13 | #define MyGateway_h 14 | #ifndef TINY 15 | #include "MySensor.h" 16 | 17 | #define MAX_RECEIVE_LENGTH 100 // Max buffersize needed for messages coming from controller 18 | #define MAX_SEND_LENGTH 120 // Max buffersize needed for messages destined for controller 19 | 20 | class MyGateway : public MySensor 21 | { 22 | public: 23 | /** 24 | * Constructor 25 | * 26 | * Creates a new instance of MyGateway class. 27 | * If you don't use status leds and/or inclusion mode button on your arduino gateway 28 | * you can disable this functionality by calling the 2 argument constructor. 29 | * 30 | * @param _cepin The pin attached to RF24 Chip Enable on the RF module (default 9) 31 | * @param _cspin The pin attached to RF24 Chip Select (defualt 10) 32 | * @param _inclusion_time Time of inclusion mode (in minutes, default 1) 33 | * @param _inclusion_pin Digital pin that triggers inclusion mode 34 | * @param _rx Digital pin for receive led 35 | * @param _tx Digital pin for transfer led 36 | * @param _er Digital pin for error led 37 | * 38 | */ 39 | MyGateway(uint8_t _cepin=DEFAULT_CE_PIN, uint8_t _cspin=DEFAULT_CS_PIN, uint8_t _inclusion_time = 1, uint8_t _inclusion_pin = 3, uint8_t _rx=6, uint8_t _tx=5, uint8_t _er=4); 40 | 41 | /* Use this and pass a function that should be called when you want to process commands that arrive from radio network */ 42 | void begin(rf24_pa_dbm_e paLevel=RF24_PA_LEVEL_GW, uint8_t channel=RF24_CHANNEL, rf24_datarate_e dataRate=RF24_DATARATE, void (*dataCallback)(char *)=NULL); 43 | 44 | void processRadioMessage(); 45 | void parseAndSend(char *inputString); 46 | 47 | private: 48 | char convBuf[MAX_PAYLOAD*2+1]; 49 | char serialBuffer[MAX_SEND_LENGTH]; // Buffer for building string when sending data to vera 50 | unsigned long inclusionStartTime; 51 | boolean useWriteCallback; 52 | void (*dataCallback)(char *); 53 | uint8_t pinInclusion; 54 | uint8_t inclusionTime; 55 | 56 | uint8_t h2i(char c); 57 | 58 | void serial(const char *fmt, ... ); 59 | void serial(MyMessage &msg); 60 | void checkButtonTriggeredInclusion(); 61 | void setInclusionMode(boolean newMode); 62 | void checkInclusionFinished(); 63 | void ledTimers(); 64 | void rxBlink(uint8_t cnt); 65 | void txBlink(uint8_t cnt); 66 | void errBlink(uint8_t cnt); 67 | }; 68 | 69 | void ledTimersInterrupt(); 70 | void startInclusionInterrupt(); 71 | 72 | #endif 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /libraries/MySensors/MyMQTT.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MySensors library adds a new layer on top of the RF24 library. 3 | It handles radio network routing, relaying and ids. 4 | 5 | Created by Henrik Ekblad 6 | Modified by Daniel Wiegert 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | version 2 as published by the Free Software Foundation. 10 | */ 11 | 12 | #ifndef MyMQTT_h 13 | #define MyMQTT_h 14 | 15 | #include "MySensor.h" 16 | 17 | 18 | ////////////////////////////////////////////////////////////////// 19 | 20 | #ifdef DEBUG 21 | #define TCPDUMP // Dump TCP packages. 22 | #endif 23 | 24 | #define MQTT_FIRST_SENSORID 20 // If you want manually configured nodes below this value. 255 = Disable 25 | #define MQTT_LAST_SENSORID 254 // 254 is max! 255 reserved. 26 | #define MQTT_BROKER_PREFIX "MyMQTT" // First prefix in MQTT tree, keep short! 27 | #define MQTT_SEND_SUBSCRIPTION 1 // Send empty payload (request) to node upon MQTT client subscribe request. 28 | // NOTE above : Beware to check if there is any length on payload in your incommingMessage code: 29 | // Example: if (msg.type==V_LIGHT && strlen(msg.getString())>0) otherwise the code might do strange things. 30 | 31 | ////////////////////////////////////////////////////////////////// 32 | 33 | #define EEPROM_LATEST_NODE_ADDRESS ((uint8_t)EEPROM_LOCAL_CONFIG_ADDRESS) 34 | #define MQTT_MAX_PACKET_SIZE 100 35 | 36 | #define MQTTPROTOCOLVERSION 3 37 | #define MQTTCONNECT 1 // Client request to connect to Server 38 | #define MQTTCONNACK 2 // Connect Acknowledgment 39 | #define MQTTPUBLISH 3 // Publish message 40 | #define MQTTPUBACK 4 // Publish Acknowledgment 41 | #define MQTTPUBREC 5 // Publish Received (assured delivery part 1) 42 | #define MQTTPUBREL 6 // Publish Release (assured delivery part 2) 43 | #define MQTTPUBCOMP 7 // Publish Complete (assured delivery part 3) 44 | #define MQTTSUBSCRIBE 8 // Client Subscribe request 45 | #define MQTTSUBACK 9 // Subscribe Acknowledgment 46 | #define MQTTUNSUBSCRIBE 10 // Client Unsubscribe request 47 | #define MQTTUNSUBACK 11 // Unsubscribe Acknowledgment 48 | #define MQTTPINGREQ 12 // PING Request 49 | #define MQTTPINGRESP 13 // PING Response 50 | #define MQTTDISCONNECT 14 // Client is Disconnecting 51 | #define MQTTReserved 15 // Reserved 52 | 53 | #define MQTTQOS0 (0 << 1) 54 | #define MQTTQOS1 (1 << 1) 55 | #define MQTTQOS2 (2 << 1) 56 | 57 | class MyMQTT : 58 | public MySensor { 59 | 60 | public: 61 | MyMQTT(uint8_t _cepin=5, uint8_t _cspin=6); 62 | void begin(rf24_pa_dbm_e paLevel=RF24_PA_LEVEL_GW, uint8_t channel=RF24_CHANNEL, rf24_datarate_e dataRate=RF24_DATARATE, void (*dataCallback) 63 | (const char *, uint8_t *)=NULL, uint8_t _rx=6, uint8_t _tx=5, uint8_t _er=4 ); 64 | void processRadioMessage(); 65 | void processMQTTMessage(char *inputString, uint8_t inputPos); 66 | private: 67 | void (*dataCallback)(const char *, uint8_t *); 68 | void SendMQTT(MyMessage &msg); 69 | void ledTimers(); 70 | void rxBlink(uint8_t cnt); 71 | void txBlink(uint8_t cnt); 72 | void errBlink(uint8_t cnt); 73 | 74 | uint8_t MQTTClients; 75 | char buffer[MQTT_MAX_PACKET_SIZE]; 76 | char convBuf[MAX_PAYLOAD*2+1]; 77 | uint8_t buffsize; 78 | char *getType(char *b, const char **index); 79 | }; 80 | 81 | extern void ledTimersInterrupt(); 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /libraries/MySensors/MyMessage.cpp: -------------------------------------------------------------------------------- 1 | #include "MyMessage.h" 2 | #include 3 | #include 4 | 5 | 6 | MyMessage::MyMessage() { 7 | destination = 0; // Gateway is default destination 8 | } 9 | 10 | MyMessage::MyMessage(uint8_t _sensor, uint8_t _type) { 11 | destination = 0; // Gateway is default destination 12 | sensor = _sensor; 13 | type = _type; 14 | } 15 | 16 | bool MyMessage::isAck() const { 17 | return miGetAck(); 18 | } 19 | 20 | /* Getters for payload converted to desired form */ 21 | void* MyMessage::getCustom() const { 22 | return (void *)data; 23 | } 24 | 25 | const char* MyMessage::getString() const { 26 | uint8_t payloadType = miGetPayloadType(); 27 | if (payloadType == P_STRING) { 28 | return data; 29 | } else { 30 | return NULL; 31 | } 32 | } 33 | 34 | // handles single character hex (0 - 15) 35 | char MyMessage::i2h(uint8_t i) const { 36 | uint8_t k = i & 0x0F; 37 | if (k <= 9) 38 | return '0' + k; 39 | else 40 | return 'A' + k - 10; 41 | } 42 | 43 | char* MyMessage::getCustomString(char *buffer) const { 44 | for (uint8_t i = 0; i < miGetLength(); i++) 45 | { 46 | buffer[i * 2] = i2h(data[i] >> 4); 47 | buffer[(i * 2) + 1] = i2h(data[i]); 48 | } 49 | buffer[miGetLength() * 2] = '\0'; 50 | return buffer; 51 | } 52 | 53 | char* MyMessage::getStream(char *buffer) const { 54 | uint8_t cmd = miGetCommand(); 55 | if ((cmd == C_STREAM) && (buffer != NULL)) { 56 | return getCustomString(buffer); 57 | } else { 58 | return NULL; 59 | } 60 | } 61 | 62 | char* MyMessage::getString(char *buffer) const { 63 | uint8_t payloadType = miGetPayloadType(); 64 | if (payloadType == P_STRING) { 65 | strncpy(buffer, data, miGetLength()); 66 | buffer[miGetLength()] = 0; 67 | return buffer; 68 | } else if (buffer != NULL) { 69 | if (payloadType == P_BYTE) { 70 | itoa(bValue, buffer, 10); 71 | } else if (payloadType == P_INT16) { 72 | itoa(iValue, buffer, 10); 73 | } else if (payloadType == P_UINT16) { 74 | utoa(uiValue, buffer, 10); 75 | } else if (payloadType == P_LONG32) { 76 | ltoa(lValue, buffer, 10); 77 | } else if (payloadType == P_ULONG32) { 78 | ultoa(ulValue, buffer, 10); 79 | } else if (payloadType == P_FLOAT32) { 80 | dtostrf(fValue,2,fPrecision,buffer); 81 | } else if (payloadType == P_CUSTOM) { 82 | return getCustomString(buffer); 83 | } 84 | return buffer; 85 | } else { 86 | return NULL; 87 | } 88 | } 89 | 90 | uint8_t MyMessage::getByte() const { 91 | if (miGetPayloadType() == P_BYTE) { 92 | return data[0]; 93 | } else if (miGetPayloadType() == P_STRING) { 94 | return atoi(data); 95 | } else { 96 | return 0; 97 | } 98 | } 99 | 100 | bool MyMessage::getBool() const { 101 | return getInt(); 102 | } 103 | 104 | float MyMessage::getFloat() const { 105 | if (miGetPayloadType() == P_FLOAT32) { 106 | return fValue; 107 | } else if (miGetPayloadType() == P_STRING) { 108 | return atof(data); 109 | } else { 110 | return 0; 111 | } 112 | } 113 | 114 | long MyMessage::getLong() const { 115 | if (miGetPayloadType() == P_LONG32) { 116 | return lValue; 117 | } else if (miGetPayloadType() == P_STRING) { 118 | return atol(data); 119 | } else { 120 | return 0; 121 | } 122 | } 123 | 124 | unsigned long MyMessage::getULong() const { 125 | if (miGetPayloadType() == P_ULONG32) { 126 | return ulValue; 127 | } else if (miGetPayloadType() == P_STRING) { 128 | return atol(data); 129 | } else { 130 | return 0; 131 | } 132 | } 133 | 134 | int MyMessage::getInt() const { 135 | if (miGetPayloadType() == P_INT16) { 136 | return iValue; 137 | } else if (miGetPayloadType() == P_STRING) { 138 | return atoi(data); 139 | } else { 140 | return 0; 141 | } 142 | } 143 | 144 | unsigned int MyMessage::getUInt() const { 145 | if (miGetPayloadType() == P_UINT16) { 146 | return uiValue; 147 | } else if (miGetPayloadType() == P_STRING) { 148 | return atoi(data); 149 | } else { 150 | return 0; 151 | } 152 | 153 | } 154 | 155 | MyMessage& MyMessage::setType(uint8_t _type) { 156 | type = _type; 157 | return *this; 158 | } 159 | 160 | MyMessage& MyMessage::setSensor(uint8_t _sensor) { 161 | sensor = _sensor; 162 | return *this; 163 | } 164 | 165 | MyMessage& MyMessage::setDestination(uint8_t _destination) { 166 | destination = _destination; 167 | return *this; 168 | } 169 | 170 | // Set payload 171 | MyMessage& MyMessage::set(void* value, uint8_t length) { 172 | miSetPayloadType(P_CUSTOM); 173 | miSetLength(length); 174 | memcpy(data, value, min(length, MAX_PAYLOAD)); 175 | return *this; 176 | } 177 | 178 | MyMessage& MyMessage::set(const char* value) { 179 | uint8_t length = min(strlen(value), MAX_PAYLOAD); 180 | miSetLength(length); 181 | miSetPayloadType(P_STRING); 182 | strncpy(data, value, length); 183 | return *this; 184 | } 185 | 186 | MyMessage& MyMessage::set(uint8_t value) { 187 | miSetLength(1); 188 | miSetPayloadType(P_BYTE); 189 | data[0] = value; 190 | return *this; 191 | } 192 | 193 | MyMessage& MyMessage::set(float value, uint8_t decimals) { 194 | miSetLength(5); // 32 bit float + persi 195 | miSetPayloadType(P_FLOAT32); 196 | fValue=value; 197 | fPrecision = decimals; 198 | return *this; 199 | } 200 | 201 | MyMessage& MyMessage::set(unsigned long value) { 202 | miSetPayloadType(P_ULONG32); 203 | miSetLength(4); 204 | ulValue = value; 205 | return *this; 206 | } 207 | 208 | MyMessage& MyMessage::set(long value) { 209 | miSetPayloadType(P_LONG32); 210 | miSetLength(4); 211 | lValue = value; 212 | return *this; 213 | } 214 | 215 | MyMessage& MyMessage::set(unsigned int value) { 216 | miSetPayloadType(P_UINT16); 217 | miSetLength(2); 218 | uiValue = value; 219 | return *this; 220 | } 221 | 222 | MyMessage& MyMessage::set(int value) { 223 | miSetPayloadType(P_INT16); 224 | miSetLength(2); 225 | iValue = value; 226 | return *this; 227 | } -------------------------------------------------------------------------------- /libraries/MySensors/MyMessage.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MySensors library adds a new layer on top of the RF24 library. 3 | It handles radio network routing, relaying and ids. 4 | 5 | Created by Henrik Ekblad 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | version 2 as published by the Free Software Foundation. 10 | */ 11 | 12 | #ifndef MyMessage_h 13 | #define MyMessage_h 14 | 15 | #ifdef __cplusplus 16 | #include 17 | #include 18 | #include 19 | #endif 20 | 21 | #define PROTOCOL_VERSION 2 22 | #define MAX_MESSAGE_LENGTH 32 23 | #define HEADER_SIZE 7 24 | #define MAX_PAYLOAD (MAX_MESSAGE_LENGTH - HEADER_SIZE) 25 | 26 | // Message types 27 | typedef enum { 28 | C_PRESENTATION = 0, 29 | C_SET = 1, 30 | C_REQ = 2, 31 | C_INTERNAL = 3, 32 | C_STREAM = 4 // For Firmware and other larger chunks of data that need to be divided into pieces. 33 | } mysensor_command; 34 | 35 | // Type of sensor data (for set/req/ack messages) 36 | typedef enum { 37 | V_TEMP,V_HUM, V_LIGHT, V_DIMMER, V_PRESSURE, V_FORECAST, V_RAIN, 38 | V_RAINRATE, V_WIND, V_GUST, V_DIRECTION, V_UV, V_WEIGHT, V_DISTANCE, 39 | V_IMPEDANCE, V_ARMED, V_TRIPPED, V_WATT, V_KWH, V_SCENE_ON, V_SCENE_OFF, 40 | V_HEATER, V_HEATER_SW, V_LIGHT_LEVEL, V_VAR1, V_VAR2, V_VAR3, V_VAR4, V_VAR5, 41 | V_UP, V_DOWN, V_STOP, V_IR_SEND, V_IR_RECEIVE, V_FLOW, V_VOLUME, V_LOCK_STATUS, 42 | V_DUST_LEVEL, V_VOLTAGE, V_CURRENT 43 | } mysensor_data; 44 | 45 | // Type of internal messages (for internal messages) 46 | typedef enum { 47 | I_BATTERY_LEVEL, I_TIME, I_VERSION, I_ID_REQUEST, I_ID_RESPONSE, 48 | I_INCLUSION_MODE, I_CONFIG, I_FIND_PARENT, I_FIND_PARENT_RESPONSE, 49 | I_LOG_MESSAGE, I_CHILDREN, I_SKETCH_NAME, I_SKETCH_VERSION, 50 | I_REBOOT, I_GATEWAY_READY 51 | } mysensor_internal; 52 | 53 | // Type of sensor (for presentation message) 54 | typedef enum { 55 | S_DOOR, S_MOTION, S_SMOKE, S_LIGHT, S_DIMMER, S_COVER, S_TEMP, S_HUM, S_BARO, S_WIND, 56 | S_RAIN, S_UV, S_WEIGHT, S_POWER, S_HEATER, S_DISTANCE, S_LIGHT_LEVEL, S_ARDUINO_NODE, 57 | S_ARDUINO_REPEATER_NODE, S_LOCK, S_IR, S_WATER, S_AIR_QUALITY, S_CUSTOM, S_DUST, 58 | S_SCENE_CONTROLLER 59 | } mysensor_sensor; 60 | 61 | // Type of data stream (for streamed message) 62 | typedef enum { 63 | ST_FIRMWARE_CONFIG_REQUEST, ST_FIRMWARE_CONFIG_RESPONSE, ST_FIRMWARE_REQUEST, ST_FIRMWARE_RESPONSE, 64 | ST_SOUND, ST_IMAGE 65 | } mysensor_stream; 66 | 67 | typedef enum { 68 | P_STRING, P_BYTE, P_INT16, P_UINT16, P_LONG32, P_ULONG32, P_CUSTOM, P_FLOAT32 69 | } mysensor_payload; 70 | 71 | 72 | 73 | #define BIT(n) ( 1<<(n) ) 74 | // Create a bitmask of length len. 75 | #define BIT_MASK(len) ( BIT(len)-1 ) 76 | // Create a bitfield mask of length starting at bit 'start'. 77 | #define BF_MASK(start, len) ( BIT_MASK(len)<<(start) ) 78 | 79 | // Prepare a bitmask for insertion or combining. 80 | #define BF_PREP(x, start, len) ( ((x)&BIT_MASK(len)) << (start) ) 81 | // Extract a bitfield of length len starting at bit 'start' from y. 82 | #define BF_GET(y, start, len) ( ((y)>>(start)) & BIT_MASK(len) ) 83 | // Insert a new bitfield value x into y. 84 | #define BF_SET(y, x, start, len) ( y= ((y) &~ BF_MASK(start, len)) | BF_PREP(x, start, len) ) 85 | 86 | // Getters/setters for special bit fields in header 87 | #define mSetVersion(_msg,_version) BF_SET(_msg.version_length, _version, 0, 3) 88 | #define mGetVersion(_msg) BF_GET(_msg.version_length, 0, 3) 89 | 90 | #define mSetLength(_msg,_length) BF_SET(_msg.version_length, _length, 3, 5) 91 | #define mGetLength(_msg) BF_GET(_msg.version_length, 3, 5) 92 | 93 | #define mSetCommand(_msg,_command) BF_SET(_msg.command_ack_payload, _command, 0, 3) 94 | #define mGetCommand(_msg) BF_GET(_msg.command_ack_payload, 0, 3) 95 | 96 | #define mSetRequestAck(_msg,_rack) BF_SET(_msg.command_ack_payload, _rack, 3, 1) 97 | #define mGetRequestAck(_msg) BF_GET(_msg.command_ack_payload, 3, 1) 98 | 99 | #define mSetAck(_msg,_ackMsg) BF_SET(_msg.command_ack_payload, _ackMsg, 4, 1) 100 | #define mGetAck(_msg) BF_GET(_msg.command_ack_payload, 4, 1) 101 | 102 | #define mSetPayloadType(_msg, _pt) BF_SET(_msg.command_ack_payload, _pt, 5, 3) 103 | #define mGetPayloadType(_msg) BF_GET(_msg.command_ack_payload, 5, 3) 104 | 105 | 106 | // internal access for special fields 107 | #define miGetCommand() BF_GET(command_ack_payload, 0, 3) 108 | 109 | #define miSetLength(_length) BF_SET(version_length, _length, 3, 5) 110 | #define miGetLength() BF_GET(version_length, 3, 5) 111 | 112 | #define miSetRequestAck(_rack) BF_SET(command_ack_payload, _rack, 3, 1) 113 | #define miGetRequestAck() BF_GET(command_ack_payload, 3, 1) 114 | 115 | #define miSetAck(_ack) BF_SET(command_ack_payload, _ack, 4, 1) 116 | #define miGetAck() BF_GET(command_ack_payload, 4, 1) 117 | 118 | #define miSetPayloadType(_pt) BF_SET(command_ack_payload, _pt, 5, 3) 119 | #define miGetPayloadType() BF_GET(command_ack_payload, 5, 3) 120 | 121 | 122 | #ifdef __cplusplus 123 | class MyMessage 124 | { 125 | private: 126 | char* getCustomString(char *buffer) const; 127 | 128 | public: 129 | // Constructors 130 | MyMessage(); 131 | 132 | MyMessage(uint8_t sensor, uint8_t type); 133 | 134 | char i2h(uint8_t i) const; 135 | 136 | /** 137 | * If payload is something else than P_STRING you can have the payload value converted 138 | * into string representation by supplying a buffer with the minimum size of 139 | * 2*MAX_PAYLOAD+1. This is to be able to fit hex-conversion of a full binary payload. 140 | */ 141 | char* getStream(char *buffer) const; 142 | char* getString(char *buffer) const; 143 | const char* getString() const; 144 | void* getCustom() const; 145 | uint8_t getByte() const; 146 | bool getBool() const; 147 | float getFloat() const; 148 | long getLong() const; 149 | unsigned long getULong() const; 150 | int getInt() const; 151 | unsigned int getUInt() const; 152 | 153 | // Getter for ack-flag. True if this is an ack message. 154 | bool isAck() const; 155 | 156 | // Setters for building message "on the fly" 157 | MyMessage& setType(uint8_t type); 158 | MyMessage& setSensor(uint8_t sensor); 159 | MyMessage& setDestination(uint8_t destination); 160 | 161 | // Setters for payload 162 | MyMessage& set(void* payload, uint8_t length); 163 | MyMessage& set(const char* value); 164 | MyMessage& set(uint8_t value); 165 | MyMessage& set(float value, uint8_t decimals); 166 | MyMessage& set(unsigned long value); 167 | MyMessage& set(long value); 168 | MyMessage& set(unsigned int value); 169 | MyMessage& set(int value); 170 | 171 | #else 172 | 173 | typedef union { 174 | struct 175 | { 176 | 177 | #endif 178 | uint8_t last; // 8 bit - Id of last node this message passed 179 | uint8_t sender; // 8 bit - Id of sender node (origin) 180 | uint8_t destination; // 8 bit - Id of destination node 181 | 182 | uint8_t version_length; // 3 bit - Protocol version 183 | // 5 bit - Length of payload 184 | uint8_t command_ack_payload; // 3 bit - Command type 185 | // 1 bit - Request an ack - Indicator that receiver should send an ack back. 186 | // 1 bit - Is ack messsage - Indicator that this is the actual ack message. 187 | // 3 bit - Payload data type 188 | uint8_t type; // 8 bit - Type varies depending on command 189 | uint8_t sensor; // 8 bit - Id of sensor that this message concerns. 190 | 191 | // Each message can transfer a payload. We add one extra byte for string 192 | // terminator \0 to be "printable" this is not transferred OTA 193 | // This union is used to simplify the construction of the binary data types transferred. 194 | union { 195 | uint8_t bValue; 196 | unsigned long ulValue; 197 | long lValue; 198 | unsigned int uiValue; 199 | int iValue; 200 | struct { // Float messages 201 | float fValue; 202 | uint8_t fPrecision; // Number of decimals when serializing 203 | }; 204 | struct { // Presentation messages 205 | uint8_t version; // Library version 206 | uint8_t sensorType; // Sensor type hint for controller, see table above 207 | }; 208 | char data[MAX_PAYLOAD + 1]; 209 | } __attribute__((packed)); 210 | #ifdef __cplusplus 211 | } __attribute__((packed)); 212 | #else 213 | }; 214 | uint8_t array[HEADER_SIZE + MAX_PAYLOAD + 1]; 215 | } __attribute__((packed)) MyMessage; 216 | #endif 217 | 218 | #endif 219 | -------------------------------------------------------------------------------- /libraries/MySensors/Version.h: -------------------------------------------------------------------------------- 1 | /*** 2 | * This file defines the Sensor library version number 3 | * Normally, contributors should not modify this directly 4 | * as it is manaaged by the MySensors Bot. 5 | */ 6 | #ifndef Version_h 7 | #define Version_h 8 | 9 | #define LIBRARY_VERSION "1.4.1" 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/BatteryPoweredSensor/BatteryPoweredSensor.ino: -------------------------------------------------------------------------------- 1 | // This is an example that demonstrates how to report the battery level for a sensor 2 | // Instructions for measuring battery capacity on A0 are available in the follwoing forum 3 | // thread: http://forum.micasaverde.com/index.php/topic,20078.0.html 4 | 5 | #include 6 | #include 7 | 8 | int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point 9 | 10 | MySensor gw; 11 | unsigned long SLEEP_TIME = 900000; // sleep time between reads (seconds * 1000 milliseconds) 12 | int oldBatteryPcnt = 0; 13 | 14 | void setup() 15 | { 16 | // use the 1.1 V internal reference 17 | analogReference(INTERNAL); 18 | gw.begin(); 19 | 20 | // Send the sketch version information to the gateway and Controller 21 | gw.sendSketchInfo("Battery Meter", "1.0"); 22 | } 23 | 24 | void loop() 25 | { 26 | // get the battery Voltage 27 | int sensorValue = analogRead(BATTERY_SENSE_PIN); 28 | Serial.println(sensorValue); 29 | 30 | // 1M, 470K divider across battery and using internal ADC ref of 1.1V 31 | // Sense point is bypassed with 0.1 uF cap to reduce noise at that point 32 | // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts 33 | // 3.44/1023 = Volts per bit = 0.003363075 34 | float batteryV = sensorValue * 0.003363075; 35 | int batteryPcnt = sensorValue / 10; 36 | 37 | Serial.print("Battery Voltage: "); 38 | Serial.print(batteryV); 39 | Serial.println(" V"); 40 | 41 | Serial.print("Battery percent: "); 42 | Serial.print(batteryPcnt); 43 | Serial.println(" %"); 44 | 45 | if (oldBatteryPcnt != batteryPcnt) { 46 | // Power up radio after sleep 47 | gw.sendBatteryLevel(batteryPcnt); 48 | oldBatteryPcnt = batteryPcnt; 49 | } 50 | gw.sleep(SLEEP_TIME); 51 | } 52 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/BinarySwitchSensor/BinarySwitchSensor.ino: -------------------------------------------------------------------------------- 1 | // Simple binary switch example 2 | // Connect button or door/window reed switch between 3 | // digitial I/O pin 3 (BUTTON_PIN below) and GND. 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #define CHILD_ID 3 10 | #define BUTTON_PIN 3 // Arduino Digital I/O pin for button/reed switch 11 | 12 | MySensor gw; 13 | Bounce debouncer = Bounce(); 14 | int oldValue=-1; 15 | 16 | // Change to V_LIGHT if you use S_LIGHT in presentation below 17 | MyMessage msg(CHILD_ID,V_TRIPPED); 18 | 19 | void setup() 20 | { 21 | gw.begin(); 22 | 23 | // Setup the button 24 | pinMode(BUTTON_PIN,INPUT); 25 | // Activate internal pull-up 26 | digitalWrite(BUTTON_PIN,HIGH); 27 | 28 | // After setting up the button, setup debouncer 29 | debouncer.attach(BUTTON_PIN); 30 | debouncer.interval(5); 31 | 32 | // Register binary input sensor to gw (they will be created as child devices) 33 | // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage. 34 | // If S_LIGHT is used, remember to update variable type you send in. See "msg" above. 35 | gw.present(CHILD_ID, S_DOOR); 36 | } 37 | 38 | 39 | // Check if digital input has changed and send in new value 40 | void loop() 41 | { 42 | debouncer.update(); 43 | // Get the update value 44 | int value = debouncer.read(); 45 | 46 | if (value != oldValue) { 47 | // Send in the new value 48 | gw.send(msg.set(value==HIGH ? 1 : 0)); 49 | oldValue = value; 50 | } 51 | } 52 | 53 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/BinarySwitchSleepSensor/BinarySwitchSleepSensor.ino: -------------------------------------------------------------------------------- 1 | // Interrupt driven binary switch example with dual interrupts 2 | // Author: Patrick 'Anticimex' Fallberg 3 | // Connect one button or door/window reed switch between 4 | // digitial I/O pin 3 (BUTTON_PIN below) and GND and the other 5 | // one in similar fashion on digital I/O pin 2. 6 | // This example is designed to fit Arduino Nano/Pro Mini 7 | 8 | #include 9 | #include 10 | 11 | #define SKETCH_NAME "Binary Sensor" 12 | #define SKETCH_MAJOR_VER "1" 13 | #define SKETCH_MINOR_VER "0" 14 | 15 | #define PRIMARY_CHILD_ID 3 16 | #define SECONDARY_CHILD_ID 4 17 | 18 | #define PRIMARY_BUTTON_PIN 2 // Arduino Digital I/O pin for button/reed switch 19 | #define SECONDARY_BUTTON_PIN 3 // Arduino Digital I/O pin for button/reed switch 20 | 21 | #if (PRIMARY_BUTTON_PIN < 2 || PRIMARY_BUTTON_PIN > 3) 22 | #error PRIMARY_BUTTON_PIN must be either 2 or 3 for interrupts to work 23 | #endif 24 | #if (SECONDARY_BUTTON_PIN < 2 || SECONDARY_BUTTON_PIN > 3) 25 | #error SECONDARY_BUTTON_PIN must be either 2 or 3 for interrupts to work 26 | #endif 27 | #if (PRIMARY_BUTTON_PIN == SECONDARY_BUTTON_PIN) 28 | #error PRIMARY_BUTTON_PIN and BUTTON_PIN2 cannot be the same 29 | #endif 30 | #if (PRIMARY_CHILD_ID == SECONDARY_CHILD_ID) 31 | #error PRIMARY_CHILD_ID and SECONDARY_CHILD_ID cannot be the same 32 | #endif 33 | 34 | MySensor sensor_node; 35 | 36 | // Change to V_LIGHT if you use S_LIGHT in presentation below 37 | MyMessage msg(PRIMARY_CHILD_ID, V_TRIPPED); 38 | MyMessage msg2(SECONDARY_CHILD_ID, V_TRIPPED); 39 | 40 | void setup() 41 | { 42 | sensor_node.begin(); 43 | 44 | // Setup the buttons 45 | pinMode(PRIMARY_BUTTON_PIN, INPUT); 46 | pinMode(SECONDARY_BUTTON_PIN, INPUT); 47 | 48 | // Activate internal pull-ups 49 | digitalWrite(PRIMARY_BUTTON_PIN, HIGH); 50 | digitalWrite(SECONDARY_BUTTON_PIN, HIGH); 51 | 52 | // Send the sketch version information to the gateway and Controller 53 | sensor_node.sendSketchInfo(SKETCH_NAME, SKETCH_MAJOR_VER"."SKETCH_MINOR_VER); 54 | 55 | // Register binary input sensor to sensor_node (they will be created as child devices) 56 | // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage. 57 | // If S_LIGHT is used, remember to update variable type you send in. See "msg" above. 58 | sensor_node.present(PRIMARY_CHILD_ID, S_DOOR); 59 | sensor_node.present(SECONDARY_CHILD_ID, S_DOOR); 60 | } 61 | 62 | // Loop will iterate on changes on the BUTTON_PINs 63 | void loop() 64 | { 65 | uint8_t value; 66 | static uint8_t sentValue=2; 67 | static uint8_t sentValue2=2; 68 | 69 | // Short delay to allow buttons to properly settle 70 | sensor_node.sleep(5); 71 | 72 | value = digitalRead(PRIMARY_BUTTON_PIN); 73 | 74 | if (value != sentValue) { 75 | // Value has changed from last transmission, send the updated value 76 | sensor_node.send(msg.set(value==HIGH ? 1 : 0)); 77 | sentValue = value; 78 | } 79 | 80 | value = digitalRead(SECONDARY_BUTTON_PIN); 81 | 82 | if (value != sentValue2) { 83 | // Value has changed from last transmission, send the updated value 84 | sensor_node.send(msg2.set(value==HIGH ? 1 : 0)); 85 | sentValue2 = value; 86 | } 87 | 88 | // Sleep until something happens with the sensor 89 | sensor_node.sleep(PRIMARY_BUTTON_PIN-2, CHANGE, SECONDARY_BUTTON_PIN-2, CHANGE, 0); 90 | } 91 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/ClearEepromConfig/ClearEepromConfig.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * This sketch clears radioId, relayId and routing info in EEPROM 4 | * 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | void setup() 11 | { 12 | for (int i=0;i<512;i++) { 13 | EEPROM.write(i, 0xff); 14 | } 15 | } 16 | 17 | void loop() 18 | { 19 | // Nothing to do here... 20 | } 21 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/DallasTemperatureSensor/DallasTemperatureSensor.ino: -------------------------------------------------------------------------------- 1 | // Example sketch showing how to send in OneWire temperature readings 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected 8 | #define MAX_ATTACHED_DS18B20 16 9 | unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds) 10 | OneWire oneWire(ONE_WIRE_BUS); 11 | DallasTemperature sensors(&oneWire); 12 | MySensor gw; 13 | float lastTemperature[MAX_ATTACHED_DS18B20]; 14 | int numSensors=0; 15 | boolean receivedConfig = false; 16 | boolean metric = true; 17 | // Initialize temperature message 18 | MyMessage msg(0,V_TEMP); 19 | 20 | void setup() 21 | { 22 | // Startup OneWire 23 | sensors.begin(); 24 | 25 | // Startup and initialize MySensors library. Set callback for incoming messages. 26 | gw.begin(); 27 | 28 | // Send the sketch version information to the gateway and Controller 29 | gw.sendSketchInfo("Temperature Sensor", "1.0"); 30 | 31 | // Fetch the number of attached temperature sensors 32 | numSensors = sensors.getDeviceCount(); 33 | 34 | // Present all sensors to controller 35 | for (int i=0; i(static_cast((gw.getConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.; 54 | 55 | // Only send data if temperature has changed and no error 56 | if (lastTemperature[i] != temperature && temperature != -127.00) { 57 | 58 | // Send in the new temperature 59 | gw.send(msg.setSensor(i).set(temperature,1)); 60 | lastTemperature[i]=temperature; 61 | } 62 | } 63 | gw.sleep(SLEEP_TIME); 64 | } 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/DimmableLEDActuator/DimmableLEDActuator.ino: -------------------------------------------------------------------------------- 1 | /*** 2 | * This program is free software; you can redistribute it and/or 3 | * modify it under the terms of the GNU General Public License 4 | * version 2 as published by the Free Software Foundation. 5 | * 6 | * DESCRIPTION 7 | * This sketch provides a Dimmable LED Light using PWM and based Henrik Ekblad 8 | * Vera Arduino Sensor project. 9 | * Developed by Bruce Lacey, inspired by Hek's MySensor's example sketches. 10 | * 11 | * The circuit uses a MOSFET for Pulse-Wave-Modulation to dim the attached LED or LED strip. 12 | * The MOSFET Gate pin is connected to Arduino pin 3 (LED_PIN), the MOSFET Drain pin is connected 13 | * to the LED negative terminal and the MOSFET Source pin is connected to ground. 14 | * 15 | * This sketch is extensible to support more than one MOSFET/PWM dimmer per circuit. 16 | * 17 | * REVISION HISTORY 18 | * Version 1.0 - February 15, 2014 - Bruce Lacey 19 | * Version 1.1 - August 13, 2014 - Converted to 1.4 (hek) 20 | * 21 | ***/ 22 | #define SN "DimmableLED" 23 | #define SV "1.1" 24 | 25 | #include 26 | #include 27 | 28 | #define LED_PIN 3 // Arduino pin attached to MOSFET Gate pin 29 | #define FADE_DELAY 10 // Delay in ms for each percentage fade up/down (10ms = 1s full-range dim) 30 | 31 | MySensor gw; 32 | 33 | static int currentLevel = 0; // Current dim level... 34 | MyMessage dimmerMsg(0, V_DIMMER); 35 | MyMessage lightMsg(0, V_LIGHT); 36 | 37 | 38 | /*** 39 | * Dimmable LED initialization method 40 | */ 41 | void setup() 42 | { 43 | Serial.println( SN ); 44 | gw.begin( incomingMessage ); 45 | 46 | // Register the LED Dimmable Light with the gateway 47 | gw.present( 0, S_DIMMER ); 48 | 49 | gw.sendSketchInfo(SN, SV); 50 | // Pull the gateway's current dim level - restore light level upon sendor node power-up 51 | gw.request( 0, V_DIMMER ); 52 | } 53 | 54 | /*** 55 | * Dimmable LED main processing loop 56 | */ 57 | void loop() 58 | { 59 | gw.process(); 60 | } 61 | 62 | 63 | 64 | void incomingMessage(const MyMessage &message) { 65 | if (message.type == V_LIGHT || message.type == V_DIMMER) { 66 | 67 | // Retrieve the power or dim level from the incoming request message 68 | int requestedLevel = atoi( message.data ); 69 | 70 | // Adjust incoming level if this is a V_LIGHT variable update [0 == off, 1 == on] 71 | requestedLevel *= ( message.type == V_LIGHT ? 100 : 1 ); 72 | 73 | // Clip incoming level to valid range of 0 to 100 74 | requestedLevel = requestedLevel > 100 ? 100 : requestedLevel; 75 | requestedLevel = requestedLevel < 0 ? 0 : requestedLevel; 76 | 77 | Serial.print( "Changing level to " ); 78 | Serial.print( requestedLevel ); 79 | Serial.print( ", from " ); 80 | Serial.println( currentLevel ); 81 | 82 | fadeToLevel( requestedLevel ); 83 | 84 | // Inform the gateway of the current DimmableLED's SwitchPower1 and LoadLevelStatus value... 85 | gw.send(lightMsg.set(currentLevel > 0 ? 1 : 0)); 86 | 87 | // hek comment: Is this really nessesary? 88 | gw.send( dimmerMsg.set(currentLevel) ); 89 | 90 | 91 | } 92 | } 93 | 94 | /*** 95 | * This method provides a graceful fade up/down effect 96 | */ 97 | void fadeToLevel( int toLevel ) { 98 | 99 | int delta = ( toLevel - currentLevel ) < 0 ? -1 : 1; 100 | 101 | while ( currentLevel != toLevel ) { 102 | currentLevel += delta; 103 | analogWrite( LED_PIN, (int)(currentLevel / 100. * 255) ); 104 | delay( FADE_DELAY ); 105 | } 106 | } 107 | 108 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/DimmableLight/DimmableLight.ino: -------------------------------------------------------------------------------- 1 | /*** 2 | * This program is free software; you can redistribute it and/or 3 | * modify it under the terms of the GNU General Public License 4 | * version 2 as published by the Free Software Foundation. 5 | * 6 | * DESCRIPTION 7 | * This sketch provides an example how to implement a Dimmable Light 8 | * It is pure virtual and it logs messages to the serial output 9 | * It can be used as a base sketch for actual hardware. 10 | * Stores the last light state and level in eeprom. 11 | * 12 | * Developed by GizMoCuz (Domoticz) 13 | * 14 | * REVISION HISTORY 15 | * Version 1.0 - January 30, 2015 16 | * 17 | ***/ 18 | 19 | #include 20 | #include 21 | 22 | #define CHILD_ID_LIGHT 1 23 | 24 | #define EPROM_LIGHT_STATE 1 25 | #define EPROM_DIMMER_LEVEL 2 26 | 27 | #define LIGHT_OFF 0 28 | #define LIGHT_ON 1 29 | 30 | #define SN "Dimable Light" 31 | #define SV "1.0" 32 | 33 | int LastLightState=LIGHT_OFF; 34 | int LastDimValue=100; 35 | 36 | MySensor gw; 37 | MyMessage lightMsg(CHILD_ID_LIGHT, V_LIGHT); 38 | MyMessage dimmerMsg(CHILD_ID_LIGHT, V_DIMMER); 39 | 40 | void setup() 41 | { 42 | gw.begin(incomingMessage, AUTO, false); 43 | 44 | // Send the Sketch Version Information to the Gateway 45 | gw.sendSketchInfo(SN, SV); 46 | 47 | gw.present(CHILD_ID_LIGHT, S_DIMMER ); 48 | 49 | //Retreive our last light state from the eprom 50 | int LightState=gw.loadState(EPROM_LIGHT_STATE); 51 | if (LightState<=1) { 52 | LastLightState=LightState; 53 | int DimValue=gw.loadState(EPROM_DIMMER_LEVEL); 54 | if ((DimValue>0)&&(DimValue<=100)) { 55 | //There should be no Dim value of 0, this would mean LIGHT_OFF 56 | LastDimValue=DimValue; 57 | } 58 | } 59 | 60 | //Here you actualy switch on/off the light with the last known dim level 61 | SetCurrentState2Hardware(); 62 | 63 | Serial.println( "Node ready to receive messages..." ); 64 | } 65 | 66 | void loop() 67 | { 68 | //delay(1000); // Removed by hek 69 | // Process incoming messages (like config and light state from controller) 70 | gw.process(); 71 | } 72 | 73 | void incomingMessage(const MyMessage &message) 74 | { 75 | if (message.type == V_LIGHT) { 76 | Serial.println( "V_LIGHT command received..." ); 77 | 78 | int lstate= atoi( message.data ); 79 | if ((lstate<0)||(lstate>1)) { 80 | Serial.println( "V_LIGHT data invalid (should be 0/1)" ); 81 | return; 82 | } 83 | LastLightState=lstate; 84 | gw.saveState(EPROM_LIGHT_STATE, LastLightState); 85 | 86 | if ((LastLightState==LIGHT_ON)&&(LastDimValue==0)) { 87 | //In the case that the Light State = On, but the dimmer value is zero, 88 | //then something (probably the controller) did something wrong, 89 | //for the Dim value to 100% 90 | LastDimValue=100; 91 | gw.saveState(EPROM_DIMMER_LEVEL, LastDimValue); 92 | } 93 | 94 | //When receiving a V_LIGHT command we switch the light between OFF and the last received dimmer value 95 | //This means if you previously set the lights dimmer value to 50%, and turn the light ON 96 | //it will do so at 50% 97 | } 98 | else if (message.type == V_DIMMER) { 99 | Serial.println( "V_DIMMER command received..." ); 100 | int dimvalue= atoi( message.data ); 101 | if ((dimvalue<0)||(dimvalue>100)) { 102 | Serial.println( "V_DIMMER data invalid (should be 0..100)" ); 103 | return; 104 | } 105 | if (dimvalue==0) { 106 | LastLightState=LIGHT_OFF; 107 | } 108 | else { 109 | LastLightState=LIGHT_ON; 110 | LastDimValue=dimvalue; 111 | gw.saveState(EPROM_DIMMER_LEVEL, LastDimValue); 112 | } 113 | } 114 | else { 115 | Serial.println( "Invalid command received..." ); 116 | return; 117 | } 118 | 119 | //Here you set the actual light state/level 120 | SetCurrentState2Hardware(); 121 | } 122 | 123 | void SetCurrentState2Hardware() 124 | { 125 | if (LastLightState==LIGHT_OFF) { 126 | Serial.println( "Light state: OFF" ); 127 | } 128 | else { 129 | Serial.print( "Light state: ON, Level: " ); 130 | Serial.println( LastDimValue ); 131 | } 132 | 133 | //Send current state to the controller 134 | SendCurrentState2Controller(); 135 | } 136 | 137 | void SendCurrentState2Controller() 138 | { 139 | if ((LastLightState==LIGHT_OFF)||(LastDimValue==0)) { 140 | gw.send(dimmerMsg.set(0)); 141 | } 142 | else { 143 | gw.send(dimmerMsg.set(LastDimValue)); 144 | } 145 | } 146 | 147 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/DistanceSensor/DistanceSensor.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define CHILD_ID 1 6 | #define TRIGGER_PIN 6 // Arduino pin tied to trigger pin on the ultrasonic sensor. 7 | #define ECHO_PIN 5 // Arduino pin tied to echo pin on the ultrasonic sensor. 8 | #define MAX_DISTANCE 300 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm. 9 | unsigned long SLEEP_TIME = 5000; // Sleep time between reads (in milliseconds) 10 | 11 | MySensor gw; 12 | NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance. 13 | MyMessage msg(CHILD_ID, V_DISTANCE); 14 | int lastDist; 15 | boolean metric = true; 16 | 17 | void setup() 18 | { 19 | gw.begin(); 20 | 21 | // Send the sketch version information to the gateway and Controller 22 | gw.sendSketchInfo("Distance Sensor", "1.0"); 23 | 24 | // Register all sensors to gw (they will be created as child devices) 25 | gw.present(CHILD_ID, S_DISTANCE); 26 | boolean metric = gw.getConfig().isMetric; 27 | } 28 | 29 | void loop() 30 | { 31 | int dist = metric?sonar.ping_cm():sonar.ping_in(); 32 | Serial.print("Ping: "); 33 | Serial.print(dist); // Convert ping time to distance in cm and print result (0 = outside set distance range) 34 | Serial.println(metric?" cm":" in"); 35 | 36 | if (dist != lastDist) { 37 | gw.send(msg.set(dist)); 38 | lastDist = dist; 39 | } 40 | 41 | gw.sleep(SLEEP_TIME); 42 | } 43 | 44 | 45 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/DustSensor/DustSensor.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Arduino Dust Sensort 3 | 4 | connect the sensor as follows : 5 | 6 | VCC >>> 5V 7 | A >>> A0 8 | GND >>> GND 9 | 10 | Based on: http://www.dfrobot.com/wiki/index.php/Sharp_GP2Y1010AU 11 | Authors: Cyrille Médard de Chardon (serialC), Christophe Trefois (Trefex) 12 | Contribution: epierre 13 | COnverted to 1.4 by Henrik Ekblad 14 | 15 | The dust sensor used (see purchase guide for latest link): 16 | http://rover.ebay.com/rover/1/711-53200-19255-0/1?icep_ff3=2&pub=5575069610&toolid=10001&campid=5337433187&customid=&icep_item=171259125886&ipn=psmain&icep_vectorid=229466&kwid=902099&mtid=824&kw=lg 17 | 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | #define CHILD_ID_DUST 0 24 | #define DUST_SENSOR_ANALOG_PIN 1 25 | 26 | unsigned long SLEEP_TIME = 30*1000; // Sleep time between reads (in milliseconds) 27 | //VARIABLES 28 | int val = 0; // variable to store the value coming from the sensor 29 | float valDUST =0.0; 30 | float lastDUST =0.0; 31 | int samplingTime = 280; 32 | int deltaTime = 40; 33 | int sleepTime = 9680; 34 | float voMeasured = 0; 35 | float calcVoltage = 0; 36 | float dustDensity = 0; 37 | 38 | MySensor gw; 39 | MyMessage dustMsg(CHILD_ID_DUST, V_DUST_LEVEL); 40 | 41 | void setup() 42 | { 43 | gw.begin(); 44 | 45 | // Send the sketch version information to the gateway and Controller 46 | gw.sendSketchInfo("Dust Sensor", "1.1"); 47 | 48 | // Register all sensors to gateway (they will be created as child devices) 49 | gw.present(CHILD_ID_DUST, S_DUST); 50 | 51 | } 52 | 53 | void loop() 54 | { 55 | uint16_t voMeasured = analogRead(DUST_SENSOR_ANALOG_PIN);// Get DUST value 56 | 57 | // 0 - 5V mapped to 0 - 1023 integer values 58 | // recover voltage 59 | calcVoltage = voMeasured * (5.0 / 1024.0); 60 | 61 | // linear eqaution taken from http://www.howmuchsnow.com/arduino/airquality/ 62 | // Chris Nafis (c) 2012 63 | dustDensity = (0.17 * calcVoltage - 0.1)*1000; 64 | 65 | Serial.print("Raw Signal Value (0-1023): "); 66 | Serial.print(voMeasured); 67 | 68 | Serial.print(" - Voltage: "); 69 | Serial.print(calcVoltage); 70 | 71 | Serial.print(" - Dust Density: "); 72 | Serial.println(dustDensity); // unit: ug/m3 73 | 74 | if (ceil(dustDensity) != lastDUST) { 75 | gw.send(dustMsg.set((int)ceil(dustDensity))); 76 | lastDUST = ceil(dustDensity); 77 | } 78 | 79 | gw.sleep(SLEEP_TIME); 80 | } 81 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/EnergyMeterPulseSensor/EnergyMeterPulseSensor.ino: -------------------------------------------------------------------------------- 1 | // Use this sensor to measure KWH and Watt of your house meeter 2 | // You need to set the correct pulsefactor of your meeter (blinks per KWH). 3 | // The sensor starts by fetching current KWH value from gateway. 4 | // Reports both KWH and Watt back to gateway. 5 | // 6 | // Unfortunately millis() won't increment when the Arduino is in 7 | // sleepmode. So we cannot make this sensor sleep if we also want 8 | // to calculate/report watt-number. 9 | 10 | #include 11 | #include 12 | 13 | #define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your light sensor. (Only 2 and 3 generates interrupt!) 14 | #define PULSE_FACTOR 1000 // Nummber of blinks per KWH of your meeter 15 | #define SLEEP_MODE false // Watt-value can only be reported when sleep mode is false. 16 | #define MAX_WATT 10000 // Max watt value to report. This filetrs outliers. 17 | #define INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway) 18 | #define CHILD_ID 1 // Id of the sensor child 19 | unsigned long SEND_FREQUENCY = 20000; // Minimum time between send (in milliseconds). We don't wnat to spam the gateway. 20 | MySensor gw; 21 | double ppwh = ((double)PULSE_FACTOR)/1000; // Pulses per watt hour 22 | boolean pcReceived = false; 23 | volatile unsigned long pulseCount = 0; 24 | volatile unsigned long lastBlink = 0; 25 | volatile unsigned long watt = 0; 26 | unsigned long oldPulseCount = 0; 27 | unsigned long oldWatt = 0; 28 | double oldKwh; 29 | unsigned long lastSend; 30 | MyMessage wattMsg(CHILD_ID,V_WATT); 31 | MyMessage kwhMsg(CHILD_ID,V_KWH); 32 | MyMessage pcMsg(CHILD_ID,V_VAR1); 33 | 34 | 35 | void setup() 36 | { 37 | gw.begin(incomingMessage); 38 | 39 | // Send the sketch version information to the gateway and Controller 40 | gw.sendSketchInfo("Energy Meter", "1.0"); 41 | 42 | // Register this device as power sensor 43 | gw.present(CHILD_ID, S_POWER); 44 | 45 | // Fetch last known pulse count value from gw 46 | gw.request(CHILD_ID, V_VAR1); 47 | 48 | attachInterrupt(INTERRUPT, onPulse, RISING); 49 | lastSend=millis(); 50 | } 51 | 52 | 53 | void loop() 54 | { 55 | gw.process(); 56 | unsigned long now = millis(); 57 | // Only send values at a maximum frequency or woken up from sleep 58 | bool sendTime = now - lastSend > SEND_FREQUENCY; 59 | if (pcReceived && (SLEEP_MODE || sendTime)) { 60 | // New watt value has been calculated 61 | if (!SLEEP_MODE && watt != oldWatt) { 62 | // Check that we dont get unresonable large watt value. 63 | // could hapen when long wraps or false interrupt triggered 64 | if (watt<((unsigned long)MAX_WATT)) { 65 | gw.send(wattMsg.set(watt)); // Send watt value to gw 66 | } 67 | Serial.print("Watt:"); 68 | Serial.println(watt); 69 | oldWatt = watt; 70 | } 71 | 72 | // Pulse cout has changed 73 | if (pulseCount != oldPulseCount) { 74 | gw.send(pcMsg.set(pulseCount)); // Send pulse count value to gw 75 | double kwh = ((double)pulseCount/((double)PULSE_FACTOR)); 76 | oldPulseCount = pulseCount; 77 | if (kwh != oldKwh) { 78 | gw.send(kwhMsg.set(kwh, 4)); // Send kwh value to gw 79 | oldKwh = kwh; 80 | } 81 | } 82 | lastSend = now; 83 | } else if (sendTime && !pcReceived) { 84 | // No count received. Try requesting it again 85 | gw.request(CHILD_ID, V_VAR1); 86 | lastSend=now; 87 | } 88 | 89 | if (SLEEP_MODE) { 90 | gw.sleep(SEND_FREQUENCY); 91 | } 92 | } 93 | 94 | void incomingMessage(const MyMessage &message) { 95 | if (message.type==V_VAR1) { 96 | pulseCount = oldPulseCount = message.getLong(); 97 | Serial.print("Received last pulse count from gw:"); 98 | Serial.println(pulseCount); 99 | pcReceived = true; 100 | } 101 | } 102 | 103 | void onPulse() 104 | { 105 | if (!SLEEP_MODE) { 106 | unsigned long newBlink = micros(); 107 | unsigned long interval = newBlink-lastBlink; 108 | if (interval<10000L) { // Sometimes we get interrupt on RISING 109 | return; 110 | } 111 | watt = (3600000000.0 /interval) / ppwh; 112 | lastBlink = newBlink; 113 | } 114 | pulseCount++; 115 | } 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/EthernetGateway/EthernetGateway.ino: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2013 Henrik Ekblad 4 | * 5 | * Contribution by a-lurker 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License 9 | * version 2 as published by the Free Software Foundation. 10 | * 11 | * DESCRIPTION 12 | * The EthernetGateway sends data received from sensors to the ethernet link. 13 | * The gateway also accepts input on ethernet interface, which is then sent out to the radio network. 14 | * 15 | * The GW code is designed for Arduino 328p / 16MHz. ATmega168 does not have enough memory to run this program. 16 | * 17 | * 18 | * COMPILING WIZNET (W5100) ETHERNET MODULE 19 | * > Edit RF24_config.h in (libraries\MySensors\utility) to enable softspi (remove // before "#define SOFTSPI"). 20 | * 21 | * COMPILING ENC28J60 ETHERNET MODULE 22 | * > Use Arduino IDE 1.5.7 (or later) 23 | * > Disable DEBUG in Sensor.h before compiling this sketch. Othervise the sketch will probably not fit in program space when downloading. 24 | * > Remove Ethernet.h include below and include UIPEthernet.h 25 | * > Remove DigitalIO include 26 | * Note that I had to disable UDP and DHCP support in uipethernet-conf.h to reduce space. (which means you have to choose a static IP for that module) 27 | * 28 | * VERA CONFIGURATION: 29 | * Enter "ip-number:port" in the ip-field of the Arduino GW device. This will temporarily override any serial configuration for the Vera plugin. 30 | * E.g. If you want to use the defualt values in this sketch enter: 192.168.178.66:5003 31 | * 32 | * LED purposes: 33 | * - RX (green) - blink fast on radio message recieved. In inclusion mode will blink fast only on presentation recieved 34 | * - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly 35 | * - ERR (red) - fast blink on error during transmission error or recieve crc error 36 | * 37 | * See http://www.mysensors.org/build/ethernet_gateway for wiring instructions. 38 | * 39 | */ 40 | 41 | #include // This include can be removed when using UIPEthernet module 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | // Use this if you have attached a Ethernet ENC28J60 shields 48 | //#include 49 | 50 | // Use this fo WizNET W5100 module and Arduino Ethernet Shield 51 | #include 52 | 53 | 54 | #define INCLUSION_MODE_TIME 1 // Number of minutes inclusion mode is enabled 55 | #define INCLUSION_MODE_PIN 3 // Digital pin used for inclusion mode button 56 | 57 | #define RADIO_CE_PIN 5 // radio chip enable 58 | #define RADIO_SPI_SS_PIN 6 // radio SPI serial select 59 | #define RADIO_ERROR_LED_PIN 7 // Error led pin 60 | #define RADIO_RX_LED_PIN 8 // Receive led pin 61 | #define RADIO_TX_LED_PIN 9 // the PCB, on board LED 62 | 63 | #define IP_PORT 5003 // The port you want to open 64 | IPAddress myIp (192, 168, 178, 66); // Configure your static ip-address here COMPILE ERROR HERE? Use Arduino IDE 1.5.7 or later! 65 | 66 | // The MAC address can be anything you want but should be unique on your network. 67 | // Newer boards have a MAC address printed on the underside of the PCB, which you can (optionally) use. 68 | // Note that most of the Ardunio examples use "DEAD BEEF FEED" for the MAC address. 69 | byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // DEAD BEEF FEED 70 | 71 | // a R/W server on the port 72 | EthernetServer server = EthernetServer(IP_PORT); 73 | 74 | // No blink or button functionality. Use the vanilla constructor. 75 | MyGateway gw(RADIO_CE_PIN, RADIO_SPI_SS_PIN, INCLUSION_MODE_TIME); 76 | 77 | // Uncomment this constructor if you have leds and include button attached to your gateway 78 | //MyGateway gw(RADIO_CE_PIN, RADIO_SPI_SS_PIN, INCLUSION_MODE_TIME, INCLUSION_MODE_PIN, RADIO_RX_LED_PIN, RADIO_TX_LED_PIN, RADIO_ERROR_LED_PIN); 79 | 80 | 81 | char inputString[MAX_RECEIVE_LENGTH] = ""; // A string to hold incoming commands from serial/ethernet interface 82 | int inputPos = 0; 83 | 84 | void setup() 85 | { 86 | Ethernet.begin(mac, myIp); 87 | 88 | // give the Ethernet interface a second to initialize 89 | delay(1000); 90 | 91 | // Initialize gateway at maximum PA level, channel 70 and callback for write operations 92 | gw.begin(RF24_PA_LEVEL_GW, RF24_CHANNEL, RF24_DATARATE, writeEthernet); 93 | 94 | // start listening for clients 95 | server.begin(); 96 | } 97 | 98 | // This will be called when data should be written to ethernet 99 | void writeEthernet(char *writeBuffer) { 100 | server.write(writeBuffer); 101 | } 102 | 103 | 104 | void loop() 105 | { 106 | // if an incoming client connects, there will be 107 | // bytes available to read via the client object 108 | EthernetClient client = server.available(); 109 | 110 | if (client) { 111 | // if got 1 or more bytes 112 | if (client.available()) { 113 | // read the bytes incoming from the client 114 | char inChar = client.read(); 115 | 116 | if (inputPos 2 | #include 3 | #include 4 | 5 | #define CHILD_ID_HUM 0 6 | #define CHILD_ID_TEMP 1 7 | #define HUMIDITY_SENSOR_DIGITAL_PIN 3 8 | unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds) 9 | 10 | MySensor gw; 11 | DHT dht; 12 | float lastTemp; 13 | float lastHum; 14 | boolean metric = true; 15 | MyMessage msgHum(CHILD_ID_HUM, V_HUM); 16 | MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); 17 | 18 | 19 | void setup() 20 | { 21 | gw.begin(); 22 | dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); 23 | 24 | // Send the Sketch Version Information to the Gateway 25 | gw.sendSketchInfo("Humidity", "1.0"); 26 | 27 | // Register all sensors to gw (they will be created as child devices) 28 | gw.present(CHILD_ID_HUM, S_HUM); 29 | gw.present(CHILD_ID_TEMP, S_TEMP); 30 | 31 | metric = gw.getConfig().isMetric; 32 | } 33 | 34 | void loop() 35 | { 36 | delay(dht.getMinimumSamplingPeriod()); 37 | 38 | float temperature = dht.getTemperature(); 39 | if (isnan(temperature)) { 40 | Serial.println("Failed reading temperature from DHT"); 41 | } else if (temperature != lastTemp) { 42 | lastTemp = temperature; 43 | if (!metric) { 44 | temperature = dht.toFahrenheit(temperature); 45 | } 46 | gw.send(msgTemp.set(temperature, 1)); 47 | Serial.print("T: "); 48 | Serial.println(temperature); 49 | } 50 | 51 | float humidity = dht.getHumidity(); 52 | if (isnan(humidity)) { 53 | Serial.println("Failed reading humidity from DHT"); 54 | } else if (humidity != lastHum) { 55 | lastHum = humidity; 56 | gw.send(msgHum.set(humidity, 1)); 57 | Serial.print("H: "); 58 | Serial.println(humidity); 59 | } 60 | 61 | gw.sleep(SLEEP_TIME); //sleep a bit 62 | } 63 | 64 | 65 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/IrSensor/IrSensor.ino: -------------------------------------------------------------------------------- 1 | // Example sketch showing how to control ir devices 2 | // An IR LED must be connected to Arduino PWM pin 3. 3 | // An optional ir receiver can be connected to PWM pin 8. 4 | // All receied ir signals will be sent to gateway device stored in VAR_1. 5 | // When binary light on is clicked - sketch will send volume up ir command 6 | // When binary light off is clicked - sketch will send volume down ir command 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | int RECV_PIN = 8; 13 | 14 | #define CHILD_1 3 // childId 15 | 16 | IRsend irsend; 17 | IRrecv irrecv(RECV_PIN); 18 | IRdecode decoder; 19 | //decode_results results; 20 | unsigned int Buffer[RAWBUF]; 21 | MySensor gw; 22 | MyMessage msg(CHILD_1, V_VAR1); 23 | 24 | void setup() 25 | { 26 | irrecv.enableIRIn(); // Start the ir receiver 27 | decoder.UseExtnBuf(Buffer); 28 | gw.begin(incomingMessage); 29 | 30 | // Send the sketch version information to the gateway and Controller 31 | gw.sendSketchInfo("IR Sensor", "1.0"); 32 | 33 | // Register a sensors to gw. Use binary light for test purposes. 34 | gw.present(CHILD_1, S_LIGHT); 35 | } 36 | 37 | 38 | void loop() 39 | { 40 | gw.process(); 41 | if (irrecv.GetResults(&decoder)) { 42 | irrecv.resume(); 43 | decoder.decode(); 44 | decoder.DumpResults(); 45 | 46 | char buffer[10]; 47 | sprintf(buffer, "%08lx", decoder.value); 48 | // Send ir result to gw 49 | gw.send(msg.set(buffer)); 50 | } 51 | } 52 | 53 | 54 | 55 | void incomingMessage(const MyMessage &message) { 56 | // We only expect one type of message from controller. But we better check anyway. 57 | if (message.type==V_LIGHT) { 58 | int incomingRelayStatus = message.getInt(); 59 | if (incomingRelayStatus == 1) { 60 | irsend.send(NEC, 0x1EE17887, 32); // Vol up yamaha ysp-900 61 | } else { 62 | irsend.send(NEC, 0x1EE1F807, 32); // Vol down yamaha ysp-900 63 | } 64 | // Start receiving ir again... 65 | irrecv.enableIRIn(); 66 | } 67 | } 68 | 69 | // Dumps out the decode_results structure. 70 | // Call this after IRrecv::decode() 71 | // void * to work around compiler issue 72 | //void dump(void *v) { 73 | // decode_results *results = (decode_results *)v 74 | /*void dump(decode_results *results) { 75 | int count = results->rawlen; 76 | if (results->decode_type == UNKNOWN) { 77 | Serial.print("Unknown encoding: "); 78 | } 79 | else if (results->decode_type == NEC) { 80 | Serial.print("Decoded NEC: "); 81 | } 82 | else if (results->decode_type == SONY) { 83 | Serial.print("Decoded SONY: "); 84 | } 85 | else if (results->decode_type == RC5) { 86 | Serial.print("Decoded RC5: "); 87 | } 88 | else if (results->decode_type == RC6) { 89 | Serial.print("Decoded RC6: "); 90 | } 91 | else if (results->decode_type == PANASONIC) { 92 | Serial.print("Decoded PANASONIC - Address: "); 93 | Serial.print(results->panasonicAddress,HEX); 94 | Serial.print(" Value: "); 95 | } 96 | else if (results->decode_type == JVC) { 97 | Serial.print("Decoded JVC: "); 98 | } 99 | Serial.print(results->value, HEX); 100 | Serial.print(" ("); 101 | Serial.print(results->bits, DEC); 102 | Serial.println(" bits)"); 103 | Serial.print("Raw ("); 104 | Serial.print(count, DEC); 105 | Serial.print("): "); 106 | 107 | for (int i = 0; i < count; i++) { 108 | if ((i % 2) == 1) { 109 | Serial.print(results->rawbuf[i]*USECPERTICK, DEC); 110 | } 111 | else { 112 | Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC); 113 | } 114 | Serial.print(" "); 115 | } 116 | Serial.println(""); 117 | } 118 | */ 119 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/LightLuxSensor/LightLuxSensor.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Vera Arduino BH1750FVI Light sensor 3 | communicate using I2C Protocol 4 | this library enable 2 slave device addresses 5 | Main address 0x23 6 | secondary address 0x5C 7 | connect the sensor as follows : 8 | 9 | VCC >>> 5V 10 | Gnd >>> Gnd 11 | ADDR >>> NC or GND 12 | SCL >>> A5 13 | SDA >>> A4 14 | 15 | Contribution: idefix 16 | 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #define CHILD_ID_LIGHT 0 25 | #define LIGHT_SENSOR_ANALOG_PIN 0 26 | unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds) 27 | 28 | BH1750 lightSensor; 29 | MySensor gw; 30 | MyMessage msg(CHILD_ID_LIGHT, V_LIGHT_LEVEL); 31 | uint16_t lastlux; 32 | 33 | void setup() 34 | { 35 | gw.begin(); 36 | 37 | // Send the sketch version information to the gateway and Controller 38 | gw.sendSketchInfo("Light Lux Sensor", "1.0"); 39 | 40 | // Register all sensors to gateway (they will be created as child devices) 41 | gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL); 42 | 43 | lightSensor.begin(); 44 | } 45 | 46 | void loop() 47 | { 48 | uint16_t lux = lightSensor.readLightLevel();// Get Lux value 49 | Serial.println(lux); 50 | if (lux != lastlux) { 51 | gw.send(msg.set(lux)); 52 | lastlux = lux; 53 | } 54 | 55 | gw.sleep(SLEEP_TIME); 56 | } 57 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/LightSensor/LightSensor.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define CHILD_ID_LIGHT 0 5 | #define LIGHT_SENSOR_ANALOG_PIN 0 6 | 7 | unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds) 8 | 9 | MySensor gw; 10 | MyMessage msg(CHILD_ID_LIGHT, V_LIGHT_LEVEL); 11 | int lastLightLevel; 12 | 13 | void setup() 14 | { 15 | gw.begin(); 16 | 17 | // Send the sketch version information to the gateway and Controller 18 | gw.sendSketchInfo("Light Sensor", "1.0"); 19 | 20 | // Register all sensors to gateway (they will be created as child devices) 21 | gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL); 22 | } 23 | 24 | void loop() 25 | { 26 | int lightLevel = (1023-analogRead(LIGHT_SENSOR_ANALOG_PIN))/10.23; 27 | Serial.println(lightLevel); 28 | if (lightLevel != lastLightLevel) { 29 | gw.send(msg.set(lightLevel)); 30 | lastLightLevel = lightLevel; 31 | } 32 | gw.sleep(SLEEP_TIME); 33 | } 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/MAX6875TemperatureSensor/MAX6875TemperatureSensor.ino: -------------------------------------------------------------------------------- 1 | // MAX6875 Hight temperature sensor with range: -200 degC - +1300 degC 2 | // Contribution by MrLynx 3 | // http://forum.mysensors.org/topic/641/max6675 4 | // 5 | // Connect: 6 | // MAX6675 - Arduino 7 | // CS0 - 4 8 | // SO - 3 9 | // SCLK - 5 10 | // VCC - 5V 11 | // GND - GND 12 | 13 | #include 14 | #include 15 | #include 16 | uint8_t CS0 = 4; // CS pin on MAX6675 17 | uint8_t SO = 3; // SO pin of MAX6675 18 | uint8_t SCLK = 5; // SCK pin of MAX6675 19 | uint8_t units = 1; // Units to readout temp (0 = ˚F, 1 = ˚C) 20 | float temperature = 0.0; // Temperature output variable 21 | float lastTemperature; 22 | unsigned long SLEEP_TIME = 30000; 23 | boolean metric = true; 24 | MySensor gw; 25 | 26 | MyMessage msg(0, V_TEMP); 27 | 28 | // Initialize the MAX6675 Library for our chip 29 | 30 | MAX6675 temp0(CS0, SO, SCLK, units); 31 | 32 | void setup() 33 | { 34 | // Startup and initialize MySensors library. Set callback for incoming messages. 35 | gw.begin(); 36 | 37 | // Send the sketch version information to the gateway and Controller 38 | gw.sendSketchInfo("Max6675 Temp Sensor", "1.0"); 39 | 40 | // Present all sensors to controller 41 | gw.present(0, S_TEMP); 42 | } 43 | 44 | void loop() 45 | { 46 | // Process incoming messages (like config from server) 47 | gw.process(); 48 | 49 | temperature = temp0.read_temp(); // Read the temp 50 | 51 | if (temperature < 0) { // If there is an error with the TC, temperature will be < 0 52 | Serial.println("Thermocouple Error!!"); // There is a thermocouple error 53 | } else { 54 | Serial.print("Current Temperature: "); 55 | Serial.println( temperature ); // Print the temperature to Serial 56 | if (temperature != lastTemperature) 57 | gw.send(msg.setSensor(0).set(temperature, 1)); 58 | lastTemperature = temperature; 59 | } 60 | 61 | gw.sleep(SLEEP_TIME); 62 | } 63 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/MQTTGateway/MQTTGateway.ino: -------------------------------------------------------------------------------- 1 | /* MyMQTT Broker Gateway 0.1b 2 | 3 | Created by Daniel Wiegert 4 | Based on MySensors Ethernet Gateway by Henrik Ekblad 5 | http://www.mysensors.org 6 | 7 | Requires MySensors lib 1.4b 8 | 9 | * Change below; TCP_IP, TCP_PORT, TCP_MAC 10 | This will listen on your selected TCP_IP:TCP_PORT below, Please change TCP_MAC your liking also. 11 | *1 -> NOTE: Keep first byte at x2, x6, xA or xE (replace x with any hex value) for using Local Ranges. 12 | 13 | *2 You can use standard pin set-up as MySensors recommends or if you own a IBOARD you may change 14 | the radio-pins below if you hardware mod your iBoard. see [URL BELOW] for more details. 15 | http://forum.mysensors.org/topic/224/iboard-cheap-single-board-ethernet-arduino-with-radio/5 16 | 17 | * Don't forget to look at the definitions in libraries\MySensors\MyMQTT.h! 18 | 19 | define TCPDUMP and connect serial interface if you have problems, please write on 20 | http://forum.mysensors.org/ and explain your problem, include serial output. Don't forget to 21 | turn on DEBUG in libraries\MySensors\MyConfig.h also. 22 | 23 | MQTT_FIRST_SENSORID is for 'DHCP' server in MyMQTT. You may limit the ID's with FIRST and LAST definition. 24 | If you want your manually configured below 20 set MQTT_FIRST_SENSORID to 20. 25 | To disable: set MQTT_FIRST_SENSORID to 255. 26 | 27 | MQTT_BROKER_PREFIX is the leading prefix for your nodes. This can be only one char if like. 28 | 29 | MQTT_SEND_SUBSCRIPTION is if you want the MyMQTT to send a empty payload message to your nodes. 30 | This can be useful if you want to send latest state back to the MQTT client. Just check if incoming 31 | message has any length or not. 32 | Example: if (msg.type==V_LIGHT && strlen(msg.getString())>0) otherwise the code might do strange things. 33 | 34 | * Address-layout is : [MQTT_BROKER_PREFIX]/[NodeID]/[SensorID]/V_[SensorType] 35 | NodeID and SensorID is uint8 (0-255) number. 36 | Last segment is translation of the sensor type, look inside MyMQTT.cpp for the definitions. 37 | User can change this to their needs. We have also left some space for custom types. 38 | 39 | Special: (sensor 255 reserved for special commands) 40 | You can receive a node sketch name with MyMQTT/20/255/V_Sketch_name (or version with _version) 41 | 42 | To-do: 43 | Special commands : clear or set EEPROM Values, Send REBOOT and Receive reboot for MyMQTT itself. 44 | Be able to send ACK so client returns the data being sent. 45 | ... Please come with ideas! 46 | What to do with publish messages. 47 | 48 | Test in more MQTT clients, So far tested in openhab and MyMQTT for Android (Not my creation) 49 | - http://www.openhab.org/ 50 | - https://play.google.com/store/apps/details?id=at.tripwire.mqtt.client&hl=en 51 | ... Please notify me if you use this broker with other software. 52 | 53 | 54 | * How to set-up Openhab and MQTTGateway: 55 | http://forum.mysensors.org/topic/303/mqtt-broker-gateway 56 | 57 | */ 58 | 59 | #include 60 | #include 61 | #include 62 | #include 63 | #include 64 | 65 | // * Use this for IBOARD modded to use standard MISO/MOSI/SCK, see note *1 above! 66 | /* 67 | #define RADIO_CE_PIN 3 // radio chip enable 68 | #define RADIO_SPI_SS_PIN 8 // radio SPI serial select 69 | #define RADIO_ERROR_LED_PIN A2 // Error led pin 70 | #define RADIO_RX_LED_PIN A1 // Receive led pin 71 | #define RADIO_TX_LED_PIN A0 // the PCB, on board LED 72 | */ 73 | 74 | // * Use this for default configured pro mini / nano etc : 75 | ///* 76 | #define RADIO_CE_PIN 5 // radio chip enable 77 | #define RADIO_SPI_SS_PIN 6 // radio SPI serial select 78 | #define RADIO_ERROR_LED_PIN 7 // Error led pin 79 | #define RADIO_RX_LED_PIN 8 // Receive led pin 80 | #define RADIO_TX_LED_PIN 9 // the PCB, on board LED*/ 81 | 82 | #define TCP_PORT 1883 // Set your MQTT Broker Listening port. 83 | IPAddress TCP_IP ( 192, 168, 0, 234 ); // Configure your static ip-address here 84 | byte TCP_MAC[] = { 0x02, 0xDE, 0xAD, 0x00, 0x00, 0x42 }; // Mac-address - You should change this! see note *2 above! 85 | 86 | ////////////////////////////////////////////////////////////////// 87 | 88 | EthernetServer server = EthernetServer(TCP_PORT); 89 | EthernetClient *currentClient = NULL; 90 | MyMQTT gw(RADIO_CE_PIN, RADIO_SPI_SS_PIN); 91 | 92 | void processEthernetMessages() { 93 | char inputString[MQTT_MAX_PACKET_SIZE] = ""; 94 | byte inputSize = 0; 95 | byte readCnt = 0; 96 | byte length = 0; 97 | 98 | EthernetClient client = server.available(); 99 | if (client) { 100 | while (client.available()) { 101 | // Save the current client we are talking with 102 | currentClient = &client; 103 | byte inByte = client.read(); 104 | readCnt++; 105 | 106 | if (inputSize < MQTT_MAX_PACKET_SIZE) { 107 | inputString[inputSize] = (char)inByte; 108 | inputSize++; 109 | } 110 | 111 | if (readCnt == 2) { 112 | length = (inByte & 127) * 1; 113 | } 114 | if (readCnt == (length+2)) { 115 | break; 116 | } 117 | } 118 | #ifdef TCPDUMP 119 | Serial.print("<<"); 120 | char buf[4]; 121 | for (byte a=0; a>"); 131 | char buf[4]; 132 | for (byte a=0; a<*writeSize; a++) { sprintf(buf,"%02X ",(byte)writeBuffer[a]); Serial.print(buf); } Serial.println(); 133 | #endif 134 | // Check whether to respond to a single client or write to all 135 | if (currentClient != NULL) 136 | currentClient->write((const byte *)writeBuffer, *writeSize); 137 | else 138 | server.write((const byte *)writeBuffer, *writeSize); 139 | } 140 | 141 | int main(void) { 142 | init(); 143 | Ethernet.begin(TCP_MAC, TCP_IP); 144 | delay(1000); // Wait for Ethernet to get configured. 145 | gw.begin(RF24_PA_LEVEL_GW, RF24_CHANNEL, RF24_DATARATE, writeEthernet, RADIO_RX_LED_PIN, RADIO_TX_LED_PIN, RADIO_ERROR_LED_PIN); 146 | server.begin(); 147 | while (1) { 148 | processEthernetMessages(); 149 | gw.processRadioMessage(); 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/MotionSensor/MotionSensor.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds) 5 | #define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!) 6 | #define INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway) 7 | #define CHILD_ID 1 // Id of the sensor child 8 | 9 | MySensor gw; 10 | // Initialize motion message 11 | MyMessage msg(CHILD_ID, V_TRIPPED); 12 | 13 | void setup() 14 | { 15 | gw.begin(); 16 | 17 | // Send the sketch version information to the gateway and Controller 18 | gw.sendSketchInfo("Motion Sensor", "1.0"); 19 | 20 | pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input 21 | // Register all sensors to gw (they will be created as child devices) 22 | gw.present(CHILD_ID, S_MOTION); 23 | 24 | } 25 | 26 | void loop() 27 | { 28 | // Read digital motion value 29 | boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; 30 | 31 | Serial.println(tripped); 32 | gw.send(msg.set(tripped?"1":"0")); // Send tripped value to gw 33 | 34 | // Sleep until interrupt comes in on motion sensor. Send update every two minute. 35 | gw.sleep(INTERRUPT,CHANGE, SLEEP_TIME); 36 | } 37 | 38 | 39 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/MysensorMicro/MysensorMicro.ino: -------------------------------------------------------------------------------- 1 | // Default sensor sketch for MySensor Micro module 2 | // Act as a temperature / humidity sensor by default. 3 | // 4 | // If A0 is held low while powering on, it will enter testmode, which verifies all on-board peripherals 5 | // 6 | // Battery voltage is repported as child sensorId 199, as well as battery percentage 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | // Define a static node address, remove if you want auto address assignment 19 | //#define NODE_ADDRESS 3 20 | 21 | // Child sensor ID's 22 | #define CHILD_ID_TEMP 1 23 | #define CHILD_ID_HUM 2 24 | #define CHILD_ID_BATT 199 25 | 26 | //Pin definitions 27 | #define TEST_PIN A0 28 | #define LED_PIN A2 29 | #define ATSHA204_PIN 17 // A3 30 | 31 | const int sha204Pin = ATSHA204_PIN; 32 | atsha204Class sha204(sha204Pin); 33 | 34 | 35 | #define MEASURE_INTERVAL 60000 36 | 37 | // FORCE_TRANSMIT_INTERVAL, this number of times of wakeup, the sensor is forced to report all values to the controller 38 | #define FORCE_TRANSMIT_INTERVAL 30 39 | 40 | SI7021 humiditySensor; 41 | SPIFlash flash(8, 0x1F65); 42 | 43 | MySensor gw; 44 | 45 | // Sensor messages 46 | MyMessage msgHum(CHILD_ID_HUM, V_HUM); 47 | MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); 48 | MyMessage msgBattery(CHILD_ID_BATT, V_VOLTAGE); 49 | 50 | // Global settings 51 | int measureCount = 0; 52 | 53 | // Storage of old measurements 54 | float lastTemperature = -100; 55 | int lastHumidity = -100; 56 | long lastBattery = -100; 57 | 58 | 59 | void setup() { 60 | 61 | pinMode(LED_PIN, OUTPUT); 62 | digitalWrite(LED_PIN, LOW); 63 | 64 | Serial.begin(115200); 65 | // First check if we should boot into test mode 66 | 67 | pinMode(TEST_PIN,INPUT); 68 | digitalWrite(TEST_PIN, HIGH); // Enable pullup 69 | if (!digitalRead(TEST_PIN)) testMode(); 70 | 71 | digitalWrite(TEST_PIN,LOW); 72 | digitalWrite(LED_PIN, HIGH); 73 | 74 | #ifdef NODE_ADDRESS 75 | gw.begin(NULL, NODE_ADDRESS, false); 76 | #else 77 | gw.begin(NULL,AUTO,false); 78 | #endif 79 | 80 | digitalWrite(LED_PIN, LOW); 81 | 82 | humiditySensor.begin(); 83 | 84 | gw.sendSketchInfo("MysensorMicro", "1.0"); 85 | 86 | gw.present(CHILD_ID_TEMP,S_TEMP); 87 | gw.present(CHILD_ID_HUM,S_HUM); 88 | 89 | gw.present(CHILD_ID_BATT, S_POWER); 90 | switchClock(1< FORCE_TRANSMIT_INTERVAL 100 | ) {// Every 60th time we wake up, force a transmission on all sensors. 101 | forceTransmit = true; 102 | measureCount = 0; 103 | } 104 | 105 | gw.process(); 106 | sendBattLevel(forceTransmit); 107 | sendTempHumidityMeasurements(forceTransmit); 108 | 109 | gw.sleep(MEASURE_INTERVAL); 110 | } 111 | 112 | /* 113 | * Sends temperature and humidity from Si7021 sensor 114 | * 115 | * Parameters 116 | * - force : Forces transmission of a value (even if it's the same as previous measurement) 117 | */ 118 | void sendTempHumidityMeasurements(bool force) 119 | { 120 | if (force) { 121 | lastHumidity = -100; 122 | lastTemperature = -100; 123 | } 124 | 125 | si7021_env data = humiditySensor.getHumidityAndTemperature(); 126 | 127 | float temperature = data.celsiusHundredths/100; 128 | 129 | int humidity = data.humidityPercent; 130 | 131 | if (lastTemperature != temperature) { 132 | gw.send(msgTemp.set(temperature,1)); 133 | lastTemperature = temperature; 134 | } 135 | if (lastHumidity != humidity) { 136 | gw.send(msgHum.set(humidity)); 137 | lastHumidity = humidity; 138 | } 139 | } 140 | 141 | /* 142 | * Sends battery information (both voltage, and battery percentage) 143 | * 144 | * Parameters 145 | * - force : Forces transmission of a value 146 | */ 147 | void sendBattLevel(bool force) 148 | { 149 | if (force) lastBattery = -1; 150 | long vcc = readVcc(); 151 | if (vcc != lastBattery) { 152 | lastBattery = vcc; 153 | // Calculate percentage 154 | gw.send(msgBattery.set(vcc)); 155 | vcc = vcc - 1900; // subtract 1.9V from vcc, as this is the lowest voltage we will operate at 156 | 157 | long percent = vcc / 14; 158 | gw.sendBatteryLevel(percent); 159 | } 160 | } 161 | 162 | long readVcc() { 163 | // Read 1.1V reference against AVcc 164 | // set the reference to Vcc and the measurement to the internal 1.1V reference 165 | #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 166 | ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); 167 | #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) 168 | ADMUX = _BV(MUX5) | _BV(MUX0); 169 | #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) 170 | ADcdMUX = _BV(MUX3) | _BV(MUX2); 171 | #else 172 | ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); 173 | #endif 174 | 175 | delay(2); // Wait for Vref to settle 176 | ADCSRA |= _BV(ADSC); // Start conversion 177 | while (bit_is_set(ADCSRA,ADSC)); // measuring 178 | 179 | uint8_t low = ADCL; // must read ADCL first - it then locks ADCH 180 | uint8_t high = ADCH; // unlocks both 181 | 182 | long result = (high<<8) | low; 183 | 184 | result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000 185 | return result; // Vcc in millivolts 186 | } 187 | 188 | void switchClock(unsigned char clk) 189 | { 190 | cli(); 191 | 192 | CLKPR = 1< SI7021 : ")); 210 | Serial.flush(); 211 | 212 | if (humiditySensor.begin()) 213 | { 214 | Serial.println(F("ok!")); 215 | tests ++; 216 | } 217 | else 218 | { 219 | Serial.println(F("failed!")); 220 | } 221 | Serial.flush(); 222 | 223 | Serial.print(F("-> Flash : ")); 224 | Serial.flush(); 225 | if (flash.initialize()) 226 | { 227 | Serial.println(F("ok!")); 228 | tests ++; 229 | } 230 | else 231 | { 232 | Serial.println(F("failed!")); 233 | } 234 | Serial.flush(); 235 | 236 | 237 | Serial.print(F("-> SHA204 : ")); 238 | ret_code = sha204.sha204c_wakeup(rx_buffer); 239 | Serial.flush(); 240 | if (ret_code != SHA204_SUCCESS) 241 | { 242 | Serial.print(F("Failed to wake device. Response: ")); Serial.println(ret_code, HEX); 243 | } 244 | Serial.flush(); 245 | if (ret_code == SHA204_SUCCESS) 246 | { 247 | ret_code = sha204.getSerialNumber(rx_buffer); 248 | if (ret_code != SHA204_SUCCESS) 249 | { 250 | Serial.print(F("Failed to obtain device serial number. Response: ")); Serial.println(ret_code, HEX); 251 | } 252 | else 253 | { 254 | Serial.print(F("Ok (serial : ")); 255 | for (int i=0; i<9; i++) 256 | { 257 | if (rx_buffer[i] < 0x10) 258 | { 259 | Serial.print('0'); // Because Serial.print does not 0-pad HEX 260 | } 261 | Serial.print(rx_buffer[i], HEX); 262 | } 263 | Serial.println(")"); 264 | tests ++; 265 | } 266 | 267 | } 268 | Serial.flush(); 269 | 270 | Serial.println(F("Test finished")); 271 | 272 | if (tests == 3) 273 | { 274 | Serial.println(F("Selftest ok!")); 275 | while (1) // Blink OK pattern! 276 | { 277 | digitalWrite(LED_PIN, HIGH); 278 | delay(800); 279 | digitalWrite(LED_PIN, LOW); 280 | delay(200); 281 | } 282 | } 283 | else 284 | { 285 | Serial.println(F("----> Selftest failed!")); 286 | while (1) // Blink FAILED pattern! Rappidly blinking.. 287 | { 288 | digitalWrite(LED_PIN, HIGH); 289 | delay(100); 290 | digitalWrite(LED_PIN, LOW); 291 | delay(100); 292 | } 293 | } 294 | } 295 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/RF433MhzSensor/RF433MhzSensor.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * This sketch demonstrates how to use InterruptChain to receive and 3 | * decode remote switches (old and new) and remote sensors. 4 | * 5 | * Basically, this sketch combines the features of the ShowReceivedCode 6 | * and ShowReceivedCodeNewKaku examples of RemoteSwitch and the 7 | * ThermoHygroReceiver of RemoteSensor all at the same time! 8 | * 9 | * After uploading, enable the serial monitor at 115200 baud. 10 | * When you press buttons on a 433MHz remote control, as supported by 11 | * RemoteSwitch or NewRemoteSwitch, the code will be echoed. 12 | * At the same time, if data of a remote thermo/hygro-sensor is 13 | * received, as supported by RemoteSensor, it will be echoed as well. 14 | * 15 | * Setup: 16 | * - connect a 433MHz receiver on digital pin 2. 17 | * 18 | * 19 | * MySensor note: This example has not yet been adopted but can be used as an example 20 | * of receiving 433Mhz stuff. 21 | * 22 | * One idea could be to echo received 433 codes back to gateway to be able to pick up and 23 | * handle data over there. 24 | * 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | void setup() { 33 | Serial.begin(115200); 34 | 35 | // Interrupt -1 to indicate you will call the interrupt handler with InterruptChain 36 | RemoteReceiver::init(-1, 2, showOldCode); 37 | 38 | // Again, interrupt -1 to indicate you will call the interrupt handler with InterruptChain 39 | NewRemoteReceiver::init(-1, 2, showNewCode); 40 | 41 | // And once more, interrupt -1 to indicate you will call the interrupt handler with InterruptChain 42 | SensorReceiver::init(-1, showTempHumi); 43 | 44 | // On interrupt, call the interrupt handlers of remote and sensor receivers 45 | InterruptChain::addInterruptCallback(0, RemoteReceiver::interruptHandler); 46 | InterruptChain::addInterruptCallback(0, NewRemoteReceiver::interruptHandler); 47 | InterruptChain::addInterruptCallback(0, SensorReceiver::interruptHandler); 48 | } 49 | 50 | void loop() { 51 | // You can do other stuff here! 52 | } 53 | 54 | // shows the received code sent from an old-style remote switch 55 | void showOldCode(unsigned long receivedCode, unsigned int period) { 56 | // Print the received code. 57 | Serial.print("Code: "); 58 | Serial.print(receivedCode); 59 | Serial.print(", period: "); 60 | Serial.print(period); 61 | Serial.println("us."); 62 | } 63 | 64 | // Shows the received code sent from an new-style remote switch 65 | void showNewCode(NewRemoteCode receivedCode) { 66 | // Print the received code. 67 | Serial.print("Addr "); 68 | Serial.print(receivedCode.address); 69 | 70 | if (receivedCode.groupBit) { 71 | Serial.print(" group"); 72 | } else { 73 | Serial.print(" unit "); 74 | Serial.print(receivedCode.unit); 75 | } 76 | 77 | switch (receivedCode.switchType) { 78 | case NewRemoteCode::off: 79 | Serial.print(" off"); 80 | break; 81 | case NewRemoteCode::on: 82 | Serial.print(" on"); 83 | break; 84 | case NewRemoteCode::dim: 85 | Serial.print(" dim level "); 86 | Serial.print(receivedCode.dimLevel); 87 | break; 88 | case NewRemoteCode::on_with_dim: 89 | Serial.print(" on with dim level "); 90 | Serial.print(receivedCode.dimLevel); 91 | break; 92 | } 93 | 94 | Serial.print(", period: "); 95 | Serial.print(receivedCode.period); 96 | Serial.println("us."); 97 | } 98 | 99 | // Shows the received sensor data 100 | void showTempHumi(byte *data) { 101 | // is data a ThermoHygro-device? 102 | if ((data[3] & 0x1f) == 0x1e) { 103 | // Yes! 104 | byte channel, randomId; 105 | int temp; 106 | byte humidity; 107 | 108 | // Decode the data 109 | SensorReceiver::decodeThermoHygro(data, channel, randomId, temp, humidity); 110 | 111 | // Print temperature. Note: temp is 10x the actual temperature! 112 | Serial.print("Temperature: "); 113 | Serial.print(temp / 10); // units 114 | Serial.print('.'); 115 | Serial.println(temp % 10); // decimal 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/RFIDLockSensor/RFIDLockSensor.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RFID Lock sensor/actuator 3 | 4 | Henrik Ekblad 5 | 6 | Use RFID tag to lock/unlock a door or trigger a scene on your controller. 7 | This example sketch allows you to add an optional relay or solenoid 8 | which can be activated/opened by RFID or controller. 9 | 10 | Use the I2C wiring option for your RFID module and connect to the following Arduino pins. 11 | 12 | RFID Arduino 13 | ----- ------- 14 | GND -> GND 15 | VCC -> +5V 16 | SCL -> A5 17 | SDA -> A4 18 | 19 | Use normal wiring for NRF24L01 radio 20 | 21 | Attach a optional relay or solonoid lock to pin 4 22 | 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | 32 | // Add your valid rfid keys here. To find you your key just run sketch; hold your new RFID tag in fron ot the reader; 33 | // and copy the key from serial output of this sketch. 34 | const uint8_t maxKeyLength = 7; 35 | uint8_t validKeys[][maxKeyLength] = { 36 | { 0xB3, 0xC6, 0xD9, 0x80, 0x00, 0x00, 0x00 }, 37 | { 0, 0, 0, 0, 0, 0, 0 }, // ADD YOUR KEYS HERE! 38 | { 0, 0, 0, 0, 0, 0, 0 }}; 39 | int keyCount = sizeof validKeys / maxKeyLength; 40 | 41 | 42 | #define CHILD_ID 99 // Id of the sensor child 43 | 44 | /*Pin definitions*/ 45 | const int lockPin = 4; // (Digital 4) The pin that activates the relay/solenoid lock. 46 | 47 | bool lockStatus; 48 | MySensor gw; 49 | MyMessage lockMsg(CHILD_ID, V_LOCK_STATUS); 50 | PN532_I2C pn532i2c(Wire); 51 | PN532 nfc(pn532i2c); 52 | 53 | void setup() { 54 | 55 | pinMode(lockPin, OUTPUT); 56 | 57 | nfc.begin(); 58 | uint32_t versiondata = nfc.getFirmwareVersion(); 59 | if (! versiondata) { 60 | Serial.print("Couldn't find PN53x board"); 61 | while (1); // halt 62 | } 63 | Serial.print("Found NFC chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX); 64 | Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC); 65 | Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC); 66 | // Set the max number of retry attempts to read from a card 67 | // This prevents us from waiting forever for a card, which is 68 | // the default behaviour of the PN532. 69 | nfc.setPassiveActivationRetries(0x3); 70 | 71 | // configure board to read RFID tags 72 | nfc.SAMConfig(); 73 | 74 | // Init mysensors library 75 | gw.begin(incomingMessage); 76 | 77 | gw.sendSketchInfo("RFID Lock", "1.0"); 78 | gw.present(CHILD_ID, S_LOCK); 79 | 80 | lockStatus = gw.loadState(0); // Read last lock status from eeprom 81 | setLockState(lockStatus, true); // Now set the last known state and send it to controller 82 | } 83 | 84 | void loop() { 85 | gw.process(); // Process incomming messages 86 | 87 | boolean success; 88 | uint8_t key[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID 89 | uint8_t currentKeyLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type) 90 | 91 | 92 | // Wait for an ISO14443A type cards (Mifare, etc.). When one is found 93 | // 'uid' will be populated with the UID, and uidLength will indicate 94 | // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight) 95 | success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &key[0], ¤tKeyLength); 96 | 97 | if (success) { 98 | Serial.print("Found tag id: "); 99 | for (uint8_t i=0; i < currentKeyLength; i++) 100 | { 101 | if (i>0) Serial.print(","); 102 | Serial.print("0x");Serial.print(key[i], HEX); 103 | } 104 | for (uint8_t i=currentKeyLength; i < maxKeyLength; i++) 105 | { 106 | Serial.print(",0x00"); 107 | } 108 | 109 | 110 | Serial.println(""); 111 | 112 | boolean valid = false; 113 | // Compare this key to the valid once registered here in sketch 114 | for (int i=0;i 6 | // Inspired by Gregl 7 | 8 | // Wiring (radio wiring on www.mysensors.org) 9 | // ------------------------------------ 10 | // Arduino RTC-Module I2C Display 11 | // ------------------------------------ 12 | // GND GND GND 13 | // +5V VCC VCC 14 | // A4 SDA SDA 15 | // A5 SCL SCL 16 | 17 | 18 | #include 19 | #include 20 | #include 21 | #include // A DS3231/DS3232 library 22 | #include 23 | #include 24 | 25 | MySensor gw; 26 | boolean timeReceived = false; 27 | unsigned long lastUpdate=0, lastRequest=0; 28 | 29 | // Initialize display. Google the correct settings for your display. 30 | // The follwoing setting should work for the recommended display in the MySensors "shop". 31 | LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); 32 | 33 | void setup() 34 | { 35 | gw.begin(); 36 | 37 | // Send the sketch version information to the gateway and Controller 38 | gw.sendSketchInfo("RTC Clock", "1.0"); 39 | 40 | // the function to get the time from the RTC 41 | setSyncProvider(RTC.get); 42 | 43 | // Request latest time from controller at startup 44 | gw.requestTime(receiveTime); 45 | 46 | // initialize the lcd for 16 chars 2 lines and turn on backlight 47 | lcd.begin(16,2); 48 | } 49 | 50 | // This is called when a new time value was received 51 | void receiveTime(unsigned long controllerTime) { 52 | // Ok, set incoming time 53 | Serial.print("Time value received: "); 54 | Serial.println(controllerTime); 55 | RTC.set(controllerTime); // this sets the RTC to the time from controller - which we do want periodically 56 | timeReceived = true; 57 | } 58 | 59 | void loop() 60 | { 61 | unsigned long now = millis(); 62 | gw.process(); 63 | 64 | // If no time has been received yet, request it every 10 second from controller 65 | // When time has been received, request update every hour 66 | if ((!timeReceived && now-lastRequest > 10*1000) 67 | || (timeReceived && now-lastRequest > 60*1000*60)) { 68 | // Request time from controller. 69 | Serial.println("requesting time"); 70 | gw.requestTime(receiveTime); 71 | lastRequest = now; 72 | } 73 | 74 | // Update display every second 75 | if (now-lastUpdate > 1000) { 76 | updateDisplay(); 77 | lastUpdate = now; 78 | } 79 | } 80 | 81 | 82 | void updateDisplay(){ 83 | tmElements_t tm; 84 | RTC.read(tm); 85 | 86 | // Print date and time 87 | lcd.home(); 88 | lcd.print(tm.Day); 89 | lcd.print("/"); 90 | lcd.print(tm.Month); 91 | // lcd.print(" "); 92 | // lcd.print(tmYearToCalendar(tm.Year)-2000); 93 | 94 | lcd.print(" "); 95 | printDigits(tm.Hour); 96 | lcd.print(":"); 97 | printDigits(tm.Minute); 98 | lcd.print(":"); 99 | printDigits(tm.Second); 100 | 101 | // Go to next line and print temperature 102 | lcd.setCursor ( 0, 1 ); 103 | lcd.print("Temp: "); 104 | lcd.print(RTC.temperature()/4); 105 | lcd.write(223); // Degree-sign 106 | lcd.print("C"); 107 | } 108 | 109 | 110 | void printDigits(int digits){ 111 | if(digits < 10) 112 | lcd.print('0'); 113 | lcd.print(digits); 114 | } 115 | 116 | 117 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/RelayActuator/RelayActuator.ino: -------------------------------------------------------------------------------- 1 | // Example sketch showing how to control physical relays. 2 | // This example will remember relay state even after power failure. 3 | 4 | #include 5 | #include 6 | 7 | #define RELAY_1 3 // Arduino Digital I/O pin number for first relay (second on pin+1 etc) 8 | #define NUMBER_OF_RELAYS 1 // Total number of attached relays 9 | #define RELAY_ON 1 // GPIO value to write to turn on attached relay 10 | #define RELAY_OFF 0 // GPIO value to write to turn off attached relay 11 | 12 | MySensor gw; 13 | 14 | void setup() 15 | { 16 | // Initialize library and add callback for incoming messages 17 | gw.begin(incomingMessage, AUTO, true); 18 | // Send the sketch version information to the gateway and Controller 19 | gw.sendSketchInfo("Relay", "1.0"); 20 | 21 | // Fetch relay status 22 | for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS;sensor++, pin++) { 23 | // Register all sensors to gw (they will be created as child devices) 24 | gw.present(sensor, S_LIGHT); 25 | // Then set relay pins in output mode 26 | pinMode(pin, OUTPUT); 27 | // Set relay to last known state (using eeprom storage) 28 | digitalWrite(pin, gw.loadState(sensor)?RELAY_ON:RELAY_OFF); 29 | } 30 | } 31 | 32 | 33 | void loop() 34 | { 35 | // Alway process incoming messages whenever possible 36 | gw.process(); 37 | } 38 | 39 | void incomingMessage(const MyMessage &message) { 40 | // We only expect one type of message from controller. But we better check anyway. 41 | if (message.type==V_LIGHT) { 42 | // Change relay state 43 | digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF); 44 | // Store state in eeprom 45 | gw.saveState(message.sensor, message.getBool()); 46 | // Write some debug info 47 | Serial.print("Incoming change for sensor:"); 48 | Serial.print(message.sensor); 49 | Serial.print(", New status: "); 50 | Serial.println(message.getBool()); 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/RelayWithButtonActuator/RelayWithButtonActuator.ino: -------------------------------------------------------------------------------- 1 | // Example sketch för a "light switch" where you can control light or something 2 | // else from both vera and a local physical button (connected between digital 3 | // pin 3 and GND). 4 | // This node also works as a repeader for other nodes 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #define RELAY_PIN 4 // Arduino Digital I/O pin number for relay 11 | #define BUTTON_PIN 3 // Arduino Digital I/O pin number for button 12 | #define CHILD_ID 1 // Id of the sensor child 13 | #define RELAY_ON 1 14 | #define RELAY_OFF 0 15 | 16 | Bounce debouncer = Bounce(); 17 | int oldValue=0; 18 | bool state; 19 | MySensor gw; 20 | MyMessage msg(CHILD_ID,V_LIGHT); 21 | 22 | void setup() 23 | { 24 | gw.begin(incomingMessage, AUTO, true); 25 | 26 | // Send the sketch version information to the gateway and Controller 27 | gw.sendSketchInfo("Relay & Button", "1.0"); 28 | 29 | // Setup the button 30 | pinMode(BUTTON_PIN,INPUT); 31 | // Activate internal pull-up 32 | digitalWrite(BUTTON_PIN,HIGH); 33 | 34 | // After setting up the button, setup debouncer 35 | debouncer.attach(BUTTON_PIN); 36 | debouncer.interval(5); 37 | 38 | // Register all sensors to gw (they will be created as child devices) 39 | gw.present(CHILD_ID, S_LIGHT); 40 | 41 | // Make sure relays are off when starting up 42 | digitalWrite(RELAY_PIN, RELAY_OFF); 43 | // Then set relay pins in output mode 44 | pinMode(RELAY_PIN, OUTPUT); 45 | 46 | // Set relay to last known state (using eeprom storage) 47 | state = gw.loadState(CHILD_ID); 48 | digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF); 49 | } 50 | 51 | 52 | /* 53 | * Example on how to asynchronously check for new messages from gw 54 | */ 55 | void loop() 56 | { 57 | gw.process(); 58 | debouncer.update(); 59 | // Get the update value 60 | int value = debouncer.read(); 61 | if (value != oldValue && value==0) { 62 | gw.send(msg.set(state?false:true), true); // Send new state and request ack back 63 | } 64 | oldValue = value; 65 | } 66 | 67 | void incomingMessage(const MyMessage &message) { 68 | // We only expect one type of message from controller. But we better check anyway. 69 | if (message.isAck()) { 70 | Serial.println("This is an ack from gateway"); 71 | } 72 | 73 | if (message.type == V_LIGHT) { 74 | // Change relay state 75 | state = message.getBool(); 76 | digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF); 77 | // Store state in eeprom 78 | gw.saveState(CHILD_ID, state); 79 | 80 | // Write some debug info 81 | Serial.print("Incoming change for sensor:"); 82 | Serial.print(message.sensor); 83 | Serial.print(", New status: "); 84 | Serial.println(message.getBool()); 85 | } 86 | } 87 | 88 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/RepeaterNode/RepeaterNode.ino: -------------------------------------------------------------------------------- 1 | // Example sketch showing how to create a node thay repeates messages 2 | // from nodes far from gateway back to gateway. 3 | // It is important that nodes that has enabled repeater mode calls 4 | // gw.preocess() frequently. This node should never sleep. 5 | 6 | #include 7 | #include 8 | 9 | MySensor gw; 10 | 11 | void setup() 12 | { 13 | // The third argument enables repeater mode. 14 | gw.begin(NULL, AUTO, true); 15 | 16 | //Send the sensor node sketch version information to the gateway 17 | gw.sendSketchInfo("Repeater Node", "1.0"); 18 | } 19 | 20 | void loop() 21 | { 22 | // By calling process() you route messages in the background 23 | gw.process(); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/SerialGateway/SerialGateway.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Henrik Ekblad 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License 6 | * version 2 as published by the Free Software Foundation. 7 | * 8 | * DESCRIPTION 9 | * The ArduinoGateway prints data received from sensors on the serial link. 10 | * The gateway accepts input on seral which will be sent out on radio network. 11 | * 12 | * The GW code is designed for Arduino Nano 328p / 16MHz 13 | * 14 | * Wire connections (OPTIONAL): 15 | * - Inclusion button should be connected between digital pin 3 and GND 16 | * - RX/TX/ERR leds need to be connected between +5V (anode) and digital ping 6/5/4 with resistor 270-330R in a series 17 | * 18 | * LEDs (OPTIONAL): 19 | * - RX (green) - blink fast on radio message recieved. In inclusion mode will blink fast only on presentation recieved 20 | * - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly 21 | * - ERR (red) - fast blink on error during transmission error or recieve crc error 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #define INCLUSION_MODE_TIME 1 // Number of minutes inclusion mode is enabled 30 | #define INCLUSION_MODE_PIN 3 // Digital pin used for inclusion mode button 31 | 32 | 33 | MyGateway gw(DEFAULT_CE_PIN, DEFAULT_CS_PIN, INCLUSION_MODE_TIME, INCLUSION_MODE_PIN, 6, 5, 4); 34 | 35 | char inputString[MAX_RECEIVE_LENGTH] = ""; // A string to hold incoming commands from serial/ethernet interface 36 | int inputPos = 0; 37 | boolean commandComplete = false; // whether the string is complete 38 | 39 | void setup() 40 | { 41 | gw.begin(); 42 | } 43 | 44 | void loop() 45 | { 46 | gw.processRadioMessage(); 47 | if (commandComplete) { 48 | // A command wass issued from serial interface 49 | // We will now try to send it to the actuator 50 | gw.parseAndSend(inputString); 51 | commandComplete = false; 52 | inputPos = 0; 53 | } 54 | } 55 | 56 | 57 | /* 58 | SerialEvent occurs whenever a new data comes in the 59 | hardware serial RX. This routine is run between each 60 | time loop() runs, so using delay inside loop can delay 61 | response. Multiple bytes of data may be available. 62 | */ 63 | void serialEvent() { 64 | while (Serial.available()) { 65 | // get the new byte: 66 | char inChar = (char)Serial.read(); 67 | // if the incoming character is a newline, set a flag 68 | // so the main loop can do something about it: 69 | if (inputPos 10 | #include 11 | #include 12 | 13 | #define SERVO_DIGITAL_OUT_PIN 3 14 | #define SERVO_MIN 0 // Fine tune your servos min. 0-180 15 | #define SERVO_MAX 180 // Fine tune your servos max. 0-180 16 | #define DETACH_DELAY 900 // Tune this to let your movement finish before detaching the servo 17 | #define CHILD_ID 10 // Id of the sensor child 18 | 19 | MySensor gw; 20 | MyMessage msg(CHILD_ID, V_DIMMER); 21 | Servo myservo; // create servo object to control a servo 22 | // a maximum of eight servo objects can be created Sensor gw(9,10); 23 | unsigned long timeOfLastChange = 0; 24 | bool attachedServo = false; 25 | 26 | void setup() 27 | { 28 | // Attach method for incoming messages 29 | gw.begin(incomingMessage); 30 | 31 | // Send the sketch version information to the gateway and Controller 32 | gw.sendSketchInfo("Servo", "1.0"); 33 | 34 | // Register all sensors to gw (they will be created as child devices) 35 | gw.present(CHILD_ID, S_COVER); 36 | 37 | // Request last servo state at startup 38 | gw.request(CHILD_ID, V_DIMMER); 39 | } 40 | 41 | void loop() 42 | { 43 | gw.process(); 44 | if (attachedServo && millis() - timeOfLastChange > DETACH_DELAY) { 45 | myservo.detach(); 46 | attachedServo = false; 47 | } 48 | } 49 | 50 | void incomingMessage(const MyMessage &message) { 51 | myservo.attach(SERVO_DIGITAL_OUT_PIN); 52 | attachedServo = true; 53 | if (message.type==V_DIMMER) { // This could be M_ACK_VARIABLE or M_SET_VARIABLE 54 | int val = message.getInt(); 55 | myservo.write(SERVO_MAX + (SERVO_MIN-SERVO_MAX)/100 * val); // sets the servo position 0-180 56 | // Write some debug info 57 | Serial.print("Servo changed. new state: "); 58 | Serial.println(val); 59 | } else if (message.type==V_UP) { 60 | Serial.println("Servo UP command"); 61 | myservo.write(SERVO_MIN); 62 | gw.send(msg.set(100)); 63 | } else if (message.type==V_DOWN) { 64 | Serial.println("Servo DOWN command"); 65 | myservo.write(SERVO_MAX); 66 | gw.send(msg.set(0)); 67 | } else if (message.type==V_STOP) { 68 | Serial.println("Servo STOP command"); 69 | myservo.detach(); 70 | attachedServo = false; 71 | 72 | } 73 | timeOfLastChange = millis(); 74 | } 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/SoilMoistSensor/SoilMoistSensor.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define DIGITAL_INPUT_SOIL_SENSOR 3 // Digital input did you attach your soil sensor. 5 | #define INTERRUPT DIGITAL_INPUT_SOIL_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway) 6 | #define CHILD_ID 0 // Id of the sensor child 7 | 8 | MySensor gw; 9 | MyMessage msg(CHILD_ID, V_TRIPPED); 10 | int lastSoilValue = -1; 11 | 12 | void setup() 13 | { 14 | gw.begin(); 15 | 16 | // Send the sketch version information to the gateway and Controller 17 | gw.sendSketchInfo("Soil Moisture Sensor", "1.0"); 18 | // sets the soil sensor digital pin as input 19 | pinMode(DIGITAL_INPUT_SOIL_SENSOR, INPUT); 20 | // Register all sensors to gw (they will be created as child devices) 21 | gw.present(CHILD_ID, S_MOTION); 22 | } 23 | 24 | void loop() 25 | { 26 | // Read digital soil value 27 | int soilValue = digitalRead(DIGITAL_INPUT_SOIL_SENSOR); // 1 = Not triggered, 0 = In soil with water 28 | if (soilValue != lastSoilValue) { 29 | Serial.println(soilValue); 30 | gw.send(msg.set(soilValue==0?1:0)); // Send the inverse to gw as tripped should be when no water in soil 31 | lastSoilValue = soilValue; 32 | } 33 | // Power down the radio and arduino until digital input changes. 34 | gw.sleep(INTERRUPT,CHANGE); 35 | } 36 | 37 | 38 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/TimeAwareSensor/TimeAwareSensor.ino: -------------------------------------------------------------------------------- 1 | 2 | // Example sketch showing how to request time from controller. 3 | // Created by Henrik Ekblad 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | MySensor gw; 10 | boolean timeReceived = false; 11 | unsigned long lastUpdate=0, lastRequest=0; 12 | 13 | void setup() 14 | { 15 | gw.begin(); 16 | 17 | // Send the sketch version information to the gateway and Controller 18 | gw.sendSketchInfo("Clock", "1.0"); 19 | 20 | // Request time from controller. 21 | gw.requestTime(receiveTime); 22 | } 23 | 24 | // This is called when a new time value was received 25 | void receiveTime(unsigned long time) { 26 | // Ok, set incoming time 27 | setTime(time); 28 | timeReceived = true; 29 | } 30 | 31 | void loop() 32 | { 33 | unsigned long now = millis(); 34 | gw.process(); 35 | 36 | // If no time has been received yet, request it every 10 second from controller 37 | // When time has been received, request update every hour 38 | if ((!timeReceived && now-lastRequest > 10*1000) 39 | || (timeReceived && now-lastRequest > 60*1000*60)) { 40 | // Request time from controller. 41 | Serial.println("requesting time"); 42 | gw.requestTime(receiveTime); 43 | lastRequest = now; 44 | } 45 | 46 | // Print time every second 47 | if (timeReceived && now-lastUpdate > 1000) { 48 | Serial.print(hour()); 49 | printDigits(minute()); 50 | printDigits(second()); 51 | Serial.print(" "); 52 | Serial.print(day()); 53 | Serial.print(" "); 54 | Serial.print(month()); 55 | Serial.print(" "); 56 | Serial.print(year()); 57 | Serial.println(); 58 | lastUpdate = now; 59 | } 60 | } 61 | 62 | void printDigits(int digits){ 63 | // utility function for digital clock display: prints preceding colon and leading 0 64 | Serial.print(":"); 65 | if(digits < 10) 66 | Serial.print('0'); 67 | Serial.print(digits); 68 | } 69 | 70 | 71 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/TouchDisplaySceneControllerSensor/TouchDisplaySceneControllerSensor.ino: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Touch Display Scene Controller build using a touch enabled tft display 4 | * attached to a ATMega 2560. This example fetches time from controller and sends 5 | * in scene commands to the controller. 6 | * Short press sends V_SCENE_ON and long press (>0.5sec) sends V_SCENE_OFF. 7 | * 8 | * Henrik Ekblad 9 | * 10 | * This example uses: 11 | * UTFT library: http://www.henningkarlsen.com/electronics/library.php?id=51 12 | * Convert your own images here: http://www.henningkarlsen.com/electronics/t_imageconverter565.php 13 | * 14 | * The 3v3 output on the ATMega2560 is especially bad. I had to use a step down 15 | * on the 5V output to get solid transmissions. 16 | * 17 | * The shield does not seem like sharing SPI with RF24 so you'll have to 18 | * activate SOFTSPI-define in MySenors/util/RF24_config.h 19 | * 20 | * Connect radio 21 | * ---------------------------------- 22 | * Radio Arduino Pin 23 | * ---------------------------------- 24 | * GND GND 25 | * 5V -> Step down -> 3V3 (see buying guide for help finding step-down) 26 | * SCK 14 27 | * MOSI 15 28 | * MISO 16 29 | * CE 17 30 | * CSN 18 31 | * 32 | */ 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include "arial_bold.c" 44 | #include "ArialNumFontPlus.c" 45 | #include "logo.c" 46 | 47 | #define CHILD_ID 1 48 | 49 | int LONG_PRESS = 500; // Number of millisecons to trinnger scene off for button push 50 | int RESEND_DEBOUNCE = 2000; // Number of millisecons interval between sending of same 51 | // scene number again. 52 | // This is used to avoid unwanted re-trigger when using 53 | // a sensetive touch diplay. 54 | 55 | // Add your buttons here. Max is 5 if you still want time at the top. 56 | char *buttons[] = { 57 | "Good Morning", 58 | "Clean Up!", 59 | "All Lights Off", 60 | "Music On/Off" 61 | }; 62 | 63 | const int buttonCount = sizeof(buttons)/sizeof(char *); 64 | const int padding = 10; 65 | const int topBarHeight = 60; 66 | 67 | MySensor gw(17,18); 68 | MyMessage on(CHILD_ID, V_SCENE_ON); 69 | MyMessage off(CHILD_ID, V_SCENE_OFF); 70 | 71 | UTFT myGLCD(ITDB32S,38,39,40,41); 72 | UTouch myTouch( 6, 5, 4, 3, 2); 73 | UTFT_Buttons myButtons(&myGLCD, &myTouch); 74 | boolean timeReceived = false; 75 | unsigned long lastTimeUpdate=0, lastRequest=0; 76 | char timeBuf[20]; 77 | 78 | 79 | void setup() 80 | { 81 | gw.begin(NULL, AUTO, false, 0); 82 | 83 | myGLCD.InitLCD(); 84 | myGLCD.clrScr(); 85 | myGLCD.setFont((uint8_t*)ArialNumFontPlus); 86 | myGLCD.setColor(100, 255, 100); 87 | myGLCD.setBackColor(0, 0, 0); 88 | myGLCD.drawBitmap (0, 0, 60, 60, (unsigned int*)logo); 89 | 90 | myTouch.InitTouch(); 91 | myTouch.setPrecision(PREC_MEDIUM); 92 | 93 | myButtons.setButtonColors(VGA_WHITE, VGA_GRAY, VGA_WHITE, VGA_RED, VGA_BLUE); 94 | myButtons.setTextFont((uint8_t*)arial_bold); 95 | int height = (myGLCD.getDisplayYSize()-topBarHeight-(padding*(buttonCount+2)))/buttonCount; 96 | 97 | // Add buttons 98 | for (int i=0; i=0) { 126 | bool longPress = millis()-now>LONG_PRESS; 127 | 128 | if (pressedButton != lastPressedButton || now-lastPressedButtonTime > RESEND_DEBOUNCE) { 129 | if (longPress) { 130 | gw.send(off.set(pressedButton)); 131 | Serial.print("Long pressed: "); 132 | } else { 133 | gw.send(on.set(pressedButton)); 134 | Serial.print("Pressed: "); 135 | } 136 | Serial.println(pressedButton); 137 | lastPressedButton = pressedButton; 138 | lastPressedButtonTime=now; 139 | } 140 | } 141 | } 142 | 143 | // If no time has been received yet, request it every 10 second from controller 144 | // When time has been received, request update every hour 145 | if ((!timeReceived && now-lastRequest > 10*1000) 146 | || (timeReceived && now-lastRequest > 60*1000*60)) { 147 | // Request time from controller. 148 | Serial.println("requesting time"); 149 | gw.requestTime(receiveTime); 150 | lastRequest = now; 151 | } 152 | 153 | // Update time every second 154 | if (timeReceived && now-lastTimeUpdate > 1000) { 155 | printTime(); 156 | lastTimeUpdate = now; 157 | } 158 | } 159 | 160 | 161 | 162 | // This is called when a new time value was received 163 | void receiveTime(unsigned long time) { 164 | // Ok, set incoming time 165 | setTime(time); 166 | timeReceived = true; 167 | } 168 | 169 | void printTime() { 170 | sprintf(timeBuf, "%02d:%02d:%02d", hour(), minute(), second()); 171 | myGLCD.print(timeBuf, 60,7); 172 | } 173 | 174 | 175 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/UVSensor/UVSensor.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | /* 4 | Arduino UVM-30A 5 | 6 | connect the sensor as follows : 7 | 8 | + >>> 5V 9 | - >>> GND 10 | out >>> A0 11 | 12 | Contribution: epierre, bulldoglowell, gizmocuz 13 | 14 | Index table taken from: http://www.elecrow.com/sensors-c-111/environment-c-111_112/uv-sensor-moduleuvm30a-p-716.html 15 | Because this table is pretty lineair, we can calculate a UVI with one decimal 16 | 17 | License: Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0) 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | #define UV_SENSOR_ANALOG_PIN 0 24 | 25 | #define CHILD_ID_UV 0 26 | 27 | unsigned long SLEEP_TIME = 30*1000; // Sleep time between reads (in milliseconds) 28 | 29 | MySensor gw; 30 | MyMessage uvMsg(CHILD_ID_UV, V_UV); 31 | 32 | unsigned long lastSend =0; 33 | float uvIndex; 34 | float lastUV = -1; 35 | int uvIndexValue [12] = { 50, 227, 318, 408, 503, 606, 696, 795, 881, 976, 1079, 1170}; 36 | 37 | void setup() 38 | { 39 | gw.begin(); 40 | 41 | // Send the sketch version information to the gateway and Controller 42 | gw.sendSketchInfo("UV Sensor", "1.2"); 43 | 44 | // Register all sensors to gateway (they will be created as child devices) 45 | gw.present(CHILD_ID_UV, S_UV); 46 | } 47 | 48 | void loop() 49 | { 50 | unsigned long currentTime = millis(); 51 | 52 | uint16_t uv = analogRead(UV_SENSOR_ANALOG_PIN);// Get UV value 53 | if (uv>1170) 54 | uv=1170; 55 | 56 | //Serial.print("UV Analog reading: "); 57 | //Serial.println(uv); 58 | 59 | int i; 60 | for (i = 0; i < 12; i++) 61 | { 62 | if (uv <= uvIndexValue[i]) 63 | { 64 | uvIndex = i; 65 | break; 66 | } 67 | } 68 | 69 | //calculate 1 decimal if possible 70 | if (i>0) { 71 | float vRange=uvIndexValue[i]-uvIndexValue[i-1]; 72 | float vCalc=uv-uvIndexValue[i-1]; 73 | uvIndex+=(1.0/vRange)*vCalc-1.0; 74 | } 75 | 76 | //Serial.print("UVI: "); 77 | //Serial.println(uvIndex,2); 78 | 79 | //Send value to gateway if changed, or at least every 5 minutes 80 | if ((uvIndex != lastUV)||(currentTime-lastSend >= 5*60*1000)) { 81 | lastSend=currentTime; 82 | gw.send(uvMsg.set(uvIndex,2)); 83 | lastUV = uvIndex; 84 | } 85 | 86 | gw.sleep(SLEEP_TIME); 87 | } 88 | -------------------------------------------------------------------------------- /libraries/MySensors/examples/WaterMeterPulseSensor/WaterMeterPulseSensor.ino: -------------------------------------------------------------------------------- 1 | // 2 | // Use this sensor to measure volume and flow of your house watermeter. 3 | // You need to set the correct pulsefactor of your meter (pulses per m3). 4 | // The sensor starts by fetching current volume reading from gateway (VAR 1). 5 | // Reports both volume and flow back to gateway. 6 | // 7 | // Unfortunately millis() won't increment when the Arduino is in 8 | // sleepmode. So we cannot make this sensor sleep if we also want 9 | // to calculate/report flow. 10 | // 11 | 12 | #include 13 | #include 14 | 15 | #define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your sensor. (Only 2 and 3 generates interrupt!) 16 | #define SENSOR_INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway) 17 | 18 | #define PULSE_FACTOR 1000 // Nummber of blinks per m3 of your meter (One rotation/liter) 19 | 20 | #define SLEEP_MODE false // flowvalue can only be reported when sleep mode is false. 21 | 22 | #define MAX_FLOW 40 // Max flow (l/min) value to report. This filters outliers. 23 | 24 | #define CHILD_ID 1 // Id of the sensor child 25 | 26 | unsigned long SEND_FREQUENCY = 20000; // Minimum time between send (in milliseconds). We don't want to spam the gateway. 27 | 28 | MySensor gw; 29 | MyMessage flowMsg(CHILD_ID,V_FLOW); 30 | MyMessage volumeMsg(CHILD_ID,V_VOLUME); 31 | MyMessage lastCounterMsg(CHILD_ID,V_VAR1); 32 | 33 | double ppl = ((double)PULSE_FACTOR)/1000; // Pulses per liter 34 | 35 | volatile unsigned long pulseCount = 0; 36 | volatile unsigned long lastBlink = 0; 37 | volatile double flow = 0; 38 | boolean pcReceived = false; 39 | unsigned long oldPulseCount = 0; 40 | unsigned long newBlink = 0; 41 | double oldflow = 0; 42 | double volume =0; 43 | double oldvolume =0; 44 | unsigned long lastSend =0; 45 | unsigned long lastPulse =0; 46 | 47 | void setup() 48 | { 49 | gw.begin(incomingMessage); 50 | 51 | // Send the sketch version information to the gateway and Controller 52 | gw.sendSketchInfo("Water Meter", "1.2"); 53 | 54 | // Register this device as Waterflow sensor 55 | gw.present(CHILD_ID, S_WATER); 56 | 57 | pulseCount = oldPulseCount = 0; 58 | 59 | // Fetch last known pulse count value from gw 60 | gw.request(CHILD_ID, V_VAR1); 61 | 62 | lastSend = lastPulse = millis(); 63 | 64 | attachInterrupt(SENSOR_INTERRUPT, onPulse, RISING); 65 | } 66 | 67 | 68 | void loop() 69 | { 70 | gw.process(); 71 | unsigned long currentTime = millis(); 72 | 73 | // Only send values at a maximum frequency or woken up from sleep 74 | if (SLEEP_MODE || (currentTime - lastSend > SEND_FREQUENCY)) 75 | { 76 | lastSend=currentTime; 77 | 78 | if (!pcReceived) { 79 | //Last Pulsecount not yet received from controller, request it again 80 | gw.request(CHILD_ID, V_VAR1); 81 | return; 82 | } 83 | 84 | if (!SLEEP_MODE && flow != oldflow) { 85 | oldflow = flow; 86 | 87 | Serial.print("l/min:"); 88 | Serial.println(flow); 89 | 90 | // Check that we dont get unresonable large flow value. 91 | // could hapen when long wraps or false interrupt triggered 92 | if (flow<((unsigned long)MAX_FLOW)) { 93 | gw.send(flowMsg.set(flow, 2)); // Send flow value to gw 94 | } 95 | } 96 | 97 | // No Pulse count received in 2min 98 | if(currentTime - lastPulse > 120000){ 99 | flow = 0; 100 | } 101 | 102 | // Pulse count has changed 103 | if (pulseCount != oldPulseCount) { 104 | oldPulseCount = pulseCount; 105 | 106 | Serial.print("pulsecount:"); 107 | Serial.println(pulseCount); 108 | 109 | gw.send(lastCounterMsg.set(pulseCount)); // Send pulsecount value to gw in VAR1 110 | 111 | double volume = ((double)pulseCount/((double)PULSE_FACTOR)); 112 | if (volume != oldvolume) { 113 | oldvolume = volume; 114 | 115 | Serial.print("volume:"); 116 | Serial.println(volume, 3); 117 | 118 | gw.send(volumeMsg.set(volume, 3)); // Send volume value to gw 119 | } 120 | } 121 | } 122 | if (SLEEP_MODE) { 123 | gw.sleep(SEND_FREQUENCY); 124 | } 125 | } 126 | 127 | void incomingMessage(const MyMessage &message) { 128 | if (message.type==V_VAR1) { 129 | unsigned long gwPulseCount=message.getULong(); 130 | pulseCount += gwPulseCount; 131 | Serial.print("Received last pulse count from gw:"); 132 | Serial.println(pulseCount); 133 | pcReceived = true; 134 | } 135 | } 136 | 137 | void onPulse() 138 | { 139 | if (!SLEEP_MODE) 140 | { 141 | unsigned long newBlink = micros(); 142 | unsigned long interval = newBlink-lastBlink; 143 | 144 | if (interval!=0) 145 | { 146 | lastPulse = millis(); 147 | if (interval<500000L) { 148 | // Sometimes we get interrupt on RISING, 500000 = 0.5sek debounce ( max 120 l/min) 149 | return; 150 | } 151 | flow = (60000000.0 /interval) / ppl; 152 | } 153 | lastBlink = newBlink; 154 | } 155 | pulseCount++; 156 | } 157 | 158 | -------------------------------------------------------------------------------- /libraries/MySensors/utility/LowPower.h: -------------------------------------------------------------------------------- 1 | #ifndef LowPower_h 2 | #define LowPower_h 3 | 4 | enum period_t 5 | { 6 | SLEEP_15Ms, 7 | SLEEP_30MS, 8 | SLEEP_60MS, 9 | SLEEP_120MS, 10 | SLEEP_250MS, 11 | SLEEP_500MS, 12 | SLEEP_1S, 13 | SLEEP_2S, 14 | SLEEP_4S, 15 | SLEEP_8S, 16 | SLEEP_FOREVER 17 | }; 18 | 19 | enum bod_t 20 | { 21 | BOD_OFF, 22 | BOD_ON 23 | }; 24 | 25 | enum adc_t 26 | { 27 | ADC_OFF, 28 | ADC_ON 29 | }; 30 | 31 | enum timer5_t 32 | { 33 | TIMER5_OFF, 34 | TIMER5_ON 35 | }; 36 | 37 | enum timer4_t 38 | { 39 | TIMER4_OFF, 40 | TIMER4_ON 41 | }; 42 | 43 | enum timer3_t 44 | { 45 | TIMER3_OFF, 46 | TIMER3_ON 47 | }; 48 | 49 | enum timer2_t 50 | { 51 | TIMER2_OFF, 52 | TIMER2_ON 53 | }; 54 | 55 | enum timer1_t 56 | { 57 | TIMER1_OFF, 58 | TIMER1_ON 59 | }; 60 | 61 | enum timer0_t 62 | { 63 | TIMER0_OFF, 64 | TIMER0_ON 65 | }; 66 | 67 | enum spi_t 68 | { 69 | SPI_OFF, 70 | SPI_ON 71 | }; 72 | 73 | enum usart0_t 74 | { 75 | USART0_OFF, 76 | USART0_ON 77 | }; 78 | 79 | enum usart1_t 80 | { 81 | USART1_OFF, 82 | USART1_ON 83 | }; 84 | 85 | enum usart2_t 86 | { 87 | USART2_OFF, 88 | USART2_ON 89 | }; 90 | 91 | enum usart3_t 92 | { 93 | USART3_OFF, 94 | USART3_ON 95 | }; 96 | 97 | enum twi_t 98 | { 99 | TWI_OFF, 100 | TWI_ON 101 | }; 102 | 103 | enum usb_t 104 | { 105 | USB_OFF, 106 | USB_ON 107 | }; 108 | 109 | class LowPowerClass 110 | { 111 | public: 112 | #if defined (__AVR_ATmega328P__) || defined (__AVR_ATmega168__) 113 | void idle(period_t period, adc_t adc, timer2_t timer2, 114 | timer1_t timer1, timer0_t timer0, spi_t spi, 115 | usart0_t usart0, twi_t twi); 116 | #elif defined __AVR_ATmega2560__ 117 | void idle(period_t period, adc_t adc, timer5_t timer5, 118 | timer4_t timer4, timer3_t timer3, timer2_t timer2, 119 | timer1_t timer1, timer0_t timer0, spi_t spi, 120 | usart3_t usart3, usart2_t usart2, usart1_t usart1, 121 | usart0_t usart0, twi_t twi); 122 | #elif defined __AVR_ATmega32U4__ 123 | void idle(period_t period, adc_t adc, timer4_t timer4, timer3_t timer3, 124 | timer1_t timer1, timer0_t timer0, spi_t spi, 125 | usart1_t usart1, twi_t twi, usb_t usb); 126 | #else 127 | #error "Please ensure chosen MCU is either 328P, 32U4 or 2560." 128 | #endif 129 | void adcNoiseReduction(period_t period, adc_t adc, timer2_t timer2); 130 | void powerDown(period_t period, adc_t adc, bod_t bod); 131 | void powerSave(period_t period, adc_t adc, bod_t bod, timer2_t timer2); 132 | void powerStandby(period_t period, adc_t adc, bod_t bod); 133 | void powerExtStandby(period_t period, adc_t adc, bod_t bod, timer2_t timer2); 134 | }; 135 | 136 | extern LowPowerClass LowPower; 137 | #endif -------------------------------------------------------------------------------- /libraries/MySensors/utility/MsTimer2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | MsTimer2.h - Using timer2 with 1ms resolution 3 | Javier Valencia 4 | 5 | History: 6 | 29/Dec/11 - V0.6 added support for ATmega32u4, AT90USB646, AT90USB1286 (paul@pjrc.com) 7 | some improvements added by Bill Perry 8 | note: uses timer4 on Atmega32u4 9 | 29/May/09 - V0.5 added support for Atmega1280 (thanks to Manuel Negri) 10 | 19/Mar/09 - V0.4 added support for ATmega328P (thanks to Jerome Despatis) 11 | 11/Jun/08 - V0.3 12 | changes to allow working with different CPU frequencies 13 | added support for ATMega128 (using timer2) 14 | compatible with ATMega48/88/168/8 15 | 10/May/08 - V0.2 added some security tests and volatile keywords 16 | 9/May/08 - V0.1 released working on ATMEGA168 only 17 | 18 | 19 | This library is free software; you can redistribute it and/or 20 | modify it under the terms of the GNU Lesser General Public 21 | License as published by the Free Software Foundation; either 22 | version 2.1 of the License, or (at your option) any later version. 23 | 24 | This library is distributed in the hope that it will be useful, 25 | but WITHOUT ANY WARRANTY; without even the implied warranty of 26 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 27 | Lesser General Public License for more details. 28 | 29 | You should have received a copy of the GNU Lesser General Public 30 | License along with this library; if not, write to the Free Software 31 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 32 | */ 33 | #if defined (__AVR_ATmega328P__) || defined (__AVR_ATmega168__) || defined (__AVR_ATmega2560__) || defined (__AVR_ATmega32U4__) 34 | #include 35 | 36 | unsigned long MsTimer2::msecs; 37 | void (*MsTimer2::func)(); 38 | volatile unsigned long MsTimer2::count; 39 | volatile char MsTimer2::overflowing; 40 | volatile unsigned int MsTimer2::tcnt2; 41 | 42 | void MsTimer2::set(unsigned long ms, void (*f)()) { 43 | float prescaler = 0.0; 44 | 45 | if (ms == 0) 46 | msecs = 1; 47 | else 48 | msecs = ms; 49 | 50 | func = f; 51 | 52 | #if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) 53 | TIMSK2 &= ~(1<= 1000000UL) && (F_CPU <= 16000000UL)) { // prescaler set to 64 60 | TCCR2B |= (1< 16Mhz, prescaler set to 128 68 | TCCR2B |= ((1<= 1000000UL) && (F_CPU <= 16000000UL)) { // prescaler set to 64 79 | TCCR2 |= (1< 16Mhz, prescaler set to 128 87 | TCCR2 |= ((1<= 1000000UL) && (F_CPU <= 16000000UL)) { // prescaler set to 64 97 | TCCR2 |= ((1< 16Mhz, prescaler set to 256 105 | TCCR2 |= (1<= 16000000L) { 116 | TCCR4B = (1<= 8000000L) { 119 | TCCR4B = (1<= 4000000L) { 122 | TCCR4B = (1<= 2000000L) { 125 | TCCR4B = (1<= 1000000L) { 128 | TCCR4B = (1<= 500000L) { 131 | TCCR4B = (1<= msecs && !overflowing) { 182 | overflowing = 1; 183 | count = count - msecs; // subtract ms to catch missed overflows 184 | // set to 0 if you don't want this. 185 | (*func)(); 186 | overflowing = 0; 187 | } 188 | } 189 | 190 | #if defined (__AVR_ATmega32U4__) 191 | ISR(TIMER4_OVF_vect) { 192 | #else 193 | ISR(TIMER2_OVF_vect) { 194 | #endif 195 | #if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) 196 | TCNT2 = MsTimer2::tcnt2; 197 | #elif defined (__AVR_ATmega128__) 198 | TCNT2 = MsTimer2::tcnt2; 199 | #elif defined (__AVR_ATmega8__) 200 | TCNT2 = MsTimer2::tcnt2; 201 | #elif defined (__AVR_ATmega32U4__) 202 | // not necessary on 32u4's high speed timer4 203 | #endif 204 | MsTimer2::_overflow(); 205 | } 206 | 207 | #endif -------------------------------------------------------------------------------- /libraries/MySensors/utility/MsTimer2.h: -------------------------------------------------------------------------------- 1 | #ifndef MsTimer2_h 2 | #define MsTimer2_h 3 | 4 | #ifdef __AVR__ 5 | #include 6 | #else 7 | #error MsTimer2 library only works on AVR architecture 8 | #endif 9 | 10 | namespace MsTimer2 { 11 | extern unsigned long msecs; 12 | extern void (*func)(); 13 | extern volatile unsigned long count; 14 | extern volatile char overflowing; 15 | extern volatile unsigned int tcnt2; 16 | 17 | void set(unsigned long ms, void (*f)()); 18 | void start(); 19 | void stop(); 20 | void _overflow(); 21 | } 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /libraries/MySensors/utility/RF24_config.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Copyright (C) 2011 J. Coliz 4 | 5 | This program is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU General Public License 7 | version 2 as published by the Free Software Foundation. 8 | 9 | Added Arduino Due support from https://github.com/mcrosson/ 10 | */ 11 | 12 | #ifndef __RF24_CONFIG_H__ 13 | #define __RF24_CONFIG_H__ 14 | 15 | #if ARDUINO < 100 16 | #include 17 | #else 18 | #include 19 | #endif 20 | 21 | #include 22 | 23 | /*** USER DEFINES: ***/ 24 | //#define FAILURE_HANDLING 25 | //#define SERIAL_DEBUG 26 | #define MINIMAL 27 | //#define SPI_UART // Requires library from https://github.com/TMRh20/Sketches/tree/master/SPI_UART 28 | //#define SOFTSPI // Requires library from https://github.com/greiman/DigitalIO 29 | /**********************/ 30 | 31 | // Define _BV for non-Arduino platforms and for Arduino DUE 32 | #if defined (ARDUINO) && !defined (__arm__) 33 | #if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) 34 | #define RF24_TINY 35 | #define _SPI SPI 36 | #else 37 | #if defined SPI_UART 38 | #include 39 | #define _SPI uspi 40 | #elif defined SOFTSPI 41 | // change these pins to your liking 42 | // 43 | const uint8_t SOFT_SPI_MISO_PIN = 16; 44 | const uint8_t SOFT_SPI_MOSI_PIN = 15; 45 | const uint8_t SOFT_SPI_SCK_PIN = 14; 46 | const uint8_t SPI_MODE = 0; 47 | #define _SPI spi 48 | 49 | #else 50 | #include 51 | #define _SPI SPI 52 | #endif 53 | #endif 54 | #else 55 | #include 56 | #include 57 | #include 58 | 59 | 60 | #if defined(__arm__) || defined (CORE_TEENSY) 61 | #include 62 | #endif 63 | 64 | #if !defined(CORE_TEENSY) 65 | #define _BV(x) (1<<(x)) 66 | #if !defined(__arm__) 67 | extern HardwareSPI SPI; 68 | #endif 69 | #else 70 | #define printf Serial.printf 71 | #endif 72 | 73 | #define _SPI SPI 74 | #endif 75 | 76 | 77 | #ifdef SERIAL_DEBUG 78 | #define IF_SERIAL_DEBUG(x) ({x;}) 79 | #else 80 | #define IF_SERIAL_DEBUG(x) 81 | #if defined(RF24_TINY) 82 | #define printf_P(...) 83 | #endif 84 | #endif 85 | 86 | // Avoid spurious warnings 87 | // Arduino DUE is arm and uses traditional PROGMEM constructs 88 | #if 1 89 | #if ! defined( NATIVE ) && defined( ARDUINO ) && ! defined(__arm__) && ! defined( CORE_TEENSY3 ) 90 | #undef PROGMEM 91 | #define PROGMEM __attribute__(( section(".progmem.data") )) 92 | #undef PSTR 93 | #define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];})) 94 | #endif 95 | #endif 96 | 97 | // Progmem is Arduino-specific 98 | // Arduino DUE is arm and does not include avr/pgmspace 99 | #if defined(ARDUINO) && ! defined(__arm__) 100 | #include 101 | #define PRIPSTR "%S" 102 | #else 103 | #if ! defined(ARDUINO) // This doesn't work on Arduino DUE 104 | typedef char const char; 105 | #else // Fill in pgm_read_byte that is used, but missing from DUE 106 | #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) 107 | #endif 108 | 109 | 110 | #if !defined ( CORE_TEENSY ) 111 | typedef uint16_t prog_uint16_t; 112 | #define PSTR(x) (x) 113 | #define printf_P printf 114 | #define strlen_P strlen 115 | #define PROGMEM 116 | #define pgm_read_word(p) (*(p)) 117 | #endif 118 | 119 | #define PRIPSTR "%s" 120 | 121 | #endif 122 | 123 | 124 | 125 | // ATTiny support code is from https://github.com/jscrane/RF24 126 | 127 | #if defined(RF24_TINY) 128 | #include 129 | #include 130 | #include 131 | 132 | #define SPI_CLOCK_DIV4 0x00 133 | #define SPI_CLOCK_DIV16 0x01 134 | #define SPI_CLOCK_DIV64 0x02 135 | #define SPI_CLOCK_DIV128 0x03 136 | #define SPI_CLOCK_DIV2 0x04 137 | #define SPI_CLOCK_DIV8 0x05 138 | #define SPI_CLOCK_DIV32 0x06 139 | //#define SPI_CLOCK_DIV64 0x07 140 | 141 | #define SPI_MODE0 0x00 142 | #define SPI_MODE1 0x04 143 | #define SPI_MODE2 0x08 144 | #define SPI_MODE3 0x0C 145 | 146 | #define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR 147 | #define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR 148 | #define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR 149 | 150 | 151 | 152 | class SPIClass { 153 | public: 154 | static byte transfer(byte _data); 155 | 156 | // SPI Configuration methods 157 | 158 | inline static void attachInterrupt(); 159 | inline static void detachInterrupt(); // Default 160 | 161 | static void begin(); // Default 162 | static void end(); 163 | 164 | static void setBitOrder(uint8_t); 165 | static void setDataMode(uint8_t); 166 | static void setClockDivider(uint8_t); 167 | }; 168 | extern SPIClass SPI; 169 | 170 | #endif //ATTiny 171 | #endif // __RF24_CONFIG_H__ 172 | 173 | -------------------------------------------------------------------------------- /libraries/MySensors/utility/nRF24L01.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2007 Stefan Engelke 3 | Portions Copyright (C) 2011 Greg Copeland 4 | 5 | Permission is hereby granted, free of charge, to any person 6 | obtaining a copy of this software and associated documentation 7 | files (the "Software"), to deal in the Software without 8 | restriction, including without limitation the rights to use, copy, 9 | modify, merge, publish, distribute, sublicense, and/or sell copies 10 | of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* Memory Map */ 27 | #define CONFIG 0x00 28 | #define EN_AA 0x01 29 | #define EN_RXADDR 0x02 30 | #define SETUP_AW 0x03 31 | #define SETUP_RETR 0x04 32 | #define RF_CH 0x05 33 | #define RF_SETUP 0x06 34 | #define STATUS 0x07 35 | #define OBSERVE_TX 0x08 36 | #define CD 0x09 37 | #define RX_ADDR_P0 0x0A 38 | #define RX_ADDR_P1 0x0B 39 | #define RX_ADDR_P2 0x0C 40 | #define RX_ADDR_P3 0x0D 41 | #define RX_ADDR_P4 0x0E 42 | #define RX_ADDR_P5 0x0F 43 | #define TX_ADDR 0x10 44 | #define RX_PW_P0 0x11 45 | #define RX_PW_P1 0x12 46 | #define RX_PW_P2 0x13 47 | #define RX_PW_P3 0x14 48 | #define RX_PW_P4 0x15 49 | #define RX_PW_P5 0x16 50 | #define FIFO_STATUS 0x17 51 | #define DYNPD 0x1C 52 | #define FEATURE 0x1D 53 | 54 | /* Bit Mnemonics */ 55 | #define MASK_RX_DR 6 56 | #define MASK_TX_DS 5 57 | #define MASK_MAX_RT 4 58 | #define EN_CRC 3 59 | #define CRCO 2 60 | #define PWR_UP 1 61 | #define PRIM_RX 0 62 | #define ENAA_P5 5 63 | #define ENAA_P4 4 64 | #define ENAA_P3 3 65 | #define ENAA_P2 2 66 | #define ENAA_P1 1 67 | #define ENAA_P0 0 68 | #define ERX_P5 5 69 | #define ERX_P4 4 70 | #define ERX_P3 3 71 | #define ERX_P2 2 72 | #define ERX_P1 1 73 | #define ERX_P0 0 74 | #define AW 0 75 | #define ARD 4 76 | #define ARC 0 77 | #define PLL_LOCK 4 78 | #define RF_DR 3 79 | #define RF_PWR 6 80 | #define RX_DR 6 81 | #define TX_DS 5 82 | #define MAX_RT 4 83 | #define RX_P_NO 1 84 | #define TX_FULL 0 85 | #define PLOS_CNT 4 86 | #define ARC_CNT 0 87 | #define TX_REUSE 6 88 | #define FIFO_FULL 5 89 | #define TX_EMPTY 4 90 | #define RX_FULL 1 91 | #define RX_EMPTY 0 92 | #define DPL_P5 5 93 | #define DPL_P4 4 94 | #define DPL_P3 3 95 | #define DPL_P2 2 96 | #define DPL_P1 1 97 | #define DPL_P0 0 98 | #define EN_DPL 2 99 | #define EN_ACK_PAY 1 100 | #define EN_DYN_ACK 0 101 | 102 | /* Instruction Mnemonics */ 103 | #define R_REGISTER 0x00 104 | #define W_REGISTER 0x20 105 | #define REGISTER_MASK 0x1F 106 | #define ACTIVATE 0x50 107 | #define R_RX_PL_WID 0x60 108 | #define R_RX_PAYLOAD 0x61 109 | #define W_TX_PAYLOAD 0xA0 110 | #define W_ACK_PAYLOAD 0xA8 111 | #define FLUSH_TX 0xE1 112 | #define FLUSH_RX 0xE2 113 | #define REUSE_TX_PL 0xE3 114 | #define NOP 0xFF 115 | 116 | /* Non-P omissions */ 117 | #define LNA_HCURR 0 118 | 119 | /* P model memory Map */ 120 | #define RPD 0x09 121 | #define W_TX_PAYLOAD_NO_ACK 0xB0 122 | 123 | /* P model bit Mnemonics */ 124 | #define RF_DR_LOW 5 125 | #define RF_DR_HIGH 3 126 | #define RF_PWR_LOW 1 127 | #define RF_PWR_HIGH 2 128 | -------------------------------------------------------------------------------- /libraries/readVcc/readVcc.h: -------------------------------------------------------------------------------- 1 | long readVcc() { 2 | // Read 1.1V reference against AVcc 3 | // set the reference to Vcc and the measurement to the internal 1.1V reference 4 | #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 5 | ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); 6 | #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) 7 | ADMUX = _BV(MUX5) | _BV(MUX0); 8 | #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) 9 | ADMUX = _BV(MUX3) | _BV(MUX2); 10 | #else 11 | ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); 12 | #endif 13 | 14 | delay(2); // Wait for Vref to settle 15 | ADCSRA |= _BV(ADSC); // Start conversion 16 | while (bit_is_set(ADCSRA,ADSC)); // measuring 17 | 18 | uint8_t low = ADCL; // must read ADCL first - it then locks ADCH 19 | uint8_t high = ADCH; // unlocks both 20 | 21 | long result = (high<<8) | low; 22 | 23 | result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000 24 | return result; // Vcc in millivolts 25 | } 26 | -------------------------------------------------------------------------------- /libraries/readVcc/readme.md: -------------------------------------------------------------------------------- 1 | include the readVcc library: ```#include ``` 2 | 3 | 4 | Add this to the setup: 5 | 6 | ``` 7 | // Define voltages 8 | 9 | int MIN_V = 2400; // empty voltage (0%) 10 | int MAX_V = 3200; // full voltage (100%) 11 | int oldBatteryPcnt; 12 | ``` 13 | 14 | Add this to the loop: 15 | 16 | ``` 17 | // Measure battery 18 | float batteryV = readVcc(); 19 | int batteryPcnt = (((batteryV - MIN_V) / (MAX_V - MIN_V)) * 100 ); 20 | if (batteryPcnt > 100) { 21 | batteryPcnt = 100; 22 | } 23 | ``` 24 | 25 | If you want to send the percentage to the mysensors gateway you have to add: 26 | 27 | ``` 28 | if (batteryPcnt != oldBatteryPcnt) { 29 | gw.sendBatteryLevel(batteryPcnt); // Send battery percentage 30 | oldBatteryPcnt = batteryPcnt; 31 | } 32 | 33 | ``` 34 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | Arduino sketches for sensors on 433Mhz and 2.4Ghz (MySensors). These sketches use the [NewRemoteSwitch](https://github.com/hjgode/homewatch/tree/master/arduino/libraries/NewRemoteSwitch) as 433Mhz library or the [customized MySensors library](https://github.com/sweebee/Arduino-home-automation/tree/master/libraries/MySensors). 2 | --------------------------------------------------------------------------------