Programmumschaltung über TINY45
Moderator: T.Hoffmann
Hallo,
hich hätte mal wieder eine Frage. Ich möchte mit einem TINY45 zwei Led´s in einer Blinkfolge an und ausschalten, was für mich noch kein Problem darstellt. Nun möchte ich aber gerne über einen Taster die Blinkfolge verändern.
Bsp.: Einschalten -> 1. Blinkfolge -> Taster drücken -> 2. Blinkfolge -> Taster drücken -> 3. Blinkfolge usw...
Ausgangslage: Tiny45
PB5=Eingang Taster (schließer)
PB1 und PB4=Ausgänge LED´s
Könnte mir evtl. kurz jemand zeigen wie die "Weiterschaltung" mit dem Taster programmiert wird? Die Blinkfolgen werden nur über Zeiten angesteuert.
Danke!!!
Gruß
Wiessje
hich hätte mal wieder eine Frage. Ich möchte mit einem TINY45 zwei Led´s in einer Blinkfolge an und ausschalten, was für mich noch kein Problem darstellt. Nun möchte ich aber gerne über einen Taster die Blinkfolge verändern.
Bsp.: Einschalten -> 1. Blinkfolge -> Taster drücken -> 2. Blinkfolge -> Taster drücken -> 3. Blinkfolge usw...
Ausgangslage: Tiny45
PB5=Eingang Taster (schließer)
PB1 und PB4=Ausgänge LED´s
Könnte mir evtl. kurz jemand zeigen wie die "Weiterschaltung" mit dem Taster programmiert wird? Die Blinkfolgen werden nur über Zeiten angesteuert.
Danke!!!
Gruß
Wiessje
Wo ist das Problem?
Als erstes musst du eine Flankenerkennung und Entprellung programmieren. Das macht man einfach so:
Taster abfragen:
- Wenn nicht gedrückt Entprellzählervariable = 0 setzen.
- Wenn Taster gedrückt Entprellzählervariable eins hoch zählen. (Auf int-Überlauf achten.)
Ist Entprellzählervariable größer X?
- nein: nix machen.
- ja: Zustandsvariable eins hoch zählen und dann modulo Anzahl der Zustände.
Entsprechend dem Wert der Zustandsvariable blinken.
Mit modulo ist der Divisonsrest gemeint. Also 7 modulo 3 = 1. 8 modulo 3 = 2, ...
Dadurch läuft die Zustandsvariable bei z.B. vier Zuständen immer rund:
0, 1, 2, 3, 0, 1, 2, 3, 0, ...
Als erstes musst du eine Flankenerkennung und Entprellung programmieren. Das macht man einfach so:
Taster abfragen:
- Wenn nicht gedrückt Entprellzählervariable = 0 setzen.
- Wenn Taster gedrückt Entprellzählervariable eins hoch zählen. (Auf int-Überlauf achten.)
Ist Entprellzählervariable größer X?
- nein: nix machen.
- ja: Zustandsvariable eins hoch zählen und dann modulo Anzahl der Zustände.
Entsprechend dem Wert der Zustandsvariable blinken.
Mit modulo ist der Divisonsrest gemeint. Also 7 modulo 3 = 1. 8 modulo 3 = 2, ...
Dadurch läuft die Zustandsvariable bei z.B. vier Zuständen immer rund:
0, 1, 2, 3, 0, 1, 2, 3, 0, ...
Da wäre zunächst mal die Frage, ob das Weiterschalten 'immer' möglich sein soll/muss, oder erst nach 'Ausführung' der Blinkfolge. Im ersten Fall ist ein Interrupt erforderlich, im zweiten Fall reicht es den Zustand des Tasters nach jeder Blinkfolge zu prüfen, wenn Taster=0 (es wird gegen Masse geschaltet!), Variable erhöhen und in einem Case... je nach dieser Variablen die entsprechende Blinkfolge auswählen. Weil die Blinkfolge ja einige Zeit läuft, ist keine Entprellung erforderlich. Wenn letzte Blinkfolge erreicht und Taster=0 dann Variable wieder auf Blinkfolge 1 setzten. Mit Interrupt geht das so ähnlich, nur dass man im Timer-Interrupt (der z.B. jede Millisekunde kommt) erst mal wenn Taster=0 eine Variable hochzählt (die sofort auf Null gesetzt wird, wenn Taster=1) und erst dann die Blinkfolgenvariable erhöht, wenn die Zählvariable = 30 ist (das wären dann 0.03 Sekunden Entprellzeit). Die Zählvariable sollte aber Typ Int oder Word sein, nicht dass die nach 256 Millisekunden überläuft und dann automatisch wieder weiterzählt. Wobei man auch das natürlich 'ausnützen' kann. Da musst Du halt ein bischen rumprobieren, bis es so läuft wie Du es haben willst. Das 'Gerüst' ist eigentlich auch nicht viel anders als das beim Test_Mega8_Blinker2 Programm (siehe viewtopic.php?f=35&t=5911&start=54 )
Hallo,
danke schonmal für die schnelle hilfe. Also mir wäre es am liebsten wenn ich immer umschalten könnte. Das Grundgerüst ist eigentlich kein Problem, haste mir ja schon beigebracht
. Mir gehts halt nur um das weiterschalten mit dem Taster!
Danke!
danke schonmal für die schnelle hilfe. Also mir wäre es am liebsten wenn ich immer umschalten könnte. Das Grundgerüst ist eigentlich kein Problem, haste mir ja schon beigebracht
Danke!
Also habe hier mal die Programme welche ich gerne mit dem Taster umschalten möchte.
Habe schon in allen möglichen Foren nachgelesen, habe aber nichts Passendes gefunden.
Wäre toll wenn mir das jemand so umschreiben könnte, dass ich die Programme1-6 mit einem Taster weiterschalten kann.
Gruß
Wiessje
$regfile = "atTiny45.dat"
$crystal = 1000000
'by default the tiny45 has a 8 MHz internal osc.
'and by default the internal 8 divider is enabled resulting in 1 Mhz clock freq.
Dim B As Byte
Kanal1 Alias Portb.4
Config Kanal1 = Output
Kanal2 Alias Portb.1
Config Kanal2 = Output
Eingang1 Alias Portb.5
'Programm1
Do
Set Kanal1
Waitms 40
Reset Kanal1
Waitms 20
Set Kanal2
Waitms 40
Reset Kanal2
Waitms 300
Loop
'Programm2
Do
Set Kanal1
Set Kanal2
Waitms 50
Reset Kanal1
Reset Kanal2
Waitms 100
Set Kanal1
Set Kanal2
Waitms 50
Reset Kanal1
Reset Kanal2
Waitms 250
Loop
'Programm3
Do
Set Kanal1
Waitms 50
Reset Kanal1
Waitms 50
Set Kanal1
Waitms 50
Reset Kanal1
Waitms 150
Set Kanal2
Waitms 50
Reset Kanal2
Waitms 50
Set Kanal2
Waitms 50
Reset Kanal2
Waitms 150
Loop
'Programm4
Do
Set Kanal1
Set Kanal2
Waitms 150
Reset Kanal1
Reset Kanal2
Waitms 100
Set Kanal1
Set Kanal2
Waitms 50
Reset Kanal1
Reset Kanal2
Waitms 100
Set Kanal1
Set Kanal2
Waitms 50
Reset Kanal1
Reset Kanal2
Waitms 350
Loop
'Programm5
Do
Set Kanal1
Waitms 150
Reset Kanal1
Waitms 50
Set Kanal1
Waitms 50
Reset Kanal1
Waitms 50
Set Kanal1
Waitms 50
Reset Kanal1
Waitms 100
Set Kanal2
Waitms 150
Reset Kanal2
Waitms 50
Set Kanal2
Waitms 50
Reset Kanal2
Waitms 50
Set Kanal2
Waitms 50
Reset Kanal2
Waitms 150
Loop
'Programm6
Do
Set Kanal1
Set Kanal2
Waitms 150
Reset Kanal1
Reset Kanal2
Waitms 100
Set Kanal1
Set Kanal2
Waitms 50
Reset Kanal1
Reset Kanal2
Waitms 350
Loop
Habe schon in allen möglichen Foren nachgelesen, habe aber nichts Passendes gefunden.
Wäre toll wenn mir das jemand so umschreiben könnte, dass ich die Programme1-6 mit einem Taster weiterschalten kann.
Gruß
Wiessje
$regfile = "atTiny45.dat"
$crystal = 1000000
'by default the tiny45 has a 8 MHz internal osc.
'and by default the internal 8 divider is enabled resulting in 1 Mhz clock freq.
Dim B As Byte
Kanal1 Alias Portb.4
Config Kanal1 = Output
Kanal2 Alias Portb.1
Config Kanal2 = Output
Eingang1 Alias Portb.5
'Programm1
Do
Set Kanal1
Waitms 40
Reset Kanal1
Waitms 20
Set Kanal2
Waitms 40
Reset Kanal2
Waitms 300
Loop
'Programm2
Do
Set Kanal1
Set Kanal2
Waitms 50
Reset Kanal1
Reset Kanal2
Waitms 100
Set Kanal1
Set Kanal2
Waitms 50
Reset Kanal1
Reset Kanal2
Waitms 250
Loop
'Programm3
Do
Set Kanal1
Waitms 50
Reset Kanal1
Waitms 50
Set Kanal1
Waitms 50
Reset Kanal1
Waitms 150
Set Kanal2
Waitms 50
Reset Kanal2
Waitms 50
Set Kanal2
Waitms 50
Reset Kanal2
Waitms 150
Loop
'Programm4
Do
Set Kanal1
Set Kanal2
Waitms 150
Reset Kanal1
Reset Kanal2
Waitms 100
Set Kanal1
Set Kanal2
Waitms 50
Reset Kanal1
Reset Kanal2
Waitms 100
Set Kanal1
Set Kanal2
Waitms 50
Reset Kanal1
Reset Kanal2
Waitms 350
Loop
'Programm5
Do
Set Kanal1
Waitms 150
Reset Kanal1
Waitms 50
Set Kanal1
Waitms 50
Reset Kanal1
Waitms 50
Set Kanal1
Waitms 50
Reset Kanal1
Waitms 100
Set Kanal2
Waitms 150
Reset Kanal2
Waitms 50
Set Kanal2
Waitms 50
Reset Kanal2
Waitms 50
Set Kanal2
Waitms 50
Reset Kanal2
Waitms 150
Loop
'Programm6
Do
Set Kanal1
Set Kanal2
Waitms 150
Reset Kanal1
Reset Kanal2
Waitms 100
Set Kanal1
Set Kanal2
Waitms 50
Reset Kanal1
Reset Kanal2
Waitms 350
Loop
hi les dir ma den beitrag durch
dann hast du die möglichkeit mit dem drücken des tasters eine variable zu erhöhen (von 0-5 und wenns höher wird soll er widda von 0 anfangen)
dann schreibst du ein letztes unterprogramm (kannst au als hauptprogramm laufen lassen und alles andere als unterprogramme laufen lassen) mit overflow und lässt da abfragen wie hoch die variable gerade is und je nachdem wie hoch soll er eins der anderen programme ausführen.
zweite und glaub ich einfachere, jedoch längere, lösung:
das mit der variable bleibt gleich jedoch sparst du dir den overflow...
also könntest du einfach 7 if funktionen nehmen setzt als vorraussetzung die höhe der variable ein, in den "then" teil dein programm und in den else teil kannst du dir sparen^^
in die 7. if funktion setzt du dann schlussendlich einfach nur "if vari = 6 then vari = 0 end if" (weil vari ja nur von 0-5 gehn soll)
ich hoffe ich konnte dir helfen,ansonsten frag nochma (und sry das ich zu faul was das programm jetzt zu tippen^^, bin eh aus der übung)
mfg, franny
dann hast du die möglichkeit mit dem drücken des tasters eine variable zu erhöhen (von 0-5 und wenns höher wird soll er widda von 0 anfangen)
dann schreibst du ein letztes unterprogramm (kannst au als hauptprogramm laufen lassen und alles andere als unterprogramme laufen lassen) mit overflow und lässt da abfragen wie hoch die variable gerade is und je nachdem wie hoch soll er eins der anderen programme ausführen.
zweite und glaub ich einfachere, jedoch längere, lösung:
das mit der variable bleibt gleich jedoch sparst du dir den overflow...
also könntest du einfach 7 if funktionen nehmen setzt als vorraussetzung die höhe der variable ein, in den "then" teil dein programm und in den else teil kannst du dir sparen^^
in die 7. if funktion setzt du dann schlussendlich einfach nur "if vari = 6 then vari = 0 end if" (weil vari ja nur von 0-5 gehn soll)
ich hoffe ich konnte dir helfen,ansonsten frag nochma (und sry das ich zu faul was das programm jetzt zu tippen^^, bin eh aus der übung)
mfg, franny
Wenns ganz einfach sein soll dann vieleicht so?
---------
---------
---------
Config pinb.5 = input
pinb.5 = 1
Taster1 Alias Portb.5
do
If Taster1 = 1 then goto Unterprogramm1
loop
Unterprogramm1:
do
if Taster1 = 1 then goto Unterprogramm2
LED1 = 1
wait x
LED1 = 0
wait x
loop
Unterprogramm2:
do
if Taster1 = 1 then goto Unterprogramm3
LED1 = 1
wait x
LED1 = 0
wait x
loop
Unterprogramm3:
do
if Taster1 = on then goto Unterprogramm1
LED1 = 1
wait x
LED1 = 0
wait x
loop
Dieser Programmansatz schaltet einfach bei drücken von Taster1 ein Blinkmodus weiter - allerdings darf der Blinkmodus nicht zu kurz sein da sonst, sollte der Taster zu lange gedrückt werden einfach in den nächsten Blinkmodus gewechselt wird.
Natürlich nicht das Tasterentprellen mit debounce vergessen.
Die ersten drei Zeilen können auch entfallen.
Sollte es nicht klappen dann einfach mal "if Taster1 =1 then........" ändern in "if Taster1 = 0 then ......"
---------
---------
---------
Config pinb.5 = input
pinb.5 = 1
Taster1 Alias Portb.5
do
If Taster1 = 1 then goto Unterprogramm1
loop
Unterprogramm1:
do
if Taster1 = 1 then goto Unterprogramm2
LED1 = 1
wait x
LED1 = 0
wait x
loop
Unterprogramm2:
do
if Taster1 = 1 then goto Unterprogramm3
LED1 = 1
wait x
LED1 = 0
wait x
loop
Unterprogramm3:
do
if Taster1 = on then goto Unterprogramm1
LED1 = 1
wait x
LED1 = 0
wait x
loop
Dieser Programmansatz schaltet einfach bei drücken von Taster1 ein Blinkmodus weiter - allerdings darf der Blinkmodus nicht zu kurz sein da sonst, sollte der Taster zu lange gedrückt werden einfach in den nächsten Blinkmodus gewechselt wird.
Natürlich nicht das Tasterentprellen mit debounce vergessen.
Die ersten drei Zeilen können auch entfallen.
Sollte es nicht klappen dann einfach mal "if Taster1 =1 then........" ändern in "if Taster1 = 0 then ......"
Moin,
das hier funktioniert nicht.
Wenn Debounce benutzt wird, entprellt er nur die Taste und setzt deinen Tastereingang nicht automatisch auf 0
Mach das besser mit ner hochzählenden Variablen für den Taster bei der er die Anzahl der Tastendrücke abfängt und jeweils per neuem tasterdruck 1 hochzählt. Lass ihn dann je nach Höhe dieser Zahl in das passende Unterprogramm springen!
Grüße
tom
das hier funktioniert nicht.
Wenn Debounce benutzt wird, entprellt er nur die Taste und setzt deinen Tastereingang nicht automatisch auf 0
In Unterprogramm 1 fragt er den Tastereingang erneut ab, und so schnell lässt kein Mensch den taster los, wie der µProz die Schleife durch hat. Unterprogramm1 würde also nur per Zufall durchlaufen werdendo
If Taster1 = 1 then goto Unterprogramm1
loop
Unterprogramm1:
do
if Taster1 = 1 then goto Unterprogramm2
LED1 = 1
Mach das besser mit ner hochzählenden Variablen für den Taster bei der er die Anzahl der Tastendrücke abfängt und jeweils per neuem tasterdruck 1 hochzählt. Lass ihn dann je nach Höhe dieser Zahl in das passende Unterprogramm springen!
Grüße
tom
Besser das gesamte Timing mit einen Timer-Interupt durchführen. Sowohl für Taster (incl. Entprellung) als auch Ausgabe (keine Waitms verwenden sondern Pausen per Variable festlegen). Steht auch in der Bascom Hilfe:
Also statt PB5 besser PB3 als Eingang verwenden.
Wie schon mal gesagt gibt es ein 'prinzipiell passendes' Programm-Gerüst (für einen ATMega8, aber das sollte man recht einfach umbauen können) schon im alten Thread (siehe viewtopic.php?f=35&t=5911&start=54 )
[EDIT]
Also gut... was macht man nicht alles in der Mittagspause (KEINE FUNKTIONSGARANTIE!):
Noch mal EDIT:
Ich hab vergessen den Pullup für den Eingangspin PORTB.3 zu aktivieren...
Also bitte im Code noch die unterste Zeile einfügen:
PB5 ist der Reset-Pin. Den sollte man nicht verwenden (es ist zwar möglich das per Fuses 'freizuschalten', aber neu programmieren ist danach nur noch mit einem teuren Spezial-Programmer möglich)Waitms...
No accurate timing is possible with this command.
In addition, the use of interrupts can slow this routine.
Also statt PB5 besser PB3 als Eingang verwenden.
Wie schon mal gesagt gibt es ein 'prinzipiell passendes' Programm-Gerüst (für einen ATMega8, aber das sollte man recht einfach umbauen können) schon im alten Thread (siehe viewtopic.php?f=35&t=5911&start=54 )
[EDIT]
Also gut... was macht man nicht alles in der Mittagspause (KEINE FUNKTIONSGARANTIE!):
Noch mal EDIT:
Ich hab vergessen den Pullup für den Eingangspin PORTB.3 zu aktivieren...
Also bitte im Code noch die unterste Zeile einfügen:
Code: Alles auswählen
Kanal1 Alias Portb.4
Config Kanal1 = Output
Kanal2 Alias Portb.1
Config Kanal2 = Output
Eingang1 Alias Pinb.3
Config Eingang1 = Input
Set Portb.3 'Pullup aktivieren
- Dateianhänge
-
- Test_Tiny45_Blinker2.zip
- (1.47 KiB) 209-mal heruntergeladen
Erstmal vielen lieben Dank an alle!
Habe das Programm jetzt auf 6 Programme erweitert, und nun geht es nicht mehr! Kann evtl. mal jemand drüber gucken warum? Macht nur noch wirres zeug!
Danke!
Wiessje
Habe das Programm jetzt auf 6 Programme erweitert, und nun geht es nicht mehr! Kann evtl. mal jemand drüber gucken warum? Macht nur noch wirres zeug!
Danke!
Wiessje
- Dateianhänge
-
- Test_Tiny45_Blinker2.1.rar
- sind beide dateien drin!
- (3.06 KiB) 200-mal heruntergeladen
Bevor ich jetzt das Suchen anfange... Die Version mit 3 Programmen ('meine original-version') hat schon mal/noch funktioniert?
Weil ich hab das ja nie getestet (respektive nur mal so grob im Simulator).
Nicht das der Fehler schon vorher da war...
Weil ich hab das ja nie getestet (respektive nur mal so grob im Simulator).
Nicht das der Fehler schon vorher da war...
Ich glaube, ich hab den Fehler (war aber vorher auch schon da und ob das der einzige Fehler ist, weiß ich auch noch nicht)...
Der Tastercounter bleibt bis zum nächsten Timer-Interrupt beim Stand 30 und schaltet dann die Programme weiter. Um das zu verhindern muss der nach dem 'Weiterschalten' geändert werden. Probier mal das Stück hier einzubauen:
Der Tastercounter bleibt bis zum nächsten Timer-Interrupt beim Stand 30 und schaltet dann die Programme weiter. Um das zu verhindern muss der nach dem 'Weiterschalten' geändert werden. Probier mal das Stück hier einzubauen:
Code: Alles auswählen
'--------------------------
Get_prog_a_type:
'Tastercounter prüfen
If Tastercounter = 30 Then
Incr Prog_a_type
Incr Tastercounter
If Prog_a_type = 7 Then Prog_a_type = 1
End If
If Tastercounter > 500 Then Tastercounter = 0 ' Reset nach 0.5 Sekunden; entspricht 'Autorepeat' alle 0.53 Sekunden
Return
Na also! War doch gar nicht so schwer...
Allerdings sind dann auch noch ein paar zusätzliche/andere Initialisierungen nötig.
Probier mal:
Ja. Einfach den Wert von Act_prog_a im EEPROM speichern.Gibt es die Möglichkeit das wenn ich die Spannung ausschalte der Tiny wieder bei dem Programm weiter macht welches als letztes an war?
Allerdings sind dann auch noch ein paar zusätzliche/andere Initialisierungen nötig.
Probier mal:
Code: Alles auswählen
'Variable für Programm- und Pausensteuerung
Dim Eedummy As Eram Byte
Dim Prog_a_type As Byte 'Lauflichtprogramm 1-5; 6=aus
Dim Act_prog_a As Eram Byte 'aktuell laufendes Lauflichtprogramm 1-5; 6=aus
Dim Prog_a_state As Byte 'Aktueller Zustand Lauflichtprogramm
Dim Prog_a_time As Word 'aktueller Timerstand Lauflichtprogramm
Dim Prog_a_pause As Word 'Pausenzeit Lauflichtprogramm (Max. 65 Sekunden)
Dim Tastercounter As Word
'Init
Tastercounter = 0
Prog_a_pause = 0
Prog_a_time = 1
Prog_a_state = 1
Prog_a_type = Act_prog_a
If Prog_a_type = 0 Or Prog_a_type > 6 Then
Prog_a_type = 1
Act_prog_a = Prog_a_type
End If
'Main Program
...
Ja. Das ist durchaus möglich. Das Speichern ist aber eher nicht das Problem, sondern das Lesen (Select Case Act_prog_a...). Anscheinend ist auch das Lesen vom EEPROM sehr langsam. Also noch eine Variable verwenden und EEPROM nur benutzen wenn 'nötig':
Code: Alles auswählen
'Variable für Programm- und Pausensteuerung
Dim Eedummy As Eram Byte
Dim Prog_a_type As Byte 'Lauflichtprogramm 1-5; 6=aus
Dim Act_prog_a As Byte 'aktuell laufendes Lauflichtprogramm 1-5; 6=aus
Dim Act_prog_ae As Eram Byte 'Gespeichertes letzes aktives Programm
Dim Prog_a_state As Byte 'Aktueller Zustand Lauflichtprogramm
Dim Prog_a_time As Word 'aktueller Timerstand Lauflichtprogramm
Dim Prog_a_pause As Word 'Pausenzeit Lauflichtprogramm (Max. 65 Sekunden)
Dim Tastercounter As Word
'Init
Tastercounter = 0
Prog_a_pause = 0
Prog_a_time = 1
Prog_a_state = 1
Prog_a_type = Act_prog_ae 'gespeichertes Programm abrufen
If Prog_a_type = 0 Or Prog_a_type > 6 Then 'Falls kein gespeichertes Programm vorhanden
Prog_a_type = 1 ' Programm 1 verwenden
Act_prog_ae = Prog_a_type ' und im EEPROM speichern
End If
Act_prog_a = Prog_a_type
'Main Program
Do 'Schleife beginnen
Gosub Get_prog_a_type
If Act_prog_a <> Prog_a_type Then
'Neues Programm ausgewählt -> Init
Act_prog_a = Prog_a_type 'Neues Programm setzen
Act_prog_ae = Prog_a_type 'Neues Programm im EEPROM speichern
Prog_a_pause = 0
Prog_a_time = 1
Prog_a_state = 1
End If
Select Case Act_prog_a
...



