Absolute Magnetic Encoder
Aleks
Posts: 52
Hey all, I know (from experience) that there are a lot of very knowledgeable people in this forum, so obviously this is the first place to go when I need help. Well, I need help again, so here's my issue:
I recently acquired a US Digital 12 bit absolute magnetic encoder, part number MA3-P12. This was to replace the original resolver DRBG-11-AA-01AA offered by Moog that I was using in an important project. The latter of the two was easy enough to write a library for, appropriately labeled Resolver.spin on my PC. However, this new absolute magnetic encoder lacks the digital interface offered by the Moog resolver, and instead tracks absolute shaft angle via PWM. The spec sheet can be viewed here. www.usdigital.com/assets/general/ma3_datasheet.pdf Basically, the duty cycle of the information coming across can be decoded with simple math into a position between 0 and 4095. The equation is (([noparse][[/noparse]time on] * 4097) / ([noparse][[/noparse]time off]+[noparse][[/noparse]time on]))-1 . In essence, if you take the "high time" and subtract 1, u get the position. The given equation is meant to account for some inaccuracies in the encoder. My question to everyone is how should I go about measuring this time frame, or better yet how do I read the value? I currently tried using the system below
In this pin 2 was used as the input pin from the encoder, and it waited for the high state. After reading the high state it waits for the low state. Once the low state occurs it grabs the count value and waits for another high state. Once the high state occurs it grabs this new count value and displays the delta of the two on an LCD screen. Now while this is only measuring the low state, I figured it would be good for analyzing incoming signals. In theory, if the shaft is not rotating the same signal will be coming through. Because the same signal is coming through both the high time and the low time will be the same. However, my low time was constantly varying in a pattern that leads me to believe that i'm losing count time when I poll for the state of pin 2. Does anyone have an effective way to check the pulse width of this part?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
~Some men see things as they are and ask "why?"
I dream of things that never were and ask "why not?"~
I recently acquired a US Digital 12 bit absolute magnetic encoder, part number MA3-P12. This was to replace the original resolver DRBG-11-AA-01AA offered by Moog that I was using in an important project. The latter of the two was easy enough to write a library for, appropriately labeled Resolver.spin on my PC. However, this new absolute magnetic encoder lacks the digital interface offered by the Moog resolver, and instead tracks absolute shaft angle via PWM. The spec sheet can be viewed here. www.usdigital.com/assets/general/ma3_datasheet.pdf Basically, the duty cycle of the information coming across can be decoded with simple math into a position between 0 and 4095. The equation is (([noparse][[/noparse]time on] * 4097) / ([noparse][[/noparse]time off]+[noparse][[/noparse]time on]))-1 . In essence, if you take the "high time" and subtract 1, u get the position. The given equation is meant to account for some inaccuracies in the encoder. My question to everyone is how should I go about measuring this time frame, or better yet how do I read the value? I currently tried using the system below
dira~ repeat repeat until ina == 1 motor := cnt repeat until ina == 0 repeat until ina == 1 monitor := cnt lcd.cls lcd.print(monitor-motor) pause(30_000_000)
In this pin 2 was used as the input pin from the encoder, and it waited for the high state. After reading the high state it waits for the low state. Once the low state occurs it grabs the count value and waits for another high state. Once the high state occurs it grabs this new count value and displays the delta of the two on an LCD screen. Now while this is only measuring the low state, I figured it would be good for analyzing incoming signals. In theory, if the shaft is not rotating the same signal will be coming through. Because the same signal is coming through both the high time and the low time will be the same. However, my low time was constantly varying in a pattern that leads me to believe that i'm losing count time when I poll for the state of pin 2. Does anyone have an effective way to check the pulse width of this part?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
~Some men see things as they are and ask "why?"
I dream of things that never were and ask "why not?"~
Comments
WAITPEQ will give you much more accurate results, since there's no telling when during a REPEAT UNTIL loop the transition occurred.
-Phil
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
'Still some PropSTICK Kit bare PCBs left!
Post Edited (Phil Pilgrim (PhiPi)) : 8/16/2008 12:01:04 AM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
~Some men see things as they are and ask "why?"
I dream of things that never were and ask "why not?"~
BTW, measuring the pulse widths in Spin may still place upper and lower limits on the pulse widths you can read, due to the interpreter overhead and the fact that this may lead to missing very short positive- or negative-going pulses. It will depend on the PWM frequency coming from you encoder. If this is a problem, the only solution would be to rewrite the code in assembler.
-Phil
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
'Still some PropSTICK Kit bare PCBs left!
Post Edited (Phil Pilgrim (PhiPi)) : 8/16/2008 8:08:48 PM GMT
I know the code is sloppy and the variables poorly named, but where it is still in the proto stage I'm running off of a dynamic testing program I wrote a while back so I don't have to keep writing new programs every time I want to test something. All my variables are pre-defined. I should have a range of 0 - 4096, but because I'm measuring time and using the period of the logic high state in terms of 25E-9 seconds per count, at 40 MHz, I've managed to secure a range of 25~4150. I'm using a small gear so getting any lower values is extremely difficult by hand. Everything is working beautifully though, so thanks again
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
~Some men see things as they are and ask "why?"
I dream of things that never were and ask "why not?"~
Just a thought for the lazy,
Craig
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
My system: 1.6 GHz AMD Turion64 X2, 4GB DDR2, 256MB ATI Radeon Graphics card, 15.4" Widescreen HD Screen
I have a duel boot of Ubuntu Linux and Windows Vista. Vista, because it came with the PC, Ubuntu because I like software that works.
"Failure is not an option -- it comes bundled with Windows."
Use The Best...
Linux for Servers
Mac for Graphics
Android for Mobility
Windows for Blue Screens
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
~Some men see things as they are and ask "why?"
I dream of things that never were and ask "why not?"~
Don
Thankfully enough, in the time frame between my last post and yours I have succeeded in using the MA3-P12 as a resolver replacement in my project, and proceeded to post the resulting driver on the propeller object exchange. Feel free to try it obex.parallax.com/objects/357/. If you have any ideas for improvement please post me a message or continue this thread.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
~Some men see things as they are and ask "why?"
I dream of things that never were and ask "why not?"~
Don
Using the counters to measure pulse widths involves setting them up to count only when a pin is positive (or negative). The counter is then cleared before the pulse arrives, and the value of the counter is read out before another pulse arrives.
The above code assumes PHSA can be cleared in the time between pulses. It also assumes that the value in PHSA can be grabbed before another pulse can arrive.
Marty
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Lunch cures all problems! have you had lunch?
Will try actual circuit tomorrow and thrash it out. Think it might actually work. Use is for two axis radiotelescope system, so have to learn PWM as well, but there are examples. Haven't programmed in assembly/machine language for a LONG time...but will give it a go.
Don
My answer is: forget about doing that in SPIN. I assume it's about a precision setup, or you would have been happy with a 1024 solution or less.
You need PASM, and you need to measure two things: time from falling to rising edge and time from falling to falling edge.
I'm really no PASM pro in conjuction with the timer/counter, so hopefully someone else jumps in.
And next time, buy a Heidenhain ROD! [noparse]:)[/noparse]
Nick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO
http://www.austriamicrosystems.com/eng/content/download/12890/229418/file/AS5145_datasheet_Rev1.5.pdf
I'm not an Austria Micro representative or otherwise compensated for this endoresment, but it made my crank angle detector and throttle position detector in my engine management project a breeze.
I read the absolute angle at boot over SPI, and then use the quadrature outputs to track any updates (of course, if the logic sees an "index" pulse, it cancels the SPI read and just starts from 360 or 0 - depending on which direction it's running).· I should mention that I'm running this in a Xilinx CPLD, so I don't have a pre-written SPIN routine for that...
-Tim
Post Edited (GreyBox Tim) : 7/7/2009 10:28:26 PM GMT
If your application is something that rotates (and not just swivels to some degree), a QE-output is the way to go.
Where do you intend to use the decoder?
Nick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO
You'll also have an index signal (good for measuring speed).
But you'll only get the absolute position after maximum 1 revolution. That should be enough.
And for traction-control, you don't need the absolute position. You need:
difference left/right of the driven axle and difference non-driven axle / driven axle. The slip should be something around 20%.
On a 4WD, things get a bit more complicated, you have to measure acceleration of each wheel and acceleration of the vehicle and match that.
Those rotary encoders cost about 20$. HEDL (IIRC) and some 4 digits number US-Robotics has them in the USofA.
HTH,
Nick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO
Moral of the story is that I certainly don't need this much resolution. I'd be happy with 0-360.
PASM = Parrot assembly?
QE-Object?
You may want to set it up so that two Cogs are running the motor:
Cog 1 is running an absolute counter from the SPI initial value and updated by the quadrature input and writing the resultant 12-bit value to the Port B pins 0-11 (at full input speed) so it doesn't use up your physical pins.
Cog 2·can read an accelerometer value·and keep a running count of the pulses from one half of the quadrature input from the encoder and with a little math create an estimated traction coefficient value from 0-1 (0.0000 = no traction, 1.0000 = full traction).· Based on the throttle RPM request, motor direction request, traction coefficient, tach, and absolute position (read from·port ·- it can then calculate how often to change the polarity of the coils, and which sequence to use (this is much slower work than the absolute-postion requirements, so it can all be time-shared in one Cog).
Final RPM request would be Throttle RPM x Traction Coeff. = Motor Drive RPM
i.e., If your Throttle was 2468, but your traction coeff was 0.4321, then your motor drive RPM would get reduced to (2468 * 0.4321 = ) 1066. If the actual real-time tach·speed is used in relation to the accelerometer data, this math should be self balancing... assuming you calculate the traction coeff correctly·.· You may want to watch the motor current as well to detemine if your acceleration matches the expected motor load - less current should indicate a lighter rider (and thus more current should indicate a heavier rider), so the acceleration should be higher if the tach is actively climbing - if the acceleration is not matching the rate of climb of the tach for this load, it indicates a lower ammount of traction (i.e. wheel spin).· As the increase in acceleration gets closer to the expected acceleration via the tach signal using the Motor Drive RPM math above, the·Motor Drive RPM value·will increase to match the throttle without a timed ramp (which may kill sporty acceleration, like if you were on a little slippery patch of grass but now you are on hot/dry tarmac).
A little extra math in Cog 2·can also tell you if the motor is starting to stall (from too much load...), so it can turn off the coils to keep them from burning up...
-Tim
Post Edited (GreyBox Tim) : 7/8/2009 1:02:40 AM GMT
Next, rollover (i.e. a 1024 to 0 transition) on an absolute encoder is likely to cause glitching (values other than 1024 or 0) unless carefully handled. Personally I'd prefer to use a serial interface if the encoder chip has one. (i.e. I2C or SPI or SSI etc) In this case roll over is handled digitally inside the chip and shouldn't show any glitching. (noise many still appear so the value may toggle from 1024 to 0 and back but should NEVER show an intermediate value while transitioning) Also, position sampling with a serial interface should be deterministic as it's initiated by the control program. Keeping track of position over multiple rotations requires sampling a minimum of three times per revolution, position tracking for commutation will likely require sampling 10-100 times faster than this. My second choice would be to use incremental quadrature for high speed work. (this requires a cog dedicated to encoders) Or PWM for absolute positioning. Third I'd use any sine/cosine outputs. While these require more work to process, rollover is handled internally in software so should be immune to glitching. Last I'd use an analog ramp output as it's highly susceptible to glitching on rollover if the zero point drifts, or transitions are slow.
Lawson
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Lunch cures all problems! have you had lunch?
How many phases does this motor have (and how many cycles per rev is it)?
How fast are you planning on running it?
These are key component selection questions, since if you look at the datasheet for the part you have on-hand, it claims a constant max RPM of 15K-RPM.· It also shows that the PWM output·period is 0.976kHz (976Hz).· 15K-RPM is 250 revs/second (250Hz).· This means that at the max revs for this device you will only get an update about 3.9 times in one revolution.· If you have the standard 3-phases, this means you will have to start interpolating way before you get to the limit of this device - or your position updates will be out of whack.· Also there will be a time delay from the reading, to the actual implementation of any decisions the Propeller will make on the data it gets.· The faster the motor spins (you guys had mentioned the intention of spinning it around 5K-RPM), the worse this delay will get for you, and it will have to be compensated for dynamically.
Regardless of this let's take a look at some information you already provided, the part states 10-bit resolution at 976Hz and 12-bit at 244Hz.· To get 10-bit resolution out of 976Hz, you need to be able to look at the state of the PWM line a 2^10*976Hz, to get 12-bit resolution you need to read the PWM at 2^12*244 (roughly 1MHz for both cases - using Nyquist as a guide, you realize that you really should check it at >2MHz to be sure that you are getting good data).· You can interpolate these data points by looking at the new value every 244Hz or 976Hz and dividing the difference by how many new outputs you are creating between readings.
For example, if you see that one reading is (assuming 10-bit @ 976Hz)· 531 and the next reading is 643 - assuming that the speed doesn't change much, you can divide the time between samples by four (giving a new data point every 256uS [noparse][[/noparse]3.9kHz]), and the difference by the same number (in this case 4).· This would give you new data points: 671, 699, 727 before the next REAL data came in 762 (showing a slight position error of 7, or 0.3515625 degrees - this is jitter).· This work of course adds more overhead to the micro doing the work...
The datasheet·doesn't mention it, but since it is outputting the PWM position on a roughly fixed time period, it's probably already interpolating the position internally (so you are already getting jittery data).
To count the 1MHz PWM input I would recommend using a custom assembler driver - and run the COG at 80MHz (basically as fast as you can).· Remember that with the Prop-1, you don't get single instructions per clock (have to wait for the Prop-2 for that), and with the oversampling you are likely to miss things already (at 0 or 1024 the PWM start/stop pulse is one 1MHz clock-pulse wide).· With oversampling to ensure that you are seeing the correct data, you are likely going to have to look at that pin 4X the minimum bit period, and if I recall correctly the Prop will give you one instruction every 4 clocks (if my no-coffee evening math holds, this means that you're already needing 20MHz just to look at the pin - not do anything with it... assembler helps a bit here).
You may want to look into the SX parts Parallax offers - you can run them at 75MHz and do single cycle instructions. The language isn't quite as pretty as the Prop's but is still very effective.
Also - I should drop a little anecdotal nugget here.· I have a co-worker who recently graduated from Stanford.· He was telling me about a robotic, learning helicopter project they are doing there - where the software guys (developing the learning part) were getting frustrated developing the hardware to go into it...
Having worked in tech now for at least a decade, this problem's solution is very obvious to me: the software CS guys should go buy the hardware EE guys a case of beer and have them co-develop the hardware platform.· I don't know of too many large (succesful)·companies that let their SW guys do HW or their HW guys do SW (something about "the right tool for the job"...).· A lot of headaches can be averted by hardware guys simply asking the SW guys what they need to·emulate a specific HW function, or SW guys telling the HW guys·they need such-and-such physical data presented as so-and-so soft data (and let the the EEs·pick the hardware to do the job within spec).
Dunno...
-T
Post Edited (GreyBox Tim) : 7/8/2009 5:54:14 AM GMT
You are saying that you are using it for a "formula-type cart"...· Think safety first.· Your hardware should be designed to be safe - what I mean by this is that many safety qualifications should be met before any output is enabled.· Your sensory input (like throttle), should be duplicated and syncronized (i.e. the SW should see two separate inputs which are in agreement, if either is out of a calibrated range - no motor output!!!).
"By-wire" controls are take for granted by many who use them, but the proceedures from implementing them in modern systems were hard-earned.· Even "simple" systems like automated traffic lights have checks and double checks - and no one portion of the system is trusted with total control (after the light pattern is calculated by the city's traffic priority algorithm, a completely separate module checks if the pattern makes sense - if not, all lanes get flashing red lights [noparse][[/noparse]think what happens if cross-traffic gets a green when you do?]).
In the event you have a software failure, your hardware shouldn't do something stupid - for example, when you turn on the ignition, your car shouldn't start at 100% throttle and wait for the code to boot before you can stop the car (this is done with the proper use of pull-ups/downs and interlocks).· Likewise, if you lose your throttle sensor while it's at 90%, it should default to 0% (not wait for the operator to pull the terminal off the battery because it's waiting at 90% for another update as the car careens into a wall...).· Put a switch on the normal brake pedal that is SPDT.· One position indicates no brake, and gives the micro an "OK no brake" signal, the other indicates brake and gives the micro an "OK yes brake" signal (which should clear the Motor Drive RPM·value to 0%).· If the micro can't tell if the brake is on or off it shouldn't move the car (this is why two separate outputs - at least one must be true for the data to be valid).· This second output can also be used to disconnect the motor terminals from the battery - so in a panic, the normal reaction of a driver slaming on the brakes when the car does something it shouldn't will actually put the car in a "safe" state, then when the car comes to a complete stop under the driver's full attention, the master disconnect can be triggered.
The hardware should not allow the motor to be spun-up if the driver's foot is not pushing on the accel pedal (another small micro switch would work there).· Return springs on the accel pedal should be redundant...
Each of these functions should be built up, from the outermost hardware eventually into the innermost software, and tested thuroughly each time something new is added.· This means that you will have exponentially more to test every time something new is added, but such is the nature of "by-wire" devices .
(Stepping down from soapbox)
-Tim
QE = Quadrature-encoder
And to the absolute position (with the assumed BL-motor):
I don't know, but I thought that there are sensorless methods of getting that thing to run. And if you need a sensor, the resolution can be much lower. That sounds more like a few hall sensors. AFAIK, the sensor is only needed for starting.
But then again, I don't know about BL.
Nick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO
I need high speed work (the encoder is rated to 15000RPM, although I shouldn't be using it that fast). Is there a way to get a cleaner output from the PWM? The signal looks fine on a O-scope. I had this same rollover issue when trying to pull values using the Basic Stamp. With a dedicated cog, I shouldn't be having problems but I am!! AAHHH
Excuse my frustration, too many hours spent on this problem.
Any help would be great.
@Nick, The construction of our motor is slightly different in the way that is switches between "states." Multiple stators, and coils (without giving away too much IP), hence the need for the state machine. We are only running a couple stators at a time to maximize on our magnetic field. This is a student collab, but I think eventually the guy in charge wants to make it more. For now we are more in the research phase. Someone with far more software experience than I will have their hands on our system, long before it makes its way into something like a formula car. We are indeed very worried about safety.
@Tim, The operation of the sensor on the gas pedal will be any disengagement will cut power to the motor to coast. And brake will (hopefully, eventually, do regeneration), in the first say, 20 degrees of press down, with a completely mechanical brake following it. The "engine brake" is simply to assist.
Like I said, you guys have been more than generous, and I will continue to consider these timing issues, equipment issues (I do have the ability to buy alternative parts, time is the only issue). The mechanical guys liked this sensor for its 15kRPM range, but that will probably be overkill. Hopefully Lawson, or someone has some ideas about some basic rollover code for the PWM to help out the current issue. By the time I get past the first design I expect to be using many more sensors, and much more complex SW, (Think one motor per wheel). At that point it will probably be time for an FPGA to go with the MCU(s).
I really appreciate all the time, have just graduated in June, I realize more and more, just how much there really is to learn !!!
That's OK. Only makes answers a bit more difficult.
I suggest going back to the motor-guy and insist on giving you better specs about the position-resolution. Assuming it is a 3pole-rotor it wouldn't matter in which third of a full revolution the rotor is (same for any other number of poles, the position only needs to be known within one sector). Hope not a too wild guessing by me.
If this is the case, you could think about getting the position with a bunch of hall-sensors distributed in one segment*)
If you do that with Gray-code, you'll get the absolute position and won't have problems with transitions between positions.
By working with segments, the required resolution is divided by the number of poles, compared to your current setup where you have the position within a full revolution.
Ooops, that sounds a tad complicated (I'm German, a bit hard to express what I mean, so come back).
*)Actually, you can spread them on the full circumfence by "unwinding" one segment. Hope you get the picture.
Of course, you don't need hall-sensors, optical would work the same (or better).
Nick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO