Go Down

Topic: Nano Timer2 und delay (Read 1 time) previous topic - next topic

combie

#15
Mar 03, 2018, 12:54 pm Last Edit: Mar 03, 2018, 05:29 pm by combie
Quote
In der ISR wird "count" ca. alle 22ms hochgezählt. In der switch wird erst bei "count=146" der Motor angesprochen, also 146 mal 22ms. Das sind dann alle 3,2 Sekunden. Du schreibst aber 2000 mal innerhalb von 22ms. Kannst Du mir mal weiterhelfen? Der Motor wirst doch erst im "case" 146 angesprochen, oder?

Wenn es eine längere Erklärung erfordert, dann will ich Dich nicht weiter bemühen.
In loop() wird dein switch ausgeführt!

Loop() wird geschätzte einhunderttausend mal pro Sekunde durchlaufen, eher häufiger.
(auf einem typischen 16MHz Arduino)

Für die Zeit von 22ms ist count == 146

22ms sind ca 2200 Loopdurchläufe, eher mehr.

Damit wird dein  servo.write(pos) ca. 2200 mal aufgerufen, bevor sich count wieder verändern kann.

War die Erklärung kurz/lang genug?
Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

michael_x

Zwar:
Wenn servo.write() keine Zeit braucht, tut es auch nicht weh, den Wert für die nächste Servo - PPM Puls-Ausgabe wieder mit dem bereits bekannten Wert zu überschreiben.

Wenn servo.write() irgendwelche Auswirkungen auf den laufenden Timer hat und das PPM-Verhalten durcheinanderbringt, stimmt die Vermutung mit den 10µs / loop nicht ;)

Was tatsächlich passiert, bin ich jetzt leider zu faul, nachzusehen.

Die Mischung aus direktem Timer2-Register-Gefummel einerseits und servo.h andererseits ist übrigens generell schräg, auch wenn man es nicht so schlimm macht, wie combie zu Recht anmeckert. (Um es mal bewusst krass auszudrücken)

Wer servo.h verwendet, braucht dazu keine ISR und handgestrickte Timer-Ansteuerung.
Quote
Mit delay(5000) funktioniert das Programm nicht mehr
Wenn das der Grund für diesen Thread ist, sollte man das lieber richtig ansehen. Die Servo library und delay() vertragen sich!

combie

#17
Mar 03, 2018, 05:30 pm Last Edit: Mar 04, 2018, 03:04 am by combie
Da die 2000 nur geschätzt waren, habe ich das (heimlich) überprüft, wie viel Durchläufe mein UNO in den 22ms schafft.
Mit dem Servo sind das 310 Durchläufe in 22ms
Ohne das Servo Gedöns sind es mehr als 6000 pro 22ms
Die geschätzten 2000 sind also nicht ganz korrekt.

Welche Auswirkungen das auf die Servofunktionalität hat, habe ich nicht getestet.

Testbeispiel:
Code: [Select]

#include <util/atomic.h>

#include <Servo.h>
volatile int count=0, pos=0;
uint16_t loopCount = 0;

Servo servo; 

ISR(TIMER2_OVF_vect)
{
    count++; // ca. alle 22ms
}
 
void setup()
{
  Serial.begin(9600);
  Serial.println("Start");
  noInterrupts();   
  TCCR2A = 0;
  TCCR2B = 1 << CS10 | 1 << CS11 |  1 << CS12;  // 1/1024
  TIMSK2 = (1 << TOIE2);   
  interrupts();
  servo.attach(11);
  servo.write(0);
  delay(4000);   
}


void loop()
{
    int bessererCount = 0;
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
    {
      bessererCount = count;
      if(292 >= count) count = 0;
    }
     
    switch (bessererCount)
    {
      case 146: loopCount++;  // 146 mal 22ms sind 3,2 Sekunden
                pos=150;
                servo.write(pos);
                break;
               
      case 292: Serial.println(loopCount);
                loopCount=0;
                pos=50;
                servo.write(pos);
                break;
    }
}

Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

Go Up