I built a vehicle that only used one RC style servo motor. To get the mindsensors servo controller just to control one servo seemed sort of pointless. I like the challenge of building circuits and programs, so I figured I’d try to build my own controller. I had gotten quite familiar with the PICAXE system, so I decided to try building the servo controller using a PICAXE 20X2.
The initial servo function tests showed great promise, so I added I2C slave and changed a couple other things in the code. And guess what! The PICAXE I2C code, hardware, and NXT program worked perfectly on the first try 🙂
The PICAXE supports up to 6 servos (when also using I2C), but I didn’t have enough header pins to build it that big. This can only control 3 servos.
Because on a solderless breadboard it didn’t have any issues with 6 outputs, I drew the schematic showing all six.
Edit (6/13/11): I was just informed that for the safety of the 20X2, it is recommended that you place a 330 ohm resistor on all the signal wires that go to the servos. I heard these protect the 20X2 from damage by plugging the servos in backwards. The schematic as follows has been updated to include these resistors.
I went to get the code I used for the PICAXE, but I can’t find it anywhere… I think it may be lost.
I rewrote the program from memory, and then modified it to be more efficient (and added a feature). I tested this code with a 20X2 that is on a breadboard, and it seems to work perfectly.
setfreq m32 'Make sure it is running at 8mHz or 32mHz clock speed. hi2csetup i2cslave, %00110000 'Set the I2C address. init: symbol SERVO_POS = B0 'Set up the names of the variables. symbol SERVO_PIN = B1 ' '' symbol LOOP_i = B2 ' '' symbol CURRENT_FLAG = B3 ' '' symbol CURRENT_FLAG_REG = B4 ' '' pullup %10100000 'Enable internal pullups on the I2C lines. main: for LOOP_i = 0 to 5 'Loop 6 times (0-5) CURRENT_FLAG_REG=LOOP_i+10 'Set the current flag register number if LOOP_i=5 then 'If it is on it's sixth loop... SERVO_PIN=6 '...set the pin to B.6. else 'Otherwise... SERVO_PIN=LOOP_i '...set pin to loop increment. endif get LOOP_i,SERVO_POS 'Get the servo positon (from the I2C register). if SERVO_POS=0 then 'If the position is 0... INPUT SERVO_PIN '...float the servo... put CURRENT_FLAG_REG,0 '...and set the flag to 0. else 'If the position isn't 0... get CURRENT_FLAG_REG,CURRENT_FLAG '...check the flag. if CURRENT_FLAG=0 then 'If the flag is 0... SERVO SERVO_PIN,SERVO_POS '...turn on the servo at the new position... put CURRENT_FLAG_REG,1 '...and set the flag to 1. else 'If the flag is already 1... SERVOPOS SERVO_PIN,SERVO_POS '...update the servo position. endif endif next LOOP_i 'End of loop. Goto main 'Return to main (repeat forever).
Now you can give the servos a 0 to turn them off (make them float).
In a future redesign, I may add parts that would allow me to monitor the voltage of both the power supply, and the NXT power bus. That would require an LDO voltage regulator, and a voltage divider (each would only require 2 parts plus some code).