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.

CCS/LAUNCHXL-F28069M: Speed Control - Improve resolution 5rpm with LAUNCHXL-f28069m, BOOSTXL-DRV8305EVM and proj_lab06e of Motorware

Part Number: LAUNCHXL-F28069M
Other Parts Discussed in Thread: MOTORWARE, CONTROLSUITE

Tool/software: Code Composer Studio

Dear all,

I am developing a speed control for two motors. I use the LAUNCHXL-f28069m with two BOOSTXL-DRV8305EVM. The program that I use is the proj_lab06e of motorware.

The goal is to adjust external the speed by an analog input voltage 0 – 3.3V. The max. speed is 5krpm.

In the source code “proj_lab06e” there are several function given.

 Extract of the program code:

(With this code the resolution that I get is 1krpm. i.e. I have only 5 speeds: 1krpm, 2krpm, 3krpm, 4krpm and 5krpm.)

 

value = (_iq)ADC_readResult(obj->adcHandle,ADC_ResultNumber_14);  //reading the ADC set value

pAdcData->dcBus = value; // save ADC value

value = _IQmpy(gAdcData[HAL_MTR2].dcBus, _IQ(0.0012820512820513));             // max. speed= 5krpm, max. ADC value 3900 -> 5 / 3900 = 0.00128205...

gMotorVars[HAL_MTR1].SpeedRef_krpm = _IQ(value);

 

With another code script it was possible to get a resolution of 40rpm. But this resolution is also too low. (But I think it is not a correct notation)

                            

value = (_iq)ADC_readResult(obj->adcHandle,ADC_ResultNumber_14);

refvalue = _IQmpy(value,_IQ(8));

pAdcData->dcBus = _IQmpy(refvalue,_IQ(0.004));

refValue = _IQmpy(_IQ(1),gAdcData[HAL_MTR2].dcBus);

gMotorVars[HAL_MTR1].SpeedRef_krpm = _IQmpy(_IQ(refValue),gSpeed_hz_to_krpm_sf[HAL_MTR1]*1.31);

gMotorVars[HAL_MTR1].SpeedRef_krpm = calculated value;        

 

I know the “value” is a _iq type and has a range of 127.999.. -128 with a resolution of around 0.000 000 060.

But my suspicion is, that I’m only able to calculate “integers”:

127 = 5krpm                                                                         

126 = 4.96krpm

125 = 4.92krpm

because I can’t realize e.g. 125.5 = 4.941krpm. What am I doing wrong?

 

What do I need to do to get a higher resolution (e.g. 5rpm)? Could you please give me an advice to solve this problem?

 

I use completely the proj_lab06e and basically I changed:

proj_lab06e.c   > lines 713 – 749

hal_2mtr.h         > lines 681 – 710

The files are attached.

Moreover, the motor is my own motor - no standard motor. In fact there are two motors connected. Only one motor will be observed/measured and the other gets the same parameters and values as the observed one. So this works well.

Thanks in advance to all.

SpeedControlCode.zip

  • I believe the issue you're seeing is that the ADC_readResult() function returns a value of type uint_least16_t, which can only return integers. You won't be able to cast a uint16 to an _iq24 and expect a fractional result

    Sean
  • Thank you for the reply I think you're right. I have some further question:

    Suppose, the input-voltage that the ADC read is 3.0V and the corresponding ADC value is 4095. I specify that the speed of 5krpm has the max. adc value of 4095.
    If the input-voltage is 2.3V, the ADC value is 3140 and the corresponding speed is 3.833krpm. For this assumption I attached an Excel table.
    Also I have a question about the data conversion of uint16 to _iq. In the file “hal_2mtr.h” it is written:

    // convert current A
    value = (_iq)ADC_readResult(obj->adcHandle,ADC_ResultNumber_1);
    value = _IQ12mpy(value,current_sf);
    pAdcData->I.value[0] = value;

    This code is written by the programmer of lab06e.
    • I think it should be possible to handle a uint16 value to a _iq24 value.
    • I also think the uint16 value has a very good resolution. It varies only 1-2 rpm per mV. Please see attached Excel-table.

    But to get the speed according to the input voltage, the value should be converted into _iq24. My question now, how could I do that?

    My assumption:
    I have an input-voltage of 2.3V. The ADC-value is 3140 (decimal) -> uint16 = 0000 1100 0100 0100 (binary)
    Due to the code part above it should be possible to cast the uint16 to an _iq24.
    And now the _iq24 value is: 000 0000.0000 0000 0000 1100 0100 0100.

    But unfortunately this doesn’t work as planned. What am I doing wrong or do I an error in reasoning?

    Thank you very much for your help.

    2604.resolution_speed.xlsx

  • The way I would take care of this is as such:

    If you have an ADC range of 4096, and you want to map that range to 5k RPM

    4096/5000 = 0.8192 steps/rpm, and since your variable SpeedRef_krpm is in kRPM, 819.2 steps/krpm

    (ADC value)/819.2 = speed in krpm

    you could do something like

    _iq mySpeed;
    _iq12 divisor = _IQ12(819.2);
    mySpeed = _IQ12toIQ( _IQ12div( ((_iq12)gAdcData[HAL_MTR2].dcBus), divisor) );

    and then mySpeed should be a value from 0-5 in IQ24 format.

    In general, to convert between IQ numbers, you use _IQtoIQN() or _IQNtoIQ(), where IQ is always the global Q type

    Check out the IQmath_Quickstart PDF in ControlSuite for all of the IQmath function calls

    Sean