One way on how to reuse 433MHZ alarming sensors for Mysensors

  • Mod

    At house I'm having an alarming system with radio 433MHz operated sensors (motion, door, fire etc.).
    Those sensors are one way informers but for many purposes it is fine.
    The sensors I have are compatible with RCSwitch library and any alert is just a 4 bytes ID.

    Just released a prototype. This prototype combines a sensor node with radio retransmitter.
    While recieving ID from 433MHZ I look into EEPROM for a child_id and then resend alert to gateway using NRF24 and Mysensors protocol.

    I have to use two modes of operation, In first mode a first ID received is stored into EEPROM with allocated child_id. Also Mysensors presentation will be send to gateway. In this mode I can register RF433 sensor on the Controller.

    In second mode any ID recieved is resend to gateway while the ID is found in EEPROM with corresponding child_id

    Here is my prototype based on UNO and Humidity sketch. The 433MHZ receiver is attached to it. it is still behaves

    and some video

  • It is interesting , it is possible to see the program code

  • Mod

    @jesper yes, sure. I get problem inserting it here. Is some one can guide me on how to insert the code?

  • @axillent if i remember well, you have to indent your code with 4 spaces

  • Mod

    i see a bug, been without a motion events for a while it is stop working
    at the same time it can work for a while in case of motion events
    hmm... fix needed

    but it is just a prototype. I plan to support 4-6 types of sensors (at least types I have with my security system). Currently only motion sensors are supportde (actually any alert sensor can be treated as a motion sensor but it will be better to differentiate)
    double radio transmittion is also not good, will be better to have an ethernet gateway directly working with RF433
    This way I'm connecting very simple RF433 sensors one way (alert is comming from sensor to home controller). Same idea but different hardware and different sketch are needed to soport RF433 relays and wall switches.

    #include <avr/eeprom.h>
    #include <SPI.h>
    #include <MySensor.h>  
    #include <DHT.h>  
    #include <RCSwitch.h>
    #define CHILD_ID_HUM 0
    #define CHILD_ID_TEMP 1
    unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
    MySensor gw;
    DHT dht;
    float lastTemp;
    float lastHum;
    boolean metric = true; 
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    RCSwitch mySwitch = RCSwitch();
    #define RF433_CHILDS_MAX	20
    typedef struct {
    	unsigned long	key;
    	uint8_t			child_id;
    } rf433_child_type;
    uint8_t				*eeprom_last_id = (uint8_t*)EEPROM_LOCAL_CONFIG_ADDRESS; 
    rf433_child_type	*eeprom_rf433_array = (rf433_child_type*)EEPROM_LOCAL_CONFIG_ADDRESS+1;
    unsigned long dht_period;
    void setup()  
      mySwitch.enableReceive(0);  // Receiver on inerrupt 0 => that is pin #2
      digitalWrite(5, HIGH);
      // Send the Sketch Version Information to the Gateway
      gw.sendSketchInfo("Humidity", "1.0");
      // Register all sensors to gw (they will be created as child devices)
      gw.present(CHILD_ID_HUM, S_HUM);
      gw.present(CHILD_ID_TEMP, S_TEMP);
      metric = gw.getConfig().isMetric;
    void loop()      
      if(digitalRead(5)) {
    	Serial.println("-- enetered RF433 init mode");
    	unsigned long t = millis();
    	while(millis() - t < 60000) {
    	  if (mySwitch.available()) {
    		unsigned long key = mySwitch.getReceivedValue();
    		uint8_t child_id = rf_find_child(key);
    		Serial.print("--- child_id - ");
    		if(child_id == 255) {
    			// key is not presented in EEPROM
    			uint8_t last_id = rf_get_last_id();
    			if(last_id < RF433_CHILDS_MAX) {
    				// a new id should be created
    				rf433_child_type child;
    				// prepare data to be stored in eeprom
    				child.key = key;
    				child.child_id = last_id + 2;
    				eeprom_write_block(&child, &eeprom_rf433_array[last_id], sizeof(child));
    				// store new last_id
    				Serial.print("new ");
    				gw.present(child.child_id, S_MOTION);
    			} else {
    				// no more space in EEPROM
    				Serial.println("no space");
    		} else {
    			// existing key
    			gw.present(child_id, S_MOTION);
    	Serial.println("-- left RF433 init mode");
      if (mySwitch.available()) {
    	  // motion event
    	  unsigned long key = mySwitch.getReceivedValue();
    	  uint8_t child_id = rf_find_child(key);
    	  Serial.print("-- rf key ");
    	  Serial.print(" child_id ");
    	  if(child_id != 255) {
    		  MyMessage msg(child_id, V_TRIPPED);
    		  gw.send(msg.set("1"));  // Send tripped value to gw 
      if(dht_period < millis()) {
    	  float temperature = dht.getTemperature();
    	  if (isnan(temperature)) {
    		  Serial.println("Failed reading temperature from DHT");
    	  } else if (temperature != lastTemp) {
    		lastTemp = temperature;
    		if (!metric) {
    		  temperature = dht.toFahrenheit(temperature);
    		gw.send(msgTemp.set(temperature, 1));
    		Serial.print("T: ");
    	  float humidity = dht.getHumidity();
    	  if (isnan(humidity)) {
    		  Serial.println("Failed reading humidity from DHT");
    	  } else if (humidity != lastHum) {
    		  lastHum = humidity;
    		  gw.send(msgHum.set(humidity, 1));
    		  Serial.print("H: ");
    	  //gw.sleep(SLEEP_TIME); //sleep a bit
    	  dht_period = millis() + SLEEP_TIME;
    uint8_t rf_get_last_id() {
    	uint8_t x = eeprom_read_byte(eeprom_last_id);
    	if(x == 255) x = 0;
    	return x;
    void rf_set_last_id(uint8_t last_id) {
    	eeprom_write_byte(eeprom_last_id, last_id);
    uint8_t rf_find_child(unsigned long key) {
    	uint8_t last_id = rf_get_last_id();
    	uint8_t id = 0;
    	while(id != last_id) {
    		rf433_child_type child;
    		eeprom_read_block(&child, &eeprom_rf433_array[id], sizeof(child));
    		if(child.key == key) return child.child_id;
    	return 255;