Drehzahl auf LCD ausgeben - Problem mit Sketch

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);
      }
  }
}

Auf die Schnelle:
const int hallPin=2;
klingt nicht nach A0

Hallo,

// read the hall effect sensor on pin 2
const int hallPin=2;

also muss der Hall-Sensor am Digitaleingang 2 angeschlossen werden.

Gruss

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?

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?

Warum soll das nicht gehen? Geht!

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.

Wenn der arduino mit 5V läuft darfst Du auch 5V anlegen. Wenn er mit 3,3 V läuft dann nur 3,3V.
Kurz: Eingangsspannung max Betriebsspannung

Klaus_ww:
Wenn der arduino mit 5V läuft darfst Du auch 5V anlegen. Wenn er mit 3,3 V läuft dann nur 3,3V.
Kurz: Eingangsspannung max Betriebsspannung

Das gleiche gilt aber auch für analoge Eingänge.

Das gesagte gilt für alle Arduino aber nicht für den Arduino DUE. Dieser Verträgt an allen Eingängen nur 3,3V.
Grüße Uwe

Vielen Dank für die "Aufklärung". Ich habe wahrscheinlich zu lange am Raspberry rumgebastelt und das durcheinander geworfen.

Der Sketch läuft und das Display zeigt endlich an, was es soll :slight_smile:

Ich habe noch ein Problem mit dem Sketch. Wie bekomme ich in die Anzeige einen Tausenderpunkt? Die Anzeige soll dann zum Beispiel so aussehen:

10.200 RPM

Das ist beim schnellen Blick zur Seite für mich einfacher abzulesen als

10200 RPM

Das kann doch eigentlich nicht so schwer sein, nur bekomme ich es nicht hin :frowning:

Tausender = RPM/1000;
Einer = RPM%1000;

print Tausender "." Einer.

Grüße Uwe

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?

Weil das nicht zulässig ist.
statt
lcd.print(Tausender "." Einer,DEC);
schreib mal
lcd.print(Tausender,DEC); lcd.print ("."); lcd.print (Einer,DEC);

Grüße Uwe

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?

Ich habe es dann wieder so probiert:

 lcd.print(rpm/1000,DEC); lcd.print (".");  lcd.print (rpm%1000,DEC);

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.

Das eine Modulo-Division. Der Rest einer Division:
http://arduino.cc/en/Reference/Modulo

Rein Mathematisch korrekt da 3000 / 1000 = 3 Rest 0

Hier könntest du vielleicht die Nachkommastellen mit sprintf() auf konstant 3 Stellen Breite definieren.

EDIT:
Oder einfacher wäre sicher sowas:

int nach = rpm%1000;
if(nach == 0)
   lcd.print("000");
else
   lcd.print(nach);

und was ist mit z.B. 3001 ?
sprintf mit führenden Nullen war eindeutig der bessere Vorschlag

z.B:

char text[6] = "0.000";
text[0] = rpm/1000+'0';  // 1 Ziffer nach in Text wandeln
sprintf( &text[2],"%03d", rpm%1000);
lcd.print(text);

Mhh stimmt. Nicht ganz fertig gedacht. :blush:

Oder so:

char text[6];
sprintf(text, "%d.%03d", rpm / 1000, rpm % 1000);
lcd.print(text);

Funktioniert mit allen rpm ab 1000. Ab 10000 muss man den Puffer vergrößern.

Funktioniert mit allen rpm ab 1000

Geht auch unter 1000. ( Nur nicht unter 0 ) :wink:

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" )