Go Down

Topic: X10 in the UK and Europe (Read 2529 times) previous topic - next topic

LJRob

Dec 07, 2012, 10:44 pm Last Edit: Dec 13, 2012, 04:05 pm by LJRob Reason: 1
Hi
Here is my sketch for X10 control. It does not use any libraries, the commands only need to be sent once and does not use the zero cross method.

The catch is the X10 controller is a CM12U. All I am doing is sending serial commands to the CM12U. I have been using X10 in my house for many years using an Apple Mini with no problems. I wanted to control my house with my Arduino.

I tried many sketches and libraries but could not get any of them to work. Then I tried reading the commands coming from my Apple Mini USB to serial and thought why not use a TTL to serial to send commands to the X10.

When the CM12U is first plugged into a socket it sends out a polling command. Unless you reply to this command it will not respond to any other X10 commands.

Code: [Select]

/*
 Arduino 1.0.1
This sketch controls X10 modules using a TTL to RS232 and a UK CM12U X10 controller


*/


#include <SoftwareSerial.h> // For the TTL to RS232

#define A 0x60
#define B 0xE0
#define C 0x20
#define D 0xA0
#define E 0x10
#define F 0x90
#define G 0x50
#define H 0xD0
#define I 0x70
#define J 0xF0
#define K 0x30
#define L 0xB0
#define M 0x00
#define N 0x80
#define O 0x40
#define P 0xC0

#define UNIT_1 0x06
#define UNIT_2 0x0E
#define UNIT_3 0x02
#define UNIT_4 0x0A
#define UNIT_5 0x01
#define UNIT_6 0x09
#define UNIT_7 0x05
#define UNIT_8 0x0D
#define UNIT_9 0x07
#define UNIT_10 0x0F
#define UNIT_11 0x03
#define UNIT_12 0x0B
#define UNIT_13 0x00
#define UNIT_14 0x08
#define UNIT_15 0x04
#define UNIT_16 0x0C

#define ALL_UNITS_OFF 0x00
#define ALL_LIGHTS_ON 0x01
#define ON 0x02
#define OFF 0x03
#define DIM 0x04
#define BRIGHT 0x05
#define ALL_LIGHTS_OFF 0x06
#define EXTENDED_CODE 0x07
#define HAIL_REQUEST 0x08
#define HAIL_ACKNOWLEDGE 0x09
#define PRE_SET_DIM_1 0x0A
#define PRE_SET_DIM_2 0x0B
#define EXTENDED_DATA 0x0C
#define STATUS_ON 0x0D
#define STATUS_OFF 0x0E
#define STATUS_REQUEST 0x0F

#define d 600    // 600 ms to 2000 ms delay after first three bytes are sent
#define d2 20    // 20 ms delay waiting for checksum before sending the next three bytes

SoftwareSerial X10Serial(2, 3); // RX, TX to TTL RS232
             
byte incomingByte;     // from the X10 controller or the keyboard
byte Housecode_Devicecode; // for the X10Serial.write third byte
byte Housecode_Function;   // for the X10Serial.write third byte
byte luminance = 0x00;     // brightness and dim value

void setup() {

 Serial.begin(9600);
 X10Serial.begin(4800);    // X10 Baud 4800 8,NONE,1
 delay(d);    //
 PrintMenu();    // Print the menu on the screen
}

void loop() {

 CheckX10controller ();  // Check X10 controller
 CheckKeyboard();       // Check keyboard
}

// Read from X10 controller
void CheckX10controller () {

 if (X10Serial.available() > 0) {
   incomingByte = X10Serial.read();

   switch (incomingByte) {

     case ((byte)0xA5):          // Polling. This happens the first time you plug the X10 controller in the socket or after a power cut
     delay(d2);                  // wait 20 ms before sending Acknowledge
     X10Serial.write((byte)0x9B);   // Acknowledge / Clear, This must be cleared or it will not except any other x10 commands
     PowerSupplyRestored();
     break;

     case ((byte)0x5A):          // Polling. this happens after remote wireless button has been pressed.
     delay(d2);                  // wait 20 ms before sending Acknowledge
     X10Serial.write((byte)0xC3);   // Acknowledge / Clear, This must be cleared or it will not except any other x10 commands
     RFrestored();
     break;
   }
 }
}


// Read from Keyboard
void CheckKeyboard() {

 if (Serial.available() > 0) {
   incomingByte = Serial.read();

   switch (incomingByte) {

   case '?':                       // Keyboard "?"
     PrintMenu();               // Print help menu
     break;

   case '1':                     // Keyboard "1"
     X10Command(A+UNIT_1,A+ON, 0x00); // A1 ON
     break;

   case '2':                       // Keyboard "2"
     X10Command(A+UNIT_1,A+OFF, 0x00); // A1 OFF
     break;

   case '3':                     // Keyboard "3"
     X10Command(A+UNIT_2,A+ON, 0x00);  // A2 ON
     break;

   case '4':                       // Keyboard "4"
     X10Command(A+UNIT_2,A+OFF, 0x00); // A2 OFF
     break;

   case 'p':                       // Keyboard "p"
     PowerSupplyStatus();              // Check X10 Interface power supply
     break;

   case '0':                       // Keyboard "0" send all units OFF to A ... P
     for (int i = 0x00; i <= 0xF0; i += 0x08) {
       X10Function(i+ALL_UNITS_OFF,0x00);
       delay(300);
     }
     break;

   case 'b':                       // Keyboard "b" brighten lamp A2
     X10Command(A+UNIT_2, A+BRIGHT, 0x03);
     break;

   case 'd':                     // Keyboard "d" dim lamp A2
     X10Command(A+UNIT_2, A+DIM, 0x03);
     break;
   }

 }  
}

void X10Command(byte Housecode_Devicecode, byte Housecode_Function, byte luminance) {

 // first three bytes
 X10Serial.write((byte)0x04);                      // start code
 X10Serial.write((byte)Housecode_Devicecode);      // house code and device code
 delay(d2);                                        // short delay to wait for checksum from Interface
 X10Serial.write((byte)0x00);                      // Acknowledge checksum

 delay(d);                                         // long delay Interface ready

 // second three bytes
 X10Serial.write((byte)0x06 + (luminance << 3));  // start code plus bright or dim value. luminance value is shiftbit left by 3
 X10Serial.write((byte)Housecode_Function);       // house and function code. on/off dim/bright
 delay(d2);                                       // short delay to wait for checksum from Interface
 X10Serial.write((byte)0x00);                     // Acknowledge checksum
}

void X10Function(byte Housecode_Function, byte luminance) {

 // second three bytes
 X10Serial.write((byte)0x06 + (luminance << 3));  // start code plus bright or dim value. luminance value is shiftbit left by 3
 X10Serial.write((byte)Housecode_Function);       // house and function code. on/off dim/bright
 delay(d2);                                       // short delay to wait for checksum from Interface
 X10Serial.write((byte)0x00);                     // Acknowledge checksum
}

void PowerSupplyStatus() {

 X10Serial.write((byte)0xEB);                     // send Enable Ring to check power supply
 delay(20);                                       // short to wait for checksum from Interface
 if (X10Serial.read() == ((byte) 0xEB)) {         // checksum should be 0xEB
   PowerSupplyHealthy();                          // X10 controller still mains on
 }
 else {
   PowerSupplyDown();                            // X10 controller dead
 }
}

void PowerSupplyHealthy() {
 Serial.println("\nPower Supply Healthy");
}
void PowerSupplyDown() {
 Serial.println("\nPower Supply Down");
}
void PowerSupplyRestored() {
 Serial.println("\nPower Supply Restored");
}
void RFrestored() {
 Serial.println("\nRemote polling Reset");
}

void PrintMenu() {
 Serial.println("X10 Menu");
 Serial.println(
 "? Help\n"
   "1 A1 Appliance ON\n"
   "2 A1 Appliance OFF\n"
   "3 A2 Lamp ON\n"
   "4 A2 Lamp OFF\n"
   "b A2 Bright\n"
   "d A2 Dim\n"
   "0 All Units OFF A to P\n"
   "p Check Power Supply");
}

daxke

Hi LJRob,

I just bought an arduino and want to use it to control my X10-system, at the end it is the idea to put on an ethernet shield and control my X10 modules via an app on my TAB/mobile.

Your code was very usefull to test my setup. I have some problems however. I'm using the CM11a (belgian version of your CM12u I suppose)

I have my arduino connected to a MAX232 to convert the TTL into RS232. (followed this diagram http://avrprogrammers.com/doc-max232-arduino.php)

But I'm not sure about the pin-out of the CM11 module. There is a lot of contradictionary info on the net about this pinning. How did you connect your CM12 to the arduino?

The furthest I got was to request the 'power supply' but there the answer was allways 'power down'.

Any ideas?

Thank you! Dax

LJRob

#2
Dec 14, 2012, 09:54 pm Last Edit: Dec 14, 2012, 10:49 pm by LJRob Reason: 1
Hello Dax

Thank you for your interest of my X10 sketch. I am using a MAX232 to TTL converter like this one
http://www.ebay.co.uk/itm/MAX232-RS232-Serial-To-TTL-Output-Converter-Board-RXD-TXD-RTS-CTS-F-PIC-Atmel-/290712442058?pt=UK_BOI_Electrical_Components_Supplies_ET&hash=item43afcfd4ca

I had to make up a new cable from my CM12 because it came with a female DB9. The RS232 to TTL converter also had a female DB9. I tried using a gender changer but it also needed a nul modem to make it work.

Here's the connections I have used.

Holding the RJ11 with the cable away from you and the locking clip on the top.
From left to right, pins are 1 2 3 4

       Signal  DB9 Connector   RJ11 Connector
       SIN       Pin 2                 Pin 3
       SOUT    Pin 3                 Pin 1
       GND     Pin 5                 Pin 4
       RI         Pin 9                 Pin 2

You don't need to use pin 9 on the DB9.        
You may need to swap the wires on pins 2 and 3 on the DB9 if it not work first time.

Im using pins 2 and 3 on my Arduino for software serial for the RS232 to TTL converter, I notice the connection website your using  has pins 0 and 1 for the MAX232



Let me know if this works for you,
Thanks.
LJRob.

daxke

:) :) :)

Hello LJRob,

Thank you very much for your reply, I just had some time to test it with your explanation of the cabling and it is working very well.

My biggest problem was indeed that I overlooked the RX/TX from/to the arduino, I was using the pins 0 and 1 instead 2 and 3.

Again one step closer to my X10-automation via a smartphone :-)

Thank you,

Dax

stephenwong

Hi LJRob,

I am newbie in electronics and is learning to do some home automation stuffs with my arduino. How do I hook up the MAX232 to TTL converter to my CM12U x10 controller. Please advise. Thank you very much.

zoomkat

The combo of the below transponder and the bottom firecracker would mqake x10 control super simple. The cm17a firecracker connects to the arduino with three wires and is powered by the arduino.

http://www.x10europe.com/pdf/TM13E.pdf
http://www.ebay.com/sch/i.html?_trksid=p5197.m570.l1313&_nkw=x10+cm17a&_sacat=0&_from=R40
Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

LJRob

With all due respect to zoomKat, He has not read the specifications of the european X10 transponder. The firecracker uses 310 MHZ and the european X10 transponder uses 433.92 MHZ. They will not talk to each other. I found this out to my cost by not reading the specs of the firecracker and buying one.

I have not found any articles on the internet about people in Europe using an Arduino with X10 (except for people not able to make them work) So I decided to learn X10 myself and help others by starting this post and freely giving the information I have learned, which is in the first thread of this post.

zoomkat

Quote
With all due respect to zoomKat, He has not read the specifications of the european X10 transponder.


True, I just bought off on their "• Compatible with all X10 wireless remotes." The hand held remotes can be hacked, but probably not worth the effort.
Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

Go Up