Programming X10 devices

Hi,

I'm trying to program an X10 device (an activehome product) via an ultralite E iT GSM device using ethernut. I'm new to x10 and *all* the stuff found on the internet hadn't helped me one bit with the problem I'm having. The X10 protocol says that for a CM11a device, I should send

0x9b to stop the device from polling. Then I send the header:code combination for which I receive a checksum. After verifying that the checksum si correct, I then send it a 0x00 signal for which I should receive 0x55 (interface ready signal). This is where I keep getting

-91!! I've pulled my hair out and I still haven't gotten around the problem. I tried sending the device a raw hex file in which I send all the bytes together and sometimes I do get a 0x55 signal. However, this is not working programatically. Can someone please please give me a hand here if they've worked on X10? Thanks a lot!

Sona

Reply to
Sona
Loading thread data ...

As I said in another thread, a sign-extended 0x55 is equal to -91 in decimal.

I think your device is working properly, and your C code is incorrect. I sent some suggested changes, and I didn't see a reply.

Reply to
Alan Kilian

Thanks Alan, I must've overlooked your previous reply - sorry about that.

Actually I don't know what sign-extension means so I guess I'm not doing it :) But here's my code:

void ReceiveMessage(char *buffer) {

char readBuf[256]; char temp[256]; char input[2]; int ret_val=0; int no_of_tries=0;

input[0] = 0x9b; NutPrintBinary(uart,&input[0], 1); NutPrintFlush(uart); NutSleep(1000);

input[0]= 0x04; input[1]= 0x66; NutPrintBinary(uart,&input[0], 2); NutPrintFlush(uart); NutSleep(1000);

input[0]= 0x00; NutPrintBinary(uart,&input[0], 1); NutPrintFlush(uart); NutSleep(1000);

ret_val = NutDeviceRead(uart, &readBuf[0], sizeof(readBuf));

if (ret_val != 1 && ((int)readBuf[0]) != 0x55) { SendMessage("Error"); } else { SendMessage(readBuf); } }

Actually changing char to unsigned char made the code to stop working and didnt go beyond the very first transmission, i.e. of 0x9b. Probably because the function takes in a signed char? But it didn't work so I stopped trying too hard. Could you point out where the sign extension is happening? Thanks :)

Cheers,

Sona

Alan Kilian wrote:

Reply to
Sona

Hi Sona,

Signed binary numbers use the highest bit as a sign bit (1 means negative, 0 means positive). That's why a signed char can only go up to 127 but an unsigned char can go to 255 - that top bit isn't 'available' for the signed char.

Sign extension means that when you go from a smaller variable to a larger one (for example, char to int), you take the highest bit and copy it - extend it - into the extra space. For example, 91 in binary looks like

01011011 when it's stored in a 8-bit variable (such as char) and 0000000001011011 when it's stored in a 16-bit variable (such as short nt). -91 in binary looks like 10100101 in a 8-bit variable and 1111111110100101 in a 16-bit variable.

I hate to disagree with Alan - he surely has much more hardware experience than I do - but I don't think sign extension is the problem here. According to my calculator and my PC, 0x55 = 85 = 01010101 in binary, and 0x65 = 101 =

01100101. Both 0x55 and 0x65 have a 0 for the MSB (most significant bit), so sign extension wouldn't make them negative. -91 = 10100101 = 0xA5.

I looked up the ethernut docs online to get a better feel for what you're trying to do. One thing that jumped out at me is that NutDeviceRead returns the number of bytes read from the device. Have you verified that you are indeed reading just 1 byte, and you're not getting an error? If NutDeviceRead gives you something > 1, that means that there was extra stuff in the read buffer. Try adding an extra NutDeviceRead call just before you send 0x00 That should clear the buffer, Also, in the other thread you said that you're expecting to read 0x65, but here you say 0x55 - which is it?

Hope this helps, Don Pratt

Reply to
Don Pratt

Don is completely right on this. I fat-fingered my calculator when doing the "guessing-where the (-91) comes from" experiment. So, I have no idea why you're getting 0xA5 instead of 0x55 (or 0x65) Is a reply of 0xA5 defined in the X10 interface you are using? Maybe if you could point me to that document I could try again.

Reply to
Alan Kilian

Thanks a lot guys :) Yes, -91 turned out to be 0xA5.. which is the polling signal the device sends everytime it starts. I need to send it

0x9b to stop the device from polling (looking for a time request).

I finally got it working, that is, I got the initialized signal from the divice (which is 0x55).. but I stumbled over it in plain trial and error. The protocol says that after sending in the header:code combination, we should send a 0x00 to the device for which we'll receive

0x55. This was not working.. so I tried sending the header:code combination (two bytes, e.g 0x04 and 0x66) along with 6 more bytes of 0x00. For this I constructed a single array of characters holding 0x04 and 0x66 in the first two slots and 0x00s in the next 6 slots. Doing this works surprisingly. The device sends back an initialized signal (0x55) and I'm able to turn devices connected to the X-10 device on and off. What I don't understand is that the protocol does not specify this and there's no place that says that I should do it this way, that is, sending 6 more bytes of 0x00 along with the header:code combination. I don't even have to send an extra 0x00 signal after this.. is this my mistake or is there something different about this particular device? Or maybe it's something that'll work for a little time and will stop working later on (for example, when I'll add on more activehome devices on my power line etc).

In short, previsouly the protocol said, that the following should be done (translated into code):

char readBuf[256]; char signal[2];

NutPrintBinary(device, "0x9b", 1); // send 0x9b NutPrintFlush(device); NutSleep(1000);

signal[0] = 0x04; //header signal[1] = 0x66; //code NutPrintBinary(device, signal, 2); //send 2 bytes 0x04, 0x66 NutPrintFlush(device); NutSleep(1000);

signal[0] = 0x00; //header NutPrintBinary(device, signal, 1); //send 0x00 NutPrintFlush(device); NutSleep(1000);

ret_val = NutDeviceRead(uart, &readBuf[0], sizeof(readBuf));

if (ret_val == 1 && ((unsigned int)readBuf[0]) = 0x55) { Print("Device initialized"); } else { Print("Error"); // This gets called }

I changed this to:

char readBuf[256]; char signal[8] = {0x00};

NutPrintBinary(device, "0x9b", 1); // send 0x9b NutPrintFlush(device); NutSleep(1000);

signal[0] = 0x04; //header signal[1] = 0x66; //code NutPrintBinary(device, signal, 8); //send 0x04, 0x66 along with 6 bytes NutPrintFlush(device); NutSleep(1000);

ret_val = NutDeviceRead(uart, &readBuf[0], sizeof(readBuf));

if (ret_val == 1 && ((unsigned int)readBuf[0]) = 0x55) { Print("Device initialized"); // This gets called } else { Print("Error"); }

Can someone explain why this is happening? The protocol doesn't say this at all... thanks a lot!

cheers,

Sona

Alan Kilian wrote:

Reply to
Sona

PolyTech Forum website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.