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.

QEP-example adaptation problems and IQ-math

Other Parts Discussed in Thread: CONTROLSUITE

Hi there,
 I'm using F28335 and setting up a 500 line/rev encoder for the QEP-module. I'm using an old TI-example header file for helping with the setup:

// TI File $Revision: /main/2 $
// Checkin $Date: July 30, 2009   18:44:51 $
//###########################################################################
//
// FILE:	Example_posspeed.h
//
// TITLE:	Pos/speed measurement using EQEP peripheral
//
// DESCRIPTION:
//
// Header file containing data type and object definitions and 
// initializers. 
//
//###########################################################################
// Original Author: SD
//
// $TI Release: DSP2833x/DSP2823x C/C++ Header Files V1.31 $
// $Release Date: August 4, 2009 $
//###########################################################################

#ifndef __POSSPEED__
#define __POSSPEED__

#include "IQmathLib.h"         // Include header for IQmath library
/*-----------------------------------------------------------------------------
Define the structure of the POSSPEED Object 
-----------------------------------------------------------------------------*/
typedef struct {int theta_elec;     	// Output: Motor Electrical angle (Q15)  
                int theta_mech;     	// Output: Motor Mechanical Angle (Q15) 
                int DirectionQep;      	// Output: Motor rotation direction (Q0) 
                int QEP_cnt_idx; 	 	// Variable: Encoder counter index (Q0)
                int theta_raw;     		// Variable: Raw angle from Timer 2 (Q0)            
                int mech_scaler;    	// Parameter: 0.9999/total count, total count = 4000 (Q26)
                int pole_pairs;     	// Parameter: Number of pole pairs (Q0) 
                int cal_angle;     		// Parameter: Raw angular offset between encoder and phase a (Q0) 
                int index_sync_flag; 	// Output: Index sync status (Q0)                   

                Uint32 SpeedScaler;     // Parameter :  Scaler converting 1/N cycles to a GLOBAL_Q speed (Q0) - independently with global Q
                _iq Speed_pr;           // Output :  speed in per-unit
                Uint32 BaseRpm;         // Parameter : Scaler converting GLOBAL_Q speed to rpm (Q0) speed - independently with global Q
                int32 SpeedRpm_pr;      // Output : speed in r.p.m. (Q0) - independently with global Q                               

                _iq  oldpos;  			// Input: Electrical angle (pu) 
                _iq Speed_fr;           // Output :  speed in per-unit
                int32 SpeedRpm_fr;     	// Output : Speed in rpm  (Q0) - independently with global Q
                void (*init)();     	// Pointer to the init funcion          
                void (*calc)();    		// Pointer to the calc funtion        
                }  POSSPEED;

/*-----------------------------------------------------------------------------
Define a POSSPEED_handle
-----------------------------------------------------------------------------*/
typedef POSSPEED *POSSPEED_handle;

/*-----------------------------------------------------------------------------
Default initializer for the POSSPEED Object.
-----------------------------------------------------------------------------*/

#if (CPU_FRQ_150MHZ)
  #define POSSPEED_DEFAULTS {0x0, 0x0,0x0,0x0,0x0,16776,2,0,0x0,\
        94,0,6000,0,\
        0,0,0,\
        (void (*)(long))POSSPEED_Init,\
        (void (*)(long))POSSPEED_Calc }
#endif
#if (CPU_FRQ_100MHZ)
  #define POSSPEED_DEFAULTS {0x0, 0x0,0x0,0x0,0x0,16776,2,0,0x0,\
        63,0,6000,0,\
        0,0,0,\
        (void (*)(long))POSSPEED_Init,\
        (void (*)(long))POSSPEED_Calc }
#endif


/*-----------------------------------------------------------------------------
Prototypes for the functions in posspeed.c                                 
-----------------------------------------------------------------------------*/
void POSSPEED_Init(void);                                              
void POSSPEED_Calc(POSSPEED_handle);
                
#endif /*  __POSSPEED__ */

However, as mentioned, my encoder is 500l/rev, and thus (by my calculations) the mech_scaler should be set to 16776*2 = 33552. And then i'm getting a warning when building the project, stating that the conversion caused a sign change (because number is too large?).

I'm not completely sure how to program myself out of this problem. I tried changing the type from int to Uint32, but I'm not sure if this is the right way.
I'm aware of the motor-control libraries added in ControlSuite, but I'm not sure how to implement those. And I've spend a great deal of time trying to understand this code, so I'd prefer to just modify this :)

I've seen similar questions on the forum, but not something answering this. I hope you can help :)

Edit: For reference, the code uses the value to calculate position (and speed in another part of the program) with this code:

//**** Position calculation - mechanical and electrical motor angle  ****//
     p->DirectionQep = EQep1Regs.QEPSTS.bit.QDF;    // Motor direction: 0=CCW/reverse, 1=CW/forward

	 pos16bval=(unsigned int)EQep1Regs.QPOSCNT;     // capture position once per QA/QB period
     p->theta_raw = pos16bval+ p->cal_angle;        // raw theta = current pos. + ang. offset from QA

	 // The following lines calculate p->theta_mech ~= QPOSCNT/mech_scaler [current cnt/(total cnt in 1 rev.)]
	 // where mech_scaler = 4000 cnts/revolution
     tmp = (long)((long)p->theta_raw*(long)p->mech_scaler);  	// Q0*Q26 = Q26
     tmp &= 0x03FFF000;
     p->theta_mech = (int)(tmp>>11);         		// Q26 -> Q15
     p->theta_mech &= 0x7FFF;