PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Anfängerfragen für Schulprojekt



YaNnIk
23.05.2009, 15:38
Hi Leute!!

ich habe im Moment ein Schulprojekt zum Thema Beleuchtungstechnik.. Wir sollen aus Sperrholz ne kleine Bühne bauen (Also ne Modellbühne).. Dann sollen wir auf dieser Bühne verschiedene Beleuchtungseffekte vorstellen..

Da ich mit meiner Gruppe was besseres machen will, als die andern O:) O:) habe ich mich entschieden die LED's über einen AtMega 8 anzusteuern..

Da ich in Bascom kein Genie bin und mich erlichgesagt mit dem Programm nur ein ganz kleines bisschen beschäftigt habe, bräuchte ich ein paar Tipps..

So LED Blinken oder so macht ich einfach per I/O Output und dem waitms signal.. das sollte für das projekt reichen..

Nun will ich aber auch LED's dimmen.. Also dass die LED vom ausgeschateten Zustand bis zur voll Power langsamm heller werden soll..


Leider habe ich keine Ahnung, wie das geht.. Ich habe gehört, dass es i-wie mit Timern und PWM gemacht wird.. Aber ich habe das nicht wirklich verstanden..

Kann mir einer dazu nen Tipp geben??

Weil einfach nur an/aus über nen schalter ist mir zu langweilig.. Das machen die anderen Gruppen ja auch ^^


Mfg Yannik

ikarus_177
23.05.2009, 16:56
Nun ja, PWM ist im Prinzip auch nichts anderes als sehr schnelles aus- und einschalten.

Google mal nach "Software-PWM", da dürfte sich schon was finden lassen...

Viele Grüße

YaNnIk
23.05.2009, 18:09
Vielen Dank!!

Also so müsste der Code jetzt richtig sein oder??



$regfile = "m8def.dat"
$crystal = 4000000

Config Portb.1 = Output

Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Prescale = 1

Do
Pwm1a = 205
End



Jetzt habe ich aber noch ein paar Fragen dazu, auf die ich bis jetzt keine Antwort geunden habe..

1. Wenn ich das jetzt so eingebe, wird die LED ja einmal hell und dann direkt wieder dunkel.. Wie kann ich machen, dass sie nur hell wird und dann hell bleibt??

2. Wie kann ich die Geschwindigkeit einstellen??

3. Wie kann ich einen PWM-Wert vorgeben, der gehalten werden soll?? Also ich will nicht, dass es hoch bzw. runter geregelt wird, sondern, dass z.B. die LED nur 50% leuchtet.. Was muss ich dann da machen??


Mfg Yannik

ikarus_177
23.05.2009, 19:21
Hi,

das was jetzt in deinem Code steht, ist die Hardware-PWM der ATMegas. Die läuft völlig autonom vom eigentlichen Prozessor, der so alle Zeit der Welt hat, andere Dinge zu erledigen. Die Hardware-PWM ist so sehr schnell und sehr genau, allerdings kann das Signal nur an bestimmten Pins ausgegeben werden.

Wieviele LEDs sollen denn angesteuert werden?

Vorteil der Software-PWM: es können viele LEDs individuell gesteuert werden (auch an frei wählbaren Pins)

Das hat aber dann den Nachteil, dass der Controller mit dem Steuern der LEDs beschäftigt ist, und nicht mehr viel Zeit für andere Dinge hat.

Das Prinzip dieser Methode ist so einfach wie genial: ein Timer wird so eingestellt, dass er bei Überlauf in eine Interrupt-Routine verzweigt. Dort wird eine Variable bei jedem Durchlauf um 1 erhöht. Ist jetzt der Helligkeitswert der LED (die Vorgabe also) größer als diese Zählvariable, wird der Pin, an dem die LED hängt, auf log. 1 gestellt, ansonsten auf log. 0. Erreicht die Zählvariable den maximal möglichen Helligkeitswert, wird sie wieder auf 0 zurückgesetzt.

Ich hoffe, das war jetzt einigemaßen verständlich ;-)

Die LED leuchtet also immer nur so hell, wie das der Helligkeitswert angibt. Soll die LED dann langsam heller bzw. dunker werden, kannst du das einfach per Änderung der Helligkeitswerte im Hauptprogramm erreichen.

Viele Grüße

YaNnIk
23.05.2009, 19:27
Das Prinzip dieser Methode ist so einfach wie genial: ein Timer wird so eingestellt, dass er bei Überlauf in eine Interrupt-Routine verzweigt. Dort wird eine Variable bei jedem Durchlauf um 1 erhöht. Ist jetzt der Helligkeitswert der LED (die Vorgabe also) größer als diese Zählvariable, wird der Pin, an dem die LED hängt, auf log. 1 gestellt, ansonsten auf log. 0. Erreicht die Zählvariable den maximal möglichen Helligkeitswert, wird sie wieder auf 0 zurückgesetzt.

Sorry, aber ich versteh nur Bahnhof :-s 8-
s_177"]Hi,
Wieviele LEDs sollen denn angesteuert werden?

Also nicht so viele!! Das soll nur nen ganz eifaches Projekt werden.. Also ich denke, es wird immer nur eine Aktion gleichzeitig sein.. Also erst heller werden, dann binken.. oder sowas in der art..

Könntest du das mit dem Software-PWM nochmal genauer erklären.. Ich hab das nicht so wirklich verstanden.. Am besten mit BeispielCode..

Oder nen Link, wos erklärt ist, wär auch gut xD

ikarus_177
23.05.2009, 19:38
Hi,

gut :-)

Hier ein Beispielcode, den ich mal für thunder87 für sein Lauflichtprojekt (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=46218&highlight=atmega8+lauflicht) geschrieben habe - ich denke, er hat nichts dagegen, wenn ich den Code hier reinstelle, ist ja schließlich nichts geheimes dran.


$regfile = "m32def.dat"
$crystal = 16000000
$hwstack = 64
$swstack = 64
$framesize = 128
'$sim

Config Adc = Single , Prescaler = Auto
Start Adc

Config Timer0 = Timer , Prescale = 1
On Timer0 Isr
Enable Timer0

Enable Interrupts


Config Portc = Output
Dim I As Byte
Dim J As Byte
Dim K As Word
Dim W As Word

Dim T As Byte
Dim Wert(9) As Byte


Start Timer0


Portc = 255


Do

Wert(1) = Xx
...
Wert(9) = Yy

Loop

Isr:

Incr T

If T >= 31 Then T = 0

If T < Wert(1) Then Portc.0 = 0
If T >= Wert(1) Then Portc.0 = 1

If T < Wert(2) Then Portc.1 = 0
If T >= Wert(2) Then Portc.1 = 1

If T < Wert(3) Then Portc.2 = 0
If T >= Wert(3) Then Portc.2 = 1

If T < Wert(4) Then Portc.3 = 0
If T >= Wert(4) Then Portc.3 = 1

If T < Wert(5) Then Portc.4 = 0
If T >= Wert(5) Then Portc.4 = 1

If T < Wert(6) Then Portc.5 = 0
If T >= Wert(6) Then Portc.5 = 1

If T < Wert(7) Then Portc.6 = 0
If T >= Wert(7) Then Portc.6 = 1

If T < Wert(8) Then Portc.7 = 0
If T >= Wert(8) Then Portc.7 = 1

If T < Wert(9) Then Portd.7 = 0
If T >= Wert(9) Then Portd.7 = 1

Return


Dieser Code kann also die Helligkeiten von 9LEDs in 256 Stufen regeln (es wären sicherlich auch noch mehr LEDs möglich).

Viele Grüße

YaNnIk
24.05.2009, 10:14
Hi,

wow, vielen Dank!

Aber gib es da nichts einfacheres??? Ich blick da nämlich nicht durch.. Wie gesagt.. Ich hatte mich nur einmal ganz kurz mit Microcontrollern beschäftigt...

EDIT : Könntest du den Code so zurechtstutzen, dass nur noch eine LED von 0% auf 100% gedimmt wird?? Dann könnte ich das glaub ich besser verstehen.. Wäre dir auf jeden Fall sehr dankbar!!

ikarus_177
24.05.2009, 10:28
Hi,

eigentlich ist es überhaupt nicht kompliziert ;-)

Ich versuchs einfach nochmal: ein Timer wird so eingestellt, dass er in bestimmten Zeitabständen in ein Unterprogramm reinspringt, wo dann die LEDs angesteuert werden. Die Initialisierung des Timers ist die Geschichte mit
Config Timer0 = Timer , Prescale = 1
On Timer0 Isr
Enable Timer0


Hier sagen wir ihm also, er soll nach einer gewissen Zeit (die hier eher nebensächlich ist, zumindest fürs Verständnis) zu der Stelle springen, die da heißt: Isr
Das ist eher im unteren Codeabschnitt.

Sagen wir, der Prozessor springt jetzt Hausnummer 1000Mal pro Sekunde in dieses Unterprogramm, also mit 1kHz. Bei jedem Durchlauf der Routine wird die Variable "T" um 1 erhöht. Da thunder87 256 Stufen zu viel waren, hab ich es hier auf 31 Stufen beschränkt. Erreicht die Variable also den Wert 31, wird sie wieder auf 0 zurückgesetzt und weiter fröhlich erhöht.

Eine LED kann also maximal 31 "Zeiteinheiten" eingeschaltet sein. In meinem Beispiel geben die Wert(x)-Zahlen an, wie lange die LED AUSgeschaltet ist, man könnte es aber genausogut umgekehrt machen. Angenommen, der Wert, den wir haben wollen, ist 15, also ca. die Hälfte der Zeit. Jetzt kommt der Prozessor in die Unterroutine, die Zählvariable ist 0. Dank
If T < Wert(1) Then Portc.0 = 0 ist die LED nun so lange ausgeschaltet, bis T den Wert von Wert(1) erreicht hat, in unserem Fall eben 15. Die restliche Zeit, also von 15-31, ist die LED nun eingeschaltet, danach wird die Variable wieder auf 0 gesetzt und das Spiel beginnt von neuem.

Da diese Routine nun sehr oft in der Sekunde ausgeführt wird, merken wir das ständige Blinken der LED nicht - für das menschliche Auge erscheint die Helligkeit "gedimmt".

Viele Grüße

YaNnIk
24.05.2009, 10:40
Ahh.. Okay, ich glaube ich verstehs langsam.. Aber eine Sache ist mir noch unklar..



Da thunder87 256 Stufen zu viel waren, hab ich es hier auf 31 Stufen beschränkt.

Wo steht das in dem Code?? Bin ich blind oder was??


bis T den Wert von Wert(1) erreicht hat, in unserem Fall eben 15.

Warum entspricht die 1 da jetzt dem Wert 15?? Was wäre dann Wert(2)?? 30??

ikarus_177
24.05.2009, 10:43
Hi,

das steht da:
If T >= 31 Then T = 0
Wenn T also den Wert 31 erreicht, wird es auf 0 zurückgesetzt.

Bei Wert(x) handelt es sich um ein Array, im Prinzip 9 zusammenhängende Variablen (da wir ja 9 LEDs haben). Auf die einzelnen Variablen kann durch einen sog. Index zugegriffen werden, der geht bei uns von 1-9. Wert(1) ist also eine eingenständige Variable (genauso wie Wert(8) oder Wert(6)) der einfach der gewünschte Helligkeitswert zugewiesen wird.

Viele Grüße

YaNnIk
24.05.2009, 12:23
Okay.. Ich versuch mal mein Glück und schreib das mal so, wie ichs verstnden hab..


$regfile = "m32def.dat"
$crystal = 16000000

Config Porta.0 = Output

Config Timer0 = Timer , Prescale = 1
On Timer0 Isr

Enable Timer0

Enable Interrupts

Dim T As Byte

Start Timer0

Porta.0 = 255


So... Jetzt komm ich nicht mehr weiter..


Was muss ich da jetzt machen um Porta.0 von 0% auf 100% zu dimmen?? Und wie kann ich die Geschwindigkeit einstellen??







Edit :

So, ich habe jetzt nochmal das Internet durchkämmt und habe nun Folgenden kleinen Code geschrieben :


$regfile = "attiny2313.dat"
$crystal = 4000000

Config Portb.2 = Output

Config Timer0 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Prescale = 1

Dim Hochdimmen As Byte
Dim Runterdimmen As Byte

Helligkeit Alias Pwm0a

Do

For Hochdimmen = 1 To 255
Helligkeit = Hochdimmen

Next Hochdimmen

Wait 10

For Runterdimmen = 1 To 255
Helligkeit = 255 - Runterdimmen

Loop

End

Also die LED an Pin 14 des ATTiny2313 wir nun von 0% auf 100% Hochgedimmt und dann nach 10 Sekunden von 100% auf 0% runtergedimmt..

Und um die Geschwindigkeit zu verändern kann man


For Hochdimmen = 1 To 255

ja auch anders definieren..


Ähmm ja.. Wie kann man das den anders definieren??
8-[

Wie kann ich die Geschwindigkeit, die er zum Hochzählen von 1 auf 255 ändern?? Die ist ja durch Timer0 definiert!!?!!


Auch noch eine Frage : Wie lange bräuchte der Jetzt um hochzuzählen?? 1 Sekunde oder was?

ikarus_177
24.05.2009, 20:37
Hi,

in dem Code für den ATTiny verwendest du ja die HW-PWM. Die Zeit, die er jetzt bräuchte, um die LED hochzudimmen würdest du wahrscheinlich gar nicht bemerken, da der µC die Schleife mit seinen volle 4MHz ausführt...

Du könntest so etwas wie "waitms X" in die Schleife einbauen, dann macht er bei jedem Durchlauf eine kleine Pause. Je nach dem, wie lange diese Pause ist, desto langsamer/schneller wird gedimmt.

Viele Grüße

YaNnIk
24.05.2009, 20:40
Du könntest so etwas wie "waitms X" in die Schleife einbauen, dann macht er bei jedem Durchlauf eine kleine Pause. Je nach dem, wie lange diese Pause ist, desto langsamer/schneller wird gedimmt.

Vielen Dank! Könntest du den Code mal so veränder und den Qait Befehl einbauen?? Ich wüsste nämlich nicht, wo ich das jetzt reinpacken soll...


Mfg Yannik

ikarus_177
24.05.2009, 20:42
Hi,


$regfile = "attiny2313.dat"
$crystal = 4000000

Config Portb.2 = Output

Config Timer0 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Prescale = 1

Dim Hochdimmen As Byte
Dim Runterdimmen As Byte

Helligkeit Alias Pwm0a

Do

For Hochdimmen = 1 To 255
Helligkeit = Hochdimmen
Waitms 10
Next

Wait 10

For Runterdimmen = 1 To 255
Helligkeit = 255 - Runterdimmen
Waitms 10
Next

Loop

End

Die 10 ms sind jetzt aber nur geschätzt, da müsste man schon die Schaltung zuerst aufbauen, und sich dann langsam an den Wert rantasten, der einem am meisten zusagt.

YaNnIk
24.05.2009, 20:46
For Hochdimmen = 1 To 255
Helligkeit = Hochdimmen
Waitms 10
Next

Wait 10

For Runterdimmen = 1 To 255
Helligkeit = 255 - Runterdimmen
Waitms 10
Next

Aber da wird doch jetzt nur 10ms gewartet, dann hochgedimmt, dann 10 sekunden gewartet und dann wieder runtergedimmt.. Was hat das jetzt mit der Geschwindigkeit der Hoch-/Runterdimmen zu tun??

ikarus_177
24.05.2009, 20:48
Nein, nicht ganz. Der Controller kommt zur Schleife, die Variable "Hochdimmen" ist 1. Dieser Wert geht nun an die LED, die logischerweise sehr dunkel ist. Dann wartet er 10 ms, dann wird die LED um 1 "heller gemacht", wieder gewartet. Solange, bis die Schleife zu Ende ist, und die LED 100% leuchtet. Dann erst wartet er 10 Sekunden und dann dimmt die LED nach dem selben Schema wieder gegen 0.

YaNnIk
24.05.2009, 20:51
Na wenn du meinst xD Dann wird auch hoffentlich so stimmen...