Ghost Writing Robot

Matthew Guindin (mbg35)

Michael Sandman (ms458)

The wireless ghost writer is a robot that draws what the user draws with a connected mouse.


Robot in shoe-box ready to be demoed later in the day.


We used two stepper motors to drive a steel ball scavenged from a ball-bearing.  These motors were controlled by a PS/2 mouse wirelessly using the RCR-433 and RCT-433 receiver/transmission combination mentioned in lecture.  We then took the PS/2 protocol, made it compact, modified existing transmission code and deduced a way to control the robot via the mouse.  We also mounted a solenoid which raises and lowers a writing instrument.  The device is meant to write on a sheet of paper.
By using a mouse to control the robot, anyone can sit down and doodle remotely with it.  This was done since we wanted to create a project that could be used intuitively by anyone and be fun, yet useful in some applications.  Also, we wanted to build a robot since robots are interesting.  We chose the spherical drive since it was a novel approach that we had only seen a few times on the internet (  We made the design wireless to allow the robot to move unopposed in any direction. 

High Level Design


We were trying to figure out what to do for our final project when we came across the idea of creating something we could entertain and scare people with. After some research online we were determined to make the ghost writing robot. We wanted to be able to put the robot in a room and from another room get it to draw messages and images wirelessly. We also wanted to create a system for easily blowing up or shrinking what someone draws while maintaining accurate drawing scale.
We chose the spherical drive train since that most accurately mimics the mouse movements and would allow for drawings that did not have unnecessary curves due to rotation of a conventional drive train (like 2 or 4 drive motors controlling wheels that are parallel to each other).  In determining the motors to use, we chose stepper motors since they were small in size yet had a sizeable amount of torque, which we felt would be necessary for driving the robot, the electronics, and batteries.  By using this drive train we also simplified the amount of software needed to translate the mouse input into stepper motor control since both would now be on a similar Δx and Δy coordinate system.

Background Math

Most of the mathematics behind this project dealt with timing.  The mouse defaults to 100 packet updates per second.  However, we found that with a maximum baud rate of 4800, the wireless link can only send 480 bytes per second, or at most 160 mouse packets.  Additionally, running the wireless at maximum speed caused a couple of dropped packets, whereas running it at around 4300 baud provided near flawless communication; so we did.  With the overhead on the packets however, we were only able to transmit 4300/10 = 430/15 = about 27 mouse packets per second.  We reduced the overhead on the wireless link and were able to transmit 430/5 = 86 packets per second.  Since the mouse can only deal with certain discrete values, we had to settle for 80 updates per second, which is more than enough to report apparently smooth motion.
The motors also have timing issues.  Assuming 80 updates occur per second, one update reaches the receiver every 12.5 ms.  The limit on the motors (tested by trial and error) seemed to be about one update (motor tick) every 2 ms.  Additionally, we switched to a half-step drive for the motors, which cuts the max speed to one half motor tick per 2 ms, one full tick per 4 ms.  Therefore, the mouse would theoretically only be able to move 3 spaces per update, or ¾ mm.  (One unit of mouse movement = ¼ mm, although this can be changed by sending a command to the mouse.)  ¾ mm per 12.5 ms = 60 mm per second, or about 2.5 inches per second.  We figured that this would be ok, since we don’t really want the robot to be made to move too fast anyway, and we essentially buffer anything beyond this limit using the xmov and ymov variables in rx.c.  The timing we ended up going with was 313 overflows of timer 0, or 313 * 16 us = 5 ms per half tick.  We find that as long as the mouse is moved fairly slowly (which is pretty essential if you want to draw accurately with the mouse), this causes no overflow problems with the motors.
Each unit of mouse movement translates to one half tick of the motor.  Theoretically, this means that each ¼ mm of mouse movement translates to pi * ¾ in = roughly .6 mm after unit conversions.  This would mean that given a perfect drivetrain the drawing would be scaled up.  However, given the slippage of the ball, the drawing comes out to be much closer in size to the mouse movement.  We actually wanted to keep the drawings small for the safety of the robot and for simplicity’s sake, so this works out. 


Logical Structure

The high level structure follows a simple scheme of taking input from the PS/2 mouse, sending it wirelessly from one Atmega32 to the Atmega32 onboard the robot and then driving the motors and solenoid.  It is illustrated in the following diagram.


Hardware/software tradeoffs

In the creation of the robot, we ended up hitting quite a few snags due to physical, as well as hardware, limitations.  Of these were speed of the motors—if the motors ran too fast they slipped on the sphere and the robot would just jerk and not move.  In order to account for this, in software we slowed down the maximum operating speed of the stepper motors.  We also had to sacrifice accuracy of the robot due to inability of the design to drive the sphere straight in the cardinal directions (+,-x and +,-y).  The limitations of the wireless transmitter and receiver meant that we had to eliminate bytes of overhead from the transmission as well as package the PS/2 mouse output to take up less room in order to increase the data rate from the mouse.  This is evident in that initially the 100 updates/second from the mouse was producing a massive amount of packet loss due to wireless overhead constraints.  By reducing the updates/second to 20 and gradually increasing it from 20 to 80 while removing a lot of overhead bytes (as discussed in the software section), we were able to get smooth updates from the mouse.  The goal was for the mouse to be the limiting factor in precision for the project, not the wireless or the robot.


Our robot’s wireless transmitter and receiver combination complies with FCC standards since it does not interfere with licensed transmitters and it transmits in the acceptable range of frequencies found in Part 15 of the FCC rules ( 
Since we used a PS/2 mouse we had to develop a way of conforming to the PS/2 mouse protocol (  We also used a 6-pin mini-DIN connector as per required by the PS/2 protocol.  Due to this, any mouse that complies with the standard can be used with our project.

Patents, Copyright, Trademarks

Since we used the PS/2 mouse protocol (somewhat reversed engineered), it should be acknowledged that the full protocol was developed by IBM.  We have not used any other patented or potentially patented hardware or software in the design of this project.  Our code has been modified from other code released under the GNU Public License and the authors have been acknowledged in this report.

Program/Hardware Design

Software Details

PS/2 Interface

The interface to the PS/2 mouse is located on the transmitter chip and in tx.c.  The PS/2 protocol allows 2-way communication with a keyboard or mouse using only 2 electrical lines, data and clock.  Both lines are defaulted to high but can be pulled low by either the host (the microcontroller) or the device (the mouse).  Communication with the mouse is initiated when the MCU pulls the clock low (inhibiting mouse communication to the MCU), then sends a 0 over the data line, then releases control of the clock back to the mouse.  The mouse then sends a clock signal allowing the host to send a data packet.  First a start bit (0) is sent, then 8 data bits, then an odd parity bit, and finally a stop bit (1).  The mouse then sends an acknowledgement bit (0) and will follow that up with its own communication.  When the mouse communicates to the host, it drives the clock line itself and sends data in the same format as described above.  The send() function allows for host-to-mouse communication, while mouse-to-host communication is triggered by an external interrupt (using PORTD.2) that fires when the start bit is sent from the mouse.  The other functions used are init_receive() and disable_receive(), which turn that external interrupt on and off.  In order for the MCU to send a command to the mouse, it must first turn receiving off in order to prevent that interrupt from firing.
To set up the mouse for our purposes, we first send a reset command (0xff) to verify that the mouse is connected properly and is working.  We then send 0xf3 followed by a decimal number to set the mouse sampling rate.  This number can be 10, 20, 40, 60, 80, 100, or 200, and represents the number of mouse updates per second (we use 80, as it is the fastest we can go without exceeding the baud rate of the wireless transmitter).  Finally, a 0xf4 command is sent to enable mouse data reporting, and the mouse will then send updates in the form of packets.  Mouse packet format is given by the following table:

Byte 1 

Bit 7

Bit 6

Bit 5

Bit 4

Bit 3

Bit 2

Bit 1

Bit 0

Y overflow

X overflow

Y sign bit

X sign bit

Always 1

Middle Btn

Right Btn

Left Btn

Byte 2

X Movement

Byte 3 

Y Movement


Wireless Link

The wireless code is present on both chips, and also in txrx.c, a header file originally written by Meghan Desai that provided a protocol for wireless transmission.  Due to the timing issues described above, however, the protocol had to be modified somewhat.  We attempted to cut back as much overhead as possible from the packets and were able to reduce amount of overhead from 12 bytes to 1 byte, which brought the allowable sampling rate of the mouse from 20 packets/second to 80 packets/second.  Our wireless uses the same functions as the original code, but only sends 1 byte of 0xaa for calibration/synchronization of the two units (we tried getting rid of this too, but it wouldn’t work).  In addition, the start byte is now compressed with part of the mouse data; the first half of the start byte is overhead, and the second half contains the mouse button info and sign bits for the movement.  (The overflow bits are barely physically relevant, since the user would have to move the mouse about 3 inches in 12.5 ms, or about 20 feet per second, to cause an overflow; the robot itself can’t handle this as it is.  The middle mouse button is not present on the mouse, and the “Always On” bit is, well, always on, and thus does not need to be sent.)  The last two bytes contain the X and Y movement, respectively.  Packet length for our purposes is always 3 (4 including overhead), so there is no need for an end byte or transmitting the length of the packet.  Channel ID’s, while originally present, do nothing to prevent physical collisions of packets, so they were removed as well.  While the encoding scheme used by Meghan Desai is useful for reliability, we found that without it, our link rarely if ever dropped a packet, and since higher sampling rate was of greater priority, we discarded it.
When a packet is ready to transmit, the USART is first cleared with 0x00, then the packet is sent using the tx_me() function.  This function will place the mouse packet into a transmittable packet (with a synch byte and “start nibble”) and send it using the UDR Empty interrupt.  The interrupt had to be modified to continuously clear the USART whenever a packet was not being transmitted. 
On the receive side, a packet comes in and is decoded using the RXC interrupt (RX complete).  When a packet is fully received, rx_done() is set, and the necessary data is extrapolated from the packet.

Motor Control

The two stepper motors are controlled using 4 wires that go to 2 coils.  Essentially, to control a stepper motor, one must first power one wire, then the next, then the next, etc. (i.e. send 1000, 0100, 0010, 0001, 1000, 0100, and so on, to make the motor move).  In order to produce more torque out of the motors, we used a “half-stepping” method of driving (send 1000, 1100, 0100, 0110, 0010, 0011, 0001, 1001, and repeat).  Although half stepping effectively halves the top speed of the motors (the motors we used cannot handle signal changes quicker than one every 2 ms or so), this proved irrelevant, since the robot itself refused to move at speeds that fast.  We had to drive the motors at a speed that would be slow enough to drive the robot without tons of slipping yet would be quick enough to preserve the accuracy of the drawing.
The motor is controlled by task1 on the receiver chip (rx.c) which is scheduled by Timer 0.  When Timer 0 overflows, a virtual timer is decremented.  When the timer hits 0, the motors’ positions are updated based on the values of xmov and ymov, two variables that accumulate based on the data packets that come in.

Solenoid Control

The solenoid is controlled by the left mouse button.  It is wired to be active low: it raises the pen when the port pin (D.3) is set high, lowers it when the pin is set low.  To do this, it takes the last bit from the first data byte whenever a packet is received by the MCU mounted on the robot.

Hardware Details

The hardware for the project was mostly borrowed from previous projects and then modified to suit our needs.  However, this was not just a straight-forward task as the circuits provided on some project pages had key elements poorly labeled or missing and thus we had to research how these circuit exactly worked to implement them correctly.

Transmitter and Receiver Circuits              
The circuits for the RCT-433 transmitter and the RCR-433 receiver were taken from Tytus Mak and Daniel DiBernardo’s “Touch Screen Controlled R/C Car.”

PS/2 Mouse Communication Circuit

The mouse control hardware involved using two NPN transistors (2N3904) two drive the mouse whereas the inputs from the mouse were connected directly to ports D.2 and D.3.  This was possible since the PS/2 mouse never exceeds the 5V or 50mA limits on the inputs of the Atmega32.
Solenoid Control Circuit

To drive the solenoid we used two transistors and a resistor to allow the microcontroller to power and control the solenoid.  With this circuit, the ground of the 18V power supply (two 9V batteries in series) is common with the ground of the microcontroller.  The two NPN BJT transistors allow the microcontroller to drive the solenoid with is much higher in current ~250mA than the ports of the Atmega32 can handle as well as being at a higher voltage (18V).  The solenoid can operate between 12V and 24V, we chose 18V as it provided enough power to lift the writing instrument as well as it was easy to generate 18V by putting two 9V batteries in series.

Solenoid mounted on robot with Sharpie for drawing.

Stepper Motor Driver Circuit
The stepper motor circuit was based off of the same from Pallavi Arora, Stephane Constantin, Elizabeth Fatusin’s “Music Recognition Marionette.”  It uses two ULN2003 Darlington arrays to isolate the voltages of the stepper motors from the Atmega32 microcontroller.  The stepper motors took 9V to drive, which was supplied by a 9V battery connected to the ULN2003 and the stepper motors (the green and red wires).
Overall the hardware design is straightforward; considerations were taken for ease of building as well as availability of parts.  Luckily all of the components, save for the solenoid, were available in lab. Voltages were chosen that corresponded to real voltages that could be easily generated from 9V batteries.

Mechanical Design Details

                The robot was initially designed in Pro/Engineer and was based on initially using a mouse ball of 7/8” diameter. 
The robot design needed a way of mounting the stepper motors to the lexan base.  We used 1.5” aluminum L-brackets which were machined to accurately and securely mount the stepper motors.  Lexan was chosen as a base since it’s clear, which would aid in seeing what the robot had already drawn, as well as strong and Matt had experience in machining it before.  The Lexan was machined to create a diameter of 1.1” to allow the sphere to freely move around.  We decided upon this after initial testing with the 7/8” ball on Lexan with a .625” diameter opening failed to adequately move the robot.  Switching to a larger sphere—1” as opposed to 7/8”—as well as different material—steel as opposed to rubber coated iron—allowed the robot to carry the weight of the portable circuitry as well as the four 9V batteries to power the electronics.
Ultimately, however, we needed to add a collar to hold the sphere to a specific location in space and move the L-brackets in to provide additional tension on the ball.  By having the motors and the L-brackets provide the tension, the sphere is secured in three dimensions which aids in transferring power from the motors to the sphere to the paper effectively.
The material is held together with epoxy with the exception of the motors to the brackets which are held with one screw each.  The epoxy was used since there was no room for a screw and nut to be put through the Lexan and aluminum brackets.

Results of the Design

Speed of Execution

As mentioned above, due to slippage of the motors on the sphere at higher speeds, we had to limit the speed of the stepper motors.  However, since we were able to get the updates of the mouse to 80 per second, there is no aliasing between movement of the mouse and movement of the robot.  Since 80Hz is above the Shannon-Nyquist frequency of human vision (> 2*~15-20Hz), the robot’s movements seem fluid with the motion of the robot, save for a small delay from the wireless transmission.
Due to physical limitations of the solenoid (it is continuous-duty), after about 4-5 seconds of turning the solenoid on-and-off at the maximum human button frequency of 5Hz, the solenoid needs to rest for a few seconds before being active again (able to lift).  This will not prevent drawing as the solenoid in its de-energized state has the writing instrument touching the surface of the paper.


We aimed to have the robot create drawings that are pretty accurate to the mouse movements, but due to physical limitations of the robot’s design, we saw in testing that the robot had slightly different speeds for different directions (reverse is slightly faster than forward for the robot as well as left is slightly faster than right for the robot).  These variations are due to the mounting of the motors on the robot as when it pulls the ball it has all of the power from the motor going in the downward rotational direction as opposed to pushing the ball where the power is lost in the transition of going up to down rotationally.
The transmission is very accurate and during the testing of the wireless communication in lab with an oscilloscope we noticed no dropped packets while others were not transmitting.

Safety Enforcement

We enforced safety by allowing the robot to operate wirelessly without direct physical interaction from the user.  Since the user is only moving and clicking a mouse, his/her primary safety concern is fatigue in the wrist/hands, the possibility of carpel tunnel syndrome after prolonged use of the mouse as well as discomfort due to the lack of effective ergonomics in most modern mouses.  The robot is made of Lexan with burred edges which would prevent cutting the user during direct interaction with the robot (moving it, storing it).  We aimed to have a collar holding the ball in the robot to prevent the ball from falling out when transporting it, but due to changes in the design, this was omitted.  To maximize safety, it’s recommended to lift the robot on its side, remove the drive ball, secure it, then move the robot to prevent and unforeseen injury due to the ball dropping on something or someone.
We avoided electrical hazards by using relatively low voltage and low current devices.  Since the robot is wireless and battery driven, the same hazards exist when dealing with batteries for this device as any other—handle the batteries with care, don’t bang them and dispose of them properly.


The PS/2 mouse and the motors should not cause any interference because they are wired and fairly self-contained.
The 433 Mhz transmitter is likely to interfere with other groups receiving on the same frequency.  Originally, we used packets with a set channel ID, believing that it would prevent interference from occurring.  However, we found that we had to sacrifice this overhead in the packets to allow for faster communication.  Also, the channel ID’s didn’t actually do anything for physical interference, and would only help if we ended up receiving someone else’s packet who is using the same packet system.
We found that on our end, any interference that was caused by other groups was minimal, and caused fewer than 10% (likely around 5%) of the packets to be dropped.  We also found that our transmissions caused even less interference to other groups since we were not continuously transmitting, but only transmitted after a mouse update.  If we ever were to commercialize our project, we would find faster wireless hardware, and would use a packet system with ID’s to prevent logical interference; however, physical interference would still occur.


Since the project uses a mouse input, it is usable by anyone able to use a PS/2 mouse device.  This allows people who don’t have the dexterity to hold a conventional writing instrument and/or draw for long periods of time to use this device to overcome those obstacles.


Design Analysis

Overall we were impressed that we were able to use this novel drive approach to create a fun and useful device for drawing and writing.  Our requirements for the project:

 -Must accept input ONLY from PS/2 mouse
-PS/2 mouse MUST control robot WIRELESSLY
-Robot MUST be able to move in almost any direction
-Robot MUST be able to draw to a sheet of paper what is being done with mouse

We satisfied all of the requirements, but we didn’t get the accuracy or precision out of the robot that we wanted.  Electronically and software-wise the project was completed to our standards and expectations.  Mechanically, the design had problems that were unforeseen in the development stage since neither project member is a mechanical engineer.  Thanks to the lab operators in the Hollister CEE machine shop, we were able to eliminate many mechanical issues and get the robot working decently well.
If we could do this project in a different way we would design a more constrained platform for the robot with a larger sphere, gear drivers instead of the grommets we used and supporting spheres to aid in sliding the robot around.  Aside from this, we would recommend to any group in the future to be prepared for the worst and try to pick a project that is within your realm and field of interest as an engineering student.

Applicable Standards

We didn’t really follow any ‘applicable standards’ aside from the PS/2 mouse protocol, which was necessary for getting the mouse signal correct.

Intellectual Property Considerations

We referenced 3 other projects for code that correspond to the 3 major pieces of our project.  The wireless code was borrowed and (greatly) modified from Meghan Desai’s wireless transmission/receiving protocol.  The PS/2 code was borrowed and (slightly less) modified from James Yu and Jared Clifton’s Mouse Painter project.  The motor code was written entirely by us, but we would like to cite Pallavi Arora, Stephane Constantin, and Elizabeth Fatusin and their Music-Controlled Puppet project, as we referenced their website to understand how stepper motors are driven. 
The solenoid code was about 2 lines long and really easy to write, but we referenced the Non-Orthogonal Plotter project (Michael Guagliardi & Prachi Sanghavi) for the circuit schematic.
We do not plan to patent the project.

Ethical Considerations

The IEEE Code of Ethics establishes a guideline to adhere to for the development of safe, innovating applications.  We adhered to the Code of Ethics by always paying attention to what we were using, how we used it and why.  We cited other groups who code we reused and modified as well as circuit designs we borrowed.  We strived for safety throughout the development of this project by accepting “responsibility in making decisions consistent with the safety, health and welfare of the public, and to disclose promptly factors that might endanger the public…”  We also helped other groups when they needed aid and never tried to work that angle to get help in return.  We did not lie about what we did/didn’t do for the project and we tried to adhere to reasonable goals and not make false claims in this document.  We didn’t pressure companies to donate parts or other people and we did not engage in bribery or anything of the like at anytime.
We could have cherry-picked data to present our project in a more favorable view, but we didn’t.  We presented what we expected to happen and what did and show the data that supports our claims as well as data that contradicts them, if any.  We believed in doing this project for us and as such we did not want to do anything unethical or lie to ourselves or anyone else involved in the creation or demonstration of this project.

Legal Considerations

Our project complies with FCC standards since it does not interfere with licensed transmitters and it transmits in the acceptable range of frequencies found in Part 15 of the FCC rules ( 


Commented Code (make into hyperlinks)


Transmitter and Receiver Circuits              

PS/2 Mouse Communication Circuit


Solenoid Control Circuit


Stepper Motor Driver Circuit

Cost Details
STK500: $15
DIP socket(2): $1
Atmega32 : 8 = $8
Atmega32 (second): Sampled, Atmel
RCT-433 Transmitter: $4
RCR-433 Reciever: $4
Max233: $7
Power supply: $5
custom PC board: $5
Stepper motor (2) (35T-48):: $2
GUARDIAN A420-067074 Solenoid: $3.85 (All Electronics)
PS/2 connector: $1
PS/2 mouse: Free (old mouse)
Steel ball: Free (scavenged from old bearing)
Aluminum: $1 (1/12 of $12 piece)
Lexan: free (found in machine shop)
Screws & nuts: free (found in house)
Grommets: free (found in machine shop)
Battery(4): $8
Small solder board (4): $4
Assorted capacitors, inductors, LEDs, and resistors: free (from lab)
2N3904 (3): Free (from lab)
TIP31: Free (from lab)
ULN2003AN (2): Free (from lab)
9V connectors (3): Free (from lab)
Cable ties: Free (Matt purchased before Spring 2007)
Pen/Sharpie: Free (found around house)
Epoxy: Free (from machine shop)

Total: $68.85


Specific Tasks

Hardware design, testing, and debugging: Matt
Software design, testing, and debugging: Mike
Robot design: Matt
Robot testing and debugging: Matt & Mike
Report: Matt & Mike
Website: Matt
Full project testing and debugging: Mike & Matt
Making the robot do the electric slide: Mike


Data Sheets
4N35 Opto-isolator
35T-48 Solenoid
RCR-433 and RCT-433


Code/Designs Borrowed from Others

Meghan Desai’s wireless transmission/receiving protocol. 
James Yu and Jared Clifton’s Mouse Painter project. 
Pallavi Arora, Stephane Constantin, and Elizabeth Fatusin’s Music-Controlled Puppet project
Non-Orthogonal Plotter project (Michael Guagliardi & Prachi Sanghavi) for the circuit schematic.

Background Sites/Papers

                Self-balancing robot with spherical drive (  This was the inspiration to pursue this novel drive train.


We would like to thank Paul Charles, Tim Brock, and Graham Seward in helping fix the original design of the robot.


Matthew Guindin & Michael Sandman - Cornell University ECE476