Forum: Mikrocontroller und Digitale Elektronik Problem mit TimerOne-Bibliothek auf Leonardo


von Johannes (menschenskind)


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

von Johannes (menschenskind)


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.

von Checker (Gast)


Lesenswert?

Eigentlich willst die Pulsweite steuern, nicht die Periodendauer.

von Johannes (menschenskind)


Lesenswert?

Nein, das Tastverhältnis bleibt konstant. Ich möchte die Frequenz 
variieren.

von Checker (Gast)


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.

von Checker (Gast)


Lesenswert?

a) ohne Vorwiderstand höchst fahrlässig
b) wird das festgelegte Duty Cycle mit dem Top Wert kollidieren, weil es 
bestimmt nicht dynamisch angepasst wird

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.