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

Eine eigene Frage? Dieser Thread ist über 8 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.