- 3D-Druck Einstieg und Tipps         
Seite 2 von 2 ErsteErste 12
Ergebnis 11 bis 14 von 14

Thema: RC5 kurzen und langen Tastendruck unterscheiden

  1. #11
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    06.07.2006
    Alter
    94
    Beiträge
    627
    Anzeige

    Praxistest und DIY Projekte
    @peterfido
    toll, danke!
    "eigendlich" funktioniert es ja - nur die Funktion, wenn man die Taste lange drückt...
    ich Suche den Fehler weiter...

  2. #12
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    52
    Beiträge
    765
    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.

    Code:
    '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
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  3. #13
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    06.07.2006
    Alter
    94
    Beiträge
    627

    Es funktionert!!!! Juhuuu

    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!!!

    Code:
    '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

  4. #14
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    52
    Beiträge
    765
    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.
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

Seite 2 von 2 ErsteErste 12

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad