Guten Abend zusammen Nachdem ich nun einige Tutorials und Beiträge zur PWM durchgelesen habe und leider immer noch nicht weiter bin, hoffe ich hier auf eine Problemlösung von erfahrenen Usern. Das Coding rund herum funktioniert schon, nur die PWM bereitet mir Probleme. Hier mal eine Erläuterung des kompletten Programms: Ich nutze das myavr MK2 board mit LCD Anzeige und einem atMega8 Prozessor. Auf der LCD Anzeige wird die Soll und Ist-Temperatur angezeigt. Die Soll Temperatur ist mit zwei vorhanden Tastern in 0,5er Schritten hoch oder runter zu regeln. Die IST-Temperatur soll irgendwann mittels Temperatursensor eingelesen werden. Zur Simulation nutze ich zurzeit ein Poti mit AD-Wandlung zur Einstellung der IST-Temperatur. Dann sollen zwei LED's an den PWM Ausgängen geregelt werden. Grüne LED für IST > SOLL und gelb für IST < SOLL. Je grösser der Temperaturunterschied desto heller die jeweilige LED. Nunmal der Programm-Ausschnitt: DDRB |= (1 << PB1 ); // PB1 als Ausgang für PWM DDRB |= (1 << PB2 ); // PB2 als Ausgang für PWM DDRB |= (1 << PB3 ); // PB3 als Ausgang für PWM Habe alle 3 als Ausgang gesetzt weil ich auch schon versucht habe mit OCR2 zu arbeiten. TCCR1A = 0b10100010; // COM1A1-COM1A0 = Nicht invertierend ; // COM1B1-COM1B0 = Nicht invertierend ; // FOC1A und FOC1B = 0; // WGM11 = 1, WGM10 = 0 TCCR1B = 0b00011001; // WGM13 = 1, WGM12= 1 <<- Mode14, Fast PWM //CS12-CS11-CS10 = 001 <<- Kein Vorteiler ICR1 = 0x0040; // Top Wert auf 64 setzen durch Mode14 if (e>0) //wenn e > 0 -->heizung an(gelbe LED) { OCR1A = y; // vergleichwert für compare match y OCR1B =0; // Gegenwert zum "Schutz" auf 0 } if (e<0) //wenn e < 0 -->lüftung an(grüne LED) { OCR1B =-y; // vergleichwert für compare match y OCR1A = 0; // Gegenwert zum "Schutz" auf 0 } Wo hab ich hier den Fehler? Denke ich da komplett Falsch? Komme leider wirklich nicht weiter... Vielen Dank schonmal für jede Hilfe Mfg
Nachtrag: Mit zusätzlichem OCR2 Timer bekomme ich ein besseres Ergebnis. TCCR2 = 0b01100100; if (e>0) //wenn e > 0 -->heizung an(gelbe LED) { OCR2 = 0; OCR1A = y; // vergleichwert für compare match y OCR1B =0; // Gegenwert zum "Schutz" auf 0 } if (e<0) //wenn e < 0 -->lüftung an(grüne LED) { OCR1B =-y; // vergleichwert für compare match y OCR1A = 0; // Gegenwert zum "Schutz" auf 0 OCR2 = -y ; } Die grüne LED wird allerdings scheinbar nicht voll aufgeregelt. Hab ich trotzdem noch Fehler im Programm? Danke im Voraus
Gast
#2240410
>Hab ich trotzdem noch Fehler im Programm?
Da kannst du deinen Arsch drauf verwetten;)
holger schrieb: >>Hab ich trotzdem noch Fehler im Programm? > > Da kannst du deinen Arsch drauf verwetten;) Das ist zumindest schonmal ein klitzekleiner Hinweis :D Hoffe auf etwas präzisere Antworten.. Danke! Gruß
Kann mir hier keiner einen verwendbaren Tip geben? Wäre echt super.. Mfg
Gast
#2242016
das die led in deiner schaltung überhaupt heller leuchten kann als das momentane maximum hast du verifiziert..? also zb mal nen adc messwert an eine pwm durchreichen, und eine andere per code fest auf vollausschlag stellen..? leider sind deine programmausschnitte ja nicht wirklich aussagekräftig. zumindest erfährt man, das "e" angeblich negativ werden kann..? was ist e, was ist y..? was für nen wert hat y.. leider wird hier überhaupt nichts klar, sry. am besten mal die sourcen in den anhang, und genauer erläutern, was du da versuchst.. mfg
Hallo dunno Zu deiner ersten Frage. Ja, dass habe ich bereits verifiziert. Ich dachte der Programmausschnitt würde reichen um einen Hinweis zu bekommen was mit der PWM nicht stimmt. Hier mein C-Code Ausschnitt für die AD-Wandlung:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
Und hier meine PWM mit integrieter PI-Regelung:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
Ich hoffe das ist nun alles Aussagekräftiger und würde mich sehr über Lösungsansätze freuen. p.s: Das die Werte alle NICHT unbedingt float sein sollten/müssten/dürften :-) ist mir bewusst.
Gast
#2242431
okay, da ich sowas wie regelungstechnik nich hab, kann ich zu deinem algorithmus nix sagen... allerdings macht mir dein zahlenhandling bauchschmerzen.. du bekommst einen adc messwert als unsigned char, interpretierst den dann ohne cast als float, rechnest damit irgendwas lustig rum, gehst dann davon aus, das das problemlos in einen integer geht, und gibst das dann an deine OCR register aus, die sicher weniger als 16bit haben.. ich würd zu gerne da mal in den speicher gucken, und schauen was da für werte rauskommen, aus dem gerechne.. sicher nix sinnvolles mehr.. keine ahnung, wie man da am professionellsten vorgeht, ich würd zumindest mal sicher gehen wollen, was da für ergebnisse rauskommen.. generell halt ich es für ungünstig da mit float und integers zu rechnen.. wahrscheinlich fährst du mit ner look up table o.ä. besser.. mfg
Gast
#2242449
achso, hab den fehler im algorithmus wohl doch.. =) wozu genau ist eigentlich deine esum gut? also, nicht nur das die irgendwie durch die ifs mehrmals umgeschrieben werden kann.. [ wenn y==0 ist, wird y auch <50 sein..? ] vom negativen bereich mal ganz zu schweigen. da wäre die tante else wohl ganz sinnvoll platziert. außerdem: dein esum ist immer 0, in der berechnung. damit sollte dein iwert immer =0 sein. wenn dein iwert 0 ist, ist dein pwert immer 0.5*e. y=pwert=0.5e e ist die differenz der 2 ad-wandelergebnisse(denke ich). also kann y nie größer als 128 werden. also ist mit deiner pwm alles in ordnung. ;) mfg
Danke schonmal für deine Antwort dunno. du bekommst einen adc messwert als unsigned char <-- Ist das so? Die Wandlung wird ja in result geschrieben welches als float deklariert ist. Oder ist der generelle ADC - Wert immer unsigned char? Des Weiteren (was mich aber auch wundert) meckert mein Compiler darüber nicht! Also wenn ich den Wert nicht caste.. Wenn ich die ORCL und OCRH Register nutze habe ich doch 16 Bit oder? Damit habe ich es bereits versucht...Leider auch ohne Erfolg! Muss natürlich auch als blutiger Anfänger sagen, dass ich mich da noch son bisschen durchwühle. Nichts desto trotz werde ich da nochmal gezielt drauf schauen und nachsehen, welche Zahlen dementsprechend dann im Speicher stehen. Vielleicht bringt mich das ja etwas weiter... Gruß
Gast
#2242486
ja, aus dem adc kommen erstmal so 8 bit raus, die kannst du gerne als float interpretieren, aber das ergibt keinen sinn.. übrigens machts auch keinen sinn H und L zu nutzen, denn der adc kann nur 10 bit. das der compiler nicht meckert, liegt wohl daran das es ihm erstmal völlig egal ist, was für zahlen du da hast. sind ja nur nullen und einsen in einem (bzw mehreren) register(n), wie die jetzt interpretiert werden sollen, das ist dein problem. ich bin mir auch garnicht so sicher, ob casten alleine dich jetzt aus der misere zieht, da kann vielleicht jemand anders noch was dazu sagen.. mfg
Hi dunno Das mit H und L war nicht auf die AD-Wandlung sondern auf die PWM bezogen. E ist die Differenz zwischen Soll und Ist Wert. Der eine Wert kommt aus der AD-Wandlung (IST) und Soll wird über Taster hoch bzw. runtergestellt. Mit esum immer 0 hast du für den obigen Code recht. Jedoch ( sorry, mein Fehler) wird der Wert durch die Main Routine (Endlosschleife) verändert. Deshalb hier auch mal mein Main Part + die Funktion für die LCD-Anzeige: ( sorry, hätte ich auch direkt posten können)
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
Ich hoffe ich werde für meine "Programmierkünste" nicht gesteinigt :-)! Danke schonmal Dunno! Gruß
Gast
#2242539
@ H/L richtig, die pwm kannst du mit H/L auf 16 bit bringen, der adc hat aber eine maximale auflösung von 10 bit.. es gibt ja auch ADCH und ADCL ;) und das esum in deiner main irgendwie verändert werden KANN, bezweifle ich stark. zum einen sehe ich esum da nirgends, zum anderen ists lokal definiert. abgesehen davon, wenn es verändert werden WÜRDE, würde float esum=0; bei funktionsaufruf das unter garantie wieder auf 0 ändern. ;)
Gast
#2242550
ach gott, irgendwann muss ich mich hier doch mal fest anmelden.. ergänzung zu dem von grade... dir ist klar, das dein ad wandler immer werte von 0..255 liefern wird.? du musst das erstmal auf ne temperatur umrechnen. also sagen wir, du misst bei 20 grad einen wert von 128, und dein soll ist 20.0 (weil float) dann hast du ja in e eine differenz von 108..... schau dir lieber nochmal an, wie das mit temperatursensoren und temperatur gemacht wird.. ;)
Hi dunno Danke für deine Bemühungen. Ich bin dadurch mal wieder etwas von der PWM weggekommen und habe nochmal "versucht" alles zu prüfen :-). Mit esum hast du natürlich absolut Recht. Ich habe die Regelung mal etwas abgewandelt... Einige Fragen dazu: Wenn ich esum lokal so definiere -> float esum; Hab ich keinen definierten Wert anfangs oder? Ich geh langsam am Stock hier..mir fallen die einfachsten Sachen nicht mehr ein :-/ Wie löse ich das? Des Weiteren muss ich beim debuggen feststellen, dass die Berechnungen pwert=(kp*e); //P-Anteil ausrechnen iwert=(ki*ta*esum); wenn ich Schrittweise debugge übersprungen werden. Warum? Weiss das jemand?
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
Dunno, sieht es so etwas besser aus? Übrigens, über die Sache mit den Berechnungen bin ich mir im klaren. Das würde dann angepasst wenn wir wirklichen mit einem Sensor arbeiten. Bis auf die ganzen floats natürlich... :-) Danke!!
Lös doch mal deine PWM von der Regelung und teste sie seperat. Du willst 2 LED gegengleich dimmen. Das sollte sich doch mit einem kleinen Testprogramm erstmal losgelöst von allem anderen realisieren lassen. Dann weißt du schon mal, dass die PWM grundsätzlich funktioniert.
Seb astian schrieb: > Einige Fragen dazu: > Wenn ich esum lokal so definiere -> float esum; > Hab ich keinen definierten Wert anfangs oder? richtig > Ich geh langsam am Stock > hier..mir fallen die einfachsten Sachen nicht mehr ein :-/ > Wie löse ich das? Wie hast du es denn bei den anderen Variablen gemacht? Aber abgesehen davon, ist das immer noch Quatsch, weil du ja nicht bei jedem Aufruf der Regelfunktion ein neues esum haben willst, sondern ein esum, dessen Wert mehrere Aufrufe übersteht. Sonst hat das ja keinen Sinn. Also: entweder esum als globale Variable machen oder die Variable static machen. Mach doch dein Lüfter/Heizungs Spielchen erst mal ohne den PI-Regler. Ein simpled 2-Punkt Regler: Wenn die Temperatur kleiner als die Solltemperatur - 1Grad, dann Lüfter aus und Heizung ein Wenn die Temperatur größer als die Solltemperatur + 1 Grad, dann Heizung aus und Lüfter an. Das ganze garniert mit den LED Und wenn das dann läuft, dann beschäftigst du dich mit dem PI Regler.
Seb astian schrieb: > Dunno, sieht es so etwas besser aus? No. Deine Formatierung ist ein Graus. Wozu muss man in der Regelgungsfunktion ständig die Timer neu konfigurieren und die Ports auf Ausgang stellen? Stell die Dinge EINMAL ein und belasse es dann dabei! Das generelle Layout eines Programms sieht so aus
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
Gast
#2242762
ganz recht, esum hat so keinen definierten wert. kannst du also so auch nicht machen. ne einfache lösung, wenn du keine pointer nutzen willst, wäre, die funktion jeweils die aktuelle esum zurückgeben zu lassen, und dann eben den nächsten aufruf mit dem alten wert als parameter machen... dann speicherst du das quasi in main. ansonsten gäbe es da noch static. warum deine berechnungen übersprungen werden..? keine ahnung was du mit übersprungen meinst, aber nen grund dafür kann ich mir grad nich vorstellen.. in den variablenwerten müsste man allemal ne veränderung sehen.. und y>-50 ist auch immernoch wahr, wenn y<50 ist. ich kann nur immer wieder meine alte tante else erwähnen.. oh, und was noch ziemlich komisch ist, das du versuchst, die pwm ganz am ende mit -y zu beschreiben.. denn die hardware wird den wert ganz sicher als unsigned interpretieren.... und DAS ist nun wirklich nicht was du willst.
Gast
#2242770
edit: verdammt, ist der herr buchegger schnell. ^^
Also... @ Karl Heinz Buchegger Eine simple 2-Punkt Regelung hatte ich bereits laufen. Das war so weit OK. Dabei habe ich natürlich die Regelung und die PWM weggelassen. Das mit der seperaten PWM werde ich gleich noch einmal machen. Esum wollte ich in der Tat returnen! Das hab ich im ganzen Wusel wirklich vergessen..Nur war mir dabei auch nicht klar ob der Wert dann jedes mal an den Funktionsanfang gegeben wird?? Wenn das bei der definition float esum; so ist, dann ist es genau das was ich brauche/will! Sorry für diese Formatierung. Das hab ich schon des öfteren gehört :-/..Muss ich mir dringend angewöhnen. @ Dunno.. ne einfache lösung, wenn du keine pointer nutzen willst, wäre, die funktion jeweils die aktuelle esum zurückgeben zu lassen, und dann eben den nächsten aufruf mit dem alten wert als parameter machen... dann speicherst du das quasi in main. <-- Hm warum speicher ich das in main? In main brauche ich den Wert ja gar nicht!! oh, und was noch ziemlich komisch ist, das du versuchst, die pwm ganz am ende mit -y zu beschreiben.. denn die hardware wird den wert ganz sicher als unsigned interpretieren.... <-- Das hab ich mir auch gedacht. Nur was zum Teufel soll ich daran anders machen? Das ist nunmal mein Vergleichswert ... Danke für eure Hilfe!
Gast
#2242804
Seb astian schrieb: > Hm warum speicher ich das in > main? In main brauche ich den Wert ja gar nicht!! ganz einfach, du speicherst den in der main, weil der wert in der funktion bei jedem beenden der funktion gnadenlos aus dem speicher fliegt. du kannst natürlich auch global arbeiten, aber das wird allgemein als mieser stil gesehen.. (okay okay, hier spricht der student und nicht der praktiker..) in der main bliebe der wert die ganze zeit gespeichert. alternative ist static, hier stellt sich aber wohl das problem mit dem initialisieren beim 1. start... bin mir nicht sicher, ob man das =0 setzen darf, dann. zur pwm.. naja, musst dir halt deinene werte berechnen.. so wirds nicht klappen, mit dem gegengleich.
dunno. schrieb: > Seb astian schrieb: >> Hm warum speicher ich das in >> main? In main brauche ich den Wert ja gar nicht!! > > ganz einfach, du speicherst den in der main, weil der wert in der > funktion bei jedem beenden der funktion gnadenlos aus dem speicher > fliegt. du kannst natürlich auch global arbeiten, aber das wird > allgemein als mieser stil gesehen.. (okay okay, hier spricht der student > und nicht der praktiker..) :-) Im Prinzip richtig. Aber auf einem kleinen µC gelten ein klein wenig andere Gesetze. Hab ich auch erst lernen müssen. Zum einen sind Programme klein genug, dass globale Variablen noch nicht so das Problem sind. Viel wichtiger aber ist, dass du eine ziemlich konkrete Vorstellung davon hast, wieviel RAM für Vairablen drauf geht. Mit globalen Variablen geht das am besten und einfachsten. > alternative ist static, hier stellt sich aber wohl das problem mit dem > initialisieren beim 1. start... bin mir nicht sicher, ob man das =0 > setzen darf, dann. Kann man. Die Initialisierung wird dann nur beim ersten mal ausgeführt. static ist in dieser Form wie eine globale Variable, die nur in einer Funktion sichtbar ist. > naja, musst dir halt deinene werte berechnen.. so wirds nicht klappen, > mit dem gegengleich. Ich bin mir noch nicht mal sicher, ob y überhaupt vom Wertebereich her zu einer PWM passt. Ist halt immer das gleiche: Ohne Möglichkeit zum Ausgeben von Werten ist das oft ein Stochern im Nebel.
> Kann man. > Die Initialisierung wird dann nur beim ersten mal ausgeführt. > static ist in dieser Form wie eine globale Variable, die nur in einer > Funktion sichtbar ist. Danke! Variable ist nun auf static gesetzt! Einige Änderungen bezgl. der ganzen if's sind nun auch passiert. Else wurde eingefügt! >> naja, musst dir halt deinene werte berechnen.. so wirds nicht klappen, >> mit dem gegengleich. > > Ich bin mir noch nicht mal sicher, ob y überhaupt vom Wertebereich her > zu einer PWM passt. Ist halt immer das gleiche: Ohne Möglichkeit zum > Ausgeben von Werten ist das oft ein Stochern im Nebel. Das ist wirklich wahr. Leider habe ich die Möglichkeit nicht. Mein Problem bezgl. PWM ist ganz ehrlich folgendes, dass an 1000 Stellen die Initialisierung einer PWM beschrieben wird. Diese sollte auch wirklich stimmen bei mir. Die Vergleichswerte ( wie genau die Variablen verglichen werden) und welcher Wertebereich akzeptiert wird steht nicht wirklich gut beschrieben. Ausserdem ist mir auch nicht klar ob ich 2 oder 3 Timer brauche um die LED's gegengleich zu beleuchten :-( Gruß
Seb astian schrieb: >> zu einer PWM passt. Ist halt immer das gleiche: Ohne Möglichkeit zum >> Ausgeben von Werten ist das oft ein Stochern im Nebel. > > Das ist wirklich wahr. Leider habe ich die Möglichkeit nicht. Tja. Darum entwickelt man Software auch gerne auf Entwicklungsboards. Denn dort hat man dann die Möglichkeiten. Oder aber man baut sich in seine Hardware von vorne herein zb eine UART/MAX232 ein, die nur dazu dient, damit man während der Entwicklungszeit eine Möglichkeit zur Ausgabe hat. Oder man hat eine kleine Zusatzplatine, auf der ein MAX232 sitzt, die man während der Entwicklungszeit 'fliegend' mit der Hardware verbindet. Du musst damit rechnen, dass du beim Entwickeln Fehler machst. Du musst damit rechnen, dass du eine Ausgabemöglichkeit brauchst. Alles andere ist dumm und Stochern im Nebel. > Mein Problem bezgl. PWM ist ganz ehrlich folgendes, dass an 1000 Stellen > die Initialisierung einer PWM beschrieben wird. Diese sollte auch > wirklich stimmen bei mir. Die Vergleichswerte ( wie genau die Variablen > verglichen werden) und welcher Wertebereich akzeptiert wird steht nicht > wirklich gut beschrieben. Da gibts auch nicht viel zu beschrieben. Eine 8-Bit PWM hat einen Wertebereich von 0 bis 255. Warum? Weil mit 8 Bit von 0 bis 255 gezählt werden kann. Eine 10 Bit PWM hat einen Wertebereich von 0 bis 1023. Warum? Weil man mit 10 Bit von 0 bis 1023 zählen kann. Eine 9 Bit PWM hat einen Wertebereich von 0 bis 511. Warum? WEil man mit 9 Bit von 0 bis 511 zählen kann. Eine Custom PWM, bei der man die Obergrenzer mittels ICR Register festlegen kann, hat einen Wertebereich von 0 bis zu eben dieser Obergrenze. > Ausserdem ist mir auch nicht klar ob ich 2 > oder 3 Timer brauche um die LED's gegengleich zu beleuchten :-( Du brauchst 2 PWM Stufen. Ob die jetzt mit 1 Timer oder mit 2 gemacht werden, hängt davon ab, was die Timer können. Wenn 1 Timer 2 Stück PWM erzeugen kann, dann reicht einer.
Karl Heinz Buchegger schrieb: > Seb astian schrieb: > >>> zu einer PWM passt. Ist halt immer das gleiche: Ohne Möglichkeit zum >>> Ausgeben von Werten ist das oft ein Stochern im Nebel. >> >> Das ist wirklich wahr. Leider habe ich die Möglichkeit nicht. > > Tja. > Darum entwickelt man Software auch gerne auf Entwicklungsboards. Denn > dort hat man dann die Möglichkeiten. Oder aber man baut sich in seine > Hardware von vorne herein zb eine UART/MAX232 ein, die nur dazu dient, > damit man während der Entwicklungszeit eine Möglichkeit zur Ausgabe hat. > Oder man hat eine kleine Zusatzplatine, auf der ein MAX232 sitzt, die > man während der Entwicklungszeit 'fliegend' mit der Hardware verbindet. > > Du musst damit rechnen, dass du beim Entwickeln Fehler machst. Du musst > damit rechnen, dass du eine Ausgabemöglichkeit brauchst. Alles andere > ist dumm und Stochern im Nebel. > >> Mein Problem bezgl. PWM ist ganz ehrlich folgendes, dass an 1000 Stellen >> die Initialisierung einer PWM beschrieben wird. Diese sollte auch >> wirklich stimmen bei mir. Die Vergleichswerte ( wie genau die Variablen >> verglichen werden) und welcher Wertebereich akzeptiert wird steht nicht >> wirklich gut beschrieben. > > Da gibts auch nicht viel zu beschrieben. > Eine 8-Bit PWM hat einen Wertebereich von 0 bis 255. Warum? Weil mit 8 > Bit von 0 bis 255 gezählt werden kann. > Eine 10 Bit PWM hat einen Wertebereich von 0 bis 1023. Warum? Weil man > mit 10 Bit von 0 bis 1023 zählen kann. > Eine 9 Bit PWM hat einen Wertebereich von 0 bis 511. Warum? WEil man mit > 9 Bit von 0 bis 511 zählen kann. > Eine Custom PWM, bei der man die Obergrenzer mittels ICR Register > festlegen kann, hat einen Wertebereich von 0 bis zu eben dieser > Obergrenze. Das habe ich verstanden! Ich habe bei mir nun Fast-PWM 8 Bit gesetzt! TopWert also 255! > >> Ausserdem ist mir auch nicht klar ob ich 2 >> oder 3 Timer brauche um die LED's gegengleich zu beleuchten :-( > > Du brauchst 2 PWM Stufen. Ob die jetzt mit 1 Timer oder mit 2 gemacht > werden, hängt davon ab, was die Timer können. Wenn 1 Timer 2 Stück PWM > erzeugen kann, dann reicht einer. Gut! Mein Timer1 kann direkt auf OC1A und OC1B zugreifen. Deiner Beschreibung nach würde dieser Timer also ausreichen. Welcher Mode muss aber für meine Funktion gesetzt werden? Also wie COM1A1 - COM1A0 setzen? 00 = Normale Operation = Quatsch! 01 = Toggle bei Compare Match = ? 10 = Löscht OC1A / OC1B bei compare match = ?! 11 = Setzt OC1A / OC1B bei compare match = ?! Wenn y nun im Wertebereich von 0..255 liegt müsste es doch OK sein. -y kann natürlich unter 0 liegen. Wie krieg ich den Wert hin für die PWM? Danke
Seb astian schrieb: > Gut! Mein Timer1 kann direkt auf OC1A und OC1B zugreifen. > Deiner Beschreibung nach würde dieser Timer also ausreichen. Yep > > Welcher Mode muss aber für meine Funktion gesetzt werden? > > Also wie COM1A1 - COM1A0 setzen? > > 00 = Normale Operation = Quatsch! > 01 = Toggle bei Compare Match = ? > 10 = Löscht OC1A / OC1B bei compare match = ?! entweder diesen > 11 = Setzt OC1A / OC1B bei compare match = ?! oder diesen, je nachdem wie deine LED angeschlossen sind. Beim einen wird die LED heller, je höher der Wert ist. Bei der anderen wird sie mit steigendem Wert dunkler > Wenn y nun im Wertebereich von 0..255 liegt müsste es doch OK sein. > -y kann natürlich unter 0 liegen. Wie krieg ich den Wert hin für die > PWM? Du kannst ja zb die eine PWM auf MOdus 10 und die andere auf Modus 11 stellen. Dann laufen sie schon per Hardware gegengleich bei gleichem y Wert. Oder die eine setzt du auf y und die andere auf 255 - y Aber es muss sichergestellt sein, dass y auch wirklich im Bereich 0 bis 255 bleibt. Zur Not muss man sich dann eben eine kleine Umrechnung ausdenken, die das gewährleistet. AUch wenn die kleinen AVRs jetzt nicht gerade die Rechenkünstler sind, ein bischen addieren, subtrahieren, multiplizeren und wenn es sein muss auch dividieren können sie gut genug. Und mehr braucht man dann auch meistens nicht. Und genau deswegen liebe ich kleine Testprogramme, mit denen man einzelne Aspekte eines Projektes unabhängig vom Rest austesten, probieren und damit Erfahrung sammeln kann.
> Du kannst ja zb die eine PWM auf MOdus 10 und die andere auf Modus 11 > stellen. Dann laufen sie schon per Hardware gegengleich bei gleichem y > Wert. Das ist mir vollkommen Schleierhaft. Warum? Ich habe zwei Register: TCCR1A= COM1A1 COM1A0 COM1B1 COM1B0 FOC1A FOC1B WGM11 WGM10 TCCR1B= ICNC1 ICES1 - WGM13 WGM12 CS12 CS11 CS10 Mit der Zusammensetzung der 4 WGM Bits setze ich den Modus. Wie also kann ich zwei verschiedene machen? > > Oder die eine setzt du auf y und die andere auf 255 - y > > Aber es muss sichergestellt sein, dass y auch wirklich im Bereich 0 bis > 255 bleibt. Zur Not muss man sich dann eben eine kleine Umrechnung > ausdenken, die das gewährleistet. AUch wenn die kleinen AVRs jetzt nicht > gerade die Rechenkünstler sind, ein bischen addieren, subtrahieren, > multiplizeren und wenn es sein muss auch dividieren können sie gut > genug. Und mehr braucht man dann auch meistens nicht. > > Und genau deswegen liebe ich kleine Testprogramme, mit denen man > einzelne Aspekte eines Projektes unabhängig vom Rest austesten, > probieren und damit Erfahrung sammeln kann. Da werde ich wohl um eine Umrechnung nicht drum herum kommen... Vielen Dank schonmal für die super Hilfe hier!! Gute nacht
Seb astian schrieb: >> Du kannst ja zb die eine PWM auf MOdus 10 und die andere auf Modus 11 >> stellen. Dann laufen sie schon per Hardware gegengleich bei gleichem y >> Wert. > > Das ist mir vollkommen Schleierhaft. > Warum? > Ich habe zwei Register: > TCCR1A= COM1A1 COM1A0 COM1B1 COM1B0 FOC1A FOC1B WGM11 WGM10 > TCCR1B= ICNC1 ICES1 - WGM13 WGM12 CS12 CS11 CS10 > > Mit der Zusammensetzung der 4 WGM Bits setze ich den Modus. > Wie also kann ich zwei verschiedene machen? Timer 1 kann 2 PWM Ausgänge versorgen. Den 'A' Ausgang und den 'B' Ausgang. Drum gibt es ein COM1A1 + COM1A0 und es gibt COM1B1 + COM1B0 Deshalb gibt es ein OCR1A und es gibt ein OCR1B, es gibt .... (jeweils ein 'A' Register und ein 'B' Register, einen Pin am µC der für den Timer 1 ein A im Namen hat und einen der ein B im Namen hat) Vielleicht doch mal das Datenblatt etwas genauer studieren?
Ergänzung zum vorigen Post. Mit meinem 2 Timer OCR2 kann ich nur WGM20 und WGM21 setzen. Daher also dort auch nicht die Möglichkeit Modus 10 oder 11 ein zustellen. Hatte ich gerade vergessen zu erwähnen! Gruß
Karl Heinz Buchegger schrieb: > Timer 1 kann 2 PWM Ausgänge versorgen. Den 'A' Ausgang und den 'B' > Ausgang. Drum gibt es ein > > COM1A1 + COM1A0 > > und es gibt > > COM1B1 + COM1B0 > > Deshalb gibt es ein OCR1A und es gibt ein OCR1B, es gibt .... (jeweils > ein 'A' Register und ein 'B' Register, einen Pin am µC der für den Timer > 1 ein A im Namen hat und einen der ein B im Namen hat) > > > Vielleicht doch mal das Datenblatt etwas genauer studieren? Das verstehe ich! Den Modus 10 oder 11 setze ich aber durch die WGM Bits und nicht durch COM1A1 oder COM1B1. Gruß
Guten Morgen War anscheinend schon zu spät gestern. WIr haben völlig aneinander vorbei geredet..( oder ich an dir :-/) Du meinst natürlich die Modis COM1A1 und COM1B1. Ich habe es verwechselt mit PWM Mode 10 ( ZEHN ) und 11 ( ELF )....Sorry Werde gleich an einer seperaten PWM arbeiten und dann versuchen -y definitiv in einen korrekten Wertebereich zu bekommen. Wenn das erledigt ist werde ich den pi regler part + PWM nochmals posten. Danke und Gruß
Gast
#2243142
na ihr habt ja gestern noch gut gerödelt.. wärs aber nicht sinnvoller, y wirklich sichergestellt auf 8 bit zu quetschen? dann kannste dein gegengleich einfach mit 255-y hinbekommen.. das wär nämlich auch mein ansatz gewesen.. mfg
Morgen dunno. Ja, zu erst dachte ich heute morgen ich könnte y einfach iint8_t definieren. Dann fiel mir aber ein das wir ja dann den Wertebereich der PWM wieder verlassen. Als uint8_t gehts allerdings auch nicht wirklich, da y auch negativ sein kann. Das heisst, dass ich im Falle von e<0 y in eine positive Zahl umrechnen müsste, oder? Die richtige Idee hatte ich noch nicht.
So, morgen nochmal :-)
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
Das ist nun meine AD-Wandlung mit PWM völlig losgelöst vom Rest. Und? Sie funktioniert ;-) Die LED's werden gegengleich geregelt. So, wie Karl Heinz Buchegger es geschrieben hat, habe ich Mode 10 und 11 verwendet. Trotzdem bekomme ich es beim anderen Programm nicht hin. Es ist zum Mäuse melken. Gruß
Übrigens sieht meine PI-Regelung nun folgendermaßen aus:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
Ich hoffe ich habe eure Anmerkungen nun soweit richtig geändert. Verglichen mit der "obigen eigenen" PWM, kann mir jemand Hilfestellung leisten mit dieser PWM im Regelprogramm? Danke und Gruß
Gast
#2243829
Seb astian schrieb:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
das kann doch niemals was werden... bitte schau dir an, worin sich eine vorzeichenbehaftete, und eine unsigned zahl unterscheiden, in der binär- darstellung. die OCR register erwarten unsigned werte!! wenn deine pwms wirklich so eingestellt sind wie im standalone beispiel, braucht y auch garnicht negativ zu sein..? übrigens, zu deinem standalone beispiel.. du hast doch nur 1 adc kanal, den du liest..? dann sollte das hier reichen:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
und bitte sei so nett und gewöhn dir ne einrückung an. macht alles lesbarer. mfg
Seb astian schrieb: > Morgen dunno. > > Ja, zu erst dachte ich heute morgen ich könnte y einfach iint8_t > definieren. Dann fiel mir aber ein das wir ja dann den Wertebereich der > PWM wieder verlassen. > Als uint8_t gehts allerdings auch nicht wirklich, da y auch negativ > sein kann. y gleich 0 bedeutet bei dir, dass weder die Heizung noch der Lüfter eingeschaltet ist. Richtig? Na dann zähl zu y einfach 128 dazu. dann hast du einen Wert, der genau in der Mitte des LED-PWM Bereichs liegt und bei dem beide LED gleich hell leuchten. Wird y negativ, sagen wir mal -64, dann hast du nach der Addition von 128 einen Wert von +64 für die eine LED und (255-64 = 191) für die andere LED. Die eine wird also dunkel sein und die andere hell. Ist dein y auf der anderen Seite gleich +64, dann hast du nach der Addition von 64 fpr die eine LED einen Wert von 191 und für die andere einen Wert von (255-191 = 64). Ergo wird diesmal die eine LED die helle sein und die andere Led die dunklere. Natürlich mit fliessenden Übergängen dazwischen, je nach Wert von y. Alles was du noch tun musst, ist dafür zu sorgen, dass dein original y Wert den Bereich -128 bis +128 nicht verlassen kann. Manchmal muss man sich eben selber ein bischen die Mathematik ausdenken, die man benutzen möchte. Meistens reicht ein bischen Addieren, Subtrahieren und das was man in der Grundschule gelernt hat.
Nabende zusammen Da war irgendwie ziemlich der Wurm drin. Ich bin die Funktion pi_regler nochmal komplett durchgegangen. Schrittweises debuggen zeigt gute Ergebnisse. So sieht das ganze nun aus:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
Das Problemchen das ich nun habe: Wenn Soll wert beispielsweise 20° ist, der IST war aber maximum (255) wegen 8-Bit, habe ich eine Ausgangsspannung von ca. 2,5 Volt. Wenn ich nun mit dem Soll-Wert in den negativen Bereich gehe wird der Unterschied natürlich größer und damit auch die Spannung. Ich brauche aber keinen Negativen Soll-Wert Bereich. Was muss ich nun einstellen, damit mein µC weiss, dass wenn Soll=0 und Ist=255 die PWM auf 100% stehen muss? Die Begrenzung habe ich nicht verstanden bzw. habe auch keine Idee wie ich diese dann im Coding einbauen soll. Über Hilfe wäre ich sehr denkbar.. (auch wenn ich schon viel Hilfe bekommen habe ;-) Danke dafür...) Gruß
Seb astian schrieb: > Wenn Soll wert beispielsweise 20° ist, der IST war aber maximum (255) > wegen 8-Bit, habe ich eine Ausgangsspannung von ca. 2,5 Volt. Wenn ich > nun mit dem Soll-Wert in den negativen Bereich gehe wird der Unterschied > natürlich größer und damit auch die Spannung. Ich brauche aber keinen > Negativen Soll-Wert Bereich. Was muss ich nun einstellen, damit mein µC > weiss, dass wenn Soll=0 und Ist=255 die PWM auf 100% stehen muss? Wie würdest du es denn mit der Hand rechnen? Man kann kein Programm für ein Problem schreiben, das man nicht zumindest im Prinzip auch mit der Hand und Papier und Bleistift lösen kann. Also setz dich hin, schreib dir Zahlenwerte auf von denen du dir versprichst, dass sie dir Einsicht ins Problem geben, überlege was deiner Meinung nach bei welchen Soll- Ist-Werte für ein Ergebnis rauskommen müsste und dann such nach mathematischen Zusammenhängen. Die sind meistens ganz einfache Zusammenhänge. > Die Begrenzung habe ich nicht verstanden bzw. habe auch keine Idee wie > ich diese dann im Coding einbauen soll. Du kennst ein if?
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.