Shop OBEX P1 Docs P2 Docs Learn Events
Absolute Magnetic Encoder — Parallax Forums

Absolute Magnetic Encoder

AleksAleks Posts: 52
edited 2009-07-08 21:45 in Propeller 1
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
  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?"~
«1

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-08-15 20:58
    Try this instead (assuming you're using pin A0):

    repeat
      waitpeq(1, 1, 0)
      waitpeq(0, 1, 0)
      waitpeq(1, 1, 0)
      t0 := cnt
      waitpeq(0, 1, 0)
      t1 := cnt
      waitpeq(1, 1, 0)
      t2 := cnt
      lcd.cls
      lcd.print((t1 - t0) * 4097 / (t2 - t0) - 1)
    
    
    


    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
  • AleksAleks Posts: 52
    edited 2008-08-16 19:45
    Thanks Phil. My project is unfortunately at my workplace, and I have no access to it until monday. But in the meantime could you perhaps explain to me how waitpeq(...) works?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ~Some men see things as they are and ask "why?"
    I dream of things that never were and ask "why not?"~
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-08-16 20:01
    You can read about WAITPEQ in the Propeller Manual. Basically, it continuously polls the input pins, ANDs them with the second argument, and compares that result with the first argument. If it matches, the program continues. Otherwise, it continues polling the inputs until there is a match. In my example, pin A0 is used. If you wanted to use pin A2, change all the 1 arguments to %100.

    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
  • AleksAleks Posts: 52
    edited 2008-08-18 15:04
    Thanks Phil, I've rewritten my code to look like this
    pub read
      controller := 0                              
      repeat until controller == 10                
        waitpeq(0, |< pin, 0)                     
        waitpeq(|< pin, |< pin, 0)                     
        motor := cnt                           
        waitpeq(0, |< pin, 0)                     
        set := cnt
        waitpeq(|< pin, |< pin, 0)                             
        counter[noparse][[/noparse]controller] :=((set-motor)/40)-1      
        controller++
      motor := ((counter[noparse][[/noparse]0]+counter+counter+counter+counter+counter+counter[noparse][[/noparse]6]+counter[noparse][[/noparse]7]+counter[noparse][[/noparse]8]+counter[noparse][[/noparse]9])/10)
      return motor         
    
    



    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 smile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ~Some men see things as they are and ask "why?"
    I dream of things that never were and ask "why not?"~
  • crgwbrcrgwbr Posts: 614
    edited 2008-08-19 02:03
    I've used the MA2-P10 from US Digital before, should be basically the same. It maybe cheating smile.gif , but the 'pulsin' function in the 'BS2functions' object works well.

    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
  • AleksAleks Posts: 52
    edited 2008-08-19 02:37
    lol the MA3-P10 is the same exact product, just with 1024 resolution instead of 4096. It operates the same way. Thanks for the advice! I'm definitely gonna try that out tomorrow

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ~Some men see things as they are and ask "why?"
    I dream of things that never were and ask "why not?"~
  • bufflerbuffler Posts: 22
    edited 2008-09-25 06:12
    Hello. I have the same product, the MA3-P12, and need to read it as well. Why, with all the marvelous stuff available with the counters in each cog, is there no way to use the A and B counters to do this. I've tried to struggle through the AN1 band there is a statement that pulse widths can be measured, but no clue is given as to how. This seems like a very simple thing to do, but I haven't a clue!
    Don
  • AleksAleks Posts: 52
    edited 2008-09-25 13:27
    Hi 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?"~
  • Cluso99Cluso99 Posts: 18,069
    edited 2008-09-25 14:45
    It's not hard to do this in assembler and will not have the intrinsic delay of the spin interpreter (which·would be normally the same·for the high and low period)·- use something like this...

            org       0
    entry   waitpeq   pin,pin
            mov       t0,cnt
            waitpne   pin,pin
            mov       t1,cnt
            ....
            jmp       #entry
     
    pin     long      1 << x     'where x = pin no 0-31
    t0      long      0          'could also use t0 res 1
    t1      long      0
    
  • bufflerbuffler Posts: 22
    edited 2008-09-26 20:58
    Thanks to both! I need the full range 0-4096 so the assembly will be needed, Cluso. Now, to get the required accuracy (not precision) we'll also have to measure the frequency or preferably the width of the basic pulse and get the duty cycle. That is, we need the time between positive transitions and the time positive to negative transition. It will of course have to be every other pulse or even more, which is OK and probably average a few measurements to fight noise. My application is very slow angular motion, so don't have to have really rapid response. The smallest pulse width is 2 us, so that's a bit of a problem. And here I thought these would be simpler than a good ol' quadrature device. O what a tangled web we weave...
    Don
  • LawsonLawson Posts: 870
    edited 2008-09-26 21:48
    buffler said...
    Hello. I have the same product, the MA3-P12, and need to read it as well. Why, with all the marvelous stuff available with the counters in each cog, is there no way to use the A and B counters to do this. I've tried to struggle through the AN1 band there is a statement that pulse widths can be measured, but no clue is given as to how. This seems like a very simple thing to do, but I haven't a clue!
    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.


        CTRA := %01000<<26 + pin     'Setup the counter to count when PIN is high
        FRQA := 1                    'count up by 1 each clock PIN is high
    
        waitpeq(|< pin, |< pin, 0)   'wait for a falling edge
        waitpeq(0     , |< pin, 0)
        PHSA := 0                    'clear PHSA
    
        waitpeq(|< pin, |< pin, 0)   'wait for a falling edge
        waitpeq(0     , |< pin, 0)
        Pulse_width_CLOCKS := PHSA   'read the value in PHSA into a variable
    
    



    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?
  • bufflerbuffler Posts: 22
    edited 2008-09-27 05:45
    Thanks, Marty. Was kinda getting there, beginning to rtfm for real. found the logic controls. Was not sure how to store.
    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
  • mminasianmminasian Posts: 26
    edited 2009-07-07 18:32
    Hey guys, I'd like to revive an old topic here. Perhaps Aleks or someone else can chime in. I'm using this exact encoder, and the object created for it. I first attempted to use this encoder with the Basic Stamp, and was told by parallax support that it was basically impossible because of clock speed. I then bought a propeller as was recommended. I was happy to find this object, but upon setup I still get the same range values from my encoder. The range is somewhere in the neighborhood of 1000-9000, but occasionally it jumps around to random places. Do I have some kind of timing issue? Does this object assume that the clock is set a certain way that I am missing? I am using the Parallax serial terminal to display my values, and need a certain clock speed for the baud rate to work correctly with that. Could that be the problem? If so, is there any way to actually see what the values are that the encoder is spitting out? This is frustrating because I am seeing an IDENTICAL response that I did on the STAMP. Hopefully someone has some advice. Thanks guys.

    
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
    CON
      DelayTime = 10
    
    CON
      Rows    = 13
      Columms = 40
      DisplayBufferSize = Rows * Columms
      
    Var
      Long motor
      Long Stack[noparse][[/noparse]9] 
    OBJ
      Position : "MA3P12_Absolute_Encoder"
      PC_Text    : "PC_Text_advanced"
      PC_Keyb    : "PC_Keyboard"
    
    PUB MainLoop '| i, KeyCode
     PC_Text.start(31) 'rxpin, txpin rx/tx from the sight of the propellerchip. Propeller-rx <-----receive from PC, Propeller-tx -----> send to PC
     PC_Keyb.start(31,30)
     Position.initialize(10)
     repeat
        motor := Position.Read
        PC_Text.dec(motor)
        PC_Text.Cursorhome
    
    
    



    
                                    *****************|| Absolute Magnetic Encoder ||*********************
    
    
    var
      long pin, controller, motor, set, counter[noparse][[/noparse]10]
    
    pub initialize(input)                                   'Use this routine to declare the data line of the MA3-P12
      dira[noparse][[/noparse]input]~ 
      pin := input
      return pin     
    {
      If the pin (input) == 1, the binary value for the pin/high variable is %10 which == 2.
      Thus, because this is a binary base we can use the formula 2 ^ input to determine the
      value of pin and high. 
    }   
        
    pub read                                                'Use this routine to recall the current shaft location
      controller := 0                              
      repeat until controller == 10                
        waitpeq(0, |< pin, 0)                     
        waitpeq(|< pin, |< pin, 0)                     
        motor := cnt                           
        waitpeq(0, |< pin, 0)                     
        set := cnt
        waitpeq(|< pin, |< pin, 0)                             
        counter[noparse][[/noparse]controller] :=((set-motor)/80)-1      
        controller++
      motor := ((counter[noparse][[/noparse]0]+counter+counter+counter+counter+counter+counter[noparse][[/noparse]6]+counter[noparse][[/noparse]7]+counter[noparse][[/noparse]8]+counter[noparse][[/noparse]9])/10)
      return motor
    
    
  • Nick MuellerNick Mueller Posts: 815
    edited 2009-07-07 21:28
    mminasian, you asked me to help you. smile.gif
    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
  • GreyBox TimGreyBox Tim Posts: 60
    edited 2009-07-07 22:21
    Aleks said...
    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
      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?

    If you are looking for a new absolute rotary magnetic encoder,·I have had great success with Austria Microsystems.· They allow for direct buy from their website.· Take a look at the AS5145, it's a 12-bit part with SPI and quadrature outputs.· The SPI bus can be run at 1MHz, and the quadrature is good for 30K-RPM (but it is interpolated above 9K-RPM).· This is a multi-turn part so it also features an index output for the quadrature output, and·the part works on either 5VDC or 3.3VDC.

    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
  • Nick MuellerNick Mueller Posts: 815
    edited 2009-07-07 22:28
    I just realized that now: You intend to use that for something "fast" moving? Well, the signal is OK for quasi-static applications (like a rotary table on the mill). But as soon as that thing does more than one revolution you're quite lost. You can't detect that well in wich direction it rotates and its easy to get lost with the number of revolutions.
    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
  • mminasianmminasian Posts: 26
    edited 2009-07-07 22:34
    Yep, one on the shaft of an electric motor (>5000RPM potentially), and one each for throttle and brake pedals. Those last two can be incremental. The former needs to be absolute. The shaft sensor needs to be able to read a single position (presumably at rest), and then also record speeds so that I can update my logic. (I'm making a "traction control system" using the speed of the cart, throttle amount etc, so that the wheels don't spin out).
  • mminasianmminasian Posts: 26
    edited 2009-07-07 22:41
    And to be honest I could really get away with a LOT less accuracy than this encoder provides, the model was chosen for me, and when choosing between 10 and 12 bits I figured more res = better.
  • Nick MuellerNick Mueller Posts: 815
    edited 2009-07-07 22:47
    OK with an QE-encoder and a 1024 resolution (do you really need that much!?!?) you will have about 100kHz. No big deal for the QE-object (in PASM).
    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
  • mminasianmminasian Posts: 26
    edited 2009-07-07 23:02
    Sorry let me elaborate, we are manually building an electric motor, and I need the absolute position simply for the startup of the motor, I need to know the position of the shaft (think of it like deciding where top dead center is). All other position is incremental for the other modes. In our go cart example, with limited control, I just don't want to dump the entirety of my battery onto the motor when the thing isn't moving and have the wheels spin out. I will create a basic ramping type function based on the shaft speed, and throttle to decide what the delay in that state machine is. (Those "LEDs" will become switches and capacitors that release current to stators at specific times).

    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?
  • GreyBox TimGreyBox Tim Posts: 60
    edited 2009-07-08 00:35
    mminasian said...
    Sorry let me elaborate, we are manually building an electric motor, and I need the absolute position simply for the startup of the motor, I need to know the position of the shaft (think of it like deciding where top dead center is). All other position is incremental for the other modes. In our go cart example, with limited control, I just don't want to dump the entirety of my battery onto the motor when the thing isn't moving and have the wheels spin out. I will create a basic ramping type function based on the shaft speed, and throttle to decide what the delay in that state machine is. (Those "LEDs" will become switches and capacitors that release current to stators at specific times).

    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 say "building an electric motor" - I presume this means you are building a brushless motor, which needs external commutation...· See the above part I mentioned to get you a digital position indication, with simple quadrature output at high speed.· As for "traction control", use an accelerometer and a motor tachometer.· If the motor tach frequency is climbing but there is no acceleration, this means the tire is spinning without transferring power to the pavement.· Essentially, the tach's rate of change should relate to an accelerometer's rate of acceleration (or deceleration) using a simple equation (you will need to know what a rev increase relates to as acceleration).

    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 B)·- 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·yeah.gif.· 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
  • mminasianmminasian Posts: 26
    edited 2009-07-08 00:59
    Thanks Tim! It's going to take awhile for me to wade through the response to understand everything you are saying fully, but you're on the right path. I am planning on using one Cog per encoder, as well as one to run my "switching state machine" (essentially delivers current to different stator coils at different times). We are working on a research type project with what we hope is an innovative design for a DC motor in terms of efficiency and power/torque. Hopefully my controlling circuit doesn't hold us back!
  • mminasianmminasian Posts: 26
    edited 2009-07-08 01:26
    We will be putting this (hopefully) into Formula Student car in the future, and so that will all be extremely helpful. In the meantime in terms of quick development/extremely basic solution, do you see any way I can use these encoders as it is? I feel like if I could get a reasonable range of values out of this I can make something work for this relatively low tech go cart. The issue seems to be something with the PWM signal.
  • LawsonLawson Posts: 870
    edited 2009-07-08 02:07
    @Mminasian: What exact absolute magnetic rotary encoder chip/device are you using? Links to product web pages or datasheets would be idea.

    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?
  • GreyBox TimGreyBox Tim Posts: 60
    edited 2009-07-08 05:17
    mminasian said...
    We will be putting this (hopefully) into Formula Student car in the future, and so that will all be extremely helpful. In the meantime in terms of quick development/extremely basic solution, do you see any way I can use these encoders as it is? I feel like if I could get a reasonable range of values out of this I can make something work for this relatively low tech go cart. The issue seems to be something with the PWM signal.
    A few questions...

    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 platformjumpin.gif.· 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
  • GreyBox TimGreyBox Tim Posts: 60
    edited 2009-07-08 05:46
    Thinking a bit more here...·(stepping up on soapbox)

    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 skull.gif.

    (Stepping down from soapbox)

    -Tim
  • Nick MuellerNick Mueller Posts: 815
    edited 2009-07-08 06:01
    PASM = Propeller-assembler
    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
  • mminasianmminasian Posts: 26
    edited 2009-07-08 07:08
    @Lawson: Thanks for the reply. I'm using the Propeller with the MA3 digital encoder that's described by the OP. He even wrote an object for it! For whatever reason, it doesn't seem to be working for me. The only output option is 12-bit PWM. Rollover definitely seems to be the culprit, because the first revolution often is close to ok, but then the rollover resets to like 1000 instead of 0. Is there any way I can get a more solid result. The object is described above. Datasheet is here: http://www.usdigital.com/assets/general/ma3_datasheet.pdf

    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.
  • mminasianmminasian Posts: 26
    edited 2009-07-08 07:26
    Wow guys, thanks to Nick and Tim also, I really appreciate the wisdom. Tim I like your point about HW/SW, I'm a HW guy working on SW. I have background in some control theory but some of the bitwise implementation, especially in code, gets lost on me. I have a SW guy at my disposal, and methinks I am going to start disposing more of his resources [noparse]:)[/noparse].

    @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 !!!
  • Nick MuellerNick Mueller Posts: 815
    edited 2009-07-08 09:12
    > without giving away too much IP

    That's OK. Only makes answers a bit more difficult. smile.gif
    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
Sign In or Register to comment.