Hi,
ich habe selbst noch keine Lösung gefunden.
Ist mein Problem zu schwer? Oder hab ichs unverständlich dargestellt?
Danke
Gruß Daniel
Hi,
ich habe einen Atmega48, welcher ja 2 8bit und einen 16bit Timer hat.
Mein Problem ist das ich 4 Led´s unabhängig voneinander Blinken lassen möchte. Die Einschaltzeit ist bei allen 10ms, die Zeit in der sie abgeschaltet sind liegt bei jeweils 2 einmal bei 51ms und einmal bei 86ms. Dabei soll die Zeitspanne in der die Led´s aus sind jeweils um ca. +-5-10ms variieren. Die Variation wollte ich mit dem rnd() Befehl machen. Allerdings weiss ich nicht wie die Led´s jetzt unabhängig voneinander Blinken lasse.
Ich hoffe ihr versteht mein Problem. Ich brauche nur eine Herangehensweise, das Programm schreibe ich dann natürlich selbst.
Danke
Gruß Daniel
Unser Sommer ist ein grün angestrichener Winter. Das einzige reife Obst, das wir haben, sind gebratene Äpfel. [Heinrich Heine]
Hi,
ich habe selbst noch keine Lösung gefunden.
Ist mein Problem zu schwer? Oder hab ichs unverständlich dargestellt?
Danke
Gruß Daniel
Unser Sommer ist ein grün angestrichener Winter. Das einzige reife Obst, das wir haben, sind gebratene Äpfel. [Heinrich Heine]
verständlich JA, aber ohne wissen über die existierende Lösung kann man da jetzt keine sachdienlichen Hinweis geben, die Lösungsmöglichkeiten divergieren zu stark.
Je nachdem wie du das Blinken realisierst, kannst du im Compare-Interrupt ja den nächsten Compare-Wert mit deiner Rnd() um ein paar Takte vergrößern oder verkleinern .... bring mal ein wenig Code mit was du bisher shco hast, dann sehen wir weiter ^^
Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
nicht.
Also eine existierende Lösung habe ich noch nicht so recht. Den Atmega48 wollte ich nehmen, weil es der kleinste µC ist den ich hier rumliegen habe. Ich denke schnell genug ist er. Die Leds hab ich im Moment an PB1-PB4, das kann aber gerne geändert werden.
Mein Code sagt nicht viel weil ich ja noch keinen Ansatz habe. Aber trotzdem zeig ich was ich bis jetzt habe:
Ich dachte mir ich lass den Timer einfach 1000 mal pro Sekunde auslösen, so das er dann für die vier Kanäle jeweils den Status berechnet. Also ob die Led an oder aus sein soll. Aber so recht weiss ich nicht wie ich das realisieren soll.$regfile = "m48def.dat"
$crystal = 1000000
$baud = 9600
Config Timer0 = Timer, Prescale = 8
Config Pinb.1 = Output
Config Pinb.2 = Output
Config Pinb.3 = Output
Config Pinb.4 = Output
Dim I As Integer
Const Timervorgabe = 131
On Timer0 Timer_irq
Enable Timer0
Enable Interrupts
Do
Loop
End
Timer_irq:
Timer0 = Timervorgabe
Return
Das ist meine Überlegung dazu es kann aber alles noch geändert werden, da bin ich flexibel.
Wenn du sonst noch infos brauchst, sag mir was fehlt ich versuche es zu liefern.
Danke
Gruß Daniel
Unser Sommer ist ein grün angestrichener Winter. Das einzige reife Obst, das wir haben, sind gebratene Äpfel. [Heinrich Heine]
die überlegung ist schonmal sehr gut! du legst einfach 4 counter fest und jedesmal wenn einer deiner counter abgelaufen ist, setzt du ihn mit einem neuen wert + (rnd() * zu variierendem Wert) ... aber unter der vorraussetzung, dass rnd() einen wert zwischen 0 udn 1 liefert, das weis ich leider grad nicht ^^
beachte unbedingt, wenn du mit float arbeitest auch immer schön zu casten und die ergebnisvariablen richtig festzulegen, damit du keine kommastellen verlierst!
achja das wichtigeste vergessen, in den counterüberläufen dekrementierst du deine counter bis sie 0 erreichen, vll. noch 4 variablen die signalisieren ob du für die jeweilige LLED gerade in die on oder off phase gehst! und fasse dich bei deinen bedingungen so kurz wie möglich, der interrupt darf nciht so lange dauern!
Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
nicht.
Hallo
Als Bascom-Laie würde ich es so versuchen:
(Ungetestet)Code:$regfile = "m48def.dat" $crystal = 1000000 $baud = 9600 Config Timer0 = Timer, Prescale = 8 Config Pinb.1 = Output Config Pinb.2 = Output Config Pinb.3 = Output Config Pinb.4 = Output Dim I As Integer Dim Led1 As Byte Dim Led2 As Byte Const Timervorgabe = 131 On Timer0 Timer_irq Enable Timer0 Enable Interrupts Led1 = 51 Led2 = 86 Do Loop End Timer_irq: Timer0 = Timervorgabe If Led1 > 0 Then Decr Led1 Else Toggle Pinb.1 If Pinb.1 = 1 Then Led1 = 10 ' Anzeit Else Led1 = Rnd(10) + 51 ' Auszeit End If End If If Led2 > 0 Then Decr Led2 Else Toggle Pinb.2 If Pinb.2 = 1 Then Led2 = 10 Else Led2 = Rnd(10) + 86 End If End If Return
Gruß
mic
Bild hier
Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life!
....ich hatte mir für meine Lichtsteuerung von der letzten Party einfach Zufallszahlen generieren lassen und per if then mit festen Werten verglichen und geschaltet....
à la
if x =2 or x=4 or x=7 then Licht1an
if x =1 or x=4 or x=8 then Licht2an
...usw.
http://www.youtube.com/watch?v=Jk1I7pQMXlU&
http://www.youtube.com/watch?v=UsCiMEjm3Cw
[nachtrag]....habe mal wieder nur Alles halb durchgelesen, da sind ja noch ganz andere Anforderungen...
Geändert von Andree-HB (19.07.2011 um 09:27 Uhr)
Hi,
danke für eure Antworten. Ich habe jetzt auch mal meinen Ansatz in Bascom umgesetzt.
Der ist allerdings auch noch ungetestet. Es geht sicherlich noch einfacher da muss ich nochmal ran und optimieren. Ich gucke nachher mal in Bascom wielange ein IRQ braucht. Dann muss ich evtl auf 2ms "Auflösung" gehen oder ich setz die Fuses auf 8Mhz dann wirds wohl reichen!? Soo Zeitkritisch ist das ganze nicht. Ob ich überhaupt mit den Zeiten so klar komme oder ob ich die Pausen länger ziehen muss weiss ich auch noch nicht. Aber ich denke das gröbste ist geschafft.Code:$regfile = "m48def.dat" $crystal = 1000000 Config Timer0 = Timer , Prescale = 8 Config Pinb.1 = Output Config Pinb.2 = Output Config Pinb.3 = Output Config Pinb.4 = Output Mg1 Alias Pinb.1 Mg2 Alias Pinb.2 Mg3 Alias Pinb.3 Mg4 Alias Pinb.4 Dim Mg1flag As Byte Dim Mg2flag As Byte Dim Mg3flag As Byte Dim Mg4flag As Byte Dim Mg1time As Integer Dim Mg2time As Integer Dim Mg3time As Integer Dim Mg4time As Integer Dim I As Integer Const Timervorgabe = 131 On Timer0 Timer_irq Enable Timer0 Enable Interrupts Mg1flag = 0 Mg2flag = 0 Mg3flag = 0 Mg4flag = 0 Mg1time = 0 Mg2time = 0 Mg3time = 0 Mg4time = 0 Do Loop End Timer_irq: Timer0 = Timervorgabe If Mg1time = 0 Then If Mg1flag = 0 Then Mg1time = Rnd(10) + 46 '46 weil ich gerne 51 +- 5 ms hätte Mg1 = 1 Mg1flag = 1 Else Mg1time = 10 Mg1 = 0 Mg1flag = 0 End If End If If Mg2time = 0 Then If Mg2flag = 0 Then Mg2time = Rnd(10) + 46 Mg2 = 1 mg2flag = 1 Else mg2time = 10 mg2 = 0 mg2flag = 0 End If End If If Mg3time = 0 Then If mg3flag = 0 Then mg3time = Rnd(10) + 81 mg3 = 1 mg3flag = 1 Else mg3time = 10 mg3 = 0 mg3flag = 0 End If End If If mg4time = 0 Then If mg4flag = 0 Then mg4time = Rnd(10) + 81 mg4 = 1 mg4flag = 1 Else mg4time = 10 mg4 = 0 mg4flag = 0 End If End If Mg1time = Mg1time - 1 Mg2time = Mg2time - 1 Mg3time = Mg3time - 1 Mg4time = Mg4time - 1 Return
EDIT: Ok ich muss die Fuses für 8Mhz setzen. Mit 1Mhz schafft er die IRQ nicht rechtzeitig zu beenden. Bei 8Mhz schafft er es ganz locker.
@Mic: Deine Lösung scheint schonmal etwas kürzer zu sein. Das werde ich mir nachher mal genauer ansehen. Durch den Toggle Befehl würde ich ja schonmal die Flags und deren Abfrage sparen.
Danke
Gruß Daniel
Geändert von DanielSan (19.07.2011 um 10:39 Uhr)
Unser Sommer ist ein grün angestrichener Winter. Das einzige reife Obst, das wir haben, sind gebratene Äpfel. [Heinrich Heine]
So hab jetzt mein Programm ausprobiert.
Irgendwie spuckt der Befehl:
rnd(10)
aber nicht die Gewünschten Zufallszahlen von 0-9 aus sondern von 0-5500 (oderso).
Ein weiteres Problem ist, das die Zeiten für "an" und "aus" scheinbar gleich lang sind. Wenn ich die "an"Zeit auf 1000 setze, ist die Led genauso lange an wie aus!?
Gruß Daniel
Unser Sommer ist ein grün angestrichener Winter. Das einzige reife Obst, das wir haben, sind gebratene Äpfel. [Heinrich Heine]
Hallo
Ich programmiere selten mit Bascom und habe das jetzt mal mit dem Simulator überprüft:
Tatsächlich zeigt der Simulator im Watch-Modus nach immer der selben Anzahl von J-Durchläufen einen I-Wert von über 9! In der ersten Variante ohne J war der I-Wert über 9 aber wiederrum ganz anders. Interessanterweise funktioniert rnd() scheinbar richtig, wenn man den Timer0-Interrupt nicht freigibt oder alle Interrupts gesperrt sind. Vielleicht verwendet rnd() irgendwie den Timer0? Seltsam und wieder typisch Bascom..Code:... Dim I As Integer Dim J As Integer Dim Led1 As Byte Dim Led2 As Byte Const Timervorgabe = 131 On Timer0 Timer_irq Enable Timer0 Enable Interrupts Led1 = 51 Led2 = 86 J = 0 Do I = Rnd(10) Incr J Loop End ...
[Edit]
Weil ich auch was sehen will habe ich das Programm an meinen asuro (8 MHz Mega8) angepasst:
Ausgabe auf dem Bascom-Terminal:Code:$regfile = "m8def.dat" $crystal = 8000000 $baud = 2400 Config Timer0 = Timer , Prescale = 64 Config Pind.2 = Output Config Pind.3 = Output Dim I As Integer Dim J As Integer Dim Led1 As Integer Dim Led2 As Integer Const Timervorgabe = 131 On Timer0 Timer_irq Enable Timer0 Enable Interrupts Led1 = 51 Led2 = 86 J = 0 Print "Hallo" Print Do I = Rnd(10) Incr J If I > 9 Then Print "I: " ; I Print "J: " ; J Print J = 0 End If Loop End Timer_irq: Timer0 = Timervorgabe If Led1 > 0 Then Decr Led1 Else Toggle Portd.2 If Pind.2 = 1 Then Led1 = 500 ' Anzeit Else Led1 = 500 ' Auszeit End If End If If Led2 > 0 Then Decr Led2 Else Toggle Portd.3 If Pind.3 = 1 Then Led2 = 200 Else Led2 = Rnd(400) + 500 End If End If Return
VerblüffendCode:Hallo I: 4767 J: 13 I: 61 J: 1 I: 116 J: 9 I: 172 J: 28 I: 59 J: 5 I: 10 J: 53 I: 180 J: 6 I: 176 J: 38 I: 14 J: 2 I: 164 J: 10 I: 157 J: 14 I: 46 J: 57 I: 71 J: 63 I: 113 J: 16
btw. muss es Toggle PORTx.y lauten...
[Edit2]
So scheint es zu funktionieren:
Code:Disable Interrupts I = Rnd(10) Enable Interrupts
Geändert von radbruch (19.07.2011 um 21:28 Uhr)
Bild hier
Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life!
Lesezeichen