IR-Kommunikation mit RC5
Verfasst: So 10. Feb 2013, 16:57
In dem Beitrag Funken mit dem Attiny (https://www.forum.g-heinrichs.de/viewto ... ?f=12&t=54) habe ich schon beschrieben, wie zwei Attiny-Platinen drahtlos miteinander kommunizieren können. Preiswerter und einfacher gestaltet sich die drahtlose Kommunikation allerdings mithilfe von Infrarotlicht. Bereits für wenige Euro erhält man nämlich eine IR-Leuchtdiode nebst Vorwiderstand sowie einen IR-Empfänger (z. B. SFH5110). Und die Programmierung ist recht einfach, wenn man auf die RC5-Befehle von BASCOM zurückgreift.
An einem Beispiel soll dies kurz erläutert werden: Ein Text (mit maximal 20 Zeichen) soll über ein Terminalprogramm an eine erste Attiny-Platine übergeben werden. Von dort soll er über IR-Licht an eine zweite Platine gesendet werden; und diese soll den Text auf einem LCD anzeigen.
Dazu wird eine IR-LED wie in der Abb. 1 mit PortB.3 und über einen Widerstand mit + 5 V verbunden. Wenn nicht allzu große Entfernungen überbrückt werden sollen, ist ein Transistor, wie er in der BASCOM-Hilfe zu finden ist, nicht erforderlich.
Auf der Empfänger-Platine wird der SFH5110-Baustein mit Masse und + 5 V verbunden; den Datenausgang verbinden wir mit PortD.5.
Zum Senden des Textes benutzen wir das unten angegebene Sende-Programm; es zerlegt die vom Terminal erhalte Zeichenkette in seine einzelnen Zeichen und sendet deren ASCII-Code Byte für Byte über RC5 an die zweite Platine. Dabei muss beachtet werden, dass das RC5-Protokoll für den Gebrauch von Fernbedienungen konzipiert ist und jeweils einen Satz von 14 Bits sendent: Neben den zwei Startbits und dem Toggle-Bit sind das 5 Bits für die Geräte-Adresse und 6 Bits für das Geräte-Kommando. Dies spiegelt sich auch in der Syntax des BASCOM-Befehls rc5send wieder:
rc5send ToggleBit, Adresse, Kommando
Dabei sind die Parameter jeweils vom Type Byte; dies bedeutet jedoch nicht, dass über diese Parameter jeweils ein vollständiges Byte übertragen werden kann.
Deswegen zerlegen wir das zu übertragende Byte in zwei Nibbles (Halbbytes): Das Low-Nibble übertragen wir mithilfe des Kommando-Parameters, das High-Nibble mithilfe des Adresse-Parameters; das Toggle-Bit setzen wir auf 0. Die Daten werden dann vom Mikrocontroller hochfrequenzmoduliert an die Empfänger-Platine gesendet. Der Empfangsbaustein demoduliert die Signale; sie werden dann von dem BASCOM-Befehl
getrc5(Adresse, Kommando)
wieder den Variablen Adresse und Kommando zugeordnet. Darin befinden sich unsere beiden Nibbles; wir müssen sie nur noch zusammensetzen und erhalten damit den ASCII-Code des gesendeten Zeichens. Die so empfangenen Zeichen müssen dann nur noch zu einer Zeichenkette zusammengefügt werden.
Um das Prinzip der Übertragung deutlich zu machen, wurden die Programme bewusst einfach gehalten. Außerdem wird nach dem Senden eines Bytes eine recht lange Pause gemacht; diese kann bei Bedarf wesentlich verkürzt werden. Allerdings ist darauf zu achten, dass das nächste Zeichen erst gesendet werden darf, wenn der Empfänger das vorangegangene Zeichen schon verarbeitet hat.
.
An einem Beispiel soll dies kurz erläutert werden: Ein Text (mit maximal 20 Zeichen) soll über ein Terminalprogramm an eine erste Attiny-Platine übergeben werden. Von dort soll er über IR-Licht an eine zweite Platine gesendet werden; und diese soll den Text auf einem LCD anzeigen.
Dazu wird eine IR-LED wie in der Abb. 1 mit PortB.3 und über einen Widerstand mit + 5 V verbunden. Wenn nicht allzu große Entfernungen überbrückt werden sollen, ist ein Transistor, wie er in der BASCOM-Hilfe zu finden ist, nicht erforderlich.
Auf der Empfänger-Platine wird der SFH5110-Baustein mit Masse und + 5 V verbunden; den Datenausgang verbinden wir mit PortD.5.
Zum Senden des Textes benutzen wir das unten angegebene Sende-Programm; es zerlegt die vom Terminal erhalte Zeichenkette in seine einzelnen Zeichen und sendet deren ASCII-Code Byte für Byte über RC5 an die zweite Platine. Dabei muss beachtet werden, dass das RC5-Protokoll für den Gebrauch von Fernbedienungen konzipiert ist und jeweils einen Satz von 14 Bits sendent: Neben den zwei Startbits und dem Toggle-Bit sind das 5 Bits für die Geräte-Adresse und 6 Bits für das Geräte-Kommando. Dies spiegelt sich auch in der Syntax des BASCOM-Befehls rc5send wieder:
rc5send ToggleBit, Adresse, Kommando
Dabei sind die Parameter jeweils vom Type Byte; dies bedeutet jedoch nicht, dass über diese Parameter jeweils ein vollständiges Byte übertragen werden kann.
Deswegen zerlegen wir das zu übertragende Byte in zwei Nibbles (Halbbytes): Das Low-Nibble übertragen wir mithilfe des Kommando-Parameters, das High-Nibble mithilfe des Adresse-Parameters; das Toggle-Bit setzen wir auf 0. Die Daten werden dann vom Mikrocontroller hochfrequenzmoduliert an die Empfänger-Platine gesendet. Der Empfangsbaustein demoduliert die Signale; sie werden dann von dem BASCOM-Befehl
getrc5(Adresse, Kommando)
wieder den Variablen Adresse und Kommando zugeordnet. Darin befinden sich unsere beiden Nibbles; wir müssen sie nur noch zusammensetzen und erhalten damit den ASCII-Code des gesendeten Zeichens. Die so empfangenen Zeichen müssen dann nur noch zu einer Zeichenkette zusammengefügt werden.
Code: Alles auswählen
' Sende-Programm
'
' Datei für Attiny-Platine von E. Eube, G. Heinrichs und U. Ihlefeldt
' + 5V - 80 Ohm - irled - pb.3 = OC1A (rc5send benutzt Timer1-PWM)
' Text (maximal 20 Zeichen) über Terminal eingeben und als rc5-Signale ausgeben.
' RC5send benutzt Timer1, aber keine Interrupts (vgl. BASCOM_Hilfe)
'----------------------------------------------------------------------------
$regfile = "attiny2313.dat" 'Attiny2313
$crystal = 4000000 '4 MHz
$baud = 9600
'**********************************************************
'******************* Deklarationen ************************
Dim Togglebit As Byte , Lownibble As Byte , Highnibble As Byte ,
Dim Z As Byte , Bascii As Byte , Laenge As Byte
Dim Buchstabe As String * 1
Dim Text As String * 20
Declare Sub Sende(b As Byte)
'****************** Initialisierung ***********************
Ddrb = &B11111111 'Port B als Ausgangsport
Ddrd = &B01110000 'D4, D5, D6 als Ausgang; Rest als Eingang
Portd = &B10001111 'Eingänge auf high legen
Togglebit = 0
'**********************************************************
'******************** Hauptprogramm ***********************
Do
Input Text Noecho
Laenge = Len(text)
Call Sende(laenge)
Waitms 100
For Z = 1 To Laenge
Buchstabe = Mid(text , Z , 1) 'z-ter Buchstabe
Bascii = Asc(buchstabe)
Call Sende(bascii)
Waitms 100
Next Z
Loop
'**********************************************************
'******************* Unterprogramme ***********************
Sub Sende(b As Byte)
Lownibble = B And &B00001111
Highnibble = B / 16
Printbin Highnibble
Printbin Lownibble
Rc5send Togglebit , Highnibble , Lownibble
End Sub
Code: Alles auswählen
' Empfangs-Programm
'
' Datei für Attiny-Platine von E. Eube, G. Heinrichs und U. Ihlefeldt
' RC5-Out an Port D.5
' empfängt Texte über RC5 und gibt sie auf LCD aus
'----------------------------------------------------------------------------
$regfile = "attiny2313.dat" 'Attiny2313
$crystal = 4000000 '4 MHz
'**********************************************************
'******************* Deklarationen ************************
Dim Lownibble As Byte , Highnibble As Byte
Dim Z As Byte , Bascii As Byte , Laenge As Byte
Dim Buchstabe As String * 1
Dim Text As String * 20
Dim Adresse As Byte , Kommando As Byte
Dim Ergebnis As Byte
Declare Function Empfange() As Byte
'****************** Initialisierung ***********************
Ddrb = &B11111111 'Port B als Ausgangsport
Ddrd = &B01000000 'D4, D6 als Ausgang; Rest als Eingang
Portd = &B10001111 'Eingänge auf high legen
Config Lcd = 16 * 2 'LCD konfigurieren
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.4 , Rs = Portb.6
Cursor Off
Config Rc5 = Pind.5 'IR-Empfänger-Ausgang an PortD.5
Enable Interrupts
Waitms 50
'**********************************************************
'******************** Hauptprogramm ***********************
Cls
Lcd "RC5>"
Wait 1
Do
Text = ""
Laenge = Empfange()
Cls
Lcd Laenge
If Laenge > 0 Then
For Z = 1 To Laenge
Bascii = Empfange()
Lcd "."
Buchstabe = Chr(bascii)
Text = Text + Buchstabe
Next Z
Cls
Lcd Text
Else
Lcd "Leere ZK"
End If
Wait 3
Loop
'**********************************************************
'******************* Unterprogramme ***********************
Function Empfange() As Byte
Do
Getrc5(adresse , Kommando)
Loop Until Adresse < 255 'Adresse = 255 bedeutet: kein Signal
Adresse = Adresse And &B00001111
Highnibble = Adresse * 16
Lownibble = Kommando And &B00001111
Empfange = Highnibble + Lownibble
End Function
.