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.

RTOS/TM4C129ENCPDT: quadrature encoder Issue

Part Number: TM4C129ENCPDT

Tool/software: TI-RTOS

Hi,

I am facing a problem In Qudrature Encode API Function.

I am facing same Problem metion in below thread,

As Mention in thread, I am using same code and In my code Direction and position is working fine.Velocity is the only issue.

I am getting Below output.

++++++++ qei.c: qeiPosition = {100} +++++++

++++++++ qei.c: qeiDirection = {1} +++++++

++++++++ qei.c: qeiVelocity = {0} +++++++

Regards,

Nimesh

  • Here is my code,

    Void QEITaskFxn(UArg arg0, UArg arg1)
    {
    	uint32_t qeiVelocity = 0;
    	uint32_t qeiPosition = 0;
    	int32_t qeiDirection = 0;

     //Quadrature Encoder (QEI)
    SysCtlPeripheralEnable(SYSCTL_PERIPH_QEI0);
    GPIOPinConfigure(GPIO_PL1_PHA0);
    GPIOPinTypeQEI(GPIO_PORTL_BASE, GPIO_PIN_1);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_QEI1);
    GPIOPinConfigure(GPIO_PL2_PHB0);
    GPIOPinTypeQEI(GPIO_PORTL_BASE, GPIO_PIN_2); //

    	// Disable the quadrature encoder.
    	//
    	QEIDisable(QEI0_BASE);
    
    
    	QEIConfigure(QEI0_BASE, (QEI_CONFIG_CAPTURE_A_B | QEI_CONFIG_NO_RESET | QEI_CONFIG_QUADRATURE | QEI_CONFIG_NO_SWAP),10000);
    
    	QEIVelocityConfigure(QEI0_BASE,QEI_VELDIV_1,1000);
    
    	QEIVelocityEnable(QEI0_BASE);
    
    	QEIPositionSet(QEI0_BASE, 1000);
    	
            //
    	// Enable the quadrature encoder.
    	//
    	QEIEnable(QEI0_BASE);
    
    	//
    	// Delay for some time...
    	//
    	Task_sleep(1);
    
    	//
    	// Read the encoder position.
    	//
    //	qeiVelocity = QEIVelocityGet(QEI0_BASE);
    //	System_printf("\r\n++++++++ qei.c: qeiVelocity = {%d} +++++++\r\n", qeiVelocity);
    
    	while (1)
    	{
    
    		qeiPosition = QEIPositionGet(QEI0_BASE);
    		System_printf("\r\n++++++++ qei.c: qeiPosition = {%d} +++++++\r\n", qeiPosition);
    		System_flush();
    
    		qeiDirection=QEIDirectionGet(QEI0_BASE);
    		System_printf("\r\n++++++++ qei.c: qeiDirection = {%d} +++++++\r\n", qeiDirection);
    		System_flush();
    
    		qeiVelocity = QEIVelocityGet(QEI0_BASE);
    		System_printf("\r\n++++++++ qei.c: qeiVelocity = {%d} +++++++\r\n", qeiVelocity);
    		System_flush();
    
    		Task_sleep(1000);
    	}
    
    }
    

    Regards,

    Nimesh

  • Feel your pain - and it must be noted that the, "QEI Code Example - furnished w/in "SW-DRL-UG-xxxx" - proved embarrassingly brief and "avoided entirely" the (more complex) QEI-Velocity function!     To be fair - and in that (so very brief) example's favor - detail was provided re: "Setting of the maximum position parameter" w/in function "QEIConfigure()."     Still - even when "graded on the curve" - the award of "D" would be generous!

    As both you & the earlier arriving poster reported "Velocity Issue" - might you (both) have (more deeply) considered both: "that maximum position" parameter AND its "related parameter" w/in "QEIVelocityConfigure()?"      Your code list two different values - and is totally silent - as to how (either) was chosen!      That cannot be good - can it?

    Consider the impact if those parameters are:

    • set too high
    • set too low
    • set properly

    Such proves a "good starting point" for (your) continued analysis - does it not?      "Some" detail - especially the "significant detail" - must be provided to maximize the effectiveness of your "helpers."

    You may choose to alter those parameters - and "widen" the delay time w/in your "while loop" - and see if the "Velocity function" (then) starts to perform...

  • Hi cb1,

    Thanks for the Reply.

    I am applying your suggestion But I have below doubts. Please explain me in detail if possible.

    1. In  QEIVelocityConfigure(uint32_t ui32Base, uint32_t ui32PreDiv, uint32_t ui32Period) Last Parameter "ui32Period" Is in milli seconds or seconds.

    2. In QEIConfigure(uint32_t ui32Base, uint32_t ui32Config, uint32_t ui32MaxPosition)  Lat Paramete "ui32MaxPosition" Is affected In Velocity Measurement? If Yes ,  How it affect velocity?

    Regards,

    Nimesh

  • My friend - you announce "doubts!"       Are you not (almost) alone (ship-wrecked) upon a deserted south-sea island - and arrives a sleek craft - and one offering "food & water."     And you have doubts?

    1. In  QEIVelocityConfigure(uint32_t ui32Base, uint32_t ui32PreDiv, uint32_t ui32Period) Last Parameter "ui32Period" Is in milli seconds or seconds.

    NEITHER!    (doubt slayer #1)     That last parameter is "System Clock ticks."     Thus - both your mS & S "assertions" fail.    

    2. In QEIConfigure(uint32_t ui32Base, uint32_t ui32Config, uint32_t ui32MaxPosition)  Last Paramete "ui32MaxPosition" Is affected In Velocity Measurement? If Yes ,  How it affect velocity?

    This time you correctly noted that (pesky) last parameter.      And that parameter should specify the, "Number of Encoder Pulses arriving during one complete motor revolution."    You must understand (or at least accept, that.)     (doubt slayer #2)     Thus, "To calculate velocity" - you may note that "true velocity" is calculated by:

    "QEIVelocityGet()'s returned value (which is the number of pulses detected in the time-frame specified by "QEIVelocityConfigure()" followed by several math operations - which "normalize" the velocity calculation.)      Read this several times if "unclear."   

    For "extra credit" - why don't  "you" (now) supply the "few" remaining math operations to convert, "QEIVelocityGet()'s returned value into (either) RPS or RPM.     (so that myself/others - may bask in "doubt.")

    Your kind award of  "Verified Answer" may avoid my presence on a major Chicago street-corner - seeking "donations."      (some funds are required to "sail far" from your deserted island...)

  • Hi cb1,

    Thanks for your Reply.

    Now i am getting correct velocity. Here is my working code.

        //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
        //Quadrature Encoder (QEI)
        SysCtlPeripheralEnable(SYSCTL_PERIPH_QEI0);
        GPIOPinConfigure(GPIO_PL1_PHA0);
        GPIOPinTypeQEI(GPIO_PORTL_BASE, GPIO_PIN_1);
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_QEI1);
        GPIOPinConfigure(GPIO_PL2_PHB0);
        GPIOPinTypeQEI(GPIO_PORTL_BASE, GPIO_PIN_2);
    
        GPIOPinConfigure(GPIO_PL3_IDX0);
        GPIOPinTypeQEI(GPIO_PORTL_BASE, GPIO_PIN_3);
        //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
    
    Void QEITaskFxn(UArg arg0, UArg arg1)
    {
    	uint32_t qeiVelocity = 0;
    	uint32_t qeiPosition = 0;
    	int32_t qeiDirection = 0;
    
    	// Disable the quadrature encoder.
    	QEIDisable(QEI0_BASE);
    
        	QEIConfigure(QEI0_BASE, (QEI_CONFIG_CAPTURE_A_B | QEI_CONFIG_RESET_IDX | QEI_CONFIG_QUADRATURE | QEI_CONFIG_SWAP), 1000);
    
    	// Configure the Velocity.
    	QEIVelocityConfigure(QEI0_BASE,QEI_VELDIV_1,30000000);
    
    	// Note	:For Claculating "ui32Period" , TM4c129NCPDT Supports 120 MHz Operation, So I Have to Take 
    	//	ui32Period = 1/4(120 MHz) = 30000000
    
    	// setting the Position.
    	QEIPositionSet(QEI0_BASE, 0);
    
    	// Enable the quadrature encoder velocity.
    	QEIVelocityEnable(QEI0_BASE);
    
    	// Enable the quadrature encoder.
    	QEIEnable(QEI0_BASE);
    
    	// Delay for some time...
    	Task_sleep(1000);
    
    	while (1)
    	{
    		// Read the encoder position.
    		qeiPosition = QEIPositionGet(QEI0_BASE);
    		System_printf("\r\n++++++++ qei.c: qeiPosition = {%d} +++++++\r\n", qeiPosition);
    		System_flush();
    
    		// Read the encoder Direction.
    		qeiDirection=QEIDirectionGet(QEI0_BASE);
    		System_printf("\r\n++++++++ qei.c: qeiDirection = {%d} +++++++\r\n", qeiDirection);
    		System_flush();
    
    		// Read the encoder velocity.
    		qeiVelocity = QEIVelocityGet(QEI0_BASE);
    		System_printf("\r\n++++++++ qei.c: qeiVelocity = {%d} +++++++\r\n", qeiVelocity);
    		System_flush();
    
    		Task_sleep(1000);
    	}
    
    }
    

    Regards,

    Nimesh

  • Greetings Nimesh,

    Both proud of and pleased for your persistence - in Solving your Issue.     (prmarily by yourself - w/some/slight guidance.)     Very good, that!

    Yet - should we not "dig a bit deeper" - now that you've achieved (some) response from your "Velocity function?"

    Earlier you employed the value 10K (10,000) w/in "QEIConfig()" - and today's post shows that reduced to 1K.    (a factor of TEN!)    May we ask, "How that new value was determined?"     Do you (really) achieve 1K encoder impulses during one complete motor revolution?

    Also today QEIVelocityConfig() reveals 30M (30,000,000) - past was 1K (1,000) - that's a (truly) substantial change - is it not?     In an earlier post we discovered that this parameter has "System Clock ticks" as units - thus your use of 30/120 yields 1/4 second - or 250mS as the, "Velocity Measurement Period."    (and earlier - it was suggested that you "consider" the effect of "altering" your use of the "far too small" (1K) parameter.)

    So clearly - the added "aperture" (time in which your velocity function computes) has enabled your success.     And as your "measurement aperture (or window) is 1/4 Second" - must you "multiply that result by FOUR - to achieve (most likely) RPS?    (Motor Revolutions per Second)     And then again by SIXTY (i.e. RPS * 60) which yields RPM.    (Motor Revolutions per Minute)     You must note too - that the "1,000" parameter (w/in QEIConfig()) may impact such calculation as well.     You can determine this via a "speed-controlled" motor rotation - and observing the output of the Velocity function.

    Do note that w/in motor control - RPM is dominant - and (other) measures (but not RPS) are "unusual" and unlikely to be "universally" recognized...   (you may wish to move "more" towards the herd's center...)