theAndreas / TimerTwo

Arduino Timer2 library
9 stars 3 forks source link

Is this lbrary exact the same as the TimerOne library, but for TimerTwo? #3

Open Rimbaldo opened 1 year ago

Rimbaldo commented 1 year ago

Hi! I'm driving a BLDC motor with 3 pwm pins. So I have to use Timer1 and Timer2 to adjust this pins at the same time. Is your library exactly the same as the TimerOne, library, adapted to the Timer2? I mean, Can I use the same functions for both? I noticed in your's there's a little difference on some names and commands... If I use both at the same time, with the right values, could I have the same output for Timer1 and Timer2 pins at the same frequencies, duties, at the same time?

theAndreas commented 1 year ago

Hi, yes my library is very simular to the Timer1. But Timer1 is a 16 Bit timer and Timer2 only 8 Bit. So the resolution is lower. But it should work.

Rimbaldo commented 1 year ago

Hi, yes my library is very simular to the Timer1. But Timer1 is a 16 Bit timer and Timer2 only 8 Bit. So the resolution is lower. But it should work.

Ok.. I´m testing timerone and your´s timertwo together now.. In the timeone library there´s this function that enables output pwm on a timer 1 pin, for instance, a led on pin 9:

Timer1.pwm(9, dutyCycle, period);

or with just the first two arguments, without period:

Timer1.pwm(9, dutyCycle);

It actuallys outputs a pwm signal on a led attached to pin 9, for instance.

But with yours, if I write the same code, but for timer2, like this:

Timer2.setPwmDuty(TimerTwo::PWM_PIN_11, dutycycle);

or

Timer2.enablePwm(TimerTwo::PWM_PIN_11, dutycycle);`

I get nothing on the led, and with a scope I see no pwm on the pin 11.. why is that? What can I do so it outputs a pwm signal that I can use just like the timer one library? Can you help me out on this? Thanks!

Here´s the complete code for timerone (pin9) that I want to use with timer two on pin 11

include // https://github.com/PaulStoffregen/TimerOne

// This example creates a PWM signal with a variable duty cycle. // This scheme enforces a minimum pulse width at low duty cycles // by varying the frequency and increasing the off times between // pulses. // // this code was adapted from the TimerOne library example // for a 25kHz fan // https://github.com/PaulStoffregen/TimerOne/blob/master/examples/FanSpeed/FanSpeed.ino // // Minimum pulse width could be important for good torque from motors // With a tau=L/R, a 5tau pulse width for a R=1.65ohm, L=3.2mH stepper // would be tau=0.0032/1.65=1.9ms and 5L/R = 5*.0032/1.65=9.7ms //

constexpr int fanPin = 9; // Uno Timer1 OC1A pin

// Set the high frequency period and the minimum pulse // These settings work for the Wokwi chips-scope from // https://github.com/Dlloydev/Wokwi-Chip-Scope // scope demo config: // https://wokwi.com/projects/359331973918199809 // 2000us & 400us looks good with 200us sampling rate >22Hz // 80 &4 at 1us sampling rate >1Hz // 20000us and 2000us at 1ms sample rate for 50Hz>3Hz // 20 & 1 and a real scope for 50K operation constexpr unsigned long basePeriod = 2000; constexpr unsigned long minUs = 400; // calculate the changeover from adjusting pulse width at const freq // to adjusting the frequency at const pulse width: constexpr float minDuty = 100.0 * minUs / basePeriod;

float dutyCycle = 0; int lastA0 = 0; void setup(void) { Timer1.initialize(basePeriod); // us Serial.begin(9600); }

void loop(void) { updateSettings(); delay(0); }

void updateSettings(void) { const int interval = 250; static unsigned long last = -interval; if (millis() - last < interval ) return; last += interval; int val = analogRead(A0); if (val != lastA0) { lastA0 = val; dutyCycle = 100 (1 - cos(PI / 2 val / 1023)); // 0-100% with high res at low end unsigned long myPeriod = 0; Serial.print("PWM Fan, Duty Cycle = "); Serial.println(dutyCycle); if (dutyCycle > minDuty || dutyCycle == 0.0) { myPeriod = basePeriod; Timer1.setPeriod(myPeriod); Timer1.pwm(fanPin, (dutyCycle 1023UL / 100)); Serial.print((int)(dutyCycle myPeriod / 100)); Serial.print("us pulse at Hz:"); Serial.println(1000000UL / myPeriod);

} else { // Set by minimum width:
  myPeriod = minUs * 100UL / dutyCycle;
  if(myPeriod > 1885292UL){ 
    myPeriod  = 1885292UL;
  }
  Timer1.setPeriod(myPeriod);
  Timer1.pwm(fanPin, (uint32_t)(dutyCycle * 1023UL / 100));
  Serial.print(minUs);
  Serial.print("us pulse / ");
  Serial.print(myPeriod);
  Serial.print("us period / Hz:");
  Serial.println(1.0e6 / myPeriod);
  Serial.print("Timer1.OCR1A:"); Serial.print(OCR1A);
  Serial.print(" / ICR1:");Serial.print(ICR1);
  Serial.print(" TCCR1B:0b");Serial.println(TCCR1B,BIN);

}

}

}

theAndreas commented 1 year ago

Timer2 must be explicitly started with the API start(). Could you please try this? Seems to me there is a difference between Timer1 and Timer2. Timer1 is automatically started by calling initialize(). This is not really clear from the documentation. After analyzing the Timer1 example: start() is never called. In my example, however, it is.

Rimbaldo commented 1 year ago

Hi! ok, I did like this, to make that code for both timers, and still the same result... the led on pin 11 never lits...

void setup(void) { Timer1.initialize(basePeriod); // us

Timer2.init(basePeriod); Timer2.start(); Timer2.enablePwm(TimerTwo::PWM_PIN_11, 127);

Serial.begin(9600); }

... inside the code:

Timer1.setPeriod(myPeriod); Timer1.pwm(ledPin9, (dutyCycle 1023UL / 100)); Timer2.setPeriod(myPeriod); Timer2.setPwmDuty(TimerTwo::PWM_PIN_11, (dutyCycle 1023UL / 100));

Anything else I could try???

theAndreas commented 1 year ago

Ok this is strange. I will try it in the evening on the Arduino Board. As far as I have more information. I will let you know.

Rimbaldo @.***> schrieb am So., 25. Juni 2023, 14:13:

Hi! ok, I did like this, to make that code for both timers, and still the same result... the led on pin 11 never lits...

void setup(void) { Timer1.initialize(basePeriod); // us

Timer2.init(basePeriod); Timer2.start(); Timer2.enablePwm(TimerTwo::PWM_PIN_11, 127);

Serial.begin(9600); }

... inside the code:

Timer1.setPeriod(myPeriod); Timer1.pwm(ledPin9, (dutyCycle 1023UL / 100)); Timer2.setPeriod(myPeriod); Timer2.setPwmDuty(TimerTwo::PWM_PIN_11, (dutyCycle 1023UL / 100));

Anything else I could try???

— Reply to this email directly, view it on GitHub https://github.com/theAndreas/TimerTwo/issues/3#issuecomment-1606061565, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABG65UZSBS2DM5VBR5DHSOLXNATOXANCNFSM6AAAAAAYE6PP2M . You are receiving this because you commented.Message ID: @.***>

theAndreas commented 1 year ago

Ok Pin 11 is wrong. Pin 3 is correct. Fixed also some other things. This code with the updated Timer.h and Timer.cpp is now working on my board:

#include <Arduino.h>
#include <TimerTwo.h>

void setup() {
  Timer2.init();
  Timer2.start();
  Timer2.enablePwm(TimerTwo::PWM_PIN_3, 10);
}

void loop() {
}