So, relatively close to where I live, is opening a new hacker space, The Hacker Dojo. I went to Their open house, bearing food, a handfull of completely empty Freeduino PCBs (mostly of the 0603 SMT version that has never quite seen the light of day, and probably won’t. But it did work), and a few misgivings about whether anyone in that particular hacker community would even know what an Arduino was. Whatever; I had other things to do too.
I need not have feared; the PCB was happily accepted and shown around, and one of the other attendees (“Tim”) piped up: “Did you bring any WORKING arduinos? I have a servo motor (one of those $3.50 micro servos) that I’ve just modded for continuous rotation, and I need to see if the Arduino can work with it, but I didn’t bring my actual arduino…” Well, of course I had a real arduino (and laptop with the IDE), and it seemed a FINE project to spend some time on at such an event.
After some minor struggling with the fact that this particular laptop had never had an actual arduino connected to it, and needed the FTDI drivers installed, we quickly had my arduino running BLINK. A quick raid on the (infant but growing) HW lab at the dojo yielded an unmodified full-sized servo plus appropriate jumpers, and in moments we had the SWEEP demo program moving the servo arm around. (Then we paused for the Welcoming Speeches.)
The same unmodified SWEEP did in fact work just fine to drive the MODIFIED servo in both directions; one way for part of the sweep and the other way for another part. The BIG question was whether we could make it STOP by finding and sending the appropriate middle value pulse. SWEEP was modified to run slower, and to print out the values it was using, so we could track when the servo seemed to stop. The middle value in this case was “about 80.” Given THAT info, we narrowed the loop further, trying to find an exact “stopped” value…
This however, failed. On this particular servo, the best we could do was to have the motor move VERY SLOWLY in one direction or the other. While this raised interesting possibilities for continuous rotation at multiple speeds, it didn’t solve the “stop” problem. Noting that the servo didn’t seem to move at all when there was NO signal, we decided to see if we could use a digitalWrite() to set STOP, and return to servo.write when we wanted it to move again. This didn’t quite work either; once PWM was fully stopped (digitalWrite turns off PWM on the appropriate pin), servo.write is insufficient to turn it back on. However, servo.attach is simple code that doesn’t do anything non-repeatable, and adding that back in to the forward/backward code gave us an example that did everything we wanted. Here it is. (This is also an example of how you can read from the PC-side (serial) without having to WAIT for an available character…)
// cont_servo by WestfW
// Based on the "Sweep" example program
// by BARRAGAN <http://barraganstudio.com>
#include <Servo.h>
Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created
void setup()
{
pinMode(9, OUTPUT);
digitalWrite(9,0);
delay(1000);
myservo.attach(9); // attaches the servo on pin 9 to the servo object
Serial.begin(9600);
}
void loop()
{
switch(Serial.read()) {
case -1: // -1 is the normal case where there is no data. Just keep going
break;
case 'f':
case 'F': // Forward
myservo.attach(9); // Possibly restart the servo PWM
myservo.write(50); // a number much less than center
break;
case 'B': // Backward
case 'b':
myservo.attach(9); // attaches the servo on pin 9 to the servo object
myservo.write(120); // a number much higher than center
break;
case 's': // Stop
case 'S':
digitalWrite(9,0); // Note that digitalWrite will turn OFF any PWM.
break;
}
delay(1000); // waits 15ms for the servo to reach the position
}