ina219.getCurrent_mA(); Funktion in der ISR nicht aufrufbar

OP #5956512
Ich habe einen Arduino Nano und ein INA219 Strommessmodul.
Ich möchte über die TimerOne.h Bibliothek einmal die Sekunde den 
Stromwert auslesen.
Hierzu wird 1 mal die Sekunde die ISR per Timer mit dem Namen Strom 
aufgerufen.
Normalerweise sollte der Befehl zum abfragen " I = 
ina219.getCurrent_mA(); " in der ISR mit dem Namen Strom stehen.  Da 
funktioniert er aber nicht und der Arduino Nano stützt ab.
Zum Testen habe ich mal versucht eine andere Methode in der ISR 
aufzurufen. Das geht. Es scheint also ein Problem mit dieser einen 
Funktion zu sein.
Weiß jemand warum ich gerade diese Funktion nicht aufrufen kann aber 
andere Sachen schon?
1
#include <TimerOne.h>
2
#include <Wire.h>
3
#include <Adafruit_INA219.h>
4
Adafruit_INA219 ina219;
5

6
int I = 0;                          //Stromwert
7

8
void setup(void){
9
ina219.begin();
10
Timer1.initialize(1000000);         //Timer auf 1 Sekunden stellen
11
Timer1.attachInterrupt(Strom);      //ISR Strom wird jede Sekunde aufgerufen
12
Serial.begin(115200);
13
}
14
void loop(void){   
15
I = ina219.getCurrent_mA();         //hier wird die Funktion aufgerufen
16
delay(1000);
17
Serial.println("Läuft noch");
18
}
19
void Strom(void){
20
//I = ina219.getCurrent_mA();       //hier wird die Funktion nicht aufgerufen.Warum?
21
Serial.println(I);
22
}
Gast
Generell ist es eine riskante Sache, aus Interrupts heraus Funktionen 
aufzurufen, die extern kommunizieren oder viel Speicher belegen. Dein 
Serial.println() halte ich dort ebenfalls für eine ganz schlechte Idee.

Denn Interrupts können andere Funktionen unterbrechen, die bereits viel 
Speicher belegt haben. RAM ist bei den kleinen AVR Mikrocontrollern 
knapp bemessen.
Hallo,

auch wenn das hier warscheinlich nicht das Problem ist, solltest du 
Objekt so initialisieren das sie zum Aufrufzeitpunkt auch verfügbar 
sind.
Serial.begin() sollte also noch vor der Timer1.attachInterrupt() stehen, 
sonst könnte die ISR mit Serial.print() noch vor Serial.begin() 
ausgeführt werden.

Bekommst du vom Compiler irgendwelche Warnungen?

Sascha
Gast
Sandro N. schrieb:
> Sascha W. schrieb:
>> solltest du
>> Objekt so initialisieren das sie zum Aufrufzeitpunkt auch verfügbar
>> sind.
>
> Da hast du grundsätzlich recht aber wie du schon geschrieben hast spielt
> das hier keine rolle :-)
>
> Achso, und ich bekomme keine Probleme beim Compiler .

Aber, das Problem, hast du jetzt verstanden, oder?
OP
Sascha W. schrieb:
> Oder besser noch, im IRQ ein Flag setzen und in der Loop darauf
> reagieren. In Loop darf dann natürlich kein delay vorkommen.

ja, so habe ich das jetzt auch gelöst. Ich musste nur sicherstellen, 
dass der Code in einer Stunde genau 3600 mal ausgeführt wird.
Solange der Loop nicht länger als 1 Sekunde braucht sollte das auch 
funktionieren.
Ich hatte mich schon gefragt wozu so ein "Job Flag" gut sein soll. Mann 
kann ja alles in die ISR schreiben dachte ich. Aber in meinem Fall ging 
es eben doch nur über eine "Flag".
(Firma: egal)
Sascha W. schrieb:
> Brain 2.0 schrieb:
>> Und warum überhaupt per IRQ ?
>> 1 sek ist doch nicht zeitkritisch, das geht auch wunderbar in der loop.
> Oder besser noch, im IRQ ein Flag setzen und in der Loop darauf
> reagieren. In Loop darf dann natürlich kein delay vorkommen.
>
> Sascha

Oder in der IRQ erst den ADC-Wert sichern und dann den ADC neu starten.
So bracht man nicht Warten bis der ADC fertig ist, dar hat dann fast 
eine Sekunde zeit um fertig zu werden. Die Werte sind dann zwar eine 
Sekunde alt, dafür aber nirgends Wartezeiten wegen dem ADC. Und in 
etlichen Anwendungsfällen ist das durchaus langt das durchaus.
Moderator (Firma: Titel) Persönliche Seite
Sandro N. schrieb:
> Solange der Loop nicht länger als 1 Sekunde braucht sollte das auch
> funktionieren.
Für mich enthält eine main()-Loop, die mehr als 50ms(*) braucht, schon 
einen Fehler. Denn dort drin wird zyklisch alles abgearbeitet, was 
während des letzten Durchlaufs in den Interrupts so angefallen ist.

(*) je nach Anwendung 10..100ms

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 7 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.