Hi, bin neu im Programmieren von Basic und hab gerade ein immenses problem mit der Ansteuerung der Pwm über ein Poti. Hab schon etliche Sachen ausprobiert, aber nichts hat wirklich gefruchtet. Möchte die Pwm in 5 Stufen haben, also 0%, 25%, 50%, 75% und 100%. Hat jemand eine Idee wie man so was hinbekommt bzw. ob dies mit Basic oder überhaupt realisierbar ist. Auf überhebliche oder ironische Antworten wird verzichtet. An alle anderen die mir nützliche Tipps bzw. Infos liefern können, schon mal im Vorraus ein herzliches Danke. MfG Eddy
Hi, keine große Sache und als Einsteigerprojekt geeignet.... Neben dem Stichwort PWM musst du dich mit der Sache ADC vertraut machen, denn was du eigentlich brauchst ist: Ein Poti welches die Spannung auf den ADC gibt. Eine Firmware, die den Registerwert des ADCs in das Register der PWM schiebt. Eventuell durch 4 Teilen falls du 8Bit PWM bei 10Bit ADC nutzt... Sitze leider gerade am falschen PC sonst würde ich dir ein Code Snippet mitschicken... Gruß Jochen
EazyEddy schrieb: > ist. Auf überhebliche oder ironische Antworten wird verzichtet. Kein Problem. Nur ist die Aussage 'immense Probleme' nicht wirklich hilfreich festzustellen, wobei du Probleme hast. Welche Teile kannst du alleine? * PWM (und über welche PWM [Bitzahl] reden wir eigentlich?) * ADC auslesen und recht viel mehr brauchst du ja auch nicht.
EazyEddy schrieb: > Auf überhebliche oder ironische Antworten wird verzichtet. Ebenso auf eine konkrete Problembeschreibung oder gar ein Schaltplan. Wie soll dir also jemand helfen? Kann man nur sagen: 1. gehe auf google 2. tippe "bascom tutorial" ein 3. drücke return 4. such dir einen passenden Link aus und lerne
Wenn du nur pwm machen willst könntest du auch einen multivibrator mit variablen tastverhältnis aufbauen.
Morgen, mein programm sieht bis lang so aus: $regfile = "m8def.dat" $crystal = 8000000 $baud = 19200 $hwstack = 32 $swstack = 16 $framesize = 40 Config Adc = Single , Prescaler = Auto Start Adc Dim Analogwert As Word Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1 Enable Timer1 Start Timer1 Pwm1b = 0 Analogwert = Getadc(0) Pwm1b = Analogwert End Hab ich hier irgendeinen Fehler gemacht? Hab dies mit Hilfe der BASCOM AVR Help Reference geschrieben. Wäre sehr dankbar wenn mir jemand weiter helfen könnte. MfG Eddy
Hallo Eddy, das sieht schon gut aus, nur fehlt eine Endlosschleife. Es wird einmal eine ADC-Wandlung durchgeführt und der Wert als PWM-Wert übergeben und danach rennt der ProgrammCounter ins Leere. Und weiterhin bist du weit über dein Ziel hinausgeschossen - aus der 5-Stufen-PWm wurden jetzt fast 1000 Gruß Limloz
Dankeschön. Zu den 1000 Stufen: Soll ich den Wert auf 8bit stellen. Verstehe ich das richtig?
Habe den Wert auf 8bit gestellt, Das tastverhältnis Pwm1b =64. Zudem: Do Analogwert = Getadc(0) Pwm1b = Analogwert Loop Funktioniert leider nicht so recht-.- Zum besseren verständnis mein aufbau: Das Poti ist mit einem Patchkabel am Pin 23 (ADC0) des mega8 angeschlossen. Von Pin 16 (OC1B) führt ein patchkabel zu einem uln2803a (Darlington). Und zu guter letzt noch eins zur Pwm Leitung des Lüfters.
EazyEddy schrieb: > Zu den 1000 Stufen: Soll ich den Wert auf 8bit stellen. Meinte natürlich auf 8bit heruntersetzen für mein 5 Stufen system^^
8Bit sind 256 Stufen, und wenn Du die PWM auf 8Bit setzt, dann müsstest Du den ADC auch auf 8Bit bringen, sonst hat das merkwürdige Effekte. Wenn Du ein einen Bereich in nur 5 Stufen auswerten willst, bei angenommenen 10Bit für ADC & PWM: ADC-Wert = ADC-Wert / 204 PWM-Wert = ADC-Wert * 204 Dann baut man allerdings noch eine Hysterese ein, damit das "flattern" an den Umschaltpunkten unterbleibt. Aber das wird noch ein bisserl komplexer, schau' erstmal das die einfachsten Sachen laufen.
Das sieht demnach so aus: Config Adc = Single , Prescaler = Auto Start Adc Dim Analogwert As Word Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1 Enable Timer1 Start Timer1 Analogwert = 1023 / 204 Pwm1b = 1023 * 204 Do Analogwert = Getadc(0) Pwm1b = Analogwert Loop End Ist das korrekt oder muss man da noch was verändern?
EazyEddy schrieb: > Ist das korrekt oder muss man da noch was verändern? Nein, das ist nicht richtig. Die Rechnung muss nach GetADC() in der Schleife ausgeführt und dann der errechnete Wert jeweils an die PWM übergeben werden. > Analogwert = 1023 / 204 > Pwm1b = 1023 * 204 Das macht keinen Sinn, schau' Dir nochmal meine Berechnung an und denk' drüber nach.
Demnach müsste das ganze dann so aussehen: Config Adc = Single , Prescaler = Auto Start Adc Dim Analogwert As Word , Pwm1 As Word Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1 Enable Timer1 Start Timer1 Pwm1b = 0 Do Analogwert = Getadc(0) Analogwert = Analogwert / 204 Pwm1 = Analogwert * 204 Pwm1b = Pwm1 Loop End Fail???
EazyEddy schrieb: > Fail??? Ja! rechne das doch mal als Zahlenbeispiel auf einem Blatt Papier durch.
Bei 100%: 1023/204=5,01470882352941*204=1023 Bei 50%: 512/204=2,509803921568627*204=512 Und wo hat sich jetzt der fail versteckt? xD Spass beiseite dieses Thema ist mir ziemlich ernst und ich steig da nich so durch!
EazyEddy schrieb: > Bei 100%: > 1023/204=5,01470882352941*204=1023 > Bei 50%: > 512/204=2,509803921568627*204=512 > > Und wo hat sich jetzt der fail versteckt? xD Ich geb dir eine Analogie. Denn eben weil das so wichtig ist, musst du selbst drauf kommen. Angenommen du hättest Zahlen von 1 bis 100 0, 1, 2, 3, 4, 5, ...,, 98, 99, 100 Die dividierst du jetzt erst mal durch 10. Und zwar ganzzahlig! Also keine Kommastallen. Alle Zahlen von 0 bis 9 ergebn, wenn man sie durch 10 dividiert eine glatte 0. Alle Zahlen von 10 bis 19 ergeben eine glatte 1 Alle Zahlen von 20 bis 29 ergeben eine glatte 2 .... soweit klar? Wenn du nun dieses Zwischenergebnis wieder mit 10 multiplizierst, was ergibt sich dann. Nun 0 mal 10 ist wieder 0 1 mal 10 ist wieder 1 etc. Das sollte auch klar sein. Bis hier her ist alles trivial. Und jetzt fügen wir das alles mal zusammen Ausgangszahl / 10 Zwischenergebnis * 10 Endergebnis --------------------------------------------------------------- 0 0 0 1 0 0 2 0 0 ... 9 0 0 10 1 10 11 1 10 12 1 10 ... 19 1 10 20 2 20 21 2 20 ... 29 2 20 30 3 30 31 3 30 ... merkst du was? Durch das dividieren durch 10 (ohne Kommastellen) und anschliessende Multiplizieren mit 10, hast du etwas erreicht. Nämlich alle Zahlen von 0 bis 9 ergeben geschlossen 0. Alle Ausgangszahlen von 10 bis 19 ergeben geschlossen 10, usw. usw. Was du also gemacht hast: Du hast die Ausgangszahlen von 0 bis 99 in 10 Bereiche eingeteilt, wobei die Bereiche auch wieder von 0 bis 90 laufen, aber die Ausgangszahlen sauber in diese Bereiche eingepasst werden.
es ist auch keine Formel verkehrt, aber dumerkst doch sicher auch selber, das etwas anderes herauskommt, als du willt. >Analogwert = Getadc(0) >Analogwert = Analogwert / 204 >Pwm1 = Analogwert * 204 >Pwm1b = Pwm1 wenn man die sinnlose Rechnerei kürzt steht da: Pwm1b = Getadc(0) damit liegen wieder die 10 bit an der PWM.
Edit: Und nein. Du musst nicht durch die gleiche Zahl dividieren mit der du auch multiplizierst. Indem du die beiden Zahlen geeignet wählst, kannst du auch den Zahlenbereich 0 bis 1023 (die Werte, die du vom ADC bekommst) zb in den Wertebereich 0 bis 255 (so wie sie eine 8 Bit PWM haben will) umrechnen, wobei sich eine von dir gewünschte Anzahl an 'Stufen' ergibt. > 1023/204=5,01470882352941*204=1023 > 512/204=2,509803921568627*204=512 Dein Fehler besteht darin, dass du ganz automatisch davon ausgehst, dass in einem Computer alles mit Nachkommastellen gerechnet wird. Dem ist aber nicht so.
Karl Heinz Buchegger schrieb: > Dein Fehler besteht darin, dass du ganz automatisch davon ausgehst, dass > in einem Computer alles mit Nachkommastellen gerechnet wird. Dem ist > aber nicht so. Es ist mir schon bewusst. War eben nur ein dummer fehler von mir. Programmier jetzt schon über 1 Woche an der Pwm rum und mein Kopf lässt mich langsam im Stich.
Du hast das Problem, dass so viele haben. Du willst nich wahrhaben, dass man erst mal mit den Grundlagen anfangen muss, ehe man sein erstes reales Projekt macht.
EazyEddy schrieb: > Karl Heinz Buchegger schrieb: >> Dein Fehler besteht darin, dass du ganz automatisch davon ausgehst, dass >> in einem Computer alles mit Nachkommastellen gerechnet wird. Dem ist >> aber nicht so. > > Es ist mir schon bewusst. War eben nur ein dummer fehler von mir. > Programmier jetzt schon über 1 Woche an der Pwm rum und mein Kopf lässt > mich langsam im Stich. Hinweis. In meiner Tabelle findet sich die Anzahl der Stufen bei dem Zwischenergebnis wieder. Wenn du also 5 Stufen haben willst, dann sorg dafür dass dein Zwischenergebnis aus den Zahlen 0, 1, 2, 3, 4 bestehen kann und aus sonst nichts. Wenn also der ADC Werte von 0 bis 1023 liefert, wodurch musst du diesen Wert dividieren, damit da nur die Zahlen 0, 1, 2, 3, 4 rauskommen können? (Dazu gehst du am besten von der Zahl 1024 aus und verusuchst die so zu dividieren, dass da 5 rauskommt. Denn du willst ja haben, dass sich deine 5 Bereiche gleichmässig auf die ADC Werte verteilen) Hast du dein Zwischenergebnis, dann wird von dort auf die PWM umgerechnet. Die PWM-Stufe (ich geh jetzt mal von einer 8-Bit PWM aus) möchte Werte von 0 bis 255 (weil sie ja 8 Bit ist). Du hast die Zahlen 0, 1, 2, 3, 4. Womit musst du die daher multiplizieren, damit sich daraus Zahlen ergebn die im Bereich 0 bis 255 liegen? (Wieder: womit musst du 5 multplizieren, damit da möglichst 256 rauskommt. Denn auch wieder: du willst eine gleichmässige Aufteilung). Übrigens: Mit Excel lässt sich am PC das alles ganz wunderbar für jede einzelne Zahl, die vom ADC kommen kann, erst mal durchspielen. Da kannst du dir für jede Zahl ansehen, was bei deiner Berechnung rauskommen wird (und natürlich auch die Zwischenwerte, damit du auch verfolgen kannst, wie sich das Endergebnis ergibt)
Limloz schrieb: > wenn man die sinnlose Rechnerei kürzt steht da: > Pwm1b = Getadc(0) Das lässt aber komischer weise nicht kompilieren. Nur das geht: Analogwert = Getadc(0) Pwm1b = Analogwert
EazyEddy schrieb: > Do > Analogwert = Getadc(0) > Analogwert = Analogwert / 204 > Pwm1 = Analogwert * 204 > Pwm1b = Pwm1 > Loop Das ist schon ok so, Du musst nur hier aufpassen: > Config Adc = Single , Prescaler = Auto Ich setze voraus, daß das Poti an VCC & GND angeschlossen ist, es liefert damit zwischen 0..5V an den ADC Eingang. Wenn der ARef-Pin nicht beschaltet ist, dann sollte die Config-Zeile so aussehen: Config Adc = Single , Prescaler = Auto , Reference = AVCC Wenn dagegen der ARef-Pin am µC mit VCC verbunden ist (was man vermeiden sollte), dann reicht Deine ursprüngliche Config-Zeile. Und lass das weg: > Enable Timer1 Das schadet zwar hier nicht, ist aber sinnlos. Damit wird der Timer-Overflowinterrupt erlaubt, hast Du aber nicht.
EazyEddy schrieb: > Limloz schrieb: >> wenn man die sinnlose Rechnerei kürzt steht da: >> Pwm1b = Getadc(0) > > Das lässt aber komischer weise nicht kompilieren. Tja. das ist BASCOM. Das hat so seine Schwächen wenn es um die Formulierung von Berechnungen geht. In einer anderen Programmiersprache wäre das kein Problem. > Nur das geht: > > Analogwert = Getadc(0) > Pwm1b = Analogwert Das ist aber im eigentlichen Sinne nicht das was du willst. Du wolltest ja 5 PWM Bereiche haben. So geht die Potistellung 1:1 auf die PWM durch und du hast keine Bereiche. Die PWM wird natürlich mit der Potistellung mitgehen, aber eben in genau der Abstufung, die du vom ADC hast. Also 1024 Bereiche und nicht 5. Wenn du 5 Bereiche haben willst, dann musst du die Zahlen so bearbeiten, dass sich das ergibt. Das Handwerkszeug dazu hast du ja jetzt. Im Grunde besteht der Trick darin, dass man bei der Division die Nachkommastellen wegfallen lässt. Das ist der entscheidende Punkt, der diese Umrechnung möglich macht.
EazyEddy schrieb: > Limloz schrieb: >> wenn man die sinnlose Rechnerei kürzt steht da: >> Pwm1b = Getadc(0) > > Das lässt aber komischer weise nicht kompilieren. > Nur das geht: > > Analogwert = Getadc(0) > Pwm1b = Analogwert Das soll ja nicht die Lösung für dein Problem sein, sondern durch kürzen lediglich aufzeigen, dass deine Rechnerei keine Skalierung durchführt.
Limloz schrieb: > EazyEddy schrieb: >> Limloz schrieb: >>> wenn man die sinnlose Rechnerei kürzt steht da: >>> Pwm1b = Getadc(0) >> >> Das lässt aber komischer weise nicht kompilieren. >> Nur das geht: >> >> Analogwert = Getadc(0) >> Pwm1b = Analogwert > > > Das soll ja nicht die Lösung für dein Problem sein, sondern durch kürzen > lediglich aufzeigen, dass deine Rechnerei keine Skalierung durchführt. Nur das in seinem Beispiel >Analogwert = Getadc(0) >Analogwert = Analogwert / 204 >Pwm1 = Analogwert * 204 >Pwm1b = Pwm1 die 'sinnlose' Rechnerei durchaus einen Effekt hat und somit ganz und gar nicht sinnlos war.
EazyEddy schrieb: > Limloz schrieb: >> wenn man die sinnlose Rechnerei kürzt steht da: >> Pwm1b = Getadc(0) > > Das lässt aber komischer weise nicht kompilieren. Lass' Dich nicht verunsichern, Limloz hat noch scheinbar noch nie etwas von Ganzzahlen gehört.
Karl Heinz Buchegger schrieb: > Dazu gehst du am besten von der Zahl 1024 aus und > verusuchst die so zu dividieren, dass da 5 rauskommt. Wenn ich 1024 durch 5 dividiere komme ich auf 204,8 (204). Und da haben wir schon wieder dieses dämliche komma. -.-
EazyEddy schrieb: > Karl Heinz Buchegger schrieb: >> Dazu gehst du am besten von der Zahl 1024 aus und >> verusuchst die so zu dividieren, dass da 5 rauskommt. > > Wenn ich 1024 durch 5 dividiere komme ich auf 204,8 (204). > > Und da haben wir schon wieder dieses dämliche komma. -.- Das musst du ignorieren :-) Denn dein Rechner tut es auch.
Karl Heinz Buchegger schrieb: > Das musst du ignorieren :-) > Denn dein Rechner tut es auch. Dann war der Ansatz hier schon gar nicht mal so falsch oder? Analogwert = Getadc(0) Analogwert = Analogwert / 204 Pwm1 = Analogwert * 204 Pwm1b = Pwm1
Also wenn ich jetzt hier beim ADC von 0-1023 arbeite müsste das doch so gehen: /204 *204 0-203 = 0 = 0 204-407 = 1 = 204 408-611 = 2 = 408 612-815 = 3 = 612 816-1019 = 4 = 816 (1020-1023 = 5 = 1020)?
EazyEddy schrieb: > Karl Heinz Buchegger schrieb: >> Das musst du ignorieren :-) >> Denn dein Rechner tut es auch. > > Dann war der Ansatz hier schon gar nicht mal so falsch oder? :-) Du bist der Programmierer. Du entscheidest :-) (Und dann siehst du auch gleich, ob du das was ich dir weiter oben zu vermitteln veruscht habe, auch verstanden hast)
> /204 *204 > 0-203 = 0 = 0 > 204-407 = 1 = 204 > 408-611 = 2 = 408 > 612-815 = 3 = 612 > 816-1019 = 4 = 816 >(1020-1023 = 5 = 1020)? Na das sieht doch schon prinzipiell gut aus! Jetzt musst du nur noch überlegen, ob das deine Forderung > 0%, 25%, 50%, 75% und 100% erfüllt oder nicht, bzw. wie du die Zahlenwerte anpassen musst, damit es das tut. Du willst wahrscheinlich
1 | ADC 0 ................... ............... 1023 |
2 | ----------------------------------------------------------------------------- |
3 | PWM in % 0 0 0 ... 25 25 25 ... 50 50 50 ... 75 75 75 ... 100 100 100 |
4 | PWM als Wert 0 ... 256 ... 512 ... 768 ... 1023 |
und dafür musst du jetzt eine Umrechnung finden, so dass die 100% PWM nicht erst bei einem ADC Wert von 1023 erreicht werden sondern schon früher. Denn die 100% sollen ja wahrscheinlich nicht erst dann kommen, wenn du das Poti an den rechten Anschlag gedreht hast, sondern die Stufen sollen sich gleichmässig auf den Potiweg verteilen. Aber vielleicht sollen sie das auch nicht - du bist der Programmierer, du entscheidest. Wie immer du das haben willst, das ist per Definition richtig.
Karl Heinz Buchegger schrieb: > Jetzt musst du nur noch überlegen, ob das deine Forderung >> 0%, 25%, 50%, 75% und 100% > erfüllt oder nicht, bzw. wie du die Zahlenwerte anpassen musst, damit es > das tut. sieht mir eher nach 0,20,40,60,80,100 aus, da es jetzt von 0 bis 5 geht statt von 0 bis 4^^ Aber ich komme lagsam dahinter. Danke.
EazyEddy schrieb: > Karl Heinz Buchegger schrieb: >> Jetzt musst du nur noch überlegen, ob das deine Forderung >>> 0%, 25%, 50%, 75% und 100% >> erfüllt oder nicht, bzw. wie du die Zahlenwerte anpassen musst, damit es >> das tut. > > sieht mir eher nach 0,20,40,60,80,100 aus, da es jetzt von 0 bis 5 geht > statt von 0 bis 4^^ > > Aber ich komme lagsam dahinter. Danke. Ich bin sicher du kriegst es jetzt alleine hin. Und du hast sicher auch schon eines bemerkt: Es hilft, wenn man sich neben die Tastatur einen Zettel und Bleistift legt, mit dem man solche Zahlenspielereien durchprobieren kann :-) Das glauben nämlich viele auch nicht. Aber in der Programmierung ist Vorbereitung das halbe Leben. Wenn ich etwas nicht mit Papier und Bleistift lösen kann, kann ich es auch nicht programmieren. Papier und Bleistift haben aber den Vorteil, dass ich leicht die Dinge variieren kann und mir an konkreten Zahlen die Dinge verdeutlichen kann. Und zwar in meiner Sprache, zb in Form von Diagrammen oder in Form von Tabellen, und nicht in einer abstrakten Programmiersprache.
Karl Heinz Buchegger schrieb: > Jetzt musst du nur noch überlegen, ob das deine Forderung >> 0%, 25%, 50%, 75% und 100% > erfüllt oder nicht, bzw. wie du die Zahlenwerte anpassen musst, damit es > das tut. Stimmt, hab's zwar aufgemalt, bin trotzdem reingefallen. Was hier erschwerend dazukommt, ist daß beim Schema 0/25/50/75/100 die 100% PWM bereits bei 4V ADC kommen müssen, es also eine Transformation mit gleichzeitiger Begrenzung des Wertes nach oben werden muss, also: pwm_val = adc / 204 * 256 wenn pwm_val > 1023 dann pwm_val = 1023
Das ganze tut jetzt was. Ne veränderung ist feststellbar. werd mir das ma nachm wochenende an nem oszi anschauen. Danke für eure hilfe und schönes Wochenende. MfG Eddy
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.