Rotational Encoder from old CD motor
Last updated: September 22, 2010
The spindle motors used in CD-ROM drives often (always?) contain 3 Hall-sensors.
These sensors are used by the motor controller to determine the position of
the axle. This makes it possible to use these motors as rotational encoders.
Test setup without microcontroller
Test setup with microcontroller,
small power supply and programmer
First try to find the connections between the Hall sensors and the motor
controller. The datasheet of the motorcontroller is a big help here.
The CD-rom used for this experiment used a Toshiba TA8493 motorcontroller.
You will probably find something like this:
The Hall sensors are connected in parallel. The Hall-signals are fed into 3
The current through the sensors is limited by 2 resistors.
One of these resistors is
connected to Vcc (5V), the other is connected to the motorcontroller.
This is probably used to switch the current through the sensors on and off.
By feeding the Hall signals into a LM339 you get 3 TTL compatible signals that
indicate the axle position.
The Hall sensors are permanently connected to Vcc and GND. Because the common
mode range of the LM339 includes ground only 1 current limiting resistor is
needed. The common mode voltage of the sensors is approx. 1.3V,
the differential Hall voltage is approx. 0.3V.
Rotating the motor gives the following output pattern: 001, 000, 010, 110, 110, 101.
The pattern depends on how the LM339 signals are connected to the hardware,
The test setup gave 36 changes per revolution.
This is not compatible with the usual encoders which have 2 output signals.
There are several ways to handle this:
- A software solution. If the application has enough (3) IO pins available
no conversion has to be done.
The demo program uses this approach.
You have to choose between a polling
solution and a interrupt driven solution. For the interrupt driven solution, the
hardware should supports interrupts on all IO pins in use if the signals
on these pins changes.
Or extra hardware should be added to generate an interrupt signal
(see above schematic). This requires an extra input pin.
- Use a small 8-pin microcontroller (AVR, PIC) to do a conversion.
The output could be the usual I/Q output, but also something completely
different like I2C or RS232.
An attempt to interface the encoder directly to 3 ADC channels of an ATtiny13
microcontroller failed. Probably due to the following reasons:
The Archive contains the ADC code
- The ATtiny13 does not have enough ADC channels to measure the
voltage between the hall-sensor connections. The voltage swing becomes
rather small, approx. 70mV. Probably due to thermal effects the voltage also
drifts. I could not find a usable auto-calibration strategy, that
compensates for this drift.
- The ATtiny13 only has 1 AD converter. The hall-voltages have to be sampled
after each other. Especially when the rotor is turned fast this results in
codes that do not represent the rotor possition.
In a second attempt the outputs of the (already existing) LM339 where connected
to the ATtiny13.
After the required code change, this worked at first try.
The internal pull-up resistors of the ATtiny are enabled.
The code uses a timer interrupt to generate the serial output, and the
'pin changed' interrupt to detect rotor movements.
The ATtiny13 generates 2 output signals: a RS232-like signal on pin 6 and a
pulse to signal a change on pin 5. When turned anti-clockwise the ATtiny
generate a 'B' (0x42) on pin 5 and a positive pulse on pin 6 during the time
pin 5 is low. When turned clock-wise a '<' (0x3c) is generated and pin 6 is
high during the pulse on pin 5:
an improved STK200 programmer
connected to a FreeBSD 8 system with avrdude, for this project.
archive for the AVR code.
To change the internal clock from 1.2 MHz to 9.6 MHz the CKDIV8 bit
in the Fuse Low Byte has to be set to 1. The avrdude command for this is
avrdude -v -P /dev/ppi0 -c stk200 -p t13 -U lfuse:w:0x7a:m
This has to be done only once.
The software is programmed with
avrdude -v -P /dev/ppi0 -c stk200 -p t13 -U flash:w:oenc.bin:r
Archive containing the Xcircuit files
(encapsulated postscript), a DOS test program for the version without the AVR
and the ATtiny13 code.
- Write program to test the 'pulse output'