Problem mit TimerOne-Bibliothek auf Leonardo

OP #5212704
Lesenswert?

Hallo,

Für mein Projekt benötige ich eine PWM, deren Periodendauer ich per Poti 
steuern möchte.
Dafür habe ich mir die Leonardokompatible TimerOne-Bibliothek von hier 
(https://www.pjrc.com/teensy/td_libs_TimerOne.html) geladen.

Nachdem ich ein Problem feststellte, habe ich nun erstmal diesen Code 
zum Testen (das Auskommentierte ist die ursprüngliche Funktionalität):
1
#include <TimerOne.h>
2

3
int LedPin = 11;
4

5
unsigned int potiPin = 1;
6

7
unsigned long delayValue = 0;
8
unsigned long old = 0;
9
unsigned int readoutPoti = 0;
10

11
void setup() {
12
  Timer1.initialize(10000);
13
  Timer1.pwm(LedPin, 500);
14
  
15
  Serial.begin(9600);
16
  
17
  //The pin with the LED
18
  pinMode(LedPin, OUTPUT);
19
}
20

21
void loop() {
22
  readoutPoti = analogRead(potiPin);
23
  delayValue = map(readoutPoti,0,1023,200000,1000000);
24
//  Timer1.setPeriod(delayValue);
25

26
  Serial.println(readoutPoti);
27
  Serial.println(delayValue);
28
  delay(10);  
29
  
30
  for (unsigned long i=1;i<50;i++){
31
    Timer1.setPeriod(i*10000);
32
    delay(500);
33
  }
34
}

Die LED-Blinkdauer wird damit auch länger, aber zwischendurch gibt es 
wie "Sprünge" die ich mir nicht erklären kann, als würde sich der Timer 
zwischendurch noch mal mit einem anderen DutyCycle initialisieren. Dann 
blinkt die LED plötzlich mit etwas höherer Frequenz und dann reduziert 
sich die Blinkdauer wieder.
Ich hab mal ein kurzes Video gemacht, da sieht man das aber nur 
bedingt... https://youtu.be/Di3e10YUvWc

Vom Code sollte es ja passen und auch die Variable, die "setPeriod" 
übergeben wird hat eine ausreichende Datenbreite.
Funktioniert evtl. die Bibliothek nicht korrekt?

Danke im Voraus.
Hannes
OP #5213587
Lesenswert?

Ok, ich hab mir mal die Headerdatei angeschaut und ich vermute es liegt 
daran, dass der Timer umkonfiguriert wird, wenn die Periodendauer einen 
bestimmten Bereich überschreitet.
1
if (cycles < TIMER1_RESOLUTION * 2UL) {
2
    clockSelectBits = _BV(CS11);
3
    pwmPeriod = cycles / 2;
4
  } else
5
  if (cycles < TIMER1_RESOLUTION * 4UL) {
6
    clockSelectBits = _BV(CS11) | _BV(CS10);
7
    pwmPeriod = cycles / 4;
8
  } else
9
  if (cycles < TIMER1_RESOLUTION * 8UL) {
10
    clockSelectBits = _BV(CS12);
11
    pwmPeriod = cycles / 8;
12
  } else
13
  if (cycles < TIMER1_RESOLUTION * 16UL) {
14
    clockSelectBits = _BV(CS12) | _BV(CS10);
15
    pwmPeriod = cycles / 16;
16
  } else

Dass das aber so sichtbar zu Tage tritt hätte ich nicht gedacht.
Gast #5213760
Lesenswert?

Dann darfst du dich nicht wundern wenn du Frequenzbereiche fährst die 
eine Änderung des Prescalers erfordern. Alternative wäre es selbst zu 
schreiben mit festen Prescaler. Schränkt dann den Frequenzbereich ein.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren