Motordrehzahl am Arduino auswerten (primär Elektronik Frage)

Hallo zusammen.

Ich möchte mich heute mit einer Frage an Euch richten, die eher ein Elektronik Problem ist, als ein programmier-technisches.
Ich habe an einem Boot nen Honda Außenborder und möchte die Drehzahl des Motors am Arduino einlesen. Der Honda besitzt dafür extra einen Anschluss, der normalerweise für Drehzahlmesser von Honda vorgesehen ist. (Ich brauche aber die Drehzahl am Arduno, da ich diese mit verschiedenen anderen Daten loggen will)

Ich habe ein kleines Video gemacht, das den Verlauf am Ozzi, abhängig von der Drehzahl darstellt. Siehe Link:

Wie man sieht, ist sowohl die Spannung als auch die Frequenz von der Drehzahl anhängig. Im Leerlauf habe ich ein Frequenz von ca 100 Hz und eine Spannung Peak to Peak von ca 80 Volt.
Bei maximaler Drehzahl etwas 500 Hz sowie Spannung Peak to Peak von ca 230 Volt.

Jetzt ist die Frage, wie ich das am besten im Arduino auswerte?
Die 2 Möglichkeiten sind, entweder die Spannung zu messen oder die Frequenz.
Welche Methode würdet ihr wählen?

Die Spannung auszuwerten wäre von der vorgeschalteten Elektronik sowie Programmierung sicher einfach zu realisieren. Meine Idee wäre ein Brückengleichrichter sowie ein Spannungsteiler 230 -> 5 Volt.

Die Messung via Frequenz wäre sicher genauer. Messfehler durch den Spannungsteiler und Gleichrichter wären hier ausgeschlossen. Jedoch muss ja hier mein Arduino über einen bestimmten Zeitraum die Frequenz am Eingang messen, und während der Zeit kann er ja nicht anderes machen, oder?

Zusätzlich ist mir hier nicht ganz klar, wie die vorgeschaltete Elektronik aussehen muss. Ich dachte an einen Spannungsteiler, sowie Zener Dioden um die Spannung konstant bei 5 Volt am Ausgang zu halten, sowie einen Nachgeschalteten Opto Koppler um den Arduino vor Störungen zu schützen…

Vielen Dank schon mal für Eure Hilfe
Gruß Michl

Ich würde die Frequenz auswerten. Meine Schaltungsidee dazu: Signal mit einer Diode einweggleichrichten und die hohen Spannungen mit einer Z-Diode eliminieren. Das resultierende Signal auf einen Optokoppler zur galvanischen Trennung geben und mit dem Arduino auswerten.
100 bis 500 Hz sollten auch noch per Polling funktionieren, man könnte ebenso eine externen Interrupt verwenden, der auf die steigende Flanke getriggert wird.

[edit] Eventuell sollte man noch die Flankensteilheit mit einem Schmitt-Trigger erhöhen.
Bin auch für anderslautende Ideen dankbar, scheint ein interessantes Projekt zu sein. Inwieweit man von der Frequenz auf die Drehzahl schließen kann, musst du noch herausfinden. 100-500 Hz sind ja nicht 100 bis 500 Umdrehungen pro Minute, sondern gefühlt eher das 10fache.

Auf alle Fälle die Frequenz!

Das ist ein klassischer induktiver Signalgeber, also eine Spule mit Magnet, an der eine Markierung am Schwungrad vorbeirauscht. Dadurch bekommst du natürlich eine höhere Spannung mit höherer Drehzahl, schliesslich ist das ja sowas wie ein generator.

Die eigentliche Information steckt aber in der Frequenz.
Das hier sieht nach 6 Pulsen pro Umdrehung aus.

Schaltung:
Spannungsteiler => Begrenzer (2 Schottkys) => Arduino.

Die Pulse über einen Interrupt zählen und in einer Zeitscheibe auswerten.

Edit:
Mir war so, dass ich da schon mal so was hatte. kram kram
Gefunden!
Ein Sketch zum frequenz messen. Denn kannst du unkompliziert auf Drehzahl umschreiben.
Achtung: delay() ist verboten!

Frequenz_messen.ino (1.12 KB)

Hi und vielen Dank für die Antworten:

Ja, stimmt, das hatte ich vergessen zu erwähnen, sind 6 Pulse. Aber das ist ja dann nur eine Umrechnung.

Vielen Dank für das Beispiel und die Bauvorschläge.

Bei der Frequenzmessung sehe ich ein Problem (bei mir), daher auch die Idee, mit der Spannungsmessung. Bitte verbessert mich, wenn ich falsch liege:

Warum ein Problem:

Die Dauer der Frequenzmessung muss ja mindestens 2 x die 1/Frequenz sein, wenn ich richtig liege, eher mehr um ein ordentliches Ergebnis zu bekommen.

Das würde also im Leerlauf (100Hz) mindestens 20 ms benötigen, in dem der Arduino nix anderes macht, als die Messung, oder?

Das Problem ist, das der Arduino bei mir viele Aufgaben in besagtem Boot erledigt. Vor allem regelt er über ne IMU und 4 Aktuator gesteuerte Flügel, die Lage des Bootes im Wasser. (Ist ein Tragflügelboot)
Ich weiß jetzt nicht genau, ob ich ein Problem bekomme, wenn in dieser Zeit nix anderes passiert…

Was meint Ihr?

Du kannst die Frequenz auch in Hardware messen. Die Timer haben dafür extra einen Eingang um sie extern zu takten. Und ein anderen Modus der automatisch die Zeit zwischen zwei Signalen an diesem Eingang misst (Input Capture).

Diese Library macht ersteres für dich:
https://www.pjrc.com/teensy/td_libs_FreqCount.html

Hat aber den Nachteil, dass dadurch viele PWM Pins verloren gehen. Die Library belegt nämlich zwei Timer. Einen für die Torschaltung und einen fürs Zählen.
Das kann man auch einfach per Hand machen. Dann braucht man nur den Timer fürs Zählen und macht die Torschaltung mit millis(), und es fallen 2 oder 3 PWM Pins weg.

Alternativ kann man auch die Puls-Länge messen:
https://www.pjrc.com/teensy/td_libs_FreqMeasure.html

Das belegt auch nur einen Timer und ist gerade für langsamere Signale besser.

TEC_MICHL:
Das würde also im Leerlauf (100Hz) mindestens 20 ms benötigen, in dem der Arduino nix anderes macht, als die Messung, oder?

Würdest du die Zeit mit pulseIn() messen, stimmt deine Annahme. Für die vorgeschlagene Variante über externe Interrupts trifft dies jedoch nicht zu. Alternativ könntest du auch einen separaten Mikrocontroller ausschließlich für die Drehzahlmessung abstellen, der seinerseits mit dem Hauptcontroller in Verbindung steht (I2C oder seriell).

Frequenz, wir die anderen schon gesagt haben. Auch noch eine Möglichkeit den Optokoppler anzusteuern wäre über einen hinreichend spannungsfesten Kondensator als Blindwiderstand :grin:
Bei den von dir geschilderten Frequenzen und Spannungen würde ich einen 330n 630V Kondensator nutzen. Dahinter dann eine kleine Gleichrichterbrücke und an deren Ausgangsseite dann die LED des Optokopplers mit 220 Ohm Kohleschichtwiderstand Kohleschicht deswegen, wenn der Kondensator durchschlägt, soll der Widerstand kontrolliert abbrennen und den Strom unterbrechen :wink:
So bekommst du beide Halbwellen mit, also 2 Impulse pro Umdrehung. Alternativ kannst du auch die Gleichrichterbrücke weglassen und nur eine Diode antiparallel zum Optokoppler nehmen, dann hast du nur eine Halbwelle und schließt die andere HW kurz und liest 1 Impuls pro Umdrehung.

Gruß Gerald

Hmm, die vorgeschlagen externe Variante von Serenifly wäre perfekt, wenn ich nicht so viele PINS verlieren würde, da ich auf meinem Brett schon fast alle Pins belegt habe... Gehe ich richtig der Annahme, dass die PINS nur nicht als PWM Ausgang verwendet werden können, ansonsten aber schon?

@Serenifly: Kannst Du mir das kurz erklären, wie ich das per Hand machen kann:

Das kann man auch einfach per Hand machen. Dann braucht man nur den Timer fürs Zählen und macht die Torschaltung mit millis(), und es fallen 2 oder 3 PWM Pins weg

@sth77 oder guntherb

Für die vorgeschlagene Variante über externe Interrupts trifft dies jedoch nicht zu.

Bezieht sich diese Aussage jetzt auf den Post von Serenifly oder das Beispiel von guntherb?

@nix_mehr

Danke für Deinen Vorschlag, das klingt recht solide. Muss ich mir mal aufzeichnen, ganz ist mir dass noch nicht klar... :cold_sweat:

Schönen Abend noch!

Probier am besten erst mal externe Interrupts. Das ist einfacher als Timer - da du die Arduino Mittel verwenden kannst - und die Interrupts sollten bei dir nicht so oft kommen sollten dass sie deinen Programm-Ablauf groß stören.

Einfach mit attachInterrupt() eine Variable hochzählen lassen. Die Torzeit machst du mit millis(). Am Anfang die Variable auf 0 setzen und am Ende der Torzeit auswerten.

Falls der Rest deines Programms gestört wird weil die Interrupts doch zu oft kommen, kann man weiter sehen.

Gehe ich richtig der Annahme, dass die PINS nur nicht als PWM Ausgang verwendet werden können, ansonsten aber schon?

Korrekt.

Das ist für die Timer-Variante. Bei Interrupts ändert sich nichts und es ist einfacher zu programmieren. Aber dein Programm wird halt bei jedem Impulse kurz unterbrochen. Bei langsamen Signalen ist das nicht unbedingt schlimm. Muss man ausprobieren.

Probiert doch einfach mal den Sketch aus, den ich oben angehängt habe.

Ich denke, du hast nicht verstanden, wie er funktioniert:

Eine Interruptroutine wird durch den externen Pin getriggert.
Die macht nix anderes, als eine Variable zu incrementieren.

void ISR_f(){
  count++;
}

Das dauert maximal 200ns.

Und in der Loop fragst du im festen Rythmus (hier 200ms) ab, wieviele Pulse ankamen.

 if ( millis()-Timestamp > 200){
     noInterrupts();
     f = (count * long(1000))/ 200;
     count = 0;
     Timestamp = millis();
     interrupts();
   }

Also die Frequenzmessung blockiert deinen Arduino überhaupt nicht!

Aber du hast in sofern recht, als die Frequenzmessung nur funktioniert, wenn jeder Interrupt sauber durchkommt und die loop schnell genug durchlaufen wird. ein einziges delay() kann alles kaputtmachen.

Edit: Serenifly war schneller.

Na, ja, etwas länger als 200ns wird es schon sein. Bei einem Interrupt wird erst mal in die Interrupt-Vektor Tabelle gesprungen und dort steht ein Sprung in eine Funktion. Und wie bei einer normalen Funktion müssten Daten auf dem Stack gesichert werden. Das kostet schon ein klein wenig Zeit.

Hallo,

das ist doch Krümmelkackerei. Ob nun mehr oder weniger als 200ns ist doch bei seinen max. 500Hz egal. Das wäre bei ihm eh aller 2ms ein Interrupt. Während 2ms kann der µC viele andere Dinge machen.

Ist schon klar, dass es egal ist solange die Frequenz nicht zu hoch wird.

Hallo zusammen, nach einer langen Zeit!

Nach ein paar Monaten der abstinenz will ich mich nun wieder ein bissl dem Thema widdmen. Hab das Thema hier leider nie zu Ende gebracht. Das will ich jetzt unbedingt noch tun.

Auf Arduinoseite hab ich mir das alles angesehen und es klappt bestens. (Im Moment aber nur mit nem taster)

An der Schaltung an sich habe ich mich noch nicht versucht, da habe ich noch ein, zwei Fragen:

Ich bin im bereich der Wechsel/Hochspannung nicht soooo fit. Daher wollte ich zu euren Bauvorschlägen noch einmal zurück kommen.

Drei Vorschläge waren es ja:

Schaltung:
Spannungsteiler => Begrenzer (2 Schottkys) => Arduino.

Frequenz, wir die anderen schon gesagt haben. Auch noch eine Möglichkeit den Optokoppler anzusteuern wäre über einen hinreichend spannungsfesten Kondensator als Blindwiderstand :grin:
Bei den von dir geschilderten Frequenzen und Spannungen würde ich einen 330n 630V Kondensator nutzen. Dahinter dann eine kleine Gleichrichterbrücke und an deren Ausgangsseite dann die LED des Optokopplers mit 220 Ohm Kohleschichtwiderstand Kohleschicht deswegen, wenn der Kondensator durchschlägt, soll der Widerstand kontrolliert abbrennen und den Strom unterbrechen.

Meine Schaltungsidee dazu: Signal mit einer Diode einweggleichrichten und die hohen Spannungen mit einer Z-Diode eliminieren. Das resultierende Signal auf einen Optokoppler zur galvanischen Trennung geben und mit dem Arduino auswerten.

Welche würdet Ihr bevorzugen. (Nen optokoppler auf jeden Fall)

Und gibts irgendwo Beispielschaltungen? Bilder, und wie ich die Bauteile berechnen kann? mir ist bei manchen Schaltungen nicht ganz klar, wie ich das zusammen löten soll...

Vielen Dank schon mal für die Antworten!! Gruß Michl

Hallo,

ich werf mal meine Idee in die Runde.

einen Trafo/Übertrager mit 10:1 Untersetzung. Aber der muß 120V~ am Eingang verkraften. Hab jetzt nur Übertrager bis 100V gesehen. Außer Du fährst nie Vollgas. :wink: Danach eine Diode zur Einweggleichrichtung. Nach der Diode bist im ungefährlichen Gleichspannungsbereich von 4 bis 12V. Wenn ich Deine Oszi Meßdaten richtig interpretiere. Die noch sinusförmige Halbwelle, würde ich dann mit einem Optokopler an dessen Transistor gleichzeitig als Spannungswandler auf 5V Level bringen und dann mit einem OPV als Komparator in ein Rechtecksignal wandeln.

Das wäre (m)ein Vorschlag.

Doc_Arduino:
einen Trafo/Übertrager mit 10:1 Untersetzung.

Das könnte funktionieren, ist aber übertrieben.
Das ist ja keine energiereiche Wechselspannung, sonder letztlich eine Spule mit Magnet, an der ein Stückchen Eisen vorbeisaust.

ich würde das so probieren:
Zwischenablage01.jpg

R1, um den Strom durch den Optokoppler zu begrenzen, D1 um den Optokoppler vor der negativen Halbwelle zu schützen.

Bei den im Video gezeigten Spannungen sollte das ausreichen.
Allerdings waren das im Video unbelastete Spannungen, die Impedanz des Sensors ist unbekannt.
Falls die Schaltung bei höheren Drehzahlen funktioniert, bei niedrigen nicht, muß R1 kleiner werden.

Hallo,

könnte funktionieren, wenn das Signal nicht zusammenbricht. Aber das würde bei meiner Idee auch zusammenbrechen wenn die Belastung zu groß ist. Das Problem ist die hohe Wechselspannung.

Ich glaube wir können uns sonstwas ausdenken. Es wird an der Belastung durch den Optokoppler scheitern oder auch nicht. Er müßte mal probieren, was passiert wenn er es Stufenweise mit bis zu 5mA belastet. Aber mach sachte, sind ja schließlich bis 120V~ und Wasser in unmittlerbarer Nähe !

Edit:
ich frage mich gerade, was sich der Typ beim Hersteller dabei gedacht hat, so einen Drehzahlsensor in den Motor zubauen. Was hat der sich dabei gedacht das Signal wie auszuwerten? Oder es war nie vorgesehen das zu nutzen.

Doc_Arduino:
ich frage mich gerade, was sich der Typ beim Hersteller dabei gedacht hat, so einen Drehzahlsensor in den Motor zubauen. Was hat der sich dabei gedacht das Signal wie auszuwerten? Oder es war nie vorgesehen das zu nutzen.

Das ist Standard.
Ich bin mir völlig sichern auch der Motor in deinem Auto hat diese Art von induktiven Sensoren. Die Spannung ist kein Problem, weil keine Leistung dahinter steckt. (Bei den Zündkerzen ist die Spannung noch höher!)

die Auswerteschaltungen dazu sind auch entsprechend verfügbar, sind aber meist komplizierter, weil es hier um die exakte Erfassung des Nulldurchganges geht, was hier ja nicht nötig ist.

Die Gefahr der oben geposteten Schaltung ist, dass sie dass originale Signal des Sensors leicht verfälscht und damit die Funktionsweise des Motors stören könnte. Die Motorelektronik braucht dieses Signal ja auch.

Moin,
eine ganz andere Herangehensweise wäre,
einen Neodym-Magnet auf einem drehenden Teil des Motors anzubringen.
Dann mit einem Hall-Sensor die Drehzahl einlesen.

Gruss
Kurti

kurti:
einen Neodym-Magnet auf einem drehenden Teil des Motors anzubringen.
Dann mit einem Hall-Sensor die Drehzahl einlesen.

Bei schnell drehenden Motorteilen was draufpacken endet meist mit einer bösen, zerstörenden Unwucht. Das würde ich lassen.

Was allerdings funktionieren könnte: das Zündsignal kapazitiv (berührungslos) abgreifen. Das habe ich allerdings noch nie gemacht.