Shop OBEX P1 Docs P2 Docs Learn Events
FlexBasic and 16bit PWM — Parallax Forums

FlexBasic and 16bit PWM

Does anyone have a sample of how to do this, please? The Quadrature Encoder code (thanks @Ariba) is working beautifully and so I am hoping for a similar solution for PWM.

Why 16bit? Yeah it's overkill but we can do it, right?

Comments

  • I'm working on this too. If I make any headway, I'll post it.

  • @Mickster I'm using this to control an injection pump between 1 and 9 hz. It's PWM at its core. Helpful as a starting point?

    SUB PumpSet(pin as ulong, freqHz as single, widthMS as ulong)
    '
    ' Sets the pump to pulse at the rate of FREQHZ with an output
    ' pulse width of WIDTHMS milliseconds
    
    dim width as ulong
    dim frame_period as ulong
    dim base_period as ulong
    
        ' trap for out of bounds FREQHZ argument
        ' limit range to 0.5 hz to 9.0 hz
        if freqhz < 0.5 then
            pinlo(pin)                                                  ' reset pin (stops pulsing)
            exit sub
        else if freqhz > 9.0 then
            freqhz = 9.0                                                ' constrain freq to 9 hz                                            
        end if
    
        base_period = clkfreq / 10_000
        frame_period = (cast(ulong, 10000.0) / freqHz)
        width = (widthMS * 10)
        print "   Frame: "; frame_period; "  Base: "; base_period; "  Width: "; width; "  T: ";getsec()
    
        direction(pin) = input                                      ' reset the smart pin
        wrpin(pin, P_OE OR P_PWM_SAWTOOTH)                      ' enable output and specify wave type
        wxpin(pin, (frame_period SHL 16) OR base_period)    ' FRAME period :: BASE period in clocks (16 bits, each FRAME and BASE)
        wypin(pin, width)                                               ' PWM value @ frame start
        direction(pin) = output                                     ' enable the smart pin
    
    END SUB
    
  • @JRoark said:
    @Mickster I'm using this to control an injection pump between 1 and 9 hz. It's PWM at its core. Helpful as a starting point?

    SUB PumpSet(pin as ulong, freqHz as single, widthMS as ulong)
    '
    ' Sets the pump to pulse at the rate of FREQHZ with an output
    ' pulse width of WIDTHMS milliseconds
    
    dim width as ulong
    dim frame_period as ulong
    dim base_period as ulong
    
      ' trap for out of bounds FREQHZ argument
      ' limit range to 0.5 hz to 9.0 hz
      if freqhz < 0.5 then
          pinlo(pin)                                                  ' reset pin (stops pulsing)
          exit sub
      else if freqhz > 9.0 then
          freqhz = 9.0                                                ' constrain freq to 9 hz                                            
      end if
    
      base_period = clkfreq / 10_000
      frame_period = (cast(ulong, 10000.0) / freqHz)
      width = (widthMS * 10)
      print "   Frame: "; frame_period; "  Base: "; base_period; "  Width: "; width; "  T: ";getsec()
          
      direction(pin) = input                                      ' reset the smart pin
      wrpin(pin, P_OE OR P_PWM_SAWTOOTH)                      ' enable output and specify wave type
      wxpin(pin, (frame_period SHL 16) OR base_period)    ' FRAME period :: BASE period in clocks (16 bits, each FRAME and BASE)
      wypin(pin, width)                                               ' PWM value @ frame start
      direction(pin) = output                                     ' enable the smart pin
      
    END SUB
    

    Many thanks....that looks promising :+1:

    Just hit the sack but I'll be having a play in a few hours.
    I remember your very enthusiastic post re: FlexBasic and now I totally understand this :)

  • JRoarkJRoark Posts: 1,215
    edited 2021-11-01 22:34

    @Mickster said: '
    Many thanks....that looks promising :+1:
    Just hit the sack but I'll be having a play in a few hours.
    I remember your very enthusiastic post re: FlexBasic and now I totally understand this :)

    Mischief afoot, then! GOOD!

    FWIW I’m a total and unabashed FlexBASIC fanboy. In the early days of the compiler I think I drove @ersmith nuts in our private comms. Nowadays, with most of the bugs dead or dying, I just drive him nuts generally, and in public. Lol!

    I wouldnt be playing with the P2 much if it wasnt for FlexBASIC.

  • @JRoark

    Would love to know more about your injection-pump project, if possible. Sounds like we have similar backgrounds.

    When I stated "hit-the-sack"....it's a sleeping bag at my customer's facility :lol:

    I decided that it was time to switch to the P2 and I might well lose my posterior on this project, due to the learning-curve. I am standardizing on qty:2, P2 Edge modules and qty:1, Picomite.

    The P2s will be black-boxes and handling all the heavy-lifting and the Picomite (BASIC interpreter) will dish-out the commands. At this point, one of the P2s is merely an I/O expander but I decided to go with it because it's such a chameleon. Gone are the days of not having enough of this and too much of that which seems to hit me all too often.

  • Sounds like fun! This is for industrial machine control?

    The injection pump I mentioned is in a chinese knockoff of a Webasto/Ebersparcher diesel parking heater. For a hundred bucks you get something that produces a bunch of heat but isnt exactly reliable. The controller that it comes with cost about $20 retail and is worth about half of that. :) So I’m replacing the entirety of the control guts with a custom P2. It has PWM outputs for fan motor speed speed, injection pump rate and glow plug. Analog inputs for case temp, inlet temp, supply voltage, fan motor voltage & current, injection pump current, glowplug current and fuel level. My controller integrates an RTC and a temp/hum/baro and a CO sensor. So it becomes adaptive to ambient changes just like any proper combustion controller SHOULD! Lol.

    If you need other “canned” routines for your stuff, holler at me. Happy to share!

  • BTW, those injection pumps are ideally suited for minimum quantity mist coolant and lubrication for CNC machines. All those chinese solutions with venturi nozzles and needle valves don't work reliably. Sooner or later the needle valve clobbers and the oil flow stops. You need to force-feed the oil. With the injection pump the flow rate is always the same and doesn't depend on the temperature, viscosity or tiny differences of the needle position.

  • @ManAtWork said:
    BTW, those injection pumps are ideally suited for minimum quantity mist coolant and lubrication for CNC machines. All those chinese solutions with venturi nozzles and needle valves don't work reliably. Sooner or later the needle valve clobbers and the oil flow stops. You need to force-feed the oil. With the injection pump the flow rate is always the same and doesn't depend on the temperature, viscosity or tiny differences of the needle position.

    Interesting, @ManAtWork! Those little pumps find applications all over.

    I have a stainless steel version I got off eBay with a 0.069 ml/stroke displacement acting as a chlorine feeder for the water supply at my barn. When the pump runs, it runs, forcing small amounts of chlorine into the pump intake. It's been running for ~8 years without a peep. They don't like to be run dry however... :)

  • @JRoark said:
    Sounds like fun! This is for industrial machine control?

    Yeah, this is the very machine when running on my old DOS control. I used to supply these guys ~100+ controls/year. Now they are gradually dying-off and I am re-controlling them because mechanically, they are still in great shape.

    If you need other “canned” routines for your stuff, holler at me. Happy to share!

    This would be a huge help as I am having to fast-track myself in to this stuff :+1:

  • AribaAriba Posts: 2,690

    This is an example for a 14 bit PWM. You could do 16 bits, but then the PWM frequency is only around 2.5 kHz (sysclock / 65536). With 14 bits you get around 10 kHz, which I find a good frequency for driving motors. For 16 bits just replace the $3FFF literals with $FFFF.

    '' simple 14 bit PWM in BASIC
    ''
    const _clkfreq = 160_000_000
    const pwm1 = 56                    ' PWM output pin (an LED)
    
    dim pulswidth as long
    
    pinstart(pwm1, P_PWM_SAWTOOTH + P_OE, $3FFF_0001, 0)  'init pwm, 14 bits = sysclock/16384
    do
      pulswidth = getrnd() AND $3FFF   ' a random value limited to 14 bits
      wypin(pwm1, pulswidth)           ' write to PWM smartpin
      pausems 100
    loop
    
  • MicksterMickster Posts: 2,698
    edited 2021-11-02 19:00

    @Ariba

    OMG, This is perfect!!!
    Please PM me your Xmas list :lol:

    In actual fact, I would be deliriously happy with 12bits because, IIRC, the analog input on the vast majority of industrial drives is 12bits anyway. Here, I can have 13bits and 19.531KHz which keeps me above audible range.

    I just thought that we had some sort of dithering trick to achieve 16bits at higher frequency.

    Many, many thanks, once again :+1:

  • @Mickster Based on what I see at 4:35 in that video, you play with machine control for people who make giant paperclips!

    On a serious note, that is really cool. I hope you make a MINT with the P2!

    @Ariba I'm totally stealing that.

  • evanhevanh Posts: 16,028

    @Mickster said:
    I just thought that we had some sort of dithering trick to achieve 16bits at higher frequency.

    What you're probably remembering is the two smartpin modes that dither the lsb of the 8-bit DAC. One of them a +8-bit PWM even.

  • evanhevanh Posts: 16,028

    On that note, the DAC could probably be used instead of the pure logic levels.

  • @evanh said:
    On that note, the DAC could probably be used instead of the pure logic levels.

    As in level-shift to +/- 10v ? I thought about that but I am currently using a desktop rig of 3 small motor/encoders, driven by LMD18200 h-bridges.

Sign In or Register to comment.