For the mount parts, you can use wood and metal fittings like last time. But this time, I’d like to 3D print the parts. It’s possible to maintain stability even if the servo motor is larger by preparing a tripod with screw holes. A small tripod I designed has a directionality and can be used with just one hand.
Here is the part I 3D printed. When assembled it will look like this:
Please note that if you use ABS resin for 3D printing, shrinkage can occur when the material solidifies. This happened when I printed the parts. I noticed slight distortion and it was difficult to put the screws in when assembling each part. After several trials and errors, I decided to print the parts, which will be attached to the servo motors, separately. 3D model for the mount can be downloaded here: https://github.com/DevicePlus/ServoGimbal
When you assemble the tripod, it will look like this:
As for the case itself, it’s really up to you to know what kind of cameras you’ll mount on, etc. And the overall design of the parts can be improved/changed according to your phone type.
For the program, calibration is necessary to first tilt the acceleration sensor by 180 degrees and adjust the tilt of the servo motor based on the output value. So we improved the 17th program slightly and calibrated. Let’s try to output the numbers in an easy-to-understand manner.
It is necessary to first calibrate the accelerometer by tilting it by 180 degrees and adjusting the inclination degree of the servo motor based on the output value. Let’s improve the program in Part 1 a little so that the calibration values output in an easy-to-understand manner.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
int _maxX = 0; int _minX = 1000; int _maxY = 0; int _minY = 1000; int _maxZ = 0; int _minZ = 1000; //****************************************** //Program for acquiring accelerometer values //****************************************** void setup() { // initialize the serial monitor Serial.begin(9600) ; } void loop() { long x , y , z ; x = y = z = 0 ; x = analogRead(1) ; // X axis y = analogRead(2) ; // Y axis z = analogRead(3) ; // Z axis if(_maxX < x){ _maxX = x; } if(_minX > x){ _minX = x; } if(_maxY < y){ _maxY = y; } if(_minY > y){ _minY = y; } if(_maxZ < z){ _maxZ = z; } if(_minZ > z){ _minZ = z; } int centerX = (_maxX-_minX)/2+_minX; int centerY = (_maxY-_minY)/2+_minY; int centerZ = (_maxZ-_minZ)/2+_minZ; float rotateX = ((float)_maxX-(float)_minX)/180; float rotateY = ((float)_maxY-(float)_minY)/180; float rotateZ = ((float)_maxZ-(float)_minZ)/180; Serial.print("X:") ; Serial.print(_minX) ; Serial.print(" ") ; Serial.print(centerX) ; Serial.print(" ") ; Serial.print(_maxX) ; Serial.print(" ") ; Serial.print(rotateX) ; Serial.print(" Y:") ; Serial.print(_minY) ; Serial.print(" ") ; Serial.print(centerY) ; Serial.print(" ") ; Serial.print(_maxY) ; Serial.print(" ") ; Serial.print(rotateY) ; Serial.print(" Z:") ; Serial.print(_minZ) ; Serial.print(" ") ; Serial.print(centerZ) ; Serial.print(" ") ; Serial.print(_maxZ) ; Serial.print(" ") ; Serial.println(rotateZ) ; delay(50) ; } |
After running this program, start up the serial monitor, then tilt the sensor in the X and Y directions from -90 degrees to 90 degrees, respectively, and confirm the output value. The numerical value obtained by dividing the minimum value and the maximum value of the output value by 180 degrees becomes the inclination value of the accelerometer per degree so that it synchronizes with the operation of the servo motor.
The numerical value on the serial monitor is reflected in the program that activates the servo motor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
//******************************************** //Program 2 for acquiring accelerometer values //******************************************** #include <Servo.h> Servo myservoX; Servo myservoY; void setup() { // initialize the serial monitor Serial.begin(9600) ; myservoX.attach( 5 ); myservoY.attach( 6 ); } void loop() { int i ; long x , y; // read each data 100 times and average x = y = 0 ; for (i=0 ; i < 100 ; i++) { x = x + analogRead(1) ; // read x axis y = y + analogRead(2) ; // read y axis } x = x / 100 ; y = y / 100 ; int rotateX = (x-493)/1.30; //obtain anble myservoX.write( 90-rotateX ); Serial.print("X:") ; Serial.print(x) ; Serial.print(" ") ; Serial.print(rotateX) ; int rotateY = (y-488)/1.23; myservoY.write( 90-rotateY ); Serial.print(" Y:") ; Serial.print(y) ; // Y axis Serial.print(" ") ; Serial.println(rotateY) ; // Y axis delay(10) ; } |
So we have enough power this time but the movement of the mount is still funny…
In the video above, the accelerometer captures even the slightest shaking when you hold it with your hand. Even though the sensor axes are aligned, some unintended movements form different angles were observed. It’s crucial to address this issue to smooth the rotation and for future improvement.
The motion (or shaking) will be proportional to the weight of the camera (or smartphone). If you put small, lighter object, it will move relatively lightly, but if you put heavier object like a smartphone, shaking will be pretty bad. The program should also be improved for higher performance with improved reliability.
Our ultimate goal would be to create a gimbal as stable as the product below:
There seems to be quite a few people who are trying this with drones. Some drones can maintain stable attitude so maybe it’s more suitable for drones.
Today, we remade a horizontal camera gimbal which we previously created in Part 1 and Part 2. We made several improvements to the mechanical design of the gimbal, yet we discovered more challenges as we proceeded further with the project. We still have trouble smoothly controlling the gimbal. Let’s say it’s still in the test phase and we are not finished yet. We’ll be sure to retackle this problem in the near future and make this a functioning device.