Ich habe eine schöne Darstellung der Motordrehzahl auf einem LCD gefunden:
Ich habe das Display und den Sensor nach dem Vorschlag angeschlossen. Leider passiert aber nichts auf dem Display. Die Anzeige verharrt bei "0 RPM". Die Messung mit dem Multimeter bestätigt, dass der Pegel zwischen knapp 5V und gut 0 Volt wechselt. Am Hallsensor und seinem Anschluss liegt es also nicht.
Könnte sich mal jemand den Sketch anschauen und mir sagen, ob der Anschluss des Hallsensors am Arduino Uno auf Pin A0 (wie in der Zeichnung) so richtig ist? Oder ist da sonst noch irgend ein Bug in dem Sketch, der eine Anzeige der Drehzahl verhindert?
/*
RPM meter code (tested on device rotating at 10,000 rpm)
rev.001
* using a hall effect sensor
http://www.adafruit.com/index.php?main_page=product_info&cPath=35&products_id=158
* using a parallel LCD with
LiquidCrystal Library
http://www.ladyada.net/learn/lcd/charlcd.html
http://www.arduino.cc/en/Tutorial/LiquidCrystal
with pins 7,8,9,10,11,12
*/
// 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);
// read the hall effect sensor on pin 2
const int hallPin=2;
const unsigned long sampleTime=1000;
const int maxRPM = 10200;
void setup()
{
pinMode(hallPin,INPUT);
Serial.begin(9600);
// set up the LCD's number of rows and columns:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("initializing");
delay(1000);
lcd.clear();
}
void loop()
{
delay(100);
int rpm=getRPM();
lcd.clear();
displayRPM(rpm);
displayBar(rpm);
}
int getRPM()
{
// sample for sampleTime in millisecs
int kount=0;
boolean kflag=LOW;
unsigned long currentTime=0;
unsigned long startTime=millis();
while (currentTime<=sampleTime)
{
if (digitalRead(hallPin)==HIGH)
{
kflag=HIGH;
}
if (digitalRead(hallPin)==LOW && kflag==HIGH)
{
kount++;
kflag=LOW;
}
currentTime=millis()-startTime;
}
int kount2rpm = int(60000./float(sampleTime))*kount;
return kount2rpm;
}
void displayRPM(int rpm)
{
lcd.clear();
// set the cursor to column 0, line 1
lcd.setCursor(0, 0);
// print the number of seconds since reset:
lcd.print(rpm,DEC);
lcd.setCursor(7,0);
lcd.print("RPM");
}
void displayBar(int rpm)
{
int numOfBars=map(rpm,0,maxRPM,0,15);
lcd.setCursor(0,1);
if (rpm!=0)
{
for (int i=0; i<=numOfBars; i++)
{
lcd.setCursor(i,1);
lcd.write(1023);
}
}
}
Gelegenheitsbastler:
Genau das habe ich mir auch gedacht. Aber da darf ich doch keine 5V drauf legen?!
Wie müsste denn der Sketch in der Zeile lauten, damit es über den A0 läuft? Einfach die "2" durch "A0" ersetzen?
Ich dachte, dass die digitalen Eingänge nur maximal 3,3V vertragen. Also kann ich da wirklich mit 5V drauf gehen? Ich frage lieber nochmal nach, bevor ich mir beim Versuch den Arduino abschieße.
Ich bekomme darüber noch graue Haare... Es will mit dem Tausenderpunkt nicht klappen. Das hier habe ich zuerst probiert:
.
.
.
void loop()
{
delay(100);
int rpm=getRPM();
int Tausender=rpm/1000;
int Einer=rpm%1000;
lcd.clear();
displayRPM(rpm);
displayBar(rpm);
}
int getRPM()
{
// sample for sampleTime in millisecs
int kount=0;
boolean kflag=LOW;
unsigned long currentTime=0;
unsigned long startTime=millis();
while (currentTime<=sampleTime)
{
if (digitalRead(hallPin)==HIGH)
{
kflag=HIGH;
}
if (digitalRead(hallPin)==LOW && kflag==HIGH)
{
kount++;
kflag=LOW;
}
currentTime=millis()-startTime;
}
int kount2rpm = int(60000./float(sampleTime))*kount;
return kount2rpm;
}
void displayRPM(int rpm)
{
lcd.clear();
// set the cursor to column 0, line 1
lcd.setCursor(0, 0);
// print the number of seconds since reset:
lcd.print(Tausender "." Einer,DEC);
lcd.setCursor(7,0);
lcd.print("RPM");
}
void displayBar(int rpm)
{
int numOfBars=map(rpm,0,maxRPM,0,15);
lcd.setCursor(0,1);
if (rpm!=0)
{
for (int i=0; i<=numOfBars; i++)
{
lcd.setCursor(i,1);
lcd.write(1023);
}
}
}
Weil das mit einem Fehler quittiert wurde, den ich nicht ausmerzen konnte, habe ich es anders probieren wollen:
lcd.print(rpm/1000 "." rpm%1000);
Aber auch das geht nicht. Sobald ich mehr als rpm/1000 schreibe, gibt es eine Fehlermeldung:
lcd.print((rpm/1000) "." );
ergibt beispielsweise:
RPM_Balkenanzeige_2.ino: In function ‘void displayRPM(int)’:
RPM_Balkenanzeige_2:80: error: expected `)' before string constant
Das verstehe ich nicht. Könnte mir jemand sagen, wo mein (Gedanken)Fehler liegt?
Das hat so leider auch nicht geklappt. Steht die Definition von Tausender und Einer vielleicht an der falschen Stelle, oder ist in der Schreibweise ein Fehler?
Da gab es zumindest keine Fehlermeldung. Allerdings lautet die Anzeige im Display bei beispielsweise 3000 Umdrehungen nun:
3.0 RPM
Welche Funktion hat das Prozentzeichen? Da scheint der Fehler zu liegen. Ich würde den Hunderter, Zehner und Einer gerne immer anzeigen lassen, auch wenn der Wert zufällig exakt 3000 lautet, so dass die angezeigte Zahl immer 4 Stellen hat, wobei die der Tausenderpunkt die erste Stelle von den drei folgenden Stellen trennt.
Ja, über 9.999 müsste man bei der letzten Lösung nur text[7] definieren.
Der vorige Trick ( rpm/1000 + '0' ) zeigt dann Unsinn an, braucht aber nicht mehr Platz auf dem LCD. ( "<.345" statt "12.345" )