This code is experimental--- it could cause your Fluke to need to be re-programmed. Only try this firmware if you can upgrade the fluke over the serial port and cable (i.e. you have an external power connector and serial cable). It seems ok, but the firmware has been modified substantially and the over-the-air upgrade procedure could be affected.
Fluke firmware 2.8.1 and myro 2.8.15 add support for sending and receiving infrared messages from one robot to another. By default, the fluke uses all three IR emitters to transmit.
The main Myro API calls are:
- getIRMessage() - returns a string of the last message received, and clears the buffer for the next message.
- sendIRMessage(msg) - broadcasts a string (you can receive your own messages, nice for network collision detection)
To configure the communication routines:
- setIRPower(value) - was already there, but now even more useful since this changes your communication distance. For most communication, you should set this 255 (the maximum range).
- setCommunicateLeft(on=True) - enables (disables) the left IR emitter for transmission
- setCommunicateCenter(on=True) - enables (disables) the center IR emitter for transmission
- setCommunicateRight(on=True) - enables (disables) the right IR emitter for transmission
- setCommunicateAll(on=True) - enables (disables) all the IR emitters for transmission
A Robot Communication Example
# robot A from myro import * init() setIRPower(255) #set IR power to maximum sendIRMessage("Hello Robot B")
# robot B from myro import * while timeRemaining(15): msg = getIRMessage() if msg: print msg
An Obstacle Detection Example
from myro import * init() setIRPower(140) #set IR power low enough to only get the message as a reflection off an obstacle while timeRemaining(15): sendIRMessage("Ping") msg = getIRMessage() if msg == "Ping": print "Obstacle!" else: print "No obstacle detected"
Underneath the Hood
The rest of this page describes the low-level details of the IR communication interface.
The infrared protocol that is used by the fluke is the same as used by the LEGO Mindstorms RCX robots. This means the flukes can communicate with RCX robots, the RCX USB infrared dongle, the RCX remote, and possibly other infrared remotes or beacons. The fluke uses 40KHz IR receivers, and although the RCX uses 38KHz things still work ok. For example you can use NQC to send messages or commands to the RCX.
The infrared protocol is 2400 baud, 8 data bits, and odd parity.
A single byte is sent as 11 bits:
| START | DATA 0 | DATA 1 | DATA 2 | DATA 3 | DATA 4 | DATA 5 | DATA 6 | DATA 7 | ODD PARITY BIT | STOP BIT |
each bit is indicated by 417 microseconds of IR activity or 417 usecs of rest. A logical one is represented by a rest, and a zero by IR activity (40 Khz IR light). The start bit is indicated by IR activity, and the stop bit by rest. The parity bit is set when there are an odd number of ones in the data bits.
The fluke implementation is in infrared.h and infrared.c in the SVN repository. For receiving, an interrupt handler is configured to use the CAPTURE/TIMER1 capabilities of the IRIN pin. For transmitting, TIMER0 is used to strobe the IR emitters at 40Khz and time the 417 usec pulses of IR.
The fluke uses interrupts to receive infrared packets. This means it can be doing other things while receiving an IR packet (e.g. sending an IR message), but this also means things are a little more complicated. The interrupt handler is triggered when the IR receiver changes, the handler puts the amount of times since the last change in a circular buffer. The non-interrupt code then processes this circular buffer of up/down times into bytes of data, filtering out noise, computing parity bits etc. TIMER1 is used to time the transitions, with the prescalar set so each timer tick is approx. 0.1 microseconds.
The RLE buffer is used by the receiving routine, so there is a slight chance your RLE image could be affected by IR traffic. If this is a big deal we can fix it by disabling interrupts during the RLE routine. We are running low on memory, so I made this choice.
The transmit routine is a simple blocking send; however, you can receive messages as you send. Therefore, you can use the communication routines to detect obstacles, by receiving reflections from obstacles.