Hallo,
Ich möchte die Drehzahl einer Lochscheibe mit dem Arduino Nano
überwachen, und auf ein LCD ausgeben.
Schaltung mit Lischtschranken und Schmidt Trigger ist aufgebaut und gibt
ein sauberes Rechteck aus.
Die Scheibe hat 12 Löcher, und eine Drehzahl von knapp 1000 bis max
20.000 Umdrehungen.
Ich bräuchte sogesehen nur den passenden Code.
Kann mir dabei bitte jemand helfen?
Nick S. schrieb:> Hallo,>> Ich möchte die Drehzahl einer Lochscheibe mit dem Arduino Nano> überwachen, und auf ein LCD ausgeben.>> Schaltung mit Lischtschranken und Schmidt Trigger ist aufgebaut und gibt> ein sauberes Rechteck aus.>> Die Scheibe hat 12 Löcher, und eine Drehzahl von knapp 1000 bis max> 20.000 Umdrehungen.>> Ich bräuchte sogesehen nur den passenden Code.
Dann würde ich an deiner Stelle anfangen zu programmieren. So gesehen.
Nick S. schrieb:> Ich bräuchte sogesehen nur den passenden Code.
Ja, genau .... das ist schnell erledigt. Das Forum entwickelt für dich.
Nick S. schrieb:> Schaltung mit Lischtschranken und Schmidt Trigger ist aufgebaut und gibt> ein sauberes Rechteck aus.
Bis über 200 KHz ...... sicher ?
Arduinoquäler schrieb:> Ja, genau .... das ist schnell erledigt. Das Forum entwickelt für dich.
Schon fertig, http://www.mikrocontroller.net/articles/Drehzahlmesser
muss er nur noch
aber nicht von dir, denn du...
> Bis über 200 KHz ...... sicher ?
...kannst nicht mal Sekunden und Minuten auseinanderhalten.
Arduinoquäler schrieb:> Was kann ich denn noch alles nicht
Offensichtlich eine Menge, denn du merkst noch nicht mal,
wenn man dich vorsichtig auf deinen Fehler aufmerksam macht
und hast es immer noch nicht begriffen. Merkbefreit.
Die Schaltung von http://www.mikrocontroller.net/articles/Drehzahlmesser
ist ganz was anderes.
Ich habe einen Arduino Nano, und brauche den entsprechenden Code dazu.
Umdrehungen beziehen sich auf eine Minute, wenns Anfangs keine 20.000
upm schafft ist egal, sonst kann ich eine Lochscheibe mit nur einem Loch
montieren. Wär nur schön wenn ich bis knapp unter 1000U/min eine Anzeige
auf einem LCD hätte.
Es handelt sich um ein 2x16 Zeilen LCD, das ist in den Arduinobeispielen
dabei, aber kennen mich damit zuwenig aus, bzw funktioniert kaum ein
Programm von mir :(
lg
Um wenigstens etwas konstruktives beizutragen:
http://www.pyroelectro.com/tutorials/tachometer_rpm_arduino/
Wenn Du etwas Englisch verstehst ...
Deine Anpassung wäre also (time*7) durch (time*12) zu ersetzen - und die
richtigen PINs auszuwählen.
Hallo Dieter, danke für den Link, habs nach langer Fehlersuche
tatsächlich hinbekommen, Bild im Anhang :)
Aber die Verzögerung ist jenseits von gut und böse, gibts irgenwo ein
Tut mit dem Capture Register und Compare Match, etc?
In diesem Thread Beitrag "Re: Zündkurve verstellen beim 2Takter" hat
mir Max.D schon einiges an Anregungen gegeben, aber selber schaff ich
das leider nicht :(
Lg, Kolbi
Nick S. schrieb:> Aber die Verzögerung ist jenseits von gut und böse
Ja, da wird mit Absicht verzögert - nicht unbedingt optimal ... wie
eigentlich der komplette Code, wenn man genauer hinschaut.
Ich habe keine Ahnung, ob micros() in float kommen - aber das einfach
mal übernommen (bin kein Arduino-Nutzer).
Probier mal
...
1
//Main Loop To Calculate RPM and Update LCD Display
Glücklich bin ich mit der Lösung nicht - wenn ca. 7000 Umdrehungen pro
Minute überschritten werden geht es "in die Hose". Aus
Performance-Gründen würde ich die "Alternative" ausprobieren ...
Wie geschrieben bin ich kein Arduino-Spezialist und würde es wohl auf
"normaler" AVR-Ebene anders lösen. Hoffentlich schaut Karl-Heinz hier
nicht hin, sonst bekomme ich Hiebe :-)
Übrigens: Interessant, was Du da gebaut hast.
Habe mir den 2-Takter-Thread auch mal angeschaut. Da bin ich aber
mechanisch deutlich zu weit entfernt ... bin zwar vor Ur-Zeiten mal
Quickly gefahren (immer eine Vergaser-Füllung weit), aber das ist lange
her :-)
Leider funktioniert da was nicht, ich bekomme die Fehlermeldung: error:
cannot convert 'long unsigned int()' to 'float' in assignment
Wenns am Arduino liegt dass das so aufwändig ist, dann kauf ich mir gern
andere Hardware...
Lg
Nick S. schrieb:> ich bekomme die Fehlermeldung: error:> cannot convert 'long unsigned int()' to 'float' in assignment
Kannst Du bitte mal das KOMPLETTE aktuelle Coding plus ALLE
(Fehler)-Meldungen hier einstellen? Danke ...
Nur zur Information: Mit der Meldung selbst (ohne Zeilen-Referenz) kann
niemand etwas anfangen. Die Zeilen-Referenz bringt auch nur etwas, wenn
man das komplette, zugrunde liegende Coding kennt ...
Nick S. schrieb:> ich bekomme die Fehlermeldung: error:> cannot convert 'long unsigned int()' to 'float' in assignment
Und was steht in der betreffenden Code-Zeile
Dieter Frohnapfel schrieb:> Ich habe keine Ahnung, ob micros() in float kommen - aber das einfach> mal übernommen (bin kein Arduino-Nutzer).
Google kennst du?
"arduino micros" hilft in diesem Fall weiter ;-)
http://arduino.cc/en/reference/micros
Wolfgang A. schrieb:> Google kennst du?
Nö, was ist das? Du kannst ja gerne weiterhelfen, da Du ja optimal
informiert bist :-) Ich klinke mich damit aus ...
Wolfgang A. schrieb:> Und was steht in der betreffenden Code-Zeile
Aber Lesen kannst Du schon
Dieter Frohnapfel schrieb:> Kannst Du bitte mal das KOMPLETTE aktuelle Coding plus ALLE> (Fehler)-Meldungen hier einstellen? Danke ...
gut, das freut mich, mach mal weiter ... und gute Nacht etc. an alle
Leute, Leute, bitte lockerbleiben, Gefühle haben hier nix verloren, nur
Technik bitte! ^^
Ich wollte mit meinem letzen Post wirklich nicht undankbar klingen oder
so, danke an alle, die sich bisher die Mühe gemacht haben da was
weiterzubringen!
Hier die komplette Fehlermeldung:
Drehzahlmesser.ino: In function 'void fan_interrupt()':
Drehzahlmesser.ino:63:14: error: cannot convert 'long unsigned int()' to
'float' in assignment
Error compiling.
Ganz schlau werde ich daraus nicht, ist der Fehler in Zeile 63, oder wie
ist das zu verstehen?
Keine Ahnung ob der Schmitt-Trigger nötig ist, werds demnächst ohne
probieren und berichten.
Lg!
Wieso bei Dir die volatile float-Deklarationen zu Beginn keine
Fehlermeldung auslösen ist mir allerdings ein Rätsel (es sei denn, Du
hast die gar nicht übernommen ... aber Deinen Code kann ich ja nicht
sehen ...)
Habe noch ein "time = 0" eingebaut, damit nicht unsinnig bei jedem
Durchlauf gerechnet wird.
Dieter Frohnapfel schrieb:> Habe noch ein "time = 0" eingebaut, damit nicht unsinnig bei jedem> Durchlauf gerechnet wird.
Dafür kriegst Du ein dickes Minus für das time = 0!
Es geht auch ohne Schmitt Trigger, wieder ein Bauteil gespart ;)
Da ich die Wertemittelung eigentlich gar nicht brauche, hab ich den Code
dementsprechend geändert:
1
#include<LiquidCrystal.h>
2
LiquidCrystallcd(12,11,5,4,3,13);
3
4
volatilefloatZeit=0;
5
volatilefloatVorherige_Zeit=0;
6
7
voidsetup()
8
{
9
//Digital Pin 2 ist jetzt ein Interrupt und reagiert auf fallende Flanken
10
attachInterrupt(0,Sensor_Interrupt,FALLING);
11
12
// 2x16 LCD Display einrichten
13
lcd.begin(16,2);
14
// Drehzahl auf dem LCD Ausgeben
15
lcd.print("Umdrehungen/Min");
16
}
17
18
//Hauptschleife zum Berechnen der Drehzahl und LCD Displayupdate
19
voidloop()
20
{
21
intupm=0;
22
23
while(1){
24
25
//Displayupdates verzögern
26
delay(200);
27
28
//Letzte Reihe löschen
29
lcd.setCursor(0,1);
30
lcd.print(" ");
31
32
//Drehzahl ausgeben
33
lcd.setCursor(0,1);
34
lcd.print(upm);
35
36
lcd.setCursor(4,1);
37
lcd.print(time);
38
39
//Drehzahlberechnung, *12 für die Anzahl der Impulse (Lochscheibe, Lüfterflügel,...)
40
if(Zeit>0)
41
{
42
upm=60*(1000000/(Zeit*12));
43
}
44
45
}
46
}
47
48
//Interrrupt Capture
49
voidSensor_Interrupt()
50
{
51
Zeit=(micros()-Vorherige_Zeit);
52
Vorherige_Zeit=micros();
53
}
Zum messen hoher Drehzahlen würd ich die Drehzahl einfach auf 10er oder
100er Stellen runden.
Herzlichen Dank für die Hilfe, Projekt fertig! :)
Lg
nicht haben.
Das Arduino Framework ist so aufgebaut, dass es dir ein main() vorgibt,
welches vom Prinzip her so aussieht
1
intmain()
2
{
3
ArduinoInitialisierungen
4
5
setup();
6
7
sei();
8
9
while(1){
10
11
loop();
12
13
ArdiunoFrameworkinterneBuchhaltung
14
}
15
}
Die obligate Endlosschleife steckt bereits in diesem vorgegebenem main()
drinnen, welches du nicht selbst schreibst. D.h. die Funktion loop()
wird laufend ohne dein Zutun aufgerufen und das willst du auch so haben,
damit das Framework die Chance kriegt ihre eigene Buchhaltung zu
erledigen.
Dein
1
voidloop()
2
{
3
...
4
while(1){
5
...
6
}
7
}
ist daher kontraproduktiv. Denn genau letzters, dem Framework die
Möglichkeit zu geben ihre eigenen Dinge zu erledigen, unterbindest du
damit.
Das andere ist der delay, den du da drinnen hast. Du willst keinen delay
haben (ausser ganz kurze)! Denn in dieser Zeit kann der µC nichts
anderes machen als Däumchen drehen und noch ISR abarbeiten. Das ist dir
aber zu wenig.
Zeitsteuerungen im Arduino Framework funktionieren so (am Beispiel mit
Millisekunden
Auf die Art vermeidest du das unproduktive Däumchen drehen. Das Prinzip
ist simpel: Wenn du alle 5 Sekunden eine Aktion machen willst und deine
Uhr hat bei der letzten Aktion den Sekundenzeiger auf 20 gehabt, dann
ist die nächste Aktion fällig, wenn der Sekundenzeiger auf 25 steht.
Was anderes hast du im Prinzip hier
1
voidSensor_Interrupt()
2
{
3
Zeit=(micros()-Vorherige_Zeit);
4
Vorherige_Zeit=micros();
5
}
auch nicht gemacht. Nur dass natürlich die Verwendung von float an
dieser Stelle den programmtechnischen Supergau darstellt und du nicht 2
mal micros() aufrufen willst, weil du ja keine Gewähr hast, dass sich
der Wert in der Zwischenzeit nicht geändert hat (mal abgesehen vom
unnötigen Zeitbedarf für den Aufruf)
Nein. Sorry.
Es ist dein Projekt und du lernst gefälligst programmieren.
Ausserdem denke ich, dass ich mehr als ausführlich die Motivation und
die Hintergünde geschildert habe. Einfach Copy&Paste und gut ist spielt
es bei mir nicht mehr. Nicht auf diesem simplen Schwierigkeitsgrad.