Create 25-pin Cargo Bay Connector:
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

This is how I calculate my running x,y coordinates using the Create  Distance and Angle sensor data:

  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;
 // calculate distance directly to target
 // (solve for the hypotenuse of the triangle) hypotenuse=sqrt(x^2 + y^2)


Here's how Create transitions between the states in packet 21, under
normal conditions:

  Charge requested?
  Battery hot?
  |   |
  N   Y
  |   |
  |   |
  Voltage very low?
  |  |
  N  Y
  |           |
  |           |
  Battery hot ?
  |   |
  N   Y
  |   |
  |   |

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

initial crc = 0x5555
nop = 128
download = 142
packet length = 11
escape char = 128

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))
                             0 ) )

         finally (return crc) ) )

(defun send-ir-char-escaped (char)
  (if (or (= char data-packet-escape-char)  ; 128
          (= char remote-opcode-download) ) ; 142
   (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 on the Command Module:

|      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.


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)