Hallo,
ich habe ein Problem mit mein Kleinen Projekt.
Dabei soll jede Sekunde der Aktuelle Strom von einem INA219 abgerufen
werden, und per Serielle Schnittstelle ausgegeben werden.
Jedoch sobald ich die Lese Routine über die ISR ausführen möchte hängt
sich der Controller auf.
Lasse ich die Routine im Loop laufen funktioniert sie Fehlerfrei. Auch
wenn ich zusätzlich in der ISR was anderes mache läuft der LOOP und die
ISR problemlos.
Kann mir jemand dabei helfen.
Patrick schrieb:> ISR(TIMER1_COMPA_vect)> {> data = current_get_Current (Add_Current1,Acc1);> Serial.println(data,4);
Mindestens 2 Fehler:
- data muss volatile sein
- Serial.println in einer ISR ist verboten
leo
wenn du die einfach in der Loop laufen lässt, wie schnell kommen denn
dann die Werte?
Viel schneller als 1s oder langsamer?
Und wie ist es mit dem Timer?
Läuft der immer weiter? Oder muss der in der ISR einfach neu gestartet
werden?
Sprich, ließt er einmal die Werte aus und stoppt dann? (Weil der Timer
stehen geblieben ist).
Grüße, Jens
Also er blibt im Timer hängen.
Wenn ich dort nur mir die millis anzeigen lasse kommen die im Sekunden
Takt.
das eine Print Funktion nix in der ISR zu suchen hat ist mir klar, war
jetzt nur zum debuggen.
Die print Funktion soll später im Loop und nur ausgeführt werden, wenn
ich neue Daten über die i2C empfangen habe.
hab den Datentyp geändert mit "volatile" geändert.
jedoch bleibt das Programm weiter vor der Print Funktion hängen, so das
diese nicht ausgeführt wird.
Hab es auch mal so versucht, auch hier wird die Print funktion nicht
ausgeführt.
Die unterprogramme welche unverändert sind habe ich mal jetzt nicht
mitgesendet.
hab des rätsels Lösung.
Die Wire.h benötigt ebenfalls Interrupt befehle welche in der ISR
deaktiviert sind.
habe jetzt zu beginn der ISR die Interrupts per sei(); aktiviert und es
läuft.
keine schöne lösung, funktioniert aber schonmal.
falls jemand ein eleganteren vorschlag hat gerne her damit.
Weshalb muss die Abfrage der Daten in der ISR stattfinden? Setze in der
ISR einfach ein Flag und werte es in der Loop aus.
Und überhaupt, weshalb für diesen Zweck einen Timer Interrupt? Bei einer
Periode von 1 Sekunde kann das auch ein millis() Vergleich in der Loop
erledigen.
wichtig ist, das der Daten abruf im sekunden intervall passiert. Da noch
einiges mehr im Code später passiert, dann es sein das ein kompletter
durchlauf länger dauert als eine sekunde.
Hallo,
Nimm doch die Struktur aus dem Arduino Beispiel "blink without delay".
unsigned long millis_1s =0;
void loop(){
if( millis() - millis_1s >= 1000){
millis_1s+=1000;
// Hier was du jede Sekunde ausgeführt haben willst
}
// Restlicher Code
}
Gruß
Michael V. schrieb:> Nimm doch die Struktur aus dem Arduino Beispiel "blink without delay".
Er hat in seiner loop() noch andere Programmteile, die länger als 1
Sekunde laufen können (vermutlich wegen großzügigem Delay-Einsatz)
---> loop umstrukturieren, dass ein durchlauf wieder nur eine sache von
wenigen msec ist.
Eine Statemachine kann dabei helfen.