I DLed and installed the 0.5-Lib and wrote a short Testprogram to test a buzzer i have with 950 HZ and 30% duty.
Running on a Mega1280 and a Mega2560
The f is spot on with like 950.01Hz
But the Duty is off by a factor of 2.54ish and too low
I added a correction-factor to the duty, which is suuuper janky...
Is this a problem with the lib, I made a mistake or something else entirely?
My code:
/*
PWM-Libnrary from Runnerup @ https://forum.arduino.cc/index.php?topic=117425.0 / https://code.google.com/archive/p/arduino-pwm-frequency-library/downloads
The library
allows for a frequency range from 1Hz - 2MHz on 16 bit timers and 31Hz - 2 MHz on 8 bit timers. When
SetPinFrequency()/SetPinFrequencySafe() is called, a bool is returned which can be tested to verify the
frequency was actually changed.
This example runs on mega and uno.
*/
#include <PWM.h>
//use pin 11 on the Mega instead, otherwise there is a frequency cap at 31 Hz
int8_t i_pin_output = 11; // the pin that the Buzzer is attached to
int32_t i_f = 1000;
int i_ms = 0;
int i_duty = 0;
int i_duty2 = 0;
bool b_success = false;
bool b_verbose = true;
int i_parts_in_sequence = 0;
int i_serial_speed = 9600; // Be aware of the limit of int!
// The buzzer-sequence. Always 3 INT per step for: Frequency(Hz), duration(ms), Duty(%)
int i_Freq_Time_Duty[] = {
950, 100, 30,
950, 100, 0,
950, 100, 30,
950, 100, 0,
950, 100, 30,
950, 300, 0,
950, 100, 30,
950, 100, 0,
950, 100, 30,
950, 500, 0,
950, 100, 30,
950, 100, 0,
950, 100, 30,
950, 100, 0,
950, 100, 30,
950, 300, 0,
950, 100, 30,
950, 100, 0,
950, 100, 30,
950, 5000, 0
};
void setup()
{
Serial.begin(i_serial_speed); // Öffnet die serielle Schnittstelle bei 57.600 Bit/s:
//initialize all timers except for 0, to save time keeping functions
InitTimersSafe();
//sets the frequency for the specified pin
b_success = SetPinFrequencySafe(i_pin_output, i_f);
//if the pin frequency was set successfully, notify me
if(b_success) {
// Some messages to Serial maybe?
Serial.println("All ok @ setup");
}
i_parts_in_sequence = sizeof(i_Freq_Time_Duty)/sizeof(int)/3; // determine the # of sets in the array
// print_table(i_Freq_Time_Duty[],3);
Serial.println("----- Table-printout -------");
for (int i = 0; i <= i_parts_in_sequence-1; i++) {
Serial.print("Part "); Serial.print(i); Serial.print(": \t");
Serial.print(i_Freq_Time_Duty[i * 3 + 0]); Serial.print("Hz, \t");
Serial.print(i_Freq_Time_Duty[i * 3 + 1]); Serial.print("ms, \t");
Serial.print(i_Freq_Time_Duty[i * 3 + 2]); Serial.println("%");
}
Serial.println("----- End of Table-printout -------");
Serial.println("");
if(b_verbose==false){Serial.println("As verbose = false, no further output will be generated");}
}
void loop()
{
for (int i = 0; i <= i_parts_in_sequence-1; i++) {
if(i_Freq_Time_Duty[i * 3 + 0] != i_f) { // Only update frequncy of PWM if necessary
i_f = i_Freq_Time_Duty[i * 3 + 0];
b_success = SetPinFrequencySafe(i_pin_output, i_f);
if(b_verbose){
if(b_success){
Serial.print("Set f: Success \t");
} else {
Serial.print("Set f: FAIL \t");
}
}
} else {
if(b_verbose){Serial.print("Set f: n/a (same)\t");}
}
i_ms = i_Freq_Time_Duty[i * 3 + 1]; // Get how long the next part will be
i_duty = i_Freq_Time_Duty[i * 3 + 2]; // get the next duty-dycle of next part
//use this functions instead of analogWrite on 'initialized' pins
i_duty2 = int(i_duty * 2.56); // <----- I HAVE TO ADD A CORRECTION-FACTOR! WHY!?!?!??!
// Serial.println(i_duty);
pwmWrite(i_pin_output, i_duty2);
wait_part(i_ms, b_verbose); // Delaytime(ms), UART-Rapporting?
}
if(b_verbose){
Serial.println("------- REPEATING -------");
}
}
void wait_part(int i_ms, boolean uart)
{
int32_t i_timing = millis() + i_ms;
if(uart == true) {
Serial.print("f = ");
Serial.print(i_f);
Serial.print("\t ms = ");
Serial.print(i_ms);
Serial.print("\t duty% = ");
Serial.println(i_duty);
}
//Wait till the part is over
do {
delay(0);
} while (millis() < i_timing);
}