PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RC5 kurzen und langen Tastendruck unterscheiden



TobiasBlome
03.01.2011, 21:39
Hallo,
ich möchte mit einer RC5FB bei kurzem druck auf Taste 1 Ausgang 1 schalten. Bei langem Druck sollen Ausgang 1&2 schalten.
Wie werte ich die Tastenlänge aus?

In meinem Versuch zähle ich eine Variable hoch - aber irgend wo hängt es - uns zwar beim zurücksetzen/auswerten der Variable.



'RC5 Eingang über Pin5 / PD3

'L1-L12 sind die Lampen, wobei die ungerade die halbe Helligkeit ist und die gerade die volle Helligkeit mit beiden zusammen

'-------------------------------------------------------------------------------
'Konfiguration µC:
$regfile = "m8def.dat" 'AT-Mega8
$crystal = 16000000 'Quarz: 16 MHz
$baud = 38400 'Baudrate definieren

'-------------------------------------------------------------------------------
'Ein- Ausgänge:
Ddrb = &B11111111 '1 Ausgang, 0 Eingang => Pin PB7-0 als Ausgang
Ddrc = &B11111111 '1 Ausgang, 0 Eingang => Pin PB7-0 als Ausgang

Portb = 0
Portc = 0

'-------------------------------------------------------------------------------
'Timer0 = 8 Bit
'wird für RC5 Auswertung benötigt!!!
Config Rc5 = Pind.3 'Timer0 in Benutzung!!!
Portd.3 = 1 '??????????????????????????????????

'16Bit Timer:
Config Timer1 = Timer , Prescale = 256
On Timer1 Timer1_irq
Const Timervorgabe = 34286 '2 mal pro Sekunde
Enable Timer1
Enable Interrupts


'-------------------------------------------------------------------------------
'Variablen:
'-------------------------------------------------------------------------------
Dim Address As Byte , Command As Byte , Flag As Bit 'RC5

'Taste 1-6 auf der FB
Dim T1 As Word , T2 As Word , T3 As Word , T4 As Word , T5 As Word , T6 As Word
'Lampe 1-12
Dim L1 As Bit , L2 As Bit , L3 As Bit , L4 As Bit , L5 As Bit , L6 As Bit , L7 As Bit , L8 As Bit , L9 As Bit , L10 As Bit , L11 As Bit , L12 As Bit ,


'Lampen festlegen
Portc.5 = L1
Portc.4 = L2




'-------------------------------------------------------------------------------
'Vor Programmstart:

'alle Lampen aus:
L1 = 0
L2 = 0
L3 = 0
L4 = 0
L5 = 0
L6 = 0
L7 = 0
L8 = 0
L9 = 0
L10 = 0
L11 = 0
L12 = 0


'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'Hauptprogramm Do...Loop
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
Print " geht los... "
Do


'-------------------------------------------------------------------------------
'Rc5 Code einlesen:
Getrc5(address , Command)
'Print "Address: " ; Address
'Print "Command: " ; Command



'-------------------------------------------------------------------------------
'RC5 Code umsetzen:

If Address = 0 Then 'Adresse 0=TV FB
Command = Command And &B01111111
Reset Command.7 ' reset toggle bit / Restmüll beseitigen

Select Case Command

Case 0 : Print "CASE = 0"
Case 1 : Incr T1
Case 2 : Incr T2
Case 3 : Incr T3
Case 4 : Incr T4
Case 5 : Incr T5
Case 6 : Incr T6
Case Else : Print "Fehler: " ; Command
End Select


If T1 > 0 Then 'wenn Taste 1 gedrückt wurde




If T1 => 1 And T1 < 6 Then 'wenn Taste kurz gedrückt wurde
Print "--> T1: " ; T1
If L1 = 0 Then 'wenn Lampe 1 aus ist
Set L1 'schalte Lampe 1 an
Print "L1 an"
Else 'sonst
Reset L1 'schalte Lampe 1 aus
Print "L1 aus"
Reset L2 'schalte Lampe 2 aus
Print "L2 aus"
End If

Else 'Wenn Taste 1 lange gedrückt wurde
Print "--> T1größer5: " ; T1
If L1 <> L2 Then 'also nur 1 Lampen an
Set L1 'schalte Lampe 1 an
Print "L1an"
Set L2 'schalte Lame 2 an
Print "L2an"
End If

If L1 = 1 And L2 = 1 Then 'Wenn beide Lampen an sind
Reset L1 'schalte Lampe 1 aus
Print "L1aus"
Reset L2 'schalte Lampe 2 aus
Print "L2aus"
End If

If L1 = 0 And L2 = 0 Then 'Wenn beide Lampen aus sind
Set L1 'schlate Lampe 1 an
Print "L1 AN"
Set L2 'schalte Lampe 2 an
Print "L2 AN"
End If

End If


End If 'ENDE von "wenn Taste 1 gedrückt wurde"







'Print "-----------------------"
'Print "Address: " ; Address
'Print "Command: " ; Command
'Print "-----------------------"

Else 'Wenn Adresse nicht = 0
Timer1 = Timervorgabe 'Timer1 zurücksetzen, damit erst bei Tastendruck gezählt wird
Print "timerzurück"
End If






Loop
'-------------------------------------------------------------------------------

'-------------------------------------------------------------------------------
'Sprungmarken
'-------------------------------------------------------------------------------
Timer1_irq:
Timer1 = Timervorgabe

T1 = 0
T2 = 0
T3 = 0
T4 = 0
T5 = 0
T6 = 0

Print "L1: " ; L1
Print "L2: " ; L2


Return


wo muss ich den Timer zurück setzen? - nun wird er nach jedem Tastendruck zurück gesetzt und wenn man die Taste lange drückt, verhält sich das Programm so, als wenn die FB immer Impulse sendet.


Hintergrund:
Ich habe 6 Lampen mit je 2 Leuchtmitteln. 1 Leuchtmittel ist also halbe Helligkeit und 2 Leuchtmittel sind dann volle Helligkeit. Wenn man kurz drückt, soll eine Lampe angehen und wenn man etwas länger drückt, sollen beide Leuchtmittel angehen. "Aus" natürlich genauso.

radbruch
03.01.2011, 22:10
Hallo

Ja, genau das macht die Fernbedienung, wenn man länger drückt. Sie sendet mehrfach fast den selben Code. Das "fast" steckt hier:

Reset Command.7 ' reset toggle bit / Restmüll beseitigen

Schau dir mal an was das Togglebit macht!

Gruß

mic

Im RN-Wissen ist es das Flip-Bit:
http://www.rn-wissen.de/index.php/RC5-Code

TobiasBlome
04.01.2011, 09:42
Hallo,
vielen Dank, nun wusste ich wonach ich suchen muss.

Nun kann ich einen langen Tastendruck auswerten. Die Variable Taste_lang wird jede Sekunde zurückgesetzt.


If Command.7 = Command_old Then
Incr Taste_lang
Else
Command_old = Command.7
End If


Jetzt muss ich es nur noch schaffen, dass bei einem langen Tastendruck nicht 5 mal vorher geschaltet wird - so ist es zumindest jetzt...(Variable Taste_lang = 5 ist ein langer Tastendruck)

TobiasBlome
04.01.2011, 11:51
so, ich habe nun einen neuen Lösungsansatz:
Problem war dass bei einem langen Tastendruck mehrmals zuvor geschaltet wurde bis der lange Tastendruck zählt(also der kurze Tastendruck wurde vorher ausgewertet). Nun habe ich mit den Bedingungen Variablen gesetzt und diese werden 1 mal pro Sekunde an die Ports übertragen.

Manchmal kommt es vor, dass der Timer schon fast durchgelaufen ist, wenn eine Taste gedrückt wird. Wie muss ich das anstellen, dass der Timer erst losläuft, wenn eine Taste gedrückt wird?


'-------------------------------------------------------------------------------
'Konfiguration µC:
$regfile = "m8def.dat" 'AT-Mega8
$crystal = 16000000 'Quarz: 16 MHz
$baud = 38400 'Baudrate definieren

'-------------------------------------------------------------------------------
'Ein- Ausgänge:
Ddrb = &B11111111 '1 Ausgang, 0 Eingang => Pin PB7-0 als Ausgang
Ddrc = &B11111111 '1 Ausgang, 0 Eingang => Pin PB7-0 als Ausgang

Portb = 0
Portc = 0

'-------------------------------------------------------------------------------
'Timer0 = 8 Bit
'wird für RC5 Auswertung benötigt!!!
Config Rc5 = Pind.3 'Timer0 in Benutzung!!!
Portd.3 = 1 '??????????????????????????????????

'16Bit Timer:
Config Timer1 = Timer , Prescale = 256
On Timer1 Timer1_irq
Const Timervorgabe = 64911 '100 mal pro Sekunde
Enable Timer1
Enable Interrupts


'-------------------------------------------------------------------------------
'Variablen:
'-------------------------------------------------------------------------------
Dim Address As Byte , Command As Byte , Command_old As Bit , Flag As Bit 'RC5

'Taste lange gedrückt
Dim Taste_lang As Word
'Taste 1-6 auf der FB
Dim T1 As Word , T2 As Word , T3 As Word , T4 As Word , T5 As Word , T6 As Word
'Lampe 1-12
Dim L1 As Bit , L2 As Bit , L3 As Bit , L4 As Bit , L5 As Bit , L6 As Bit , L7 As Bit , L8 As Bit , L9 As Bit , L10 As Bit , L11 As Bit , L12 As Bit ,
Dim L1s As Bit , L2s As Bit

Dim Sek As Byte 'wenn = 100 dann 1 sec um

'Lampen festlegen
L1 Alias Portc.5
L2 Alias Portc.4



'-------------------------------------------------------------------------------
'Vor Programmstart:

'alle Lampen aus:
L1 = 0
L2 = 0
L3 = 0
L4 = 0
L5 = 0
L6 = 0
L7 = 0
L8 = 0
L9 = 0
L10 = 0
L11 = 0
L12 = 0


'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'Hauptprogramm Do...Loop
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
Print " geht los... "
Do


'-------------------------------------------------------------------------------
'Rc5 Code einlesen:
Getrc5(address , Command)
'Print "Address: " ; Address
'Print "Command: " ; Command



'-------------------------------------------------------------------------------
'RC5 Code umsetzen:

If Address = 0 Then 'Adresse 0=TV FB

If Command.7 = Command_old Then
Incr Taste_lang
Else
Command_old = Command.7
End If

'Print "Command.7: " ; Command.7
'Print "Taste_lang: " ; Taste_lang

'Command = Command And &B01111111 'reset toggle bit
Reset Command.7 'reset toggle bit
Select Case Command

Case 0 : Print "CASE = 0"
Case 1 : Incr T1
Case 2 : Incr T2
Case 3 : Incr T3
Case 4 : Incr T4
Case 5 : Incr T5
Case 6 : Incr T6
Case Else : Print "Fehler: " ; Command
End Select





If T1 > 0 Then 'wenn Taste 1 gedrückt wurde

L1s = L1 'Iststatus übernehmen
L2s = L2 'Iststatus übernehmen

If L1s = 0 And L2s = 0 Then
L1s = 1
Goto Sprung1 'wenn Bedingung richtig, dann Restüberspringen bzw. bei lange drücken weitermachen
End If
If L1s = 1 And L2s = 0 Then
L1s = 0
Goto Sprung1
End If
If L1s = 1 And L2s = 1 Then
L2s = 0
End If

Sprung1:


If Taste_lang => 2 Then 'wenn lange gedrückt wird
Print "Taste_lang: " ; Taste_lang
If L1 = 1 And L2 = 0 Then
L1s = 1 'immer beide setzen, falls davor anders gesetzt wurde(einzellampe)
L2s = 1
Goto Sprung2 'wenn Bedingung richtig, dann Restüberspringen bzw. bei lange drücken weitermachen
End If
If L1 = 1 And L2 = 1 Then
L1s = 0
L2s = 0
Goto Sprung2 'wenn Bedingung richtig, dann Restüberspringen bzw. bei lange drücken weitermachen
End If
If L1 = 0 And L2 = 0 Then
L1s = 1
L2s = 1
End If
End If

Sprung2:

End If 'ENDE von "wenn Taste 1 gedrückt wurde"







'Print "-----------------------"
'Print "Address: " ; Address
'Print "Command: " ; Command
'Print "-----------------------"



Else 'Wenn Adresse nicht = 0
'Timer1 = Timervorgabe 'Timer1 zurücksetzen, damit erst bei Tastendruck gezählt wird
'Print "timerzurück"
End If




If Sek => 100 Then
Sek = 0
T1 = 0
T2 = 0
T3 = 0
T4 = 0
T5 = 0
T6 = 0
Taste_lang = 0

L1 = L1s
L2 = L2s

Print "L1: " ; L1
Print "L2: " ; L2

Sek = 0
End If



Loop
'-------------------------------------------------------------------------------

'-------------------------------------------------------------------------------
'Sprungmarken
'-------------------------------------------------------------------------------
Timer1_irq:
Timer1 = Timervorgabe

Incr Sek



Return

TobiasBlome
04.01.2011, 18:33
so, das Programm läuft soweit.
Als nur 2 Ausgänge geschaltet werden konnten lief es flüssig - jetzt mit 12 Ausgängen ist es etwas hackelig...also falls jemand noch optimierungsvorschläge hat - gerne!





'Konfiguration µC:
$regfile = "m8def.dat" 'AT-Mega8
$crystal = 16000000 'Quarz: 16 MHz
$baud = 38400 'Baudrate definieren

'-------------------------------------------------------------------------------
'Ein- Ausgänge:
Ddrb = &B11111111 '1 Ausgang, 0 Eingang => Pin PB7-0 als Ausgang
Ddrc = &B11111111 '1 Ausgang, 0 Eingang => Pin PB7-0 als Ausgang

Portb = 0
Portc = 0

'-------------------------------------------------------------------------------
'Timer0 = 8 Bit
'wird für RC5 Auswertung benötigt!!!
Config Rc5 = Pind.3 'Timer0 in Benutzung!!!
Portd.3 = 1 '??????????????????????????????????

'16Bit Timer:
Config Timer1 = Timer , Prescale = 256
On Timer1 Timer1_irq
Const Timervorgabe = 64911 '100 mal pro Sekunde
Enable Timer1
Enable Interrupts


'-------------------------------------------------------------------------------
'Variablen:
'-------------------------------------------------------------------------------
Dim Address As Byte , Command As Byte , Command_old As Bit , Flag As Bit 'RC5

'Taste lange gedrückt
Dim Taste_lang As Word
'Taste 1-6 auf der FB
Dim T1 As Word , T2 As Word , T3 As Word , T4 As Word , T5 As Word , T6 As Word
'Lampe 1-12
Dim L1s As Bit , L2s As Bit , L3s As Bit , L4s As Bit , L5s As Bit , L6s As Bit , L7s As Bit , L8s As Bit , L9s As Bit , L10s As Bit , L11s As Bit , L12s As Bit ,

Dim Empfang As Bit 'ist 0 wenn kein empfang also 255 von address

Dim Sek As Byte 'wenn = 100 dann 1 sec um

'Lampen festlegen
L1 Alias Portc.5
L2 Alias Portc.4
L3 Alias Portc.3
L4 Alias Portc.2
L5 Alias Portc.1
L6 Alias Portc.0
L7 Alias Portb.5
L8 Alias Portb.4
L9 Alias Portb.3
L10 Alias Portb.2
L11 Alias Portb.1
L12 Alias Portb.0

'-------------------------------------------------------------------------------
'Vor Programmstart:

'alle Lampen aus:
L1 = 0
L2 = 0
L3 = 0
L4 = 0
L5 = 0
L6 = 0
L7 = 0
L8 = 0
L9 = 0
L10 = 0
L11 = 0
L12 = 0


'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'Hauptprogramm Do...Loop
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
Print "Programm Start 38400 Baud..."
Do


'-------------------------------------------------------------------------------
'Rc5 Code einlesen:
Getrc5(address , Command)
'Print "Address: " ; Address
'Print "Command: " ; Command



'-------------------------------------------------------------------------------
'RC5 Code umsetzen:
If Address = 255 Then 'also kein Signal
Empfang = 0
End If


If Address = 0 Then 'Adresse 0=TV FB
If Empfang = 0 Then
Empfang = 1
Timer1 = Timervorgabe 'Timer1 zurücksetzen, damit erst bei Tastendruck gezählt wird
'Print "timerzurück"
End If

If Command.7 = Command_old Then
Incr Taste_lang
Else
Taste_lang = 0 'Variable zurücksetzen
Command_old = Command.7
End If

'Print "Command.7: " ; Command.7
'Print "Taste_lang: " ; Taste_lang

'Command = Command And &B01111111 'reset toggle bit
Reset Command.7 'reset toggle bit

Select Case Command
Case 0 : Print "CASE = 0"
Case 1 : Incr T1
Goto Lampe1
Case 2 : Incr T2
Goto Lampe3
Case 3 : Incr T3
Goto Lampe5
Case 4 : Incr T4
Goto Lampe7
Case 5 : Incr T5
Goto Lampe9
Case 6 : Incr T6
Goto Lampe11
Case Else : Print "Fehler: " ; Command
End Select
End If


'-------------------------------------------------------------------------------
'Relais ansteuern
'-------------------------------------------------------------------------------

Lampe1:
'=============

If T1 > 0 And Taste_lang < 6 Then 'wenn Taste 1 gedrückt wurde UND Taste_lang nicht überlaufen ist!

L1s = L1 'Iststatus von Lampen übernehmen
L2s = L2 'Iststatus von Lampen übernehmen

If L1s = 0 And L2s = 0 Then
L1s = 1
Goto Sprung1 'wenn Bedingung richtig, dann Restüberspringen bzw. bei lange drücken weitermachen
End If
If L1s = 1 And L2s = 0 Then
L1s = 0
Goto Sprung1
End If
If L1s = 1 And L2s = 1 Then
L2s = 0
End If

Sprung1:


If Taste_lang => 3 And Taste_lang <= 5 Then 'wenn lange gedrückt wird (<=5 damit nicht über Timer gesprungen wird)
Print "Taste_lang: " ; Taste_lang
Taste_lang = 100 'Variable setzen damit Routine kein zweites mal erfüllt wird
If L1 = 1 And L2 = 0 Then
L1s = 1 'immer beide setzen, falls davor anders gesetzt wurde(einzellampe)
L2s = 1
Goto Sprung2 'wenn Bedingung richtig, dann Restüberspringen bzw. bei lange drücken weitermachen
End If
If L1 = 1 And L2 = 1 Then
L1s = 0
L2s = 0
Goto Sprung2 'wenn Bedingung richtig, dann Restüberspringen bzw. bei lange drücken weitermachen
End If
If L1 = 0 And L2 = 0 Then
L1s = 1
L2s = 1
End If
End If

Sprung2:

End If 'ENDE von "wenn Taste 1 gedrückt wurde"
Goto Lampenende


Lampe3:
'=============

If T2 > 0 And Taste_lang < 6 Then 'wenn Taste 1 gedrückt wurde UND Taste_lang nicht überlaufen ist!

L3s = L3 'Iststatus von Lampen übernehmen
L4s = L4 'Iststatus von Lampen übernehmen

If L3s = 0 And L4s = 0 Then
L3s = 1
Goto Sprung3 'wenn Bedingung richtig, dann Restüberspringen bzw. bei lange drücken weitermachen
End If
If L3s = 1 And L4s = 0 Then
L3s = 0
Goto Sprung3
End If
If L3s = 1 And L4s = 1 Then
L4s = 0
End If

Sprung3:


If Taste_lang => 3 And Taste_lang <= 5 Then 'wenn lange gedrückt wird (<=5 damit nicht über Timer gesprungen wird)
Print "Taste_lang: " ; Taste_lang
Taste_lang = 100 'Variable setzen damit Routine kein zweites mal erfüllt wird
If L3 = 1 And L4 = 0 Then
L3s = 1 'immer beide setzen, falls davor anders gesetzt wurde(einzellampe)
L4s = 1
Goto Sprung4 'wenn Bedingung richtig, dann Restüberspringen bzw. bei lange drücken weitermachen
End If
If L3 = 1 And L4 = 1 Then
L3s = 0
L4s = 0
Goto Sprung4 'wenn Bedingung richtig, dann Restüberspringen bzw. bei lange drücken weitermachen
End If
If L3 = 0 And L4 = 0 Then
L3s = 1
L4s = 1
End If
End If

Sprung4:

End If 'ENDE von "wenn Taste 1 gedrückt wurde"
Goto Lampenende


Lampe5:
'=============

If T3 > 0 And Taste_lang < 6 Then 'wenn Taste 1 gedrückt wurde UND Taste_lang nicht überlaufen ist!

L5s = L5 'Iststatus von Lampen übernehmen
L6s = L6 'Iststatus von Lampen übernehmen

If L5s = 0 And L6s = 0 Then
L5s = 1
Goto Sprung5 'wenn Bedingung richtig, dann Restüberspringen bzw. bei lange drücken weitermachen
End If
If L5s = 1 And L6s = 0 Then
L5s = 0
Goto Sprung5
End If
If L5s = 1 And L6s = 1 Then
L5s = 0
End If

Sprung5:


If Taste_lang => 3 And Taste_lang <= 5 Then 'wenn lange gedrückt wird (<=5 damit nicht über Timer gesprungen wird)
Print "Taste_lang: " ; Taste_lang
Taste_lang = 100 'Variable setzen damit Routine kein zweites mal erfüllt wird
If L5 = 1 And L6 = 0 Then
L5s = 1 'immer beide setzen, falls davor anders gesetzt wurde(einzellampe)
L6s = 1
Goto Sprung6 'wenn Bedingung richtig, dann Restüberspringen bzw. bei lange drücken weitermachen
End If
If L5 = 1 And L6 = 1 Then
L5s = 0
L6s = 0
Goto Sprung6 'wenn Bedingung richtig, dann Restüberspringen bzw. bei lange drücken weitermachen
End If
If L5 = 0 And L6 = 0 Then
L5s = 1
L6s = 1
End If
End If

Sprung6:

End If 'ENDE von "wenn Taste 1 gedrückt wurde"
Goto Lampenende


Lampe7:
'=============

If T4 > 0 And Taste_lang < 6 Then 'wenn Taste 1 gedrückt wurde UND Taste_lang nicht überlaufen ist!

L7s = L7 'Iststatus von Lampen übernehmen
L8s = L8 'Iststatus von Lampen übernehmen

If L7s = 0 And L8s = 0 Then
L7s = 1
Goto Sprung7 'wenn Bedingung richtig, dann Restüberspringen bzw. bei lange drücken weitermachen
End If
If L7s = 1 And L8s = 0 Then
L7s = 0
Goto Sprung7
End If
If L7s = 1 And L8s = 1 Then
L8s = 0
End If

Sprung7:


If Taste_lang => 3 And Taste_lang <= 5 Then 'wenn lange gedrückt wird (<=5 damit nicht über Timer gesprungen wird)
Print "Taste_lang: " ; Taste_lang
Taste_lang = 100 'Variable setzen damit Routine kein zweites mal erfüllt wird
If L7 = 1 And L8 = 0 Then
L7s = 1 'immer beide setzen, falls davor anders gesetzt wurde(einzellampe)
L8s = 1
Goto Sprung8 'wenn Bedingung richtig, dann Restüberspringen bzw. bei lange drücken weitermachen
End If
If L7 = 1 And L2 = 1 Then
L7s = 0
L8s = 0
Goto Sprung8 'wenn Bedingung richtig, dann Restüberspringen bzw. bei lange drücken weitermachen
End If
If L7 = 0 And L8 = 0 Then
L7s = 1
L8s = 1
End If
End If

Sprung8:

End If 'ENDE von "wenn Taste 1 gedrückt wurde"
Goto Lampenende


Lampe9:
'=============

If T5 > 0 And Taste_lang < 6 Then 'wenn Taste 1 gedrückt wurde UND Taste_lang nicht überlaufen ist!

L9s = L9 'Iststatus von Lampen übernehmen
L10s = L10 'Iststatus von Lampen übernehmen

If L9s = 0 And L10s = 0 Then
L9s = 1
Goto Sprung9 'wenn Bedingung richtig, dann Restüberspringen bzw. bei lange drücken weitermachen
End If
If L9s = 1 And L10s = 0 Then
L9s = 0
Goto Sprung9
End If
If L9s = 1 And L10s = 1 Then
L10s = 0
End If

Sprung9:


If Taste_lang => 3 And Taste_lang <= 5 Then 'wenn lange gedrückt wird (<=5 damit nicht über Timer gesprungen wird)
Print "Taste_lang: " ; Taste_lang
Taste_lang = 100 'Variable setzen damit Routine kein zweites mal erfüllt wird
If L9 = 1 And L10 = 0 Then
L9s = 1 'immer beide setzen, falls davor anders gesetzt wurde(einzellampe)
L10s = 1
Goto Sprung10 'wenn Bedingung richtig, dann Restüberspringen bzw. bei lange drücken weitermachen
End If
If L9 = 1 And L10 = 1 Then
L9s = 0
L10s = 0
Goto Sprung10 'wenn Bedingung richtig, dann Restüberspringen bzw. bei lange drücken weitermachen
End If
If L9 = 0 And L10 = 0 Then
L9s = 1
L10s = 1
End If
End If

Sprung10:

End If 'ENDE von "wenn Taste 1 gedrückt wurde"
Goto Lampenende


Lampe11:
'=============

If T6 > 0 And Taste_lang < 6 Then 'wenn Taste 1 gedrückt wurde UND Taste_lang nicht überlaufen ist!

L11s = L11 'Iststatus von Lampen übernehmen
L12s = L12 'Iststatus von Lampen übernehmen

If L11s = 0 And L12s = 0 Then
L11s = 1
Goto Sprung11 'wenn Bedingung richtig, dann Restüberspringen bzw. bei lange drücken weitermachen
End If
If L11s = 1 And L12s = 0 Then
L11s = 0
Goto Sprung11
End If
If L11s = 1 And L12s = 1 Then
L12s = 0
End If

Sprung11:


If Taste_lang => 3 And Taste_lang <= 5 Then 'wenn lange gedrückt wird (<=5 damit nicht über Timer gesprungen wird)
Print "Taste_lang: " ; Taste_lang
Taste_lang = 100 'Variable setzen damit Routine kein zweites mal erfüllt wird
If L11 = 1 And L12 = 0 Then
L11s = 1 'immer beide setzen, falls davor anders gesetzt wurde(einzellampe)
L12s = 1
Goto Sprung12 'wenn Bedingung richtig, dann Restüberspringen bzw. bei lange drücken weitermachen
End If
If L11 = 1 And L12 = 1 Then
L11s = 0
L12s = 0
Goto Sprung12 'wenn Bedingung richtig, dann Restüberspringen bzw. bei lange drücken weitermachen
End If
If L11 = 0 And L12 = 0 Then
L11s = 1
L12s = 1
End If
End If

Sprung12:

End If 'ENDE von "wenn Taste 1 gedrückt wurde"
Goto Lampenende



Lampenende:


'Print "-----------------------"
'Print "Address: " ; Address
'Print "Command: " ; Command
'Print "-----------------------"





'_________________________________________________ ______________________________
If Sek => 100 And Address = 255 Then
Sek = 0

T1 = 0 'Tastenzähler zurücksetzen
T2 = 0
T3 = 0
T4 = 0
T5 = 0
T6 = 0

L1 = L1s 'Werte auf Ausgänge übertragen
L2 = L2s
L3 = L3s
L4 = L4s
L5 = L5s
L6 = L6s
L7 = L7s
L8 = L8s
L9 = L9s
L10 = L10s
L11 = L11s
L12 = L12s


Print "L1: " ; L1
Print "L2: " ; L2
Print "L3: " ; L3
Print "L4: " ; L4
Print "L5: " ; L5
Print "L6: " ; L6
Print "L7: " ; L7
Print "L8: " ; L8
Print "L9: " ; L9
Print "L10: " ; L10
Print "L11: " ; L11
Print "L12: " ; L12
Print "____________"



End If



Loop
'-------------------------------------------------------------------------------

'-------------------------------------------------------------------------------
'Sprungmarken
'-------------------------------------------------------------------------------
Timer1_irq:
Timer1 = Timervorgabe

Incr Sek



Return

peterfido
04.01.2011, 20:21
Habe nicht getestet. Wäre ein Versuch wert.


'Konfiguration µC:
$regfile = "m8def.dat" 'AT-Mega8
$crystal = 16000000 'Quarz: 16 MHz
$baud = 38400 'Baudrate definieren
$hwstack = 64 ' default use 32 for the hardware stack
$swstack = 64 ' default use 10 for the SW stack
$framesize = 64
'-------------------------------------------------------------------------------
'Ein- Ausgänge:
Ddrb = &B11111111 '1 Ausgang, 0 Eingang => Pin PB7-0 als Ausgang
Ddrc = &B11111111 '1 Ausgang, 0 Eingang => Pin PB7-0 als Ausgang

Portb = 0
Portc = 0

'-------------------------------------------------------------------------------
'Timer0 = 8 Bit
'wird für RC5 Auswertung benötigt!!!
Config Rc5 = Pind.3 'Timer0 in Benutzung!!!
Portd.3 = 1 'Pull Up für Empfänger

'16Bit Timer:
Config Timer1 = Timer , Prescale = 256
On Timer1 Timer1_irq
Const Timervorgabe = 64911 '100 mal pro Sekunde
Enable Timer1
Enable Interrupts


'-------------------------------------------------------------------------------
'Variablen:
'-------------------------------------------------------------------------------
Dim Address As Byte , Command As Byte , Command_old As Bit , Flag As Bit 'RC5

'Taste lange gedrückt
'Dim Taste_lang As Word
'Taste 1-6 auf der FB
Dim T1 As Byte , T2 As Byte , T3 As Byte ' , T4 As Byte , T5 As Byte , T6 As Byte
'Lampe 1-12
'Dim L1s As Bit , L2s As Bit , L3s As Bit , L4s As Bit , L5s As Bit , L6s As Bit , L7s As Bit , L8s As Bit , L9s As Bit , L10s As Bit , L11s As Bit , L12s As Bit ,

Dim Empfang As Bit 'ist 0 wenn kein empfang also 255 von address

Dim Sek As Byte 'wenn = 100 dann 1 sec um
Dim L As Integer

'Lampen festlegen

'-------------------------------------------------------------------------------
'Vor Programmstart:

'alle Lampen aus:

Const An = 1
Const Aus = 0
Const Nichts = 255

T3 = Nichts
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'Hauptprogramm Do...Loop
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
Print "Programm Start 38400 Baud..."
Do


'-------------------------------------------------------------------------------
'Rc5 Code einlesen:
Getrc5(address , Command)
'Print "Address: " ; Address
'Print "Command: " ; Command



'-------------------------------------------------------------------------------
'RC5 Code umsetzen:
If Address = 255 Then 'also kein Signal
Empfang = 0
Sek = 0
T3 = Nichts
End If


If Address = 0 Then 'Adresse 0=TV FB
If Empfang = 0 Then
Empfang = 1
' Timer1 = Timervorgabe 'Timer1 zurücksetzen, damit erst bei Tastendruck gezählt wird
'Print "timerzurück"
End If

' If Command.7 = Command_old Then
' Incr Taste_lang
' Else
' Taste_lang = 0 'Variable zurücksetzen
' Command_old = Command.7
' End If

'Print "Command.7: " ; Command.7
'Print "Taste_lang: " ; Taste_lang

'Command = Command And &B01111111 'reset toggle bit
' Reset Command.7 'reset toggle bit

Select Case Command
Case 0 : Print "CASE = 0"
Case 1 : T1 = 1
T2 = 2
Gosub Lampe1

Case 2 : T1 = 3
T2 = 4
Gosub Lampe1

Case 3 : T1 = 5
T2 = 6
Gosub Lampe1

Case 4 : T1 = 7
T2 = 8
Gosub Lampe1

Case 5 : T1 = 9
T2 = 10
Gosub Lampe1

Case 6 : T1 = 11
T2 = 12
Gosub Lampe1

Case Else : Print "Fehler: " ; Command
End Select
End If
'_________________________________________________ ______________________________

Loop
End



'-------------------------------------------------------------------------------
'Relais ansteuern
'-------------------------------------------------------------------------------




Lampe1:
'=============
If T3 = Nichts Then
If L.t1 = 0 Then
T3 = An
Else
T3 = Aus
End If
End If
If Sek < 200 Then
If T3 = An Then
Set L.t1
Print "L" ; T1 ; ":1"
Else
Reset L.t2
Print "L" ; T2 ; ":0"
End If
Else
If T3 = An Then
Set L.t2
Print "L" ; T2 ; ":1"
Else
Reset L.t1
Print "L" ; T1 ; ":0"
End If
End If
Gosub Setzen

Return

Timer1_irq:
Timer1 = Timervorgabe

If Empfang = 1 Then
If Sek < 255 Then
Incr Sek
End If
End If


Return


Setzen:
Portc.5 = L.1
Portc.4 = L.2
Portc.3 = L.3
Portc.2 = L.4
Portc.1 = L.5
Portc.0 = L.6
Portb.5 = L.7
Portb.4 = L.8
Portb.3 = L.9
Portb.2 = L.10
Portb.1 = L.11
Portb.0 = L.12
Return

TobiasBlome
06.01.2011, 08:16
Hallo,
sorry das ich erst nun antworte.

@peterfido
Das Programm läuft leider nicht.
Dadurch dass mehrere Impulse von der FB gesendet werden reicht die Verriegelung mit der 255 nicht aus und man schafft es fast nie die FB Taste so kurz zu drücken das der Kontakt nicht mehrmals schaltet.
Die andere Sache ist, dass nur ein Leuchtmittel gesteuert werden kann (oder ich hab das Programm noch nicht durchschaut) Jede Lampe hat 2 Leuchtmittel, wodurch 2 Helligkeitsstuffen möglich sind.

ABER ich habe die Programmierweise (über die Variablen L.1 - L.12 die Lampen auswählen und so viele Programmzeilen sparen) übernommen.

Jetzt kommt der Fehler der mir unmöglich erscheint. Alle Funktionen mit Taste 1,3,5 funktionieren - Taste 2,4,6 LANGE drücken auswerten funktioniert nicht?! Dabei werden doch alle Tasten gleich abgefragt...
(zur Funktion: kurz drücken -> erstes Leuchtmittel an bzw. aus. lange drücken beide Leuchtmittel an bzw. aus)


'-------------------------------------------------------------------------------
'Konfiguration µC:
$regfile = "m8def.dat" 'AT-Mega8
$crystal = 16000000 'Quarz: 16 MHz
$baud = 38400 'Baudrate definieren

'-------------------------------------------------------------------------------
'Ein- Ausgänge:
Ddrb = &B11111111 '1 Ausgang, 0 Eingang => Pin PB7-0 als Ausgang
Ddrc = &B11111111 '1 Ausgang, 0 Eingang => Pin PB7-0 als Ausgang

Portb = 0
Portc = 0

'-------------------------------------------------------------------------------
'Timer0 = 8 Bit
'wird für RC5 Auswertung benötigt!!!
Config Rc5 = Pind.3 'Timer0 in Benutzung!!!
Portd.3 = 1 '??????????????????????????????????

'16Bit Timer:
Config Timer1 = Timer , Prescale = 256
On Timer1 Timer1_irq
Const Timervorgabe = 64911 '100 mal pro Sekunde
Enable Timer1
Enable Interrupts


'-------------------------------------------------------------------------------
'Variablen:
'-------------------------------------------------------------------------------
Dim Address As Byte , Command As Byte , Command_old As Bit , Flag As Bit 'RC5

'Taste lange gedrückt
Dim Taste_lang As Word
Dim Empfang As Bit 'ist 0 wenn kein empfang also 255 von address
Dim Sek As Byte 'wenn = 100 dann 1 sec um
Dim L As Integer , Ls As Integer , Lampe_x As Byte , Lampe_y As Byte

'Lampen festlegen
Lampe1 Alias Portc.5
Lampe2 Alias Portc.4
Lampe3 Alias Portc.3
Lampe4 Alias Portc.2
Lampe5 Alias Portc.1
Lampe6 Alias Portc.0
Lampe7 Alias Portb.5
Lampe8 Alias Portb.4
Lampe9 Alias Portb.3
Lampe10 Alias Portb.2
Lampe11 Alias Portb.1
Lampe12 Alias Portb.0

'-------------------------------------------------------------------------------
'Vor Programmstart:

'alle Lampen aus:
Lampe1 = 0
Lampe2 = 0
Lampe3 = 0
Lampe4 = 0
Lampe5 = 0
Lampe6 = 0
Lampe7 = 0
Lampe8 = 0
Lampe9 = 0
Lampe10 = 0
Lampe11 = 0
Lampe12 = 0

Address = 255 'also kein Signal
Command = 255 'also kein Signal

Lampe_x = 255
Lampe_y = 255

'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'Hauptprogramm Do...Loop
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
Print "Programm Start 38400 Baud..."
Do
Anfang:

'-------------------------------------------------------------------------------
'Rc5 Code einlesen:
Getrc5(address , Command)
'Print "Address: " ; Address
'Print "Command: " ; Command



'-------------------------------------------------------------------------------
'RC5 Code umsetzen:
If Address = 255 Then 'also kein Signal
Empfang = 0
End If


If Address = 0 Then 'Adresse 0=TV FB
If Empfang = 0 Then
Empfang = 1
Timer1 = Timervorgabe 'Timer1 zurücksetzen, damit erst bei Tastendruck gezählt wird
'Print "timerzurück"
End If

If Command.7 = Command_old Then
Incr Taste_lang
Else
Taste_lang = 0 'Variable zurücksetzen
Command_old = Command.7
End If

'Print "Command.7: " ; Command.7
'Print "Taste_lang: " ; Taste_lang

'Command = Command And &B01111111 'reset toggle bit
Reset Command.7 'reset toggle bit

'Print Command

Select Case Command
Case 0 : Goto All_off

Case 1 : Lampe_x = 1
Lampe_y = 2
Goto Lampe
Case 2 : Lampe_x = 3
Lampe_y = 4
Goto Lampe
Case 3 : Lampe_x = 5
Lampe_y = 6
Goto Lampe
Case 4 : Lampe_x = 7
Lampe_y = 8
Goto Lampe
Case 5 : Lampe_x = 9
Lampe_y = 10
Goto Lampe
Case 6 : Lampe_x = 11
Lampe_y = 12
Goto Lampe
Case Else : Print "Fehler: " ; Command
End Select
End If


'-------------------------------------------------------------------------------
'Relais ansteuern
'-------------------------------------------------------------------------------

Lampe:
'=============

If Lampe_x < 255 And Taste_lang < 7 Then 'wenn Taste 1 gedrückt wurde UND Taste_lang nicht überlaufen ist!

Ls.lampe_x = L.lampe_x 'Iststatus von Lampen übernehmen
Ls.lampe_y = L.lampe_y 'Iststatus von Lampen übernehmen

If Ls.lampe_x = 0 And Ls.lampe_y = 0 Then
L.lampe_x = 1
Goto Sprung1 'wenn Bedingung richtig, dann Restüberspringen bzw. bei lange drücken weitermachen
End If
If Ls.lampe_x = 1 And Ls.lampe_y = 0 Then
L.lampe_x = 0
Goto Sprung1
End If
If Ls.lampe_x = 1 And Ls.lampe_y = 1 Then
L.lampe_y = 0
End If

Sprung1:

If Taste_lang => 3 And Taste_lang < 7 Then 'wenn lange gedrückt wird (<=5 damit nicht über Timer gesprungen wird)

Print "Taste_lang: " ; Taste_lang
Taste_lang = 100 'Variable setzen damit Routine kein zweites mal erfüllt wird

If Ls.lampe_x = 1 And Ls.lampe_y = 0 Then
L.lampe_x = 1 'immer beide setzen, falls davor anders gesetzt wurde(einzellampe)
L.lampe_y = 1
Goto Sprung2 'wenn Bedingung richtig, dann Restüberspringen bzw. bei lange drücken weitermachen
End If

If Ls.lampe_x = 1 And Ls.lampe_y = 1 Then
L.lampe_x = 0
L.lampe_y = 0
Goto Sprung2 'wenn Bedingung richtig, dann Restüberspringen bzw. bei lange drücken weitermachen
End If

If Ls.lampe_x = 0 And Ls.lampe_y = 0 Then
L.lampe_x = 1
L.lampe_y = 1
End If

End If

Sprung2:
Gosub Lampen_setzen
End If 'ENDE von "wenn Taste 1 gedrückt wurde"





'_________________________________________________ ______________________________
'If Sek = 50 Then
'Goto Ausgabe



'Ausgabe:
'End If


'_________________________________________________ ______________________________
If Sek => 100 And Address = 255 Then
Sek = 0

Print "L1: " ; Lampe1
Print "L2: " ; Lampe2
Print "L3: " ; Lampe3
Print "L4: " ; Lampe4
Print "L5: " ; Lampe5
Print "L6: " ; Lampe6
Print "L7: " ; Lampe7
Print "L8: " ; Lampe8
Print "L9: " ; Lampe9
Print "L10: " ; Lampe10
Print "L11: " ; Lampe11
Print "L12: " ; Lampe12
Print "____________"

End If



Loop
'-------------------------------------------------------------------------------

'-------------------------------------------------------------------------------
'Sprungmarken
'-------------------------------------------------------------------------------
Timer1_irq:
Timer1 = Timervorgabe

Incr Sek

Return

'-------------------------------------------------------------------------------
Lampen_setzen:
Lampe1 = L.1 'Werte auf Ausgänge übertragen
Lampe2 = L.2
Lampe3 = L.3
Lampe4 = L.4
Lampe5 = L.5
Lampe6 = L.6
Lampe7 = L.7
Lampe8 = L.8
Lampe9 = L.9
Lampe10 = L.10
Lampe11 = L.11
Lampe12 = L.12
Lampe_x = 255
Lampe_y = 255

Return

'-------------------------------------------------------------------------------
All_off: 'Alle Lampen ausschalten

Lampe1 = 0 'Werte auf Ausgänge übertragen
Lampe2 = 0
Lampe3 = 0
Lampe4 = 0
Lampe5 = 0
Lampe6 = 0
Lampe7 = 0
Lampe8 = 0
Lampe9 = 0
Lampe10 = 0
Lampe11 = 0
Lampe12 = 0

'rücksetzen der Variablen
L.1 = 0
L.2 = 0
L.3 = 0
L.4 = 0
L.5 = 0
L.6 = 0
L.7 = 0
L.8 = 0
L.9 = 0
L.10 = 0
L.11 = 0
L.12 = 0


Goto Anfang

peterfido
06.01.2011, 15:27
War ein Versuch wert. Evtl. Sek nur jedes 10. Mal hochzählen...

Leider habe ich passende Hardware nicht hier und kann so nicht testen. Diese Gotos aus Subs heraus würde ich durch Gosubs mit Return ersetzen.

TobiasBlome
06.01.2011, 18:31
naja, goto hat natürlich den Vorteil, dass der µC den Rest dann nicht mehr bearbeiten muss - so spare ich (jenachdem welche Taste gedrückt wurde und welche Lampen an sind) einige If...then-Schleifen.
Macht es Sinn statt 16MHz mal 20Mhz zu testen?

peterfido
06.01.2011, 19:00
Innerhalb der Subs nutze ich auch gelegentlich Goto. Aber aus der Hauptschleife heraus ein Sub mit Goto anzuspringen und am Ende wieder mit Goto zurück in die Hauptschleife habe ich bisher noch nicht gemacht.

Mein IR-Fernbedienungsprojekt läuft super schnell mit 8 MHZ und steuert dabei noch ein Display an. Allerdings nutze ich da nicht die GetRc5 sondern eine eigene InterruptRoutine. 20 MHZ testen kann aber trotzdem nicht schaden, wobei ich den Fehler woanders vermute.

Vielleicht krame ich am Wochenende mal mein Bastelzeugs vor und schaue mal, woran es liegt. Auch der Fehler in meinem schnell hingeschriebenen Code interessiert mich...

TobiasBlome
06.01.2011, 19:24
@peterfido
toll, danke!
"eigendlich" funktioniert es ja - nur die Funktion, wenn man die Taste lange drückt...
ich suche den Fehler weiter...

peterfido
08.01.2011, 14:36
Ich habe mal die RC5 Routine aus dem http://www.Bascom-Forum.de verwendet. Die GetRC5 war bei mir etwas hakelig.

Der Takt steht auf 8MHZ intern.



'Konfiguration µC:
$regfile = "m8def.dat" 'AT-Mega8
$crystal = 8000000 'Quarz: 16 MHz
$baud = 38400 'Baudrate definieren
$hwstack = 64 ' default use 32 for the hardware stack
$swstack = 64 ' default use 10 for the SW stack
$framesize = 64
'-------------------------------------------------------------------------------
'Ein- Ausgänge:
Ddrb = &B11111111 '1 Ausgang, 0 Eingang => Pin PB7-0 als Ausgang
Ddrc = &B11111111 '1 Ausgang, 0 Eingang => Pin PB7-0 als Ausgang

Portb = 0
Portc = 0

'-------------------------------------------------------------------------------
'Timer0 = 8 Bit
'wird für RC5 Auswertung benötigt!!!
'Config Rc5 = Pind.3 'Timer0 in Benutzung!!!

Input_pin Alias Pind.3

'Set Portd.3 'Pull Up für Empfänger

'16Bit Timer:
Config Timer1 = Timer , Prescale = 256
On Timer1 Timer1_irq
'Const Timervorgabe = 64911 '100 mal pro Sekunde


'-------------------------------------------------------------------------------
'Variablen:
'-------------------------------------------------------------------------------
'Dim Address As Byte , Command As Byte , Command_old As Bit , Flag As Bit , Addressalt As Byte , Commandalt As Byte , Tmr_exp As Byte 'RC5
Dim Address_rc5 As Byte , Command_rc5 As Byte , Rc5_flag As Bit , Command_old As Bit
'Taste lange gedrückt
'Dim Taste_lang As Word
'Taste 1-6 auf der FB
Dim T1 As Byte , T2 As Byte , T3 As Byte

Dim Empfang As Bit 'ist 0 wenn kein empfang also 255 von address

Dim Sek As Byte 'wenn = 100 dann 1 sec um
Dim L As Integer

'Lampen festlegen

'-------------------------------------------------------------------------------
'Vor Programmstart:

'alle Lampen aus:

Const An = 1
Const Aus = 0
Const Nichts = 255


Config Timer0 = Timer , Prescale = 8
On Timer0 Timer_irq
Const Timervorgabe = 78 'Timeraufruf alle 178µs (10 Samples = 1 Bit = 1,778ms)
Enable Timer0 'Hier werden die Timer aktiviert
Enable Interrupts

'Timing für 10 Samples Per Bit = 1,778ms
Const Samples_early = 8 'Flanke Frühestens Nach 8 Samples
Const Samples_late = 12 'Flanke Spätestens Nach 12 Samples
Const Samples_min = 3 'Flanke Vor 3 Samples - > Paket Verwerfen

'Variablen der ISR
Dim Sample As Byte 'eigentlich Bit, spart aber 46Byte ROM
Dim Ir_lastsample As Byte 'zuletzt gelesenes Sample
Dim Ir_bittimer As Byte 'zählt die Aufrufe von Timer_IRQ
Dim Ir_data_tmp As Word 'Bitstream
Dim Ir_bitcount As Byte 'Anzahl gelesener Bits





T3 = Nichts
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'Hauptprogramm Do...Loop
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
Print "Programm Start 38400 Baud..."
Do


If Rc5_flag = 1 Then
Reset Rc5_flag

If Address_rc5 = 0 Then 'Adresse 0=TV FB
Incr Sek
If Command_rc5.7 <> Command_old Then
Sek = 0
T3 = Nichts
Command_old = Command_rc5.7
End If

Reset Command_rc5.7 'reset toggle bit

Select Case Command_rc5
Case 0 : Print "CASE = 0"
Case 1 : T1 = 1
T2 = 2
Gosub Lampe1

Case 2 : T1 = 3
T2 = 4
Gosub Lampe1

Case 3 : T1 = 5
T2 = 6
Gosub Lampe1

Case 4 : T1 = 7
T2 = 8
Gosub Lampe1

Case 5 : T1 = 9
T2 = 10
Gosub Lampe1

Case 6 : T1 = 11
T2 = 12
Gosub Lampe1

Case Else : Print "Fehler: " ; Command_rc5
End Select
End If
End If
'_________________________________________________ ______________________________

Loop
End



'-------------------------------------------------------------------------------
'Relais ansteuern
'-------------------------------------------------------------------------------




Lampe1:
'=============
If T3 = Nichts Then
If L.t1 = 0 Then
T3 = An
Else
T3 = Aus
End If
End If

If Sek < 5 Then
If T3 = An Then
Set L.t1
Print "L" ; T1 ; ":1"
Else
If L.t2 = 1 Then
Reset L.t2
Print "L" ; T2 ; ":0"
Else
Reset L.t1
Print "L" ; T1 ; ":0"
End If
End If
Else
If T3 = An Then
Set L.t2
Print "L" ; T2 ; ":1"
Else
Reset L.t1
Print "L" ; T1 ; ":0"
End If
End If
Gosub Setzen

Return


Setzen:
Portc.5 = L.1
Portc.4 = L.2
Portc.3 = L.3
Portc.2 = L.4
Portc.1 = L.5
Portc.0 = L.6
Portb.5 = L.7
Portb.4 = L.8
Portb.3 = L.9
Portb.2 = L.10
Portb.1 = L.11
Portb.0 = L.12
Return


'************************************************* ************************************
'Quelle: Bascom-Forum

Timer_irq:
Timer0 = Timervorgabe
Sample = Not Input_pin

'bittimer erhöhen (bleibt bei 255 stehen)
If Ir_bittimer < 255 Then Incr Ir_bittimer

'flankenwechsel erkennen
If Ir_lastsample <> Sample Then

If Ir_bittimer <= Samples_min Then
'flanke kommt zu früh: paket verwerfen
Ir_bitcount = 0
Else
'nur Flankenwechsel in Bit-Mitte berücksichtigen
If Ir_bittimer >= Samples_early Then
If Ir_bittimer <= Samples_late Then
'Bit speichern
Shift Ir_data_tmp , Left , 1
Ir_data_tmp = Ir_data_tmp + Sample
Incr Ir_bitcount
Else
'Flankenwechsel zu spät: Neuanfang mit gemessener Flanke
Ir_bitcount = 1
Ir_data_tmp = Sample
End If
'bittimer zurücksetzen wenn Timer > Samples_early
Ir_bittimer = 0
End If
End If

'Kontrolle des Startbits auf 1
If Ir_bitcount = 1 Then Ir_bitcount = Ir_data_tmp.0

'Alle 14 Bits gelesen?
If Ir_bitcount >= 14 Then
Command_rc5 = Ir_data_tmp 'Bit 6 und 7 siehe unten
Shift Ir_data_tmp , Right , 6
Address_rc5 = Ir_data_tmp And &B00011111
'For extended RC5 code, the extended bit is bit 6 of the command.
Command_rc5.6 = Not Ir_data_tmp.6
'The toggle bit is stored in bit 7 of the command
Command_rc5.7 = Ir_data_tmp.5
'Paket erfolgreich gelesen
Set Rc5_flag
'paket zurücksetzen
Ir_bitcount = 0
End If

End If
'sample im samplepuffer ablegen
Ir_lastsample = Sample

Return
'************************************************* *************************************

Timer1_irq:
If Sek < 255 Then
Incr Sek
End If

Return

TobiasBlome
09.01.2011, 16:51
Es funktioniert nun alles!

@perterfido

Dein Code läuft mit dem IR Code hier aus dem Forum super flüssig! =D> =D> =D> Vielen Dank dafür.
Probleme hatte ich mit dem Auswerten der lang gedrückten Tasten:
1) wenn beide Leuchtmittel an sind und lange gedrückt wird, soll nur eine ausgehen (es gehen beide aus) Problem behoben.
2) wenn eine an ist und lange gedrückt wird, soll die zweite dazu angehen - etwas aufwendiger, da erst der kurze Tastendruck ausgewertet wurde und die Lampe kurzzeitig ganz ausschaltete bis beide Lampen angingen - nun habe ich diesen Effekt mit einem Timer verhindert(diese Zeitverzögerung läßt sich wohl leider nicht vermeiden).
Ausserdem habe ich die Variable "T3" in Status umbenannt und hier den tasächlichen Satus reingeschrieben und nicht den Sollwert.
Nun läuft es so wie ich es mir vorgestellt habe! Danke peterfido!!!



'Konfiguration µC:
$regfile = "m8def.dat" 'AT-Mega8
$crystal = 8000000 'Quarz: 16 MHz
$baud = 38400 'Baudrate definieren
$hwstack = 64 ' default use 32 for the hardware stack
$swstack = 64 ' default use 10 for the SW stack
$framesize = 64
'-------------------------------------------------------------------------------
'Ein- Ausgänge:
Ddrb = &B11111111 '1 Ausgang, 0 Eingang => Pin PB7-0 als Ausgang
Ddrc = &B11111111 '1 Ausgang, 0 Eingang => Pin PB7-0 als Ausgang

Portb = 0
Portc = 0

'-------------------------------------------------------------------------------
'Timer0 = 8 Bit
Config Timer0 = Timer , Prescale = 8
On Timer0 Timer0_irq
Const Timervorgabe_t0 = 78 'Timeraufruf alle 178µs (10 Samples = 1 Bit = 1,778ms)
Enable Timer0 'Hier werden die Timer aktiviert
Enable Interrupts


'16Bit Timer:
Config Timer1 = Timer , Prescale = 64
On Timer1 Timer1_irq
Const Timervorgabe_t1 = 64286 '100 mal pro Sekunde @ 8MHz
Enable Timer1 'Hier werden die Timer aktiviert
Enable Interrupts

'-------------------------------------------------------------------------------
'Variablen:
'-------------------------------------------------------------------------------

Dim Address_rc5 As Byte , Command_rc5 As Byte , Rc5_flag As Bit , Command_old As Bit

'Taste 1-6 auf der FB
Dim T1 As Byte , T2 As Byte

Dim Status As Byte 'zeigt den Status der gewaehlten Lampe an NICHTS / AN / AUS

Dim Empfang As Bit 'ist 0 wenn kein empfang (also 255 von Variable address)

Dim Zaehler As Byte 'wenn = 100 dann 1 sec um
Dim L As Integer

Dim Setzen_merker As Bit '1 = setzenroutine freigegeben
Dim Z_timer1 As Byte '100 = 1 sec

Input_pin Alias Pind.3

'Set Portd.3 'Pull Up für Empfänger

Const An = 1
Const Aus = 0
Const Nichts = 255


'Timing für 10 Samples Per Bit = 1,778ms
Const Samples_early = 8 'Flanke Frühestens Nach 8 Samples
Const Samples_late = 12 'Flanke Spätestens Nach 12 Samples
Const Samples_min = 3 'Flanke Vor 3 Samples - > Paket Verwerfen

'Variablen der IR-ISR
Dim Sample As Byte 'eigentlich Bit, spart aber 46Byte ROM
Dim Ir_lastsample As Byte 'zuletzt gelesenes Sample
Dim Ir_bittimer As Byte 'zählt die Aufrufe von Timer_IRQ
Dim Ir_data_tmp As Word 'Bitstream
Dim Ir_bitcount As Byte 'Anzahl gelesener Bits



'-------------------------------------------------------------------------------
'Vor Programmstart:

Zaehler = 0
Status = Nichts
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'Hauptprogramm Do...Loop
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
Print "Programm Start 38400 Baud..."
Do


If Rc5_flag = 1 Then
Reset Rc5_flag

If Address_rc5 = 0 Then 'Adresse 0=TV FB
Incr Zaehler
If Command_rc5.7 <> Command_old Then
Zaehler = 0 'wenn ungleich also neuer Befehl, dann Zaehler zurücksetzen
Status = Nichts
Command_old = Command_rc5.7
End If

Reset Command_rc5.7 'reset toggle bit

'Print Command_rc5

Select Case Command_rc5
Case 0 : Gosub Alles_aus 'Print "CASE = 0"
Case 1 : T1 = 1
T2 = 2
Gosub Lampe1

Case 2 : T1 = 3
T2 = 4
Gosub Lampe1

Case 3 : T1 = 5
T2 = 6
Gosub Lampe1

Case 4 : T1 = 7
T2 = 8
Gosub Lampe1

Case 5 : T1 = 9
T2 = 10
Gosub Lampe1

Case 6 : T1 = 11
T2 = 12
Gosub Lampe1

Case 7 : Gosub Gruppe_7

Case 9 : Gosub Gruppe_9

Case 12 : Gosub Alles_aus

Case Else : Print "Fehler: " ; Command_rc5
End Select
End If
End If
'_________________________________________________ ______________________________
If Z_timer1 > 40 And Setzen_merker = 1 Then 'Schaltvert für Z_Timer1 ist Quarzfrequenz abhängig und soll bei langem Tastendruck verhindern
Setzen_merker = 0 'dass wenn eine Lampe an ist und die zweite hinzukommt, dass die erste kurz aus geht!
Gosub Setzen
End If


Loop
End



'-------------------------------------------------------------------------------
'Relais ansteuern
'-------------------------------------------------------------------------------

'Status = so wie der aktuelle Status IST (nicht wie er sein soll!!!)


Lampe1:
'=============
'aktuellen Status auslesen und setzen
If Status = Nichts Then
If L.t1 = 0 Then
Status = Aus
Else
Status = An
End If
End If




If Zaehler = 0 Then 'WENN KURZ GEDRÜCKT WURDE
'Print Zaehler ; " = Zaehler = 0"
If Status = Aus Then 'wenn lampe eingeschaltet werden soll dann
Set L.t1
'Print "L" ; T1 ; ":1"

Else 'wenn lampe 1 = an

If L.t2 = 1 Then
Reset L.t2
'Print "L" ; T2 ; ":0"
Else
Reset L.t1
'Print "L" ; T1 ; ":0"
End If

End If
End If





'WENN LANGE GEDRÜCKT WURDE
If Zaehler > 2 Then
'Print Zaehler ; " = Zaehler > 2"

If Status = Aus Then
Set L.t2
'Print "Lange" ; T2 ; ":1"
Else
If L.t2 = 0 Then
Set L.t1
Set L.t2
'Print "Lange" ; T1 ; ":1 und " ; T2 ; ":1"
End If
End If
End If

Setzen_merker = 1
'Print "Setzen_merker = " ; Setzen_merker

If Zaehler = 0 Then 'die Variable soll nur bei kurzem Tastendruck eine Zeitverzögerung machen
Z_timer1 = 0 'Timer1 zurücksetzen
End If

'Gosub Setzen
Return


Setzen:
'Print " S E T Z E N "
'Print Zaehler ; " Zaehler"
Portc.5 = L.1
Portc.4 = L.2
Portc.3 = L.3
Portc.2 = L.4
Portc.1 = L.5
Portc.0 = L.6
Portb.5 = L.7
Portb.4 = L.8
Portb.3 = L.9
Portb.2 = L.10
Portb.1 = L.11
Portb.0 = L.12
Return


Timer1_irq:
Timer1 = Timervorgabe_t1
If Z_timer1 < 255 Then
Incr Z_timer1
End If

Return

'************************************************* ************************************
'Quelle: Bascom-Forum

Timer0_irq:
Timer0 = Timervorgabe_t0
Sample = Not Input_pin

'bittimer erhöhen (bleibt bei 255 stehen)
If Ir_bittimer < 255 Then Incr Ir_bittimer

'flankenwechsel erkennen
If Ir_lastsample <> Sample Then

If Ir_bittimer <= Samples_min Then
'flanke kommt zu früh: paket verwerfen
Ir_bitcount = 0
Else
'nur Flankenwechsel in Bit-Mitte berücksichtigen
If Ir_bittimer >= Samples_early Then
If Ir_bittimer <= Samples_late Then
'Bit speichern
Shift Ir_data_tmp , Left , 1
Ir_data_tmp = Ir_data_tmp + Sample
Incr Ir_bitcount
Else
'Flankenwechsel zu spät: Neuanfang mit gemessener Flanke
Ir_bitcount = 1
Ir_data_tmp = Sample
End If
'bittimer zurücksetzen wenn Timer > Samples_early
Ir_bittimer = 0
End If
End If

'Kontrolle des Startbits auf 1
If Ir_bitcount = 1 Then Ir_bitcount = Ir_data_tmp.0

'Alle 14 Bits gelesen?
If Ir_bitcount >= 14 Then
Command_rc5 = Ir_data_tmp 'Bit 6 und 7 siehe unten
Shift Ir_data_tmp , Right , 6
Address_rc5 = Ir_data_tmp And &B00011111
'For extended RC5 code, the extended bit is bit 6 of the command.
Command_rc5.6 = Not Ir_data_tmp.6
'The toggle bit is stored in bit 7 of the command
Command_rc5.7 = Ir_data_tmp.5
'Paket erfolgreich gelesen
Set Rc5_flag
'paket zurücksetzen
Ir_bitcount = 0
End If

End If
'sample im samplepuffer ablegen
Ir_lastsample = Sample

Return
'************************************************* *************************************

'GRUPPEN PROGRAMME:
'____________________________
Gruppe_7:
If Zaehler < 2 Then
L.1 = 1
L.2 = 0
L.3 = 1
L.4 = 0
L.5 = 1
L.6 = 0

Else
L.1 = 1
L.2 = 1
L.3 = 1
L.4 = 1
L.5 = 1
L.6 = 1
End If
Gosub Setzen
Return

'____________________________
Gruppe_9:
If Zaehler = 0 Then

L.9 = 1
L.10 = 0
L.11 = 1
L.12 = 0
Else
L.9 = 1
L.10 = 1
L.11 = 1
L.12 = 1
End If
Gosub Setzen
Return

'____________________________
Alles_aus:
L.1 = 0
L.2 = 0
L.3 = 0
L.4 = 0
L.5 = 0
L.6 = 0
L.7 = 0
L.8 = 0
L.9 = 0
L.10 = 0
L.11 = 0
L.12 = 0
Gosub Setzen
Return

peterfido
09.01.2011, 18:30
Freut mich, dass es dir gefällt. Fairerweise möchte ich erwähnen, dass der IR- Code aus dem http://www.bascom-forum.de/ kommt.