Hertz (Hz) Angabe im Display nach Messwert

Hallo.
Der sketch funktioniert prima. Nun möchte ich aber im Display noch zusätzlich das Kürzel "Hz" hinter dem Wert hinzufügen. Und deshalb wende ich mich nach erfolglosen Versuchen als Neuling an Euch.

Könnt ihr mir helfen?
Auch wenn ich den sketch als (Entschuldige, neue Benutzer dürfen keine Anhänge hochladen) nicht hochladen kann. Deshalb per copy and paste.

LiquidCrystal lcd(7, 6, 11, 10, 9, 8); //In dieser Zeile wird festgelegt, welche Pins des Mikrocontrollerboards für das LCD verwendet wird (Am besten erstmal nicht verändern).

const int SensorPin = 2; //Define Interrupt Pin (2 or 3 @ Arduino Uno)

int InterruptCounter, rpm;

void setup()
{
Serial.begin(9600);
delay(1000);

lcd.begin(16, 2); //Im Setup wird angegeben, wie viele Zeichen und Zeilen verwendet werden. Hier: 16 Zeichen in 2 Zeilen.
lcd.print("Counting");
}

void loop() {
meassure();
}

void meassure() {
InterruptCounter = 0;
attachInterrupt(digitalPinToInterrupt(SensorPin), countup, RISING);
delay(3000);
detachInterrupt(digitalPinToInterrupt(SensorPin));
rpm = (InterruptCounter / 2) ;
display_rpm();
}

void countup() {
InterruptCounter++;
}

void display_rpm() {
lcd.clear();
lcd.print("Counts: ");
lcd.print(InterruptCounter, 1);
lcd.setCursor(0, 2);
lcd.print("RPS: ");
lcd.print(rpm);

}

öhm.. ganz schlicht würd ich jetzt sagen: setz in der Zeile nach lcd.print(rpm); noch ein lcd.print("Hz"); und fertig. :wink:
Nur wird das "Hz" bei ein- bis dreistelligen Werten dementsprechend direkt hinter der Zahl an eine andere Position gesetzt und springt daher im schlimmsten Fall ständig umher. Das könnte man z.B. wie folgt vermeiden, in dem man die letzte Ziffer an eine feste Position setzt:

if (rpm < 100) { lcd.print(" "); }
if (rpm < 10) { lcd.print(" "); }
lcd.print(rpm);
lcd.print("Hz");

Das geht bestimmt noch eleganter (wie auch die blockierende Drehzahlmessung), aber als Schnellschuss tuts das.. :wink:

Pure Begeisterung. Es funktioniert bestens, dein Tip. Super vielen Dank dafür. Du bist großartig.

Chapeau für Deinen Aufbau!

Ein paar ungefragte Hinweise:

  1. Bitte setze Dein Programm in Code-Tags! Das kannst Du auch nachträglich noch tun durch verändern von Beitrag #1.

  2. Funduino hat auch ein paar I²C Displays im Angebot, damit benötigst Du nur zwei Datenkabel. An den I²C-Bus kannst Du noch weitere Komponenten anschließen, das spart Pins.

  3. Als Bibliothek empfehle ich Dir die NoiascaLiquidCrystal-Bibliothek, denn die kann auch Umlaute.

  4. Die Textformatierung überlasse ich als fauler Mensch gerne snprintf, auch wenn dazu etwas mehr Speicher benötigt wird.

  5. Vergiß delay, steige um auf millis.

Programm zur Veranschaulichung
const byte cols = 16;                               // columns/characters per row
const byte rows = 2;                                // how many rows
const byte addr = 0x26;                             // set the LCD address to 0x3F or 0x27
#include <Wire.h>                                   // needed for the I2C interface
#include <NoiascaLiquidCrystal.h>                   // download library from https://werner.rothschopf.net/202009_arduino_liquid_crystal_intro.htm 
#include <NoiascaHW/lcd_PCF8574.h>                  // include the proper IO interface
LiquidCrystal_PCF8574 lcd(Wire, addr, cols, rows);  // create lcd object - with support of special characters

uint32_t jetzt = 0, vorhin = 0;
uint16_t z = 0;                                     // Zähler

void setup()
{
  Wire.begin();                                     // start I2C library
  lcd.begin();                                      // initialize the LCD
  lcd.backlight();                                  // turn on backlight

}

void loop() {
  jetzt = millis();
  char buf[cols + 1];                               // Anzahl Spalten plus Zeilenende
  if (jetzt - vorhin >= 1000)
  {
    vorhin = jetzt;
    snprintf( buf, sizeof(buf), "Zähler: %4u", z);    // Text formatieren
    lcd.setCursor(0, 0);                              // Schreibposition wählen
    lcd.print( buf );                                 // Text anzeigen
    z++;
    if (z > 9999) z = 0;
  }
}

Mein schlichter Aufbau:

Viel Spaß beim Basteln :slightly_smiling_face:

In Code-Tags setzen? Aber wie genau? Das Forum Programm lässt mich als Neuling keinen Code hochladen. Da kommt immer (Entschuldige, neue Benutzer dürfen keine Anhänge hochladen)

Zwei Möglichkeiten in der IDE auf bearbeiten für Forum kopieren und hier mit strg +V einfügen oder den Sketch im Post markieren kopieren , und auf CODE klicken, hier oben im Fenster und einfügen

image

Ausnahme weise habe das für dich gemacht :wink:

LiquidCrystal lcd(7, 6, 11, 10, 9, 8); //In dieser Zeile wird festgelegt, welche Pins des Mikrocontrollerboards für das LCD verwendet wird (Am besten erstmal nicht verändern).
const int SensorPin = 2; //Define Interrupt Pin (2 or 3 @ Arduino Uno)
int InterruptCounter, rpm;

void setup()
{
  Serial.begin(9600);
  delay(1000);

  lcd.begin(16, 2); //Im Setup wird angegeben, wie viele Zeichen und Zeilen verwendet werden. Hier: 16 Zeichen in 2 Zeilen.
  lcd.print("Counting");
}

void loop() {
  meassure();
}

void meassure() {
  InterruptCounter = 0;
  attachInterrupt(digitalPinToInterrupt(SensorPin), countup, RISING);
  delay(3000);
  detachInterrupt(digitalPinToInterrupt(SensorPin));
  rpm = (InterruptCounter / 2) ;
  display_rpm();
}

void countup() {
  InterruptCounter++;
}

void display_rpm() {
  lcd.clear();
  lcd.print("Counts: ");
  lcd.print(InterruptCounter, 1);
  lcd.setCursor(0, 2);
  lcd.print("RPS: ");
  lcd.print(rpm);

}

Wen Du in der IDE auf strg +T druckst wird dein Sketch schön Formatiert und zeigt einige Fehler an zB. fehlende geschweiften Klammern(Die Einrückung stimmt im den fall nicht), dadurch ist das besser zum lesen, ja wir sind ein wenig verwöhnt :sweat_smile:

Vielen Dank für die Ausnahme.

Stell Dir vor...Du möchtest auf der Autobahn mal schneller fahren. Und 3 Sekunden lang tritt jemand voll auf die Bremse...Schmeiß den Beifahrer raus :slight_smile: Du kommst so nur auf 10 Kmh...wenn überhaupt..

Das muss doch delay(1000) sein, oder was?

Dann tritt dein Beifahrer 1 Sec auf die Bremse. :wink: Ist Dir aber schon in -Post 4 geschrieben worden.

Zu dem ist noch ein, eigentlich zwei denk Fehler im Sketch.
1.

void meassure() {
  InterruptCounter = 0;

somit bleibt


rpm = (InterruptCounter / 2) ;

rpm immer 0 (Null)

void countup() {
  InterruptCounter++;
}

ist nirgend wo eingebunden (oder übersehe das), somit bleibt
rpm weiter 0.
Damit wen es Funktioniert das Display nicht Flackert gehört

lcd.clear();

in Setup nach dem delay().
nur musst danach die

void display_rpm()

damit es die Werte vernünftig angezeigt werden.

ZB.

void display_rpm() {
  lcd.clear();
  lcd.print("Counts: ");
  if (InterruptCounter < 100)lcd.print(" ");
  if (InterruptCounter < 10)lcd.print(" ");
  lcd.print(InterruptCounter, 1);
  lcd.setCursor(0, 2);
  lcd.print("RPS: ");
  if (rpm < 100)lcd.print(" ");
  if (rpm < 10)lcd.print(" ");
  lcd.print(rpm);
}

Man kann die Anzeige der Werte anders bauen, für Anfang ist sowas aber OK.

1 Like

Global int InterruptCounter, rpm;

Nö, die Messung findet während delay(3000); statt. Danach hat InterruptCounter einen Wert.

1 Like

Nur wird der wert vom InterruptCounter sich nicht Ändern, auch wen der TO den

void countup()

in Sketch einbindet, wird der InterruptCounter nach der Messung gelöscht, oder?

Nun ich wage mal zu bezweifeln, das dieser Sketch überhaupt lüft :wink: Ohne Lib einbindung lässt er sich sicher noch nicht mal hochladen

Und doch lässt sich der sketch hochladen und zum plausiblen Laufen bringen. Alles gut. Hier ( Drehzahlmesser von Lüfter auswerten )habe ich mir den Entwurf abgeschaut. Beste Grüße an Alle.

welcher sketch?

Nur...Serial.print.. ist was anderes als LCD...... :wink: Die Lib ist nicht eingebunden. Dann in der 3 Sec. Pause liest Du die Pulse aus und.....Wer misst misst Mist oder wie?
#include <LiquidCrystal.h> habe ich nicht entdecken können.
Dann RPS: soll wohl heißen Umdrehungen pro Sec... Sind aber 3 Sekunden Messdauer.
Und somit hat das doch nicht hin oder?

1 Like

Siehe #1 und #6 als nette Serviceleistung.

Doch:

LiquidCrystal lcd(7, 6, 11, 10, 9, 8); //In dieser Zeile wird festgelegt, welche Pins des Mikrocontrollerboards für das LCD verwendet wird (Am besten erstmal nicht verändern).

Vermutlich handelt es sich um ein Beispielprogramm von Funduino.

Nö Nö :slight_smile:
So lüpt das

#include <LiquidCrystal.h>

LiquidCrystal lcd(7, 6, 11, 10, 9, 8);  //In dieser Zeile wird festgelegt, welche Pins des Mikrocontrollerboards für das LCD verwendet wird (Am besten erstmal nicht verändern).
const int SensorPin = 2;                //Define Interrupt Pin (2 or 3 @ Arduino Uno)
int InterruptCounter, rpm, rpmOld;
uint16_t Zeit, Time;
uint8_t SW;
uint16_t Pruefzeit = 3000;  // 1000 = 1 Sec.
void setup() {
  Serial.begin(9600);
  delay(1000);

  lcd.begin(16, 2);  //Im Setup wird angegeben, wie viele Zeichen und Zeilen verwendet werden. Hier: 16 Zeichen in 2 Zeilen.
  lcd.print("Counting");
}

void loop() {
  Zeit = millis();
  meassure();
}

void meassure() {
  if (SW == 0) {
    InterruptCounter = 0;
    SW = 1;
    Time = Zeit;
    attachInterrupt(digitalPinToInterrupt(SensorPin), countup, RISING);
  }
  if (Zeit >= Time + Pruefzeit) {
    detachInterrupt(digitalPinToInterrupt(SensorPin));
    SW = 0;
    InterruptCounter = InterruptCounter / (Pruefzeit / 1000);
    rpm = (InterruptCounter / 2);
    if (rpmOld != rpm) {
      rpmOld = rpm;
      display_rpm();
    }
  }
}

void countup() {
  InterruptCounter++;
}

void display_rpm() {
  lcd.clear();
  lcd.print("Counts: ");
  if (InterruptCounter < 100) lcd.print(" ");
  if (InterruptCounter < 10) lcd.print(" ");
  lcd.print(InterruptCounter, 1);
  lcd.setCursor(0, 2);
  lcd.print("RPS: ");
  if (rpm < 100) lcd.print(" ");
  if (rpm < 10) lcd.print(" ");
  lcd.print(rpm);
}