PDA

View Full Version : angular speed and gyrometer



fefenin
- 24th March 2007, 11:02
hi,
i m a beginner with picbasic ,
i'm actually using a head mounted display (iglasses) and i'd like to make a gyro track sensor,i've got my program running with a tokin sensor on a 10bits adc from pic 16f88 i can display the value of the sensor but i really don t have a clue how to change this value (around 459) to an angle.

looks like i have an angular speed proportionnal voltage out of my sensor
the center value is 2.200 volts and when i move the sensor one way at different speed i can change this value +or - of 2.200


can anybody help me??

ps: i did google around a search on this web site but i didn 't found anything serious

i m sorry for my very basic english!

thank's
fefenin

mat janssen
- 24th March 2007, 11:36
Does that sensor have a type number or a brand name. Maybe that than a point to look further for the data!

fefenin
- 24th March 2007, 11:48
yep it does have something:

tokin 5AB1
tokin website had some datasheet for devices close to mine but not quite the same

all i know is that it is powered with 5v and the static output is around 2.4v

here there is a linkhttp://www.pgoelz.com/piccolo_piccoboard_troubleshooting_guide.html

my sensor come from this device "the piccoboard" i just kept the sensor itself because the rest of the board was dead

fefenin

fefenin
- 24th March 2007, 11:56
i m sorry but i just realised by reredind the web page taht the new gyro is probably very similar to the one i have exepted it has a 3 volt power suply

here is the link:

http://www.nec-tokinamerica.com/products/PDF-New-Products/pd-057e.pdf

my mistake

fefenin

mat janssen
- 24th March 2007, 12:29
The spec. says 0,66 mV/deg/sec. maybe this is for your sensor the same value.
This is something you can test by yourselves.

fefenin
- 24th March 2007, 13:04
yes i can see that with my oscillospope and stuff but i have no clue how to handle this in my soft
i have an angular rate i just put it in a variable from 10bit adc i can debug it and see the variation when i move the sensor but after what math can i use to transform that in a rotation angle of for example 180° to move a servo??

fefenin

mat janssen
- 24th March 2007, 13:19
Yes, that is possible.

fefenin
- 24th March 2007, 14:30
i know that is possible but what i ask is how i could do
and if people good in programming (not like me) have some ideas

thank ' s for your help
fefenin

skimask
- 24th March 2007, 14:50
i know that is possible but what i ask is how i could do
and if people good in programming (not like me) have some ideas

thank ' s for your help
fefenin

You probably have to get a book on some pretty good math here.
It's called integration. If I know I've been accelerating for 10 seconds and a rate of 10 feet per second, then I know at the end of 10 seconds I'll be moving 100 feet per second and I'll have travelled 50 ft ('cause I started at 0 and now I'm at 100 and the acceleration was constant).
The big thing with integration is the speed at which you integrate. It doesn't do any good if you look at a signal once a minute 'cause you may have been going 100 mph for 50 seconds of that minute, but may have started and ended that minute at 0 mph. Make any sense? Same thing goes with an angular sensor. If I know I started the time at 0 degrees position and zero degree per second of rotation, and now I know I'm rotating at 10 degrees per second, and now it's one second later, then I should know that I've rotated 5 degrees and I'm rotating at 10 degrees per second. So, in another second, I'll be at 15 degrees position, and still be rotating at 10 degrees per second, assuming I haven't had a change in rotational speed.

Problem with this, is that no matter how good you think your math is, over time, your position will be off (especially using integer math like in PBP). You need some way to reset your position to zero (or some known angle). In the Nintendo Wii, the WiiMote uses those 2 IR LEDs from the sensor bar and the small sensor in the front of the WiiMote for just that...to reset the 'level angle' (for lack of a better term).

So, for this to work effectively, you need, at the very least, a few things:
A tight A/D with lots of bits, a fast sampling rate of your sensor, good floating point math, fast processing speed (a PIC is ok, but a dsPIC would be much better).
But if you're just playing around, trying to get something to work...heck ya, a PIC and all it's internals should be perfect. You just have to write some integrating code like I described above and you're set.
Hope you got a couple of ideas out of this...good or bad :)

fefenin
- 24th March 2007, 15:03
yes that 's an explaination i'll try to do something with what i have already
so that would be a pic16f88 a 8mhz and it's internal 10bit adc and i should probably set it up with -vref and +vref for better range
i ll try to work on it but it very blur for me i m fearly new on it

thank's again

skimask
- 24th March 2007, 15:13
yes that 's an explaination i'll try to do something with what i have already
so that would be a pic16f88 a 8mhz and it's internal 10bit adc and i should probably set it up with -vref and +vref for better range
i ll try to work on it but it very blur for me i m fearly new on it

thank's again

Well, if you power your PIC and the gyro off the same power supply, you shouldn't need to change your Vref's, since everything will 'drift' together. And on another note, I just bought an Eflight Blade CP Pro. To get a good center, there's a light on the side of the PCB that blinks, tell me not to move the heli while it 'finds it center'. You could easily do the same thing I'm sure, don't move it for X seconds after powering up, or hitting a button or something.

And a PIC16F88 @ 8mhz (2 MIPS) would probably get you started and in the ball park, but I don't see it accomplishing anything you'd be totally amazed at. Once you get a good basic project working, I'd suggest switching over to a PIC18F1320 (or something similar) and going as fast as you can with it (40mhz), to get some really kickin' results.

Have you had a look at the ADXL330 (www.sparkfun.com and other sites, same part used in the WiiMote)? X,Y,Z outputs, basically the same thing you've got, but better, and a lot more documentation. And it's relatively cheap.

fefenin
- 24th March 2007, 15:41
yes i had a look a sparkfun.com and the devices they sell seems very good for what i plan to do next, but for the moment i just want to sense the motion of my head and send it by the ppm signal of my radio to get it on my receiver it should move a servo that move a camera who send the signal to my head mounted display(i know that's a long sentence)

i think that should be enought accurate with the need of a reset button of course.

the ppm sending part is already running with my equipement (just need to put a value from 0 to 1200 in every channel variable)


here is my code:
define OSC 4
OSCCON=%01100000 'pour f88 pic oscillateur interne config marche pas sans ca
output portB.0 'suncro led
output portb.1 'ppm out
input porta.0 'gyro 1
output porta.2 'lcd

ANSEL=%00000001

ADCON1.7=0 ' Left justified bits (10-bits ADRESH=Left ADRESL=Right)
PAUSE 10

ADCON1=%00000000 ' Switch ON an0 A/D's with Vdd as Reference

' A/D 0
ADCON0 = %10000001 ' 20 MHz, Channel 0

'variable for adc
AD0H VAR BYTE ' High Byte 0 - 255
AD0L VAR BYTE ' Low Byte 0 - 255
AD0 VAR WORD ' AD0 word (10 bits)

'need to put fosc2-1 = 100 that means r7 and r8 is i/o et xtal is internal
ch1 var word 'word = 256bit value or 65000 dec val i think
ch2 var word
ch3 var word
ch4 var word
pan var word
tilt var word
ch7 var word
ch8 var word
chsyncro var word
chseparator con 300'296 'with the pauseus it is 0,3ms or 300us
servotest var word
A var word
'change those value for more angles 90° 120°
servomin con 400'700
servomed con 1000 'this is med
servomax con 1600'1700

'channels goes from 0.7ms to 1.7ms min to max
'so that's sounds good with the 0.3ms, entire signal varies from 1ms to 2ms
'neutral without interchannel minipulse is 1,2ms and 1,5ms with minipulse

'i assume that 1200 would be the neutral 1,2ms with the pauseus instruction

'initialise servo position
'put pan servo inthe middle
ch1 = servomed
ch2 = servomed
ch3 = servomed
ch4 = servomed

pan = servomed'is ch5
tilt = servomed'is ch6
ch7 = servomed
ch8 = servomed







gosub lcd_init 'goto lcd init

' Send the ASCII value of B0 followed by a linefeed out Pin0 serially at 19200 baud
SEROUT2 PORTA.2,32,["headtrack ppm adc"]
pause 1000



main:

ReadAD:

ADCON0.2 = 1 ' Start conversion

pauseus 10

AD0H = ADRESH
AD0L = ADRESL
AD0=(AD0H*4)+(AD0L/64)
'ad0=((ad0-460)*10)+ servomed
pan = ad0
SEROUT2 PORTA.2,32,[$A3,$01] 'clear alcd and locate in 0,0
SEROUT2 PORTA.2,32,["value is:",dec pan]
pause 10





'is all servo test mode

'for servotest = servomin to servomax step 5 'start to the min angle and go to max angle progressivly
'ch1 = servotest
'ch2 = servotest
'ch3 = servotest
'ch4 = servotest
'pan = servotest
'tilt = servotest
'ch7 = servotest
'ch8 = servotest
'gosub ppmtrame
'next

'for servotest = servomax to servomin step -5 'start to the min angle and go to max angle progressivly
'ch1 = servotest
'ch2 = servotest
'ch3 = servotest
'ch4 = servotest
'pan = servotest
'tilt = servotest
'ch7 = servotest
'ch8 = servotest
'gosub ppmtrame
'next
'goto main





'send ppm trame and high del0 during chsyncro time
ppmtrame:

'protection against overrange
if ch1 > servomax then ch1 = servomax 'protection cannot go upper than servomax value
if ch1 < servomin then ch1 = servomin 'protection cannot go less than servomin value

if ch2 > servomax then ch2 = servomax 'protection cannot go upper than servomax value
if ch2 < servomin then ch2 = servomin 'protection cannot go less than servomin value

if ch3 > servomax then ch3 = servomax 'protection cannot go upper than servomax value
if ch3 < servomin then ch3 = servomin 'protection cannot go less than servomin value

if ch4 > servomax then ch4 = servomax 'protection cannot go upper than servomax value
if ch4 < servomin then ch4 = servomin 'protection cannot go less than servomin value

if pan > servomax then pan = servomax 'protection cannot go upper than servomax value
if pan < servomin then pan = servomin 'protection cannot go less than servomin value

if tilt > servomax then tilt = servomax 'protection cannot go upper than servomax value
if tilt < servomin then tilt = servomin 'protection cannot go less than servomin value

if ch7 > servomax then ch7 = servomax 'protection cannot go upper than servomax value
if ch7 < servomin then ch7 = servomin 'protection cannot go less than servomin value

if ch8 > servomax then ch8 = servomax 'protection cannot go upper than servomax value
if ch8 < servomin then ch8 = servomin 'protection cannot go less than servomin value

'calcul de chsyncro
'22000-4 for errors = 21996
chsyncro =21996-((chseparator*8)+ch1+ch2+ch3+ch4+pan+tilt+ch7+ch8-10)

'start sending the ppm frame:
high portb.0 'begining of the syncro del is on
high portb.1
pauseus chsyncro
low portb.1
low portb.0 'ending of the syncro del is off
pauseus chseparator 'should be 3us low state between channels
high portb.1
pauseus ch1
low portb.1
pauseus chseparator 'should be 3us low state between channels
high portb.1
pauseus ch2
low portb.1
pauseus chseparator 'should be 3us low state between channels
high portb.1
pauseus ch3
low portb.1
pauseus chseparator 'should be 3us low state between channels
high portb.1
pauseus ch4
low portb.1
pauseus chseparator 'should be 3us low state between channels
high portb.1
pauseus pan
low portb.1
pauseus chseparator 'should be 3us low state between channels
high portb.1
pauseus tilt
low portb.1
pauseus chseparator 'should be 3us low state between channels
high portb.1
pauseus ch7
low portb.1
pauseus chseparator 'should be 3us low state between channels
high portb.1
pauseus ch8
low portb.1
pauseus chseparator 'should be 3us low state between channels
'stop sending the frame
'return
goto main



'the lcd routine initialisation
lcd_init:
SEROUT2 PORTA.2,32,[$A3,$01] 'clear alcd and locate in 0,0
SEROUT2 PORTA.2,32,[$A1,2,0] 'locate in x,y
SEROUT2 PORTA.2,32,[$A3,$0A] 'stop blinking cursor
'SEROUT2 porta.1,32,[$A3,$0B] 'blink cursor
SEROUT2 PORTA.2,32,[$A3,$0C] 'hide cursor
'SEROUT2 PORTA.1,32,[$A3,$0E] 'show cursor
return

end

fefenin

fefenin
- 24th March 2007, 18:25
if anbody has a piece of code as an example for me that will be nice i found it hard to do

skimask
- 24th March 2007, 21:34
if anbody has a piece of code as an example for me that will be nice i found it hard to do

Apparently, you've only been at it for a day.
Jeeze...nobody finishes a project in a matter of hours. Give it some time...

fefenin
- 25th March 2007, 13:03
ok i get it
i already try harder
will see
i ll tell you when it is done you could probably help me after to get it optimised


bye

skimask
- 25th March 2007, 16:23
ok i get it
i already try harder
will see
i ll tell you when it is done you could probably help me after to get it optimised


bye

That's better. And no 'free help' here...
Don't tell 'ME' when the code is done and don't expect 'ME' to help you optimize it.
Post to the whole 'FORUM' that the code is done and ask the whole 'FORUM' if anybody has any suggestions for optimizations.
And I don't see anything substantial in that code above...just a few statements testing this and that. It's like saying:
"I building a car. Here's a spare tire, a seat, and a steering wheel cover. Oh, I have to pick up a few things yet, but I'm practically done."
There's nothing about angles, nothing about integration, no 'real' math, etc.etc. I could go on and on...

fefenin
- 25th March 2007, 17:27
i know there is no math yet i just post the soft working for sending ppm trame with my radio,there is still the angle soft and stuff like you said.

i found you a bit hard with me i told you i m very new in programing and very bad in math

i m actually working on the math part (trying some things like test adc value one time and just straight after an other test so i have to values)

i m probably in the right way to make that works



thank s again all

skimask
- 25th March 2007, 17:33
i know there is no math yet i just post the soft working for sending ppm trame with my radio,there is still the angle soft and stuff like you said.
i found you a bit hard with me i told you i m very new in programing and very bad in math
i m actually working on the math part (trying some things like test adc value one time and just straight after an other test so i have to values)
i m probably in the right way to make that works
thank s again all

Yep, but then again, sometimes, that's what it takes...a bit of drilling before it finally sinks in...
But I do have to reiterate...once you get something you think is good, I'm positive a bunch of us will be more than happy to look it over to obvious (and not so obvious) mistakes or logic problems, as long as we've got a good explanation of what the end result is supposed to be...
Now, going with that...
You said you're using a radio setup to move a servo remotely. You also said you're a beginner. I don't know how much of a beginner you are, but I can see a problem coming up....that is...trying to do too much at once.
Build it up in steps...and I think most importantly, keep the radio link as the very last step. Get the A/D working, make the servo move, make the servo move with the A/D, etc.etc.etc. I think you get the picture...

fefenin
- 26th March 2007, 16:07
ok so if i anderstood:

my value a first is , lets say 2.267volts it s is my first value
if i take two mesurement separeted by 1 i know that, if the second one is differente than the first one,i moved isnt it?
so if i moved i probably want to know the angle (how many degrees i traveled)

lets say the second mesurement is 2.320volts that probably means i moved one way (actually left)

i know that the sensor sensibility is 0.66mv/deg/sec

my mesurement is spaced by 1s so i probably moved 2.320-2.267=0.053v so 53mv that would say i moved around 80,3 deg is that right?


if i m right then i could do mesurement spaced by 10 us it will be better for me

and how can i do something proper with only a 16f88 without proper math (integer) calcualtion?

skimask
- 26th March 2007, 16:42
my value a first is , lets say 2.267volts it s is my first value
if i take two mesurement separeted by 1 i know that, if the second one is differente than the first one,i moved isnt it?
so if i moved i probably want to know the angle (how many degrees i traveled)

lets say the second mesurement is 2.320volts that probably means i moved one way (actually left)

i know that the sensor sensibility is 0.66mv/deg/sec

my mesurement is spaced by 1s so i probably moved 2.320-2.267=0.053v so 53mv that would say i moved around 80,3 deg is that right?

if i m right then i could do mesurement spaced by 10 us it will be better for me

and how can i do something proper with only a 16f88 without proper math (integer) calcualtion?

You can't do it proper with integer math. But what you can do is multiply all of the numbers by 10 or 100 or whatever (whatever WON'T cause an overflow in the middle somewhere), then divide the end result by whatever you multiplied it all UP by.

As far as you're math goes...you've ALMOST got it, ooo sooo close..Example..
You start at time 0 - moving at 0 degrees/second
You measure at time 1 - and see the sensor is at a rate of (in your example) 80.3 degrees/second.
That doesn't mean you moved 80.3 degrees, actually it should mean (assuming the angular acceleration was absolutely constant) that you moved 40.15 degrees/second.
Look at it this way...if I accelerate from a stop at a rate of 10 feet per second during every second, at the end of 1 second, I'll be MOVING at 10 feet per second, but I'll only haved MOVED 5 feet, like an average between start and stop. (I'm looking for a word or a phrase to throw out, but I can't think of it at the moment).
And yes, the less the time between successive measurements, the tighter you end result will be.

fefenin
- 26th March 2007, 17:23
ok i get the idea for the average of my rate,
but now how can i do if i don t have a clue how fast i move (not a constant acceleration)

there is tyle an unknow parameter


for the moment i m trying that:

main:

ReadAD:

ADCON0.2 = 1 ' Start conversion

AD0H = ADRESH
AD0L = ADRESL
AD0=(AD0H*4)+(AD0L/64)

pause 1000

ADCON0.2 = 1 ' Start conversion

AD1H = ADRESH
AD1L = ADRESL
AD1=(AD1H*4)+(AD1L/64)

SEROUT2 PORTA.2,32,[$A3,$01] 'clear alcd and locate in 0,0
SEROUT2 PORTA.2,32,["ado:",dec ad0]
SEROUT2 PORTA.2,32,[$A1,0,1]
sEROUT2 PORTA.2,32,["ad1:",dec ad1]

if ad0 > ad1 then
pan= ad0-ad1
SEROUT2 PORTA.2,32,[$A1,0,3]
sEROUT2 PORTA.2,32,["pan: +",dec pan ]
endif

if ad1 > ad0 then
pan= ad1-ad0
SEROUT2 PORTA.2,32,[$A1,0,3]
sEROUT2 PORTA.2,32,["pan: -",dec pan ]
endif


goto main


i can get a result but the variation of pan is very low from -60 to 60 if i move the sensor very fast

if think i should use +vref and - vref cause it ll be more accurate

i don 't know

i just HATE math

skimask
- 26th March 2007, 17:38
That's where getting an accurate sample as fast as you can comes into play.
But, with the A/D on a PIC, you can sample too fast and kill your accuracy.
So, you've got to play with it and find a balance between sampling fast and keeping a decent amount of accuracy. Also, whether or not the acceleration is constant isn't really an issue. The speed of sampling takes care of that for you. The less time between the samples, the less chance there is of the rate of acceleration actually changing enough to matter between those samples.
That program you posted, are you saying that it's working, it's just that you can't get a decent output from it? Not large enough or what? Not 'sensitive' enough?

I just did a bit of math. Apparently, at .66mv/deg/sec, with a 10bit A/D on the PIC (5v Vref = 4.8828125mv/bit), the lowest rate you'll be able to detect would be 7.4deg/sec.
Maybe you should change your +Vref and -Vref.
How about a resistive divider running off the 5v/Ground rail. Get 3 resistors that are almost EXACTLY the same. That should be able to get you down to 2.46deg/sec.
And you could do that all day, but then you run into the problem of range. You can have one but not the other.
I think a better fix for this might be to go with an A/D with more BITS! Maybe an external 16 bit A/D (if not more!).

fefenin
- 26th March 2007, 18:04
yes as i said my changing value is not large enough it is like only 2 volts variation a low angular speed (like my head moving) so i m losing 3volts

i ll try with the resistive divider but i heard it is very bad for the temperature drifting....??

and i have a reference voltage with my sensor (pin 3) it is like 2.4v very accurate do you think i can use that in a way as a vref+ and - (with diodes or something)


thank s anyways

skimask
- 26th March 2007, 18:45
yes as i said my changing value is not large enough it is like only 2 volts variation a low angular speed (like my head moving) so i m losing 3volts

i ll try with the resistive divider but i heard it is very bad for the temperature drifting....??

and i have a reference voltage with my sensor (pin 3) it is like 2.4v very accurate do you think i can use that in a way as a vref+ and - (with diodes or something)

thank s anyways

resistive divider - I would think that as long as you have 3 resistors, same manufacturer, same age, same values, etc.etc., I would think that they'd drift fairly equally.

You may have a 2.4v Vref on your sensor, but you still have to be able to get a 'spread' at the PIC.

What's the fastest you think this sensor will ever turn (I guess the real question is how fast can you spin head?)?

fefenin
- 26th March 2007, 20:15
i really don t have any idea how fast i can spin my head but anyway ican t go quicker than the servo motor and i guess the signal is refresh every 20ms

because i just took the sensor without amplifiers the sensitivity is bad!

the bord had apparently an amplifiers just straight after the sensor mount in instrumentation amplifier (don t know the exact name in english!)

the sensor shows me very poor resolutions i ll probably need to buy a rc gyro and mesure the pulse between 1ms and 2ms and integrate it (maybe more acurate???)

i have to finished this project anyways so you ll see me later on i think!

thank's all for the moment! and again sorry for my english (not very proper)

skimask
- 26th March 2007, 21:04
i really don t have any idea how fast i can spin my head but anyway ican t go quicker than the servo motor and i guess the signal is refresh every 20ms

because i just took the sensor without amplifiers the sensitivity is bad!

the bord had apparently an amplifiers just straight after the sensor mount in instrumentation amplifier (don t know the exact name in english!)

the sensor shows me very poor resolutions i ll probably need to buy a rc gyro and mesure the pulse between 1ms and 2ms and integrate it (maybe more acurate???)

i have to finished this project anyways so you ll see me later on i think!

thank's all for the moment! and again sorry for my english (not very proper)

Sure, you could amplify the output with a simple op-amp circuit, no problem there, a hundred different ways to get a better resolution.

Signal refresh- that's probably the one going to servos, every 20ms, the capability to read the sensor with a PIC is far greater, good enough for what you're thinking about. I'd roll with the project until it worked, I wouldn't get rid of it yet.
Your english is good enough for me, most of the time anyways :)