Hi again.
This time I thought I’d write up a little device I have put together with Arduino and printed parts so that I can point a webcam in two directions. (That’s the first use I thought of, after getting the idea of trying something with two 180° servos). To achieve this, I bought two potentiometers (adjustable resistors) and set up two servos to rotate the stand.
Here’s a little video of it in operation:
How does it work?
I have two linear potentiometers, or adjustable resistors, hooked up to the Arduino. They draw power from the +5V pins, and as this voltage is passed through the pots, I can move the slider across the pots, thus regulating the voltage. At one end, I get 0.07 volts, and at the other end, I get the whole +5 volts. Anything in between is linearly adjusted between these two values. Each pot is connected to one servo, which are at right angles to each other.
I can read the setting of the slider from a third pin, which is also known as the swipe. This value, then, can be used to set the servos at any position between 0 and 180 degrees of angle. As the slider is moved, the voltage changes, and that value is passed to the servo which rotates.
After getting one servo to work, adding another was easy. Of course you can see this is a work in progtess, otherwise there wouldn’t be any Blu-Tack. Or at least there’d be less of it.
Creating the 3D printed parts
The disc
The disc is used for the horizontal rotation.
I started off by measuring the diameter of the servo axle, and creating a circle of that diameter. In general, when starting to design something that has holes in it, it’s a good idea to start with the hole. It was 6.3mm in diameter as per the data sheet of the servo. I extruded the hole into a circle, then extruded outwards to create a round plane, and gave it a diameter of 70mm. A quick extrude up gave me a thickness of 3mm, which is fine for this light load bearing part.
I then created a set of narrow cubes and used a boolean operation to deduct their volume from the disc, using the cubes a s a drill or a punch. That way, I got the slots through the disc easier than I would have by creating a set of faces on the disc, and then removing the faces and adding walls to the cavities. Come to think of it, you could also make the single flat round plane to have a large number of faces, and remove some before extruding the thickness. In Blender, there are always more than one way to skin a cat.
The disc prints in about 20 minutes.
The servo cradle
The next part is the servo cradle, which also has a round hollow axle, and is used to swing the other servo in the vertical as seen on in the video.
The servo dimensions are found in the datasheet that comes with them, so again, I started with a plane of the same footprint, then extruded out and removed the face of the plane. Extruding up for a required thickness is rather easy; the harder part is creating the hollow axle. To do this, I snapped the 3D cursor to the side of the hollowed cube, added a circle, and gave it a diameter of 6.4mm to accommodate the servo axle.
With the circle in the correct place, I extruded out to get the wall thickness, then out to get the length of the axle. I didn’t have a real plan at this stage how long the axle should be, but it’s easy enough to adjust later. Then I snapped the 3D cursor to the exact center of the hollowed box, added an Empty element, and used that to mirror the axle to the other side.
I found out after printing that I have made the first version of the cradle too tight: the servo leads do not allow the front of the servo to be slipped inside the cradle, but I’ll fix that by cutting a hole for the leads later, the cradle is solid enough to accommodate a hole like that.
Print time is about 25 minutes.
The frame
The frame gets its measurements from the thickness of the axle, so I duplicated the end of the axle into another mesh, then extruded out for some thickness, and again out to get the horizontal length of the axle. Another extrusion down will get me the height of the frame, then a mirror operation to get both of the horns of the frame, so to speak. I found out that I had made the neck of the vertical part too narrow which resulted in oozing in printing, but I have since fixed that and will reprint at some point. Probably only after I have decided whether I will just print a box under the frame and put the Arduino there – that remains to be seen.
Print time is about one hour and five minutes. I will probably redesign this part altogether, so that I have full round holders for the axle, and the foot of the frame will probably be the lid of a box. This way, I can create a container for the Arduino.
The connections
From a connections standpoint, this is a little more complex one than the 8mm scanner’s connection. There are analog inputs and digital outputs, whereas in the previous systems, I only used digital things. Arduino has a built-in analog-digital conversion, which helps things enormously. Therefore you can lead in analog data and get a numerical value for it straight away, then use the value in your digital output. In my case, I need to take analog value in, then use the resulting value in setting the servo’s pulse width, which governs the rotation angle of the servo. Confused? You won’t be after the next little tidbit of info.
There is a nice example, ReadAnalogVoltage, available on the Arduino website. I used it as the starting point of my own work.
The servo has three leads: one for ground, one for +5V of voltage, and one for controlling it. The control wire is sent electricity as pulses, and the cycle is 18 milliseconds long. Inside that cycle lies the control pulse. If the control lead is given a pulse of electricity that is 600 microseconds long, the servo will turn all the way counterclockwise. If it’s 1500 microseconds, it’ll turn 90 degrees, and if it’s 2400 microseconds, it’ll turn all the way clockwise.
The potentiometer then has three connections: one for ground, one for voltage, and one for swipe. These need to be connected to Arduino’s ground, power, and an analog pin respectively. Then we can test to see what values the analog pin receives when the system is powered up. We can use the Serial Monitor feature of the Arduino to show us that. The potentiometer is connected to the Arduino so that the Pin1 of the pot goes to the Voltage, Pin2 goes to the Signal, and Pin3 goes to the Ground pin on the Arduino.
It then appears that the range of values that the pot sends are 0 when all the way down, and 1023 when all the way up. These values need to be converted to values between 600 and 2400, that can then be sent to the servo. To do this, I wrote this little command:
float pulseLength = (sensorValue * 1.75) +600;
The 600 has to be added to the base value so that the servo is not sent a value of 0, which it cannot use. The reason for the 1.75 is that to get the full value 2400 from 1023, it has to be multiplied by 1.75 (which is 1800/1023 – where the 1800 is 2400-600). So, if the sensor gives a value of 100, the value to be
sent to Arduino is 775, a little up from the full left turn position, and if it’s 850, the control value is 2000, which is about 60 degrees clockwise from the front position.
So, all that remains to be done is to solder the connections on the potentiometer, plug them in the Arduino, and turn the switch. Let’s hope we don’t see the magic smoke that is necessary for the operation of all computers.
Here’s the full code for the first servo:
/* ReadAnalogVoltage Reads an analog input on pin 0, converts it to voltage, and prints the result to the serial monitor. Graphical representation is available using serial plotter (Tools > Serial Plotter menu) Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground. This example code is in the public domain. See */ int servoFrontPinA = 2; //this defines which pin is used for the servo int angle; // the setup routine runs once when you press reset: void setup() { // initialize serial communication at 9600 bits per second: Serial.begin(9600); // this opens the channel to the serial monitor on your computer screen pinMode(A0, INPUT); // this selects Analog pin 0 for the potentiometer value digitalWrite(A0, HIGH); // this initializes the internal resistor of the Arduino pinMode(servoFrontPinA, OUTPUT); // this sets the control pin of the servo to be in OUTPUT mode } // the loop routine runs over and over again forever: void loop() { int sensorValue = analogRead(A0); // read the input on analog pin 0: // Convert the analog reading (which goes from 0 - 1023) to a pulse length (600 - 2400): float pulseLength = (sensorValue * 1.75) + 600; // print out the value you read on your computer screen: Serial.println(pulseLength); //send Arduino the correct pulse length: pulseServoA(servoFrontPinA, pulseLength); delay(20); } void pulseServoA(int servoPin, int pulseLenUs) { digitalWrite(servoPin, HIGH); delayMicroseconds(pulseLenUs); //this actually turns the servo digitalWrite(servoPin, LOW); delay(20); }
And here’s how it works:
The next part will discuss the addition of the second servo, and the full code that runs both of them simultaneously.
Actually, I just though of another use for this thing. What if you want to do a time lapse, shooting one frame every ten seconds, and have the camera follow the Sun? Well, it’s easy with just one of these servos. All you do is calculate how long you want the horizontal servo to turn, and guide the servo accordingly. Stay tuned!