PDA

View Full Version : [Question(s)] How to determine speed with arduino

ROBOTMAN
03-14-2009, 06:48 PM
I am having problems determining the speed of my robot using encoders in arduino. My encoders have 24 "clicks" per revolution. I am using a arduino dieclmile with the basic arduino environment. How do I figure out a the robots rpm in arduino code?:confused: I know I some how need to time it but I have no idea how. My input value is a simple 1 when it is on black and zero when it is on white. Dose anybody have example code for this? I keep getting stuck when I try to figure I out.:o

lnxfergy
03-14-2009, 08:56 PM
I am having problems determining the speed of my robot using encoders in arduino. My encoders have 24 "clicks" per revolution. I am using a arduino dieclmile with the basic arduino environment. How do I figure out a the robots rpm in arduino code?:confused: I know I some how need to time it but I have no idea how. My input value is a simple 1 when it is on black and zero when it is on white. Dose anybody have example code for this? I keep getting stuck when I try to figure I out.:o

I don't have a code example right now, I typically don't bother with speed control... but:

Have interrupts on each channel of your encoders, when the interrupt for either channel triggers, you increment the value of a Left or Right counter (integer). This may not be quite that simple, especially if you are using quadrature encoders, you'll have to decode them... also, if you can't use the hardware interrupts, the arduino doesnt have a library for the pin-change interrupts (but you can probably find the code out there.. I have a version on my SVN server, under avrra/library/dev/lite.h)

Once you are counting, then you probably want another interrupt, or maybe just your loop (if you are just trying to match the speeds, not find a definite speed). In there, you would compare your counts to your setpoints, and adjust your PWM values as neccessary...

-Fergs

ROBOTMAN
03-14-2009, 09:37 PM
Not sure what you mean by interrupts but I do have a counting program that counts the number of ticks that have happened. However this program is complex and slow. Not really sure what to do with this data to get speed though!

lnxfergy
03-14-2009, 09:51 PM
If you aren't using interrupts, then your program is polling, which is gonna be way slow!

http://lmgtfy.com/?q=arduino+interrupts

-Fergs

03-14-2009, 11:29 PM
Ok - so you can count ticks. Woot!

You haven't learned anything helpful in determining speed.

How big are your wheels? Aha. There's the key. Remember that the circumference of a circle is PI * Diameter or 2PIr?

ROBOTMAN
03-14-2009, 11:35 PM
15.3025 is my diameter at least that's what I got!:) Counting ticks indeed did not help me learn how to determine speed. I don't see how interrupts will help me determine speed; my program was slow because my computer was slow.

jes1510
03-14-2009, 11:47 PM
1 wheel revolution is equal to the circumference of your wheel. Use Adrenalyn's formula to find the circumference of your wheel. If the encoder is broken into 24 sections then the 1 "tick" on the encoder is equal circumference / 24 in inches traveled.

Interrupts help because they do just that. They interrupt whatever is going on in your microcontroller so that you don't miss a "tick".

ROBOTMAN
03-14-2009, 11:49 PM
Thanks! My micro controller for now is dedicated to my encoders so it should not mater much but as I expand I will switch.

lnxfergy
03-14-2009, 11:51 PM
Computer was slow? I wouldn't dare count on the computer, you should do most of the processing on the Arduino. General program is like this (I'm gonna only outline one motor, basically you have two loops like this running at the same time for your two motors):

1) Arduino counts the ticks of the encoder (via an interrupt, which is basically hardware that triggers every time the pin changes from high to low on the arduino).
2) The laptop/PC gives the Arduino a desired speed, for instance, if you wanted to go X inches forward/second, you would convert that to # of ticks per second.
3) The arduino has a update loop that runs every Y seconds. In this loop, you compare the actual # of ticks recieved from the motor to the desired #, and then adjust the output speed. Typically you would use something like PID for that.

Some considerations:
A) How often should the loop run (denoted Y above)? The more often it runs, the more accurate your speed will be (in theory), however, the speed at which ticks are generated by the encoder will govern the top speed of the loop.
B) Interrupts on the Arduino. The arduino has libraries using the two hardware interrupts the AVR has. This is probably sufficient, since they aren't multiplexed with the PWM.
C) Are you using the Arduino to give the motors PWM values? If not, you'll have to send data through the PC when you run your update loop.

-Fergs

ROBOTMAN
03-14-2009, 11:57 PM
Actually this is part of my robot butler project so the arduino will be streaming the data it gathers threw the serial port to my python code. I want the arduino to do all the math and just send something to my python code like this "A: 100" 100 being the speed and A meaning the encoder. Then my python will look at that number assess it and adjust the phidgets motor controller accordingly. Or at least thats the plan!:)

Rudolph
03-15-2009, 12:53 AM
Remember that the circumference of a circle is PI * Diameter or 2PIr?

And a happy Pi Day to you ;)

03-15-2009, 01:55 AM
Actually this is part of my robot butler project so the arduino will be streaming the data it gathers threw the serial port to my python code. I want the arduino to do all the math and just send something to my python code like this "A: 100" 100 being the speed and A meaning the encoder. Then my python will look at that number assess it and adjust the phidgets motor controller accordingly. Or at least thats the plan!:)

Yeah, as Fergs is pointing out - that's exactly the wrong way to do it.

PID needs to be done on a realtime system.

03-15-2009, 01:56 AM
And a happy Pi Day to you ;)

Happy PI day! Such a perfect day of infinite possibility!

ROBOTMAN
03-15-2009, 11:54 AM
I thought I followed what Fergs said almost exactly. The only part that was different was I am using a phidgets motor controller so I can't send my speed to the arduino. Do you mean that the arduino should tell my python code how much it is off and then my python code can just add that to the speed value?

robologist
03-15-2009, 12:26 PM
It may be that a number of folks are smacking themselves on the forehead right now, due to new information coming in. Checking your link, there appears that you are specifically using a Phidgets HC motor controller, correct? If so, why are you bothering with adding encoders? It appears that the motor controller itself measures motor rpm, probably with back emf measurements. It shows this on the Phidgets manual for the HC on page 3 (http://www.phidgets.com/documentation/Phidgets/1064.pdf). Perhaps you can access this with whatever Python code being used.

Note that folks have mentioned that real time control is more consistent, so it might be a good idea to seperate the whole motor control loop into an embedded solution, with a micro (such as the Arduino) both reading a pair of encoders, and driving the signals directly to a couple h-bridges controlling your motors. The micro should accept higher level commands from the PC such as go x speed, and perform all the lower level motor speed control needed to maintain that speed in its own control loop, periodically reporting back progress to the PC for possible odometry use.

lnxfergy
03-15-2009, 01:15 PM
I thought I followed what Fergs said almost exactly. The only part that was different was I am using a phidgets motor controller so I can't send my speed to the arduino. Do you mean that the arduino should tell my python code how much it is off and then my python code can just add that to the speed value?

The problem with putting a PC into middle of your feedback loop is that it will induce delays since the PC isn't real-time or even near real-time. What ends up happening then, is that your system will go into oscillation! The delay causes the system to think it is going too slow, so it ramps up, but it will overshoot, because it won't know it has reached the correct speed until after it has gone past it... and then it does the same slowing it back down. Because you don't know exactly how long the delay will be each time, its a non-stochastic process, you can't just tune the lag out of the system, because it's random. Tuning a feedback loop is enough of a challenge without inducing non-real-time lag.

-Fergs

lnxfergy
03-15-2009, 01:21 PM
It may be that a number of folks are smacking themselves on the forehead right now, due to new information coming in. Checking your link, there appears that you are specifically using a Phidgets HC motor controller, correct? If so, why are you bothering with adding encoders? It appears that the motor controller itself measures motor rpm, probably with back emf measurements. It shows this on the Phidgets manual for the HC on page 3 (http://www.phidgets.com/documentation/Phidgets/1064.pdf). Perhaps you can access this with whatever Python code being used.

Note that folks have mentioned that real time control is more consistent, so it might be a good idea to seperate the whole motor control loop into an embedded solution, with a micro (such as the Arduino) both reading a pair of encoders, and driving the signals directly to a couple h-bridges controlling your motors. The micro should accept higher level commands from the PC such as go x speed, and perform all the lower level motor speed control needed to maintain that speed in its own control loop, periodically reporting back progress to the PC for possible odometry use.

Hmm, I forget what the heck ROBOTMAN's initial reason for speed control was (and it appears it's in another thread and I'm too lazy to look it up...). Back-EMF can get you somewhere for sure, especially if you just need to control a relative speed of a single motor. However, I think you'd have a heck of a time getting a robot with differential drive to move forward in a straight line using Back-EMF on two channels.... Additionally, Back-EMF isn't especially accurate when used as control feeback for a metric mapping system.

I personally fell that eventually, active sensor is necessary if you want a robot to navigate large areas with a high-certainty of where it is -- and I think that is where he was going... but I don't remember.

-Fergs

ROBOTMAN
03-16-2009, 12:16 AM
Well my problems have ranged from mapping to changing speed when it switches from carpet to hardwoods;:o But it all boils down to three points and three problems.

Points:
1. Getting from "Kitchen to Dining Room" point A to point B
2. Switching from "carpet" to "hardwood" maintaining speed
3. Keeping the robot on a strait path

Problems:
1. Code:confused: WTF Call me stupid but I'm lost!
2. Code:confused:
3. Code :confused:

Oops did I say code to many times.:D
Code is the biggest problem and I am open to suggestions. All I need it to do boils down to; luck number three, points!

1. Get speed from two 1/0 encoders with 24 ticks per revolution
2. Based on this speed adjust the phidgets motor controller (My load is to heavy for a h bridge)
3. "Maybe at some point record the ticks and make a map my robot can back track"

Not to hard right!:rolleyes::D
At least thats what I thought. Now I find myself writing this huge post hoping somebody can give me a single easy solution!:o

Inxfergy is right that thing with the phidgets motor controller will be even more heavy weight than my original program!

Wow that was a long one! Hope this clarifies thing but I doubt it will.:)

ROBOTMAN
04-11-2009, 06:59 PM
Everybody probably left after that post! Oh well I think Ill go with the idea of the arduino sending speed commands to the computer and the computer speeding up the robot.

ROBOTMAN
04-11-2009, 07:29 PM
Wow I am stupid I just realized that the best answer to my question dose not answer my question. I just need to know how to get the rough speed of my motor. Not how far I have traveled! I got a new computer that runs my data gathering program fine so now I need to know what to do with it. When I say speed all I want is a number that goes up or down depending on how fast the wheel is spinning.

lnxfergy
04-11-2009, 07:43 PM
.... hoping somebody can give me a single easy solution!:o ....

You do realize that more than half of all of the effort expended on mobile robots in the last 30 years has been on the subject of localization, navigation and map building, right? I don't think a "single easy solution" exists. Sure, you can add encoders to get your speeds equal, just remember that feedback control loop tuning is still an art (not even a science yet...). Sure, you can make a robot follow a wall, with a simple map, just remove all clutter from your home.

In the end, making a robot successfully navigate a space, and have it work EVERY time, is tough. Take a look at the Trinity Fire Fighting Contest results from last weekend... out of 35 something robots in the senior division (university and professional teams), there were only 3 that successfully completed 3 out of 3 runs.... and thats in a tiny maze, with no clutter, etc.

-Fergs

ROBOTMAN
04-11-2009, 08:03 PM
I gave up localization long ago! I might try to position rfid tags in rooms so the robot knows which room it is in that is all I need to accomplish. But that wont happen for at least another year! Right now my problem is much simpler at least thats what it seems like.:) I need my robot to speed up when it hits carpet thats all! In another thread we determined that encoders would be the best way to do this. So we can forget about all the complex stuff and just work on the hardwood to carpet switch! Right?

04-11-2009, 08:28 PM
If the wheels slow down and you don't want them to, then speed up. If the wheels speed up and you don't want them to, slow down.

ROBOTMAN
04-11-2009, 09:58 PM
Well duh! Sorry. I need to be able to tell if they are speeding up or slowing down thats what the encoders are for, and if I can't convert the encoder input to some speed value then I'm screwed! It's the part where I try to determine the speed that is the problem.

04-11-2009, 11:06 PM
Why convert it to speed. Why throw away cycles?

The encoder is giving you the number of a frequency. What I like to call "dits per tick". If you have more dits per tick, you're going faster. If you have less dits per tick, you're going slower. If you have the same number of dits per tick you're going the same speed. There's no reason to go running off making conversions.

ROBOTMAN
04-11-2009, 11:10 PM
Are you saying how long it takes for the reading to switch from 0 to 1000? I think I get it now! If it prints four zeros on the black bar and 8 zeros on the white bar I have slowed down; correct me if I am wrong:)

ROBOTMAN
04-12-2009, 01:38 AM
Ok I actual tried it first before posting and it works great! I get a value that changes depending on the surface and thats all I needed! Thanks a lot everybody for the help! :)

ROBOTMAN
02-02-2011, 08:43 PM
I'm was really stupid...

[EDIT]

This thread sounds like a 3 a.m. call to tech support. They are trying to help and I have no idea what I'm talking about.