Drehzalmessung mit Hal-sensor

Hallo Liebe Arduino Fans,

Ich habe Folgendes Problem,
Wir möchten gerne eine Drehzahlmessung mit einem HALL Sensor realisieren.
Hardware wäre kein Problem dieses auf zu bauen, nur Scheitert es an der Programmierung

Nebst der anzeige an einem Display dessen UPM
soll eine , z.b. bei 2700 upm ein Relais geschaltet werden
und eine Möglichkeit das man mit 2 Taster ( + - ) den Schwellwert für das Relais verändern kann ( z.b. um 50 UPN )
wenn man also 1x auf + drückt das dieses Relais erst bei 2750 anzieht

Leider habe ich von der Programmierung Keinen Plan und würde mich freuen wenn Jemand so was
mal Coden würde/könnte
ggf auf einem Teensy ? aber Kein muss
für mich als Elektroniker reicht auch die Angabe für den Input ( Hallsensor ) und Output für da Relais
da las sich den Programmierer Freie Wahl
Hat da Jemand Lust auf dieses Projekt und hilft uns dabei ?
Der Aufbau sollte so klein wie möglich sein ( Arduino ) wäre das mit einem arduino nano möglich ?

Danke

p.s. Habe Herausgefunden das man so was iwi einfügen müsste in ein Script

  • Routine für die Schwellwerteingabe hinzufügen
  • Ist-Wert mit Schwellwert vergleichen und Schaltimpuls ausgeben
  • Hysterese nicht vergessen, sonst flattert das Relais

aber wie und was das sein soll.........

Willkommen Bord!

So ganz ohne Eigeninitive wird's nicht gehen, also entscheide ob Du Dich einarbeiten möchtest oder nicht.
Wenn ja teile das Projekt auf:

  • Hallsensor lesen
  • Drehzahl berechnen, Ausgabe seriell
  • Digitalports ansteuern, werteabhängig
  • Display ansteuern
  • Taster abfragen (für Schwellwerte)
  • Variablen belegen für die Schwellwerte

Das sind alles keine großen Dinger und den Code bekommst Du mit der arduino IDE in den Beispielen mitgeliefert.

Und wenn's dann hakt: Code hier posten und gezielt fragen.
Aber vielleicht findet sich ja jemand, der Dir fertigen Code liefert.

Hallo,

hast du keinerlei Grundkenntnisse zum programmieren? Das wäre aber wichtig, selbst mit fertigen Code.
Sonst kannste das nicht einmal anpassen an geänderte Bedingungen.
Irgendwelche Grundlagen solltest du schon erlernt haben. Wie fragt man Pins ab, also wie liest man diese ein usw.
Mit millis() solltest du auch umgehen können zum blockieren freien pogrammieren. delay klappt hier nicht, eigentlich fast nie.

Taster abfragen solltest du selbst können. Und Werte auf einem Display anzeigen auch.
Taster entprellen mußte wenn du mit Taster eingaben machst, die Hallsensoren müssen nicht entprellt werden.
Danach kannste mit den Taster den Sensor simulieren und die Drehzahl berechnen lassen.
Das wäre so mein Gedanke Schritt für Schritt.

Versuche es wenigstens. Das ist dann auch für uns leichter jemanden zu helfen, weil man nicht bei Null anfangen muß.

Und genau das ist das Problem, ich habe keine ahnung wie man so was am Arduino Programmiert

besteht denn die Möglichkeit, sofern ich mir ein fertigen Code " Ausleihe " für die Drehzahlerfassung
ich habe diesbezüglich schon viel im Internet gesehen / gelesen, aber steh wie Ox vor dem Berge
Diesen dann von euch zu ändern ?

wenn ja, reicht ein Arduino nano, oder ist dieser mit einem Teensy 3.x kompatibel ?
aber an der Anschaffung eines Arduino soll es nicht scheitern

Das einzige was ich so lala Programmiert habe, waren meine Raspberry's mit Python und auch da mit sehr viel Hilfe. da Lese ich lieber Schaltpläne und Schwing den Lötkolben :smiley:

schon mal Danke für eure Antworten

Hallo,

du hast noch nichts da an irgendwelcher Hardware?
Kannst du den Code auf dem Raspi wenigstens nachvollziehen oder ist das alles ein rotes Tuch für dich?
Irgendwelche Bsp. Codes zu schreiben sollte nicht das Problem sein. Aber wenn du dann selbst nicht in der Lage bist den Code anzupassen, erfolgt ein endloses Debugging übers Forum. Das ist echt mühselig. Gerade bei sowas größeren und über die Ferne. Das Debugging ist immer das was am längsten dauert und einen langem Atem erfordert.

Wenn du bereit bist das selbst zu lernen, greifen wir dir aber gern unter die Arme.
Ein Arduino Uno ist sicherlich das Mittel der Wahl für den Anfang. Alles dran und alles drauf was man benötigt.
Den Rest an Bauteilen wirst du sicherlich da haben. Taster, LEDs, Widestände usw.
Der µC im DIP Gehäuse auf dem Board eignet sich besser, kann man zur Not bei defekt austauschen.
Und am Anfang empfehle ich das Original Genuino. Später kann man immer noch Klone kaufen.

In der IDE sind viele Bsp. drin. Ein Buch ist auch nicht falsch. Möchtest du dir das an tun?
Eines kann ich dir aber jetzt schon sagen. Das wird nichts von heute auf morgen.

Danke für die Info.
Ich bin experimentierfreudig, Keine Frage, am Raspberry habe ich selbstständig schon die Scripte für mich angepasst
z.b. einen DoorPI gebaut ( wenn es an der Tür klingelt, bekomme ich eine Nachricht ans Handy
und auch so gebaut das er als Coming Home Licht fungiert ( Bluetooth Erkennung der Handys und im Flur geht Licht an und aus )
Das aber unter Python , aber bis heute läuft alles wie ich es brauche , sogar die LCD anzeige :wink:

Das aber auch mit Viel Code geschnipsel und Hilfe

einen Teensy 3 als MAC hack gebaut (haben Kunden die vergessen gerne mal ihren 4 stellige PIN am Apfel MAC) der simuliert eben die Tastatur, und LCD display damit man sehen kann wo er gerade ist 0-9999
auch das mit Hilfe
Aber ich brauch eben ein Gerüst , alleine bin ich bei so was stricken hilflos.

Aber schon mal Gut das Hier jemand mir unter die Arme greifen würde
Ich werde mir dann man ein Nano besorgen
der kann dann ja auf eine Lochraster via Steckerleiste drauf gesteckt werden, so das dieser austauschbar ist falls der mal Himmelt.
dann schau ich mal ob ich teils fertige scripte finde das zumindest die Drehzahl angezeigt wird
ein LCD via Parallel oder I2C hab ich am Teensy gemacht, sollte am Uno ja genau so gehen
Dann schon mal Danke für den Anstoß, meine erste sorge war der fehlende Support
sobald ich den Uno habe und meine Vorläufige Schaltung, melde ich mich hier wieder

Hallo,

Python ist zwar nicht C. Aber das Grundkonzept ist immer gleich, auch wenn die Befehle anders lauten.
Irgendwas mußte dabei gelernt haben, denke ich.

Löse dich bitte vom dem Gedanken für alles auf der Welt Codeschnipsel zu finden. Damit kommt man nicht weit.
Wie schon erwähnt bringt die IDE viele Bsp. mit. Die durchgehen und verstehen lernen.
Hier gab es schon Leute die haben verschiedene Codeschnipsel zusammenkopiert und sich gewundert das nichts geht.

Logikplan erstellen, wie wann was passieren soll, dann Stück für Stück in Code umsetzen.
Man darf nur nich gleich am Anfang alles machen wollen. Teilaufgaben sind sinnvoll.
Paar Stolperfallen gibts immer, dafür ist das Forum da. Und sonst auch.

OK. Danke

Habe mir soeben Bestellt:
ATMEGA16U2 Version Uno R3 MEGA328P Board
ET Tastatur-Schild Blue-Board für Arduino LCD 1602 1280 2560
Standard- Hall- Magnetsensor -Modul für Arduino AVR PIC

somit sollte ich schon mal was machen können

Motor mit Magnet für den Hall-sensor ist vorhanden um zu Experimentieren

Moin moin,

So heute hab ich mal zeit gefunden um mein Arduino mit einem Display via I2C zu verbinden
habe auch versucht das Display was zum Anzeigen zu bewegen
Aber... der will die Liquidcrystal_i2c.h nicht. Egal wo ich die Hin kopiere. was läuft da schief ?
habe die Lib aus dem Internet in die Lib von Arduino kopiert, da exestierte schon eine, Aber jedes mal der Fehler das er die nicht findet

OK.... Ist Gelöst :slight_smile: ist ja wie damals Jugend Forscht ^^

und wenn nun noch da stehen würde, was die ursache war....

... wäre das ein netter Zug für die anderen.

Also, nach ein wenig den Herr von Google Nerven, stand da dan wie man die Lib einfügt
über sketch, Bibliothek einfügen ( ZIP ) funktionierte es :wink:

Somit hab ich mein erstes Display script über I2C am Laufen bekommen für mein Drehzahl messen Projekt
fehlt nur noch Interaktive Tasten einbinden und eben das Schalten eines Relais bei X UPM

Hier mal das Scrtipt:

// Drehzahlmesser
// -------------------------------------------------------------------
#include <Wire.h>
#include <LiquidCrystal_I2C.h>                // LCD i2c Library einbinden

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

void setup()                                  // Setup
{
 Serial.begin(9600);
 pinMode(2, INPUT);                          // Eingangspin auf Eingang stellen
 digitalWrite(2, HIGH);                      // und Pullup-Widerstand einschalten
 lcd.begin(16, 2);                           // Display hat 2 Zeilen a 16 Zeichen
 lcd.setCursor(0,0);
 lcd.print("-=- Drehzahl -=-");              // Überschrift ausgeben
 lcd.setCursor(0,1);                        // cursor an den Anfang der 2. Zeile
 lcd.print("** ???? U/min **");              // 2. Zeile ausgeben
 attachInterrupt(0, readmicros, RISING );    // Interrupt 0 auf Routine readmicros setzen
}

volatile unsigned long dauer;                 // microsekunden seit dem letzten Interrupt
volatile unsigned long lastm;                 // Zählerwert beim letzten Interrup
int drehzahl;                                 // selbstredend
uint8_t count;                                // 1-Byte Wert braucht kein volatile (atomic)
char buf[17];                                 // Pufferstring für sprintf

void loop() {                                 // Hauptprogramm
 unsigned long d;
 cli();
 if (count++ > 2) {                          // Inaktivitätszähler
   dauer = 0;
   d = 0;
 } else {
   d = dauer;
 }
 sei();
 drehzahl = d ? 60000000L / d : 0;           // Drehzahl ausrechnen und
 sprintf(buf, "%5u", drehzahl);              // als 5stellig formatierte Zahl in den Puffer
 lcd.setCursor(2, 1);                        // cursor an Position bringen
 lcd.print(buf);                             // Puffer ausgeben
 delay(300);                                 // 300ms warten
}

void readmicros() {                           // Interrupt-Routine
 unsigned long m = micros();                 // Microsekundenzähler auslesen
 if (m > lastm)                              // counter-wrap ignorieren
   dauer = m - lastm;                        // Differenz zum letzten Durchlauf berechnen
 lastm = m;                                  // Letzten Wert merken
 count=0;                                    // Inaktivitätszähler
}

Hallo,

Code bitte in Code Tags, erster Button links </>, dann verschwinden auch Smilies aus dem Codetext. Ist auch nachträglich möglich. Ich dachte mir schon das die .zip nur falsch entpackt war und umbennen usw. Naja, klappt doch schon ganz gut … :slight_smile:

Thx...

Habs Editiert

So, Hab das Script soweit angepasst das es macht was es soll, auch den Schwellwert bei 2700 hab ich via Variable gesetzt bekommen und auch am Display angezeigt

Aber wie und wo Bau ich die Tastenabfrage ein das diese auf + 50 und oder - 50 reagiert ?
soweit hab ich noch kein Codeschnipsel gefunden
geschweige richtig im code Platziere.

Neue version.

// Drehzahlmesser
// by Proto
// -------------------------------------------------------------------
#include <Wire.h>
#include <LiquidCrystal_I2C.h>                // LCD i2c Library einbinden

int maxU = 2700;

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

const int Eingang = 2;                        // Pin 2 ist Eingang für Sensor

const int AVG = 4;                            // Glättung über mindestens 4 Messwerte 

volatile unsigned long dauer=0;               // microsekunden seit dem letzten Interrupt
volatile unsigned long last=0;                // Zählerwert beim letzten Interrupt
volatile unsigned long average=1;             // Integrierte Dauer // =1: divide by 0 vermeiden
volatile int avgcnt=0;                        // Anzahl Messwerte im Puffer

void setup() {
  pinMode(Eingang, INPUT);                    // Eingangspin auf Eingang stellen
  digitalWrite(Eingang, HIGH);                // und Pullup-Widerstand einschalten

  lcd.begin(16, 2);                           // Display hat 2 Zeilen a 16 Zeichen
  lcd.print("Drehzahlmesser");                // Überschrift ausgeben

  attachInterrupt(0, readmicros, RISING );    // Interrupt 0 auf Routine readmillis setzen
}                                             // reagiert auf steigende Flanken an Pin 2

void loop() {                                 // Hauptprogramm
  char buf[17];                               // Pufferstring für sprintf
  unsigned long drehzahl=0;                   // selbstredend
  if (dauer != 0) {
    drehzahl = myround(60000000 / average);   // Drehzahl ausrechnen und runden
  } else {
    drehzahl = 0;                             // keine Messung? -> Stillstand
    avgcnt = 0;                               // entwerten des Average-Puffers
  }
  sprintf(buf, "%4lu/min ", drehzahl);        // als 5stellig formatierte Zahl in den Puffer schreiben
  lcd.setCursor(0, 1);                        // cursor an den Anfang der 2. Zeile (fängt mit 0 an)
  lcd.print(buf);                             // Puffer ausgeben
  lcd.print(maxU);                            // Max UPM Schwellwert zum schalten eines Relais ab xUPM
  lcd.print("Max");                           // Max UPM Anzeige Display
  dauer >>= 10;                               // Flag für Stillstand ( : 1024 )
  delay(500);                                 // eine halbe Sekunde schlafen
}                                             // mehr als zwei Werte pro Sekunde kann eh keiner lesen

void readmicros() {                           // Interrupt-Routine
  detachInterrupt(0);                         // Interrupt ausschalten damit er uns nicht beißt
  int avgmax;
  unsigned long us = micros();                // Microsekundenzähler auslesen
  if (last == 0) {                            // erster Messwert?  
    last = us;                                // merken und nicht weiter bearbeiten
  } else { 
    if ( us < last ) {                        // Zählerüberlauf
      dauer = 4294967295 - last + us;         // erzeugt einen Fehler von 1µS - vernachlässigbar
    } else {
      dauer = us - last;                      // Differenz zum letzten Durchlauf berechnen
    }
    if (dauer > 5000) {                       // ignorieren wenn <= 5ms (Kontaktpreller)
      average = dauer + average * avgcnt++;   // Wert in buffer und mit Faktor avgcnt glätten
      average /= avgcnt;                      // und zurückrechnen
      avgmax = 1000000 / dauer;               // dynamische Größe des Integrationspuffers
      if (avgmax < AVG) avgmax = AVG;         // Trägheit mindestens 1 Sekunde
      if (avgcnt >= avgmax) avgcnt--;
      last = us;                              // und wieder den letzten Wert merken
    }
  }
  attachInterrupt(0, readmicros, RISING );    // Interrupt wieder einschalten.
}

unsigned long myround(unsigned long value) {  // Gewichtete Rundung
  int rto;
  if (value > 3000) {                         // Rundungswert bestimmen  
    rto = 100;
  } else if (value > 1500) {
    rto = 50;
  } else if (value > 500) {
    rto = 10;
  } else if (value > 100) {
    rto = 5;
  } else {
    return (value);
  }
  return (_myround(value, rto));
}

unsigned long _myround(unsigned long value, int roundto) {
  value += (roundto >> 1);                    // halben roundto Wert addieren
  value /= roundto;                           // integer division  
  value *= roundto;                           // integer multiplikation
  return (value);
}

Hallo,

Taster hast noch keinen dran? Nur den Sensor?
Dann empfehle ich dir die Bounce2 Library zum Taster entprellen.

Dann nimmste 2 Taster und schließt diese direkt an 2 Pins an und den anderen Taster Kontakt gegen Masse.
Die sind dann logisch gesehen "low" aktiv.
Mit pinMode(BUTTON_PIN,INPUT_PULLUP); wird der interne Pullup Widerstand aktiviert, sodass du extern wirklich nur den Taster anschließen mußt. Die Gedanken muß man natürlich zusammen nehmen.
Dann schauste mal die Bsp. durch, ist nicht schwer zuverstehen.
Tja und dann zählst du auf Tastendruck hin, Statusvariable vom Taster abfragen s. Bsp.,
eine Variable hoch um 50 oder beim anderen Taster diese runter um 50.

Moin..

Danke für den Gedanken Anstoß
ich werde mir das mit den Bsp. mal genauer ansehen
der Gedankenweg mit der Lib hört sich gut an und werde mich da mal durchstöbern
genau solche Gedankentritte brauch ich :smiley: :slight_smile:
Zumindest läuft dank Codeschnipsel schon mal der Hallsensor und das Display mit der Berechnung der UPM

Also... das mit der tasten abfrage bekomm ich nicht hin.. ggf. zu doof :smiley:
wenn ich die variable Init maxU = 2700 eingebe
bleibt diese Fix auf 2700
egal ob ich am Testscript maxU + 50
oder maxU -50
(Tasten) drücke

:confused:

ggf auch nicht richtig umgesetzt das demo script

Hallo,

hier ist niemand zu doof, wir machen alle schlau und schlauer ... :slight_smile:
Nimm mal das Bsp. wo eine LED nur bei Tastendruck leuchtet, wenn Finger vom Taster LED wieder aus.
Da haste eine statusvariable drin. Die fragste auch ab, wenn ja um 50 hoch und beim anderen Taster runter.
Damit dir dein Zähler bei Tastendruck nicht sofort durch die Decke zählt, ist Kreativität gefragt. :wink:

Und probiere erstmal nur mit dem angepaßten Demo Sketch. Nicht gleich ins Projekt einbauen. Erst wenn das verstanden ist und funktioniert.

Edit:
das Retrigger Bsp. sollte am Besten passen. Guck dir das mal genau an ...
Das ist mit "durch die Decke zählen" auch gleich gelöst.

Ich habe mir ja das mit der LED rausgesucht
Das es nichts bringt gleich in mein Projekt ein zu binden ist mir ja klar :wink:

Aber ich als Nichtprogrammierer weiß größtenteils Nicht was da abläuft
wie soll ich denn das als Ahnungsloser so umbauen das anstelle eine LED (Hardware)
eine Software raus und Runter zählt ?

Das script was ich da zzt. fertig habe stammt ja auch aus Anderen quellen wo das also quasi fertig ist
Ich nur soweit zusammengefügt habe das es so funktioniert

Aber da ich keinen Schimmer habe wie ich nun 2 tasten abfrage um eben einen Softwarezähler zu Rauf oder Runter springen zu lassen.
Variable hin oder her.... mit der LED ist ja gut, aber Wie geht das mit Variablen...

und dann das Problem an welcher stelle das eingebunden werden muss
Meine Experimente führen ins Leere oder das Display blinkt Fix mit meiner variable 2700 am Display