Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
7 years, 4 months ago.
PWM frequency unstable when reading data in COM port
hi everyone
first i'm french sorry for my english is bad ^^
i have a critical time application that require a stable PWM frequency but when i'm reading data from PC trough com port the frequency become very unstable i have no idea why where i'm wrong ? thanks for help
This is my code
#include "mbed.h" Serial COM(USBTX, USBRX); DigitalOut pc_activity(LED1); PwmOut rpm_pulse(D5); //PwmOut air_pwm(D2); int serial_byte; long map(long x, long in_min, long in_max, long out_min, long out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } int main() { COM.baud(115200); COM.format(8, SerialBase::None, 1); while(1) { if(COM.readable()){ pc_activity = !pc_activity; serial_byte = COM.getc(); if(serial_byte != 0xFF){ return; } serial_byte = COM.getc(); if(serial_byte != 0x02){ return; } int speed_kph = COM.getc(); int speed_decimal = COM.getc(); int lsb_rpm = COM.getc(); int msb_rpm = COM.getc(); int air_pressure = COM.getc(); int fuel = COM.getc(); int oil_pressure = COM.getc(); int water_temperature = COM.getc(); int batterie_voltage = COM.getc(); int engine_gear = COM.getc(); int retarder_steps = COM.getc(); int oil_temperature = COM.getc(); int OCTET_0 = COM.getc(); int OCTET_1 = COM.getc(); int OCTET_2 = COM.getc(); int rpm = msb_rpm; rpm = rpm <<8; rpm = rpm + lsb_rpm; //------------------------------------------------------------------------------------------------------------------------------- if (rpm > 200){ rpm = map(rpm, 200, 3000, 20, 1000); float period = 1.0f/rpm; rpm_pulse.period(period); rpm_pulse.write(0.50f); } air_pressure = map(air_pressure, 0, 140, 0, 100); float air_press = air_pressure /100.0f; oil_pressure = map(oil_pressure, 0, 86, 0, 100); float oil_press = oil_pressure /100.0f; air_pwm.period(0.0025f); air_pwm.write(oil_press); } } }
1 Answer
7 years, 4 months ago.
In addition what you found, have a look at FastPWM: https://developer.mbed.org/users/Sissors/code/FastPWM/ (too lazy to check if your device is supported, but otherwise it is fairly easy to add, might even be that the F401 code supports it). It generally handles changing settings of PWM better than the standard mbed code with less/no glitches.
Hi,
Thanks ! it's working much better :) but is it normal that i have to /2 the period to obtain the same frequency i had with mbed PWM library ?
if ((rpm > 200) && (rpm != prev_rpm)){ prev_rpm = rpm; rpm = map(rpm, 200, 3000, 20, 1000); float period = (1.000000f/rpm)/2; rpm_pulse.period_us(double(period)*1000000); rpm_pulse.write(0.50f); }
You are the second one who has noticed it, sadly also on a device I don't have. I will during the holidays see if I can reproduce it on my F401. Apparently it happens on some PWM units, but not on all PWM units. So I guess some have a different prescaler/input clock than others, and I will need to figure that out and get a fix for it in.
Which pin do you use?
posted by 22 Dec 2016Pfff I did figure out that on some STM boards some timers have a divide by two from the main clock. On some of these boards that should can be disabled (and might be already in the mbed code), on others it cannot be disabled. So then we have timers running at different frequencies. Compensating for the div2 is easy enough, but I wonder if there is a nice way to do it instead of having to add another list if if then else.
posted by 31 Dec 2016Problem should be fixed, let me know if that is not the case for you after updating (right mouse button on the lib, update). By default mbed lib sets the PWM at 50Hz. Now FastPWM reads the prescaler/timer values and uses that to calculate if an additional prescaler is active. If yes it compensates its future calculations.
posted by 01 Jan 2017
Please add
posted by Erik - 21 Dec 2016<<code>> and <</code>>
at separate lines to make it readable. Also can you clarify what you mean by unstable? And which device is this?sorry the code is readable now i use a nucleo f446RE i maybe found the solution it seems to be when i write all the time the same frequency for exemple
here i say rpm = 500 during 1 min with this code the frequency is unstable around 125 - 180 Hz
but with this code the problem seems to be solved
i never saw that ^^
posted by olivier flayols 21 Dec 2016