Wednesday 17 August 2016

433MHz control of room lighting

The Energenie sockets that are very low cost on Amazon, are controlled by a push button hand-held controller. It outputs codes over a 433.92MHz RF signal, which the sockets receive and respond to.

Each socket has a different code, one for ON and one for OFF.

RX & TX

There are some very low cost 433.92MHz transmitters and receivers on the market (below £2 the pair!). Using the receiver and some Arduino software the codes for your personal sockets can be read from the hand-held controller. Once you know these, a second Arduino program can be used to send these code out using the transmitter, and this will control the sockets.

The software for all this is in a library called "RCSwitch.h" downloadable here. The examples given with this library show how to use it.

Screen Shot 2016 08 17 at 10 41 11

These are the Energenie sockets and their controller. Each socket has to initialised to match a code from the controller, but when this is done the sockets can be controlled from the Arduino and connected transmitter.

Screen Shot 2016 08 17 at 10 51 12

The receiver is on the right and the transmitter to the left. Each has three connections (the OUTput of the receiver is on two connected pins). The receiver is connected to +5V, pin 2 (interrupt 0) and GND when you run the code reading sketch (see RCSwitch Examples). The transmitter is connected to +5V, Arduino pin 10 and GND. The sketch below allows you to type 1/2, 3/4, 5/6 into the Arduino Serial Monitor window and to switch ON or OFF three of the sockets (the code could easily be extended to cover the four sockets, and the ability to switch ON/OFF all the sockets at once. The codes below are for the sockets I bought, you will have to read and substitute your own codes.

Code to read remote codes

// RX_find_code_1
// detects remote RF signals and IDs LOW, HIGH and length
// start program, then push a button on the remote
// reset to re-run the program

// LED pin, RX input pin
 #define LEDPIN 13
 #define RXPIN A0

 //Create an array to store the data
 const int dataSize = 500;
 byte storedData[dataSize];

 // upper and lower thresholds
 const unsigned int upperThreshold = 100;
 const unsigned int lowerThreshold = 80;
 
// maximum length of the signal, length of signal
 int maxSignalLength = 255;
 int dataCounter = 0;

 // start time, end time, read time
 unsigned long startTime = 0;
 unsigned long endTime = 0;
 unsigned long signalDuration = 0;
 
 void setup(){
  Serial.begin(9600);
  pinMode(LEDPIN, OUTPUT);
  
  /* The following code will only run ONCE --------------
  ---Press the reset button on the Arduino to run again-- */
  
  //Wait here until a LOW signal is received
  while(analogRead(RXPIN) < 1) {
      startTime = micros();  //Update start time with every cycle.
  }
  digitalWrite(LEDPIN, HIGH);  //Turn LED ON
  
  //Read and store the rest of the signal into the storedData array
  for(int i = 0; i < dataSize; i = i+2) {
    
    //Identify the length of the LOW signal---------------LOW
    dataCounter = 0; //reset the counter
    while(analogRead(RXPIN) > upperThreshold && dataCounter < maxSignalLength) {
      dataCounter++;
    }
    storedData[i] = dataCounter;
    
    //Identify the length of the HIGH signal---------------HIGH
    dataCounter = 0;//reset the counter
    while(analogRead(RXPIN) < lowerThreshold && dataCounter < maxSignalLength){
      dataCounter++;
    }
    storedData[i+1] = dataCounter;
    
    /* Any readings between the two threshold values will be ignored.
     *
     * The LOW or HIGH signal length must be less than the variable "maxSignalLength"
     * otherwise it will be truncated.
     *
     * All of the HIGH signals and LOW signals combined must not exceed the variable "dataSize"
     * otherwise it will be truncated.
     *
     * The maximum number of signals is 1700 (memory limit)
     * If you try to extend this variable to a higher number than 1700
     * then the Arduino will freeze up and sketch will not work.*/
  }


  //Record the end time of the read period.
  endTime = micros();
  signalDuration = endTime - startTime;

  //Turn LED OFF
  digitalWrite(LEDPIN, LOW);
  
  //Send report to the Serial Monitor
  Serial.println("=====================");
  Serial.print("Read duration: ");
  Serial.print(signalDuration);
  Serial.println(" us");
  Serial.println("=====================");
  Serial.println("LOW, HIGH");
  delay(20);
  for(int i = 0; i < dataSize; i = i+2) {
    Serial.print(storedData[i]);
    Serial.print(", ");
    Serial.println(storedData[i+1]);
    delay(20);
  }
 }

 void loop(){
   //Do nothing here, press reset to re-run the program
 }
Code to transmit the codes

/*
 Example for my own codes, yours may be different
*/
 
#include 
 
// constructor for mySwitch object
RCSwitch mySwitch = RCSwitch();

byte inByte = 0;

void setup() {
 
 Serial.begin(9600);
 
 // Transmitter is connected to Arduino Pin 10
 mySwitch.enableTransmit(10);
 
// Optional set pulse length.
 // mySwitch.setPulseLength(320);
 
 // Optional set protocol (default is 1, will work for most outlets)
 // mySwitch.setProtocol(2);
 
 // Optional set number of transmission repetitions.
  mySwitch.setRepeatTransmit(4);
 
 Serial.println("Ready"); // Ready to receive commands
}
 
void loop() {
 /* Switch using decimal code */
 if(Serial.available() > 0) { // A byte is ready to receive
   inByte = Serial.read();

   if(inByte == '1') { // byte is '1'
     mySwitch.send(14237327, 24);
     Serial.println("1 ON");
   }
   else if(inByte == '2') { // byte is '2'
     mySwitch.send(14237326, 24);
     Serial.println("1 OFF");
   }
   else if(inByte == '3') { // byte is '3'
     mySwitch.send(14237319, 24);
     Serial.println("2 ON");
   }
   else if(inByte == '4') { // byte is '4'
     mySwitch.send(14237318, 24);
     Serial.println("2 OFF");
   }
   else if(inByte == '5') { // byte is '5'
     mySwitch.send(14237323, 24);
     Serial.println("3 ON");
   }
   else if(inByte == '6') { // byte is '6'
     mySwitch.send(14237322, 24);
     Serial.println("3 OFF");
   }
 }
}
My future target is to add a speech recognition board from Audeme to the Arduino UNO and control my lighting by voice!

No comments: