08M_serial_chip0.bas (871Bytes)
08M_serial_chip1.bas (890Bytes)
08M_serial_chip2.bas (735Bytes)
Picaxe serial bus
This walkthrough shows you how to make multiple picaxe chips talk to each other using 1 line. This works for all picaxe models but I only used the 08M in my test.
basic setup : 08M with flashing LED
This is the basic setup for each of the 3 chips. I wont bother with the serial connection to the PC because I removed the serial socket from the breadboard after the programming.
The picaxe 08M needs V and GND and a pull down resistor for the serial in (of the PC connection). To show that the chip is working, it flashes an LED every half second or so.
symbol LED = 2
symbol blinkspeed=w0
blinkspeed = 500
main:
high LED
pause blinkspeed
low LED
pause blinkspeed
goto main
Receiving a message on the serial bus
We want chip 0 to be able to receive a command that changes the speed of the flashing LED. This is done with the serin command on pin 4.
If you issue a serin command everything the picaxe is doing in the background stops. What’s worse is that the 08M will wait for ever to receive the data. There is no way for the command to timeout and resume the LED flashing. So we need to know when to expect some data.
The data-line is pulled high with a 22K resistor. We set an interrupt on pin4 the triggers when pin4 detects that the line is being pulled low, indicating that another picaxe wants to talk.
setint 0,%00010000 'interrupt on pin4 when low
(obviously: i left the V, GND and LED stuff from the basic setup out of the picture. Top one is chip0, bottom one chip2)
When the interrupt occurs, the serin command is fired. It waits for an escape code (27) to prevent it from misreading a message by starting at the wrong byte.
The message itself is 3 bytes: the number of the chip the message is for (in this case 0,1 or 2) followed by two bytes that make up a word variable indicating the new blinkspeed.
interrupt:
' someone wants to talk
serin serpin,N2400,(27),seraddr, b4,b5 ‘w2 = b5,b4
if seraddr=chipid or seraddr=255 then 'they are talking to us!
blinkspeed = w2
end if
setint 0,%00010000 'interrupt on pin4 when low
return
All messages are read, but only if it is intended for this chip, will the blinkspeed be set.
If you look at the condition in this code sample, you see that it will also act on the message if it is addressed to 255. This way, a sending chip can address all picaxes on the line in one message (broadcast). After reading the message, we set the interrupt again and return to where we left of.
Sending a message
A chip that wants to send a message has to pull down the line by setting pin 4 low. Before it does that, it turns the interrupt off to prevent the picaxe to wait for its own message. then it starts a loop waiting for the line to be high. This is just to make sure that if another chip pulled the line low, this chip will not start sending until the line is cleared.
Pin4 is renamed to talkbutton in this code: like the button on a walkie-talkie.
talk:
setint off
do: pause 1: loop until talkbutton=1
if talkbutton=1 then
low serpin
pause 50
serout serpin, N2400,(27,seraddr,b4,b5)
endif
input serpin
setint 0,%00010000 'interrupt on pin4 when low
return
using 2 pins (for non 08M picaxes)
Chip2 in this setup is configured differently. It uses two pins instead of one. Pin4 is now just an output pin. It is tied to the dataline with a 4K7 resistor and is set to high all the time, unless it wants to talk.
Pin1 is used as an input and works just like on the other 2 chips. (please note that in the drawing, I swapped the function of pin1 and pin4)
If this setup is used, the 22K pullup resistor isn’t needed but I left it there in case I wanted to remove chip2 from the circuit.
Also, and this is important, this setup requires a fixed delay on setting the interrupts on all the chips. Because output pins are low by default, any non-08M picaxe will pull the line low for a short while when starting up. The delay prevents the other chips to fire the interrupt on startup and wait for a message that will not come. Another way to circumvent that is to send a dummy message from the non-08M picaxe after startup.
code samples
In the attached code samples, chip 0 blinks and receives new blinkspeeds. If the blinkspeed is greater then 500 (half a second) if sets the blinkspeed of chip1 and chip2 to 75 (very fast)
chip1 blinks 8 times and then increases the blinkspeed (slowing down the blinking) and sends the new speed to chip0
chip2 waits for 30 seconds with the LED on. Then tells chip1 to set the speed to 300 and sets its own blinkspeed to half a second.
If you run this code you’ll see chip2 waiting with the LED on.
LED0 and LED1 going through a cycle where LED1 blinks slower and slower with LED0 following behind. Until the blinkspeed is to slow and chip0 sets the speed of chip1 to 75.
After 30 seconds, chip2 joins the blinking but without changing speed until chip0 tells it to
some remarks / ideas / todos
- The serial bus might be configured with the data line pulled low by default instead of high in order to suit the picaxe 28 board. On that board the inputs are connected to the ground with a 10K resistor. That will also solve the problem of the line being pulled into "talkmode" by the default low of an outpunt pin.
- In the talk routine there is a 50ms pause to wait for all the chips on the line to start listening. 50ms is a very long time in processing terms so this delay could be made a lot shorter. I'd say 1 or 2 ms will still be on the safe side.
- The protocol should be expanded with a sender address.
- (crazy!) make a picaxe 28X1 relay messages from a 08M to I2C devices.