Sometimes it is necessary to send data between two picaxe chips but not have the chips hang forever waiting for a serin. This code sends a packet of 11 bytes. Receiving picaxes can poll one line or any number of input lines, so long as the status of the lines is tested at least 6 times a second. In general terms;
main:
gosub testinputs
do other things
possibly a pause
goto main
The code uses pulsin and pulsout - and sends a low bit as a short pulse and a high bit as a long pulse.
This code was written for the 18X but works on any sort of picaxe. The order of the bytes is not important - so long as the order is the same for the receiver and transmitter!
To send a packet, use
It may also be useful to translate serial data to pulsewidth data - eg when interfacing to a PC. An 08 can do the job - it sits and waits for data from the PC, and then forwards it on in pulswidth format to another chip, eg an 18X. (The 18X can send data directly back to the PC using serout.)
For talking to a PC a MAX232 is used, and this inverts the signal so it is usually high coming into the picaxe. Hence serin T2400 is used. For talking via radio modules where the resting state is low, a serin N2400 is used.
main:
gosub testinputs
do other things
possibly a pause
goto main
The code uses pulsin and pulsout - and sends a low bit as a short pulse and a high bit as a long pulse.
This code was written for the 18X but works on any sort of picaxe. The order of the bytes is not important - so long as the order is the same for the receiver and transmitter!
Code:
Get_Packet:' test for packets arriving on pins 6,2, and 1 (example for an 18X, can change for other picaxe chips) and pin 7 from radio 08
let b7=pins' read pins
b7=b7 and %11000110' mask off other input pins so only look at pins that expecting an input from
select case b7' can't convert directly to a number because small chance two lines might be high at the same time
case %00000010
b1=1' change pins binary to pin number
case %00000100
b1=2
case %01000000
b1=6
case %10000000
b1=7 ' from radio 08 buffer picaxe
else
b1=0' zero if all tested input pins are zero
endselect
if b1=0 then goto end_packet' no packet so exit subroutine
' now know which pin to read
pause 300' pin goes high for 250ms and low for 300ms so if it was high, then if wait 300ms then it must be low.
b6=210' scratchpad location to store
for b4=1 to 11' count 11 bytes
b7=1' value to add
b0=0' start as zero, read LSB in first
for b5=1 to 8' count 8 bits, build byte b0
pulsin b1,1,w1' read pulse
if w1>100 then
b0=b0+b7 ' assume if <100 then is a zero - a checksum on this packet sorts out any errors
endif
if w1=0 then goto end_packet' should be 73-77 and 148 to 152. Zero means timeout.
b7=b7*2' value to add multiply by 2
next b5
poke b6,b0' store the byte
b6=b6+1' increment the scratchpad location
next b4
'now have the numbers in 210 to 220
peek 210,b12
peek 211,b13
peek 212,b2
peek 213,b3
peek 214,b4
peek 215,b5
peek 216,b6
peek 217,b7
peek 218,b8
peek 219,b10
peek 220,b11
end_packet: return
Code:
Send_Packet:' sends data packout out using pwm data protocol. To pin number in b5 eg on an 18X can be pin 0 to 7
' 11 bytes, scratchpad 210 to 220
' this can't do radio, as random noise will start pwm and then will hang for 0.65535 seconds and miss the data packet
' so if it is not radio, then no need to worry about making the high and low periods the same
' we are storing 11 bytes - pauses between each one so can store
low b5' so definitely low
pulsout b5,25000' wakeup pulse 250ms
pause 300' wait 300ms with line low (must be shorter than 0.65535 secs). 300ms is a good compromise.
for b0=210 to 220' scratchpad locations - 11 bytes
peek b0,b1' get the byte
for b2=1 to 8
b3=b1 and %00000001' test the right bit
if b3=0 then
pulsout b5,75' send a 'low' pulse
else
pulsout b5,150' send a 'high' pulse
endif
pause 20' wait a bit - time for getpacket to store bytes, do calcs etc. 20 is reliable. 10 is mostly reliable
b1=b1/2' shift right
next b2
next b0
return
Code:
' This code uses an 08 chip but will also run on an 08M. (08 chips are cheaper)
' It is identical to the radio receiver except that the radio receiver has opposite polarity on the serin.
main:serin 2,T2400,("ID"),b12,b13,b2,b3,b4,b5,b6,b7,b8,b10,b11
low 1' start low
pulsout 1,25000' wakeup pulse
pause 300' pause low
b0=b12
gosub send08
b0=b13
gosub send08
b0=b2
gosub send08
b0=b3
gosub send08
b0=b4
gosub send08
b0=b5
gosub send08
b0=b6
gosub send08
b0=b7
gosub send08
b0=b8
gosub send08
b0=b10
gosub send08
b0=b11
gosub send08
goto main
Send08:' send byte in b0 to pin 1.Uses b0, b1 and b9 as these are unused in the data packet
for b1=1 to 8
b9=b0 and %00000001 ' test the right bit
if b9=0 then
pulsout 1,75 ' send a low pulse
else
pulsout 1,150
endif
pause 20' wait a bit
b0=b0/2
next b1
return
Last edited: