Shop OBEX P1 Docs P2 Docs Learn Events
Digital to Analog Conversion with Counters — Parallax Forums

Digital to Analog Conversion with Counters

Boss9Boss9 Posts: 8
edited 2012-12-19 15:00 in Propeller 1
I need to take the pulses from an rotary encoder (digital input) and output a proportional DC voltage. Looks like I would use a counter configured for POSEDGE DETECTOR for the input, but also need DUTY MODE for the output.

Question is can I configure Counter A in one mode and Counter B in the other Mode? Basically counter A FRQA stores the frequency and Counter B is in Duty Mode and the output pin varies proportionally with FRQA ?

This is being used to provide the Velocity Gain to a Servo Drive. It requires a signal proportional to 3 Vdc @ 1000 RPM. I will convert the RPM to to Khz based on the encoder resolution and ball-screw pitch.

I'm experienced at reading the encoder pulses with a Propeller, and outputting encoder counts, degrees, etc. I haven't got the counter modules down 100% . Read the Propeller labs, and the app notes on counters.

Just trying to get headed down the right path before I get started. Having trouble with the concept. Any input would be appreciated.

Comments

  • Mark_TMark_T Posts: 1,981
    edited 2012-12-18 22:53
    Each counter is independent and identical (except for use with WAITVID), so configuring one for input frequency counting and another for PWM output is no problem - however you need code to drive both uses as I understand it - you'll see examples of PASM PWM code in various objects I'm sure, but you'll need to add code to sample the frequency counter at appropriate intervals from the other counter, either in same cog or a separate cog.
  • Boss9Boss9 Posts: 8
    edited 2012-12-19 13:21
    Thanks Mark. Sounds like I'm on the right path, so I'll continue on with this concept. Wanted to use the jm_freqin object to measure the input frequency, but it uses both counters to measure frequency, I'll try to merge the two counters with some code. Thanks.
  • AribaAriba Posts: 2,690
    edited 2012-12-19 13:41
    You can do that also in Spin.
    Here is possible (untested) code. The comments should explain it.
    CON
      _clkmode  = xtal1 + pll16x
      _xinfreq  = 5_000_000
    
      SERVO_INP  =  0        'Port Pins
      DAC_OUT    =  16
      
    PUB Main : pulse | inmask
      ctra := %01000<<26 + SERVO_INP       'CTRA in POSdetect mode
      frqa := 1
      ctrb := %00110<<26 + DAC_OUT         'CTRB in DUTY mode
      dira[DAC_OUT] := 1                   'DAC pin = output
      inmask := 1<<SERVO_INP
      
      repeat
        phsa := 0
        waitpeq(inmask,inmask,0)           'wait until pulse from servo
        waitpne(inmask,inmask,0)           'wait until pulse over
        pulse := phsa                      'get pulse-time: ~80_000..160_000 (1..2ms)                 
        pulse := (pulse-80_000) / 5 << 18  'scale value for DUTY DAC (32bit)
        frqb := pulse                      'write to DAC
    

    Andy

    EDIT: I see now that you not have a Servo pulse input, but a digital encoder, so the code above does not really fit. I hope you can get something out of it anyway. A digital encoder can not be read with a counter direct, you should use an object that does that.
  • Boss9Boss9 Posts: 8
    edited 2012-12-19 14:33
    Ariba wrote: »
    You can do that also in Spin.
    Here is possible (untested) code. The comments should explain it.
    CON
      _clkmode  = xtal1 + pll16x
      _xinfreq  = 5_000_000
    
      SERVO_INP  =  0        'Port Pins
      DAC_OUT    =  16
      
    PUB Main : pulse | inmask
      ctra := 000<<26 + SERVO_INP       'CTRA in POSdetect mode
      frqa := 1
      ctrb := 110<<26 + DAC_OUT         'CTRB in DUTY mode
      dira[DAC_OUT] := 1                   'DAC pin = output
      inmask := 1<<SERVO_INP
      
      repeat
        phsa := 0
        waitpeq(inmask,inmask,0)           'wait until pulse from servo
        waitpne(inmask,inmask,0)           'wait until pulse over
        pulse := phsa                      'get pulse-time: ~80_000..160_000 (1..2ms)                 
        pulse := (pulse-80_000) / 5 << 18  'scale value for DUTY DAC (32bit)
        frqb := pulse                      'write to DAC
    

    Andy

    Thanks Andy. I may try this first as I'm more comfortable with Spin.
  • AribaAriba Posts: 2,690
    edited 2012-12-19 14:53
    I hope you have read the EDIT in my previous post.
    I tought first you had a servo pulse to convert to a analog voltage.
    A digital encoder is much harder and needs Assembly, because the counters on Prop1 have no "Encoder input mode". (Prop2 will have).

    Andy
  • Boss9Boss9 Posts: 8
    edited 2012-12-19 15:00
    Ariba wrote: »
    I hope you have read the EDIT in my previous post.
    I tought first you had a servo pulse to convert to a analog voltage.
    A digital encoder is much harder and needs Assembly, because the counters on Prop1 have no "Encoder input mode". (Prop2 will have).

    Andy

    I have a few projects where I read the pulses from an encoder and display as encoder counts, are as positions or degrees with some math added. Think I can take this a a base and figure it out. I give it a try here soon.

    Randy
Sign In or Register to comment.