Electronics

How X-10 Works


The method used by X-10 is based on a simple
data frame with eight data bits (one byte) preceded by a predetermined start code.

hti-2-01.gif (12580 bytes)The complicated part of this technology was not the system of binary data,
but the method in which it was transmitted from one device (the transmitter) to another
device (the receiver). The key was for every device to have an integral “zero
crossing” detector so that all of them were synchronized together (figure 1). A
receiver opens its receive “window” twice each sine wave (figure 2), that is 120
times each second or 7,200 times each minute. (ThatÂ’s 432,000 an hour, or 10,368,000
a day! That means itÂ’s looking for little pulses of data 3,784,320,000 times a year
!!….at 60Hz, anyway.)

hti-2-02.gif (12500 bytes)Since these devices would not have any direct wiring between them, it was
necessary to devise a way of sending the data over the existing electrical wiring. The
actual binary data is transmitted by sending 1ms bursts of 120kHz just past the zero
crossing of the 60Hz power. (While North America remains the primary market for X-10 based
devices, products are also available which are designed for use on 50Hz electrical
distribution systems.) It was also obvious that complementary bit pairs were necessary.
Therefore, a binary “1” was defined as the presence of a pulse, immediately
followed by the absence of a pulse. A binary “0” was defined as the absence of a
pulse, immediately followed by the presence of a pulse (figure 3).

hti-2-03.gif (23622 bytes)

While the transmitted pulses were to be a full 1ms in duration, the
receivers were designed to open a receive window of only .6ms. That allowed for the loose
tolerances of the 1978-era components to “slop” plus/minus 200m sec.

In order to provide a predictable start point (figure 4), every data frame would always
begin with at least 6 leading clear zero crossings, then a start code of
“pulse”, “pulse”, “pulse”, “absence of a pulse”
(or 1110).

hti-2-04.gif (16616 bytes)hti-2-05.gif (16874 bytes)

Once the Start Code has been transmitted, the first nibble is sent. (If you are not
familiar with the term “nibble”, that means 4 bits or half a byte.) In order to
make it easier for the consumers to operate the devices, this first 4-bits were given
“letter” code designations (figure 5). It was also decided to randomly rearrange
the patterns so that the “A”, “B”, “C” codes, etc., did not
fall in the predicable binary pattern. It is easy to see that in reality, the
“M” code is first in the binary progression.
hti-2-06.gif (21026 bytes)

In one contiguous bit stream, the second nibble provides the second
half of the address (figure 6). The last bit appears to be a part of the
“number” code but in reality it is a function bit. Whenever this function bit is
a “0”, it designates the preceding nibble as a number code and therefore a part
of the address.

For purposes of redundancy, reliability and to
accommodate line repeaters, the X-10 protocol calls for every frame of data to be
transmitted twice (figure 7).

hti-2-07.gif (22038 bytes)

Whenever the data changes from one address to another address, from
an address to a command, from one command to another command or from one command to
another command (figure 8), the data frames must be separated by at least 6 clear zero
crossings (or “000000”). When teaching classes in this stuff, I often say that
this gap “gives the receivers a chance to catch their breath“. In
reality, of course, the sequence of six “zeroÂ’s” resets the shift
registers.

hti-2-08.gif (19819 bytes)

Once a receiver has processed its address data, it is ready to
receive a command. As before, all data frames must begin with a start code. Then the
following nibble gives the letter code (figure 9). The next nibble is the command. Since
the last bit is the function bit (bf = 0 = address number, bf = 1 =
command) all the commands end in a binary 1.

hti-2-09.gif (20733 bytes)

This diagram (figure 10) only shows the six most often used
commands. A later graphic will illustrate all the available commands. As before, all X-10
protocol transmitters send their data frames twice (figure 11).

hti-2-10.gif (17792 bytes)hti-2-11.gif (22216 bytes)

hti-2-12.gif (24333 bytes)

Figure 12 shows that an example transmission of two data frames (A1 A1 A-On
A-On, for instance) would take 47 cycles of the 60Hz sine wave. That would equate to
0.7833 seconds, or in practical terms, just under 1 second. Of course, some commands take
less time. When sending an “All-Lights-On” command, for example, no address
needs to be sent. Therefore the entire two frame sequence takes only one third of a second
(actually, 0.3666 seconds, but whoÂ’s quibbling). If your receivers react on the first
frame, it could take a mere two tenths of a second (0.1833 seconds).

Up to this time, all the diagrams have shown only one pulse but that
is not entirely correct. I did that just to make it easier to explain. In reality, it is
not a “single phase” world. On this planet, we generate our electrical power in
3 phases (figure 13) and so all X-10 compatible transmitters “should” send out 3
pulses (as in figure 14).

hti-2-13.gif (22065 bytes)
hti-2-14.gif (16179 bytes)

Finally, I promised to give you an “introduction” into
X-10Â’s Extended Code Protocol. IÂ’m going to take the easy way out and just give
you first a graphic showing all of the available bit sequences in the X-10 standard code.
Instead of making this just part of the text of this article, I have made it a graphic so
the word-wrap feature of your browser wonÂ’t screw up the alignment.

hti-2-15.gif (13673 bytes)

Almost everything I have said since the beginning of this
explanation can be summed up in this one graphic, but arenÂ’t you glad I took the time
to explain it?

You will notice that there are some changes in four of the command
codes.

  • Ext Code0111- Now designated as “Ext Code 1”, for data and
    control
  • Preset Dim (1)1010- Now designated as “Ext Code 3”, for
    security messages
  • Preset Dim (2)1011- Now designated as “Unused”
  • Ext Data1100- Now designated as “Ext Code 2”, for meter
    read and DSM

 

As far as we know (at the time of this writing) only “Extended
Code 1” has a defined frame length which is 31 cycles (62 bits) and is described as:

  • Start Code = 4 bits,
  • Housecode = 4 bits,
  • Extended code 1 = 5 bits (01111),
  • Unit code (device code) = 4 bits,
  • Data = 8 bits,
  • Command = 8 bits..

The explanation for not having a defined frame length for the other
two is:

“Extended code 2 is variable in length, depending on the
type of message. It has its own separate “attention” marker to separate it from
all other formats.

Extended code 3 has been “assigned” for security but
doesn’t actually exist yet so its format has not yet been defined.”


Programming Your Own ATtiny – in 9 easy steps

  1. Go to http://code.google.com/p/arduino-tiny/downloads/list, and download arduino-tiny-0022-0008.zip or the latest version thereof.
  2. In your sketches folder, create a folder called “hardware” and put the contents of the zip file in it.
  3. In that hardware folder, under the “tiny” folder, you should see a file called “boards.txt”. Open it for editing. For each ATtiny chip you plan to program, you need to set the ISP you’ll be using. In this example, I am using the Arduino as an ISP, so this block (for ATtiny85, 1MHz clock) will look like this when finished:
    # The following DO work (pick one)...
     # attiny85at1.upload.protocol=avrispv2
     attiny85at1.upload.using=arduino:arduinoisp
     # attiny85at1.upload.using=pololu

    If you haven’t figured it out, the ‘#’ sign at the beginning of a line will comment it out. Make sure only one of these lines is not commented – the one you want to use.

  4. Open the Arduino IDE. You should now see each of the boards listed in the file you just edited.
  5. Now open the ArduinoISP sketch (found in the file/examples menu). Make sure your Arduino board is selected in the list of boards (your Arduino board, not the ATtiny, we are not to that step yet). Upload the sketch. You can add some diagnostic LEDs (with 1k resistors) at this point (or even before you upload the sketch). Put an LED (with resistor) on the following pins to ground:

    9: Heartbeat – shows the programmer is running

    8: Error – Lights up if something goes wrong (use red if that makes sense)

    7: Programming – In communication with the slave (use green if you like)

    You should now see the LED at pin 9 slowly pulse on and off.

  6. VERY IMPORTANT: To finish turning your Arduino into an ISP, you must connect a 120 ohm (500 ohm seems to work as well for me anyway) resistor from the reset pin to +5v. What this does is prevents the Arduino IDE from resetting the Arduino itself. After all, we are not programming the Arduino anymore after this, but the ATtiny. Don’t forget to remove this resistor when you want to program your Arduino again.
  7. Now wire up your Arduino to the ATtiny chip. Here are the connections you need for each ATtiny pin to your Arduino:
    ATTiny45 & ATTiny85 pinout

    ATTiny45 & ATTiny85 pinout

    1. digital 10
    2. nc
    3. nc
    4. ground
    5. digital 11
    6. digital 12
    7. digital 13
    8. +5V
  8. You are ready to program. To test it do the following:
    1. Open up the Blink sketch, under examples/basics.
    2. Change all instances of pin 13 to pin 0.
    3. Under the Tools/Board menu, select the ATtiny version you are using. I am using an ATtiny85, clock speed 1MHz. No external clock is needed.
    4. Hook up a 1k resistor & LED from ATtiny pin 5 (digital 0) to ground.
    5. Upload the sketch. Your Arduino pin 7 pin should blink, and the error pin should stay off. When it is done, your ATtiny LED should be blinking on and off.

Measuring Voltage with an Arduino


It turns out the Arduino 168 and 328 can measure their own voltage rail.

Code

Copy, paste into Arduino and see what it returns. This works on an Arduino 168 or 328.

long readVcc(){
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0)| _BV(MUX3)| _BV(MUX2)| _BV(MUX1);
  delay(2);// Wait for Vref to settle
  ADCSRA |= _BV(ADSC);// Convert
  while(bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result =1126400L/ result;// Back-calculate AVcc in mV
  return result;
}

void setup(){
  Serial.begin(9600);
}

void loop(){
  Serial.println( readVcc(), DEC );
  delay(1000);
}
 

The voltage is returned in millivolts. So 5000 is 5V, 3300 is 3.3V.

Note the following:

  • This works on Arduinos with a 328 or 168 only. It looks like the same trick might be possible on the Arduino Mega – experiments are ongoing, and will be reported here.

How it works

The Arduino 328 and 168 have a built in precision voltage reference of 1.1V. This is used sometimes for precision measurement, although for Arduino it usually makes more sense to measure against Vcc, the positive power rail.

The chip has an internal switch that selects which pin the analogue to digital converter reads. That switch has a few leftover connections, so the chip designers wired them up to useful signals. One of those signals is that 1.1V reference.

So if you measure how large the known 1.1V reference is in comparison to Vcc, you can back-calculate what Vcc is with a little algebra. That is how this works.