I am currently developing a custom board to control a wowwee alive Animatronic Elvis bust. I will likely have many questions along the way, so I figured that I would define the scope of it here for reference (and suggestions.)
The input to the controller is Mini-SSC II compatible commands. This is a popular Serial Servo Controller. The command structure is very simple, for each command, there are three bytes <Sync = 0xFF> <Chan (0 to 254)> <Pos (0 to 254)>.
The output of the controller is 10 DC motors which control:
- Eyes UD
- Eyes LR
- Eyebrows UD
- Right Eyelid UD
- Left Eyelid UD
- Lip UD (signature Elvis lip curl)
- Jaw UD
- Head LR
9.Neck swing LR (tilt) - Neck swing UD (nod)
Controlling these all is not directly straightforward.
7 of the motors inside the head postion (face motors) are tracked by potentiometers. Within the head is an ADC chip (SNAD01).
1 motor (Head LR.. rotate like "no") has a potentiometer, but it is not connected to the ADC within the head.
The final 2 motors for Tilt and Nod of the neck are linear actuators which incorporate optical encoder wheels and limit switches. The encoders are not quadrature, so there is no absolute position or direction information. They are like a tachometer.
The encoder wheels are connected at the point of the motor shaft. 4 slots in it (so, 4 pulses per revolution of the motor). The gear box is a 10:1 ratio, meaning it takes 10 rotations of the motor to move the final output shaft 1 revolution. The output shaft is connected to a lead-screw which converts the rotation into linear movement. For 1 revolution of the output shaft, there is 5mm of linear travel. If you do the math, you learn that 8 pulses from the encoder wheel equals 1mm of linear travel.
One linear actuator has a full travel of 64mm (tilt), and the other 32mm (nod). There are 4 limit switches located at the extremes of movements.
Controlling the other 8 motors is pretty straightfoward since they have potentiometers and we have absolute position from them. The only complexity there is communicating with the built-in ADC for 7 of the motors. That ADC is a Sonix SNAD01. I have already written a library for this for use with the Arduino. The 8th motor will just use an internal ADC channel of the AVR.
So, back to the linear actuators. I have devised some code to accurately track the position of the linear actuators using interrupts from the encoder wheel.
Overall the project will find it's final destination in an ATMEGA32 which has exactly enough I/O while coming in a DIP package. However, for ease of prototyping, I am using an Arduino (Uno and 2560.)
So far I have the Mini-SSC II serial parsing coded, the linear actuator code tracking position, and a driver library for the SNAD01 ADC. Now I need to piece it all together.
Here's how I think it will work:
The main loop will watch for new serial commands, and upon receiving one, it will send the chan and pos to a Move() function which will determine direction, magnatude of change, and control the motors.
An updatepos position will manage the various methods of gaining the current position of each servo.
A timer will run at 50Hz, which will refresh the motors with the last position given to ensure that they stay in position
Now what I am trying to wrap my head around is the overall code, the big picture, if you will. I think that it makes sense to simply create an array of each motors position, and when a new command comes in, it will put that new position in the array which will be fixed at the next update() call. All movements must be completed in 20ms. Does this make sense, or does it make more sense to start moving the motor immediately upon a new command and just leave the update() function to maintain?
Ultimately, I think this code will have much use beyond just this application and because of that, it is my intent to make it as modular as I possibly can. It could be used for any number of applications in which we need to gain servo control over a number of motors using the popular serial servo control interface.
I am not really 'new' to this, but I am not a great programmer. Hardware has always been my specialty. Typically my code is never 'clean' and often is buggy. What I would really like is some support and guidance (not hand-holding) in this project. I fully intend to put this code into the public domain for anyone to use, abuse, or otherwise.
Finally, my next project after this is a Wowwe Alive! animatronic chimp head. For that, I will be creating my own H-bridge and ADC board. I will also make that hardware (schematics, etc..) available for anyone to use for their projects. Since that will just use pots for every motor, there is actually a nice motor control shield and code that will be useful in just about any project.
Expansion of the code (if it becomes universally modular) would include closed loop control, open loop control, encoders (quadrature and tacho), potentiometers, gray-code encoders, etc... It would be the ultimate motor library.
So is anyone interested in helping?