khoih-prog / RP2040_PWM

This library enables you to use Hardware-based PWM channels on RP2040-based boards, such as Nano_RP2040_Connect, RASPBERRY_PI_PICO, with either Arduino-mbed (mbed_nano or mbed_rp2040) or arduino-pico core to create and output PWM any GPIO pin. The most important feature is they're purely hardware-based PWM channels, supporting very high PWM frequencies. Therefore, their executions are not blocked by bad-behaving functions or tasks. This important feature is absolutely necessary for mission-critical tasks. These hardware-based PWMs, still work even if other software functions are blocking. Moreover, they are much more precise (certainly depending on clock frequency accuracy) than other software-based PWM using ISR, millis() or micros(). That's necessary if you need to control devices requiring high precision. New efficient setPWM_manual function to facilitate waveform creation using PWM
MIT License
67 stars 21 forks source link

Wrong frequency #1

Closed americodias closed 2 years ago

americodias commented 2 years ago

Describe the bug

I'm getting wrong results.

Steps to Reproduce

I'm running a modified version of your PWM_Multi example on a Arduino Nano RP2040 Connect.

Expected behavior

9 kHz output

Actual behavior

I get 11.81kHz according to the oscilloscope.

However if I change the code to 10kHz for instance, I get 10kHz.

Debug log

Starting PWM_Multi on Nano RP2040 Connect
RP2040_PWM v1.0.0
=============================================================
Index   Pin PWM_freq    DutyCycle   Actual Freq
=============================================================
0   4   9000.00     50[PWM] bestfit_PWM_Freq = 8999.28, PWM_Freq_diff = 0.72, Top_p_1 - 1 = 13889, vsDiv/16.0 = 1.00
[PWM] bestfit_PWM_Freq = 8999.93, PWM_Freq_diff = 0.07, Top_p_1 - 1 = 13888, vsDiv/16.0 = 1.00
[PWM] bestfit_PWM_Freq = 9000.01, PWM_Freq_diff = 0.01, Top_p_1 - 1 = 10581, vsDiv/16.0 = 1.31
[PWM] PWM_Freq = 9000.00, _actualFrequency = 9000.01, PWM_Freq_diff = 0.01
[PWM] TOP = 1DIV = 1
        9000.01
[PWM] 
TOP = 10581, DIV = 1, CPU_freq = 125000000
=============================================================

Screenshots

Oscilloscope screenshot here.

khoih-prog commented 2 years ago

Hi @americodias

Thanks for testing and using the library.

I'm able to duplicate the bug, which seems to happen when freq = 9000-9999Hz

I'll definitely spend time to investigate and fix this interesting bug. Hopefully, the culprit is something in the library, not in the chip.

In the mean time, I'd appreciate if you can make some more tests to see where else the similar issue happens.

Best,

khoih-prog commented 2 years ago

Hi,

Already found and fixed the bug, the culprit is the so-called best-fit algorithm. I don't use it now and just use my simple calculation. Everything will be OK as the following debug terminal shows.

Will publish a new version by tomorrow, with your contribution noted.

Best Regards,

===

Starting PWM_Multi on RaspberryPi Pico
RP2040_PWM v1.0.0
=============================================================
Index   Pin PWM_freq    DutyCycle   Actual Freq
=============================================================
0   2   200000.00       50[PWM] _PWM_config.top =624, _actualFrequency =200000.00
        200000.00
[PWM] TOP = 624, DIV = 1, CPU_freq = 125000000       =================> PWM = 200000 !!!
=============================================================

Starting PWM_Multi on RaspberryPi Pico
RP2040_PWM v1.0.0
=============================================================
Index   Pin PWM_freq    DutyCycle   Actual Freq
=============================================================
0   2   8999.00     50[PWM] _PWM_config.top =13889, _actualFrequency =8999.00
        8999.00
[PWM] TOP = 13889, DIV = 1, CPU_freq = 125000000       =================> PWM = 8999.2 !!!
=============================================================

Starting PWM_Multi on RaspberryPi Pico
RP2040_PWM v1.0.0
=============================================================
Index   Pin PWM_freq    DutyCycle   Actual Freq
=============================================================
0   2   9000.00     50[PWM] _PWM_config.top =13887, _actualFrequency =9000.00
        9000.00
[PWM] TOP = 13887, DIV = 1, CPU_freq = 125000000       =================> PWM = 9000.576 !!!
=============================================================

Starting PWM_Multi on RaspberryPi Pico
RP2040_PWM v1.0.0
=============================================================
Index   Pin PWM_freq    DutyCycle   Actual Freq
=============================================================
0   2   2000.00     50[PWM] _PWM_config.top =62499, _actualFrequency =2000.00
        2000.00
[PWM] TOP = 62499, DIV = 1, CPU_freq = 125000000       =================> PWM = 2000 !!!
=============================================================

Starting PWM_Multi on RaspberryPi Pico
RP2040_PWM v1.0.0
=============================================================
Index   Pin PWM_freq    DutyCycle   Actual Freq
=============================================================
0   2   1000.00     50[PWM] _PWM_config.top =12499, _actualFrequency =1000.00
        1000.00
[PWM] TOP = 12499, DIV = 10, CPU_freq = 125000000       =================> PWM = 1000 !!!
=============================================================

Starting PWM_Multi on RaspberryPi Pico
RP2040_PWM v1.0.0
=============================================================
Index   Pin PWM_freq    DutyCycle   Actual Freq
=============================================================
0   2   1000.00     50[PWM] _PWM_config.top =12499, _actualFrequency =1000.00
        1000.00
[PWM] TOP = 12499, DIV = 10, CPU_freq = 125000000       =================> PWM = 1000 !!!
=============================================================

Starting PWM_Multi on RaspberryPi Pico
RP2040_PWM v1.0.0
=============================================================
Index   Pin PWM_freq    DutyCycle   Actual Freq
=============================================================
0   2   500.00      50[PWM] _PWM_config.top =24999, _actualFrequency =500.00
        500.00
[PWM] TOP = 24999, DIV = 10, CPU_freq = 125000000       =================> PWM = 500 !!!
=============================================================

Starting PWM_Multi on RaspberryPi Pico
RP2040_PWM v1.0.0
=============================================================
Index   Pin PWM_freq    DutyCycle   Actual Freq
=============================================================
0   2   50.00       50[PWM] _PWM_config.top =24999, _actualFrequency =50.00
        50.00
[PWM] TOP = 24999, DIV = 100, CPU_freq = 125000000       =================> PWM = 50 !!!
=============================================================

Starting PWM_Multi on RaspberryPi Pico
RP2040_PWM v1.0.0
=============================================================
Index   Pin PWM_freq    DutyCycle   Actual Freq
=============================================================
0   2   10.00       50[PWM] _PWM_config.top =62499, _actualFrequency =10.00
        10.00
[PWM] TOP = 62499, DIV = 200, CPU_freq = 125000000       =================> PWM = 10 !!!
=============================================================

Starting PWM_Multi on RaspberryPi Pico
RP2040_PWM v1.0.0
=============================================================
Index   Pin PWM_freq    DutyCycle   Actual Freq
=============================================================
0   2   7.50        50[PWM] _PWM_config.top =65358, _actualFrequency =7.00
        7.00
[PWM] TOP = 65358, DIV = 255, CPU_freq = 125000000       =================> PWM = 7.5 !!!
=============================================================
americodias commented 2 years ago

Hi @khoih-prog,

That was fast! Thank you for creating this library and for the quick fix!

I will use this library for an ongoing project and will let you know if I find any other issues.

Kind regards, Américo

khoih-prog commented 2 years ago

Hi @americodias

The new RP2040_PW releases v1.0.1 has just been published

Your contribution has been noted in Contributions and Thanks

Thanks to the contributions of users like you, the library will have good chance to be better and better, with less and less bugs.


Releases v1.0.1

  1. Fix bug generating wrong frequency. See Wrong frequency #1