Programmumschaltung über TINY45

Fragen zu Schaltungen, Elektronik, Elektrik usw.

Moderator: T.Hoffmann

Antworten
Wiessje
Super-User
Super-User
Beiträge: 61
Registriert: Mo, 10.11.08, 21:33

Sa, 31.07.10, 11:30

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
jkunz
Mega-User
Mega-User
Beiträge: 150
Registriert: Sa, 19.06.10, 21:15

Sa, 31.07.10, 16:19

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, ...
Wiessje
Super-User
Super-User
Beiträge: 61
Registriert: Mo, 10.11.08, 21:33

Sa, 31.07.10, 16:23

Sorry bin mit der Programmierung nicht so bewandelt.

Könntest du mir evtl. grade mal ein Beispiel machen wie ich das mit Bascom programmiere? Mir geht es rein um die Umschaltung.

Wäre nett!

Gruß

Wiessje
jkunz
Mega-User
Mega-User
Beiträge: 150
Registriert: Sa, 19.06.10, 21:15

Sa, 31.07.10, 16:35

Ich nix Bascom.
Ich avr-gcc.
Borax
Star-Admin
Star-Admin
Beiträge: 12243
Registriert: Mo, 10.09.07, 16:28

So, 01.08.10, 13:43

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 )
Wiessje
Super-User
Super-User
Beiträge: 61
Registriert: Mo, 10.11.08, 21:33

So, 01.08.10, 13:52

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!
Wiessje
Super-User
Super-User
Beiträge: 61
Registriert: Mo, 10.11.08, 21:33

Mo, 02.08.10, 17:21

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
Benutzeravatar
Franny
Mega-User
Mega-User
Beiträge: 231
Registriert: Mi, 18.02.09, 13:28
Kontaktdaten:

Mo, 02.08.10, 20:54

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
dussel
Mini-User
Beiträge: 7
Registriert: Sa, 17.05.08, 10:15

Di, 03.08.10, 01:41

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 ......"
Benutzeravatar
TomTTiger
Ultra-User
Ultra-User
Beiträge: 547
Registriert: Mo, 23.06.08, 11:54
Wohnort: Weyerbusch / RP

Di, 03.08.10, 05:58

Moin,

das hier funktioniert nicht.
Wenn Debounce benutzt wird, entprellt er nur die Taste und setzt deinen Tastereingang nicht automatisch auf 0
do
If Taster1 = 1 then goto Unterprogramm1
loop

Unterprogramm1:
do
if Taster1 = 1 then goto Unterprogramm2
LED1 = 1
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 werden

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
Borax
Star-Admin
Star-Admin
Beiträge: 12243
Registriert: Mo, 10.09.07, 16:28

Di, 03.08.10, 09:28

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:
Waitms...
No accurate timing is possible with this command.
In addition, the use of interrupts can slow this routine.
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)
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
Wiessje
Super-User
Super-User
Beiträge: 61
Registriert: Mo, 10.11.08, 21:33

Di, 03.08.10, 16:41

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
Dateianhänge
Test_Tiny45_Blinker2.1.rar
sind beide dateien drin!
(3.06 KiB) 200-mal heruntergeladen
Borax
Star-Admin
Star-Admin
Beiträge: 12243
Registriert: Mo, 10.09.07, 16:28

Di, 03.08.10, 20:04

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...
Wiessje
Super-User
Super-User
Beiträge: 61
Registriert: Mo, 10.11.08, 21:33

Di, 03.08.10, 20:29

Ja so halbwegs, schaltet mal und schaltet mal nicht. aber ich habe keine Ahnung warum. Habe den Pullup noch eingefügt.
Borax
Star-Admin
Star-Admin
Beiträge: 12243
Registriert: Mo, 10.09.07, 16:28

Di, 03.08.10, 20:42

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:

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
Wiessje
Super-User
Super-User
Beiträge: 61
Registriert: Mo, 10.11.08, 21:33

Di, 03.08.10, 21:02

Ohhh yeeessss....

Das wars!!

Dankeschön!!

Aber eine frage hab ich noch. Gibt es die Möglichkeit das wenn ich die Spannung ausschalte der Tiny wieder bei dem Programm weiter macht welches als letztes an war?

Gruß
Borax
Star-Admin
Star-Admin
Beiträge: 12243
Registriert: Mo, 10.09.07, 16:28

Di, 03.08.10, 22:37

Na also! War doch gar nicht so schwer...
Gibt es die Möglichkeit das wenn ich die Spannung ausschalte der Tiny wieder bei dem Programm weiter macht welches als letztes an war?
Ja. Einfach den Wert von Act_prog_a im EEPROM speichern.
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
...
Wiessje
Super-User
Super-User
Beiträge: 61
Registriert: Mo, 10.11.08, 21:33

Mi, 04.08.10, 08:38

Moin,

kann es sein, dass es durch das speichern einen Zeitkonflikt gibt? Die Progamme laufen nur noch ca. Halb so schnell!? Aber das speichern klappt wunderbar!

Gruß
Borax
Star-Admin
Star-Admin
Beiträge: 12243
Registriert: Mo, 10.09.07, 16:28

Mi, 04.08.10, 09:24

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
...
Wiessje
Super-User
Super-User
Beiträge: 61
Registriert: Mo, 10.11.08, 21:33

Mi, 04.08.10, 11:27

Perfekt!

Ich bedanke mich!!!

Läuft erste Sahne!

Danke!!!

Wiessje
Antworten