Drehzahl messen

vor 33 weeks 18 hours von shr4pnell

Hallo,

Ich würde gern die Drehzahl meines alten Audi 80 mit dem Arduino erfassen. Von einem der Stecker für den Tacho kann man aus 2 Pins ("Signal Drehzahlmesser" und "Minus Drehzahlmesser") sicherlich das Signal abfassen. Also hab ich mir gedacht, ich verkabel vom Pin "Signal DZM" ein Kabel zu einem der analogen Eingänge und ein Kabel vom "Minus DZM" Pin zum GND vom Arduino. Dann müsste ich doch die Drehzahl messen können?
Wie kann ich das Drehzahlsignal in eine Drehzahl umrechnen ? Ich müsste doch nur mit AnalogRead() die Zündsignale erfassen und dann immer innerhalb einer Sekunde alles zählen oder ?

Ähnliche Posts

11 Antworten auf “Drehzahl messen”


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
  1. Spot sagt:

    Hallo

    Weißt du in welcher Form das Signal geliefert wird? Bist du dir sicher das es sich dabei um das Zündsignal handelt? Wenn ja ist das dann nur von einem Kolben oder der Steuerimpuls für die Zündspule? Ich kann mir eigentlich fast nicht vorstellen das die Drehzahl über ein Zündsignal bestimmt wird, das würde ja dann heißen das es bei Dieselmotoren nicht funktioniert und ich da dann wieder ein anderes System brauche. Ich vermute eher das das Signal für den Drehzahlmesser von einem Hallsensor der irgendwo an der Kurbelwelle sitzt kommt. Das Signal wird aber möglicherweise vom Steuergerät noch für die Anzeige aufbereitet. Es ist also so einiges an Signalformen auf der Leitung möglich.

    Ich denke mal es sind entweder Impulse oder ein Analogwert der an den Drehzahlmesser geliefert wird.
    Bei einem Analogwert gehst du auf einen Analogpin, vorher musst du unter Umständen das Signal anpassen(0- max. 5V je nach Ardunio).

    Bei Impulsen ist es einfacher wenn du auf einen Interrupt Eingang gehst. Da kannst du dann einfach die Impulsanzahl bzw. den Impulsabstand bestimmen.

    Beim Umrechnen kann ich dir nur ein paar pauschale Hinweise liefern da ich das Signal ja nicht kenne.

    Bei Impulsen ist es relativ einfach, da misst du einfach den Abstand zwischen zwei Impulsen(was dann hoffentlich einer Umdrehung der Kurbelwelle entspricht) und aus der Zeit für eine Umdrehung kannst du dann Ausrechnen wie viele das dann in der Minute sind.

    (( 1 / Zeit für eine Umdrehung in ms) * 60000 ) = U/min

    Wenn es sich um einen Analogwert handelt sieht die ganz anders aus. Vermutlich steht dann jede Spannung für eine bestimmte Drehzahl. Du musst deine Rechnung dann dem entsprechend auf deine Skalenfixpunkte auslegen, bzw. kalibrieren.

    Da ich mir jetzt hier nicht die Finger Wund schreiben mag solange ich noch nicht weiß ob du das ganze wirklich brauchst, schlage ich vor du meldest dich nochmal wenn es sich tatsächlich um ein Analogsignal handelt.
    mfg

    Login or register to post comments

  1. shr4pnell sagt:

    Danke für die Antwort!
    Ich habe gelesen, dass es sich um eine Rechtecksignal (oder Sägezahn, was ich nicht glaube) handeln soll. Ich werd das jetzt das Wochenende mal testen.
    Ich denke nicht, dass das Signal schon aufbereitet kommt, da man die Anschlüsse auf eine Platine stecken muss, die hinter dem Tacho verbaut ist. Auf der Platine wird das Signal sicherlich aufbereitet und dann angezeigt.
    Das mit dem Interrupt klingt gut. Mit AttachInterrupt leg ich mir ne Interrupt-funktion an und dort speicher ich mir einen Zeitwert und beim nächsten Aufruf wieder den Zeitwert. Bilde in der Interrupt-funktion die Differenz und rechne über die Formel die Drehzahl aus. Läuft dann die Loop-funktion parallel oder wird die angehalten, wenn ein Interrupt auftritt?

    Gut, ich würde dann einfach den Tacho ausbauen, den Motor anmachen und ein wenig Gas geben, dann müsste ich, wenn ich ein Multimeter an die 2 Pins halte, doch sehen, ob die Spannung varriert wird oder? Und wenn ich nichts sehe, dann kommt sicherlich ein einfaches Rechtecksignal an oder?

    Login or register to post comments

  1. Spot sagt:

    Hallo

    Besser als ein Multimeter wäre natürlich ein Oszi, da ich aber mal vermute das du keins rumstehen hast muss es auch mit dem Multimeter gehen.
    Bei einem Rechtecksignal wird dir wahrscheinlich auch eine kleine Spannung angezeigt die aber immer ein bisschen "wackelt" und sich nicht so stark ändert wenn du Gas gibst.
    Bei einem Analogwert wirst du ein sauberes Signal von vermutlich 0 - 12V messen.

    Ein (Single Core)Prozessor kann immer nur an einer Stelle des Programms arbeiten. Das Programm springt egal wo es gerade war in die ISR wenn ein Interrupt erfolgt. Das passiert dir übrigens auch jetzt schon ständig ohne das du es merkst, die Timer(millis(),PWM,...) funktionieren ja auch über Interrupts. Nach ausführen der ISR springt er an die Stelle vom Programm an der er gerade Stand bevor der Interrupt ankahm.

    mfg
    Spot

    Login or register to post comments

  1. shr4pnell sagt:

    Also hab mich mal mit nem billig Multimeter rangesetzt.
    Wie du schon geschrieben hast, konnte ich ne Spannung von 8.92 V messen. Sobald ich Gas gegeben habe, hat die leicht angefangen zu schwanken. Komischerweise musste ich als Masse die Karosserie benutzen. Irgendwie wollte beim zweiten Pin kein Strom fließen.
    Ich werd am Wochenende mal ein Testprogramm schreiben und schauen, was er so erfasst :)
    Um die Interrupt-funktion nutzen zu können, muss das Signal doch an einen bestimmten Pin angelegt werden. Laut Google ist das der Pin 2. Das der digital ist, stört doch nicht oder ?

    Login or register to post comments

  1. Spot sagt:

    Hallo

    Nein Stört nicht dein Signal ist ja auch digital und selbst wenns ein analoges wäre wird auch nichts kaputt, es funktioniert hald dann einfach nich so wie du es dir vorstellst.

    Zu den Pins kann ich jetzt nur die Arduino Reference zitieren da ich nicht weiß welchen du hast.

    http://arduino.cc/en/Reference/AttachInterrupt wrote:
    Most Arduino boards have two external interrupts: numbers 0 (on digital pin 2) and 1 (on digital pin 3). The Arduino Mega has an additional four: numbers 2 (pin 21), 3 (pin 20), 4 (pin 19), and 5 (pin 18)

    mfg
    Spot

    Login or register to post comments

  1. shr4pnell sagt:

    Sehr gut, ich versuch schon mal heute abend es zu testen :)

    Hab den arduino duemilanove. Ich steck das Signalkabel dann einfach an den Pin 2.

    Login or register to post comments

  1. Spot sagt:

    Hallo

    Nicht vergessen die Massen zu verbinden!

    mfg
    Spot

    Login or register to post comments

  1. shr4pnell sagt:

    So ich habs hinbekommen :) Allerding mit etwas Umweg :D Jetzt fehlt nur noch der Feinschliff vom Programm.
    Also ich hatte zunächst alles wie besprochen verkabelt. Leider hatte er da nichts gezählt. Zum Glück war mein Mitbewohner da, der ein Oszilloskop hat, da. Gleich mal angeschlossen und geschaut. Das Signal war in der Tat ein Rechtecksignal. Jedoch nicht von 0 bis 5 Volt, sondern von -8 oder 9 bis +12/13 Volt. Dann hab ich mir auf meinem Steckbrett einen kleinen Schaltkreis gebastelt. Mit ner Diode den Minusteil vom Signal entfernt. Das restliche Signal schaltet einen Transistor mit 5Volt vom Arduino. Die passenden Widerstände hab ich mit drauf gesteckt. Und siehe da, er zählt etwas :D Das Problem ist nun die zeitliche Synchronisierung. Ich hatte es erst mit millis(); probiert, aber irgendwie hat das Skript nicht funktioniert:

    int count;
    int saved=false;
    int diff=0;
    int zeit=0;
     
    void setup()
    {
    Serial.begin(9600);
    attachInterrupt(0, reaktion, HIGH);
    }
     
    void loop()
    {
     if(saved=false)
     {
     zeit=millis();
     saved=true;
     }
     diff=millis()-zeit;
     if(diff>1000)
     {
     Serial.println(count);
     count=0;
     saved=false;
     }
    }
     
    void reaktion()
    {
    count++;
    }

    Das Problem war, das er nie die Sekunde "abgewartet" hat. Zu Beginn hat er die Zeit gewartet und dann hintereinander weg 0 ausgegeben.

    Mit dem folgenden jetzt aktuellen Code gibt er angenehme Werte für die Drehzahl aus, wenn man davon ausgeht, das er im Leerlauf ca. 900 Umdrehungen macht.

    int count;
    int a=0;
    int i=0;
    int b=0;
     
    void setup()
    {
    Serial.begin(9600);
    attachInterrupt(0, reaktion, HIGH);
    }
     
    void loop()
    {
     i=0;
     
     while(i<=10)
     {
       a=0;
       while(a<=30000)
       {
       a++;
       b=0;
       while(b<=30000)
       {
       b++;
       }
       }
     i++;
     }
     
     Serial.println(count*90);
     count=0;
    }
     
    void reaktion()
    {
    count++;
    }

    Die Frage ist nun, wie kann ich das Programm exakter und "professioneller" gestalten? Oder wo ist das Problem mit dem millis();? Ich hatte gelesen, dass bei einem Interrupt millis nicht verwendet werden darf. Aber ich dachte das gilt nur für die Funktion, die durch das Interrupt aufgerufen wird oder?

    Login or register to post comments

  1. Spot sagt:

    Hallo

    Ganz einfacher Fehler! ;-)

     if(saved=false)
     {
    .
    .
    .

    probiere mal

     if(saved==false)
     {
    .
    .
    .

    = weist den Wert zu, == vergleicht!

    Zu deinem Programm mit der Warteschleife, du zählst ja da umgerechnet bis 900.000.000. Da ist der kleine aber schon ein bisschen beschäftigt. Was du damit bewirkst das du deine Interrupts mit 90 multiplizierst verstehe ich auch nicht ganz.

    Der Ansatz mit den millis war schon gut es hat sich eben nur ein Fehler eingeschlichen. Ich hab dir schnell einen Beispielcode geschrieben, der ist aber nicht getestet:

    unsigned int uiInterruptCount=0;
    unsigned long ulTimeHelp, ulMillisHelp;
     
    void setup()
    {
        Serial.begin(9600);
        attachInterrupt(0, reaktion, RISING);
        ulTimeHelp = (millis() + 1000);
    }
     
    void loop()
    {
        ulMillisHelp = millis();
        if(ulTimeHelp <= ulMillisHelp)
        {
            Serial.println(uiInterruptCount);
            uiInterruptCount=0;
            ulTimeHelp = (ulMillisHelp + 1000);
        }
    }
     
    void reaktion()
    {
        uiInterruptCount++;
    }

    Ganz professionell ist das ganz so auch nicht, dafür müsste man noch den Überlauf von den millis abfangen. Da der aber nur alle 50 Tage einmal auftritt spare ich mir das.

    mfg
    Spot

    Login or register to post comments

  1. shr4pnell sagt:

    Super! Wunderbar :) Ich nehm jetzt nur noch uiInterruptCount durch 4 (4Zylinder) und mal 60, dann hab ich die exakte Drehzahl :)
    Vielen Dank für die Hilfe und den support!

    Login or register to post comments

  1. Spot sagt:

    Bitte bitte kein Problem! Man hilft doch gerne wenn man kann.

    mfg
    Spot

    Login or register to post comments