01-15-2009, 12:40 AM
|
#201 (permalink)
|
PaulH
Join Date: Feb 2008
Location: Maricopa, AZ (sort of. Actually outside of town)
Posts: 3,832
Thanks: 1,362
Thanked 1,202 Times in 765 Posts
|
I thought of 2 worst cases. In one case, I think my method is a little faster than a control loop. In the other case, the control loop is significantly faster.
CASE 1: Parked facing up hill. Turn on car. Hit accelerator to floor INSTANTANEOUSLY.
Here's what my code does :
First iteration of loop: Throttle goes from 0 to 255 instantly (max is 255). Increment PWM duty by 1. PWM duty is now 1 (out of 255). Read current. Let's say it's 50% of MAX_CURRENT (it grows fast at low RPM. hehe). OK, no problem, because it's allowed to be 100% of MAX_CURRENT, because throttle is at 100%.
Next iteration of loop: Throttle is 255. Increment PWM duty by 1. PWM duty is now 2. Read current. Current is (let's say) OVER MAX_CURRENT! Oh No! While current > MAX_CURRENT, decrement PWM duty by 1. So, after a single iteration of that while loop, PWM duty is 1 (out of 255), and current is once again safely under MAX_CURRENT.
It is now in a sort of steady state, where PWM is right around where it should be to limit current to what it should be. Limiting the growth of PWM duty to 1 per iteration lets me get away with the "increment by 1, decrement by 1" method.
CASE 2: You are revving your motor with your wheels jacked up. The throttle is 255. The PWM duty is 255. the current is very small, let's say 1% of MAX_CURRENT. Suddenly, (you are very strong) you grab the tires and almost instantaneously stop the wheel from spinning. Suddenly, the current grows very fast, while PWM duty is 255.
Decrement PWM duty by 1. Check current. TOO HIGH!!!
Decrement PWM duty by 1. Check current. TOO HIGH!!!
Decrement PWM duty by 1. Check current. TOO HIGH!!!
Decrement PWM duty by 1. Check current. TOO HIGH!!!
...
etc. Controller is now on fire...
I think I'll use a simple PI loop where the constants are chosen so as to allow shifting and adding. Thanks, MazdaMatt!
Last edited by MPaulHolmes; 01-15-2009 at 02:46 AM..
|
|
|
Today
|
|
|
Other popular topics in this forum...
|
|
|
01-15-2009, 09:22 AM
|
#202 (permalink)
|
Master EcoModder
Join Date: Jun 2008
Location: London, Ontario
Posts: 1,096
Thanks: 0
Thanked 17 Times in 14 Posts
|
Paul, do you have any concept of how fast your main loop is running? Are you using an RTOS (i'm guessing not) or a tick timer make decisions, or just full-speed main looping it?
Do this test for us... at the bottom of your main loop, just toggle an output pin - that would compile into a single asm line so it won't slow down the loop at all, and see what that signal looks like on your scope. I'm used to running 32-bit 80MHz microcontrollers, and with main loops that are controling a dozen periferals and serial com and they are BLAZING fast (in the realm of microseconds).
Something i'd like to suggest (i'd do it for you, but i've got a busy day ahead of me and i shouldn't be posting on forums... oops) have a look at the datasheets for your processor and see if you can pair up PWM channels to create a 16-bit pwm count. That would change your resolution from 0-255 to 0-16k and allow you must neater current control. If at 0 speed you can go from half max current at 1 to over max current at 2, i think you need more resolution. If i build one, i'm definately going to find a processor with a 16-bit pwm for this reason.
|
|
|
01-15-2009, 01:35 PM
|
#203 (permalink)
|
PaulH
Join Date: Feb 2008
Location: Maricopa, AZ (sort of. Actually outside of town)
Posts: 3,832
Thanks: 1,362
Thanked 1,202 Times in 765 Posts
|
I was just kidding about the 50% current at 1 and overcurrent at 2. Since I was typing out each iteration, I didn't want to type very much. Assuming no current control, a problem with overcurrent could happen with the throttle at maybe 25 or 30, assuming a direct drive 11 inch warP motor with TINY internal resistance and near zero inductance (like Ian's motor), and near zero rpm.
This is a $2 8 mHz chip. It does have 10 bit max resolution, but running at the full A/D converter speed makes the bottom 2 LSBs pretty worthless. I switched all A/D channel resolutions from 0-1023 to 0-255 mainly because it was required in order to get the PWM frequency up to 16 kHz. Then, because the throttle was now 8 bit, I made it so it could be a single 8 bit read for each input, which is twice as fast as a 16 bit read. Because I was only using 10 of the possible 16 bits, and because 2 of the bits weren't accurate at that speed, 8 seemed the way to go.
The current limiting resolution will be about 1 - 2 amps per A/D channel division. In practice, I'm told that this gives very smooth results in a car. Ian told me that his 600amp current limiting with the ATMega8 feels very smooth. He even has a worst case motor for current control. I do think it would be better with an 80 MHz chip, and 16 bit resolution. I'm just trying this at first. The Atmel ISP I'm using has an extension possible, to upgrade the STK500 to an STK600, which allows for 32 bit 150 MHz micro-controllers I believe. The STK600 is $200, so I was holding off and just keeping things simple and cheap. The fancier micro-controllers were more like $20-30 each on digikey. I've already wrecked one ATMega8... hehehe.
I'll see what the loop speed is by this weekend (toggling an output. great idea!). I haven't seen anything in the 300 page (aaahh!!!) ATMega8 PDF on using 2 8 bit PWMs to get 16 bit.
|
|
|
01-15-2009, 03:52 PM
|
#204 (permalink)
|
PaulH
Join Date: Feb 2008
Location: Maricopa, AZ (sort of. Actually outside of town)
Posts: 3,832
Thanks: 1,362
Thanked 1,202 Times in 765 Posts
|
Quote:
Originally Posted by MazdaMatt
Are you using an RTOS (i'm guessing not) or a tick timer make decisions, or just full-speed main looping it?
|
I'm just using a full-speed main loop. No operating system. Each A/D conversion takes about 0.25 microseconds. The main loop is basically 4 if..thens, 2 sums, 1 shift, a bitwise and, a bitwise or, and a loop of less than or equal to 8 iterations (normally 1 or 2 iterations) which has an A/D conversion, 2 if..thens, a shift, and an addition. All are 8 bit operations.
Each instruction takes about 0.125 microseconds. I need to do a real time measurement, though.
Last edited by MPaulHolmes; 01-15-2009 at 04:10 PM..
|
|
|
01-15-2009, 06:11 PM
|
#205 (permalink)
|
Master EcoModder
Join Date: Jun 2008
Location: London, Ontario
Posts: 1,096
Thanks: 0
Thanked 17 Times in 14 Posts
|
I'm not knocking your cpu... just thinking out "loud" because i can easily scoop a variety of freescale CPU's from work and have sources for cheap boards and whatnot... i am getting pretty interested in messing with this stuff... just busy at home right now. I will keep inputting on your project as i can... don't back up and start over on my account, do what you're doing and when i can, i'll try to give you more solid additions, like control loops and "fake realtime" code structure... they'll help, but you don't need them right now. It looks like you're doing an awesome job and your biggest hurdle is definately hardware IMO...
|
|
|
01-16-2009, 12:36 AM
|
#206 (permalink)
|
PaulH
Join Date: Feb 2008
Location: Maricopa, AZ (sort of. Actually outside of town)
Posts: 3,832
Thanks: 1,362
Thanked 1,202 Times in 765 Posts
|
Thanks, MazdaMatt!!! I really appreciate all your input. I tested out the controller with a sort of fast, technician's PI loop. Now, in the worst case scenario above, where the wheel is spinning with PWM duty of 100%, and very low current, and instantly stopping the wheel, instead of like 230 iterations to getting current under control, it takes about 7 or 8. And under normal circumstances, it takes 1 or 2 iterations to get current under control.
for (i = 0; i < 8; i++) {
// check current
ADCSRA |= 64;
while (ADCSRA & 64); // Do nothing until the conversion is done.
current = ADCH;
if (current > currentLimit) {
correction = (1 << i);
if (gentleThrottlePos >= correction) {
gentleThrottlePos -= correction;
OCR1AL = gentleThrottlePos;
}
else {
gentleThrottlePos = 0;
OCR1AL = 0;
return;
}
}
else {
return; // Ya! Current is under control.
}
}
So, under all normal circumstances, getting current under control is a matter of dropping gentleThrottlePos by 1 or 2. In a catastrophic situation as described above, gentleThrottle gets dropped by 1, 2, 4, 8, 16, 32, 64, 128. (their sum is 255). At each stage, it checks to see if current has gotten under control. If it is, then it exits out of the loop and moves on.
By the way, I would love to hear some suggestions on good boards that can program in system. Also, suggestions on nice fast 32 bit 16 bit resolution A/D channel stuff.
|
|
|
The Following User Says Thank You to MPaulHolmes For This Useful Post:
|
|
01-16-2009, 01:00 AM
|
#207 (permalink)
|
EcoModding Lurker
Join Date: Jan 2009
Location: ARKANSAS
Posts: 18
Thanks: 0
Thanked 0 Times in 0 Posts
|
Quote:
Originally Posted by bennelson
I'm sensing an EcoModder Open Source Car Project™ coming on here.....
Paul, maybe you wanted to keep around the "baby PWM driver".
You could put it on your dashboard so that as you spin the engine up and down, the LEDs get brighter to indicate your power. Might be a cool motor indicator!
|
Here's a thought.... substitute the LED with an LED bar graph, stand it on end in the dash, and use that as a tachometer!! LOL
__________________
I always did want to play around with this stuff, now I have a chance to do so
|
|
|
01-16-2009, 01:08 AM
|
#208 (permalink)
|
Moderate your Moderation.
Join Date: Nov 2008
Location: Troy, Pa.
Posts: 8,919
Pasta - '96 Volkswagen Passat TDi 90 day: 45.22 mpg (US)
Thanks: 1,369
Thanked 430 Times in 353 Posts
|
LOL - I got the correct notation in my email - but the forum ate the spaces again.
And, although I can't code, and know not alot about programming in general, I can actually read and understand most of that... what language is it?
PS - in my email, I saw this:
*
.......for (i = 0; i < 8; i++) {
...............// check current
...............ADCSRA |= 64;
...............while (ADCSRA & 64); // Do nothing until the conversion is done.
...............current = ADCH;
...............if (current > currentLimit) {
.......................correction = (1 << i);
.......................if (gentleThrottlePos >= correction) {
...............................gentleThrottlePos -= correction;
...............................OCR1AL = gentleThrottlePos;
.......................}
.......................else {
...............................gentleThrottlePos = 0;
...............................OCR1AL = 0;
...............................return;
.......................}
...............}
...............else {
.......................return; // Ya! Current is under control.
...............}
.......}
*
By the way, the exact posting background color code is #F5F5FF, for anyone interested. I hate reading page source.
__________________
"¿ʞɐǝɹɟ ɐ ǝɹ,noʎ uǝɥʍ 'ʇı ʇ,usı 'ʎlǝuol s,ʇı"
|
|
|
01-16-2009, 01:21 AM
|
#209 (permalink)
|
EcoModding Lurker
Join Date: Jan 2009
Location: ARKANSAS
Posts: 18
Thanks: 0
Thanked 0 Times in 0 Posts
|
Quote:
Originally Posted by Christ
LOL - I got the correct notation in my email - but the forum ate the spaces again.
And, although I can't code, and know not alot about programming in general, I can actually read and understand most of that... what language is it?
PS - in my email, I saw this:
*
.......for (i = 0; i < 8; i++) {
...............// check current
...............ADCSRA |= 64;
...............while (ADCSRA & 64); // Do nothing until the conversion is done.
...............current = ADCH;
...............if (current > currentLimit) {
.......................correction = (1 << i);
.......................if (gentleThrottlePos >= correction) {
...............................gentleThrottlePos -= correction;
...............................OCR1AL = gentleThrottlePos;
.......................}
.......................else {
...............................gentleThrottlePos = 0;
...............................OCR1AL = 0;
...............................return;
.......................}
...............}
...............else {
.......................return; // Ya! Current is under control.
...............}
.......}
*
By the way, the exact posting background color code is #F5F5FF, for anyone interested. I hate reading page source.
|
Looks like just good ol C++ TO ME
__________________
I always did want to play around with this stuff, now I have a chance to do so
|
|
|
01-16-2009, 01:32 AM
|
#210 (permalink)
|
PaulH
Join Date: Feb 2008
Location: Maricopa, AZ (sort of. Actually outside of town)
Posts: 3,832
Thanks: 1,362
Thanked 1,202 Times in 765 Posts
|
Quote:
Originally Posted by tech2
Here's a thought.... substitute the LED with an LED bar graph, stand it on end in the dash, and use that as a tachometer!! LOL
|
I think that would work! Awesome idea! It would look way cooler than a tachometer too! I'm going to try that.
|
|
|
|