Let's Make Robots!

inter-Picaxe serial communication

AttachmentSize
08M_serial_chip0.bas871 bytes
08M_serial_chip1.bas890 bytes
08M_serial_chip2.bas735 bytes

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.

 

SerialBus_basic_setup.jpg

 

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. 

 

SerialBus.jpg

 

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.

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
DerDude's picture

I'm trying the serial communication between a 40X1 and a 08m.

With the 40X everything works fine. It's sending, pulling the line down, receiving, perfect.

But the 08m just doesn't react to the interrupt. I connected input 1 (pin6) via 330R to the data line. When I put a LED to the data line I can see how it is pulled low, but the 08m just does nothing. I used the setint 0,%00000010 command.

Does anyone has an idea?

DerDude's picture

For now I found out, that it doesn't matter if I use the interrupt for low or high signal. Both times the same behavior.

I also found out, that the whole program doesn't work correctly as soon as the controller encounters the setint command.
As soon as I delete the setint, I can perform simple checks for the inputs again. With setint it doesn't work.

I try to update my programming editor. Maybe it's a bug???

DerDude's picture

It was indeed a bug in the programming editor.

With version 5.2.11 it works.

Calculon320's picture
So how does one connect a serial line to a picaxe on a project board? The three pins on the top?
mintvelt's picture

The three pin header on top of the 28X project board connect to the hardware serial pins. I believe those are the same pins used for I2C communication, but due to the resistors on the board, I don't think you'd be able to use them for I2C. If you want to use them, use the hserin, hserout and hsersetup commands. For connection with a computer, you'll also need a MAX232 inverter chip.

For serial connection with the computer it is probably easier to use the programming cable on the jack thats on the board. 

If you want to communicate using the serial interface described in this walkthrough, have a look at Diodes and code. Also in this walkthrough. You can use any regular digital input and output. The picture shows a setup using pin11 (=input 0) for input and pin 28 (=output 7) for output. The diode is used to prevent current from flowing to the output pin when it is low. 

jklug80's picture
Serial in on a 28x1 is pin 6 and out is pin 7. Map that to your project board and your good. Those 3 pins on the project board is for i2c.
Calculon320's picture

pin 6 and 7 as in digital input 6 and 7? or the pin on the chip?

My concern is that I no longer have the 3 pins on my board (they were in the way and Rev-Ed's wonderful documentation said it was reduntant). So if there's another spot on the board that i can connect to ...

Oh wait, i just read the post below. I think that might answer the question.

Once again, thanks guys!

mintvelt's picture

Pin 6 and pin 7 are connected to the serial jack you use for uploading programs. They are not connected to anything else. The pins you'll need depend on what device is going to be connected. 

serial jack -> talk to your PC

3 pins on top -> talk to a PIC programmer 

any digital input/output -> talk to another picaxe chip. 

[edit] Oh wait. I just saw your edit. never mind .... ;) 

ViTek's picture
With CAN it can have multiple addresses along the bus.
mintvelt's picture

CAN is a serial broadcast bus just like this.

The main difference is that CAN has collision control built in. In order to do that, a device that sends a bit, reads the dataline at the same time. If one device sends a 1 while another sends a 0, all the listening devices (including the sending device) read the 0. The device that originally sent the 1 will stop sending after that.

I don't think anything like that (sending and receiving simultaniously) can be done with a PICAXE, but I've read that some PIC models have support for CAN built in. So if you're writing assembly, you'll be able to make use of that.

 BTW the setup used in this walkthrough also has multiple addresses on the bus.