Hallo Forum Hab schon die suche bemüht leider konnte ich bzgl. lookup tables nix beriedigendes finden Bin gerade dabei ein einfaches Zündungsstuergerät zu programmieren. Drehzahlerassung und erkennung des ot laufen schon soweit nun möchte ich im 1. schritt anhand der drehzahl einen zündwinkel ausgeben. Sprich eine Kennlinie in der steht bei der und der Drehzahl so der und der Zündwinkel ausgegeben werden. Wie kann ich das am einfachsten in C realisieren? Gibts dann auch möglichkeit zischen den stützstellen zu interpolieren?? Danke ür Eure Antworten
Also wenn Du einen passenden Lookuptable mit Stützstellen schon hast und die Funktion dazu, wo liegt dann Dein Problem ? Oder müssen es Floats sein ?
peter wrote: > nun möchte ich im 1. schritt anhand der drehzahl einen zündwinkel > ausgeben. Sprich eine Kennlinie in der steht bei der und der Drehzahl so > der und der Zündwinkel ausgegeben werden. > Gibts dann auch > möglichkeit zischen den stützstellen zu interpolieren?? Sicher. Ich denke mal lineare Interpolation würde durchaus ausreichen. > Wie kann ich das am einfachsten in C realisieren? Am einfachsten ist es, wenn du den Zündwinkel für Drehzahlen in einem bestimmten Raster vorgibst. Sagen wir mal für alle Vielfachen von 500 U/min hast du einen Zündwinkel. Dann brauchst du noch ein Array, in dem für alle diese Drehzahlen der zugehörige Zündwinkel abgelegt ist. uint8_t Winkel[] = { 80, /* 0 U/min */ 82, /* 500 */ 82, /* 1000 */ 85, /* 1500 */ 87, /* 2000 */ .... } Und dann brauchst du jetzt natürlich noch eine Formel, die dir, ausgehend von einer bestimmten Drehzahl ausrechnet, an welcher Stelle im Array der zugehörige Wert zu finden ist. Könnte zb so aussehen: uint16_t Drehzahl; uint8_t Index; ..... irgendwie kommst du zu deiner Drehzahl /* die rechnen wir um in einen Index in die Winkel-Tabelle: */ Index = Drehzahl / 500; einzustellender_Winkel = Winkel[ Index ]; mit dieser einfachen Berechnung kriegst du für Drehzahlen 0 bis 499 Winkel[0] 500 bis 999 Winkel[1] 1000 bis 1499 Winkel[2] 1500 bis 1999 Winkel[3] .... Wenn dir eine Abstufung von 500 U/min nicht reicht, kannst du natürlich auch feiner unterteilen.
PCler wrote: > Also wenn Du einen passenden Lookuptable mit Stützstellen schon hast und > die Funktion dazu, wo liegt dann Dein Problem ? An den mangelnden C-Kenntnissen, bzw Fantasie diese auch einzusetzen :-) Es ist schon erstaunlich, mit wie wenig Wissen sich viele an eine Programmieraufgabe heranwagen.
@ Karl heinz Buchegger: An sowas hätt' ich nie im Leben gedacht ;) BTW sollte Heinz nicht auch mit'm großen "H" anfangen ;) Ist mir nur gerade beim Kopieren aufgefallen ;) Dein C-Programm ist OK aber solltest Du nicht "krumme" Werte mit einem Modulo o.ä. abfangen ? Sonst kann's haarig werden mit Index = 2,34568 und int8_t ;) Oder wird automatisch in int8_t umgewandelt ?
Hallo Danke erst mal für die schnellen Antorten >@Karl heinz Buchegger >mit dieser einfachen Berechnung kriegst du für Drehzahlen > 0 bis 499 Winkel[0] > 500 bis 999 Winkel[1] > 1000 bis 1499 Winkel[2] > 1500 bis 1999 Winkel[3] Das muss ich ja dann mit lauter if oder case abfragen realisieren oder gibts da eine elegantere methode? Sorry für die villeicht banalen fragen aber irgendwie muss man halt erfahrungen sammeln :-)
Wieso if oder case? Karl Heinz hat dir doch schon beschrieben wir das geht! Du ermittelst deine Drehzahl, mithilfe einer Ganzzahldivision erhälst du den Index für die LUT. Schau noch mal in dem Post von 20:35 Uhr nach. Marcus
Sorry habs beim 1 mal durchlesen ned gecheckt.
> Index = Drehzahl / 500;
Was würd jezt aber passieren wenn Drehzahl zb 700 ist, Index währ ja
dann 1,4 also würde ja abgerundet. Wie kann ich dann zwischen 2
stüzstellen interpolieren??
PCler wrote: > Sonst kann's haarig werden mit Index = 2,34568 und int8_t ;) > Oder wird automatisch in int8_t umgewandelt ? Da ist alles Ganzzahl. 1350 / 500 ergibt 2
Das meinte ich mit "krumme" Werte ;) Ich bin gemein ich weiß ;)
peter wrote: > Sorry habs beim 1 mal durchlesen ned gecheckt. > > >> Index = Drehzahl / 500; > > > Was würd jezt aber passieren wenn Drehzahl zb 700 ist, Index währ ja > dann 1,4 also würde ja abgerundet. Wie kann ich dann zwischen 2 > stüzstellen interpolieren?? indem du zwischen dem Wert kleiner (diesen Index kriegst du aus der Division) und dem Wert grösser (das ist dann Index + 1) interpolierst. Also: gemessene Drehzahl 1300 Index = 1300 / 500 -> 2 Wert[2] -> 82 Wert[3] -> 85 Und jetzt wird zwischen den beiden Interpoliert. 2 * 500 -> 1000 1300 - 1000 -> 300 ( 85 - 82 ) * 300 / 500 -> 1.8 als Ganzzahl 1 82 + 1 -> 83 Die Mathe dazu jetzt herzuleiten ist mir ehrlich zu mühselig auch wenns trivial ist.
PCler wrote: > Das meinte ich mit "krumme" Werte ;) > Ich bin gemein ich weiß ;) Nicht wirklich :-) Die Interpolation ist trivial. Ich würds aber trotzdem nicht so machen: Ein Motormanagement sollte wohl so schnell wie möcglich auf veränderte Drehzahlen reagieren. Wenn 500 U/min Auflösung nicht reichen, dann geh ich halt runter auf 100 oder 50. Die Tabelle im Excel aufstellen, geht wohl schneller als wenn der µC sich da durch Divisionen durchquälen muss.
@ Karl heinz Buchegger: Bist Du Dir wirklich sicher das uint8_t var = 1300 / 500 ZWEI ergeben ? Weil da kommt ja eigentlich 2,6 heraus ?? Sorry aber in "normalem" C kracht das ziemlich ! Außer Du nimmst uint8_t var = (uint8_t) 1300 / 500 ... Oder steh' ich gerade auf'm Schlauch ?
> Bist Du Dir wirklich sicher das uint8_t var = 1300 / 500 ZWEI ergeben ? Ja, ich bin mir absolut sicher > Weil da kommt ja eigentlich 2,6 heraus ?? Nicht wirklich. 1300 ist ein int. 500 ist ein int. Also wird die Division als int-Division ausgeführt. Und das ergibt nun mal 2. > Sorry aber in "normalem" C kracht das ziemlich ! Äh. Nein. So sind die C-Regeln. Das ist schon seit Zeiten von K&R so (also seit den 60-er Jahren). > Außer Du nimmst uint8_t var = (uint8_t) 1300 / 500 ... Das ändert überhaupt nichts. Ist nach wie vor eine int Division. Ah. OK Ich hätte vielleicht dazu schreiben sollen, dass Zahlen ohne einen Kommapunkt bei mir immer int sind. Wenn ich eine Kommazahl haben will schreibe ich immer einen Dezimalpunkt: 1300.0 / 500.0 ist daher was anderes als 1300 / 500 Klärt das das Missverständniss auf?
@All: Sorry, hab's gerade selbst nachgesehen: http://www.csee.usf.edu/~eschrich/cis4930/faq/intdivision.html Also Karl-Heinz hat recht ;) Ich muß wohl irgendwie was verwechselt haben ;) Wobei es ja heißt das iterative Sprachen immer ineinander übersetzt werden können ... Aber wie heißt es So schön: C:
1 | Shoot urself in the foot. |
PENG Pascal: The compiler wont let u shoot urself in the foot. Sorry, PCler
> C > Pascal Aaaah. Jetzt weiss ich woher der Wind weht :-) In Pascal ist das anders. Stimmt.
> > ( 85 - 82 ) * 300 / 500 -> 1.8 als Ganzzahl 1 > > 82 + 1 -> 83 > Wenn du die 1.8 gerundet haben möchtest, dann musst du noch eine Rundungskorrektur anbringen. ( ( 85 - 82 ) * 300 + 250 ) / 500
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.