Although this technique cannot be used for a PICAXE receiving data from a PC or
any other device which uses standard RS232 protocols, it is a major benefit when
connecting two or more PICAXE's together, where it is not desirable to have
additional flow control or handshaking lines, or where completely asynchronous
operation of the two devices is required.The technique can be used with any PICAXE device which is transmitting, and
although primarily designed for use with PICAXE receivers which support the use
of interrupts, the scheme can be modified for use by those which don't.
Serial Communications
This article examines uni-directional, asynchronous serial communications
between PICAXE's. Initially, we will look at communications between just two
PICAXE's with the transmitter sending through Output Pin 0 and a receiver,
reading through Input Pin 0. The software examples shown will need to be
modified if other pins are used, or a baud rate of other than 2400 is required.
At the end of the article, we will look at the situation of connecting multiple
PICAXE's together.
The configuration used for the examples given here is as follows ...
Transmitter Receiver
.---------. .---------.
| | | |
| Out 0 |-------->| In 0 |
| | | |
`----.----' `----.----'
| |
--------^-------------------^-------- 0V
If we observe the transmission line when sending data using an Nxxxx baud
rate we will see something like the following; a normally low transmission line
with a 10-bit data byte packet sent, consisting of a start bit (S), 8 data
bits ( lsb sent first ), and a final stop bit (E) ...
.---. .---. .-------. .---.
| | | | | | | |
----------------' `-------' `---' `---' `-----------
| | | | | | | | | | |
S 0 1 2 3 4 5 6 7 E
It would appear possible to use the rising edge of the start bit to indicate to
the receiver that a data byte is being transmitted, and on many micro controller
devices this is often done, however the PICAXE is relatively slow in execution,
and by the time it has seen the rising edge, responded to it, and has started
reading the data sent, it may have missed the data transmission or only read
part of it ...
.---. .---. .-------. .---.
| | | | | | | |
----------------' `-------' `---' `---' `-----------
| | | | | | | | | | |
S 0 1 2 3 4 5 6 7 E
|- Responds ->|
|----- Reads the data byte ----->|
The key to having a PICAXE respond to an incoming data transmission is to tell
it one is due to arrive, giving it enough time to prepare to receive the data in
its entirety ...
.---. .---. .-------. .---.
| | | | | | | |
----------------' `-------' `---' `---' `-----------
| | | | | | | | | | | |
S 0 1 2 3 4 5 6 7 E
|- Responds ->|
|-------- Reads the data byte --------->|
The challenge is in creating a mechanism which can indicate to the receiver that
a transmission is due, which doesn't require the use of any additional control
signals.
Creating an Interrupt
The easiest way to tell a PICAXE that some data transmission was imminent would
be to put a pulse on the transmission line sometime before the actual data
transmission commences ...
.---. .---. .---. .-------. .---.
| | | | | | | | | |
---' `--------' `-------' `---' `---' `-----------
| | | | | | | | | | |
IRQ S 0 1 2 3 4 5 6 7 E
The pulse can then be used to indicate that a serial byte is about to be
transmitted, and can be used as an interrupt request; 'IRQ'. Because the
transmission line is low before the PICAXE is ready to execute a SERIN command,
such a command can be used as it normally would be.
If the receiver's interrupt handler is looking for the rising edge of the
pulse, it means that the transmitter must ensure that the pulse is long enough
to be detected, and the receiver must wait for the pulse to return to a low
level before reading the incoming character. This adds all sorts of timing
complications and delays which can be alleviated by having the receiver use the
falling edge of the pulse to initiate the interrupt.
The PICAXE cannot interrupt on rising or falling edges, only on high or low
states, so care must be taken to ensure that the low level before the interrupt
pulse doesn't generate the interrupt itself. This can be most easily achieved by
extending the pulse so it commences immediately after a transmission has
occurred, with the pulse being brought low just prior to a transmission ...
-------. .---. .---. .-------. .---. .---
| | | | | | | | | |
`--------' `-------' `---' `---' `-------'
| | | | | | | | | | | |
IRQ S 0 1 2 3 4 5 6 7 E
Because the transmitter starts the pulse, by setting the output line high as
soon as it has transmitted a data byte, it is almost a certainty that the
receiver is busy handling the received byte while that happens, and the
transmission line will be back at a high level when it comes to the receiver
re-enabling the interrupt ready to detect the next falling edge, and the state
of the input line need not be checked before re-enabling interrupts.
In order to provide for the first falling edge of the interrupt triggering pulse
to be seen, it is necessary for the transmitter to set the transmission line to
a high state as soon as it is reset.
Suitable software to handle such interrupt driven serial communications is shown
below ...
Transmitter Receiver
PowerOnReset: PowerOnReset:
HIGH 0 SETINT 0,1
MainLoop: MainLoop:
GOTO MainLoop
LOW 0
PAUSE 20 Interrupt:
SEROUT 0,N2400,(b0)
HIGH 0 SERIN 0,N2400,b0
GOSUB HandleReceivedData
PAUSE 1000 SETINT 0,1
GOTO MainLoop RETURN
Note that the 'SETINT 0,1' commands ensure the interrupt is generated when
Input Pin 0 is low.
Although this an entirely workable solution to creating interrupt driven serial
interfaces, it is not the most suitable and does have its inherent problems.
Improving the Interface
As described previously, any serial data we transmit using an Nxxxx
baud rate, requires that the transmission line is held high, brought low just
prior to transmission, transmission occurs, and the transmission line is then
returned to a high level ...
-------. .---. .---. .-------. .---. .---
| | | | | | | | | |
`--------' `-------' `---' `---' `-------'
| | | | | | | | | | | |
IRQ S 0 1 2 3 4 5 6 7 E
A high state of an output line is not the default situation when a PICAXE is
powered up and it is therefore necessary to force the transmission line high
in the early stages of the program.
While this will work, a transmission line being set low when the PICAXE is
reset or when a program is downloaded will indicate to the receiving
PICAXE that data is being transmitted when it isn't. This will cause the
receiver to interrupt, expecting to receive a transmission, but it will then
have to wait until some serial data is actually sent, which can have very
adverse effects on the program running on the receiver.
The ideal solution would be to keep the transmission line low, and use a low to
high transition to signal an interrupt. If the transmission line is brought high
then the start bit of the serial data itself needs to bring it low. This means
inverting the start bit, and ( to pre-empt the full solution ) inverting the
rest of the transmission ...
.--------. .-------. .---. .---. .-------.
| | | | | | | | | |
-------' `---' `---' `-------' `---' `---
| | | | | | | | | | | |
IRQ S 0 1 2 3 4 5 6 7 E
It can be observed that this transmission is the complete inverse of the one
shown earlier. Conveniently, using a Txxxx baud rate, allows an entirely
inverted serial transmission to be received, which means the code required is
not very different to that described earlier, but simpler and more reliable in
operation when a Reset or program download occurs.
Another advantage of this scheme, with the transmission line kept normally low,
is that data transmission can be monitored by using a simple LED and a 1K8
current limiting resistor between the transmission line and 0V; the LED will
briefly pulse when data is transmitted, and remain off otherwise.
The final solution which is recommended for use is as follows ...
Transmitter Receiver
PowerOnReset: PowerOnReset:
MainLoop: SETINT 1,1
HIGH 0 MainLoop:
PAUSE 20 GOTO MainLoop
SEROUT 0,T2400,(b0)
LOW 0 Interrupt:
PAUSE 1000 SERIN 0,T2400,b0
GOTO MainLoop GOSUB HandleReceivedData
SETINT 1,1
RETURN
Note that the 'SETINT 1,1' commands ensure the interrupt is generated when
Input Pin 0 is high.
The 'PAUSE 20' time after the 'HIGH 0' has been arbitrarily chosen, and can be
reduced by experimentation. Its length really depends upon the operating speed
of the receiving PICAXE and how quickly it responds to an interrupt request.
The transmitter must allow the receiver to have handled the interrupt request
and be ready to receive a transmission before commencing it.
As with all PICAXE serial communications, the receiver will only receive the
data sent, and without corruption, if the receiver is ready to receive the
transmission when it is commenced.
It is therefore necessary to add appropriate delays between transmissions or
to implement some other forms of handshaking using hardware control lines, but
multiple data byte transmissions can be sent and received using a single
interrupt providing both the SEROUT and SERIN send and receive the same number
of bytes.
Multiple PICAXE's
As the mechanism described above works for communication between two PICAXE's it
will also work between a single PICAXE communicating with any number of others.
The only requirement as always is that data cannot be sent to a PICAXE quicker
than it can process it, or before it is ready to respond to a further
interrupt.When a number of PICAXE's wish to communicate with another, single, PICAXE the
issue becomes more complicated.
Whether the PICAXE's use a shared communications line, or single lines, the
receiver can only receive from one PICAXE at a time, and while doing that any
transmissions from other PICAXE's will be lost or corrupted.
The only option is to use some means of arbitration so that only one PICAXE is
able to transmit at a time, and which provides a mechanism to ensure that a
transmission isn't sent before the receiver is ready for one.
Such arbitration mechanisms are beyond the scope of this article but could be
created by a shared active-low 'busy' line which each PICAXE monitors and can
pull low when it needs to send data, but detecting collisions of request can
be hard to do and time consuming. A better solution is to use dedicated hardware
or even another PICAXE to examine requests to allow transmission to proceed with
the arbitrating device handing out permission to do so.
It should be noted that the improved interface describe above ( using
Txxxx baud rates ), allows any number of PICAXE's can have their
transmission line outputs combined using simple diode-mixing to connect to one
or more PICAXE receivers ...
.---------------. | | | | .---------------.
| | | |\ | | | | | |
| Digital Out |---|----| >|----{ }---|---| Digital In |
| | | |/ | | | | | |
| 0v |---{ 1N4148 | | }---| 0v |
| | | | | | | |
`---------------' | | | | `---------------'
| | | |
.---------------. | | | | .---------------.
| | | |\ | | | | | |
| Digital Out |---|----| >|----^----.----^---|---| Digital In |
| | | |/ | _|_ | | |
| 0v |---{ 1N4148 | | }---| 0v |
| | | ?K | | | | |
`---------------' | | | | `---------------'
| `-.-' |
| | |
--^-----------------^--------^-- 0v
It is also possible to create a 'multi-drop' network, where every PICAXE can
communicate with every other using a single common line ...
.---------------. | | | | .---------------.
| Digital In |---|------------{ }------------|---| Digital In |
| | | |\ | | | | /| | | |
| Digital Out |---|----| >|----{ }----|< |----|---| Digital Out |
| | | |/ | | | | \| | | |
| 0v |---{ 1N4148 | | 1N4148 }---| 0v |
| | | | | | | |
`---------------' | | | | `---------------'
| | | |
.---------------. | | | | .---------------.
| | | | | | | |
| Digital In |---|------------{ }------------|---| Digital In |
| | | |\ | | | | /| | | |
| Digital Out |---|----| >|----^----.----^----|< |----|---| Digital Out |
| | | |/ | _|_ | \| | | |
| 0v |---{ 1N4148 | | 1N4148 }---| 0v |
| | | ?K | | | | |
`---------------' | | | | `---------------'
| `-.-' |
| | |
--^-----------------^-----------------^-- 0v
With multiple PICAXE communications, using interrupt driven serial
transmissions, very powerful and complex, but simple to use, configurations can
be created.