Remote switch plug

steliosm

Senior Member
#1
Hello all.

I have started playing around with a remote switch plug kit I got. I've seen on the internet that there are a couple of DIY projects controlling those plugs through a uC and an RF transmitter and I though that this could make a nice Picaxe project.

After reading about the protocol and especially looking at the code at this site I had a better understanding about what I needed to implement and the correct timing I had to use. I used a 20X2 chip running at 32MHz and I was able to turn on and off the plug.

This is the code I used to switch on a plug:

Code:
'
' PicAxe remote switch controller
' Emulates the output from a PT2262 encoder chip.
'
' ver 0.1(Proof-Of-Concept), by Steliosm (steliosm@gmail.com)
' based on project rc-switch (http://code.google.com/p/rc-switch/)
'
'

' Overclock the chip 
setfreq m32

' Define the timings - each pulse should be about 300-500uS depending on the receiver.
' The following timing value seem to work OK.
symbol waitShort = 150
symbol waitLong =  3 * waitShort
symbol waitSync = 31 * waitShort

'
' Bit-bang the RF Nexa protocol
'
main:
  '
  ' This should be done in a better way :-)
  '
  for b0 = 1 to 3
    ' Group address (dip switches set at 10001)
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    gosub send0
    ' Plug address (dip switches set at 01000)
    gosub sendF
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    ' SendCommand (FF-on/F0-off)
    gosub sendF
    gosub sendF
    ' Send Sync
    gosub sendSync
  next
  ' End
end

send1:
  ' Send tri-State 1
  for b1 = 1 to 2
    high 4
    pauseus waitLong
    low 4
    pauseus waitShort
  next
return 

send0:
  ' Send tri-State 0
  for b1 = 1 to 2
    high 4
    pauseus waitShort
    low 4
    pauseus waitLong
  next
return

sendF:
  ' Send tri-State F
  high 4
  pauseus waitShort
  low 4
  pauseus waitLong
  high 4
  pauseus waitLong
  low 4
  pauseus waitShort
return

sendSync:
  ' Send sync sequence
  high 4
  pauseus waitShort
  low 4
  pauseus waitSync
return
I'm trying to make the code run at 16MHz speed by altering the pulse length (waitShort). My target is to run this code on a 08M2 chip overclocked. Any ideas about what I could do to save me a few CPU cycles on the chip and run the code a bit faster at 16MHz speed?
 

steliosm

Senior Member
#2
I'm not at home to test this concept, but is there any change that pulsout can spare a few CPU cycles?
I was thinking of using these routines to send out the bits:

Code:
send1:

  ' Send tri-State 1

  pulsout 4, waitLong

  pauseus waitShort

  pulsout 4, waitLong

  pauseus waitShort
return 

send0:
  ' Send tri-State 0

   pulsout 4, waitShort

   pauseus waitLong

   pulsout 4, waitShort

   pauseus waitLong
return

sendF:
  ' Send tri-State F

  pulsout 4, waitShort

  pauseus waitLong

  pulsout 4, waitLong

  pauseus waitShort
return

sendSync:
  ' Send sync sequence
  pulsout 4, waitShort
  pauseus waitSync
return
Is there a good soundcard based scope or logic analyser?
 

hippy

Technical Support
Staff member
#3
I don't know about soundcard based but we're very impressed by the Saleae "Logic" logic analyser - http://www.saleae.com/logic

Dropping from 32MHz to 16MHz notionally requires just halving the PAUSEUS delay. I can't see any problem using PULSOUT in this case and you could also use PULSOUT on an unused pin for the low timing as well.

You can use another PICAXE running a PULSIN to determine what the timing is for a particular pulse if you put a HIGH-PAUSEUS-LOW / PULSOUT in a test program.
 

steliosm

Senior Member
#4
Saleae logic looks very good but if I was to buy one I would prefer to eitget an opensource hardware logic probe, like the Logic Shrimp.

Now, about clocking the chip from 32MHz to 16MHz, the obvious thing would be to cut the delay values by half. It didn't work yesterday while I was testing it. I even shifted the delay values a bit up and down, but still no luck. What worries me is that the lower clock speed will increase the command execution time and so I will have to take that under consideration and fine tune the pulse delays.

The pulsin trick sounds like a good idea to test out while I'm trying to figure out what is going on and how long my commands take to execute. Thanks for the tip Hippy.
 

hippy

Technical Support
Staff member
#5
That's true; doubling the command overhead isn't necessarily compensated for by simply halving the time period. if "PAUSEUS 10" has 100us of overhead plus 100us of delay, doubling brings 200us of overhead and requires no additional delay. For "PAUSEUS 20" it at first glance seems to work; 100us plus 200us changes to 200us requiring 100us delay so that would appear to be "PAUSEUS 10", but then the 10us unit delay has increased to a 20us unit, thus "PAUSEUS 5".

At the initial speed, "PAUSEUS N" ...

T = Toverhead + ( N * Tunit )

N = ( T - Toverhead ) / Tunit

At half speed ...

T = ( Toverhead * 2 ) + ( N * Tunit * 2 )

N = ( T - ( Toverhead * 2 ) ) / ( Tunit * 2 )
 

steliosm

Senior Member
#6
Interesting maths you got there Hippy.

The good news is that I found out that my Bus Pirate device can work as a low speed (~1MHz) logic analyzer using a Sump protocol compatible client :) This speed should be able to provide me with info about what is going on in the picaxe and may be help me tune my code.

I hope to have the new 082 chips by next week so I can test my theory.
 

hippy

Technical Support
Staff member
#7
That maths ( or rather just the change in Tunit ) had me stumped for a while as to why you can't just halve ( or double ) N. I'd tripped over that myself in writing an IR remote recently and changed operating speeds. It suddenly came to me as to why when writing the answer !

Given that T, Tunit and N for a certain speed are known, it should be possible to determine Toverhead and what N would need to be for another speed. It's probably easier though to just put a scope / analyser on things and look at the timing which is what I did to tweak the values used.

Watch for value changes that go between ranges 0-1, 2-15, 15-255, 256-65535 as that can shift code alignment and alter the timing. Best to put the timing sensitive code at the start of the code and jump round it to 'poweron:' or 'main:', work on getting timing right from top to bottom.

One other tip to remember is to measure at the receiver not transmitter if you are trying to match closely what an original device ( eg, hand held remote ) puts out. For IR, a 50:50 square wave modulator to the IR LED won't usually give 50:50 at the receiver output because there's usually some delay while the AGC and filtering sorts itself out when IR first appears.
 
Last edited:

steliosm

Senior Member
#8
Good news everyone!
I managed to get the speed down to 16MHz and have the code working fine. I had to use a Logic Analyzer to get to the correct timings (+/- 10uS). Each byte has about 360uS time-frame.

The following code switch on plug with id 00100 from group 10001:

Code:
' PicAxe remote switch controller
' Emulates the output from a PT2262 encoder chip.
'
' ver 0.1(Proof-Of-Concept), by Steliosm (steliosm@gmail.com)
' based on project rc-switch (http://code.google.com/p/rc-switch/)
'
'
' Overclock the chip 
setfreq m16
#no_table


' At 8Mhz for X2 parts pauseus
symbol waitShort = 61
symbol waitLong =  183
symbol waitLongLast = 118
symbol waitShortLast = 10
symbol waitSync = 31 * waitShort

'
' Bitbang the RF protocol
' F0000F00FFF0
'
main:
for b0 = 1 to 3
  ' Group address
  gosub send0
  gosub sendF
  gosub sendF
  gosub sendF
  gosub send0
  ' Plug address
  gosub sendF
  gosub sendF
  gosub send0
  gosub sendF
  gosub sendF
  'SendCommand (FF-on/F0-off)
  gosub sendF
  gosub sendF
  ' Send Sync 
  gosub sendSync
next b0
pause 10000
goto main
' End
end

send1:
    high 4
    pauseus waitLong
    low 4
    pauseus waitShort
    high 4
    pauseus waitLong
    low 4
    pauseus waitShortLast
return 

send0:
    high 4
    pauseus waitShort
    low 4
    pauseus waitLong
    high 4
    pauseus waitShort
    low 4
    pauseus waitLongLast
return

sendF:
  high 4
  pauseus waitShort
  low 4
  pauseus waitLong
  high 4
  pauseus waitLong
  low 4
  pauseus waitShortLast
return

sendSync:
  high 4
  pauseus waitShort
  low 4
  pauseus waitSync
return
I had to figure out the gosub/return command execution delays and abstract them from the pauseus values. I used extensively the logic analyzer to test different values and get the correct ones. The next move would be to test the code on a 08m2 chip, probably next week, and of course sending serial commands to turn on/off my lights :)
 
Last edited:
#10
The one I'm using it's branded as "Elro", you can get more info about the product if you look here.
Based on the research I did on the Internet, it's a Nexa-protocol compatible remote switch. Actually, if you read this page you will see at the section Supported Wall-Plug Socket Receiver Brands that there are quite a few devices manufactured by ArcTech and are sold under different brand but all of them use the same protocol.
 
#13
Hippy, that is about what I'm thinking of doing to make it run a bit faster. Since I would like my PC to control the lights/appliances, I was thinking of using a simple 2 bytes serial protocol.
Let me explain this:

Nexa protocol: 5bits for Group ID + 5bits for Device ID + 2 bits for command (on/off) = 12bit
2bytes = 16bits

S, I can store all the data that I need in just a couple of bytes. Then, I can have my little PC application creating my 2 bytes and then have the Picaxe code shifting through the bits and calling the appropriate subroutine.

Hippy, please note that the document you're linking to refers to the protocol use for a different type of appliances/remote: The ones that do not have a 10-size dip on their back. This document could be used as a reference http://code.google.com/p/rc-switch/source/browse/trunk/RCSwitch.cpp.

From the following links you can see the signal displayed on a Logic Analyzer. I used the Bus Pirate device to capture the signal, it worked great and helped me to check the speed execution of the program. First screen shows 3 bursts of the signal originating from the Picaxe and the second screen shows the signal's 0 and F bits.

Quiz: Can you decode the signal? (Of course you can, it's written in the code in the previous post ;-) )

Image 1
Image 2
 
Last edited:
#14
I'm switching the code to shift through the values stored in the w0 variable.
This statement seems to take more than a few 10s uSecs, and it's making the whole code not to function correctly.

This is the code I'm using now. Any ides on how I could make is run a bit faster, especially the shifting through the values in the w0 variable?

Code:
main:
  ' Load the command bits into an immutable variable
  w1 = %0111011011110000
  
'
' Bitbang the RF protocol
'
transmit:
  ' Repeat the transmission 3 times
  for b10 = 1 to 3
    ' Reset the variable
    let w0 = w1
    ' Shift left the w0 values for 12 times - since we need only 12 bits of data
    for b11 = 1 to 12
      ' Read the bit0 value and then shift left the w0
      ' Debug it
      'sertxd (#bit15)
      if bit15 = 1 then
        gosub sendF
      else
        gosub send0
      endif
     ' Shift the values - this probably takes some time
     let w0 = w0 * 2
  next

  ' Send the Sync signal
  gosub sendSync
  
  ' Debug
  'sertxd (10,13)

  ' Next transmission
  next b10
  
  ' Make a small pause
  pause 5000
  ' Debug
  'sertxd (10,13)
  ' Start again
  goto main
' End
end
 
#15
After testing for a bit I concluded that shifting through the bits added quite a bit of delay in the process making the pulse length differ from each other. What I did in the end was to keep the high/delay/low/delay routines and create new routines to turn on or off the appliances using fixed calls to the send0/sendF routines. I added the code to receive the appliace ID and action (1:eek:n, 0:eek:ff) and everything worked fine.

I got the 08m2 chips yesterday and started moving the code from the 20x2 to the 08m2 chip. What I noticed was that running the 08m2 at higher speed, 16MHZ or even 32MHz, yield unstable results. The length of pulses kept changing duration. I used the logic probe to tune the delay values for the pulses but I was still getting variable pulse lengths, eg. the first high pulse from the second data burst was either 400uS or 500uS. I was able to turn on/off an appliance but the timing in the pulses tends to change by about 10uS.

I will give the 08m2 another try but I'm starting to think that the 20x2 running at 16MHz is the suitable picaxe for the work, although I only need 3 pins :)
 

hippy

Technical Support
Staff member
#16
After testing for a bit I concluded that shifting through the bits added quite a bit of delay in the process making the pulse length differ from each other.
What you perhaps need to do is move the 'send0' and 'sendF' code out of subroutines and into the IF-THEN-ELSE of the code, remove the overhead of the GOSUB-RETURN.

Not sure why you'd see different timings; are those consistent or random variations ? If consistent it may be that you are using the same timing constants in a number of places whereas they may need to be individually tweaked to cater for differences of time through various code paths.
 
#17
Hello hippy.
I will post the code as soon as I get home. Moving the send0/sendF function under the IF/THEN/ELSE will probably not be that easy. I'll post the code and we can see if this is possible.

They seem to be random. I tune a specific pulse and another one seems to change. I actually have to tune:
- the pulse: T (~350uS)
- the long pulse at the end of a bit: 3 x T - (time-to-execute-commands)
- the pulse at the end of a bit: T - (time-to-execute-commands)

I'll do a bit more testing with the probe before going back to 20x2.
 
#18
This is the code now:

Code:
'
' PicAxe remote switch control application
'
' ver 0.4, Stelios M.
' based on project rc-switch (http://code.google.com/p/rc-switch/)
'
'

#no_data
#picaxe 08m2

setfreq m16

' Define the timers
symbol waitShort = 61
symbol waitLong =  3 * waitShort
symbol waitLongLast = 90
symbol waitShortLast = 10
symbol waitSync = 31 * waitShort

'
' Read the data from the serial (device id: 1..4, command: 1(on), 0 (off) )
'
main:
  ' Readthe device ID and the action (on/off) from the serial port
  serin 3, t4800_16, #b10, #b11
  ' Check if the values are valid
  if b10 < 1 or b10 > 4 then
    'serout 2, t4800_16, ("Error in device ID", 10,13)
    goto main
  endif
  if b11 > 1 then
    'serout 2, t4800_16, ("Error in command", 10,13)
    goto main
  endif
  ' Call the apropriate subroutine
  if b10 = 1 then
    branch b11, (turn_1_off, turn_1_on)
  elseif b10 = 2 then
    branch b11, (turn_2_off, turn_2_on)
  elseif b10 = 3 then
    branch b11, (turn_3_off, turn_3_on)
  elseif b10 = 4 then
    branch b11, (turn_4_off, turn_4_on)    
  endif
  ' Go back to start
  goto main
end


turn_1_on:
  ' Switch device 1 On
  'serout 2, t4800_16, ("Switching device 1 On", 10,13)
  for b0 = 1 to 3
    ' Group address
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    gosub send0
    ' Plug address
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    gosub sendF
    'SendCommand (FF-on/F0-off)
    gosub sendF
    gosub sendF
    ' Send Sync 
    gosub sendSync
  next b0
  ' Go back to start
  goto main

turn_1_off:
  ' Switch device 1 Off
  'serout 2, t4800_16, ("Switching device 1 Off", 10,13)
  for b0 = 1 to 3
    ' Group address
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    gosub send0
    ' Plug address
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    gosub sendF
    'SendCommand (FF-on/F0-off)
    gosub sendF
    gosub send0
    ' Send Sync 
    gosub sendSync
  next b0
  ' Go back to start
  goto main

turn_2_on:
  ' Switch device 2 On
  'serout 2, t4800_16, ("Switching device 2 On", 10,13)
  for b0 = 1 to 3
    ' Group address
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    gosub send0
    ' Plug address
    gosub sendF
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    'SendCommand (FF-on/F0-off)
    gosub sendF
    gosub sendF
    ' Send Sync 
    gosub sendSync
  next b0
  ' Go back to start
  goto main

turn_2_off:
  ' Switch device 2 Off
  'serout 2, t4800_16, ("Switching device 2 Off", 10,13)
  for b0 = 1 to 3
    ' Group address
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    gosub send0
    ' Plug address
    gosub sendF
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    'SendCommand (FF-on/F0-off)
    gosub sendF
    gosub send0
    ' Send Sync 
    gosub sendSync
  next b0
  ' Go back to start
  goto main

turn_3_on:
  ' Switch device 3 On
  'serout 2, t4800_16, ("Switching device 3 On", 10,13)
  for b0 = 1 to 3
    ' Group address
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    gosub send0
    ' Plug address
    gosub sendF
    gosub sendF
    gosub send0
    gosub sendF
    gosub sendF
    'SendCommand (FF-on/F0-off)
    gosub sendF
    gosub sendF
    ' Send Sync 
    gosub sendSync
  next b0
  ' Go back to start
  goto main

turn_3_off:
  ' Switch device 3 Off
  'serout 2, t4800_16, ("Switching device 3 Off", 10,13)
  for b0 = 1 to 3
    ' Group address
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    gosub send0
    ' Plug address
    gosub sendF
    gosub sendF
    gosub send0
    gosub sendF
    gosub sendF
    'SendCommand (FF-on/F0-off)
    gosub sendF
    gosub send0
    ' Send Sync
    gosub sendSync
  next b0
  ' Go back to start
  goto main

turn_4_on:
  ' Switch device 4 On
  'serout 2, t4800_16, ("Switching device 4 On", 10,13)
  for b0 = 1 to 3
    ' Group address
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    gosub send0
    ' Plug address
    gosub sendF
    gosub sendF
    gosub sendF
    gosub send0
    gosub sendF
    'SendCommand (FF-on/F0-off)
    gosub sendF
    gosub sendF
    ' Send Sync 
    gosub sendSync
  next b0
  ' Go back to start
  goto main

turn_4_off:
  ' Switch device 4 Off
  'serout 2, t4800_16, ("Switching device 4 Off", 10,13)
  for b0 = 1 to 3
    ' Group address
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    gosub send0
    ' Plug address
    gosub sendF
    gosub sendF
    gosub sendF
    gosub send0
    gosub sendF
    'SendCommand (FF-on/F0-off)
    gosub sendF
    gosub send0
    ' Send Sync 
    gosub sendSync
  next b0
  ' Go back to start
  goto main


send0:
  '
  ' Send a tri-State 0 bit
  '
  high 4
  pauseus waitShort
  low 4
  pauseus waitLong
  high 4
  pauseus waitShort
  low 4
  pauseus waitLongLast
return

sendF:
  '
  ' Send a tri-State F bit
  '
  high 4
  pauseus waitShort
  low 4
  pauseus waitLong
  high 4
  pauseus waitLong
  low 4
  pauseus waitShortLast
return

sendSync:
  '
  ' Send the sync sequence
  '
  high 4
  pauseus waitShort
  low 4
  pauseus waitSync
return
 

hippy

Technical Support
Staff member
#19
There is some jitter in pulse times and I'd guess that was 'time' ticking plus other events internally that may cause the firmware to do something slightly different, timer overflows etc. There may also be some variation in all commands which depend on what the values actually used are.

I tested my 08M2 and the attached code seemed quite stable and any receiver should tolerate a few microseconds of jitter. I used a 300us 'T' so you'd have to tweak that to get it to match what you want but should give a good foundation to work on. I didn't totally fine tune to exact time. Timing may differ anyway depending on temperature, voltage, chip, day of week, phase of moon :)

Note the 'w0 = w0 * 2' was moved so it always fits in a long period, minimises the time after a 1 ('X') to when next bit is sent. I also use 'bit12' as msb ( after shifting / multiplying by two ). That means you don't need any lsb padding when setting 'w0'. I don't generate a sync but should be easy enough to add.

Code:
#Picaxe 08M2
#No_Data

;       ___           ___
; 0 => |   |_________|   |_________
;
;      |300|   900   |300|   900   |

;       ___           _________
; 1 => |   |_________|         |___
;
;      |300|   900   |   900   |300|

Goto PowerOnReset

SendW0:
  For b11 = 1 to 12
    Toggle 4 : PauseUs 154
    Toggle 4 : PauseUs 545
    w0 = w0 * 2
    Toggle 4
    If bit12 = 0 then
      PauseUs 81
      Toggle 4
      PauseUs 400
    Else
      PauseUs 515
      Toggle 4
      PauseUs 12
    End If
  Next
  Return

PowerOnReset:
  SetFreq M32
  DisableTime
  Low 4
  Do
    w0 = %001100110011
    Gosub SendW0
    Pause 1000
  Loop
 
Last edited:
#20
hippy, thanks for the code and the tips. Moving the shifting code (w0 = w0 * 2) in side the long pulse is something I couldn't have thought of.
I was hoping on running the picaxe at 16MHz and not pushing it at 32MHz, but it didn't work that way. Too much tuning, flashing, probing, analyzing those few days :) Hippy, you used pulsein to count the pulse lengths or did you used you logic probe?
Everything seems to work OK. With the following code I can control all four devices for the group "0FFF0".

Note: Pulse duration is about 400uS

Code:
'
' PicAxe remote switch application
' Emulates PT2262 encoder chip.
'
' ver 0.4, Stelios M.
' based on project rc-switch (http://code.google.com/p/rc-switch/)
'
'

#no_data
#picaxe 08m2

setfreq m32

' Define the timers
symbol waitShort = 250
symbol waitLong =  900
symbol waitLongLast = 520
symbol waitShortLast = 1
symbol waitSync = 31 * waitShort

'
' Read the data from the serial
'
main:
  '
  ' Readthe device ID and the action (on/off) from the serial port
  serin 3, t4800_32, #b10, #b11
  ' Check if the values are valid
  if b10 < 1 or b10 > 4 then
    serout 2, t4800_32, ("Error in device ID", 10,13)
    goto main
  endif
  if b11 > 1 then
    serout 2, t4800_32, ("Error in command", 10,13)
    goto main
  endif
  ' Call the apropriate subroutine
  if b10 = 1 then
    branch b11, (turn_1_off, turn_1_on)
  elseif b10 = 2 then
    branch b11, (turn_2_off, turn_2_on)
  elseif b10 = 3 then
    branch b11, (turn_3_off, turn_3_on)
  elseif b10 = 4 then
    branch b11, (turn_4_off, turn_4_on)    
  endif
  ' Go back to start
  goto main
end


turn_1_on:
  ' Switch device 1 On
  serout 2, t4800_32, ("Switching device 1 On", 10,13)
  for b0 = 1 to 3
    ' Group address
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    gosub send0
    ' Plug address
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    gosub sendF
    'SendCommand (FF-on/F0-off)
    gosub sendF
    gosub sendF
    ' Send Sync 
    gosub sendSync
  next b0
  ' Go back to start
  goto main

turn_1_off:
  ' Switch device 1 Off
  serout 2, t4800_32, ("Switching device 1 Off", 10,13)
  for b0 = 1 to 3
    ' Group address
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    gosub send0
    ' Plug address
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    gosub sendF
    'SendCommand (FF-on/F0-off)
    gosub sendF
    gosub send0
    ' Send Sync 
    gosub sendSync
  next b0
  ' Go back to start
  goto main

turn_2_on:
  ' Switch device 2 On
  serout 2, t4800_32, ("Switching device 2 On", 10,13)
  for b0 = 1 to 3
    ' Group address
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    gosub send0
    ' Plug address
    gosub sendF
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    'SendCommand (FF-on/F0-off)
    gosub sendF
    gosub sendF
    ' Send Sync 
    gosub sendSync
  next b0
  ' Go back to start
  goto main

turn_2_off:
  ' Switch device 2 Off
  serout 2, t4800_32, ("Switching device 2 Off", 10,13)
  for b0 = 1 to 3
    ' Group address
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    gosub send0
    ' Plug address
    gosub sendF
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    'SendCommand (FF-on/F0-off)
    gosub sendF
    gosub send0
    ' Send Sync 
    gosub sendSync
  next b0
  ' Go back to start
  goto main

turn_3_on:
  ' Switch device 3 On
  serout 2, t4800_32, ("Switching device 3 On", 10,13)
  for b0 = 1 to 3
    ' Group address
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    gosub send0
    ' Plug address
    gosub sendF
    gosub sendF
    gosub send0
    gosub sendF
    gosub sendF
    'SendCommand (FF-on/F0-off)
    gosub sendF
    gosub sendF
    ' Send Sync 
    gosub sendSync
  next b0
  ' Go back to start
  goto main

turn_3_off:
  ' Switch device 3 Off
  serout 2, t4800_32, ("Switching device 3 Off", 10,13)
  for b0 = 1 to 3
    ' Group address
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    gosub send0
    ' Plug address
    gosub sendF
    gosub sendF
    gosub send0
    gosub sendF
    gosub sendF
    'SendCommand (FF-on/F0-off)
    gosub sendF
    gosub send0
    ' Send Sync
    gosub sendSync
  next b0
  ' Go back to start
  goto main

turn_4_on:
  ' Switch device 4 On
  serout 2, t4800_32, ("Switching device 4 On", 10,13)
  for b0 = 1 to 3
    ' Group address
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    gosub send0
    ' Plug address
    gosub sendF
    gosub sendF
    gosub sendF
    gosub send0
    gosub sendF
    'SendCommand (FF-on/F0-off)
    gosub sendF
    gosub sendF
    ' Send Sync 
    gosub sendSync
  next b0
  ' Go back to start
  goto main

turn_4_off:
  ' Switch device 4 Off
  serout 2, t4800_32, ("Switching device 4 Off", 10,13)
  for b0 = 1 to 3
    ' Group address
    gosub send0
    gosub sendF
    gosub sendF
    gosub sendF
    gosub send0
    ' Plug address
    gosub sendF
    gosub sendF
    gosub sendF
    gosub send0
    gosub sendF
    'SendCommand (FF-on/F0-off)
    gosub sendF
    gosub send0
    ' Send Sync 
    gosub sendSync
  next b0
  ' Go back to start
  goto main


send0:
  '
  ' Send a tri-State 0 bit
  '
  high 4
  pauseus waitShort
  low 4
  pauseus waitLong
  high 4
  pauseus waitShort
  low 4
  pauseus waitLongLast
return

sendF:
  '
  ' Send a tri-State F bit
  '
  high 4
  pauseus waitShort
  low 4
  pauseus waitLong
  high 4
  pauseus waitLong
  low 4
  pauseus waitShortLast
return

sendSync:
  '
  ' Send the sync sequence
  '
  high 4
  pauseus waitShort
  low 4
  pauseus waitSync
return
 

hippy

Technical Support
Staff member
#21
I was hoping on running the picaxe at 16MHz and not pushing it at 32MHz, but it didn't work that way.
It's always a challenge with high-speed bit-banging and finding the ideal balance between small code size needing loops but faster execution against slower speeds needing in-lining and more code.


Hippy, you used pulsein to count the pulse lengths or did you used you logic probe?
Logic analyser. It's simple to just put the mouse within a pulse and read off its time and you can work with all pulses of varying length at a time, though easiest to start with fewer pulses and build it up.

It can be a laborious process getting it spot-on, but you can usually hit 5% or better quite easily and that's often good enough. "Binary chop" is the secret here; for example try PAUSEUS 100 and 400 measure the times, find the middle number value ( 300 here ), then you know if the time you need is between 100-300 or 300-500, try the number half way ( 200 or 400 ), repeat and it quickly closes in.
 
#22
I was playing around with the transmitter yesterday, it seems to work fine. All four appliances were turning on and off without problems or without having to re-send the command. Time to make a small PCB to put it all together now.

hippy thank you for your help and the tips.
 
Top