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
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
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.
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???
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
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
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