The gimbal was pretty quick to assemble, though the order of connections was critical and I found I had to take it apart and reassemble a couple times before finishing.
Connecting the servos to an Arduino requires some changes to the wiring. The critical thing is to power the servos with an external source, if you don't the Arduino will brown out when trying to move both simultaneously. I used a 6V external power supply so the servos wouldn't be powered through the USB port.
The pan and tilt motion resulted in a way wider angle than I needed. This could be useful when the thermometer needs to be placed close to the target, but lots more math would be required to account for the angle of motion. From a distance the angular motion can be translated linearly without much distortion.
I considered modifying the servos in some way, probably not gearing but maybe the resistance values of the potentiometers inside so the feedback loop would limit the rotation to a more narrow range. I needed higher torque on another project and used these external servo gearboxes from servo city, those could work but would make the gimbal much larger and more complex.
But, luckily I discovered that servos can be controlled from an Arduino with Microseconds instead of angular measurements. Even at the small angles I wanted the servos to move, microsecond signals allow for 500+ steps of movement. This is possible in the standard library, but I ultimately elected to use the alternate VarSpeed library so I could set acceleration speeds when needed.
This is the code I used to test drawing a frame around the area to be scanned, as a preview before beginning the scan.
// Michael Shaub 1/18/2017
// Based on Sweep by BARRAGAN
#include <Servo.h>
Servo myservoTilt; // create servo object to control a servo
Servo myservoPan; // create servo object to control a servo
// a maximum of eight servo objects can be created
int posTilt = 1500; // variable to store the servo position
int posPan = 1500; // variable to store the servo position
int tiltLimitUpper = 1350; //2000;
int tiltLimitLower = 950; //500;
int panLimitUpper = 1750; //2300;
int panLimitLower = 1350; //700;
boolean countDown = true;
int frameCase = 0; //state of the frame sequence
//0=Upper Left Corner, 1=Upper Right Corner
//2=Lower Right Corner, 3=Lower Left Corner
void setup()
{
myservoTilt.attach(9, tiltLimitLower, tiltLimitUpper); // attaches the servo on pin 9 to the servo object
myservoPan.attach(10, panLimitLower, panLimitUpper); // attaches the servo on pin 9 to the servo object
}
void loop()
{
frame();
delayMicroseconds(500);
}
void frame(){
switch(frameCase){
case 1: //Upper Right Corner
if(posTilt<=tiltLimitLower){
frameCase=2;
delay(5);
}else{
posTilt--;
myservoTilt.writeMicroseconds(posTilt); // tell servo to go to position in variable 'posTilt'
}
break;
case 2: //Lower Right Corner
if(posPan<=panLimitLower){
frameCase=3;
delay(5);
}else{
posPan--;
myservoPan.writeMicroseconds(posPan); // tell servo to go to position in variable 'posPan'
}
break;
case 3: //Lower Left Corner
if(posTilt>=tiltLimitUpper){
frameCase=0;
delay(5);
}else{
posTilt++;
myservoTilt.writeMicroseconds(posTilt); // tell servo to go to position in variable 'posTilt'
}
break;
default: //Upper Left Corner
if(posPan>=panLimitUpper){
frameCase=1;
delay(5);
}else{
posPan++;
myservoPan.writeMicroseconds(posPan); // tell servo to go to position in variable 'posPan'
}
break;
}
}
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.