About DCValue in setPWM_manual #2
-
Is your feature request related to a problem? Please describe.I read documentation and "setPWM_manual" is not well described particularily "DCValue". It's named like "DutyCycleValue" but it's not. After many try I discovered that is the number of microsecond for the high level. It's PERFECT ! but not well described Describe the solution you'd likein "setPWM_manual", DCValue should be better described. Describe alternatives you've consideredA clear and concise description of any alternative solutions or features you've considered. Additional contextsetPWM_manual is THE function I am searched for. I have an idea for the case where AVR_PWM is used for trigerring something : It's shloud be intersting to set how many pulse we want before dutycycle become 0 (stop emitting on PWM pin). Great job. Thanks a lot! |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments 2 replies
-
It' really a value related to Duty-Cycle, not uS. Check the example PWM_Waveform about how to use it correctly. The function was created for Waveform creation by using PWM. I always wrongly expect the programmers using PWM should have good knowledge about hardware and research, and will come to the correct usage / conclusion via examples, experiments, library source code. The documents are normally written by non-tech Tech-Writers, and always imperfect / incorrect and not to be relied upon 100%. I also don't have time to write document for everything. Mostly if necessary, you have to read the open-source code and play with examples to master the usage. I'd certainly appreciate if you can master the function, then write the better document and post the PR to benefit other users. If interested, you can spend some time to read the story of this function (why-created, when-to-use, use-cases, etc) in this thread Duty cycle as integer rather than float #6 I also suggest unless it's a proven bug of the library, post in the Discussions QA next time |
Beta Was this translation helpful? Give feedback.
-
HI @laflaf3d It's good that you've done some tests and now I can explain more what's wrong in your assumption and code
Your use of freq = 60.0f is wrong, and some other freq is used by using the wrong overflowed data => random 480.0192 Hz as you saw. You can calculate yourself and see why and how 480.0192Hz is used as an exercise to master the PWM If you'd like to use low-frequency PWM, use my AVR_Slow_PWM library
is the max DCValue you have to use for 100% DC. Therefore, to get 50% DC, you have to use 50% * 8000 = 4000, not merely 50 as in your code Just change your code as follows, and retest #define _PWM_LOGLEVEL_ 4
//#define UPDATE_INTERVAL 10000L
#define UPDATE_INTERVAL 1000L
#include "AVR_PWM.h"
// Pins tested OK on Nano / UNO
//#define pinToUse 9 // Timer1A on UNO, Nano, etc
#define pinToUse 10 // Timer1B on UNO, Nano, etc
AVR_PWM* PWM_Instance;
//float frequency = 60.0f;
float frequency = 1000.0f;
uint16_t dutycycle = 0;
char dashLine[] = "============================================================================================";
void printPWMInfo(AVR_PWM* PWM_Instance)
{
Serial.println(dashLine);
Serial.print("Actual data: pin = ");
Serial.print(PWM_Instance->getPin());
Serial.print(", PWM DutyCycle = ");
Serial.print(PWM_Instance->getActualDutyCycle());
Serial.print(", PWMPeriod = ");
Serial.print(PWM_Instance->getPWMPeriod());
Serial.print(", PWM Freq (Hz) = ");
Serial.println(PWM_Instance->getActualFreq(), 4);
Serial.println(dashLine);
}
void setup()
{
Serial.begin(115200);
while (!Serial && millis() < 5000);
delay(100);
Serial.print(F("\nStarting PWM_Waveform on "));
Serial.println(BOARD_NAME);
Serial.println(AVR_PWM_VERSION);
// Create a dummy instance
PWM_Instance = new AVR_PWM(pinToUse, frequency, 0);
if (PWM_Instance)
{
// setPWM_manual(uint8_t pin, uint16_t level)
PWM_Instance->setPWM(pinToUse, frequency, 0);
printPWMInfo(PWM_Instance);
}
}
void loop()
{
static unsigned long update_timeout = UPDATE_INTERVAL;
static bool resultb;
// Update DC every UPDATE_INTERVAL (100) milliseconds
if (millis() > update_timeout)
{
// PWMPeriod = 8000.00 => 50% DC = 4000
dutycycle = 4000;
//resultb = PWM_Instance->setPWM_manual(pinToUse, 50);
resultb = PWM_Instance->setPWM_manual(pinToUse, dutycycle);
//Serial.print(((resultb==true)?"TRUE":"FALSE"));
printPWMInfo(PWM_Instance);
update_timeout = millis() + UPDATE_INTERVAL;
}
} You'll have the terminal Starting PWM_Waveform on Arduino AVR UNO, Nano, etc.
AVR_PWM v1.0.1
[PWM] AVR_PWM: _dutycycle = 0
[PWM] setPWM: _dutycycle = 0
[PWM] setPWM_Int: _dutycycle = 0
[PWM] setPWM_Int:using TIMER1B
[PWM] setPeriod_Timer1: F_CPU = 16000000 , cycles = 8000
[PWM] setPeriod_Timer1: clockSelectBits = 1 , pwmPeriod = 8000
============================================================================================
Actual data: pin = 10, PWM DutyCycle = 0.00, PWMPeriod = 8000.00, PWM Freq (Hz) = 1000.0000
============================================================================================
[PWM] PWM enabled, DCValue = 4000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
============================================================================================
Actual data: pin = 10, PWM DutyCycle = 0.00, PWMPeriod = 8000.00, PWM Freq (Hz) = 1000.0000
============================================================================================
[PWM] PWM enabled, DCValue = 4000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
============================================================================================
Actual data: pin = 10, PWM DutyCycle = 0.00, PWMPeriod = 8000.00, PWM Freq (Hz) = 1000.0000
============================================================================================
[PWM] PWM enabled, DCValue = 4000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00 My suggestion is that whenever you got a big issue, go back to some working example, for example PWM_Waveform in your case. Test and retest, read and reread to understand the code, with the highest debug level. Then adapt to your buggy code. For example, for new code, from debug terminal DCValue = 4000 , pwmPeriod = 8000 compared to DCValue = 50 , pwmPeriod = 8000 Certainly, there are still some more improvement to be done, such as post an error when you use too low out-of-range frequency, etc. |
Beta Was this translation helpful? Give feedback.
-
Hereafter is better code, to auto-adjust
|
Beta Was this translation helpful? Give feedback.
-
Hi @laflaf3d The new AVR_PWM releases v1.1.0 has just been published. Your contribution is noted in Contributions and Thanks Best Regards, PS: Please don't hesitate to open new Discussion / Issue. As you see, we have new better release thanks to your note. Releases v1.1.0
|
Beta Was this translation helpful? Give feedback.
-
Also check if the rewritten instruction is better 4. Set or change PWM frequency and dutyCycle manually and efficiently in waveform creation |
Beta Was this translation helpful? Give feedback.
-
Thank you very much for the time you took to explain this to me. Thank you also for your improvements, their are greats. Rating me as a contributor is too great an honor ! As I have to deal with low frequency I will try your AVR_Slow_PWM. 🙏 |
Beta Was this translation helpful? Give feedback.
HI @laflaf3d
It's good that you've done some tests and now I can explain more what's wrong in your assumption and code
Your use of freq = 60.0f is wrong, and some other freq is used by using the wrong overflowed data => random 480.0192 Hz as you saw. You can calculate yourself and see why and how 480.0192Hz is used as an exercise to master the PWM
If you'd like to use low-frequency PWM, use my AVR_Slow_PWM library