#include <math.h>
//Variablen deklarieren---------------------------------------------------------------------------------------------
long int Impuls=0; //Zählt die Anzahl der steigenden Flanken zur Messung der Drehzahl
long vorherigeMillisekunden = 0; //Millisekunden - Variable für Drehzahl
long int Intervall = 2000; //Zeit zwischen Drehzahl
int Drehzahl; //Drehzahlvar.
//Setup---------------------------------------------------------------------------------------------
void setup()
{
attachInterrupt(0, Impulszaehler, RISING); //Wenn an Interrupt 0 (I/0 Eingang 2) steigende Flanke, dann Hilffunktion "Impulszaehler" ausführen
Serial.begin(9600); //Serielle Ausgabe initialisieren
}
//Hauptprogramm---------------------------------------------------------------------------------------------
void loop()
{
unsigned long derzeitigeMillisekunden = millis();
if(derzeitigeMillisekunden - vorherigeMillisekunden >= Intervall) { //Wenn der Millisekundenzähler - vorherige Millisekunden >= Intervall
vorherigeMillisekunden = derzeitigeMillisekunden;
Drehzahl = (Impuls/3)*60; //Drehzahl = (Impulse/2 Sek) * (60s/1min) * (1 Umdrehung / 3 Impulse)
Serial.println(Drehzahl);
Impuls=0; //Impuls auf 0 setzen
}
//Hilfsfunktionen---------------------------------------------------------------------------------------------
}
void Impulszaehler(){ //Hilfsfunktion Impulszählen bei steigender Flanke
Impuls++; //Variable Impuls inkrementieren
}
Gemessen wird mit einem induktiven Sensor eine Drehzahl. Pro Umdrehung gibt es 3 Impulse.
Eigentlich müsste die Drehzahl doch auf Grund der millis-Funktion nur alle 2 Sek ausgegeben werden, richtig?
Die Ausgabe kommt aber dauerhaft!
also mir gibt das programm alle 2 sekunden einen wert aus. keinen sinnvollen klarerweise, weil ich nichts am pin hängen hab', aber brav alle 2 sekunden...
maeckes:
Hier erst mal der Code:
...
Wo sitzt der Fehler?
Bei dem geposteten Code erfolgt die Aktualisierung alle 2 Sekunden.
Der Fehler steckt also wohl nicht im geposteten Code.
Wenn das Programm größer ist als was Du gepostet hast und viel mehr RAM-Speicher verbraucht als der von dir gepostete Code, und das Programm aus einem nicht weiter erkennbaren Grund durchdreht, dann steht als Vermutung im Raum, dass Du möglicherweise zu verschwenderisch mit RAM-Speicher umgegangen bist und der Sketch nun mehr RAM benötigen würde als der Controller überhaupt eingebaut hat.
Füge mal diese Funktion in Deinen Code ein:
int freeRam () {
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}
Und lasse Dir an verschiedenen Stellen im Code die Menge des verfügbaren RAM-Speichers anzeigen:
maeckes:
Nein - das Programm, was ich hier gepostet habe, ist 1zu1 das, was auf dem Arduino drauf ist.
Eventuell ein Defekt am Board?
Welche Arduino-Version verwendest Du?
Welches Arduino-Board verwendest Du?
Verwendest Du eine alternative IDE?
Warum steht in Deinem Code "#include <math.h>" obwohl das in der Arduino-IDE nicht notwendig ist?
Was ist mit diesem Code, an dem ich einige kleine Modifikationen vorgenommen habe, aktualisiert der auch "ständig" und nicht nur alle zwei Sekunden?
#include <math.h>
//Variablen deklarieren---------------------------------------------------------------------------------------------
long Impuls=0; //Zählt die Anzahl der steigenden Flanken zur Messung der Drehzahl
unsigned long vorherigeMillisekunden = 0; //Millisekunden - Variable für Drehzahl
#define Intervall 2000 //Zeit zwischen Drehzahl
int Drehzahl; //Drehzahlvar.
//Setup---------------------------------------------------------------------------------------------
void setup()
{
attachInterrupt(0, Impulszaehler, RISING); //Wenn an Interrupt 0 (I/0 Eingang 2) steigende Flanke, dann Hilffunktion "Impulszaehler" ausführen
Serial.begin(9600); //Serielle Ausgabe initialisieren
}
//Hauptprogramm---------------------------------------------------------------------------------------------
void loop()
{
unsigned long derzeitigeMillisekunden = millis();
if(derzeitigeMillisekunden - vorherigeMillisekunden >= Intervall) { //Wenn der Millisekundenzähler - vorherige Millisekunden >= Intervall
vorherigeMillisekunden = derzeitigeMillisekunden;
Drehzahl = (Impuls/3)*60; //Drehzahl = (Impulse/2 Sek) * (60s/1min) * (1 Umdrehung / 3 Impulse)
Serial.println(Drehzahl);
Impuls=0; //Impuls auf 0 setzen
}
//Hilfsfunktionen---------------------------------------------------------------------------------------------
}
void Impulszaehler(){ //Hilfsfunktion Impulszählen bei steigender Flanke
Impuls++; //Variable Impuls inkrementieren
}
Ist auch nicht das Kernproblem :
Beim Anfassen von "long Impuls" außerhalb der ISR sollten die Interrupt gesperrt werden, nur wenn byte benutzt wird geht es ohne.
Das wurde mir zumindest hier gesagt, wenn ich das richtig verstanden habe.
rudirabbit:
Ist auch nicht das Kernproblem :
Beim Anfassen von "long Impuls" außerhalb der ISR sollten die Interrupt gesperrt werden, nur wenn byte benutzt wird geht es ohne.
Das wurde mir zumindest hier gesagt, wenn ich das richtig verstanden habe.
Richtig, und nicht das Kernproblem, auch richtig.
Es muss schon ganz dumm kommen, dass das einen Fehler verursacht:
z.B. genau wenn Impuls gelesen wird, und die Variable den Wert 255 hat, kommt ein Interrupt.
Wenn zuerst das hi Byte gelesen wird und dann das lo, kann statt 255 oder 256 auch eine 0 rauskommen,
wenn zuerst das lo Byte gelesen würde, könnte auch eine 511 rauskommen.
Allerdings muss der Interrupt, der von 255 auf 256 hochzählt, genau den Lesebefehl unterbrechen.
Und dann muss auch einer zufällig hingucken
Wenn die weitere Behandlung von Impuls kritisch ist, schadet es nicht, das durch kurzzeitig geschlossene Interrupts in loop() abzusichern,
aber wenn es nur um eine Testausgabe auf SerialMonitor geht, ist die Wahrscheinlichkeit, dass man dieses Problem je bemerkt, sehr gering.