Ghent - Belgium
Offline
Newbie
Karma: 0
Posts: 15
|
 |
« on: October 05, 2012, 05:11:26 am » |
Hi everyone I'm making a superfast(2 m/s  ) PID linefollower for school. Now, it's just a simple black line so I don't need 10 bits of accuracy. My teacher says I could change the accuracy of the ADC to 8 bit, but I don't know how to do that. He told me to look in the datasheet of the µC to see which internal register I need to change. But even IF I'd find that register, I still don't know the syntax to do it. Does anyone know how I change the 10 bit to 8 bit? Please don't tell me to get an external ADC which is faster, that's the NEXT step. I want to measure the time it takes to sample my sensor array with 8 bits of accuracy.
|
|
|
|
|
Logged
|
Oh electronics! Thou art a fickle mistress!
|
|
|
|
Global Moderator
UK
Offline
Brattain Member
Karma: 143
Posts: 19365
I don't think you connected the grounds, Dave.
|
 |
« Reply #1 on: October 05, 2012, 05:31:06 am » |
Why do you feel you need to speed up the ADC? Isn't getting on for 10000 conversions a second fast enough? (That's one conversion every 2/10 th of a mm) Now, it's just a simple black line so I don't need 10 bits of accuracy. If it is a simple black line, why do you need any more than one bit? Edit: Is the problem that you're not doing anything else during the 100 or so microseconds needed for a ADC reading (i.e, the processor is busy-waiting for a result)? This is easily addressed.
|
|
|
|
« Last Edit: October 05, 2012, 05:44:01 am by AWOL »
|
Logged
|
Pete, it's a fool looks for logic in the chambers of the human heart.
|
|
|
|
Ghent - Belgium
Offline
Newbie
Karma: 0
Posts: 15
|
 |
« Reply #2 on: October 05, 2012, 05:52:27 am » |
Why do you feel you need to speed up the ADC? Isn't getting on for 10000 conversions a second fast enough? (That's one conversion every 2/10 th of a mm) Now, it's just a simple black line so I don't need 10 bits of accuracy. If it is a simple black line, why do you need any more than one bit? I want to speed up the ADC, because it takes me about a milisecond to sample my entire sensor array. And I'm aiming for a cylce time of 4 ms (probably less) and I need every µs of that for the PID algorithm. That 4 ms cycle time results in sampling every cm(we have to be able to take turns with a 10 cm radius). I'll probably have to pick a faster µc than the 328, but I want to try if I can stretch it... And I do need more than a single bit, because I want to be able to read a certain degree of grey, to interpolate the position of the line between 2 sensors.
|
|
|
|
|
Logged
|
Oh electronics! Thou art a fickle mistress!
|
|
|
|
Global Moderator
UK
Offline
Brattain Member
Karma: 143
Posts: 19365
I don't think you connected the grounds, Dave.
|
 |
« Reply #3 on: October 05, 2012, 06:02:22 am » |
I want to speed up the ADC, because it takes me about a milisecond to sample my entire sensor array. So, you have an array of eight or nine sensors? You're still sampling every two millimetres. The analogRead (you have the source) splits neatly into four sections: 1) Setup input mux 2) start conversion 3) busy-wait for conversion to complete 4) read result. Eliminate 3), and you're probably a good way to doing what you want. Or think about using the end-of-conversion interrupt.
|
|
|
|
« Last Edit: October 05, 2012, 06:04:33 am by AWOL »
|
Logged
|
Pete, it's a fool looks for logic in the chambers of the human heart.
|
|
|
|
Ghent - Belgium
Offline
Newbie
Karma: 0
Posts: 15
|
 |
« Reply #4 on: October 05, 2012, 06:18:26 am » |
So how do I change the analogRead? I'm still a bit of a newbie, I haven't tinkered with existing instructions yet.
|
|
|
|
|
Logged
|
Oh electronics! Thou art a fickle mistress!
|
|
|
|
Global Moderator
UK
Offline
Brattain Member
Karma: 143
Posts: 19365
I don't think you connected the grounds, Dave.
|
 |
« Reply #5 on: October 05, 2012, 06:24:32 am » |
Go to the source in "wiring_analog.c"
|
|
|
|
|
Logged
|
Pete, it's a fool looks for logic in the chambers of the human heart.
|
|
|
|
Ghent - Belgium
Offline
Newbie
Karma: 0
Posts: 15
|
 |
« Reply #6 on: October 05, 2012, 06:28:24 am » |
Go to the source in "wiring_analog.c"
Sorry for being a huge noob, but where do I find the source?
|
|
|
|
|
Logged
|
Oh electronics! Thou art a fickle mistress!
|
|
|
|
Global Moderator
UK
Offline
Brattain Member
Karma: 143
Posts: 19365
I don't think you connected the grounds, Dave.
|
 |
« Reply #7 on: October 05, 2012, 06:38:37 am » |
<wherever you put the distribution>/hardware/arduino/cores/arduino/wiring_analog.c
|
|
|
|
|
Logged
|
Pete, it's a fool looks for logic in the chambers of the human heart.
|
|
|
|
Ghent - Belgium
Offline
Newbie
Karma: 0
Posts: 15
|
 |
« Reply #8 on: October 05, 2012, 07:48:57 am » |
Thanks, I found it. With a lot of help from my teacher, I was able to fix it. I'll soon post myAnalogRead here, for people who want to speed things up on their uno or duemilanove 
|
|
|
|
|
Logged
|
Oh electronics! Thou art a fickle mistress!
|
|
|
|
Ghent - Belgium
Offline
Newbie
Karma: 0
Posts: 15
|
 |
« Reply #9 on: October 05, 2012, 08:19:57 am » |
uint8_t myAnalogRead(uint8_t pin) { uint8_t low; //, high; // set the analog reference (high two bits of ADMUX) and select the // channel (low 4 bits). this also sets ADLAR (left-adjust result) // to 0 (the default). /*mask ADMUX see http://www.atmel.com/Images/doc8161.pdf point 23.9!!! set refs1 and refs0 by shifting 3(high high) six bits to the left to use the internal voltage reference shift high to ADLAR to place the most significant bits in ADCH and then mask the last nibble with the channel of the pin */ ADMUX = (0x3 << 6) | (1 << ADLAR) | pin; // start the conversion sbi(ADCSRA, ADSC); // ADSC is cleared when the conversion finishes while (bit_is_set(ADCSRA, ADSC)); // we have to read ADCL first; doing so locks both ADCL // and ADCH until ADCH is read. reading ADCL second would // cause the results of each conversion to be discarded, // as ADCL and ADCH would be locked when it completed. low = ADCL; //high = ADCH; // read the high byte return ADCH; } Then in setup, you can also set the division factor to speed things up. void setup() { setDivisionFactor(128); }
And for setting the division factor, I wrote this little void: void setDivisionFactor(byte divisionFactor) { switch(divisionFactor) { case 2 : cbi(ADCSRA, ADPS2); cbi(ADCSRA, ADPS1); sbi(ADCSRA, ADPS0); break; case 4 : cbi(ADCSRA, ADPS2); sbi(ADCSRA, ADPS1); cbi(ADCSRA, ADPS0); break; case 8 : cbi(ADCSRA, ADPS2); sbi(ADCSRA, ADPS1); sbi(ADCSRA, ADPS0); break; case 16 : sbi(ADCSRA, ADPS2); cbi(ADCSRA, ADPS1); cbi(ADCSRA, ADPS0); break; case 32 : sbi(ADCSRA, ADPS2); cbi(ADCSRA, ADPS1); sbi(ADCSRA, ADPS0); break; case 64 : sbi(ADCSRA, ADPS2); sbi(ADCSRA, ADPS1); cbi(ADCSRA, ADPS0); break; case 128 : sbi(ADCSRA, ADPS2); sbi(ADCSRA, ADPS1); sbi(ADCSRA, ADPS0); break; } }
I hope someone turns all of this in a special analogReadspeedy or something like that and introduces it into the standard Arduino library!
|
|
|
|
|
Logged
|
Oh electronics! Thou art a fickle mistress!
|
|
|
|
Global Moderator
UK
Offline
Brattain Member
Karma: 143
Posts: 19365
I don't think you connected the grounds, Dave.
|
 |
« Reply #10 on: October 05, 2012, 08:28:03 am » |
And for setting the division factor, I wrote this little void: "void" is the type of the function - you call it a "little function", not a "little void". To call it a "void" is like Prince singing "Raspberry" or "Little Red"
|
|
|
|
« Last Edit: October 05, 2012, 08:32:11 am by AWOL »
|
Logged
|
Pete, it's a fool looks for logic in the chambers of the human heart.
|
|
|
|
Ghent - Belgium
Offline
Newbie
Karma: 0
Posts: 15
|
 |
« Reply #11 on: October 05, 2012, 08:40:02 am » |
And for setting the division factor, I wrote this little void: "void" is the type of the function - you call it a "little function", not a "little void". To call it a "void" is like Prince singing "Raspberry" or "Little Red"  Sorry oh master! I shall wash my keyboard and cleanse myself of this noobishness. Anyway, thanks for the help! If you spot anything else that can be improved, please do tell me! I don't have a proper sensor yet(other teammembers are working on it), but when I do, I'll analyze which is the lowest acceptable division factor.
|
|
|
|
|
Logged
|
Oh electronics! Thou art a fickle mistress!
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 57
|
 |
« Reply #12 on: October 05, 2012, 08:47:32 am » |
"void" is the type of the function - you call it a "little function", not a "little void".
I dunno. I looked at that function and it seemed a 'little void' to me.  (Sorry it's bad joke day and I am just trying to fill my quota).
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 76
Posts: 6849
Arduino rocks
|
 |
« Reply #13 on: October 05, 2012, 08:52:33 am » |
And for setting the division factor, I wrote this little void: "void" is the type of the function No, void is the result-type of the function 
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 16
|
 |
« Reply #14 on: October 06, 2012, 01:58:24 am » |
Hi Firemann00b, Just a few design considerations before you max out on the ADC. - Do you really need to sample that fast. Controlling stuff is about controlling or changing the state they are in. Speed is a state. What is important is how fast does your robot CHANGE speed / steer. I take it it is not going to make a U-turn with a radius of 1 cm if it's doing 2 m/s. There is no point in having a very fast controller if the robot cannot comply with the commands its been given. It will cause the controller to oversteer, and can cause stability issues (oscillations)
- Fast sampling creates noisy readings. You will have to filter the readings.
- Fast sampling creates lots of data. Arduinos do not have lots of memory to store that information, nor do they have a lot of CPU power to process it in real time.
- Look ahead. Knowing what's coming gives you more time to react. Faster sampling won't.
regards, Pieter
|
|
|
|
« Last Edit: October 06, 2012, 02:48:49 am by pbrouwer »
|
Logged
|
|
|
|
|
|