Tacho mit Reed-Schalter


hallo!
mein erstes projekt auf einem arduino nano ist ein tachometer mit hilfe eines alten fahrrad-reed-schalter.
ich habe teilweise mit hilfe eines tutorials folgenden code geschrieben. leider hat aber meine freude daran, dass alles einwandfrei funktioniert nur kurz gedauert.
was mir aufgefallen ist, wenn ich in der vorletzten zeile mit "serial.println(impuls);" die zwischenschritte von der impuls-variable ausgeben lasse, stimmt das km/h ergebnis recht genau, wenn ich diese zeile weg lasse, stimmt sie nicht mehr. (km/h-ergebnis ist zu hoch) ich gehe davon aus, dass das daran liegt, dass der prozessor dann einfach schneller in die loop() gelangt und somit die millis() einen geringeren wert hat und somit der anschein entsteht, dass das fahrrad schneller fährt.
könnt ihr mir da weiterhelfen, wie man etwas besser löst? darf man davon ausgehen, dass der prozessor diesen code immer gleich schnell durchläuft? mit einem delay in der trigger-funktion wäre das dann ja viell. unschön aber funktionierend gelöst  :smiley-red:

vielen dank!

lg cleee

code: [select]

// digitaltacho mit reed-schalter

double umfang=2.0;                // in meter
int umdrehungen;
int impuls;     
int pinreed = 2;                  // digital pin arduino a2
double kmh;

double rpmilli;                   // geschwindigkeit in umdrehungen pro millisekunde
double rpm;
unsigned long timeold;       
unsigned long zeitpu;             // zeit pro umdrehung

void setup()
{
  serial.begin(9600);
 
  // pinbelegung für reed-schalter
  pinmode(pinreed, input);
  digitalwrite(pinreed, high);
  attachinterrupt(0, trigger, falling);
   
  rpmilli=0;
  timeold=0;
  zeitpu=0;
  impuls=0;
}

void loop()
{
   if (impuls >= 6)
   {
     umdrehungen=3;                         // 6 impulse bedeutzet 3 umdrehungen (2 impulse pro umdrehung)       
     zeitpu=((millis()-timeold))/3;         // zeit für eine umdrehung
     timeold=millis();                      // bereits vergangene zeit
     rpmilli=1/(double)zeitpu;              // umdrehungen pro millisekunde
     rpm=rpmilli*1000*60;                   // umdrehungen pro minute
     kmh=(rpm*60*umfang)/1000;
     serial.println(kmh);
     impuls=0;
   }
}

void trigger()
{
  impuls++;
  serial.println(impuls);
}

1.) serial hat in interrupts nichts verloren. das geht einfach nicht
2.) variablen die in interrupts und außerhalb verwendet werden müssen volatile sein!
http://arduino.cc/en/reference/volatile
das verhindert außerdem dass der compiler eine variable wegoptimiert. der hat nämlich keine möglichkeit festzustellen ob und wie die interrupt routine aufgerufen wird.

3.) delay geht in interrupts nicht und hat in interrupts auch vom prinzip nichts verloren. isrs müssen kurz wie möglich sein.

wenn du nach einem interrupt auf serial ausgeben willst mach es so:
code: [select]

volatile int impuls;
volatile boolean triggered;

void trigger()
{
 impuls++;
 triggered = true;
}

void loop()
{
    if(triggered)
    {
         serial.println(impuls);
         triggered = false;
    }
}


Arduino Forum > International > Deutsch (Moderator: uwefed) > Tacho mit Reed-Schalter


arduino

Comments

Popular posts from this blog

Connecting Raspberry Pi 2 to P10(1R)-V706 LED Dot Matrix - Raspberry Pi Forums

TypeError: <unknown> is not a numpy array - Raspberry Pi Forums

datso and removing imagetitle - Joomla! Forum - community, help and support