X10 RF using a PICAXE 08M

Hopefully, the following might be of use, I wanted to send X10 RF codes, the transmit is via a standard 433.92 Mhz AM module but the approach to the code needs a trick or two as the time for a zero bit is only 1.1 milliseconds and even doubling the processor speed that is tight at 125 microseconds a line. The code implements a complete Demo system, but it should be easy enough to jus use the relevant subroutines.

Code:
#picaxe 08m
'
' J C Burchell version 1.0 2009
'
' X10 RF out on Picaxe08m in 39 program bytes and 32 storage bytes
'
' Sends out bits of data, with X10 RF timing
'
' In X10 RF a One Bit has 2.2 ms between rising edges and a Zero bit 1.1 ms
'
' Even running the part at 8Mhz, there is not enough time to do a standard bit mask
' and IF type output pulse selection, let alone actually fetch the databytes in an inner FOR loop
' To get around this we transmit from a n byte table - where each byte contains simply the 
' delay factor to insert for the bit that is to be transmitted. 
' 
' By using a lookup table we can avoid the need for any bit testing or IF decisions, AM often demodulates better
' when the DC component is near zero - To help with this we try to keep the high and low times within 
' a One or Zero bit around 50:50
' 
goto main

symbol txPin=2                       'The pin that goes to DataIn on the TX module


symbol BitMemLow=0x50                 'Start of 32 byte memory area with data to TX
symbol BitMemMiddle=BitMemLow+16      'Where the second 16 bits start
symbol BitMemHigh=BitMemLow+31        'The last location of our 32 bit map 

symbol PreambHigh=1860                'This generates an 8 ms preamble @ 8Mhz
symbol PreambLow=8                    'This generates an 4 ms pause @ 8Mhz
symbol OneDelay=1                     'This is half the delay needed
symbol ZeroDelay=0 
symbol BitEnd=150   
symbol BetweenTryDelay=80             '40 msec between tries

symbol Memptr=b13                     'Pointer to the memory map of bits
symbol Tries=b12                      'Counter for the numbers times we send the data

symbol tmpByte=b11                    'tmp variable


' We assume that the tx module is already powered on, and the datain pin is low and that it goes high
' to send data - Some sort of hardware init code will normally have done this - though the RF Solutions RT5
' only draws 50 nanoamps when datain is low, so there is no need to bother with powering the device, it can be
' permanently connected

    
    
rfX10:
    
	setfreq m8                                'Set speed to 8 Mhz

  for Tries = 1 to 3                        'We will try to send the data three times
    pulsout txPin,PreambHigh                'Send the preamble pulse
    pause PreambLow               						'wait 4 millisecsonds

    for Memptr = BitMemLow to BitMemHigh    'Now send bits of data
      high txPin                            'First rising edge
      peek Memptr,tmpByte                   'Get the dealy whichs sets if this will be a one or zero
      pause tmpByte                         'Do half the delay - You could use pulsout DummyPin,Delay
      low txpin															'Let the tx drop - we are still within a bit
    	pause tmpByte                         'Do the rest of the delay
    next Memptr
	
	pulsout txPin,BitEnd                      'We need the final rising edge
  pause BetweenTryDelay                     'Pause between send tries
  next Tries
                
  setfreq m4                                'Restore speed
  return


' ConvertTotxMap 32 bytes
'
' The 32 byte table that rf X10 uses can be built in any number of ways - It is simply the 32 bits to be sent
' laid out in transmit order, with zero for a zero bit and OneDelay for a one bit.
' Below is a short helper routine that can take a 32 bit input (2 word registers) and convert 
' them to the 32 byte table that rf X10 needs. The input registers can be any but they must be usable as words.
' txWord0 is destroyed by this code.
' Note X10 sends the LSB of each byte first


symbol txWord0=w1      ' b3:b2
symbol txWord1=w2      ' b5:b4

' How to view the txWords as bytes
symbol txByte0=b3  
symbol txByte1=b2
symbol txByte2=b5
symbol txByte3=b4

ConvertTotxMap:

  Memptr = BitMemLow                  'Where to start the table
  do
  	tmpByte = txWord0 ** 2 * OneDelay 'Shift 1 left, get the fall out bit * delay
    txWord0 = txWord0 * 2             'update the actual word
    poke Memptr,tmpByte               'save the bit time length
    Memptr = Memptr+1
    if Memptr = BitMemMiddle then let txWord0 = txWord1 endif   'swap after 16
    loop while memptr <= BitMemHigh 
return
     

' Simple demo, sends code On then Off every 30 seconds
' Look at the CM17 protocol for the codes ftp://ftp.x10.com/pub/manuals/cm17a_protocol.txt
' For the Demo we will use
' A2 ON 0x60 0x10 and A2 OFF 0X60 0x30  - We can flip between the on and off codes with an XOR
   
symbol firstbyte = 0x60
symbol secondbyte = 0x30
symbol ToggleCode = 0x20

main:
  txByte2 = secondbyte
  forever:
   txByte0 = firstbyte           'Destroyed by ConvertTotxMap
   txByte1 = txByte0 ^ 0xff       'In X10 second byte is complement of first
   txByte2 = txByte2 ^ ToggleCode 'Switch between on and off, preserved by ConvertTotxMap
	 txByte3 = txByte2 ^ 0xff       'In X10 last byte is complement of first

   gosub ConvertTotxMap
   gosub rfx10
	 sleep 13
   goto forever
end
I blogged about it here and you can see the actual pulse trains via some Digitrace caputures.
 

davehouston

New Member
Sorry for the belated response but I'm new. I am curious what you mean by
... AM often demodulates better
when the DC component is near zero - To help with this we try to keep the high and low times within a One or Zero bit around 50:50
If you are referring to DC balance, that's built-in to the X-10 RF protocol as there are always an equal number of 1 and 0 bits because each of the two payload bytes is sent twice with the second copy inverted.

Otherwise, trying to keep the high and low times at 50:50 turns all 1 bits into 0 bits removing the information.
 

MFB

Senior Member
What's the advantage of using X10 to balance DC when the PICAXE rfin and rfout commands already provide Manchester modulation?
 

davehouston

New Member
I'm not sure I understand your question.

The X10 RF protocol has DC balance built-in and works with X10 devices as it is intended to do. While I'm completely new to PICAXE, on the face of it rfin/rfout cannot send/receive the X10 protocol but are limited to 8 byte packets used with NKM2401 which would seem rather limited.
 
Top