Sowas macht man eigentlich per Input Capture mit einem Timer.
Man lässt einen Timer durch sein Takt-Signal hochzählen und schaut sich
dann zyklisch (zweiter Timer als Tor) den Zählwert an und setzt die
Zähltregister wieder auf null.
Das ganze klappt dann nahezu vollständig in Hardware und geht bis ein
paar Megahertz (Je nach Torzeit), ohne die Firmware zu blockieren.
Philipp G. schrieb:> Da das Rechnen an sich auch CPU Zeit beansprucht,> funktioniert das so bis zu 165kHz? Hat da jemand Erfahrungswerte?
- welche Taktrate hat der?
- was ist PulseIn()? Arduino funktion? sonst poste den Code
- was macht der restliche Code?
- musst du durchgängig messen oder reicht einmal messen, dann Code zur
Anzeige u.s.w., dann wieder messen?
bei 16MHz Takt hast du 100 Zyklen für 160kHz, das sollte machbar sein in
C, allerdings nicht viel mehr außenrum und bei Arduino könnte der
overhead schon etwass viel werden. Timer zur Zeitmessung (Timerwert alt
- neu + Anzahl der Overflows => Zeit) und Pin Change Interrupt schaffen
das locker.
Philipp G. schrieb:> Ich möchte mit dem Atmega328 die Frequenz (resp. RPM) eines +5V Rechteck> Signals (50/50) messen.
RPM = revolutions per minute
Das kann selbst beim schnellsten Motor kaum über ein paar kHz gehen,
also langsam für einen Mikrocontroller.
> Der folgende Code soll mir RPM zurückgeben:> //loop> long lRPM> lRPM = 272727 / pulseIn(5, LOW); // 500000 * 60 / 11>> Meine Frage: Da das Rechnen an sich auch CPU Zeit beansprucht,> funktioniert das so bis zu 165kHz? Hat da jemand Erfahrungswerte?
Du willst mal sicher NICHT mit 165kHz eine Drehzahl berechnen, sondern
eher ein paar Mal pro Sekunde bis zu 165kHz messen und dann umrechnen.
Wobei 165 kHz nur von einem hochauflösenden Encoder kommen können, nicht
als einfaches Drehzahlsignal von einem Motor, denn der hätte dann 9,9
Millionen Umdrehung/min ;-)
Und wenn gleich deine Arduino-Methode PulseIn() irgendwas ausspucken
wird, so ist die Drehzahlmessung über nur einen Puls eher ungenau.
Sinnvollerweise mißt man deutlich mehr Pulse über einen längeren
Zeitraum.
Man kann es ja mal theoretisch betrachten:
T = 1 / 165000 = 6µs
Wenn du dein ATmega328 mit 20Mhz betreibst, dann dauert ein Takt 50ns.
Somit ergeben sich max. 120 Takte, bzw. 120 ASM-Anweisungen (wenn es
Anweisungen sind die nur 1 Takt benötigen).
Sebastian R. schrieb:> Man lässt einen Timer durch sein Takt-Signal hochzählen und schaut sich> dann zyklisch (zweiter Timer als Tor) den Zählwert an und setzt die> Zähltregister wieder auf null.Philipp G. schrieb:> Der folgende Code soll mir RPM zurückgeben:
der Vorschlag ist auch gut, aber bei sehr niedrigen RPM muss man dann in
der Software glitches ausschließen, wenn die Zeit zwischen Pulsen zu
groß wird im Verhältnis zur Torzeit, sonst schwankt der Ausgang trotz
konstanter RPM.
K. S. schrieb:> der Vorschlag ist auch gut, aber bei sehr niedrigen RPM muss man dann in> der Software glitches ausschließen, wenn die Zeit zwischen Pulsen zu> groß wird im Verhältnis zur Torzeit, sonst schwankt der Ausgang trotz> konstanter RPM.
Man muss die Torzeit so wählen, dass der Timer weder überläuft, noch
dass er nur ein paar Werte weit zählt.
Je weiter der Timer in einer Torzeit bei gegebener Drehzahl kommt, desto
genauer ist das Ergebnis und desto geringer ist der Jitter.
Wenn man dann noch die Möglichkeit hat, ein bisschen zu filtern, sollte
das schon gut gehen.
K. S. schrieb:> welche Taktrate hat der?
16MMhz
K. S. schrieb:> - was ist PulseIn()? Arduino funktion? sonst poste den Code
Ja, misst die Zeit von Low bis wieder ein High anliegt.
K. S. schrieb:> - was macht der restliche Code?
auf einem LCD die Zahl ausgeben. Plus den Höchstwert jeweils in eine
Variable schreiben.
K. S. schrieb:> - musst du durchgängig messen oder reicht einmal messen, dann Code zur> Anzeige
Nein, durchgängig messen, immer.
Falk B. schrieb:> RPM = revolutions per minute>> Das kann selbst beim schnellsten Motor kaum über ein paar kHz gehen,> also langsam für einen Mikrocontroller.
Hm, wie so oft liegt das Problem zwischen den Ohren, hast wieder mal
Recht @FAlk :)
Dann muss ich tiefer ausholen.
Es handelt sich um einen Speed Sensor für einen Turbo. Der ist bei
165'000 Umin im Surge Limit, also praktisch gesehen möchte ich messen
bis 200'000 Umin.
Das Datenblatt gibt es hierzu ab Seite 12:
https://www.garrettmotion.com/wp-content/uploads/2018/06/781328_Speed_Sensor_Kit_Installation_Instructions-1.pdf
Also:
Der Sensor misst die vorbeikommenden Blätter, ein Blatt - ein Impuls.
Mein Turbo hat 11. Der Sensor gibt jedes achte Blatt als Ausgangfrequenz
zurück. Das geht hieraus hervor:
1
Sensor Signal: the speed sensor will output a square-wave signal at 1/8 the input
2
frequency(originally intended for 8-blade wheel). The input frequency is simply one pulse
3
per blade, as the blades pass by the sensor. The sensor therefore measures the following
4
input frequency (in rpm):
5
Equation 1
6
where N is the number of blades, and RPM is the turbo speed.
7
Therefore, your data logger needs to convert the speed sensor signal based on
8
equation 1.
9
For example, with a 12-bladed wheel,
10
Example
11
Therefore the logger would need to multiply the sensor signal by 40 in order to record true
12
turbo RPM (for a 12-bladed wheel).
Das habe ich überlesen, ergo bedeutet das für meinen Code:
1
//loop
2
longlRPM
3
//lRPM = 60 * 8 / 11 * 500000 / pulseIn(5, LOW);
4
//lRPM = 43.63 * 500000 / pulseIn(5, LOW);
5
lRPM=21815000/pulseIn(5,LOW);
Stimmt die Rechung? Könnt ihr mich folgen?
ergo, das sind rund ~5Khz, nix von 165.
edit: Damit es dann so aussieht, wie deren Rundinstrument (Bild im
Anhang) messen wir bis 180'000 mit einem Teiler von 1000:
Philipp G. schrieb:> funktioniert das so bis zu 165kHz? Hat da jemand Erfahrungswerte?
Es funktioniert gerade noch so bei einem 328 mit 16MHz getaktet in C
geschrieben.
Allerdings muss getrickst werden.
Während der Messung keine Interrupts.
Wenn Arduino verwendet wird, dann nur mit direkten Port Zugriff.
Oder alternativ diese Fast IO Lib.
Hab was ähnliches gemacht.
Einen Floppy Controller mit einem Arduino Nano.
Da kommen so alle 4µs ein Datenbit ...
Philipp G. schrieb:>> - was ist PulseIn()? Arduino funktion? sonst poste den Code>> Ja, misst die Zeit von Low bis wieder ein High anliegt.
Das wäre aber ein PulsBREITENmessung und keine Frequenzmessung. Und
genau das macht die Funktion auch und ist damit für deine Anwendung
unbrauchbar.
https://www.arduino.cc/reference/en/language/functions/advanced-io/pulsein/> auf einem LCD die Zahl ausgeben. Plus den Höchstwert jeweils in eine> Variable schreiben.
Trivial, trotzdem kann man da viel Unsinn machen.
> Es handelt sich um einen Speed Sensor für einen Turbo. Der ist bei> 165'000 Umin im Surge Limit, also praktisch gesehen möchte ich messen> bis 200'000 Umin.
Schöner Staubsauger ;-)
> Der Sensor misst die vorbeikommenden Blätter, ein Blatt - ein Impuls.> Mein Turbo hat 11. Der Sensor gibt jedes achte Blatt als Ausgangfrequenz> zurück.
Also ist die echte Drehzahl
RPM = Pulsfrequenz [Hz] * 8 / 11 * 60
> Das habe ich überlesen, ergo bedeutet das für meinen Code:>> //loop> long lRPM> //lRPM = 60 * 8 / 11 * 500000 / pulseIn(5, LOW);> //lRPM = 43.63 * 500000 / pulseIn(5, LOW);> lRPM = 21815000/ pulseIn(5, LOW);>> Stimmt die Rechung? Könnt ihr mich folgen?
Wo kommt die 500000 her?
> ergo, das sind rund ~5Khz, nix von 165.
Immer noch falsch. Deine max. 200.000 U/min = 3,3kHz
Der Sensor gibt aber nur 1/8 davon aus, also 416Hz. Laaaaaangsaaaam ;-)
> edit: Damit es dann so aussieht, wie deren Rundinstrument (Bild im> Anhang) messen wir bis 180'000 mit einem Teiler von 1000:> lRPM = 21815 / pulseIn(5, LOW);> LCD.print (lRPM + " x1000 RPM")
Naja, bei den Drehzahlen und der Tatsache, daß die praktisch nie auf
Null absinkt, mißt man sinnvollerweise eine volle Periode, das ist genau
genug. Dazu reicht ein passend konfigurierter externer Interrupt, der
auf die fallende oder steigende Flanke reagiert, aber nicht auf beide.
Dann noch einen Timer passend eingestellt und die Differenz gebildet,
fettig. Dann kann man auch problemlos das Anzeigeinstrument mit 100Hz
oder mehr Updaterate betreiben und eine analoge, dynamische Anzeige
nachbauen.
Wenn man also ~420 Hz (2,3ms) mit 1% Auflösung messen will (mehr braucht
kein Mensch für sowas), braucht man ca. 42kHz Timerfrequenz. Sagen wir
62,5kHz und gut. Also den Prescaler von Timer 1 auf /256 konfigurieren
und messen, der mißt dann eine Differenz ~143 Takte bei Maximaldrehzahl.
Die messbare Minimaldrehzahl liegt um Faktor 458 tiefer bei ca. 0,2%
bzw. 430U/min, darunter kann man so direkt nicht messen, weil es dann
zum Zählerüberlauf bei der Differenzbildung von Timer 1 kommt (16 Bit).
Sollte reichen, muss man aber ggf. per Software abfangen, sonst zeigt
euer Instrument ggf. Unsinn an, wenn der Kreisel steht.
Weder Revolution, noch Resolution, noch Absolution:
RPM = rotations per minute bzw.
UPM = Umdrehungen pro Minute
Für ATmega328 oder Arduino Uno gibt es fertigen Code:
http://mino-elektronik.de/fmeter/fm_software.htm#bsp7 Automatische
Bereichswahl von 16 mHz - 250 kHz mit höchster Auflösung ist inklusiv.
Der keramische Resonator des Arduino hat aber eine sehr bescheidene
Stabilität, weshalb die Taktfrequenz unbedingt mit einem Quarz oder TCXO
erzeugt werden sollte.
Das Maximum mit AVR bei 20 MHz Takt liegt bei 1 MHz mit input-capture:
http://mino-elektronik.de/fmeter/fmeter.htm
Bascom mit Assembler Unterstützung ist auch nicht schlecht!
Thomas W. schrieb:> Philipp G. schrieb:>> funktioniert das so bis zu 165kHz? Hat da jemand Erfahrungswerte?>> Es funktioniert gerade noch so bei einem 328 mit 16MHz getaktet in C> geschrieben.>> Allerdings muss getrickst werden.
Der einfachste Tick ist, das Zählen der eingebauten Hardware im
ATmega328 zu überlassen. Wozu soll der sich damit per Software
rumplagen. Währenddessen kann er sich genauso gut mit anderen Dingen
beschäftigen.
m.n. schrieb:> Bereichswahl von 16 mHz - 250 kHz mit höchster Auflösung ist inklusiv.> Der keramische Resonator des Arduino hat aber eine sehr bescheidene> Stabilität, weshalb die Taktfrequenz unbedingt mit einem Quarz oder TCXO> erzeugt werden sollte.
Der CPU-Takt muss nicht genauer sein, als die erforderliche Genauigkeit
der Drehzahlmessung.
Falk B. schrieb:> Also ist die echte Drehzahl>> RPM = Pulsfrequenz [Hz] * 8 / 11 * 60
Genau.
Falk B. schrieb:> Immer noch falsch. Deine max. 200.000 U/min = 3,3kHz> Der Sensor gibt aber nur 1/8 davon aus, also 416Hz. Laaaaaangsaaaam
Hm, hat was, ja.
Falk B. schrieb:> Wo kommt die 500000 her?
1'000'000 us / 2, weil die Zeit gemessen wird, bis von low wieder ein
high einliegt, und nicht die volle Periode.
Falk B. schrieb:> Wenn man also ~420 Hz (2,3ms) mit 1% Auflösung messen will (mehr braucht> kein Mensch für sowas), braucht man ca. 42kHz Timerfrequenz. Sagen wir> 62,5kHz und gut. Also den Prescaler von Timer 1 auf /256 konfigurieren> und messen, der mißt dann eine Differenz ~143 Takte bei Maximaldrehzahl.
Meinst Du das so:
Da ist halt immer noch die PulseIn Funktion drin, mangels Wissen wie man
es besser machen könnte :(
m.n. schrieb:> gibt es fertigen Code:> http://mino-elektronik.de/fmeter/fm_software.htm#bsp7 Automatische> Bereichswahl von 16 mHz - 250 kHz mit höchster Auflösung
dank dir, schaue ich mir morgen mal an.
Wolfgang schrieb:> Der einfachste Tick ist, das Zählen der eingebauten Hardware im> ATmega328 zu überlassen. Wozu soll der sich damit per Software> rumplagen. Währenddessen
Damit bin ich überfordert.
Wolfgang schrieb:> Der CPU-Takt muss nicht genauer sein, als die erforderliche Genauigkeit> der Drehzahlmessung.
Im Prinzip richtig, aber: Wenn man sechs Stellen anzeigt, sollten diese
auch aussagefähig sein. Man kann zwar die letzten drei Stellen
ausblenden, nur warum? Mit einem Quarz für 20 cent hat man neben der
Auflösung auch volle Genauigkeit. Dafür nimmt man doch einen µC.
Sonst täte es ja auch ein Frequenz/Spannungs-Wandler mit angeschlossenem
Multimeter: http://mino-elektronik.de/fmeter/fm_software.htm#bsp11Philipp G. schrieb:> Wolfgang schrieb:>> Der einfachste Tick ist, das Zählen der eingebauten Hardware im>> ATmega328 zu überlassen. Wozu soll der sich damit per Software>> rumplagen. Währenddessen>> Damit bin ich überfordert.
Nicht nur Du ;-)
m.n. schrieb:> Im Prinzip richtig, aber: Wenn man sechs Stellen anzeigt, sollten diese> auch aussagefähig sein.
Manchmal nimmt man auch eine Anzeige mit vielen Stellen, um einfach nur
die Messbereichsumschaltung zu sparen und beim Ablesen nicht dauernd das
Dezimaltrennzeichen suchen zu müssen.
Wolfgang schrieb:> Manchmal nimmt man auch eine Anzeige mit vielen Stellen, um einfach nur> die Messbereichsumschaltung zu sparen und beim Ablesen nicht dauernd das> Dezimaltrennzeichen suchen zu müssen.
Womöglich noch ohne Vornullenunterdrückung? Das erinnert mich an die
70er Jahre. Da hatten alle Frequenzzähler acht Stellen (ICM7216) ;-)
Stand der Technik ist automatische Bereichswahl - seit Jahrzehnten.
Philipp G. schrieb:> Wolfgang schrieb:>> Der einfachste Tick ist, das Zählen der eingebauten Hardware im>> ATmega328 zu überlassen. Wozu soll der sich damit per Software>> rumplagen. Währenddessen>> Damit bin ich überfordert.
Wo ist das Problem? Im Kern musst du nur ein Byte Konfiguration in ein
dämliches Timer-Register schreiben, um den Timer dazu zu bringen, halt
Impulse "von aussen" zu zählen statt der des Systemtaktes.
Natürlich brauchst du einen weiteren, vom Systemtakt angetriebenen Timer
als Referenz, denn Messen heißt vergleichen.
Hast du die beiden Timer konfiguriert, laufen die einfach von alleine
und tun ihren Job ohne dass dein Programm weiter mit ihnen interagieren
muss.
Das muss bloß noch die beiden Timerregister zu zwei Zeitpunkten auslesen
und die vier ausgelesenen Werte mit ein wenig Sechstklässlermathematik
miteinander verrechnen und das Ergebnis zur Anzeige bringen.
Wenn man's richtig gut machen will, kann man auch noch die
systematischen Fehler der Ausleseroutine korrigieren und das
Messintervall dynamisch anpassen, wobei letzteres bei der Anwendung für
einen Turbolader eher nicht nötig sein dürfte. Das kann man wohl einfach
durch die Rückgabe einer schlichten 0 bei Unterschreitung eines
Grenzwertes ersetzen, da kein Schwein sich dafür interessiert, ob der
Lader eventuell im An- oder Auslaufen schon/noch mit 1000, 500 oder
100rpm läuft. Das ist im Sinne der Messaufgabe alles praktisch mit 0
gleichzusetzen.
c-hater schrieb:> Natürlich brauchst du einen weiteren, vom Systemtakt angetriebenen Timer> als Referenz, denn Messen heißt vergleichen.>> Hast du die beiden Timer konfiguriert, laufen die einfach von alleine> und tun ihren Job ohne dass dein Programm weiter mit ihnen interagieren> muss.>> Das muss bloß noch die beiden Timerregister zu zwei Zeitpunkten auslesen> und die vier ausgelesenen Werte mit ein wenig Sechstklässlermathematik> miteinander verrechnen und das Ergebnis zur Anzeige bringen.>> Wenn man's richtig gut machen will,
dann muß man diese beiden Timer synchronisieren. Und dafür bietet der
AVR nichts an. Folglich können Überläufe des Ereigniszählers falsch
zugeordnet werden.
Richtig gut geht anders!
m.n. schrieb:> Stand der Technik ist automatische Bereichswahl - seit Jahrzehnten.
Quatsch. Stand der Technik ist, das man die automatische Bereichswahl
abschalten kann, wenn man es satt hat, nicht nur die Zahlen ablesen zu
müssen, sondern auch noch immer nach dem aktuellen Messbereich gucken zu
müssen.
m.n. schrieb:> dann muß man diese beiden Timer synchronisieren.
???
Das Messprinzip beruht gerade darauf, dass sie nicht synchron sind,
einer läuft nämlich mit Systemtakt, der andere mit der zu messenden
Frequenz.
Aus diesem Prinzip ergibt sich schon zwingend, dass sie unmöglich
synchron sein können.
Tatsächlich ist das aber nur die halbe Wahrheit, denn in gewissem Umfang
sind sie doch synchron, der externe Takt über den Tn-Eingang wird
nämlich synchronisiert, bevor er tatsächlich an den Timer gelangt. Das
leistet die Hardware des AVR (ist auch so dokumentiert).
Und damit sind beide Timer sozusagen "benutzungstechnisch" natürlich in
einer Taktdomäne, weswegen eine deterministische Auswertung kein Problem
darstellt. Man muss halt nur korrekt programmieren können...
Der Nachteil der Synchronisierung mit dem Systemtakt ist eine gewisse
Unsicherheit der Messung, die man einfach dadurch unwichtig macht, dass
man das Messintervall groß genug wählt, deutlich größer als vier
Systemtakte, denn das ist der maximal durch die Synchronisierung
erzeugte Messfehler.
m.n. schrieb:> dann muß man diese beiden Timer synchronisieren.
Nö, wieso denn? Timer 1 zählt die T1 Pulse, Timer 0 liefert einen z.B.
Tickertakt (1 Sekunde, 1/10tel Sekunde oder wasauchimmer).
Der Timeroverflow des externen Counters (Timer 1)ist für 24-bit Werte
reserviert und die Timer0 ISR ist der Ticker, in der Timer 1 gelesen und
zurückgesetzt wird. Und man hat Pulse/Tickerzeit - Fertig. Timer1 ISR
kann man sich sparen, wenn die 64k Pulse/Tickerzeit reichen.
>> dann muß man diese beiden Timer synchronisieren.
ich denke, da ist was anderes gemeint.
Der gute alte Frequenzzähler hatte die Torzeit. Hardwaremäßig wurden die
Impulse während dieser Zeit gezählt. Vor ein paar Jahren habe ich einen
Zähler für das 40m Band auf dem m8 programmiert. Das einzige saubere
war, die Torzeit (weiß nicht mehr, welcher T0,1,2) an den Reset des
(externen) Vorteilers zu geben, damit ich das Pulspaket genau der
Torzeit zählen kann. Wenn man denn einen Vorteiler oder ein anderes
externes Gatter hat. Hat man das nicht, muß man zu Anfang oder Ende der
Torzeit einen Timer-Interrupt bekommen und damit den Impuls-Zähler
auslesen. Dabei ist es die Hoffnung (mehr nicht), daß von diesem
Timer-Interrupt bis zum Register lesen die Software immer gleich lang
ist sonst ist die Torzeit unterschiedlich. Fehler, und keiner hat's
gemerkt. Für 3 Stellen reicht es auch so.
Bin ich noch up-to-date mit der Info, daß das Gate des Zählers
hardwareseitig fehlt, oder gibt es was Neues?
Philipp G. schrieb:>> Immer noch falsch. Deine max. 200.000 U/min = 3,3kHz>> Der Sensor gibt aber nur 1/8 davon aus, also 416Hz. Laaaaaangsaaaam>> Hm, hat was, ja.
Ja, da hab ich aber den Faktor 11 vergessen. Ist aber nicht tragisch,
11*420Hz sind auch nur 4,6kHz, da muss man halt den Prescaler auf 64
verringern, dann paßt es wieder.
> 1'000'000 us / 2, weil die Zeit gemessen wird, bis von low wieder ein> high einliegt, und nicht die volle Periode.
Funktioniert so nicht wirklich gut. Du willst die PERIODENDAUER messen,
als von HIGH-LOW zu HIGH-LOW Flanke! Nicht die LOW oder HIGH Zeiten! Ok,
du kannst Glück haben, weil der Sensor intern durch 8 teilt, da kommen
IMMER exakt 50% Tastverhältnis raus und es funktioniert.
> Meinst Du das so:> // method 2> Serial.println(getFrequency(3));> }>> long getFrequency(int pin) {> #define SAMPLES 256> long freq = 0;> for(unsigned int j=0; j<SAMPLES; j++) freq+= 500000/pulseIn(pin, HIGH,> 250000);> return freq / SAMPLES;> }
Nö, das ist wieder halbgarer Arduino-Murks.
> Da ist halt immer noch die PulseIn Funktion drin, mangels Wissen wie man> es besser machen könnte :(
Sagte ich bereits, mit einer ISR, welche auf die Flanke eine externen
Interrupts reagiert.
> Damit bin ich überfordert.
Tja, dann mußt du entweder,
- es lernen
- jemanden finden der dir beim Lernen hilft
- jemanden finden, der dir das Programm schreibt
- es vergessen
Wähle.
Falk B. schrieb:>> Hm, hat was, ja.>> Ja, da hab ich aber den Faktor 11 vergessen.
Ja, wäre schon übel gewesen mich grad zweimal zu verrechnen.
Falk B. schrieb:> /*> RPM counter for turbo fan> */
Das ist ein Kompressor, kein CPU Lüfter. :)
Aber Danke Dir Falk!!!! Scheint zu gehen. Nächste Herausforderung ist
nun, die Luftmasse (nicht Luftmenge!) zu berechnen. Aber das muss ich
erstmal aufbereiten und hier vorstellen.
Wie funktioniert eigentlich dieser Sensor? Ist das nur ein kapazitiver
Näherungssensor oder etwas Spezielles drin? Nur der Sensor kostet gut
400USD.
Philipp G. schrieb:> Nächste Frage, die Ausgabge der korrigierten RPM in Bezug auf Luftmasse.> Wie kann ich die Formel vereinfachen? Hatte in Mathe einen Fensterplatz> :)
Was willst du da groß vereinfachen? Und was ist bei dir sq()?
Die Wurzel oder das Quadrat?
Außerdem hast du einen Unterschied zwischen dein Formel im Kommentar und
im echten Code? Welche stimmt nun?
Falk B. schrieb:> Außerdem hast du einen Unterschied zwischen dein Formel im Kommentar und> im echten Code? Welche stimmt nun?
Das ist einer der Gründe warum man Kommentare in Quellcodes meiden
sollte wie der Teufel das Weihwasser.
Die Wurzel stimmt natürlich, anbei (Beilage) noch die OEM Formel dazu.
Dann hiesse der Code:
1
voidloop(){
2
uint16_trpm_1k;
3
intrpm_1k_corr=0;// corrected turbo speed
4
intTempInF=0;// inlet temp in Fahreinheit
5
intTinC=0;// inlet temp in Celcius
6
7
// calc corrected rpm
8
// convert Temp in from celsicus to fahreinheit
9
if(TinC<0)
10
{// no need to convert minus degrees
11
TinC=0;
12
}
13
TempinF=(TinC*1.8)+32// works only for pos. degrees
14
15
// calc corrected rpm
16
uint16_trpm_1k_corr=rpm1k/(sq(TempinF+460)/545));
17
}
Ist Wurzel ziehen sehr rechenintenstiv? Wäre noch was zu vereinfachen,
eher nicht, oder?
Könnte man nicht die Faktorisierung + 460 / 545 direkt auf Celsius
ummünzen? Wie gesagt, bin eine komplette doofnuss in Mathe.
edit: Notiz an mich selber, doch, es muss einfacher gehen. Weil 545 -
460 sind umgerechnet 30°C, was Garrett mit atmospheric conditions wohl
meint. Dann könnte ich dieser Faktor schon auf C anpassen und mir die
Fahreinheit Konvertierung sparen.
Philipp G. schrieb:> Die Wurzel stimmt natürlich, anbei (Beilage) noch die OEM Formel dazu.>> Dann hiesse der Code:> void loop() {> uint16_t rpm_1k;> int rpm_1k_corr = 0; // corrected turbo speed> int TempInF = 0; // inlet temp in Fahreinheit> int TinC = 0; // inlet temp in Celcius>> // calc corrected rpm> // convert Temp in from celsicus to fahreinheit> if (TinC < 0)> { // no need to convert minus degrees> TinC = 0;> }> TempinF = (TinC * 1.8) + 32 // works only for pos. degrees
Das ist Unsinn, man kann auch negative Celsiustemperaturen in Fahrenheit
umrechnen, sogar mit der gleichen Formel!
https://de.wikipedia.org/wiki/Grad_Fahrenheit#Umrechnung> // calc corrected rpm> uint16_t rpm_1k_corr = rpm1k / (sq(TempinF + 460) / 545));
Was ist dieses sq() Funktion? Die normale Wurzel heißt sqrt (Square
root, Quadratwurzel)
sq() bedeutet square, das ist das QUADRAT!!! Somit ist sie hier FALSCH!
RTFM!
https://www.arduino.cc/reference/en/language/functions/math/sq/> Ist Wurzel ziehen sehr rechenintenstiv?
Jain, kann schon einige Dutzend Takte brauchen. Für dein
Ansteuerfrequenz von vielleicht 100 Hz ist das unkritisch.
> Wäre noch was zu vereinfachen,> eher nicht, oder?
Oder.
> Könnte man nicht die Faktorisierung + 460 / 545 direkt auf Celsius> ummünzen? Wie gesagt, bin eine komplette doofnuss in Mathe.
Warum? Das bissel Subtrahieren und Dividieren macht der Arduino im
Schlaf.
> edit: Notiz an mich selber, doch, es muss einfacher gehen. Weil 545 -> 460 sind umgerechnet 30°C, was Garrett mit atmospheric conditions wohl> meint. Dann könnte ich dieser Faktor schon auf C anpassen und mir die> Fahreinheit Konvertierung sparen.
Alles nebensächlich.
Wir waren doch gestern uns bezüglich der Ansteuerfrequenz einig:
Falk B. schrieb:> Ja, da hab ich aber den Faktor 11 vergessen. Ist aber nicht tragisch,> 11*420Hz sind auch nur 4,6kHz, da muss man halt den Prescaler auf 64> verringern, dann paßt es wieder>Jain, kann schon einige Dutzend Takte brauchen. Für dein>Ansteuerfrequenz von vielleicht 100 Hz ist das unkritisch.>
~4.5khz
Falk B. schrieb:> Das ist Unsinn, man kann auch negative Celsiustemperaturen in Fahrenheit> umrechnen, sogar mit der gleichen Formel!
Ich muss gleich mal schauen woher ist das hab mit den Minus
Temperaturen.
Falk B. schrieb:> Was ist dieses sq() Funktion? Die normale Wurzel heißt sqrt (Square> root, Quadratwurzel)
Hab es genau andersrum erwartet. Hast Recht.
Falk B. schrieb:> Jain, kann schon einige Dutzend Takte brauchen. Für dein> Ansteuerfrequenz von vielleicht 100 Hz ist das unkritisch.
Technische Verständnisfrage. Wenn der jetzt für die Wurzel länger zum
Rechnen braucht, und von 'oben' kommt ein Interrupt rein, was macht dann
der uC? Springt der zurück oder was?
Darf man Dir eigentlich auch eine PN schreiben?
Philipp G. schrieb:> Wir waren doch gestern uns bezüglich der Ansteuerfrequenz einig:
Schon, aber du redest von einer anderen Sache.
> Falk B. schrieb:>> Ja, da hab ich aber den Faktor 11 vergessen. Ist aber nicht tragisch,>> 11*420Hz sind auch nur 4,6kHz, da muss man halt den Prescaler auf 64>> verringern, dann paßt es wieder>>>Jain, kann schon einige Dutzend Takte brauchen. Für dein>>Ansteuerfrequenz von vielleicht 100 Hz ist das unkritisch.>>> ~4.5khz
Alles richtig, aber am Problem vorbei. Die 4,5kHz sind die maximale
EINGANGSfrequenz am Arduino, welche vom Drehzahlsensor kommt.
Die 100 Hz von denen ich rede, ist die UPDATE-Frequenz für deine
Drehzahlanzeige. D.h. die Umrechnung von Periode in RPM und den ganze
Rest erfolgt nur mit 100 Hz, auch denn der Interrupt im Hintergrund mit
bis zu 4,5kHz arbeitet. Wie wird deine Anzeige denn angesteuert?
> Falk B. schrieb:>> Was ist dieses sq() Funktion? Die normale Wurzel heißt sqrt (Square>> root, Quadratwurzel)>> Hab es genau andersrum erwartet. Hast Recht.
Erwartet? Schon mal was von RTFM gehört? Nein, das ist kein Oldiesender
;-)
> Technische Verständnisfrage. Wenn der jetzt für die Wurzel länger zum> Rechnen braucht, und von 'oben' kommt ein Interrupt rein, was macht dann> der uC? Springt der zurück oder was?
Wohin denn zurück? Weißt du überhaupt, wie ein Interrupt
funktioniert?
Deine Umrechnung von period in RPM etc. läuft im Hauptprogramm in einer
Endlosschleife, sinnvollerweise noch etwas gedrosselt, damit die CPU
nicht mit Maximalgeschwindigkeit da immer wieder durchrennt (das tut der
zwar nicht weh, ist aber sinnlos und in bestimmten Konstellationen
kontraproduktiv). Das Hauptprogramm kann jederzeit von einem Interrupt
unterbrochen werden. Davon merkt es gar nichts und es wird auch nicht
gestört, außer daß die Ausführung natürlich etwas länger dauert. Selbst
wenn die Wurzelberechung ein paar Dutzend mal durch einen Interrupt
unterbrochen werden sollte, so what!
> Darf man Dir eigentlich auch eine PN schreiben?
Darf man.
Falk B. schrieb:>> Darf man Dir eigentlich auch eine PN schreiben?>> Darf man.
Alles klar danke Dir Falk, ich baue das jetzt erstmal auf.
Bezüglich der PN, den letzten fanboy den ich angeschrieben habe meinte
in einem lapidaren Ein, nein Halbzeiler dass keine Unterstützung per Pn
möglich ist ;)
Philipp G. schrieb:> Mit einer EINGANGSFREQUENZ und serial.println funktioniert es bis 20kHz
Und was ist mit Deiner eingangs formulierten Forderung von 165 kHz?
Die sind es ja nun bei weitem nicht.
m.n. schrieb:>> Mit einer EINGANGSFREQUENZ und serial.println funktioniert es bis 20kHz>> Und was ist mit Deiner eingangs formulierten Forderung von 165 kHz?> Die sind es ja nun bei weitem nicht.
Ja, Gott sei Dank lag ich da weit daneben. Die Frequenz am Eingang wird
max. bei 5kHz liegen.
Cyblord -. schrieb:> Das ist einer der Gründe warum man Kommentare in Quellcodes meiden> sollte wie der Teufel das Weihwasser.
Der andere, wahre Grund ist "Arbeitsplatzsicherung" :-)
Dieter F. schrieb:> Cyblord -. schrieb:>> Das ist einer der Gründe warum man Kommentare in Quellcodes meiden>> sollte wie der Teufel das Weihwasser.>> Der andere, wahre Grund ist "Arbeitsplatzsicherung" :-)
Das ist natürlich eine Möglichkeit ;-)
Nein, der wirklich wahre Grund ist, dass jeder Kommentar dein Versagen
dokumentiert, deine Intention an dieser Stelle verständlich in Code
auszudrücken. Jeder Kommentar ist ein Eingeständnis des Scheiterns und
sollte den bitteren Geschmack der Niederlage auf deiner Zunge
hinterlassen.
Cyblord -. schrieb:> Falk B. schrieb:>> Außerdem hast du einen Unterschied zwischen dein Formel im Kommentar und>> im echten Code? Welche stimmt nun?>> Das ist einer der Gründe warum man Kommentare in Quellcodes meiden> sollte wie der Teufel das Weihwasser.
Diese Aussage ist so allgemein Unsinn. Man muss REDUNDANTE, und sich
damit tendentiell inkonsistente oder gar widersprüchliche Kommentare
vermeiden. Wenn eine Variable einen passenden Namen hat, ist sie
selbsterklärend und muss nicht kommentiert werden, dito bei Funktionen.
Strukturierte Programmierung auf Mikrocontrollern
Cyblord -. schrieb:> Nein, der wirklich wahre Grund ist, dass jeder Kommentar dein Versagen> dokumentiert, deine Intention an dieser Stelle verständlich in Code> auszudrücken. Jeder Kommentar ist ein Eingeständnis des Scheiterns und> sollte den bitteren Geschmack der Niederlage auf deiner Zunge> hinterlassen.
Unfug^3.
"Je genialer die Idee, um so nötiger der Kommentar."
Wenn gleich die Masse an Code sicher nicht genial ist sondern
bestenfalls gut bis OK.
Falk B. schrieb:> Diese Aussage ist so allgemein Unsinn. Man muss REDUNDANTE, und sich> damit tendentiell inkonsistente oder gar widersprüchliche Kommentare> vermeiden.
Kommentare sind zu vermeiden u.a. weil sie schnell veralten. Sie werden
nicht mit refaktoriert. Sie werden beim Kompilieren nicht überprüft. Sie
stehen evt. ewig lange da und sind schon lange überholt. In praktisch
jedem Projekt finden sich solche Leichen.
"Je genialer die Idee, um so nötiger der Kommentar."
Die Idee spielt keine Rolle, es kommt darauf an wie du dich in Code
ausdrücken kannst. Dann ist es egal ob dein Code genial ist oder nicht.
Die Idee dahinter sollte man mit einem Blick auf den Code sehen. DANN
erst kann man beurteilen ob die Idee jetzt OK oder Genial ist.
Der Kommentar ist eben nur die Krücke, weil du dich nicht in Code
verständlich ausdrücken kannst, sondern wohl nur in Prosa. Vielleicht
musst du das einfach üben anstatt die Prosa zu verteidigen.
Warum denkst du (als PROGRAMMIERER), Prosa sei grundsätzlich besser
verständlich als der Code selbst? Das ist eine absurde These.
Wenn ich mich in Deutsch besser ausdrücken kann, als in Suaheli, liegt
es dann an der Sprache oder an meinen Fähigkeiten?
Cyblord -. schrieb:> Falk B. schrieb:>> Diese Aussage ist so allgemein Unsinn. Man muss REDUNDANTE, und sich>> damit tendentiell inkonsistente oder gar widersprüchliche Kommentare>> vermeiden.>> Kommentare sind zu vermeiden u.a. weil sie schnell veralten.
Kann sein, ist aber nicht algemeingültig. Aber OK, es stimmt schon, Code
und Kommentar können auseinanderdriften, beides sychron zu halten ist
ebenso aufwändig und unter Softwerkern unbeliebt wie echte Doku
schreiben 8-0
> Sie werden> nicht mit refaktoriert. Sie werden beim Kompilieren nicht überprüft.
Muss man auch nicht. Ein Kommentar ist ein Kommentar.
> Sie> stehen evt. ewig lange da und sind schon lange überholt. In praktisch> jedem Projekt finden sich solche Leichen.
Mag sein, ist aber kein zwingender Grund gegen Kommentare.
> "Je genialer die Idee, um so nötiger der Kommentar.">> Die Idee spielt keine Rolle, es kommt darauf an wie du dich in Code> ausdrücken kannst. Dann ist es egal ob dein Code genial ist oder nicht.> Die Idee dahinter sollte man mit einem Blick auf den Code sehen.
Nö, das geht schlicht nicht, zumindest nicht bei anspruchsvollerer und
umfangreicher Software. Denn im Code steht bestenfalls WIE es gemacht
wird, aber nie WARUM!!!
"Zusammenhänge dokumentieren. Die erschliessen sich nicht aus den paar
Zeilen Code, auf die man gerade schaut!
Kommentare sollen die 'Warum'-Frage beantworten und nicht die
'Wie'-Frage! Wie etwas gemacht wird, steht im Code. Aber dort steht
nicht warum es gemacht wird."
Und nur weil viele Leute zu faul und disziplinlos sind, bei größeren
Änderungen auch den Kommentar mitzuziehen, ist das kein ultimatives
Argument gegen SINNVOLLE Kommentare!
Falk B. schrieb:> Nö, das geht schlicht nicht, zumindest nicht bei anspruchsvollerer und> umfangreicher Software. Denn im Code steht bestenfalls WIE es gemacht> wird, aber nie WARUM!!!
Genau das ist der Punkt. Schaut euch selber Codes an die ihr selber vor
Jahren programmiert habt, sind alle les- und nachvollziehbar, aber WARUM
macht er das? Ist doch gar nicht nötig. Dann reisst man alles
auseinander im Sinne von ist nicht nötig und zwei Tage später folgt erst
die Erkenntnis, warum es eben doch nötig war.
So geht es mir jedesmal (Ich rede jetzt nicht von uC Programmen sondern
auf PC/.net/java/shell/etc).
Philipp G. schrieb:> Genau das ist der Punkt. Schau euch selber Codes an die ihr vor Jahren> programmiert habt, sind alle les- und nachvollziehbar, aber WARUM macht> er das? Ist doch gar nicht nötig. Dann reisst man alles auseinander im> Sinne von ist nicht nötig und zwei Tage später folgt erst die> Erkenntnis, warum es eben doch nötig war.
Das liegt dann leider an deinem Code und nicht an der grunsätzlichen
Ausdrucksschwäche von Quellcode.
Es reicht natürlich nicht, nur keine Kommentare zu schreiben. In erster
Linie musst du den Code so schreiben, dass du keine Kommentare brauchst.
Cyblord -. schrieb:> Das liegt dann leider an deinem Code und nicht an der grunsätzlichen> Ausdrucksschwäche von Quellcode.
Gutes Beispiel steht weiter oben. Warum teilt der durch 8 und
multipliziert dann mal 11? na? Warum? Der Sensor gibt doch doch 1/8tel
der Drehzahl raus.
Weil eben nirgendwo steht, dass der Turbo nun mal 11 Schaufeln hat. Das
ist hier und jetzt jedem klar, nur nicht unbedingt in 5 Jahren.
Philipp G. schrieb:> Gutes Beispiel steht weiter oben. Warum teilt der durch 8 und> multipliziert dann mal 11? na? Warum? Der Sensor gibt doch doch 1/8tel> der Drehzahl raus.>> Weil eben nirgendwo steht, dass der Turbo nun mal 11 Schaufeln hat. Das> ist hier und jetzt jedem klar, nur nicht unbedingt in 5 Jahren.
Das ist Quatsch Cylord, reden wir mal von grösseren Software Projekten
mit x Mitarbeitern und n Mitarbeiter. Du brauchst dazu eine lückenlose
Doku, auch wenn das nur Kommentare sind.
Philipp G. schrieb:> Cyblord -. schrieb:>> Das liegt dann leider an deinem Code und nicht an der grunsätzlichen>> Ausdrucksschwäche von Quellcode.>> Gutes Beispiel steht weiter oben. Warum teilt der durch 8 und> multipliziert dann mal 11? na? Warum? Der Sensor gibt doch doch 1/8tel> der Drehzahl raus.>> Weil eben nirgendwo steht, dass der Turbo nun mal 11 Schaufeln hat. Das> ist hier und jetzt jedem klar, nur nicht unbedingt in 5 Jahren.
Und du bist der Meinung das könnte man nicht so hinschreiben dass man
ohne Kommentar weiß was gemacht wird, und warum?
Nur weil ein C-Vollnoob (sorry) da oben irgendwas hinkritzelt, ist das
jetzt der Beweis für die Notwendigkeit von Kommentaren?
Cyblord -. schrieb:> Philipp G. schrieb:>> Cyblord -. schrieb:>>> Das liegt dann leider an deinem Code und nicht an der grunsätzlichen>>> Ausdrucksschwäche von Quellcode.>>>> Gutes Beispiel steht weiter oben. Warum teilt der durch 8 und>> multipliziert dann mal 11? na? Warum? Der Sensor gibt doch doch 1/8tel>> der Drehzahl raus.>>>> Weil eben nirgendwo steht, dass der Turbo nun mal 11 Schaufeln hat. Das>> ist hier und jetzt jedem klar, nur nicht unbedingt in 5 Jahren.>> Und du bist der Meinung das könnte man nicht so hinschreiben dass man> ohne Kommentar weiß was gemacht wird, und warum?
Na dann zeigt doch einfach mal, wie du das ohne Kommentare
selbsterklärend aufschreiben würdest.
Cyblord -. schrieb:> Und du bist der Meinung das könnte man nicht so hinschreiben dass man> ohne Kommentar weiß was gemacht wird, und warum?>> Nur weil ein C-Vollnoob da oben irgendwas hinkritzelt, ist das jetzt der> Beweis für die Notwendigkeit von Kommentaren?
Was hast Du dagegen? Die werden nicht kompiliert, die brauchen keinen
nennenswerten Platz, also schreiben wir doch Sensor Typ und Turbo
einfach zu.
Das ist Quatsch Cylord, reden wir mal von grösseren Software Projekten
mit x Mitarbeitern und n Klassen. Du brauchst dazu eine lückenlose
Doku, auch wenn das nur Kommentare sind.
Falk B. schrieb:> Na dann zeigt doch einfach mal, wie du das ohne Kommentare> selbsterklärend aufschreiben würdest.
Also bitte. Aber das ist doch eher trivial.
Ein Anfang wäre, das ganze in eine sinnige Funktion zu packen, z.B
calculateRPM(). Mit passenden Parametern natürlich.
Das bringt erstmal dass, das ich um das Programm zu lesen und verstehen
zu können, was passiert, die Formel gar nicht sehen muss. Die
interessiert mich dafür nämlich gar nicht.
Dann in dieser Funktion NATÜRLICH errstmal die Konstanten benamen. Und
die Variablen ebenfalls sinnvoller benamen.
Mehr braucht man ja gar nicht für eine popelige Funktion die eine
Drehzahl berechnet.
> Was hast Du dagegen?
Habe ich schon ausgeführt.
Philipp G. schrieb:> Was hast Du dagegen? Die werden nicht kompiliert, die brauchen keinen> nennenswerten Platz, also schreiben wir doch Sensor Typ und Turbo> einfach zu.>> Das ist Quatsch Cylord, reden wir mal von grösseren Software Projekten> mit x Mitarbeitern und n Klassen. Du brauchst dazu eine lückenlose> Doku, auch wenn das nur Kommentare sind.
Es gibt sogar Software wie doxygen, die aus Kommentaren eine schön
lesbare, strukturierte Doku macht. Und der Kommentar im Quelltext ist
DEUTLICH näher am realen Code und kann auch deutlich einfacher synchron
gehalten werden als ein "weit entferntes" Word-Dokument.
Ich denke Cylord meint in unserem Beispiel sowas hier:
1
// no comments at all from now on;)
2
contintiTurboCompressorWheelBlades=11;
3
contintiSensorOutFreqDivider=8;
Das mag für obigen Code besser ausehen, ja. Aber nicht für grössere
Software Projekte. Da kommt man um Kommentare nicht umhin. Weil es für
andere nachvollziehbar sein muss. Schon mal nur für ein Code Review,
Security Audits, etc.
>> Das mag für obigen Code besser ausehen, ja.
Und warum hast du das dann nicht gleich so gemacht? Faul beim Coden,
aber dann fleißig beim Kommentieren? Bist du Programmierer oder
Schriftsteller?
Und es sieht nicht besser aus, es erklärt sich bereits selbst. Es gibt
nicht um Ästhetik.
Und irgendwelche magic numbers sollten sowieso nirgendwo auftauchen.
> Aber nicht für grössere Software Projekte.
Ach in größere Softwareprojekte klatscht man unlesbaren Code und
kommentiert dann aber um so mehr?
Komisch, bei meinen größeren Projekten bisher ging das alles sehr gut.
GERADE bei komplexer Software braucht man sauberen Code. Beim 100 Zeilen
Tool ist im Zweifel alles egal.
Falk B. schrieb:> "Je genialer die Idee, um so nötiger der Kommentar."
Es passiert wirklich selten, dass wir einer Meinung sind, aber hier sind
wir uns einig.
Ein Kommentar ist genau dann nötig und wünschenswert, wenn er das
Konzept des Codes dokumentiert oder ein spezielles, aus irgendwelchen
Gründen trickreich gelöstes Detail (vom Würgaround um fremde Fehler
[eigene behebt man natürlich] bis hin zu einer ungewöhnlichen
Optimierung, die im allgemeinen Fall nur Schaden anrichten würde, aber
im speziellen Fall den Unterschied zwischen "geht" und "geht nicht"
ausmacht).
Ein Kommentar ist unnötig, wenn er nur in Prosa das wiedergibt, was
links von ihm selber im Quelltext sowieso zu lesen ist. Wenn es denn zu
lesen ist. Einige C/C++-Klartext-Verschlüssler finden es ja toll, wenn
möglichst niemand versteht, was sie da hingeschrieben haben. Gerade die
neigen allerdings dann auch eher nicht dazu, irgendwelche Kommentare
hinzuzufügen.
Cyblord scheint mir ein recht sicherer Kandidat für diesen Schlag
Programmierer zu sein...
Cyblord -. schrieb:> Der Kommentar ist eben nur die Krücke, weil du dich nicht in Code> verständlich ausdrücken kannst, sondern wohl nur in Prosa. Vielleicht> musst du das einfach üben anstatt die Prosa zu verteidigen.>> Warum denkst du (als PROGRAMMIERER), Prosa sei grundsätzlich besser> verständlich als der Code selbst? Das ist eine absurde These.
Mal im Ernst: Nein.
Ein Kommentar soll nicht erklären, was getan wird (das genau tut der
Code) sondern, warum es getan wird.
nicht klar ist, aus was sich obiger faktor zusammensetzt.
WIE rechnet er das ist klar, aber warum mit diesem Faktor?
Grad in diesem Moment, wo du das liest weißt du es auch nicht. Du weißt
das erst, nachdem du nach oben scrollst und die Kommentare liest.
Klar was ich meine?
c-hater schrieb:> Einige C/C++-Klartext-Verschlüssler finden es ja toll, wenn> möglichst niemand versteht, was sie da hingeschrieben haben. Gerade die> neigen allerdings dann auch eher nicht dazu, irgendwelche Kommentare> hinzuzufügen.>> Cyblord scheint mir ein recht sicherer Kandidat für diesen Schlag> Programmierer zu sein...
Sorry, ich propagiere hier gerade das exakte GEGENTEIL. Nämlich Code so
zu schreiben dass er von vorn herein verständlich ist. Warum wird mir
hier dann jetzt sowas unterstellt?
Dieter F. schrieb:> Ein Kommentar soll nicht erklären, was getan wird (das genau tut der> Code) sondern, warum es getan wird.
Warum erklärst du es nicht in Code? Warum beim coden irgendwas
hinschludern um es dann durch einen Kommentar erklären zu müssen?
Cyblord -. schrieb:> Sorry, ich propagiere hier gerade das exakte GEGENTEIL. Nämlich Code so> zu schreiben dass er von vorn herein verständlich ist. Warum wird mir> hier dann jetzt sowas unterstellt?
Weil du Kommentare als generell unnütz dargestellt hast. Und weil genau
das absolut typisches Verhalten gerade dieser Klartextverschlüssler ist.
Ich bin seit 35 Jahren im Geschäft, ich kenne diese Typen nur zu gut...
Dieter F. schrieb:> Cyblord -. schrieb:>> Warum erklärst du es nicht in Code?>> Erkläre mal in Code, <b>warum</b> Du 0,175647 vom Sensor-Wert abziehst.
Das kommt darauf an warum du es tust.
Vielleicht wird es klar, wenn du 0,175647 erst mal ordentlich benennst?
z.B.
Cyblord -. schrieb:> Vielleicht wird es klar, wenn du 0,175647 erst mal ordentlich benennst?
Nö - dann schreibst Du vielleicht " - KorrekturFaktor"" aber kein Mensch
weiß, welchen "KorrekturFaktor" und warum genau Du meinst.
Dieter F. schrieb:> Cyblord -. schrieb:>> Ist doch völlig klar jetzt oder?>> Nö - warum?
Du wenn ich mit bockigen Kindern diskutieren will brauch ich nicht hier
her kommen. Entweder du diskutierst ordentlich oder wir lassen es. ja?
Cyblord -. schrieb:> CALIBRATION_OFFSET=0.175647;
Damit kann doch kein Mensch etwas anfangen, wenn er nicht im Thema ist -
oder?
Vergiss es - bleib in Deiner Welt. Wir werden uns (beruflich) sowieso
nie begegnen :-)
Dieter F. schrieb:> Cyblord -. schrieb:>> CALIBRATION_OFFSET=0.175647;>> Damit kann doch kein Mensch etwas anfangen, wenn er nicht im Thema ist -> oder?
Sorry. Ich denke wir sind fertig hier.
Cyblord -. schrieb:> Sorry. Ich denke wir sind fertig hier.
Full ack :-) - wie immer
Da fällt mir direkt der blöde Hierarchie-Spruch "Information ist eine
Hol-Schuld" ein ...
Philipp G. schrieb:> doch weil rpm_1k = 10909 / get_period(); // atomic read> access!!!>> nicht klar ist, aus was sich obiger faktor zusammensetzt.>> WIE rechnet er das ist klar, aber warum mit diesem Faktor?>> Grad in diesem Moment, wo du das liest weißt du es auch nicht. Du weißt> das erst, nachdem du nach oben scrollst und die Kommentare liest.>> Klar was ich meine?
du hast meine Frage nicht beantwortet cylord
Philipp G. schrieb:> Philipp G. schrieb:>> doch weil rpm_1k = 10909 / get_period(); // atomic read>> access!!!>>>> nicht klar ist, aus was sich obiger faktor zusammensetzt.>>>> WIE rechnet er das ist klar, aber warum mit diesem Faktor?>>>> Grad in diesem Moment, wo du das liest weißt du es auch nicht. Du weißt>> das erst, nachdem du nach oben scrollst und die Kommentare liest.
Jetzt mal langsam. Erst mal gehört das ordentlich in eine Funktion
gekapselt.
z.B.
1
intcalculateRPM(intperiod);
Dann wird beim ersten lesen klar was hier gemacht wird. Das WARUM ist
hier automatisch drin. Wobei der Funktionsname noch enthalten sollte von
WAS hier genau die RPM gemessen wird. Außer die Funktion ist generisch.
Dann sollte das in der aufrufenden Funktion aber stehen.
Wir abstrahieren hier also erst mal über die Details WIE GENAU von der
Periode (evt. besser benamen!) die RPM berechnet werden.
Das ist nämlich für einen Betrachter erst mal völlig irrelevant für das
Verständnis des Codes.
Nun innerhalb der Funktion calculateRPM kann man alle Konstanten
sinnvoll benennen. Mehr macht dann aber auch keinen Sinn mehr. Man muss
dabei nicht überdrehen.
Berechnet diese Funktion tatsächlich eine bestimmte Formel, und ist man
der Meinung das kann man einfach partout nicht schön darstellen, dann
kann natürlich ein Kommentar hergenommen werden. Das ist ja keine
Religion.
Wie ich Eingangs bereits andeutete, Kommentare lassen sich manchmal
nicht vermeiden. Wichtig ist das entsprechende "Mindset" dass es immer
besser wäre, ohne Kommentar auszukommen.
Dieter F. schrieb:>> CALIBRATION_OFFSET=0.175647;>> Damit kann doch kein Mensch etwas anfangen, wenn er nicht im Thema ist -> oder?
Wenn ich Jahre später die Hardware oder sonstwas anpassen muss, muss ich
wissen wie sich der Korrektur Faktor zusammensetzt. Ein Kommentar wäre
hilfreich.
1
rpm_1k=10909/get_period();// atomic read
2
>>access!!!
Nochmal, obiger Faktor setzt sich wie folgt zusammen:
1
// rpm [RPM] = 1/period[s]/11*60*8 // basic formula
2
// rpm [RPM] = 1/(period[cnt]*4us)/11*60*8 // basic formula using counter result and counter clock
3
// rpm [1000RPM] = 250e3/period[cnts]/11*60*8/1000 // result in units of 1000 RPMs
Erst nachdem ich die Kommentare weggelassen habe, war unklar was mit
10909 gemeint ist. Merkst Du was?
Cyblord -. schrieb:> Wir abstrahieren hier also erst mal über die Details WIE GENAU von der> Periode (evt. besser benamen!) die RPM berechnet werden.
Gut. Dann würdest Du das also so machen?
1
rpm_1k=1/get_period()/11*60*8;
Dann rechne ich doch lieber mit dem Faktor und schreibe die
Zusammensetzung als Kommentar dazu. Klar was ich meine?
Dieter F. schrieb:> Philipp G. schrieb:>> Merkst Du was?>> Meinst Du mich? Dann lies den Thread bitte nochmal richtig.
Nein, ich meine den Cylord, nicht Dich ;) Ich bin der TO, ich kenne den
Thread daher bestens.
Philipp G. schrieb:> Wenn ich Jahre später die Hardware oder sonstwas anpassen muss, muss ich> wissen wie sich der Korrektur Faktor zusammensetzt. Ein Kommentar wäre> hilfreich.
In diesem völlig frei erfundenen Beispiel wäre der Korrekturfactor eben
eine Konstante aus dem Datenblatt. Kein Ergebniss einer Berechnung.
Es kommt schon auf den Kontext an um zu entscheiden wie man am besten an
die Sache ran geht.
> Gut. Dann würdest Du das also so machen?>
1
>rpm_1k=1/get_period()/11*60*8;
2
>
Ne würde ich nicht.
Was ist 11, 60 und 8?
Kurz: Benenne die Konstanten sinnvoll und packe die Berechnung in eine
ebenfalls sinvoll benannte Funktion. Damit hast du mindestens 99%
Dokumentiert. Falls dann WIRKLICH noch Bedarf für die 1% ist reden wir
weiter.
> Dann rechne ich doch lieber mit dem Faktor
Bringt welchen Vorteil? Einfach eine Zahl im Code (Magic Number) sollte
man vermeiden.
> und schreibe die> Zusammensetzung als Kommentar dazu.
Hat keinen Vorteil. Aber z.B. den Nachteil dass eine Änderung der Formel
auch mal ohne Änderung des Kommentars erfolgen kann, wobei der Kommentar
dann irreführend wird.
Nutzt du den Code gleichzeitig zur Dokumentation, ist diese immer up to
date.
> Klar was ich meine?
Klar. Halte ich nur für die falsche Lösung.
Cyblord -. schrieb:>> Dann rechne ich doch lieber mit dem Faktor> Bringt welchen Vorteil? Einfach eine Zahl im Code (Magic Number) sollte> man vermeiden.
Weil der dann jede x us dasselbe rechnet, was man sich durch die
Faktorisierung sparen könnte und stattdessen einen Kommentar dazu
schreibt, wie sich die magic number zusammensetzt, anstatt:
magic = sq(rpm / 60 * 33 / 6.4223 * (200080 - 200203) + 11 - 3);
Mit diesen Zahlen kann ich genauso wenig anfangen. Wenn ich raten
müsste, könnte ich höchstens mir vorstellen dass die 60 was mit Sekunden
oder Minuten zu tun haben könnte, der Rest ist Glaskugel.
Wenn ich dich richtig verstanden habe, möchtest du stattdessen
rpm_1k = iFullSecond / get_period() / iCompressorWheelBlades *
iSecondsperMinute * iFreqDividerSensor;
sehen.
Philipp G. schrieb:> Wenn ich dich richtig verstanden habe, möchtest du stattdessen>> rpm_1k = iFullSecond / get_period() / iCompressorWheelBlades *> iSecondsperMinute * iFreqDividerSensor;
Damit wären zumindest die Bestandteile der Formel ohne jeden Kommentar
dokumentiert.
Zusätzlich kannst du die Konstanten auch noch komfortabel anpassen,
falls nötig. Ohne dir jedes mal zu überlegen welche Zahl jetzt was genau
bedeutet hat.
Wenn das ganze jetzt in der Funktion calculateCompressorRPM() steckt,
dann weiß ich doch sofort was hier passiert. Beim überfliegen. Wobei mir
da die konkrete Formel erst mal egal ist, aber auch wenn ich dann auf
die Formel schauen möchte, sehe ich sofort was ungefähr gerechnet wird.
Philipp G. schrieb:> Mit diesen Zahlen kann ich genauso wenig anfangen. Wenn ich raten> müsste, könnte ich höchstens mir vorstellen dass die 60 was mit Sekunden> oder Minuten zu tun haben könnte, der Rest ist Glaskugel.>> Wenn ich dich richtig verstanden habe, möchtest du stattdessen>> rpm_1k = iFullSecond / get_period() / iCompressorWheelBlades *> iSecondsperMinute * iFreqDividerSensor;>> sehen.
na dann könnte man ja auch den pre rechnen lassen
Falk mein Guter, irgendwo haben wir uns verrechnet.
Es funktioniert nicht. Aufbau:
Input_freq_generated: 1kHz
Input_freq_measured: 1kHz
Display: 87k (87'000 U/min)
Nach meiner Rechnung sollte es grad die Hälfte sein:
RPM = 480 * (Freq_OUT[Hz] / compressorwheelcount
RPM = 480 * (1000 / 11)
RPM = 43'636 was falsch ist.
* 2 multipliziert stimmt es aber genau. Was habe ich falsch gemacht? Wir
messen ja die volle Periodendauer, ich komme grad nicht dahinter.
Anbei nochmal der Code:
Es gibt News. Der obige Code funktioniert nicht mit dem Sensor, wohl
aber mit dem FG (Bilder siehe ein Post vorher).
Das Tastverhältnis ist jenseits von 50/50, der Impuls ist zu schmal, so
meine Vermutung. Was eigentlich keine Rolle spielen sollte wenn der die
gesamte Periodendauer messen sollte.
Aber von vorne:
Erstmal habe ich versucht, einen geeigneten Testaufbau zu machen um dem
Sensor Signale zu entlocken.
Erster Versuch:
Eine gedruckte Platte mit 4 Gewindestäbe drin. Interessant hierbei war,
dass der Dremel massive Störungen verursacht, Kollektorfeuer oder die
PWM Ansteuerung. fail01.
Zweiter Versuch:
Gedrehte und gefräste Platte mit 11 'Schaufeln'. Keine Wirkung, lag aber
evtl. auch daran, dass die Drehbank nicht schneller als 1300U/min dreht.
fail02.
Dritter Versuch:
Einen echten Turbo aus dem Lager genommen und den Sensor behelfsmässig
am Eingang angeschlossen, da dieser Turbo von Haus aus keine Aufnahme
für den Speedsensor hat. Funktioniert auf dem DSO perfekt.
Leider nicht mit dem Code: Der gibt nur 0 oder 30 aus, und das
unabhängig der Drehzahl vom Turbo. -> result01.jpg
Auf dem DSO, max 120Hz:
https://www.youtube.com/watch?v=_UvA7HQ0pzg
Auf dem DSO, max 189Hz:
https://www.youtube.com/watch?v=Rcma4bJRmx4
-> Die Impulsbreite ist immer 120us lang.
[Hinweis zu den Videos: Mir ist während der Aufnahme versehentlich die
Masseklemme abgerutscht, daher das Rauschen]
Ich fand hier sprechender, Videos zu machen als Bilder. Mehr Speed
wollte ich dem Turbo ohne die Öldruckversorgung nicht zumuten.
Evtl. hat jemand von euch eine Idee.
Durch den Fehler wurde INT0 auf "any edge" konfiguriert und dadurch mißt
dein Interrupt immer den Abstand zwischen aufeinanderfolgenden Flanken
und NICHT von steigender zu steigender! Damit ist die gemessene Frequenz
in deinem Test doppelt so hoch wie real.
Falk B. schrieb:> Durch den Fehler wurde INT0 auf "any edge" konfiguriert und dadurch mißt> dein Interrupt immer den Abstand zwischen aufeinanderfolgenden Flanken> und NICHT von steigender zu steigender! Damit ist die gemessene Frequenz> in deinem Test doppelt so hoch wie real.
Dank Dir Falk.
Das erklärt jetzt auch das Verhalten im vorher beschriebenen Post?
Philipp G. schrieb:> Dank Dir Falk.>> Das erklärt jetzt auch das Verhalten im vorher beschriebenen Post?
Ja klar. Nimm mal die noch nicht korrigierte Software und stell mal 25%
Tastverhältnis am Funktionsgenerator ein. Dann pendelt deine Anzeige
auch zwischen dem vierfachen und 1,5 fachen Wert.