This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

EK-TM4C1294XL: Problem by using the combination of QEI and PWM modul

Part Number: EK-TM4C1294XL

Hello,

I am trying to implement a motor regulation application with the evaluation kit TM4C1294XL. It seems that there is an issue by using the combination of PWM and QEI. Separately, both moduls are working fine. So I am able to generate a PWM signal with a given dutycycle. Furthermore it is possible to read and calculate the velocity and RPM by using the QEI.

I calculate the current rpm and fit the pi regulation algorithm. This algorithm returns the a new dutycycle. As soon as I fit the new calculated dutycycle to the ROM_PWMPulseWidthSet function it seems that the period time of the PWM signal changes to the selected measure time of the qei modul  which I configured with the function ROM_QEIVelocityConfigure

Do you have any idea how I could solve the problem? .. it seems that the qei blocks the pwm modul. could it be the reason?

Here the init code blocks and main routine:

 // Enable QEI Peripherals
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL); //PL1; PL2
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_QEI0);

    //Set Pins to be PHA0 and PHB0
    ROM_GPIOPinConfigure(GPIO_PL1_PHA0);
    ROM_GPIOPinConfigure(GPIO_PL2_PHB0);

    //Set GPIO pins for QEI.
    ROM_GPIOPinTypeQEI(GPIO_PORTL_BASE, GPIO_PIN_1 |  GPIO_PIN_2);

    //DISable peripheral and int before configuration
    ROM_QEIDisable(QEI0_BASE);
    ROM_QEIIntDisable(QEI0_BASE, QEI_INTERROR | QEI_INTDIR | QEI_INTTIMER | QEI_INTINDEX);

    // Configure quadrature encoder, use an arbitrary top limit of 2000
    ROM_QEIConfigure(QEI0_BASE, (QEI_CONFIG_CAPTURE_A_B  | QEI_CONFIG_NO_RESET  | QEI_CONFIG_QUADRATURE | QEI_CONFIG_NO_SWAP), 479);//QEI_CONFIG_CLOCK_DIR

    // Enable the quadrature encoder.
    ROM_QEIEnable(QEI0_BASE);

    //Set position to a middle value so we can see if things are working
    ROM_QEIPositionSet(QEI0_BASE, 0);

    ROM_QEIVelocityConfigure(QEI0_BASE, QEI_VELDIV_1, 120000000); //1000ms measure time
    ROM_QEIVelocityEnable(QEI0_BASE);
// enable necessary peripherals
    ROM_SysCtlPeripheralEnable(L298N_PWM_CONFIG0);
    ROM_SysCtlPeripheralEnable(L298N_PWM_CONFIG1);
    ROM_SysCtlPeripheralEnable(L298N_GPIO_CONFIG0);
    ROM_SysCtlPeripheralEnable(L298N_GPIO_CONFIG1);

    // setup digital output signals for direction pins
    ROM_GPIOPinTypeGPIOOutput(L298N_IN1);  // IN1
    ROM_GPIOPinTypeGPIOOutput(L298N_IN2);  // IN2

    // set pwm clock
    ROM_PWMClockSet(PWM0_BASE, PWM_SYSCLK_DIV_8);  // 15 MHz
    pwm_clock = (system_clock / 8);

    ROM_GPIOPinConfigure(L298N_ENA_TYPE);
    ROM_GPIOPinTypePWM(L298N_ENA);

    // set pwm mode
    ROM_PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC);

    // set pwm period time
    //period_time_ticks = ((system_clock / 64) / PWM_FREQUENCY)-1;
    period_time_ticks = (pwm_clock / PWM_FREQUENCY);
    ROM_PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, period_time_ticks);

    // enable pwm output
    ROM_PWMOutputState(PWM0_BASE, PWM_OUT_1_BIT, true);

    // start pwm generator (timers)
    ROM_PWMGenEnable(PWM0_BASE, PWM_GEN_0);
 while(1) {
        regulation.setParameters(Kp, Ki, Kd);

        // run motor
        motordriver.run(FORWARD, duty);

        // measure RPM
        rpm_sensor.calculateRPM();
        rpm_x = rpm_sensor.getRPM();

        // update motor regulation algorithm
        duty = regulation.PI_Regulation(rpm_w, rpm_x);
        ROM_SysCtlDelay(g_ui32SysClock/3 /100); // 10ms


        if(a==1) {
           GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0);
           a=2;
        } else if(a==2) {
           GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 1);
           a=1;
        }
}

Many thanks in advanced!

Best regards

  • There shouldn't be. What demo software package did you start with? I will need to do some checking when I get back to the office on Monday.
  • asdfasdf said:

    // set pwm period time

    //period_time_ticks = ((system_clock / 64) / PWM_FREQUENCY)-1;

    period_time_ticks = (pwm_clock / PWM_FREQUENCY);

    ROM_PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, period_time_ticks);

    Does not your use of a, "formulaic calculation" of "PWM Period" invite in such issues?    

    Always and only - firm/I would prefer you to (first) hard code the value for PWM Period - that's inviolate!     (i.e. a FAR SURER thing!)

    You've presented "No case" for "PWM Period variability" - thus (potentially) enabling such change provides no advantage - and may (instead) invite unwanted intrusions...   (just as you report!)

  • Hello,
    Many thanks for your quick reply. I started from a new empty project. and don't use any example for starting.
    As references I used the example codes of the driverlib documentation and the CLP_Workbook.

    If you want I could send you the complete source files via private message?
    I think it would be to much for a post here.

    best regards
  • My (keyboard, (partial) home-row) friend,

    Are you not making this effort, "Far too hard?"

    Simply replace the "PWMPeriod" parameter (you used a formula) with a numeric value (thus hard coded - cannot change on its own) - do not employ a formula!      

    The variables w/in that formula may be changed by (other, even unwanted/unexpected) operations w/in your program - thus you INVITE Vulnerability.        And that's NOT Good!

    Humor me - key in a numeric value - and re-launch your program.     And then report...

    In the (highly unlikely) event that you believe this recommendation NOT to succeed (in freezing your PWM Period) clearly describe your method of, "Measuring the PWM Period."    

    Firm/I have designed, produced, then shipped thousands of such boards employing this "hard coded" method - NEVER has the PWM Period "strayed" as you recite...

  • Hello cb1_mobile,

    Also many thanks for your quick replies. Sorry for my late reply but yesterday there was no time.

    I definitely agree with you that a hardcoded value decrease the possibilty of unwanted effects or whatever.

    I already tried it but without success. I set the pwm period to hard coded value. I want a pwm frequency of 500Hz so I fit the function  ROM_PWMGenPeriodSet with the value 30000. (calculation 120MHz / 8) = 15MHz --> 15MHz/500 = 30000. After setting up the pwm as described in my first post I am able to set the pulse width with the function: ROM_PWMSetPulseWidth(...)

    I checked the functionality by measuring different dutycycles of the pwm output signal with the oscilloscope. (Also the periodtime is correct)

    So in the case where I am using the PWM alone it works fine. without any problems.

    In the next step I added the QEI modul and configured it as described in my first post. I want to use QEI to calculate the RPM of my DC motor. As sensor I use the GP1A30R (optical sensors in combination with a encoder). After configuring the QEI I am able to detect the counts of pulses per second and calculate the RPM. The QEI was configured with a measure time of 1 second because of better resolutions with higher measure times.

    So at this point in my software the PWM and the QEI was configured and both moduls work fine. I can change the dutycycle of the PWM signal continously in the main - while(1) loop and also the QEI modul calculates the rpm of the motor. I face no issue with the period time of the pwm signal or with the detection of the motor rpm signal with qei.

    Now I also implement a simple pi regulation algorithm. This algorithm works also fine and I tested it with different hardcoded values.  

    If you look now to the following main-while(1) loop code - with this code the PWM signal is working great and also QEI rpm detection works fine --> no issue with the period time.

    while(1) {
            regulation.setParameters(Kp, Ki, Kd);  // set pi regulation parameter
    
            // run motor
            motordriver.run(FORWARD, duty); // start dc motor with a defined/calculated dutycycle
    
            // measure RPM
            rpm_sensor.calculateRPM();  // measure and calculate RPM of QEI - read counts/second with QEIVelocityGet(..)
            rpm_x = rpm_sensor.getRPM(); //just get the rpm value
    
            // update motor regulation algorithm
            duty = regulation.PI_Regulation(rpm_w, 3500);   // this function calculates the new dutycycle for the given rpm_w and the hardcoded 3500 - just for testing
            ROM_SysCtlDelay(g_ui32SysClock/3 /100); // 10ms   // further delay of 10ms
    
            // just for testing if there is an issue with the 10ms delay --> the pin switches a LED
            if(a==1) {
               GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0);
               a=2;
            } else if(a==2) {
               GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 1);
               a=1;
            }
    }

    So in the above code the pi- regulation coupling is not closed because the I used a hardcoded value of 3500 for the current rpm value. In this case the PWM and also the calculation of the rpm_x value works fine and without any issue. I checked it by switching the variable duty with the debugger and measuring the output signal with the oscilloscope. Also, the pwm frequency is not changed and 500 Hz. Further , the QEI modul works also fine.

    In the following code I close the regulation loop.

    while(1) {
            regulation.setParameters(Kp, Ki, Kd);  // set pi regulation parameter
    
            // run motor
            motordriver.run(FORWARD, duty); // start dc motor with a defined/calculated dutycycle
    
            // measure RPM
            rpm_sensor.calculateRPM();  // measure and calculate RPM of QEI - read counts/second with QEIVelocityGet(..)
            rpm_x = rpm_sensor.getRPM(); //just get the rpm value
    
            // update motor regulation algorithm
            duty = regulation.PI_Regulation(rpm_w, rpm_x);   // this function calculates the new dutycycle for the given rpm_w and the rpm_x
            ROM_SysCtlDelay(g_ui32SysClock/3 /100); // 10ms   // further delay of 10ms
    
            // just for testing if there is an issue with the 10ms delay --> the pin switches a LED
            if(a==1) {
               GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0);
               a=2;
            } else if(a==2) {
               GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 1);
               a=1;
            }
    }

    In this case the PWM output signal changes the periodtime to 1second. Same time as I configured in the QEI modul. The interesting point is that the QEIVelocityGet(..) doesn't block the whole while(1) loop until the new measured value of the QEI modul is available. Instead the LED is "blinking" as expected with the 10ms delay ( I checked this with the oscilloscope) .

    Just the th PWM period is changing to 1 second. Maybe a interrupt or a whatever of the PWM or QEI blocks each other!? is this possible?

    I am a little bit confused about this and I don't know what the problem could be.

    Many Thanks in advanced!

    kind regards

  • Thank you - much detail supplied - that's always preferred.

    I'm glad that you DID succeed w/the suggestion of "hard-coded" parameter for PWMPeriodSet() - it proves (most) always productive to "start" from "limited & known (unchangeable) conditions" - only "move from that" after test/verify.

    Your use of 500Hz as PWM Frequency seems far lower than most "motor control" applications firm/I have designed or consulted.     (usual suspects: 4KHz-22KHZ)     How did you arrive @ 500Hz?

    Business does not (always) "boom" for small tech firms (as it does now) so (striking while solder iron "hot") do allow (some) time for "Sunday morning client sessions" and I'll further review your most recent posting upon return...

    [edit] 08:00 CST:  While "unknown" to myself (and apparently to vendor) perhaps there IS some unwanted "interaction" between your (chosen) PWM Generator and the QEI module.    I suspect it should NOT be hard for you to switch to a DIFFERENT PWM Module - and test to see if this misfortune continues.     As always - it is preferred that you test across MULTIPLE Boards (never just one) to avoid the scourge of "single board anomaly!)

    Yet another point - "opening the QEI Module for SO LONG (i.e. 1 second) to "enhance resolution" strongly suggests that your QEI encoder is (extremely) "Resolution-Lite!"     Any decent encoder should yield multiple pulses/revolution - and thus avoid the "horror" which may result from "so LONG a QEI Velocity calculation frame!"     Be sure to check that the QEI can accommodate so large a number - we've not used this vendor's device in some time - but "everything" (for now - in your situation) must remain,  "challenged and in play."

  • Thank you very much for your support!

    I will check another PWM modul today.

    I use a Legotechnic dc motor 9V (saled in the 90's). I just tried some different PWM frequencies and in my opinion it works  best with hte frequency of 500Hz. But I will keep in mind your suggestion and will try your mentioned frequency range.

    Further, I definitely agree with you that the measure time of 1 second is very long but I don't find any information about maximum time ratings for the qei modul in the datasheet.  So I wanted to test this configuration.

    Although, it is strange that there is some unexpected effect by using the combination of the pwm and qei modul. Because QEI uses a seperate timer modul as the pwm and there is no shared component or peripheral...

    kind regards

  • Thank you - staff mentioned that (maybe) you have (older) code - "buried" - and it makes that "unwanted" call to PWMPulseWidthSet().

    In over TEN Years using predecessor & current vendor's devices - NEVER have we noted the PWM Generator's "Pulse Width" to alter.

    One more path for you to consider: Set up the PWM Module (minus the QEI function) and when running properly - "carefully inspect, note & log/record" - the key PWM Registers. Then enable the QEI module as well - and check for (unwanted) changes to any of those (earlier recorded) PWM Registers.

    You may also "dial down" that (extreme) QEI Velocity parameter - (suggest by 50%, minimum) - and see, "how or if" this impacts the tormented PWM.

    All of this should "follow" your change to a different PWM Generator - in the (most) unlikely event that there IS some interaction...