Pages: [1] 2   Go Down
Author Topic: Millis funktioniert nicht  (Read 971 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Full Member
***
Karma: 1
Posts: 135
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo!

Hier erst mal der Code:

Code:
#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!

Wo sitzt der Fehler?

Gruß
Morris
Logged

Wien
Online Online
Edison Member
*
Karma: 26
Posts: 1834
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hi,

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...

gruß stefan
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 135
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Komisch - an dem klappts nicht  smiley-fat
Logged

Wien
Online Online
Edison Member
*
Karma: 26
Posts: 1834
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hi,

ich hab' winxp und ide 1.05.

klappt denn das blinkwithoutdelay bei Dir? kannst ja eine serielle ausgabe machen statt der led.
und nimm den sensor von pin.

gruß stefan
Logged

Germany
Offline Offline
Faraday Member
**
Karma: 56
Posts: 2973
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Die etwas unglückliche Stellung des Kommentars
Code:
//Hilfsfunktionen---------------------------------------------------------------------------------------------
lässt mich raten, dass bei dir im Originalcode die geschweiften Klammern anders sitzen ???

Quote
an dem klappts nicht  smiley-fat
ist mir leider etwas unverständlich.

Ich verstehe dein Problem so, dass die Serial.println - Ausgabe nicht alle 2 Sekunden, sondern erheblich häufiger ( "dauerhaft" ) kommt
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 135
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Die etwas unglückliche Stellung des Kommentars
Code:
//Hilfsfunktionen---------------------------------------------------------------------------------------------
lässt mich raten, dass bei dir im Originalcode die geschweiften Klammern anders sitzen ???

Ne - passt so. Der Kommentar müsste hinter die geschweifte Klammer, aber das tut ja zum Programmablauf nichts zur Sache.

Ich verstehe dein Problem so, dass die Serial.println - Ausgabe nicht alle 2 Sekunden, sondern erheblich häufiger ( "dauerhaft" ) kommt
Korrekt
Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 134
Posts: 2849
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

Code:
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:
Code:
Serial.println(freeRam());
Was wird denn da angezeigt?
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 135
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nein - das Programm, was ich hier gepostet habe, ist 1zu1 das, was auf dem Arduino drauf ist.

Eventuell ein Defekt am Board?
Logged

Online Online
Edison Member
*
Karma: 28
Posts: 2105
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Welche IDE nutzt du?

In der Arduino IDE sowie Visual Studio 2012 Pro gibt es kein Problem mit der Anzeige.

Kommentier mal im Setup die Zeile vom Interrupt aus.
Logged

Kein technischer Support über die Private Nachricht!

Germany S-H
Offline Offline
Faraday Member
**
Karma: 134
Posts: 2849
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?

Code:
#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   
}

Logged

Offline Offline
Faraday Member
**
Karma: 96
Posts: 3500
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

"long Impuls" sollte auch als volatile deklariert werden. Das wird aber nicht das Problem hier sein.
Logged

Lost in Singapore
Offline Offline
Jr. Member
**
Karma: 3
Posts: 74
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Testest du das mit dem Geber? Wenn ja welche Drehzahl?

evtl die serial Instanz mal vorm interrupt initialisieren.
Logged


Lost in Singapore
Offline Offline
Jr. Member
**
Karma: 3
Posts: 74
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

und mal ansagen auf welchen arduino das laufen soll
Logged


Offline Offline
Sr. Member
****
Karma: 11
Posts: 457
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: September 25, 2013, 11:13:51 am by rudirabbit » Logged

Arduino UNO,MEGA,Pro Mini Ethernet Shield

Germany
Offline Offline
Faraday Member
**
Karma: 56
Posts: 2973
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 smiley-wink

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.
Logged

Pages: [1] 2   Go Up
Jump to: