Go Down

Topic: Arduino Software Interrupt (Read 226 times) previous topic - next topic

Selectronics

HI
Für eines meiner Projekte will ich, dass auf einem WS2812b LED Streifen immer nach einer Minute eine weitere LED angeht. Wenn die Vierte LED angeht sollen es bei der nächsten Minute alle ausgehen und das ganze dann wieder von vorne beginnen.

Das will ich mit einem Software Interrupt mit der Library TimerOne machen.

Der Interrupt wird jedoch schon nach ca. 9 Sekunden anstatt nach einer Minute ausgeführt.

Was habe ich falsch gemacht?

Hier mein Code:
Code: [Select]

#include <virtuabotixRTC.h> //Library used
#include <TimerOne.h>

int i = 0;

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
#define PIN        2 // Anschluss PIN
#define NUMPIXELS 60 //Anzahl LED's

#include <TimerOne.h>


Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  pixels.begin();


  Timer1.initialize(60000000);
  Timer1.attachInterrupt( minuten );
  Serial.begin(9600);


}

void loop() {
    pixels.show();
}

void minuten(){
      pixels.setPixelColor(i, pixels.Color(0, 0, 150));
      if (i < 4){
        i++;
      }
      else{
        i = 0;
        pixels.clear();
      }

  }

Rentner

#1
Jun 04, 2019, 04:21 pm Last Edit: Jun 04, 2019, 08:21 pm by Rentner
Hallo,

ziemlich ungewöhnlich Deine Idee das so machen zu wollen.

Geht es dir um die Ansteuerung der 4 LDE´s , da gibt es bessere Lösungen. Ich denke das würden 99% hier im Forum mit millis() machen.  Oder geht es dir um eine Übung zum Thema Interrupt. ?

Heinz

postmaster-ino

Hi

Beim Interrupt musst Du halt nehmen, was Du bekommen kannst - wenn Dieser 'alle 9 Sekunden' feuert, musst Du mit 'Vielfachen von 9' rechnen und Das auf Deine Minuten ummünzen.

Klappt aber nicht sonderlich toll, da kurz vor der Minute bei 57 Sekunden der letzte Interrupt zündet und dann erst, wenn schon 10% der nächsten Minute um sind.

Hier bieten sich ggf. kürzere Zeiten an.

Wenn Es Dir 'nur' darum geht, 'ungefähr alle Minute' eine neue LED anzuknipsen, Du also mit dem Fehler leben kannst, ziehst Du halt einfach 60 ab, wenn Du >=60 bist.
So addiert sich der Fehler nicht und Du bleibst 'ungefähr bei Deiner Minute'.

Sofern sonst aber Nichts für den Interrupt spricht: millis().
Alle 60000 'millis()-ticks' ist eine Minute um (sofern Du die Interrupts nicht großartig sperrst - die Ansteuerung der WS2812B stoppt die Interrupts für die Ansteuerung der LEDs (sehr zeitkritisch) und startet Diese danach wieder.
Bei meiner Uhr, Die allerdings sehr oft die 60 Pixel ansteuert (Animation des Sekunden-Pixel), dauert eine Sekunde 'nur 700 millis()-ticks' - Das rechnet meine Uhr aber mit und passt die Animation daran an.
Der Sekundentakt kommt dort von einer RTC - dafür ist ein Arduino zu ungenau.

MfG
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

Selectronics

Hi
Danke für die Antworten.

Ich kann es nicht mit millis() machen weil ich im Loop auch noch andere Sachen habe. Ich habe sie nicht drin gehabt im post da der Code dann ziemlich lange wäre.

Der Sekundentakt kommt dort von einer RTC
Wie geht das?

Tommy56

Die Aussage zeigt, dass Du millis() nichtmal Ansatzweise verstanden hast.
Die Arbeit mit millis() ist genau dafür da, "noch andere Sachen" im loop zu machen.

Da solltest Du nochmal zurück zu BlinkWithoutDelay und der Nachtwächtererklärung gehen und sie verstehen.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

postmaster-ino

anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

Rentner

Hi
Danke für die Antworten.

Ich kann es nicht mit millis() machen weil ich im Loop auch noch andere Sachen habe.
da verwechselst Du was, Deine Aussage trifft für delay() zu. Arbeite den link in #5 durch.

Heinz

agmue

Ich kann es nicht mit millis() machen weil ich im Loop auch noch andere Sachen habe.
Als Beweis, das es doch geht, habe ich Dir als "andere Sachen" einen Herzschlag eingebaut:

Code: [Select]
#include <Adafruit_NeoPixel.h>
#define PIN        2 // Anschluss PIN
#define NUMPIXELS 60 //Anzahl LED's
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
uint32_t jetzt, vorher, herzschlag;

void setup() {
  pixels.begin();
  pixels.show();
  pinMode (LED_BUILTIN, OUTPUT);
}

void loop() {
  jetzt = millis();
  if (jetzt - vorher >= 60000) {
    vorher = jetzt;
    minuten();
  }
  if (jetzt - herzschlag >= 100) {
    herzschlag = jetzt;
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
  }
}

void minuten() {
  static byte i = 0;
  pixels.setPixelColor(i, pixels.Color(0, 0, 150));
  if (i < 4) {
    i++;
  } else {
    i = 0;
    pixels.clear();
  }
  pixels.show();
}

Solltest Du sowas wie eine LED-Uhr bauen wollen, empfehle ich die Verwendung einer präziseren Real Time Clock RTC3231, wo man mittels I2C die Uhrzeit auslesen kann.
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

hajos118

Zu präziser Uhr:
Ich betreibe eine "Arbeitszeitanzeige" (Countdown bis Freitag 13:00) mit einem ESP8266, der per WLAN jede Stunde vom Zeitserver die aktuelle Uhrzeit holt und mit den abgelaufenen millis zur akteullen Zeit verwurschtelt.
Bei jeder Neusynchronisierung vergleiche ich die mitgerechnete Zeit mit der Zeit vom Timeserver. Dabei habe ich Abweichungen von +/- 1 sec ... also die Auflösung der Zeitabfrage selbst.
Für mich reicht die Genauigkeit aus.
P.S. ond OT: Ist Dir schon mal aufgefallen, dass die Uhr in der analogen Tagesschau (ARD) um ca. 7 sec vor der Zeit von ARD(HD, Sattelit) ist?
Orthographie und Interpunktion folgen keiner gültigen Norm. Wer Fehler findet darf sie behalten!

agmue

Zu präziser Uhr:
Als ich mit dem Projekt LED-Uhr anfing, hatte ich analoges Telefon, ein uraltes Modem der Telekom ... und kein ständiges WLAN. Da die LED-Uhr eher Schmuck als Quelle präziser Zeitanzeige ist, denn dafür nutze ich mit Funkuhren den Sender in Franfurt, reicht mir die Genauigkeit der RTC vollkommen. Ich habe noch nie nachjustiert.

Inzwischen verbreitet eine Fritz-Box auch WLAN, weshalb ESP8266 oder ESP32 eine Option für neue Projekte wären, auch mit App. Nur habe ich kein Smartphone ...

P.S. ond OT: Ist Dir schon mal aufgefallen, dass die Uhr in der analogen Tagesschau (ARD) um ca. 7 sec vor der Zeit von ARD(HD, Sattelit) ist?
Ja, die Signallaufzeiten in den geostationären Orbit und zurück sind merklich. Funkuhren zeigen eine andere Zeit als die Fernsehanstalten über verschiede Informationswege. Sylvester/Neujahr ist das immer wieder ein Spaß :)
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

Go Up