10-08-2015, 07:46 PM
|
#2151 (permalink)
|
Permanent Apprentice
Join Date: Jul 2010
Location: norcal oosae
Posts: 523
Thanks: 351
Thanked 314 Times in 215 Posts
|
Paul - I've spent some time looking over and shuffling stuff around in sensorless.c
Mainly I've moved stuff around so it's easier to find. I totally agree this is merely a programming style thing. I like it because it makes things a bit easier to find later by someone else.
In general, it goes like this:
Include statements (include other programs, like uart.c)
Define variables
Define interrupts
Define functions
Code for interrupts
Code for functions (grouped by their tasks, like time delays, etc)
Code for Main
In doing that, I found some some definitions for things that didn't exist.. ( They were probably were deleted a while ago, but the define statements are still there.)
More importantly, I saw some stuff that could actually help the program:
1) In main, there's a bunch of stuff that could be put into functions, like general error checking and activating the contactors. That would clear up what main does.
2) The function that initializes the AtoD converter, PWM, and the QEI interface should be broken into separate functions. This would give each function a clear task as well as provide easier customization. For example, my resolver doesn't want the QEI interface.
3) Just about everything runs in the AtoD converter interrupt. This has a real potential of causing instability issues if another interrupt interrupts this interrupt. (gawd just saying that sounded confusing...) I propose breaking it up into the part that MUST get the AtoD values at a specific time, and then putting up some flag so that the other functions - for example the Clarke & Park transforms, getting rotor position, and so on are done immediately afterward, in their respective functions.
If you think these are worthwhile, let me know - I'll make it happen. This will hopefully make things easier for programmers and maybe prevent impossible to track problems. In the end, it should compile the same and the end user won't notice any difference.
- E*clipse
|
|
|
The Following 2 Users Say Thank You to e*clipse For This Useful Post:
|
|
Today
|
|
|
Other popular topics in this forum...
|
|
|
10-08-2015, 08:16 PM
|
#2152 (permalink)
|
Master EcoModder
Join Date: Sep 2010
Location: Saskatoon, canada
Posts: 1,488
Thanks: 746
Thanked 565 Times in 447 Posts
|
Quote:
Originally Posted by e*clipse
Do you have any access to a lathe, maybe through work?
If you did have a ring with magnets, do you have access to the shaft?
|
I have no access to a lathe nor skills to use it.
I DO, however, work at an industrial mill and perhaps could work out an exchange with one of our machinists. I picture a 2 inch diameter disk maybe a half inch thick - mild steel - with a few 'teeth'. An inductive proximity switch could sense the metal, but the prox would need to be within about 1/4 inch of the face 'teeth'.
I have access to the outboard (second) shaft of the DC motor. Mounting would not be a problem.
I have access, for now, to the motor shaft on the AC motor when it is coupled to the DC motor. Mounting may be a challenge for me.
There is no access to the motor shaft on the AC motor once it goes into a car besides the output shaft, which will be buried by the coupler to the transmission/clutch/etc. Mounting within the transmission housing is *WAY* beyond my skill level.
Quote:
However, it's probably much easier to get the encoder working on your existing motor.
|
Agreed. I will start with that.
EDIT - found an off-the-shelf 'target ring' - kinda pricey but if you don't have access to a machine shop .. it could be less than an encoder that will survive mounting in a car?
http://www.electro-sensors.com/produ...-pulser-wraps/
Last edited by thingstodo; 10-08-2015 at 08:31 PM..
Reason: Add link for COTS solution
|
|
|
10-08-2015, 08:46 PM
|
#2153 (permalink)
|
Somewhat crazed
Join Date: Sep 2013
Location: 1826 miles WSW of Normal
Posts: 4,355
Thanks: 526
Thanked 1,187 Times in 1,047 Posts
|
I myself would use a round target 1/2" thick in aluminum and drill / tap holes for steel hex head bolts where you need pulses. Drilling through gets you 180 degree apart holes.
Because its aluminum you could use self tapping bolts. If you need more "on" time just add steel washers under bolt head.
Btw: most sensors want to see 1/32 to 3/32 gap closer is better.
Flywheel sensor installs are pretty easy using drill and tap trick above. Really accurate too.
__________________
casual notes from the underground:There are some "experts" out there that in reality don't have a clue as to what they are doing.
Last edited by Piotrsko; 10-08-2015 at 08:51 PM..
|
|
|
The Following 3 Users Say Thank You to Piotrsko For This Useful Post:
|
|
10-08-2015, 09:19 PM
|
#2154 (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
|
The dspic has priority levels for the interrupts. 0-7. If priority(A) < priority(B), B can interrupt A, but A cannot interrupt B. I have it set so that the only thing higher than the A/D is the change notification interrupt, which is catastrophically bad if that happens(well, hardware overcurrent, which isn't so bad. haha), and you have to cycle power because the hardware has permanently disabled everything until then. So I don't think anything bad can happen. I just like to have all the stuff happen in the A/D interrupt so that I know which currents/voltages go with the FOC calculations. It could happen that outside the interrupt you use phase A current from 0.0001 seconds before, and phase B current from now, which defeats the simultaneous A/D sampling. I'm sure there's a way around it, like seeing when counter10k has incremented, but then you are having to check other stuff rather than just doing what needs to be done. My thinking was, as long as nothing bad can happen, it's OK if 99% of the time is in the A/D interrupt. The UART interrupts just have to get to the back of the bus. haha. The UART interrupts are pretty much Rosa Parks. I very much like your organizational ideas, btw. I need to be able to tear things down and try a bunch of stuff with a working copy though. Although quite a bit of stuff isn't changing, so I think it will be pretty practical for you to work on what you are talking about, and I use a copy based on something that has been reorganized.
|
|
|
The Following 2 Users Say Thank You to MPaulHolmes For This Useful Post:
|
|
10-08-2015, 09:37 PM
|
#2155 (permalink)
|
Permanent Apprentice
Join Date: Jul 2010
Location: norcal oosae
Posts: 523
Thanks: 351
Thanked 314 Times in 215 Posts
|
Quote:
Originally Posted by thingstodo
I have no access to a lathe nor skills to use it.
I DO, however, work at an industrial mill and perhaps could work out an exchange with one of our machinists. I picture a 2 inch diameter disk maybe a half inch thick - mild steel - with a few 'teeth'. An inductive proximity switch could sense the metal, but the prox would need to be within about 1/4 inch of the face 'teeth'.
I have access to the outboard (second) shaft of the DC motor. Mounting would not be a problem.
I have access, for now, to the motor shaft on the AC motor when it is coupled to the DC motor. Mounting may be a challenge for me.
There is no access to the motor shaft on the AC motor once it goes into a car besides the output shaft, which will be buried by the coupler to the transmission/clutch/etc. Mounting within the transmission housing is *WAY* beyond my skill level.
Agreed. I will start with that.
EDIT - found an off-the-shelf 'target ring' - kinda pricey but if you don't have access to a machine shop .. it could be less than an encoder that will survive mounting in a car?
Split Collar Pulser Wraps :: Electro-Sensors
|
I guess those sensor rings would be ok, but I'd be concerned about their speed rating. The standard ones are limited to 3000 rpm, the "high speed" ones are limited to 6000 rpm. I think the motor you're using is capable of about 10,000rpm, right?
The little test one I made was aluminum with slots for an optical on/off sensor. I think one of the limiting factors, believe it or not, was how fast the sensor could react. I though light was instantaneous... Also, I wouldn't call it "robust" by any stretch - especially my mounting system for the sensors.
The idea Piotrsko suggested should work, even at high speeds. A solid disk is important.
One of the advantages of a resolver is the robustness. The rotor is very simple; they use a barely off-round two or four lobe disk. If I remember correctly, all my CNC mills and lathes used resolvers for feedback. They performed very well in a wet/hot/electrically noisy/mechanically noisy environment. One of the mills had a 12,000 rpm spindle that could do rigid tapping. (not @ 12,000 rpm, but remember EVERYTHING needs to be perfectly synchronised or you break a tap.)
Take care,
E*clipse
|
|
|
The Following User Says Thank You to e*clipse For This Useful Post:
|
|
10-08-2015, 10:00 PM
|
#2156 (permalink)
|
Permanent Apprentice
Join Date: Jul 2010
Location: norcal oosae
Posts: 523
Thanks: 351
Thanked 314 Times in 215 Posts
|
Quote:
Originally Posted by MPaulHolmes
The dspic has priority levels for the interrupts. 0-7. If priority(A) < priority(B), B can interrupt A, but A cannot interrupt B. I have it set so that the only thing higher than the A/D is the change notification interrupt, which is catastrophically bad if that happens(well, hardware overcurrent, which isn't so bad. haha), and you have to cycle power because the hardware has permanently disabled everything until then. So I don't think anything bad can happen. I just like to have all the stuff happen in the A/D interrupt so that I know which currents/voltages go with the FOC calculations. It could happen that outside the interrupt you use phase A current from 0.0001 seconds before, and phase B current from now, which defeats the simultaneous A/D sampling. I'm sure there's a way around it, like seeing when counter10k has incremented, but then you are having to check other stuff rather than just doing what needs to be done. My thinking was, as long as nothing bad can happen, it's OK if 99% of the time is in the A/D interrupt. The UART interrupts just have to get to the back of the bus. haha. The UART interrupts are pretty much Rosa Parks. I very much like your organizational ideas, btw. I need to be able to tear things down and try a bunch of stuff with a working copy though. Although quite a bit of stuff isn't changing, so I think it will be pretty practical for you to work on what you are talking about, and I use a copy based on something that has been reorganized.
|
Let me just start by saying this is why I LOVE working with you! It's about getting the best result - and it's fun.
I'll try to figure out a solution for the AtoD interrupt thing. I think you have a very good point. I'll try to figure out a solution - If it's not 100%, I won't even ask.
For now, I've got things swapped around; I've split up InitAD into three separate (but right next to each other functions. I've put the fault checking in a separate function too.
I haven't done anything with the ADC interrupt except move it.
I'll double check that there aren't any stupid compiler errors, then
****edit*****
Ok, it builds! Yea! I'll just clean up some of my editing stuff....
***********
Then I'll e-mail you what I've got. If it makes sense, great - otherwise throw it back at me!
Last edited by e*clipse; 10-08-2015 at 10:14 PM..
|
|
|
The Following User Says Thank You to e*clipse For This Useful Post:
|
|
10-08-2015, 11:16 PM
|
#2157 (permalink)
|
Permanent Apprentice
Join Date: Jul 2010
Location: norcal oosae
Posts: 523
Thanks: 351
Thanked 314 Times in 215 Posts
|
Ok, file sent.
Ok, now this brings up another issue, kind of an "open source" issue, if you will.
I know this has been dealt with very well by the folks involved with Ubuntu.
How do we do this so Paul can keep blazing ahead with the sensorless and PI parts of the code, without having problems if someone adds a "blinky light" routine?
Should certain parts be "frozen"? Which parts?
Quote:
I very much like your organizational ideas, btw. I need to be able to tear things down and try a bunch of stuff with a working copy though. Although quite a bit of stuff isn't changing, so I think it will be pretty practical for you to work on what you are talking about, and I use a copy based on something that has been reorganized.
|
For now, I'll look into that interrupt and how a resolver can tie into it. No coding, just learning.
BTW, here are some interesting statistics based on the latest build:
This is for the dsPIC30F4011:
Program memory used: 31431 bytes (64%)
Data Memory used: 1830 bytes (89%)
Maximum dynamic memory: 218 bytes
- E*clipse
|
|
|
The Following 2 Users Say Thank You to e*clipse For This Useful Post:
|
|
10-09-2015, 08:46 AM
|
#2158 (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
|
The used up data memory isn't actually as used up as it seems. A lot of it is tied up in some debugging arrays that I'm using. I just made them as big as possible so that all the memory was used up. It's in a UNION in sensorless.h. As for MOSTLY frozen things, that's a good question. A couple functions in UART are constantly changing as new commands are added and taken away. Also, I keep changing the commands to really short stuff so I don't have to type so much while testing.
In the rest of the code, initialization code is pretty frozen. startup sequence is frozen. I need to automate the PI loop tuning (for all motor types) and finding of rotor time constant for case of ACIM.
To get the resolver board to work, you would replace the encoder initialization with configuring 2 of those inputs as A/D inputs. Then, maybe you could do these 4 A/Ds:
throttle
CURRENT 1
CURRENT 2
RESOLVER 1
and then one time of this:
THROTTLE
CURRENT 1
CURRENT 2
RESOLVER 2
and then back to this:
throttle
CURRENT 1
CURRENT 2
RESOLVER 1
The trouble is, AN0 is throttle, AN1 is current 1, AN2 is current 2. For the 4 simultaneous samples, AN0, AN1, AN2 must be together, and then ANx is the most flexible. unfortunately, I chose AN0 to be throttle. It would have been better to have throttle be ANx (for some x not equal to 0, 1, or 2) since it doesn't have to be done as often.
The noise on the throttle is maybe +/- 1 (sometimes 1.5) A/D ticks out of a range of 1024, which doesn't need a whole lot of oversampling.
So, we could either alternate with resolver 1 and resolver 2 (I'm sure you could infer about the angle by getting alternating sine and cos values for the angle), or you could move the throttle with a little wire over to ANx, and then wire, say, resolver 1 to where the throttle used to be, and then once every 32 times check the throttle, and 31/32 times check resolver 2?
edit: maybe the alternating sine and cos isn't so bad... the only time you need both pieces of info is when you aren't sure about what quadrant you are in.
Last edited by MPaulHolmes; 10-09-2015 at 08:53 AM..
|
|
|
The Following 2 Users Say Thank You to MPaulHolmes For This Useful Post:
|
|
10-09-2015, 04:25 PM
|
#2159 (permalink)
|
Permanent Apprentice
Join Date: Jul 2010
Location: norcal oosae
Posts: 523
Thanks: 351
Thanked 314 Times in 215 Posts
|
I'm going to split this into two parts; 1st the memory issue, then the AtoD conversion issue.
Quote:
Originally Posted by MPaulHolmes
The used up data memory isn't actually as used up as it seems. A lot of it is tied up in some debugging arrays that I'm using. I just made them as big as possible so that all the memory was used up. It's in a UNION in sensorless.h. As for MOSTLY frozen things, that's a good question. A couple functions in UART are constantly changing as new commands are added and taken away. Also, I keep changing the commands to really short stuff so I don't have to type so much while testing.
In the rest of the code, initialization code is pretty frozen. startup sequence is frozen. I need to automate the PI loop tuning (for all motor types) and finding of rotor time constant for case of ACIM.
|
Regarding memory - that's really good news. I was mostly bringing up memory to illustrate the reality of having limited resources on microcontrollers. I think it's an interesting challenge.
If it ever does get close, one suggestion is to carefully choose whether memory is defined in a function or the main part of the program. The memory defined in functions is only used when the functions are operating, so there can be some overlap.
Regarding frozen code, I would like to adjust some things a little bit in the startup (top of main) code and initialization code. I wasn't quite done, but I wanted you to get this ASAP.
It's really NBD, just moving the contactor code and read/writes stuff to EEprom to separate functions. After that point the main is just a manager - it doesn't really do stufff.
If that seems ok, then a subtle " order of things " might be possible: The precharge relay has a number of time delays to ensure there is the correct voltage before moving on with the code. This is only done once, so it's really nbd. - - How about using the dead time spent reading from EEprom and initializing values as precharge time?
I can just send the new functions and main - the rest won't change.
A bit of initialization stuff may need to be altered, depending on the postion feedback the user wants - that's the next post. Also - the constantly changing uart.c is a good illustration of how a separate bit of code can be used for customization. I think it's a good thing! Something like that may be a way of addressing different motor types, etc. For example InductionMotorSetup.c or BLDCMotorSetup.c . Just food for thought. :-)
- E*clipse
|
|
|
10-09-2015, 05:25 PM
|
#2160 (permalink)
|
Permanent Apprentice
Join Date: Jul 2010
Location: norcal oosae
Posts: 523
Thanks: 351
Thanked 314 Times in 215 Posts
|
OK, here are some AtoD converter ideas -
Quote:
Originally Posted by MPaulHolmes
To get the resolver board to work, you would replace the encoder initialization with configuring 2 of those inputs as A/D inputs. Then, maybe you could do these 4 A/Ds:
throttle
CURRENT 1
CURRENT 2
RESOLVER 1
and then one time of this:
THROTTLE
CURRENT 1
CURRENT 2
RESOLVER 2
and then back to this:
throttle
CURRENT 1
CURRENT 2
RESOLVER 1
The trouble is, AN0 is throttle, AN1 is current 1, AN2 is current 2. For the 4 simultaneous samples, AN0, AN1, AN2 must be together, and then ANx is the most flexible. unfortunately, I chose AN0 to be throttle. It would have been better to have throttle be ANx (for some x not equal to 0, 1, or 2) since it doesn't have to be done as often.
The noise on the throttle is maybe +/- 1 (sometimes 1.5) A/D ticks out of a range of 1024, which doesn't need a whole lot of oversampling.
So, we could either alternate with resolver 1 and resolver 2 (I'm sure you could infer about the angle by getting alternating sine and cos values for the angle), or you could move the throttle with a little wire over to ANx, and then wire, say, resolver 1 to where the throttle used to be, and then once every 32 times check the throttle, and 31/32 times check resolver 2?
edit: maybe the alternating sine and cos isn't so bad... the only time you need both pieces of info is when you aren't sure about what quadrant you are in.
|
I hate to say this, because it's also a hardware issue. I think it would be best to move the throttle down among stuff that isn't hyper time dependant. Yes, the throttle is one of the most important feedback devices connected to this controller. However, it's not going to change so fast that it needs to be checked on a PWM frequency level.
This does look like it's going to be a pain from a setup level. I was really hoping the QEI interface pins would simply be exchanged for AtoD pins, with one extra pin left over.
You are right about just needing both to figure out what quadrant you're in. That could be very beneficial. I was hoping the ultimate advantage of a resolver would be that sin and cos would not need to be derived, just measured from the resolver. It really does look possible to do this as I look deeper into your FOC code.
I'm a little leery about sharing input pins. Technically it sounds very do-able, but one would have to be very careful about what cycle the code is on... If the code was expecting a throttle value and instead got a resolver value, what would happen?? Could there just be some bit of code to check whether an outlier happened?
This may bring up an opportunity - again, just thinking aloud - would it be possible to have certain inputs changable in hardware via jumpers to account for different set-ups? For example, my demo board uses two different sets of uart pins depending on which jumpers are chosen. If jumpers aren't reliable, it seems possible to have different 0 ohm solder in place jumpers, or something.
I'm very seriously trying to figure out a dual user-input setup. ( throttle/brake or throttle-throttle override ) The other possibility is that OE throttles like the Prius throttle have two outputs for a safety feature. In other words, having an extra analog input pin or two would be a very good thing.
I have no problem with modifying my current board(s) to re-route the throttle input. The configurable input might be a nice thing to add to the rev3 board.
- E*clipse
|
|
|
The Following User Says Thank You to e*clipse For This Useful Post:
|
|
|