Create 25-pin Cargo Bay Connector:
1 RXD
2 TXD
3 Power Control Toggle
4 Analog Input
5 Digital input 1
6 Digital input 3
7 Digital output 1
8 Switched 5V (100ma)
9 Vpwr (unregulated, 500ma)
10 Switched Vpwr (1500ma)
11 Switched Vpwr (1500ma)
12 Switched Vpwr (1500ma)
13 Robot charging
14 GND
15 BRC (digital input/baud-rate-change to 19200)
16 GND
17 Digital input 0
18 Digital input 2
19 Digital output 0
20 Digital output 2
21 GND
22 Low side driver 0 (500ma)
23 Low side driver 1/IR LED (500ma)
24 Low side driver 2 (1500ma)
25 GND
/********************************
currentX, currentY - uint16_t globals to maintain current coordinates
targetX, targetY - uint16_t globals hold the coordinates we want to head toward
targetAngle - uint16_t global holds the direction we should head (line-ofsite) to reach targetX,targetY
targetDistance - uint16_t global holds the distance (line-of-site) to targetX,targetY
********************************/
void CalcNewPosition(int16_t dist, int16_t angl)
{ // calculate new position using dist and angl
double x,y,h;
// update current x,y coordinats
// radians = angl/57.296
// newx = dist * sin(radians)
// newy = dist * cos(radians)
currentX += ( dist * sin( angl / 57.296 ));
currentY += ( dist * cos( angl / 57.296 ));
// calculate heading to targetX,targetY from currentX,currentY
// (solve: tan t = opposite/adjacent
// == atan2(adjacent,opposite) - convert 0..3.14159 radians to to 0..359 degrees
targetAngle=(atan2(currentX-targetX, currentY-targetY)*1000) / 17.4533;
targetAngle+=180;
if(targetAngle>359)
targetAngle-=360;
// calculate distance directly to target
// (solve for the hypotenuse of the triangle) hypotenuse=sqrt(x^2 + y^2)
if(currentX>targetX)
x=currentX-targetX;
else
x=targetX-currentX;
if(currentY>targetY)
y=currentY-targetY;
else
y=targetY-currentY;
h=sqrt(x*x+y*y);
targetDistance=h;
}
Here's how Create transitions between the states in packet 21, under
normal conditions:
Charge requested?
|
Battery hot?
| |
N Y
| |
| WAITING
| |
Voltage very low?
| |
N Y
| RECONDITIONING
| |
FULL CHARGE |
| |
Battery hot ?
| |
N Y
| |
| WAITING
| |
TRICKLE
The FAULT state is entered whenever a problem occurs during charge
Here's an overview of how the scheduling remote formats and transmits schedule packets:
Scheduling remote opcode format
total schedule packet is 11 bytes long, in the following format:
bytes 0-2 => current time
byte 3 => schedule days
bytes 4-10 => schedule
current time is 3 bytes long, in the following format:
[ days ][ hours ][ mins ][seconds ]
[ 3 bits ][ 5 bits ][ 8 bits ][ 8 bits ]
schedule days stores whether each day is in use. It is one byte long, in
the following format:
[day 0][day 1] ... [day 6][unused]
[bit 0][bit 1] ... [bit 6][bit 7 ]
schedule is 7 bytes long, in the following format:
[ day 0 ] ... [ day 6 ]
[ 8 bits ] ... [ 8 bits ]
Each day of a schedule is one byte long, in the following format:
[ hours ][ minutes ][ weekly or once ]
[ 5 bits ][ 2 bits ][ 1 bit ]
Sending the Packet
Constants:
initial crc = 0x5555
nop = 128
download = 142
packet length = 11
escape char = 128
Variable:
crc (16 bits long)
Functions (in Lisp):
(defun crc16-8 (crc-in new)
(loop for bit from 0 to 7
for new-item = new then (ash new-item -1)
for prev-crc = crc-in then crc
for crc = (logxor (ash prev-crc -1)
(if (/= (logand new-item 1) (logand prev-crc 1))
#x8005
0 ) )
finally (return crc) ) )
(defun send-ir-char-escaped (char)
(if (or (= char data-packet-escape-char) ; 128
(= char remote-opcode-download) ) ; 142
(progn
(send-ir-char data-packet-escape-char) ; 128
(send-ir-char (logxor char data-packet-escape-char)) )
(send-ir-char char) ) )
Steps to send the packet:
0) crc = #x5555
1) send NOP
2) send DOWNLOAD
3) crc = crc(crc, remote-opcode-download) // 142
4) send ESCAPED packet length // 11
5) crc = crc(crc, packet length) // 11
6) for i from 0 to 10 (packet length)
send ESCAPED packet[i]
crc = crc(crc, packet[i])
7) send ESCAPED low byte of ctc
8) send ESCAPED high byte of crc
Power Consumption:
When the robot is powered off, it robot consumes ~60ua.
The robot consumes about 140ma while on but not moving.
The Command Module consumes about 40ma with processor running and various LED’s on.
Changing Modes after Charger is detected:
1) Connect your robot to the charger (internal or dock) while it is in full mode.
2) Send opcode "7". This is not an official OI opcode, rather it is an opcode used by Osmo to initiate a soft reset of the robot and force it to run its bootloader.
3) The robot resets. Wait for the bootloader to complete. Do NOT send any opcodes whie the bootloader is running.
4) The robot should start charging. Note that the robot spews some battery-related text if it is charging and not in OI mode. Ignore this text.
5) Enter a Start command to get back into the OI (and stop the spew).
Charging & Docking:
Charging currently triggers only on the rising edge of the charger becoming available, so if you switch to passive mode after the charger is connected (dock or internal charger), the robot does not charge.
Reserved I/O Lines:
|------------------------------------------------------
| Initialize the ATmega168 microcontroller |
| Command Module/Create Reserves the I/O Lines below |
|------------------------------------------------------
| PIN | DESCRIPTION | DIR |
|------------------------------------------------------
| PB4 | Ser Port Sel 1=To USB, 0=To Create | Out |
| PB5 | Create Pwr Detect 1 = Create ON | In |
| PD0 | Serial Rx | In |
| PD1 | Serial Xmt | Out |
| PD2 | Create Dev Det Inp. Chg Creates Baud | Out |
| PD3 | USB Detect | In |
| PD4 | Command Module Soft Button | In |
| PD5 | Command Module LED 1 | Out |
| PD6 | Command Module LED 2 | Out |
| PD7 | Create Pwr Toggle. Low->Hi Togls Pwr | Out |
|------------------------------------------------------
by: JohnQ
Create IR Transmitter/Receiver
An "ON" is a 38khz PWM signal.
Each byte is 8 bits.
Each bit is 4 ms long.
A 0-bit consists of a 1 ms ON followed by 3 ms OFF.
A 1-bit consists of a 3 ms ON followed by 1 ms OFF.
The end of a byte is marked by 4 ms OFF.
I didn't realize what they meant by a "38khz Carrier Frequency" until I tried to implement an IR Transmitter. A "Carrier Frequency" means when you are transmitting an ON signal, it is actually Pulsed On and Off at 38000 times per second. If you don't do this, then the receiver will see a single pulsed ON at the beginning of your ON time but then the receiver will interpret the rest as OFF. When transmitting an OFF signal, simply don't transmit anything. It's only the ON signals that have to be pulsed at 38khz.
This is a capture of byte 130 (10000010) received from the Create/Roomba remote (forward button).
You can see the 3ms ON and 1ms OFF for the 1-bits, and 1ms ON and 3ms OFF for the 0-bits, then 4ms OFF for the Stop-bit. (9 bits total including the Stop bit) The byte is then repeated about 27ms later while the button is held down. One byte is transmitted every 62ms (begin byte to next being byte) while the remote button is held down.
(NOTE: My ON/OFF's are inverted here, normally you have a high-output and the IR Receiver pulls low when receiving bits)
Make your own Virtual Wall for the Create or Roomba:
The Virtual Walls generate a 1ms ON, 1ms OFF signal continuously. The 1ms ON is a 38Khz PWM pulse. I haven't written a program to simulate this, but it should be simple to modify the IR Beacon source code.
A simple RS-232 to TTL Serial Converter:
I wanted to be able to Receive RS-232 data without adding a MAX232 conversion chip so after searching around I found a simple circuit to convert RS-232 to TTL without a chip.
I am using the PC to PIC converter (above) to Receive RS-232 @ 9600 baud on a Propeller Chip with a 10k and a 2.2k resistor (didn't have a 3.3k), a standard PN2222 transistor, and a 1N4001 diode. I am supplying Vdd with 3.3v. I haven't needed to try the PIC to PC converter yet.
Capacitor Conversion Chart
| uF/ MFD | nF | pF/ MMFD | uF/ MFD | nF | pF/ MMFD | |
| 1uF / MFD | 1000nF | 1000000pF(MMFD) | 0.001uF / MFD | 1nF | 1000pF(MMFD) | |
| 0.82uF / MFD | 820nF | 820000pF (MMFD) | 0.00082uF / MFD | 0.82nF | 820pF (MMFD) | |
| 0.8uF / MFD | 800nF | 800000pF (MMFD) | 0.0008uF / MFD | 0.8nF | 800pF (MMFD) | |
| 0.7uF / MFD | 700nF | 700000pF (MMFD) | 0.0007uF / MFD | 0.7nF | 700pF (MMFD) | |
| 0.68uF / MFD | 680nF | 680000pF (MMFD) | 0.00068uF / MFD | 0.68nF | 680pF (MMFD) | |
| 0.6uF / MFD | 600nF | 600000pF (MMFD) | 0.0006uF / MFD | 0.6nF | 600pF (MMFD) | |
| 0.56uF / MFD | 560nF | 560000pF (MMFD) | 0.00056uF / MFD | 0.56nF | 560pF (MMFD) | |
| 0.5uF / MFD | 500nF | 500000pF (MMFD) | 0.0005uF / MFD | 0.5nF | 500pF (MMFD) | |
| 0.47uF / MFD | 470nF | 470000pF (MMFD) | 0.00047uF / MFD | 0.47nF | 470pF (MMFD) | |
| 0.4uF / MFD | 400nF | 400000pF (MMFD) | 0.0004uF / MFD | 0.4nF | 400pF (MMFD) | |
| 0.39uF / MFD | 390nF | 390000pF (MMFD) | 0.00039uF / MFD | 0.39nF | 390pF (MMFD) | |
| 0.33uF / MFD | 330nF | 330000pF (MMFD) | 0.00033uF / MFD | 0.33nF | 330pF (MMFD) | |
| 0.3uF / MFD | 300nF | 300000pF (MMFD) | 0.0003uF / MFD | 0.3nF | 300pF (MMFD) | |
| 0.27uF / MFD | 270nF | 270000pF (MMFD) | 0.00027uF / MFD | 0.27nF | 270pF (MMFD) | |
| 0.25uF / MFD | 250nF | 250000pF (MMFD) | 0.00025uF / MFD | 0.25nF | 250pF (MMFD) | |
| 0.22uF / MFD | 220nF | 220000pF (MMFD) | 0.00022uF / MFD | 0.22nF | 220pF (MMFD) | |
| 0.2uF / MFD | 200nF | 200000pF (MMFD) | 0.0002uF / MFD | 0.2nF | 200pF (MMFD) | |
| 0.18uF / MFD | 180nF | 180000pF (MMFD) | 0.00018uF / MFD | 0.18nF | 180pF (MMFD) | |
| 0.15uF / MFD | 150nF | 150000pF (MMFD) | 0.00015uF / MFD | 0.15nF | 150pF (MMFD) | |
| 0.12uF / MFD | 120nF | 120000pF (MMFD) | 0.00012uF / MFD | 0.12nF | 120pF (MMFD) | |
| 0.1uF / MFD | 100nF | 100000pF (MMFD) | 0.0001uF / MFD | 0.1nF | 100pF (MMFD) | |
| 0.082uF / MFD | 82nF | 82000pF (MMFD) | 0.000082uF / MFD | 0.082nF | 82pF (MMFD) | |
| 0.08uF / MFD | 80nF | 80000pF (MMFD) | 0.00008uF / MFD | 0.08nF | 80pF (MMFD) | |
| 0.07uF / MFD | 70nF | 70000pF (MMFD) | 0.00007uF / MFD | 0.07nF | 70pF (MMFD) | |
| 0.068uF / MFD | 68nF | 68000pF (MMFD) | 0.000068uF / MFD | 0.068nF | 68pF (MMFD) | |
| 0.06uF / MFD | 60nF | 60000pF (MMFD) | 0.00006uF / MFD | 0.06nF | 60pF (MMFD) | |
| 0.056uF / MFD | 56nF | 56000pF (MMFD) | 0.000056uF / MFD | 0.056nF | 56pF (MMFD) | |
| 0.05uF / MFD | 50nF | 50000pF (MMFD) | 0.00005uF / MFD | 0.05nF | 50pF (MMFD) | |
| 0.047uF / MFD | 47nF | 47000pF (MMFD) | 0.000047uF / MFD | 0.047nF | 47pF (MMFD) | |
| 0.04uF / MFD | 40nF | 40000pF (MMFD) | 0.00004uF / MFD | 0.04nF | 40pF (MMFD) | |
| 0.039uF / MFD | 39nF | 39000pF (MMFD) | 0.000039uF / MFD | 0.039nF | 39pF (MMFD) | |
| 0.033uF / MFD | 33nF | 33000pF (MMFD) | 0.000033uF / MFD | 0.033nF | 33pF (MMFD) | |
| 0.03uF / MFD | 30nF | 30000pF (MMFD) | 0.00003uF / MFD | 0.03nF | 30pF (MMFD) | |
| 0.027uF / MFD | 27nF | 27000pF (MMFD) | 0.000027uF / MFD | 0.027nF | 27pF (MMFD) | |
| 0.025uF / MFD | 25nF | 25000pF (MMFD) | 0.000025uF / MFD | 0.025nF | 25pF (MMFD) | |
| 0.022uF / MFD | 22nF | 22000pF (MMFD) | 0.000022uF / MFD | 0.022nF | 22pF (MMFD) | |
| 0.02uF / MFD | 20nF | 20000pF (MMFD) | 0.00002uF / MFD | 0.02nF | 20pF (MMFD) | |
| 0.018uF / MFD | 18nF | 18000pF (MMFD) | 0.000018uF / MFD | 0.018nF | 18pF (MMFD) | |
| 0.015uF / MFD | 15nF | 15000pF (MMFD) | 0.000015uF / MFD | 0.015nF | 15pF (MMFD) | |
| 0.012uF / MFD | 12nF | 12000pF (MMFD) | 0.000012uF / MFD | 0.012nF | 12pF (MMFD) | |
| 0.01uF / MFD | 10nF | 10000pF (MMFD) | 0.00001uF / MFD | 0.01nF | 10pF (MMFD) | |
| 0.0082uF / MFD | 8.2nF | 8200pF (MMFD) | 0.0000082uF / MFD | 0.0082nF | 8.2pF (MMFD) | |
| 0.008uF / MFD | 8nF | 8000pF (MMFD) | 0.000008uF / MFD | 0.008nF | 8pF (MMFD) | |
| 0.007uF / MFD | 7nF | 7000pF (MMFD) | 0.000007uF / MFD | 0.007nF | 7pF (MMFD) | |
| 0.0068uF / MFD | 6.8nF | 6800pF (MMFD) | 0.0000068uF / MFD | 0.0068nF | 6.8pF (MMFD) | |
| 0.006uF / MFD | 6nF | 6000pF (MMFD) | 0.000006uF / MFD | 0.006nF | 6pF (MMFD) | |
| 0.0056uF / MFD | 5.6nF | 5600pF (MMFD) | 0.0000056uF / MFD | 0.0056nF | 5.6pF (MMFD) | |
| 0.005uF / MFD | 5nF | 5000pF (MMFD) | 0.000005uF / MFD | 0.005nF | 5pF (MMFD) | |
| 0.0047uF / MFD | 4.7nF | 4700pF (MMFD) | 0.0000047uF / MFD | 0.0047nF | 4.7pF (MMFD) | |
| 0.004uF / MFD | 4nF | 4000pF (MMFD) | 0.000004uF / MFD | 0.004nF | 4pF (MMFD) | |
| 0.0039uF / MFD | 3.9nF | 3900pF (MMFD) | 0.0000039uF / MFD | 0.0039nF | 3.9pF (MMFD) | |
| 0.0033uF / MFD | 3.3nF | 3300pF (MMFD) | 0.0000033uF / MFD | 0.0033nF | 3.3pF (MMFD) | |
| 0.003uF / MFD | 3nF | 3000pF (MMFD) | 0.000003uF / MFD | 0.003nF | 3pF (MMFD) | |
| 0.0027uF / MFD | 2.7nF | 2700pF (MMFD) | 0.0000027uF / MFD | 0.0027nF | 2.7pF (MMFD) | |
| 0.0025uF / MFD | 2.5nF | 2500pF (MMFD) | 0.0000025uF / MFD | 0.0025nF | 2.5pF (MMFD) | |
| 0.0022uF / MFD | 2.2nF | 2200pF (MMFD) | 0.0000022uF / MFD | 0.0022nF | 2.2pF (MMFD) | |
| 0.002uF / MFD | 2nF | 2000pF (MMFD) | 0.000002uF / MFD | 0.002nF | 2pF (MMFD) | |
| 0.0018uF / MFD | 1.8nF | 1800pF (MMFD) | 0.0000018uF / MFD | 0.0018nF | 1.8pF (MMFD) | |
| 0.0015uF / MFD | 1.5nF | 1500pF (MMFD) | 0.0000015uF / MFD | 0.0015nF | 1.5pF (MMFD) | |
| 0.0012uF / MFD | 1.2nF | 1200pF (MMFD) | 0.0000012uF / MFD | 0.0012nF | 1.2pF (MMFD) | |
| 0.001uF / MFD | 1nF | 1000pF (MMFD) | ………. | 0.000001uF / MFD | 0.001nF | 1pF (MMFD) |

