Timer1 und Timer3 Libary auf Arduino Mega

Hallo,

kann ich auf einen Arduino Mega die Timer 1 und Timer3 Libary zusammen benutzen und so bei 6 Pins die PWM Frequenz einstellen?

Hat das jemand schon mal versucht?

Quelle:http://www.pjrc.com/teensy/td_libs_TimerOne.html

Danke für die Hilfe.

Ja.

Ich glaube aber nicht, dass du wirklich die PWM Frequenz meinst. Ich sehe nämlich nicht, dass man die in der Lib anpassen kann. Die ändert nur den Tastgrad (Duty Cycle), genauso wie analogWrite(), aber mit 10 Bit statt 8 Bit Auflösung. Die Frequenz selbst kann man einfach über den Prescaler ändern: http://playground.arduino.cc/Main/TimerPWMCheatsheet Das ist aber wohl nicht was du willst.

Hallo,

dachte der Befehl:

Timer1.initialize(microseconds); Begin using the timer. This function must be called first. "microseconds" is the period of time the timer takes.

bewirkt das Einstellen der Frequenz.

Viele Grüße

Mhhh, stimmt. Sieht so aus. Hatte ich übersehen. :slight_smile:

Wenn du aber nur die Frequenz in groben Schritten ändern willst und dir 8 Bit Auflösung reichen, würde ich aber einfach den Prescaler ändern. Das kostet keinerlei Speicher! Und meistens braucht man das nur um die PWM Frequenz aus dem hörbaren Bereich zu bringen.
Mit der Library hast du allerdings mehr Auswahl was die Zeit/Frequenz betrifft und eine höhere Auflösung beim Tastgrad.

Was etwas seltsam ist, dass da steht das in der TimeOne Doku steht dass Pin 13 von Timer1 gesteuert ist. Der gehört zu Timer0:
http://greentechhobby.com/images/Arduino/ArduinoMega.pdf

Hmm gute Frage.

ich bräuchte eine PWM Frequenz von 100Hz an 5 Pins. Wenn ich diese ändere, heißt das ja auch das Zeitfunktionen millis() nicht mehr funktionieren, oder?

Gruß

millis() und delay() ändern sich nur wenn du was an Timer0 machst (Pins 4 und 13 auf dem Mega). Die gehen dann noch, aber die Zeit passt nicht mehr. Du hast genug andere PWM Pins dass das nicht nötig ist.

Einfach über den Prescaler sind 122Hz möglich. Wenn du genau 100Hz brauchst, sind diese Libs eine gute Option. :)

Benötige genau 100 HZ auf Grund von Netzsyncronistation und dimmen von 230V Leuchten.

Kann ich beide Timer Libarys parallel verwenden?

Viele Grüße

Ja, wieso sollte das nicht gehen? Sind schließlich unterschiedliche Ressourcen.

Benötige genau 100 HZ auf Grund von Netzsyncronistation und dimmen von 230V Leuchten.

???

Willst du nicht lieber auf den Nulldurchgang synchronisieren (was effektiv was wechselndes, meist zwischen 99,9 und 100,1 Hz ist) ?

Hallo Michael, hallo Serenifly,

ich habe auch ein kleines Timer bzw. Counter Problem, aber in meinem Code liegt evtl. eine gute Lösung für Michaels Problem (stammt nicht von mir, ist aus http://www.instructables.com/id/Arduino-Timer-Interrupts/all/?lang=de

Das mit dem Timer2 klappt echt gut - allerdings ist bei mir bei ca. 45kHz Schluss mit Lustig. Mehr gibt das MEGA Board wohl nicht her; zumindest am Pin. Dazu muss man noch sagen, dass ab ca. 30kHz keine weiteren Operationen mehr vernünftig laufen, da die Interrupts für Timer2 wahrscheinlich alles andere niederschlagen.

Aber den Code für Timer2 kann man locker für 100Hz nutzen (einfach die Formel aus dem Link berechnen) und der Timer läuft wunderbar stabil (habe ich auf dem Oszi gemessen).

Nun zu meinem Problem:
In meinem Code findet Ihr auch Timer/Counter5 (unser alter Bekannter aus meinem letzten Post (nochmal vielen Dank an Serenifly). Ich möchte diesen Counter als ebenfalls im Hintergrund laufenden Vorwahlzähler nutzen (also auch im CTC-Mode) und habe den Code analog zum Beispiel aus Timer2 angelegt. Aber irgendwie wird die ISR nie aktiv. Der Zäher funktioniert im Hintergrund, was ich ja in der Loop getestet habe. Aber in der Loop läuft mir das nicht schnell genug, bzw. hat nicht die Prio, die es in der ISR hätte. Was mach ich falsch? Habe mir die Finger wund gesucht, um herauszufinden, ob Counter5 evtl. gar keinen CTC-Mode unterstütz. In der Literatur macht man aber keinen Unterschied unter den 16-Bit Countern/Timern.

Hier mein Code:

// Variables will change:
volatile int zaehler = 0;   // Zaehlerstand kurze Impulse
volatile int interval = 500;    // Vorwahl fuer Sensoraktivierung
volatile boolean cycle = false;  //Zyklusüberwachung für Interrupt CHANGE Flanke                        
                                // Ja fuer 0 ; Nein fuer 1
int maxzaehler = 0;         // Puffer fuer max Zaehlerstand
volatile boolean drucken = true;  // damit immer nur einmal pro Messzyklus der Zählerstand gedruckt wird
volatile int expect = 114;
boolean toggle2 = 0;
boolean toggle5 = 0;

void setup() {

  // initialisiere Pin47 Timer5 als digitaler Input
  pinMode(47, INPUT);
  pinMode(9, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(10, OUTPUT);  
  pinMode(11, INPUT); //initielisiere PIN 12 fuer Spur B (vor / rück Erkennung)
  pinMode(44, OUTPUT);
 
 
  cli(); //alle Interrupts anhalten
  
  //set timer2 interrupt at 8kHz
  TCCR2A = 0;// set entire TCCR2A register to 0
  TCCR2B = 0;// same for TCCR2B
  TCNT2  = 0;//initialize counter value to 0
  // set compare match register for 8khz increments
  OCR2A = 249;// = (16*10^6) / (8000*8) - 1 (must be <256)
  // turn on CTC mode
  TCCR2A |= (1 << WGM21);
  // Set CS21 bit for 8 prescaler
  TCCR2B |= (1 << CS21);   
  // enable timer compare interrupt
  TIMSK2 |= (1 << OCIE2A);
  
  TCCR5A = 0;  // TCCR5A Register auf 0 setzen
  TCCR5B = 0;  // TCCR5B Register auf 0 setzen
  TCNT5 = 0;   // initielisiere Zaehler 5 mit Startwert 0
  OCR5A = interval; // Vorwahlwert für CTC-Mode wird auf var interval gesetzt
  TCCR5A != (1<< WGM51); // CTC-Mode aktivieren
  TCCR5B |= _BV(CS52) | _BV(CS51) | _BV(CS50); // TimerCounterControl auf triggern von steigenden Flanken setzten
  TIMSK5 != (1 << OCIE5A); // timer compare interrupt aktivieren
 
  sei(); // alle Interrupts wieder aktivieren
  
  // initialize serial communication:
  Serial.begin(115200);
  digitalWrite(10, HIGH);
  digitalWrite(8, HIGH);
} // end setup



ISR(TIMER5_COMPA_vect){ 
  if (toggle5){
    digitalWrite(44,HIGH);
    toggle5 = 0;
  }
  else{
    digitalWrite(44,LOW);
    toggle5 = 1;
  }
}



ISR(TIMER2_COMPA_vect){//timer1 interrupt 8kHz toggles pin 9
//generates pulse wave of frequency 8kHz/2 = 4kHz (takes two cycles for full wave- toggle high then toggle low)
  if (toggle2){
    digitalWrite(9,HIGH);
    toggle2 = 0;
  }
  else{
    digitalWrite(9,LOW);
    toggle2 = 1;
  }
}

void loop() { 
 if (TCNT5 >500) {
   Serial.print("hallo");
   Serial.println(TCNT5);
   TCNT5 = 0;
   zaehler ++; 
   Serial.println(zaehler);
   
   if (toggle5){
    digitalWrite(12,HIGH);
    toggle5 = 0;
  }
  else{
    digitalWrite(12,LOW);
    toggle5 = 1;
  }
 } 
}
CCR5A != (1<< WGM51); // CTC-Mode aktivieren
  TCCR5B |= _BV(CS52) | _BV(CS51) | _BV(CS50); // TimerCounterControl auf triggern von steigenden Flanken setzten
  TIMSK5 != (1 << OCIE5A); // timer compare interrupt aktivieren

Was soll das bitteschön werden?
Es muss |= und nicht != heißen.

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Die_Timer_und_Zähler_des_AVR

Timer5 funktioniert genauso wie Timer1. Timer2 ist etwas anders. So grundlegende Sachen sind da sehr ähnlich, aber Timer2 hat z.B. andere Prescaler Optionen.

Ist aus dem Datenblatt ersichtlich, bei "Register Descriptions"

Was soll das bitteschön werden? Es muss |= und nicht != heißen.

Hallo sschultewolter! Vielen Dank, Irgendwann wird man betriebsblind. Ich hätte wahrscheinlich noch Wochen weitergesucht, ohne diesen sch... Typo zu sehen! Brauch mal einen größeren Bildschirm. Läuft jetzt super!