Welcome to our new forum
All users of the legacy CODESYS Forums, please create a new account at account.codesys.com. But make sure to use the same E-Mail address as in the old Forum. Then your posts will be matched. Close

PWM_mod:

wollvieh
2022-03-21
2022-05-17
  • wollvieh

    wollvieh - 2022-03-21

    {warning disable C0351}

    function block for raspberry Adafruit PWM board

    1) to use this function block install in the device-repository the "500_0000 0004_4.4.0.1.devdesc.xml"
    2) install in the library repository the "Raspberry I2C AdafruitPWM_mod.library"

    depending on bool variable "_xUseLimitsForRCServo" there are 2 modes existent :

    _xUseLimitsForRCServo := TRUE : in this mode the fb is used for controlling of RC servos , frequency 50Hz, DC = 1..2ms On

    _xUseLimitsForRCServo := FALSE : in this mode the fb is used for controlling free PWM mode
    uisetfrequency possible from 1 upto 1000Hz, DC possible from 0..100 (%)

    Sample GVL List :
    VAR_GLOBAL
    x_0FreeMode_1ServoMode : BOOL := TRUE; // RC Servo Mode is selected
    uiSetFrequency : UINT := 50; // frequency 50 Hz
    MAXPWM_RCMODE : LREAL := 2.0; // max DC = 2.0 ms
    MINPWM_RCMODE : LREAL := 1.0; // min DC = 1.0 ms

    lr_SetpointCannel_0 : LREAL := 1.5; // setpoint 0 default = 1.0 ms
    lr_SetpointCannel_1 : LREAL := 1.5; // setpoint 1 default = 1.0 ms
    lr_SetpointCannel_2 : LREAL := 1.5; // setpoint 2 default = 1.0 ms
    lr_SetpointCannel_3 : LREAL := 1.5; // setpoint 3 default = 1.0 ms
    END_VAR

    Sample Program block :

    // Settings for the fb
    Adafruit_PWM_mod._freq := uiSetFrequency; // setpoint frequency
    Adafruit_PWM_mod._xUseLimitsForRCServo := x_0FreeMode_1ServoMode; // select RC Servo Mode
    Adafruit_PWM_mod.axEnable[0] := TRUE; // enable channel 0
    Adafruit_PWM_mod.axEnable[1] := TRUE; // enable channel 1
    Adafruit_PWM_mod.axEnable[2] := TRUE; // enable channel 2
    Adafruit_PWM_mod.axEnable[3] := TRUE; // enable channel 3
    Adafruit_PWM_mod._alrMin[0] := MINPWM_RCMODE; // minimal DC RC Mode
    Adafruit_PWM_mod._alrMin[1] := MINPWM_RCMODE; // minimal DC RC Mode
    Adafruit_PWM_mod._alrMin[2] := MINPWM_RCMODE; // minimal DC RC Mode
    Adafruit_PWM_mod._alrMin[3] := MINPWM_RCMODE; // minimal DC RC Mode
    Adafruit_PWM_mod._alrMax[0] := MAXPWM_RCMODE; // maximal DC RC Mode
    Adafruit_PWM_mod._alrMax[1] := MAXPWM_RCMODE; // maximal DC RC Mode
    Adafruit_PWM_mod._alrMax[2] := MAXPWM_RCMODE; // maximal DC RC Mode
    Adafruit_PWM_mod._alrMax[3] := MAXPWM_RCMODE; // maximal DC RC Mode

    // signal to output 0
    IF x_0FreeMode_1ServoMode = TRUE // RC servo mode or free mode ?
    THEN
    Adafruit_PWM_mod.alrPWM[0] := LIMIT(0.0,(lr_SetpointCannel_0/100.0),1.0); // alrPWM = 0.0..1.0 ms (added to _alrMin )
    ELSE
    Adafruit_PWM_mod.alrPWM[0] := lr_SetpointCannel_0; // alrPWM = 0..100% DC in free mode
    END_IF
    // signal to output 1
    IF x_0FreeMode_1ServoMode = TRUE // RC servo mode or free mode ?
    THEN
    Adafruit_PWM_mod.alrPWM[1] := LIMIT(0.0,(lr_SetpointCannel_1/100.0),1.0); // alrPWM = 0.0..1.0 ms (added to _alrMin )
    ELSE
    Adafruit_PWM_mod.alrPWM[1] := lr_SetpointCannel_1; // alrPWM = 0..100% DC in free mode
    END_IF
    // signal to output 2
    IF x_0FreeMode_1ServoMode = TRUE // RC servo mode or free mode ?
    THEN
    Adafruit_PWM_mod.alrPWM[2] := LIMIT(0.0,(lr_SetpointCannel_2/100.0),1.0); // alrPWM = 0.0..1.0 ms (added to _alrMin )
    ELSE
    Adafruit_PWM_mod.alrPWM[2] := lr_SetpointCannel_2; // alrPWM = 0..100% DC in free mode
    END_IF
    // signal to output 3

    IF x_0FreeMode_1ServoMode = TRUE // RC servo mode or free mode ?
    THEN
    Adafruit_PWM_mod.alrPWM[3] := LIMIT(0.0,(lr_SetpointCannel_3/100.0),1.0); // alrPWM = 0.0..1.0 ms (added to _alrMin )
    ELSE
    Adafruit_PWM_mod.alrPWM[3] := lr_SetpointCannel_3; // alrPWM = 0..100% DC in free mode
    END_IF
    )
    FUNCTION_BLOCK AdafruitPwm_mod EXTENDS i2c
    VAR_INPUT
    _xUseLimitsForRCServo : BOOL := TRUE;(
    True = RC Servo Mode, , FALSE = Free PWM Mode )
    _freq: UINT := 50; (
    frequency [Hz] )
    alrPWM : ARRAY[0..15] OF LREAL; (
    _alrMin.._alrMax = xms..yms Signal On in RC Servo Mode , 0..100 = 0..100% %DC in free PWM Mode )
    axEnable : ARRAY[0..15] OF BOOL := [4(TRUE)]; (
    Bit x = TRUE: set PWM output channel x; FALSE: do not modify output signal of channel x )
    _alrMin: ARRAY[0..15] OF LREAL := [16(0.7)]; (
    minimum time [ms], the pulse is ON for RC Servo Mode )
    _alrMax: ARRAY[0..15] OF LREAL := [16(2.2)]; (
    maximum time [ms], the pulse is ON for RC Servo Mode )
    END_VAR
    VAR_OUTPUT
    END_VAR
    VAR
    (
    no longer supported, use axEnable instead
    _usiUsedOutputs: USINT := 16; ( number of used outputs ) )
    _usiSMAxes: USINT := 0; (
    internal counter for registered SM axes )
    _rPeriod : LREAL; (
    Period [ms], time between two rising edges *)
    _alrOldPWM : ARRAY[0..15] OF LREAL;
    _lrOldFreq : LREAL;
    END_VAR
    VAR_TEMP
    i, usi : USINT;
    END_VAR

     

    Last edit: wollvieh 2022-03-22
  • apod

    apod - 2022-05-17

    Thank you! Runs perfectly.

     
  • wollvieh

    wollvieh - 2022-05-17

    good to hear! Enjoy!
    @e.schwellinger : i've corrected the PWM frequency Faktor In the library ,and measured it with my Old (but gold) Hameg Osszilscope. Should
    be corrected in the 3s Sample lib.

     

Log in to post a comment.