PDA

View Full Version : 2WD Robot with pid



Vendra
10-27-2013, 03:55 AM
Hey,
I need some help. I would like to do a new robot, I already did a couple but they were quite simple. Now I built a 2wd platform and bought 2 motors with encoders. I have an arduino board, a dsPIC33FJ128 MC 802 and a Raspberry Pi.
What I would like to do its to learn how to implement a good software. Something that I can improve step by step. I'd like to start with a basic control o the motors and PID and then proceed to elaborate a "map" of the environment. (Adding ultrasonic sensors, webcam and stuff)

The problem is I'm stuck Don't know where to begin. Any suggestions? Link or other stuff to read/learn could be great. Also if u want to contact me send me a pm (I can use skype)

kgranat
10-29-2013, 02:13 PM
First you should do some basic diagramming of how you want to control your robot. This will consist of some basic interace diagrams -what controller you want to use to control which sensors /actuators / systems. At this point you might consider what kind of protocols you want to use for communication (though this might change as you go along) Once you've got a small diagram, it's easier for us to give you some guidance and advice.

I think that a good game plan is to use the Arduino to run the low level hardware functions (Drive, PID, sensor management) and use the Pi to do higher level logic (mapping, deciding where to go, etc). This helps you to compartmentalize the problem, as well as use your hardware more efficiently

That being said, there's a lot you'll need to do on the Arduino Level just to get the robotic basics going - so you'll probably want to get a rover running around before you so anything with the raspberry pi at all (maybe you'll use the Pi to issue commands or a test script, but you would hold off on doing anything too complex).

Knowing that you'll be controlling the rover via an external device will help when you're designing your drive firmware on the Arduino.

Also, I would take a look at ROS and the raspberry pi
http://wiki.ros.org/ROSberryPi/Setting%20up%20ROS%20on%20RaspberryPi

Vendra
10-30-2013, 10:33 AM
Hey thanks for your reply.

First of all i think I will try to handle the PIDs with Arduino and I'm going to do some tests as soon as I can.

the point is I don't know how to handle the communication between the RPi and Arduino.
I want the RPi to elaborate its things and then decides to move forward 1 meter long.
It send arduino a string command and arduino will wun 1 meter long. But my problem is, During that move do I need the Arduino to send back the actual position? So the RPi knows the actual speed and position in the space?

For now I don't want any sensor involved (expect for the encoders) but I need to know that my code allows me to add more "routines" to listen to others sensor and so on without interfering with the PIDs. And also I want he RPi gets back its info without undesired delays.

So My first thoughts were these: How can I write a structures code for Arduino that allows me to Communicate with the RPi in a fixed time, letting Arduino at the same time compute the PID calibration (and other sensor eventually)?

And also, will the I2c bus fast enough to transmit all that stuff? Should I use something else? (SPI?)

This evening I'm going to post you some pics of my 2wd platform and maybe some code structure idea.
Thanks for helping me out, I wish I was clear enough, because my english is not my mother tongue ;)

EDIT:Got some spare time now, I added a couple of pictures.

50665065

jwatte
10-30-2013, 11:37 AM
How to structure code that can both send data, receive data, and do computations, is a skill that you have to learn through practice.

Typically, you will write a main loop that checks each thing that could have happened (the UART is free to send a byte; there's a byte available to read; it's time to make another calculation, etc) over and over again. To avoid losing bytes on the input, you probably want to use buffering on the UART in. (The Arduino Serial class may do this buffering for you if you use serial communications.)

Start with the Arduino "blink without delay" example, and work your way up from there. You will need to build a state machine that receives data until a full packet is available, and then inspects that packet to figure out what needs to be done. Separately, you will need to build a timer of some sort (like blink-without-delay) to send periodic updates about position; perhaps every 100 milliseconds or so, depending on need.

Talking between RPi and Arduino is annoying because the RPi is a 3.3V device and the Arduino is 5V. I would use the USB port on the RPi to talk to the Arduino serial port, as it's a plug-and-play solution that works.

Vendra
10-30-2013, 04:43 PM
How to structure code that can both send data, receive data, and do computations, is a skill that you have to learn through practice.

Typically, you will write a main loop that checks each thing that could have happened (the UART is free to send a byte; there's a byte available to read; it's time to make another calculation, etc) over and over again. To avoid losing bytes on the input, you probably want to use buffering on the UART in. (The Arduino Serial class may do this buffering for you if you use serial communications.)

Start with the Arduino "blink without delay" example, and work your way up from there. You will need to build a state machine that receives data until a full packet is available, and then inspects that packet to figure out what needs to be done. Separately, you will need to build a timer of some sort (like blink-without-delay) to send periodic updates about position; perhaps every 100 milliseconds or so, depending on need.

Talking between RPi and Arduino is annoying because the RPi is a 3.3V device and the Arduino is 5V. I would use the USB port on the RPi to talk to the Arduino serial port, as it's a plug-and-play solution that works.
The USB idea sounds great, so i can test from the PC and later with the RPi.

I got some ideas now, but I found an issue. Will arduino still be able to count the pulses from the motor while receiving new data? Or it will just be "blind" because he can't stop the PIDs thread until its done?

I don't think that using interrupts to count the encoder pulses would let me listen to the serial port if there's anynew instruction from the master (RPi).

Or maybe I could just keep repeating the same code using flags polling every routine once and see if has to be executed, for example:
1) Listen serial port, check new instructions store them in a buffer
2) Forward flag: if i didnt reach the value desired go on for a fixed time. Otherwise skip
3,4,5) backwards/rotate left/rotate right
6)Send back actual encoder position.

This could be the minimal code for the robot movements. I wonder if this idea could work or not. I will think about something else and see if i can find any good alternative. Then I will start testing out some code.

jwatte
10-31-2013, 11:26 AM
I don't think that using interrupts to count the encoder pulses would let me listen to the serial port if there's anynew instruction from the master (RPi).

Yes, you can -- that's what interrupts are FOR!


keep repeating the same code using flags polling every routine once and see if has to be executed

That's the general idea, yes.

Do you understand what's going on in the blink_without_delay Arduino sketch? It shows the very basics of this structure.

Vendra
10-31-2013, 01:53 PM
Yeah I do, my real thoughs now are these:
-I think I'm going to fix a maximum operation time for each block otherwise I could lose some information (from the encoders for example)
-How do I interface the encoders with Arduino? I saw there's a library but on the main page it doesnt say anything the arduino I have ( think its the diecimila version). So I have only 2 pins available for interrupts. I have 2 bi-canal encoders so I should use 4 pins.

I can't find the reference page right now so I can't link it.

Also the encoder will give me a feedback in terms of space not speed. So I'm going to derivate the space over time? and compare that value with the nominal one?

jwatte
10-31-2013, 08:40 PM
I'm going to fix a maximum operation time for each block

Yes; that is very common for real-time systems. (There's a whole set of control theory for how to build microcontroller programs for interacting with the real world!)


How do I interface the encoders with Arduino?

What I would do is tie each of the four input channels to pin change interrupts (not level interrupts.)
Inside the interrupt handler, read each of the four pins, and calculate how to increment/decrement each of the counters.

In the main loop, if the time elapsed since last velocity calculation is greater than X milliseconds, disable interrupts, copy the counter values into local variables, and re-enable interrupts (this is important because of possible un-atomic math on large integers on an 8-bit controller.) Then divide the delta in change since last time by the time interval to get momentary speed. Then store the new reading as the "last value" for the next time.


So I'm going to derivate the space over time?

Yes; that's how 99.9% of all speed encoders actually work. There ARE ways to read speed using sprung masses and inertia/centrifugal forces, but those are largely not suitable at all for these use cases AFAIK :-)

Vendra
11-01-2013, 04:15 AM
Yes; that is very common for real-time systems. (There's a whole set of control theory for how to build microcontroller programs for interacting with the real world!)



What I would do is tie each of the four input channels to pin change interrupts (not level interrupts.)
Inside the interrupt handler, read each of the four pins, and calculate how to increment/decrement each of the counters.

In the main loop, if the time elapsed since last velocity calculation is greater than X milliseconds, disable interrupts, copy the counter values into local variables, and re-enable interrupts (this is important because of possible un-atomic math on large integers on an 8-bit controller.) Then divide the delta in change since last time by the time interval to get momentary speed. Then store the new reading as the "last value" for the next time.



Yes; that's how 99.9% of all speed encoders actually work. There ARE ways to read speed using sprung masses and inertia/centrifugal forces, but those are largely not suitable at all for these use cases AFAIK :-)

Hey thanks, I think I read something about real time os few months ago, i should find those slides.

For the interrupts: I have 4 pins to connect, but only 2 interrupts pin on my board.

this is the reference page for the Library I found:
http://www.pjrc.com/teensy/td_libs_Encoder.html

So basically this will count everything for me and return me the counts values.

I wonder now if I should do a routine where I move motors to a (R,L) values where R is the space to run from the right motor and L from the left. They can be signed so I will just have one function that will do everthing. Forward/backwards /right /left.

This thought because in one of my posts I wrote about doing a routine for each movement (so basically 4 routines) but I think that is the inefficient way.

I think im going to buy a couple of mechanical encoders just to do some tests without connecting the motors and stuff.

KurtEck
11-01-2013, 09:16 AM
Note: Quite awhile ago using a different Atmega (Atmega32 with SRS board), I found using 4 interrupts for reading 2 encoders was causing me to lose lots of data as depending on your Motors and encoders, you end up with a ton of interrupts. Example if you use one of the Lynxmotion motors that lets says runs at 150rpm with 50 to 1 gearing, that implies the actual motor is running at about 7500RPM and if you then use one of their encoders that has 100 cycles per revolution is actually 400 transitions, you could have: 7500*400= 3000000 interrupts for the one motor * 2 motors = 6000000 interrupts per minute or 100000 interrupts per second. As the Arduino runs at 16mhz, that leaves you a maximum of 160 clocks per interrupt, to completely use 100% of your CPU...

On this board I found I had better results when I polled the encoders instead of using the interrupts to handle the encoder.

Easier yet, on my Rovers, I am using a Roboclaw motor controller like (http://www.basicmicro.com/RoboClaw-2x5A_p_47.html), where they have their own secondary processors to handle this for you.

Edit: SRS was Atmega16 (http://www.seattlerobotics.org/WorkshopRobot/index.php)

Kurt

jwatte
11-01-2013, 10:39 AM
For the interrupts: I have 4 pins to connect, but only 2 interrupts pin on my board.


The key to the situation here is "pin change interrupt."
All pins support pin change interrupts.

I don't agree with Kurt's math, though. It seems to be multiplying "minutes" and "seconds."

A 7500 rpm motor with 400 transitions per revolution means a (7500*400/60)==50000 transitions per second. The full interrupt latency on the AVR microcontroller is between 2.5 and 4 microseconds according to web resources, allowing between 250000 or 400000 interrupts per second, so the load will be somewhere between 12% and 20% (the actual work done in the interrupt handler adds some to this, but you should be able to get by with a dozen instructions or so.)

If you use the Arduino library, it adds significant overhead in these functions, so in the end, you may need to go to the base AVR-LIBC functions that the Arduino library is built on top of, to get to this level of performance.

The harder part is conditioning the signal. Using microcontrollers with built-in quadrature decoders would make that much easier.
When using PWM to drive a Pololu 37D gear motor with a 64 CPR encoder, here is what the signal looks like after adding a 12 nF capacitor to clean it up (as well as a 100 nF capacitor across the motor):

https://www.dropbox.com/s/20t486iop0gg2hb/2013-10-11%2016.50.16.jpg

The yellow is one of the encoder channels, the red is the actual motor drive. If you're unlucky, your MCU will detect each of those spikes as an event, which will trigger way too many counts.

KurtEck
11-01-2013, 11:36 AM
I think our math was about the same ;) ? You show 50000 interrupts (per motor) per second and I show 100000 as two motors... Also side note when I was doing it with the Seattle Robotics Society Robot back maybe 10 years ago, it was using a Wheel encoder so far less interrupts and still missing transitions.

Again not trying to say it is undoable, just you got to be careful and precise. Back then I actually did look at listing files for the exact code generated and counted clocks. If you look at code generated, for simple Interrupt 0 Arduino code, you will find some interesting stuff, example: http://billgrundmann.wordpress.com/2009/03/02/the-overhead-of-arduino-interrupts/
Which has about as simple of an C interrupt handler as possible:

#define LED_PIN 5 // digital pin #13 (portb)
#define LED_ON() PORTB |= _BV(LED_PIN)
#define LED_OFF() PORTB &= ~_BV(LED_PIN)
void myfunc() {
LED_OFF();
}
void setup() {
pinMode(13, OUTPUT);
attachInterrupt(0, myfunc, RISING);
}
void loop() {
LED_ON();
delayMicroseconds(20);
}


He found that after an there are about 51 cycles before his code is called, another 35 cycles on the return, plus what is in his code... You can shorten this up some, by going direct. Now if you go with Pin Change interrupts, it gets a bit more complicated, as there is a single interrupt for a change on any of 8 IO pins, so assuming you have more than one pin active on that interrupt, you have to figure out which pin(s) changed and process them.

Depending on your requirements for accuracy there are things you can do to reduce interrupts. Like only process one transition (either Low to high, or high to low, but not both). Also the code I did only interrupted on one channel per encoder. I then read the state of both channels. I did this to be able to detect which direction the motor is running. If channel A goes high before channel B, then the motor is going one direction and i if B goes high before A then it is going in the opposite direction. Note: Which direction depends on which motor as on the rover they are running opposite directions. But in order for this to work, you need to have the interrupt code running fast enough that you can detect the state of the two encoder channels before it changes. Assuming my math which again is rusty, at full speed, we have:
7500 *100 high pulses on Channel A per minute which is 12500 highs per second, which more or less implies that A will be high for 1/25000 of a second. Assuming the two channels are offset by 90 degrees, this implies that after A changes, B will change in 1/50000 of a second, which at 16mhz implies: 320 clock cycles. Which again is doable, but can run into issues, especially when you are servicing multiple of these plus other other stuff.

5074
Again it has been a long time, so I would trust Jwatte on this far more than me! I see the date stamp on my SRS file encoder.cpp was in 2005.

Kurt

Vendra
11-01-2013, 01:28 PM
well if I have to buy something, I would buy this http://www.robot-italy.com/it/dual-12volt-2-8amp-h-bridge-motor-drive.html this is the exact driver for my motors (EMG30 devantech). Its serial so Actually I could even connect that directly to the Pi. It has inside register for counting pulses and stuff. Also it implements a kind of speed regulator but i think its not a PID.

EDIT: wow, just see the answers, need a little time to read and think about that stuff :) What if I can find an external IC for decoding the quadrature signals?

Anyway the two motors I'm using have 360 pulses per output shaft and a full load speed of 170rpm if I'm not wrong. Should be 360*170/60= 1020 pulses per second (do i have to multiply X4? For the quadrature?)

KurtEck
11-01-2013, 02:17 PM
Note: If you already have the arduino/Arbotix to drive the motors, you might try out the code on it and see if you can get it to work. It is a lot of fun.

If I understand your motors, they are 30 to 1 max 170rpm with encoder of 360 per output shaft revolution. So if I am reading this correctly there will be a lot less interrupts than the Lynxmotion encoders. Again not 100% sure what exactly they mean by:
"Encoder counts per output shaft turn = 360"? Is it 360 Channel A highs and lows and channel B highs and lows (1440 transisition) or I think just 360 (90 A highs...). But assume 360 highs, that gives you a max of 1020 per minute versus the 12500 I mentioned in the previous post, which is a lot more manageable!

However using a board to do the work for you is easier. The one you mentioned looks good. Not sure about PID... Be careful if you hook it directly up to the RPI as I believe that the board uses 5v logic signals and the RPI is 3.3v. May be OK with I2C as the RPI should be the one driving the signals high (PU resistor). But There are other members here who are much better electrically than I am.

Kurt

Vendra
11-01-2013, 03:31 PM
Note: If you already have the arduino/Arbotix to drive the motors, you might try out the code on it and see if you can get it to work. It is a lot of fun.

If I understand your motors, they are 30 to 1 max 170rpm with encoder of 360 per output shaft revolution. So if I am reading this correctly there will be a lot less interrupts than the Lynxmotion encoders. Again not 100% sure what exactly they mean by:
"Encoder counts per output shaft turn = 360"? Is it 360 Channel A highs and lows and channel B highs and lows (1440 transisition) or I think just 360 (90 A highs...). But assume 360 highs, that gives you a max of 1020 per minute versus the 12500 I mentioned in the previous post, which is a lot more manageable!

However using a board to do the work for you is easier. The one you mentioned looks good. Not sure about PID... Be careful if you hook it directly up to the RPI as I believe that the board uses 5v logic signals and the RPI is 3.3v. May be OK with I2C as the RPI should be the one driving the signals high (PU resistor). But There are other members here who are much better electrically than I am.

Kurt









I think they mean a single pulse (for each channel) starts from rise to the next one. So I think if we have 2 change per pulse (up and down) for each channel. So i think i have 360 tick for each channel. Not sure, quite a guess

jwatte
11-01-2013, 05:03 PM
Ah, yeah, I was counting a single motor!

I agree that doing only rising edges of one pin, and using the other pin as direction, would simplify and reduce overhead (by 4x) and if you have 400 qpr, going to 100 qpr doesn't make your resolution that much worse.


you have more than one pin active on that interrupt, you have to figure out which pin(s) changed and process them.

But my point is that you just run the same interrupt handler for all, and detect the change on all pins at the same time.
You can do this with a simple look-up table; treat the two bits as a 2-bit integer, and the previous state as a 2-bit integer, and thus have a 16-entry look-up table for increment/decrement/zero-change.
Do this for both sets of pins inside the interrupt handler, and you're unlikely to miss any double interrupts or anything.

And, yes, the Arduino library does add overhead.

Let's say your're using bits 0 and 1 on port C. You then get something like this:



char delta[16] = {
0, 1, -1, 0, // from 00
-1, 0, 0, 1, // from 01
1, 0, 0, -1, // from 10
0, -1, 1, 0 // from 11
};
unsigned char prevstate;
unsigned short counter;

ISR(whatever) {
unsigned char x = (prevstate << 2) | (PINC & 3);
counter += delta[x];
prevstate = x & 3;
}


Except you'd do it for two pairs of bits, so six lines instead of three.


Also, if you want to use a controller with quadrature decoders already built in, that is SO much simpler than building your own. I'm currently using RoboClaws, but there are others out there as well. I've found a few bugs in the RoboClaws, but Nathan at Orion has been good about fixing them, which is awesome!

KurtEck
11-01-2013, 05:27 PM
JWatte,

Your table lookup stuff Looks great. Probably should work with the interrupt counts that I think his encoders should generate.

If all else fails could go with much uglier all inline polling code, where you poll everything... Not pretty, something like:


for(;;) {
if ((PINC & 3) != prevstate) {
; //do your table loop up changes
}
if (Serial.available()) {
; // read in bytes for a command and process
}
; // maybe do stuff for output to motors.
}

The above still has interrupts for reading and writing to serial port. Could remove that as well and read and write directly to registers...
Still have timer interrupt. Could again remove and check for overflow yourself and do your own large increments.

Again I would only resort to doing this iff you find that you are not able to handle the interrupts.

Kurt

Vendra
11-01-2013, 05:51 PM
Ah, yeah, I was counting a single motor!

I agree that doing only rising edges of one pin, and using the other pin as direction, would simplify and reduce overhead (by 4x) and if you have 400 qpr, going to 100 qpr doesn't make your resolution that much worse.



But my point is that you just run the same interrupt handler for all, and detect the change on all pins at the same time.
You can do this with a simple look-up table; treat the two bits as a 2-bit integer, and the previous state as a 2-bit integer, and thus have a 16-entry look-up table for increment/decrement/zero-change.
Do this for both sets of pins inside the interrupt handler, and you're unlikely to miss any double interrupts or anything.

And, yes, the Arduino library does add overhead.

Let's say your're using bits 0 and 1 on port C. You then get something like this:



char delta[16] = {
0, 1, -1, 0, // from 00
-1, 0, 0, 1, // from 01
1, 0, 0, -1, // from 10
0, -1, 1, 0 // from 11
};
unsigned char prevstate;
unsigned short counter;

ISR(whatever) {
unsigned char x = (prevstate << 2) | (PINC & 3);
counter += delta[x];
prevstate = x & 3;
}


Except you'd do it for two pairs of bits, so six lines instead of three.


Also, if you want to use a controller with quadrature decoders already built in, that is SO much simpler than building your own. I'm currently using RoboClaws, but there are others out there as well. I've found a few bugs in the RoboClaws, but Nathan at Orion has been good about fixing them, which is awesome!
So let me understand, you are saying to count only the rising edges? I don't understand where your values come from.
Also what qpr stands for? Its pulse per revolution or something?

jwatte
11-01-2013, 08:21 PM
So let me understand, you are saying to count only the rising edges?

That is one option if you want to simplify. If you count only rising (or only falling) pulses on encoder A, then the state of encoder B for each of those edges will tell you which direction you are moving in. This is highly convenient, simplifies code, at the cost of getting 1/4 the resolution.


I don't understand where your values come from.

Which specific values? In the code? The code uses the bits of the current state (two bits) plus the state of the newly read state (from the encoders) to use a look-up table to figure out whether to increment or decrement the counter. You can run this in a tight loop as Kurt shows, if you have not much else work to do (else you'll be running too slow and miss edges) or you can run this in response to pin change interrupts.


Also what qpr stands for? Its pulse per revolution or something?

quantums per revolution, so yes.

Vendra
11-02-2013, 04:25 AM
If I understand your motors, they are 30 to 1 max 170rpm with encoder of 360 per output shaft revolution. So if I am reading this correctly there will be a lot less interrupts than the Lynxmotion encoders. Again not 100% sure what exactly they mean by:
"Encoder counts per output shaft turn = 360"? Is it 360 Channel A highs and lows and channel B highs and lows (1440 transisition) or I think just 360 (90 A highs...). But assume 360 highs, that gives you a max of 1020 per minute versus the 12500 I mentioned in the previous post, which is a lot more manageable!


I really would like to avoid reducing too much the accuracy of the encoders.
Assuming its 360 Highs If i count 360*170rpm/60sec= 1020 as you were saying. Considering the change of both channels I should get 4080 changes per second for each motor?
But to do this I need 2 interrupts pin for each motor. The Arduino board I'm using actually does have only 2 of them.

So I could just count all the changes of channel A and the state of channel B simplifying a little the problem but without losing too much accuracy. I should get 1020*2 so 2040 interrupts/sec for each motor?

Is this doable?

KurtEck
11-02-2013, 10:01 AM
The simple answer is try it and see. I totally understand the desire for accuracy. Sometimes you find that it does not help too much. That is if you find handling the interrupts on both channels works to give you better accuracy, but you lose some percentage of the signals, than you might become less accurate. Also with these rovers, you might not get much slippage, but with my 4wd rovers, they rely on skid steering which guarantees that there will be slippage, so accuracy gets more interesting.

Again not sure which Arduino board you are using. Yes many only have 2 or 3 IO pins with their own Interrupt you can enable. However most/all Arduino boards that I know of support some form of Pin Change interrupt on some or all of the IO pins.

On the Atmega328 (Uno, Duemilanove, ...), I believe that all of the IO pins support this. There are 3 interrupts. For the code that jwatte setup, you should pick the IO pins, such that they are all on the same interrupt, preferably with pins 0-3 on that interrupt.

On Atmega644p (Arbotix) - Again all IO pins, on 4 interrupts.

On Atmega1280/2560 (Mega...), this is a bit more scattered. Not all IO pins, easiest to look up in boards pin data... Can deliberate if desired. Example file for standard board like uno on my machine is located at: C:\Program Files (x86)\Arduino\hardware\arduino\variants\standard

Atmega32u4(Leonardo...) - There is only 8 io pins that support this, only 4 on normal IO pins (8-11), others on ICSP connector.

If it were me, I would start simple and experiment to see what works. One of the first steps I would do, would be to figure out the right 4 pins to connect the encoders up to and wire it up. I would then setup a test program with the interrupt and/or polling methods to handle the inputs from the encoders. I might even start off simple in my interrupt handler to toggle the LED on the board each time I enter the interrupt. That way gives me some comfort that it is getting called.

Note: While playing around with several different boards found that many of them defined which IO pin is the LED so in some code bases I am now using something like:

#ifndef LED_BUILTIN
#define LED_BUILTIN 13
#endif
pinMode(LED_BUILTIN, OUTPUT);

Then my toggle is something like: digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
Note using digitalRead of OUTPUT pin may not work for this on some boards such as DUE...

Now assuming you get this to work, by hand turning the wheels, then add in the code for updating the counters. Now turn a wheel pretty close to one revolution and print out your counters. This will tell you if your assumptions about how many encoder counts per revolution is correct. I had to do this with the Orion Robotics Rover as the documentation was conflicting. Was it 30:1 or 50:1.
This also helps you to figure out if you have correct the direction of when to increment versus decrement...

When this working add in some motor support. Note: I probably would have already done this in a different test program, that allow me to try to drive around the car using some form of input... Try the rover out at different speeds. See if the counters look reasonable. Ways to figure this out include, some external counter... But also, measure how far the rover moved, compute how many revolutions of the wheel this would take, from that compute how many encoder counts that should be and compare to what you got...

Once this looks reasonable, start adding the next piece...

Kurt

Vendra
11-03-2013, 04:26 PM
Hey, I just tryed the Arduino library for the encoders. They work and what I discovered disappointed me a little. I just get 360 pulses already in quadrature so its like 90pulses per channel with 30:1 it seems like i got 3 pulse per motor shaft turn. (The motor has 3 magnets?). These motors are quite expensive i though they would be better. Im going to try some interrupts code soon..

jwatte
11-03-2013, 07:02 PM
Are your encoders on the output shaft? Most often, motor encoders are on the motor shaft, which goes before the gearbox.

Vendra
11-04-2013, 12:40 AM
Are your encoders on the output shaft? Most often, motor encoders are on the motor shaft, which goes before the gearbox.
Yes they are on the motor shaft, not the output one.

jwatte
11-04-2013, 10:15 AM
So then this observation seems incorrect:


I just get 360 pulses already in quadrature so its like 90pulses per channel with 30:1 it seems like i got 3 pulse per motor shaft turn.

Vendra
11-04-2013, 04:25 PM
So then this observation seems incorrect:
Why does it?
My encoder its on the motor shaft.
If I make a complete turn with the wheel, the encoders give me 360 pulses.
So my motor did 30 revolutions, right? so 360/30= 12 quadrature pulses from each motor turn. So each channel gives me 3 low to high changes.

Does it seems right to you?

tician
11-04-2013, 05:49 PM
Quadrature encoders have two channels (sensors) 90 degrees out of phase so you can calculate the direction instead of just speed. So, you get 180 pulses per channel per revolution of the wheel == 6 pulses (low to high transition) per channel per motor turn. Means it is probably a 12 pole molded disc magnet (6 North and 6 South alternating on one face) and each encoder channel transition (low to high or high to low) corresponds to the hall sensor being passed by the interface of two poles on the magnet (N to S or S to N, depending on hardware implementation). A 12 pole magnet is actually pretty nice. If you want higher resolution, an optical or capacitive encoder could give you better resolution, but would probably be more susceptible to dust and dirt getting into the encoder housing and other forms of interference.

Devantech EMG30 gear motor with encoder for ~$60 each, or the propulsion kit for ~$250?

jwatte
11-04-2013, 07:30 PM
If the encoder is specified as 360 tpr, that should mean 360 transitions per revolution of the encoder. If your motor encoder is specified as 360 tpr, and is attached to the motor shaft (not gearbox output shaft,) and you get only 12 transitions per motor revolution (and thus encoder revolution,) then the specification of those encoders seems wrong and/or misleading. (Unless the text that specified things made it very clear that the number was per gearbox output revolution when you bought it -- that was not clear from what I read in this thread!)

tician
11-04-2013, 08:27 PM
It states very clearly on the EMG30 product page (http://www.robot-electronics.co.uk/htm/emg30.htm): "Encoder counts per output shaft turn: 360".
The usually sparse and unhelpful robotshop product description for the EMG30 states "Encoder counts per drive shaft turn 360".
Even Vendra's post acknowledged it was 360 pulses per output shaft turn:

Anyway the two motors I'm using have 360 pulses per output shaft and a full load speed of 170rpm if I'm not wrong. Should be 360*170/60= 1020 pulses per second (do i have to multiply X4? For the quadrature?)


As for expecting better for what you paid: many prepackaged 'robot' motor assemblies/kits tend to be overpriced and underpowered. Case in point: the EMG30 is only rated for ~4W continuous output power (at ~66% efficiency) and costs ~$60.

An even more painful example is any one of the various "Nexus" robot kits. Just a bunch of crap surplus gearmotors with new opto-interrupter boards for the original injection molded encoder wheels, driven by arduino clones with a motor shield (using only outdated versions of open source arduino libraries provided only if you email them after receiving the robot and start complaining), powered by a friggin' 12V 1800mAh NiMH battery pack, and moving on custom omni-wheels or mecanum wheels with improperly shaped rollers. Yes, I am very, very bitter. For what we wasted on it, we could have bought really nice AndyMark mecanum wheels, banebots P60 gearmotors, sabertooth motor drivers, and a T-slot chassis.

CUI's 'AMT'-series capacitive modular encoders have been on my wishlist for a while, but would not be of much use until I manage to acquire new motors, gearboxes, and motor drivers for the robot in question. They come in kits with multiple sleeves to mount on several different diameter motor shafts, most have programmable resolution, and come in three flavors: quadrature (~$25) (AB and index outputs), absolute position (~$50) (also has AB and index output signals), and commutation (~$36).

jwatte
11-04-2013, 10:10 PM
Bah! Seems like the Pololu version of that similar motor/gearbox combination is a slightly better deal, at $39, with a 64 cpr encoder on the actual motor shaft. Twice the power/speed, too.
http://www.pololu.com/product/1443
(http://www.pololu.com/product/1443)
I have 50:1 and 19:1 versions of those motors, and they work as advertised. With 64 cpr on the motor shaft, precision is somewhat ridiculous -- my soft 7" RC wheels deform/slip more than the quantum tick of this encoder at 50:1 gearing...

The Pololu hole pattern (symmetric hexagon) seems better to me, too...

OK, I looked up those CUI encoders, and now I have desire... only $23 each at Digi-Key...

Vendra
11-05-2013, 12:27 AM
Quadrature encoders have two channels (sensors) 90 degrees out of phase so you can calculate the direction instead of just speed. So, you get 180 pulses per channel per revolution of the wheel == 6 pulses (low to high transition) per channel per motor turn. Means it is probably a 12 pole molded disc magnet (6 North and 6 South alternating on one face) and each encoder channel transition (low to high or high to low) corresponds to the hall sensor being passed by the interface of two poles on the magnet (N to S or S to N, depending on hardware implementation). A 12 pole magnet is actually pretty nice. If you want higher resolution, an optical or capacitive encoder could give you better resolution, but would probably be more susceptible to dust and dirt getting into the encoder housing and other forms of interference.

Devantech EMG30 gear motor with encoder for ~$60 each, or the propulsion kit for ~$250?

I got the motors outside the propulsion kit. Anyway if I have 180 changes per channel I should have 6 changes each motor so only 3 rising edges.


As for expecting better for what you paid: many prepackaged 'robot' motor assemblies/kits tend to be overpriced and underpowered. Case in point: the EMG30 is only rated for ~4W continuous output power (at ~66% efficiency) and costs ~$60.

CUI's 'AMT'-series capacitive modular encoders have been on my wishlist for a while, but would not be of much use until I manage to acquire new motors, gearboxes, and motor drivers for the robot in question. They come in kits with multiple sleeves to mount on several different diameter motor shafts, most have programmable resolution, and come in three flavors: quadrature (~$25) (AB and index outputs), absolute position (~$50) (also has AB and index output signals), and commutation (~$36).


Bah! Seems like the Pololu version of that similar motor/gearbox combination is a slightly better deal, at $39, with a 64 cpr encoder on the actual motor shaft. Twice the power/speed, too.
http://www.pololu.com/product/1443
(http://www.pololu.com/product/1443)
I have 50:1 and 19:1 versions of those motors, and they work as advertised. With 64 cpr on the motor shaft, precision is somewhat ridiculous -- my soft 7" RC wheels deform/slip more than the quantum tick of this encoder at 50:1 gearing...

The Pololu hole pattern (symmetric hexagon) seems better to me, too...

OK, I looked up those CUI encoders, and now I have desire... only $23 each at Digi-Key...

Im looking at digi key, also have an italian store, but can't figure out between all that stuff. But the prices seem interesting

KurtEck
11-05-2013, 08:41 AM
Those motors with encoders look nice. As I mentioned, the ones I have in my two rovers
5079

Which are:
Lynxmotion Rover(left): Currently they are selling: http://www.lynxmotion.com/p-653-gear-head-motor-12vdc-301-200rpm-6mm-shaft.aspx but earlier they had a more powerful motors with the encoder shafts, of which I have two of them in this rover


Orion Robotics: uses the motors: http://www.orionrobotics.com/Gearmotor-300rpm-12V-301-Ratio_p_286.html These have a bit less power (I think) than the Lynxmotion ones, especially there higher output ones.

Both of them use the USDigital Encoders that Lynxmotion sells(http://www.lynxmotion.com/p-448-quadrature-motor-encoder-wcable.aspx_ with 400qpr. Total overkill, with 30:1 gearing that is 12000 per rotation of the wheel and especially with the Lynxmotion one, I do a lot of skidding :)

Vendra
11-06-2013, 10:49 AM
So basically i have very low encoders resolution, and overprized motors too?

tician
11-06-2013, 12:22 PM
It is not horrible resolution, but it could be better. ...and the motors could be far, far worse.
The most important question is: do they work in your bot? If they can move your bot at a decent speed and under your control, use them until they die or until you find something you know is better and can be easily afforded.

Darsha's surplus gearmotors have a 64:1 gearbox and 12CPR optical encoders (12 fins on a disk for 12 rising edges and 12 falling edges per channel per revolution) with a maximum input power of 17W (doubt they are even 60% efficient). They are not great for moving around a rather heavy battery and the upgraded T-slot chassis very quickly, but they WILL be abused horribly before they get replaced.