Forum: Projekte & Code einfache Drehzahlmessung mit ATmega88


von m.n. (Gast)


Angehängte Dateien:

Lesenswert?

Anbei eine Schaltung und ein Programm für einen einfachen 
Drehzahlmesser. Das Programm wurde unter AVR-Studio 4.18 entwickelt. Zum 
Einrichten eines eigenen Projektes reicht die angehängte .c-Datei sowie 
die Einstellungen  F_CPU = 2000000 sowie CPU = ATmega88. Die 'fuses' 
werden für max. ext. Quarz gewählt und BOD auf 4,3V gesetzt.

Die Schaltung ist einfach: sie besteht aus einem ATmega88, einer 
LC-Anzeige 2x16 und wenigen passiven Bauteilen besteht.
Das Programm ist einfach: eine einzige .c-Datei, die mit den 
Grundeinstellungen des AVR-Studio übersetzt wird.

Das Programm:
Gemessen wird im Grunde die Eingangsfrequenz; angezeigt werden Drehzahl 
("D") und Zeit_pro_Umdrehung ("T") als 6-stellige Werte (gerundet). Die 
Berechnungen werden mit den 'float'-Routinen des AVR-GCC durchgeführt; 
das Programm benötigt ca. 5,4KB Programmspeicher.
Gemessen wird lückenlos - jede Sekunde ein neuer Wert bei 60 rpm - und 
angezeigt werden maximal drei Ergebnisse/s; eine LED signalisiert eine 
fertige Messung.

Zur Schaltung:
Der Prozessor ist mit der Anzeige gemäß Schaltbild verdrahtet; die 
Pinbelegung ist 'historisch' gewachsen (beruht auf einem abgemagerten 
Frequenzzähler).
Das Eingangssignal wird über den analogen Komparator dem ICP des Timer1 
zugeführt. Das hat den Vorteil, dass die Eingangsbeschaltung variabel 
ausgelegt und bei Bedarf die Eingangsempfindlichkeit auf einige 10mV 
erhöht werden kann. So lassen sich z.B. R4 und C3 als Widerstände 2M2 
bestücken und D1 gegen einen Kondensator 100nF austauschen, wenn sehr 
kleine Drehzahlen nicht erwartet werden.

An anderer Stelle befindet sich noch ein Vorschlag für eine 
Eingangsstufe, mit denen man auch unsaubere Eingangssignale für die 
Drehzahlmessung aufbereiten kann. 
Beitrag "Eingangsstufe für Frequenzzähler DC-50MHz, +5V"

von m.n. (Gast)


Angehängte Dateien:

Lesenswert?

Geschickterweise hänge ich noch die .hex-Datei an. Und wem dies nicht 
reicht, programmiere ich auch gerne zugeschickte Prozessoren im 
DIL28-Gehäuse.

von Dennis S. (bzzzt)


Lesenswert?

Der Code ist ja noch einfacher als ich dachte, vielen Dank!

von Lukas (Gast)


Lesenswert?

Hallo,
folgender codeausschnitt verstehe ich nicht ganz:
1
  for(;;) {
2
    if(mess_status==MESSEN  && mess_dauer >= MESSZEIT) {
3
      mess_status=AUSLESEN;      // Auswertung starten
4
      mess_dauer = 0;        // wieder Messzeit abwarten
5
    }
6
    if(mess_status==AUSWERTEN) {
7
      end_zeit = zeit_high*0x10000 + zeit_low;
8
      mess_zeit = end_zeit - start_zeit;        // Zeit-Differenz bilden
9
      start_zeit = end_zeit;    // neue startzeit merken
10
      mess_ereignisse = end_ereignis - start_ereignis;  // Impuls-Differenz
11
    start_ereignis = end_ereignis;// fuers naechste Intervall
12
      mess_status = MESSEN;      // wieder warten
13
      if(messwert_vorhanden) {
14
    led_cnt = LED_EIN;      // LED-Zeit vorgeben
15
    frequenz = ((float)mess_ereignisse * F_CLOCK) / mess_zeit;  // Frequenz berechnen
16
    lcd_cmd(ZEILE1+5);      // 1.Zeile, 5.Spalte
17
    zeige_x(frequenz,0);    // Drehzahl anzeigen
18
    lcd_cmd(ZEILE2+5);      // 2.Zeile, 5.Spalte
19
    zeige_x(frequenz,1);    // Zeit/Umdr. anzeigen
20
      }
21
      else messwert_vorhanden = 1;  // sperre wieder aufheben
22
  }
23
  }
24
  return(815);
25
}
26
27
    lcd_cmd(ZEILE1+5);      // 1.Zeile, 5.Spalte
28
    zeige_x(frequenz,0);    // Drehzahl anzeigen
29
    lcd_cmd(ZEILE2+5);      // 2.Zeile, 5.Spalte
30
    zeige_x(frequenz,1);    // Zeit/Umdr. anzeigen

gibst du damit nicht auf beiden Zeilen das selbe aus?

mfg
Lukas

von m.n. (Gast)


Lesenswert?

Lukas schrieb:
> gibst du damit nicht auf beiden Zeilen das selbe aus?

Sieh Dir bitte weiter oben an:
"void zeige_x(float x,char zeige_periode)"

Bei 'zeige_x(frequenz,0)' wird die Drehzahl (ursprünglich die Frequenz) 
und anderfalls die Periodendauer angezeigt.
Das obige Foto entstand bei ca. 1,2kHz Eingangsfrequenz; einmal x*60 
skaliert und in der 2. Zeile mit 1/x.

von m.n. (Gast)


Lesenswert?

Vielleicht ist es niemandem aufgefallen und es wird äußerst selten zu 
'unsauberer' Auswertung führen, aber nachfolgender Programmabschnitt 
sollte vor einem T1OV-Interrupt geschützt werden. 'mess_dauer' kann 
sonst falsch gelesen oder gelöscht werden.
Die Sperre für TOIE1 habe ich hier ergänzt:

TIMSK1 &= ~(1<<TOIE1);           // t1OV interrupt sperren
    if(mess_status==MESSEN  && mess_dauer >= MESSZEIT) {
      mess_status=AUSLESEN;      // Auswertung starten
      mess_dauer = 0;            // wieder Messzeit abwarten
    }
TIMSK1 |= (1<<TOIE1);            // t1OV interrupt freigeben

von Maximilian A. (unix1970)


Lesenswert?

Kann man diese Schaltung auch so mit einem Hallsensor betreiben? Welchen 
Umbau braucht man für einen Reedkontakt?

von m.n. (Gast)


Lesenswert?

Als Hallsensor sollte ein TLE4905 direkt anschließbar sein. R4 ist der 
Pullup für den OC-Ausgang.

Bei einem Reedkontakt würde ich in Reihe zum Kontakt 1k legen und C3 
soweit vergrößeren, dass bei max. Schaltfolge die Signalamplitude an 
AIN0 maximal 1,5V unter- und minimal 3,5V überschreitet. Als 
experimentellen Startwert würde ich mit 10nF beginnen, was grob einer 
Eingangsfrequenz von 10kHz entsprechen würde. Das Tastverhältnis ist 
aber zu berücksichtigen.
Der 1k Widerstand schützt den Reedkontakt vor zu großen Entladeströmen.

Wenn kein Schmutz auftreten kann, kann man auch mit Reflexkopplern 
arbeiten. Ein bißchen Alufolie auf dem Drehteil erzeugt kaum Unwucht.

von Maximilian A. (unix1970)


Lesenswert?

Ich befürchte das geht nur an den AIN Ports. Diese sind bei mir schon 
besetzt. Gibt es noch andere Ports woran das ganze geht?

von m.n. (Gast)


Lesenswert?

Maximilian A. schrieb:
> Gibt es noch andere Ports woran das ganze geht?

Genausogut kannst Du ICP1 nehmen.
Dazu mußt Du diese Anweisung entfernen:
  ACSR |= 1<<ACIC;

Eine weitere Schaltung findest Du auch hier:
Beitrag "4-Kanal Drehzahlmessung mit ATmega88"
und noch mehr Beschreibungen auch hier:
http://www.mino-elektronik.de/fmeter/neue_versionen.htm

von Maximilian A. (unix1970)


Lesenswert?

Jetzt habe ich noch eine Frage:
wie bekomme ich das ganze auf den ATMEGA644 portiert? Theoretisch müsste 
ich doch nichts am Code verändern. Das Signal wir in PD6 gespeist, oder? 
Ich würde nämlich gerne das ganze auf dem Webserver von Ulrich Radig 
laufen lassen

von m.n. (Gast)


Lesenswert?

Das Programm zu portieren sollte kein Problem sein. ICP als Eingang ist 
auch in Ordnung.
Was den Webserver angeht: den kenne ich nicht. Dazu muß man wissen, 
welche Timer, I/O und Interrupts dort verwendet werden und ob dies mit 
der Drehzahlmessung kollidiert.

Für ein Einzelstück würde ich der Drehzahlmessung einen eigenen 
Prozessor spendieren und die Meßwerte per UART an den Webserver 
übertragen. Da stören sich die Programme nicht und man ist auf der 
sicheren Seite.

von Jan (Gast)


Lesenswert?

Hallo Leute.
Ich komme hier wirklich nicht weiter und nach langem Überlegen habe mich 
doch entschlossen kein Internet Forschung mehr in diesem Fall zu 
betreiben.
Vielleicht hilft mir hier jemand der "sich besser auskennt".
Ich versuche die möglichst Übersichtig mein Problem zu erklären :

Ich versuche seit tagen die Messung an ein ATmega8 und mein Display 
anzupassen und habe bis jetzt folgendes geändert:

-TMSK1 in TMSK unbenannt - da an ATmega 8- so steht bei Atmel
-lcd_routines.c mit meiner LCD Konfiguration eingebunden - die sind ok.
- im Code folgendes unbenannt:
--int_lcd in lcd_init von lcd_routnes
--lcd_f_str in lcd_string von lcd_routines.

An der Schaltung hängt ein Lüfter- das Schwarze Tachokabel an PD6 ( 
(AIN0) .Ich bekomme jetzt nur D: und T: auf dem Display angezeigt. Keine 
000 keine ??? - überhaupt kein Wert,
Ich gehe davon aus dass noch was in der LCD Einbindung verändert werden 
muss.
Das Programm lässt sich fehlerfrei und Warnungsfrei kompilieren.

Kann mir da bitte jemand bei der Einbuindung von lcd_routines ein Tipp 
geben ?

von Tim (Gast)


Lesenswert?

>-lcd_routines.c mit meiner LCD Konfiguration eingebunden - die sind ok.
Beweise? Quellcode?

Du hast lcd_zeichen vergessen.
Wird aber alles nicht ändern.
Wenn ich den Code beim überfliegen richtig verstanden habe
erscheinen erst dann zahlen auf dem display wenn die
Messung erfolgreich war (genauer gesagt nach der 2).
Da aber D: und T: bei dir angezeit wird vermute ich mal
das entweder
- Kein Brauchbares signal ankommt
oder
- Die Ansteuerung des Timers beim M8 nicht komatibel zum m88 ist

> An der Schaltung hängt ein Lüfter- das Schwarze Tachokabel

Ich würd eher sagen Gelb....

von m.n. (Gast)


Lesenswert?

Wenn "D: " und "T: " angezeigt werden, funktioniert die LCD-Ansteuerung.
Wenn ein Signal anliegt, muß die LED bei jeder fertigen Messung 0,1s 
aufleuchten. Falls das nicht passiert, ist das Signal nicht erkannt 
worden.

Kontrolliere bitte, ob die T1-Interrupts überhaupt arbeiten. Zunächst 
muß der OVF-Interrupt funktionieren: LED in der Routine blinken lassen.
Als Nächstes die LED in der CAPT-Routine blinken lassen.
Wenn beide Interrupts funktionieren, müßte auch die Anzeige der 
Messwerte klappen.

Noch etwas: ist SEI() wirksam, oder ist irgendwo ein CLI() vorhanden, 
was alle Interrupts wieder sperrt?

Jan schrieb:
> An der Schaltung hängt ein Lüfter- das Schwarze Tachokabel an PD6 (
> (AIN0)

Kontrolliere mit einer LED, ob hier überhaupt Impulse vorhanden sind.

von Andreas (Gast)


Angehängte Dateien:

Lesenswert?

m.n. schrieb:
> Vielleicht ist es niemandem aufgefallen und es wird äußerst selten zu
> 'unsauberer' Auswertung führen, aber nachfolgender Programmabschnitt
> sollte vor einem T1OV-Interrupt geschützt werden. 'mess_dauer' kann
> sonst falsch gelesen oder gelöscht werden.
> Die Sperre für TOIE1 habe ich hier ergänzt:
>
> TIMSK1 &= ~(1<<TOIE1);           // t1OV interrupt sperren
>     if(mess_status==MESSEN  && mess_dauer >= MESSZEIT) {
>       mess_status=AUSLESEN;      // Auswertung starten
>       mess_dauer = 0;            // wieder Messzeit abwarten
>     }
> TIMSK1 |= (1<<TOIE1);            // t1OV interrupt freigeben


Wenn ich das richtig verstanden habe muss es dann so wie angehängt 
aussehen.
Gruß Andreas

von m.n. (Gast)


Angehängte Dateien:

Lesenswert?

Oh, ich sag mal nur, dass ich suchen mußte, um Deine Änderung zu finden.

Damit niemand die schlechte Kopie verwendet, hänge ich die letzte 
Version am besten an.

von Stephan H. (stephan-)


Angehängte Dateien:

Lesenswert?

Hallo Leute,

da ich mal auf die Schnelle einen Drehzahlmesser brauchte, habe ich mal 
fix ein 1-seitiges Layout gemacht. Nix schönes und ohne ISP. Das LCD 
passt direkt oben drauf. Vielleicht kann es ja jemand brauchen.
Die Beleuchtung des LCD ist nicht vorgesehen, da ich es für 
Batteriebetrieb vorgesehen hatte.

Gruß

Stephan

von Tommy T. (thomas_k86)


Lesenswert?

Feine sache!! Hast das ganze auch in Bascom?

von Stephan (Gast)


Lesenswert?

Wozu ? Das HEX file gibts doch auf der Site zum Download.
Mino Elektronik.

von Tommy T. (thomas_k86)


Lesenswert?

kann man die hex file in bascom zurückwandeln?

hätte da einige änderungen. :)

von Mr. X (Gast)


Lesenswert?

Tommy Tomatronic schrieb:
> kann man die hex file in bascom zurückwandeln?

Und wie soll das gehen? Das scheitert schon alleine an den 
Variablennamen.

von Michael H. (michael_h45)


Lesenswert?

Tommy Tomatronic schrieb:
> kann man die hex file in bascom zurückwandeln?
>
> hätte da einige änderungen. :)

Sieh es als Zeichen, dass es an der Zeit ist, eine vernünftige 
Programmiersprache zu lernen.

von m.n. (Gast)


Lesenswert?

Tommy Tomatronic schrieb:
> hätte da einige änderungen. :)

Welche wären das denn?

von m.n. (Gast)


Lesenswert?

Eine neue Programmversion mit automatischen Abgleich auf ein 
1Hz-Referenzsignal - am besten von einem GPS-Empfänger - ist fertig.

Damit kann man den oben gezeigten Aufbau von Stephan Henning recht 
einfach abgleichen. Eine kurze Beschreibung dazu sowie .c-Quellcode und 
.hex-Datei sind hier zu finden.
http://www.mino-elektronik.de/fmeter/fm_software.htm#bsp3

von Tommy T. (thomas_k86)


Lesenswert?

des woas i doch eh dass des net geht! :)
da hatta wieda was losgetreten! :)

von Stephan H. (stephan-)


Lesenswert?

m.n. schrieb:
> Eine neue Programmversion mit automatischen Abgleich auf ein
> 1Hz-Referenzsignal - am besten von einem GPS-Empfänger - ist fertig.
>
> Damit kann man den oben gezeigten Aufbau von Stephan Henning recht
> einfach abgleichen. Eine kurze Beschreibung dazu sowie .c-Quellcode und
> .hex-Datei sind hier zu finden.
> http://www.mino-elektronik.de/fmeter/fm_software.htm#bsp3

theoretisch schon. Praktisch schwierig.
Ich habe die Eingangsbeschaltung nicht veröffentlicht.

Als Eingang habe ich die vom Sprut veröffentlichte genommen.
Fototranse mit OPV (Modellbaudrehzahlmesser)
Nein die ist nicht auf dem Bild zu sehen. das war was anderes,
was ich da vorn dran hatte.

Gruß

Stephan

funktioniert übrigens gut. Nur die Anzeige ist mir etwas zu hektisch
und macht zu größe Sprünge, was sich aber auf Grund des Prinzips
nicht viel ändern lassen wird. Möglich wäre eine gleitende 
Mittelwertbildung zB. Wert neu = Wert alt *3 / Wert neu. Was allerdings 
unweigerlich zu einer deutlich trägeren Anzeige führen würde, wenn sich 
Wert alt und wert neu langsam annähern.

Es ist eben nichts perfekt. So wie wir Menschen.  :-)

von m.n. (Gast)


Lesenswert?

Stephan Henning schrieb:
> m.n. schrieb:
>> Eine neue Programmversion mit automatischen Abgleich auf ein
>> 1Hz-Referenzsignal - am besten von einem GPS-Empfänger - ist fertig.
>>
>> Damit kann man den oben gezeigten Aufbau von Stephan Henning recht
>> einfach abgleichen. Eine kurze Beschreibung dazu sowie .c-Quellcode und
>> .hex-Datei sind hier zu finden.
>> http://www.mino-elektronik.de/fmeter/fm_software.htm#bsp3
>
> theoretisch schon. Praktisch schwierig.

Ich weiß jetzt nicht, worauf sich das "schwierig" bezieht.
Den 'Fangbereich' für den auto. Abgleich habe ich von +/-100ppm auf 
+/-1000ppm erweitert, obwohl die nun mögliche Toleranz für mich schon 
grenzwertig ist.
Unter Umständen sollte C3 bei einem GPS-Signal unbestückt sein oder R4 
verkleinert werden, falls der 1pps-Impuls nur 1µs lang ist.

von Stephan H. (stephan-)


Lesenswert?

Stephan Henning schrieb:
> theoretisch schon. Praktisch schwierig.

m.n. schrieb:

> Ich weiß jetzt nicht, worauf sich das "schwierig" bezieht.

Hallo Michael,

das bezog sich lediglich auf die Eingansbeschaltung welche ich nicht 
dargestellt hatte. Das optische Eingansteil vom Sprut.
Welche für den Abgleichzweck aber völlig uninteresant ist.
Sorry, hatte einen Knoten im Hirn.

Außerdem sind ja in der BRD Datei keine Werte enthalten.
Es ging ja bei dem Post lediglich um die mögliche Nutzung des Layouts, 
da ich es ja eh machen musste.

Bleib ganz ruhig, alles gut.

Gruß

Stephan

: Bearbeitet durch User
von m.n. (Gast)


Lesenswert?

Stephan Henning schrieb:
> Bleib ganz ruhig, alles gut.

Na ja, dass die Istfrequenz von Quarzen in manchen Fällen zu stark 
streut, ist mir schon zu Ohren gekommen. Deshalb wollte ich ein bißchen 
mehr Nachbausicherheit einbringen.

Ferner ist mir bei der Anpassung eines Frequenzzähler-Programms auf 
einen Arduino UNO R3, eine Abweicheng des 16MHz Quarzes von >500ppm 
aufgefallen. Das ist schon heftig und wohl die Folge von "Geiz ist ...".

von Stephan H. (stephan-)


Lesenswert?

Michael,

ich denke Du machst Dir zu viele unnötige Sorgen. Wenn es hier deutliche 
Probleme geben würde, hättest Du schon was davon gelesen, bzw. über 
Deine eigene Homepage ein Feedback bekommen. Dein(e) Schaltung /Programm 
erhebt ja auch nicht den Status eines Präzisionsmessers.

Das wird erst interessant wenn sich der Peter Danneger melet.

Also bleib entspannt.

Ein Arduino UNO R3 kann ja wohl nicht das Maß der Dinge sein.
Ist das Ding überhaupt Echtzeifähig ?
Kann doch bei USB Interface eigentlich nicht sein, denke ich.
Ich habe keines.

Gruß

Stephan

von Laurin (wildatheart)


Lesenswert?

Hallo alle

Ich habe die Drehzahl-Schaltung gebaut (mit externem 20MHz Quarz). Ich 
verwende am Eingang einen wie im thread besprochenen Hallsensor Typ 
TLE4905. Der Prozessor erkennt die Impulse (Led), die ich mit einem 
Magneten am Sensor gebe.
Jedoch scheint die angezeigte Frequenz und damit auch die Zeit nicht zu 
stimmen. Es zeigt mit eine deutlich zu hohe Drehzahl an, wenn ich z.B. 
im Sekundentakt den Hallsensor ansteuere.
Ich vermute, dass meine Prozessor-Clock nicht stimmt. Ich habe den 
Atmega88 mit folgenden Fuses programmiert:

Ext. Full-swing Crystal; Start-up time PWRDWN/RESET: 258 CK/14 CK + 
65ms; (CKSEL0110 SUT=01)
Brown-out detection level at VCC=4.3V

ergibt:
Low: 0x56; High: 0xDC; Extended: 0xF9

von m.n. (Gast)


Lesenswert?

Laurin E. schrieb:
> Es zeigt mit eine deutlich zu hohe Drehzahl an, wenn ich z.B.
> im Sekundentakt den Hallsensor ansteuere.

Welcher Wert wird angezeigt und ist er stabil?

von Laurin (wildatheart)


Lesenswert?

Hallo m.n.

Ich Idiot hatte vergessen die "divide clock by 8 internally* zu 
unchecken. Jetzt schein die Frequenz zu stimmen. Sorry!

von m.n. (Gast)


Lesenswert?

Das hatte ich schon vermutet. Mit der letzten Version wäre das Problem 
nicht entstanden.

m.n. schrieb:
> Eine neue Programmversion mit automatischen Abgleich auf ein
> 1Hz-Referenzsignal - am besten von einem GPS-Empfänger - ist fertig.
>
> Damit kann man den oben gezeigten Aufbau von Stephan Henning recht
> einfach abgleichen. Eine kurze Beschreibung dazu sowie .c-Quellcode und
> .hex-Datei sind hier zu finden.
> http://www.mino-elektronik.de/fmeter/fm_software.htm#bsp3

In der 1. Zeile von main() steht dort:
  CLKPR = 0x80; CLKPR = 0x0;
Damit wird der interne Vorteiler immer auf 1 gestellt.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.