GoPro HD Camera Stabilized Mount
crazyarch93
Posts: 9
I am trying to make a camera mount for my GoPro camera that will tilt as my motorcycle leans into corners. I am using a Parallax Stamp 2 microcontroller I got from the "what's a Microcontroller" kit at RS and a dual axis accelerometer I also got at RS. I am using a HiTech 1/4 scale servo to rotate the camera. The code I am using I got on this forum somewhere (I think). It was a program to control rotation which I adjusted to work for my application.
Basically, I read the x and y delta from the accelorometer use that to get a rotation angle (the accelorometer is perpendicular to the ground). I then feed the inverse of that to the servo to rotate the camera (the camera is attached directly to the servo, as bike leans one way the camera leans the other way so it stays level).
My problem is that the setup work fine on the test bench but the accelorometer is reading bumps, wiggles, etc. and the camera goes wild in real use. Any ideas how to get rid of the "noise" would be appreciated. Am I using the wrong approach with the dual axis accelorometer? Would a gyro be better?
This is my code:
' =========================================================================
'
' File...... Rotater.BS2
' Purpose... Memsic 2125 Accelerometer Rotational Angle Measurement
' Author.... (C) 2003-2004 Parallax, Inc -- All Rights Reserved
' Edited By. Willie C. Cooper, Jr. Nov 6, 2010
' Started...
' Updated... 07 SEP 2004 (by Paralax)
' Updated... 08 Nov 2010 (by W Cooper)
' Version 3.. 14 Nov 2010 (by W Cooper)
'
' {$STAMP BS2}
' {$PBASIC 2.5}
'
' =========================================================================
'
[ Program Description ]
'
' Read the pulse outputs from a Memsic 2125 accelerometer and combine to
' calculate rotational position which is passed to a standard Paralax servo.
'
[ I/O Definitions ]
Xin PIN 8 ' X input from Memsic 2125
Yin PIN 9 ' Y input from Memsic 2125
servopin PIN 15 'Servo pin
'
[ Constants ]
' Set scale factor for PULSIN
Scale CON $200 ' 2.0 us per unit
HiPulse CON 1 ' measure high-going pulse
LoPulse CON 0
DegSym CON 176 ' degrees symbol
'
[ Variables ]
pulse VAR Word ' pulse input
pulse_hold VAR Word
xmG VAR Word ' g force (1000ths)
ymG VAR Word
brads VAR Word ' binary radians
degrees VAR Word
pulse_wd VAR Word
counter VAR Word
'
GOSUB Center_servo 'Center the servo to the level position
HIGH 14 'Blink LED Red Once
LOW 13
PAUSE 100
LOW 14 'Turn LED Off
LOW 13
PAUSE 200
HIGH 14 'Blink LED Red Twice
LOW 13
PAUSE 100
LOW 14 'Turn LED Off
LOW 13
PAUSE 200
HIGH 14 'Blink LED Red Three times
LOW 13
PAUSE 200
LOW 14 'Turn LED Off
LOW 13
PAUSE 200
' Main Program
Main:
HIGH 13 'Turn LED Green
LOW 14
DO
GOSUB Read_G_Force ' read X and Y
brads = (xmG / 8) ATN (ymG / 8) ' calculate angle
GOSUB Get_degrees
GOSUB Rotate_servo
LOOP
END
'
[ Subroutines ]
'
Read_G_Force:
PULSIN Xin, HiPulse, pulse ' read pulse output
pulse = pulse */ Scale ' convert to uSecs
xmG = ((pulse / 10) - 500) * 8 ' calc 1/1000 g
PULSIN Yin, HiPulse, pulse
pulse = pulse */ Scale
ymG = ((pulse / 10) - 500) * 8
RETURN
Rotate_servo:
IF (degrees >= 0) AND (degrees <= 60) THEN
pulse_wd = (632 - (degrees * 5))
HIGH 13 'Turn LED Green
LOW 14
ELSEIF (degrees >= 300) AND (degrees <= 360) THEN
pulse_wd = (932 - ((degrees - 300) * 5))
HIGH 13 'Turn LED Green
LOW 14
ELSE
HIGH 14 'Turn LED Red
LOW 13
ENDIF
FOR counter = 1 TO 10
PULSOUT servopin, pulse_wd
PAUSE 8
NEXT
RETURN
Center_servo:
FOR counter = 1 TO 15
PULSOUT servopin, 632 ' 194 = 0, 632 = 90, 1070 = 180
PAUSE 20
NEXT
RETURN
Get_degrees:
degrees = (brads */ 360) ' convert to degrees
RETURN
Basically, I read the x and y delta from the accelorometer use that to get a rotation angle (the accelorometer is perpendicular to the ground). I then feed the inverse of that to the servo to rotate the camera (the camera is attached directly to the servo, as bike leans one way the camera leans the other way so it stays level).
My problem is that the setup work fine on the test bench but the accelorometer is reading bumps, wiggles, etc. and the camera goes wild in real use. Any ideas how to get rid of the "noise" would be appreciated. Am I using the wrong approach with the dual axis accelorometer? Would a gyro be better?
This is my code:
' =========================================================================
'
' File...... Rotater.BS2
' Purpose... Memsic 2125 Accelerometer Rotational Angle Measurement
' Author.... (C) 2003-2004 Parallax, Inc -- All Rights Reserved
' Edited By. Willie C. Cooper, Jr. Nov 6, 2010
' Started...
' Updated... 07 SEP 2004 (by Paralax)
' Updated... 08 Nov 2010 (by W Cooper)
' Version 3.. 14 Nov 2010 (by W Cooper)
'
' {$STAMP BS2}
' {$PBASIC 2.5}
'
' =========================================================================
'
[ Program Description ]
'
' Read the pulse outputs from a Memsic 2125 accelerometer and combine to
' calculate rotational position which is passed to a standard Paralax servo.
'
[ I/O Definitions ]
Xin PIN 8 ' X input from Memsic 2125
Yin PIN 9 ' Y input from Memsic 2125
servopin PIN 15 'Servo pin
'
[ Constants ]
' Set scale factor for PULSIN
Scale CON $200 ' 2.0 us per unit
HiPulse CON 1 ' measure high-going pulse
LoPulse CON 0
DegSym CON 176 ' degrees symbol
'
[ Variables ]
pulse VAR Word ' pulse input
pulse_hold VAR Word
xmG VAR Word ' g force (1000ths)
ymG VAR Word
brads VAR Word ' binary radians
degrees VAR Word
pulse_wd VAR Word
counter VAR Word
'
GOSUB Center_servo 'Center the servo to the level position
HIGH 14 'Blink LED Red Once
LOW 13
PAUSE 100
LOW 14 'Turn LED Off
LOW 13
PAUSE 200
HIGH 14 'Blink LED Red Twice
LOW 13
PAUSE 100
LOW 14 'Turn LED Off
LOW 13
PAUSE 200
HIGH 14 'Blink LED Red Three times
LOW 13
PAUSE 200
LOW 14 'Turn LED Off
LOW 13
PAUSE 200
' Main Program
Main:
HIGH 13 'Turn LED Green
LOW 14
DO
GOSUB Read_G_Force ' read X and Y
brads = (xmG / 8) ATN (ymG / 8) ' calculate angle
GOSUB Get_degrees
GOSUB Rotate_servo
LOOP
END
'
[ Subroutines ]
'
Read_G_Force:
PULSIN Xin, HiPulse, pulse ' read pulse output
pulse = pulse */ Scale ' convert to uSecs
xmG = ((pulse / 10) - 500) * 8 ' calc 1/1000 g
PULSIN Yin, HiPulse, pulse
pulse = pulse */ Scale
ymG = ((pulse / 10) - 500) * 8
RETURN
Rotate_servo:
IF (degrees >= 0) AND (degrees <= 60) THEN
pulse_wd = (632 - (degrees * 5))
HIGH 13 'Turn LED Green
LOW 14
ELSEIF (degrees >= 300) AND (degrees <= 360) THEN
pulse_wd = (932 - ((degrees - 300) * 5))
HIGH 13 'Turn LED Green
LOW 14
ELSE
HIGH 14 'Turn LED Red
LOW 13
ENDIF
FOR counter = 1 TO 10
PULSOUT servopin, pulse_wd
PAUSE 8
NEXT
RETURN
Center_servo:
FOR counter = 1 TO 15
PULSOUT servopin, 632 ' 194 = 0, 632 = 90, 1070 = 180
PAUSE 20
NEXT
RETURN
Get_degrees:
degrees = (brads */ 360) ' convert to degrees
RETURN
Comments
That leaves only the vertical acceleration due to the bike leaning. So if I write a program to compare the acceleration and then use the vector created by the result to get a rotation. Maybe something like this (I'm working with the STAMP 2, sorry I'm a beginner!):
xg_1 - xg_2 = xg_lean
yg_1 - yg_2 = yg_lean
rads = (xg_lean / 8) ATN (yg_lean / 8)
Rot_degrees = (rads */ 360)
What do you all think? Does this sound logical?
Willie
Upside down may help
also where are you mointing the servo to the cam ?
Peter
Yes, I brought it up again because it was never actually resolved. I am amazed that it is such a stumper as it seems like such a simple thing on the surface. Seems the solutions are very complex and expensive. I guess only military and aerospace companies have resolved it and the solution is beyond the reach of the hobbist.......