Hi,
ich habe mir mal ein kleines RPM Meter gebaut und die Drehzahlen von Lüftern etc. messen zu können. Ich habe mir einen Code aus dem Internet kopiert.
int ledPin = 13; // IR LED connected to digital pin 13
volatile byte rpmcount;
unsigned int rpm;
unsigned long timeold;
// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
void rpm_fun()
{
//Each rotation, this interrupt function is run twice, so take that into consideration for
//calculating RPM
//Update count
rpmcount++;
}
void setup()
{
lcd.begin(16, 2); // intialise the LCD
//Interrupt 0 is digital pin 2, so that is where the IR detector is connected
//Triggers on FALLING (change from HIGH to LOW)
attachInterrupt(0, rpm_fun, FALLING);
//Turn on IR LED
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
rpmcount = 0;
rpm = 0;
timeold = 0;
}
void loop()
{
//Update RPM every second
delay(1000);
//Don't process interrupts during calculations
detachInterrupt(0);
//Note that this would be 60*1000/(millis() - timeold)*rpmcount if the interrupt
//happened once per revolution instead of twice. Other multiples could be used
//for multi-bladed propellers or fans
rpm = 30*1000/(millis() - timeold)*rpmcount;
timeold = millis();
rpmcount = 0;
//Print out result to lcd
lcd.clear();
lcd.print("RPM=");
lcd.print(rpm);
//Restart the interrupt processing
attachInterrupt(0, rpm_fun, FALLING);
}
Ich möchte jetzt zwischen meheren Modi wechseln. Einmal gibt es ja den Modus, wenn es 2 Unterbrechungen pro Umdrehung gibt: 30*1000/(millis() - timeold)*rpmcount;
und einmal den Modus, wenn es nur eine Unterbrechung pro Umdrehung gibt.
60*1000/(millis() - timeold)*rpmcount;
Meine Frage. Kann ich über einen taktilen Schalter zwischen meheren Modi wechseln. (Am besten 4). Was zusätzlich noch schön wäre, wenn auf dem Display noch der Modus angezeigt werden könnte.
Grüße,
Lukas
müsstest du einen Taster (wenn du das mit "taktiler Schalter" meinst) bis zu eine Sekunde lang drücken, bis es gemerkt wird.
Aber sonst geht es natürlich.
Wenn statt 1 sec - delay nur ca. 2 bis 10 msec lang gewartet wird, kannst du damit das Prellen des Tasters abfangen.
Du musst dir merken, ob ein neuer Tastendruck vorliegt, und in welchem Modus du bist.
Ausserdem musst du dich bei Tastern zwischen Pullup und Pulldown entscheiden
Wenn der Taster zwischen GND und EingangsPin liegt, ist er LOW wenn gedrückt (verwirrend),
aber du brauchst keinen extra Pulldown-Widerstand:
void setup()
{
pinMode ( 3, INPUT_PULLUP); // Pin 3 ist der Taster nach GND
// ... andere Initialisierungen
}
boolean altTaster = HIGH;
int modus = 1; // wechselt zwischen 1, 2 , 3
void loop()
{
if (digitalRead(3) == LOW && altTaster == HIGH)
{
// neuer Tasterdruck
delay(10); // prellen abwarten
altTaster = LOW; // merken, dass erkannt
modus ++;
if (modus > 3) modus = 1;
}
else if (digitalRead(3) == HIGH && altTaster == LOW)
{
// jetzt wurde Taster losgelassen
delay(10); // auch hier prellen abwarten
altTaster = HIGH;
}
// ... weiter in loop
Den Sekundenzyklus ohne delay(1000) kriegst du hin durch:
if ( millis() - timeold >= 1000)
{ // hier alles was nur einmal / sec passieren soll
noInterrupts(); // detach is not required
if ( modus == 1 ) rpm = 30*1000/(millis() - timeold)*rpmcount;
// evtl. andere Modi , gerne auch mit Stefans switch ...
rpmcount = 0;
timeold = millis();
interrupts(); // Interrupts can be active again.
// update LCD
lcd.clear();
lcd.print("Modus ");
lcd.print(modus);
lcd.print(" RPM=");
lcd.print(rpm);
} // Ende der Sekunden-Funktionen
} // Ende Loop
Hallo,
das "TastenPrellen" solltest Du nicht unterschätzen. Es kann Dich in den
Wahnsinn treiben- glaube mir.
Wenn Du die vier Modi nicht "gleichzeitig" brauchst, dann ist "switch case"
eine feine und einfache Möglichkeit. http://arduino.cc/de/Reference/SwitchCase
Gruß und Spaß
Andres