Archiv verlassen und diese Seite im Standarddesign anzeigen : Funkmodule und Atmels
Knickohr
28.06.2007, 16:00
Hallo zusammen :)
Bin gerade eben frisch hier reingeschneit. Bin aber schon seit geraumer Zeit stiller Mitleser. Seit ein paar Tagen beschäftige ich mich intensiv mit den Funkmodulen und deren Programmierung mit den Atmels.
Jaaa, ich weiß, es ist hier schon jede Menge geschrieben worden. Habe auch die Beiträge fast jeden einzeln durchgeflöht. Komme aber leider auf keinen grünen Zweig.
Ich möchte im Prinzip nur 2 Befehle übertragen, die mir eine Kamera steuern. Also ein Fokus- und ein Auslösesignal. Meine Anforderungen daran sind allerdings recht hoch. Die Verbindung muß sicher sein. Nein jetzt nicht im Sinne von abhörsicher, sondern funktionssicher. Wenn ich am Sender einen Befehl ausgebe, muß ich sicher sein, das er auch am Empfänger ankommt und auch korrekt ankommt. Die Reichweite muß natürlich auch passen. 100m sollten schon drin sein, besser mehr, aber 300 Meter im freien Feld reichen aus. Das Ganze soll natürlich batteriesparend (wenige mA und mit 3V funktionieren) sein und möglichst ohne viel Programmieraufwand zu realisieren sein. Natürlich in BASCOM programmieren, was anderes kann ich nicht ;)
Ach ja, es soll für dieses Selbstbauprojekt sein :
http://www.sternhimmel-ueber-ulm.de/timer00.htm
Wie geschrieben, ich möchte damit die Kamera fernbedienen. Also den Timer im warmen Zimmer oder Auto haben und dann die Kamera über Funk auslösen.
Hat jemand eine Idee, wie man das ohne viel Programmierung und Hardwareaufwand lösen kann ? Vielleicht hat schon jemand so was verwirklicht ?
Thomas
Alex20q90
28.06.2007, 16:15
Hallo Thomas,
es gibt bei Pollin Tranceivermodule für 433MHz. Dort kannste direkt ein Atmel anschließen. Hier im Forum gibts sogar in Bascom Code für die Übertragung.
Den kannste so umschreiben das ein Befehl den Du gesendet hast, bestätigt wird. Somit haste Gewissheit das die Verbindung steht.
Grüße aus Söflingen
Alex
Knickohr
28.06.2007, 16:32
Hallo Alex.
Söflingen, Ulm ? Ist ja gleich um die Ecke ;)
Ja, hab den Beitrag für die RF12-Module von Pollin schon durchgenudelt. Der Code ist aber offensichtlich noch etwas buggy. Jedenfalls bringt er mit beim Compilieren Fehlermeldungen.
Gehts vielleicht auch einfacher ? Ich muß keine kompletten Datenpakete übertragen, sondern im Prinzip nur 2 Befehle (Fokus und Auslösen). Wie geschrieben, es muß auch wirklich sicher funktionieren, also ist eine Rückmeldung vom Empfänger unumgänglich ?
Eine große Frage blieb bei den RF12-Modulen jedoch offen. Die Reichweite und wie muß die Antenne aussehen. Oder hab ichs überlesen ?
Thomas
Eine große Frage blieb bei den RF12-Modulen jedoch offen. Die Reichweite und wie muß die Antenne aussehen. Oder hab ichs überlesen ?
Ich schaffe mit 15cm Draht 100m Freifeld.
Knickohr
28.06.2007, 18:09
Hallo Uwe,
idealerweise müßte die Antenne für Lambda/4 17,3cm lang sein. Problem ist jetzt noch die Anpassung. Aber 100m für ein Stück Draht sind echt gut !
Wenn ich in den 868Mhz-Bereich gehe, wären es nur noch knapp 9cm und der Bereich wäre auch nicht so "zugemüllt" mit allen möglichen Mist. Bei 868MHz darf man in einer Stunde nur 36 Sekunden senden.
Wenn ichs richtig weiß, kann man die RF12-Module auch auf diesem Frequenzband senden lassen.
Thomas
Hallo Uwe,
>idealerweise müßte die Antenne für Lambda/4 17,3cm lang
in unserer Umwelt sollte schon ein Verkürzungsfaktor einwirken.
Also der Stab fällt kürzer aus.
Da Du in der glückliche Lage bist, den Standort des Senders und
Empfängers zu wissen kann mit einer kleinen Richtantenne
die Reichweite erhöht werden.
Und ein Code abzuspecken das er ein Schaltkontakt bestätigt,
sehe ich kein Problem. Selbst bis Du eine funktionstüchtige
Funkstrecke zum Laufen gebracht hast, wird es Master und Slaves
auch in Bascom geben.
Wigbert
Hallo Knickohr,
Hat jemand eine Idee, wie man das ohne viel Programmierung und Hardwareaufwand lösen kann ? Vielleicht hat schon jemand so was verwirklicht ?
Es gibt bzw. gab da einen 433MHz Transceiver im C-Programm (190045), der sich bei mir als sehr funktionssicher erwiesen hat. Bei mir sitzt er in einer Regenwassersteuerung (C-Control I), einer Alarmeinrichtung (C-Control II) und seit Neustem in einer Zentralsteuerung mit AVR M32 unter Bascom.
Alle 3 Plattformen können Daten austauschen und Befehle entgegen nehmen.
Der Hardware-Aufwand ist gering (3 bidirektionale Ports am uC), die Programmierung nicht problematisch (C-Control-Treiber gibt's fertig).
Wäre das was?
Gruß Dirk
P.S. Der Transceiver ist öfter noch bei 3-2-1-Meins zu kriegen.
Knickohr
03.07.2007, 10:09
Hallo Wigbert,
ja stimmt. Deshalb habe ich auch "idealerweise" geschrieben. Wenn man die "Umwelt" mit dazu nimmt, dann wird man so auf 14,5cm kommen. Aber hier ist probieren angesagt.
Hallo Dirk,
ich habe mit die CS-8 Transceiver mal angeschaut. Eigentlich gar nicht schlecht, aber der Preis ! Bei über 80 Teuronen ist mir das zu viel. Die kosten ja mehr, wie meine gesamte Applikation. Außerdem funktionieren die nur mit 5V. Ich brauchs was im Bereich von 2,7 bis 3,6V.
Habe die RFM12-Module mal bestellt, bin gespannt wann sie kommen. Werde wohl doch etwas forschen müssen. In C und ASM gibt es ja schon einige Ansätze. Offensichtlich gibt es aber immer noch Probleme mit der Doku.
Thomas
Knickohr
03.07.2007, 19:39
Hallo zusammen,
beim stöbern im Internet bin ich auf das hier gestosen :
nRF24L01
http://nvlsi.no/index.cfm?obj=product&act=display&pro=89
http://www.sparkfun.com/commerce/product_info.php?products_id=705
Die Dinger sind von Nordic Semiconductor und scheinen genau das Richtige zu sein. Machen eine Verschlüsselung der Daten und prüfen über einen Acknowledge die korrekte Übertragung selbstständig. Sie senden in einem sogenannten Extended Burst Modus, also nur kurzer Zeit. Außerdem kann man mehrere gleichzeitig betreiben. Sie senden im 2,4GHz-Bereich (WLAN) und die Antenne wäre hier auch kein Problem.
Ein Beispielprogramm in BASCOM-AVR gibt es hier :
http://www.mcselec.com/index.php?option=com_content&task=view&id=212&Itemid=57
Hat jemand schon Erfahrung mit den Dingern sammeln können ? Leider sind sie nicht so günstig wie die RFM12-Module, aber wenn da alles implementriert ist, dann wäre das den Preis wert.
Thomas
Knickohr
04.07.2007, 23:10
Hallo,
ich habe soeben mein erstes RFM12-Mudul am laufen. Ja, ist bis jetzt nur der Sender, aber es sieht gut aus. Das Programm läuft sauber durch und eine LED in der Sendeschleife pulst beim Sendebetrieb fein brav vor sich hin.
http://www.sternhimmel-ueber-ulm.de/scratch/RFM12.jpg
Wie kann man eigentlich feststellen, ob der Sender auch was in den Äther schickt ohne gleich sauteure Meßinstrumente anzuschaffen ? Mit dem feuchten Finger wirds wohl nicht gehen ;)
In den nächsten Tage werde ich dann auch mal den Empfänger aufbauen und schauen, ob da auch alles suber ankommt.
Die Dinger sind wirklich winzig klein, fast zu klein !
Thomas
Wenn Du die Frequenz nicht verändert hast sollte im Fernseher
auf Kanal 21-22( Mischfreq.) beim Senden das Rausche aufhören
Wigbert
Knickohr
06.07.2007, 23:12
Guten Abend,
ich habe auch meinen Empfänger am Laufen. Doch leider etwas Ernüchterung. Es wird nichts übertragen, nein falsch, es wird schon was übertragen, ist aber lauter Müll.
Ich bin mir absolut sicher, das der Sender etwas sendet. Das Spiel mit dem Fernseher funktioniert und wenn ich am Empfänger RFM12-Modul an den VD-Ausgang eine LED dran hänge, blinkt die sauber im 1-Sekunden Takt. Der Sender ist so eingestellt, das er alle Sekunde den Text wiederholt.
Nun ja, ich denke, der Empfänger bleibt in der RF12_ready-Schleife hängen und kommt nicht mehr raus. Der Spi-sdo-Ausgang (MISO-Pin) geht auch nie auf 0. Seltsam.
Hier mal der abgeänderte Code.
Vom Sender :
' Atmega8
' VDD -> VCC
' GND -> GND
' SDI -> MOSI (PB3, Pin 17)
' SDO -> MISO (PB4, Pin 18)
' SCK -> SCK (PB5, Pin 19)
' nSel -> SS (PB2, Pin 16)
' Fsk - > R 10k nach VDD
' Atmega16
' VDD -> VCC
' GND -> GND
' SDI -> MOSI (PB5, Pin 6)
' SDO -> MISO (PB6, Pin 7)
' SCK -> SCK (PB7, Pin 8)
' nSel -> SS (PB4, Pin 5)
' Fsk - > R 10k nach VDD
$regfile = "m8def.dat"
$crystal = 1000000 '
$hwstack = 32
$swstack = 32
$framesize = 40
Declare Sub Rf12_init
Declare Function Rf12_trans(byval Wert As Word) As Word
Declare Sub Rf12_setfreq(byval Freq As Single)
Declare Sub Rf12_setbandwith(byval Bandwith As Byte , Byval Gain As Byte , Byval Drssi As Byte)
Declare Sub Rf12_setbaud(byval Rfbaud As Long)
Declare Sub Rf12_setpower(byval Outpower As Byte , Byval Fskmod As Byte)
Declare Sub Rf12_ready
Declare Sub Rf12_readys
Declare Sub Rf12_txdata(byval Maxchar As Byte)
Declare Sub Rf12_rxdata(byval Maxchar As Byte)
Declare Sub Senden
Declare Sub Empfangen
Const Rf12freq = 433.92
Const Rf12baud = 19200
Const Maxchar = 32
Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0
Config Lcd = 16 * 2 , Chipset = Dogm162v3
Cursor Off Noblink
Cls
' config the SPI in master mode.The clock must be a quarter of the slave cpu
' Hier ggf. den SoftSPI reinmachen
Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 128 , Noss = 1
Config Portb.1 = Output ' LED zur Schleifenkontrolle
' werden benötigt für rf12_ready
Spi_cs Alias Portb.2 ' SS-Pin
Config Spi_cs = Output
Spi_sdo Alias Pinb.4 ' MISO-PIN
Set Spi_cs
' init the spi pins
Spiinit
Dim Count As Byte
Dim Temp As Word
Dim Rfdata(32) As Byte
Dim Text As String * Maxchar At Rfdata Overlay
Dim S As String * 10
Locate 1 , 1 : Lcd "Init RFM12 "
Waitms 100
Call Rf12_init ' ein paar Register setzen (z.B. CLK auf 10MHz)
Locate 1 , 1 : Lcd "Set Frequenz "
Waitms 100
Call Rf12_setfreq(rf12freq) ' Sende/Empfangsfrequenz auf 433,92MHz einstellen
Locate 1 , 1 : Lcd "Set Bandwith "
Waitms 100
Call Rf12_setbandwith(4 , 1 , 4) ' 200kHz Bandbreite, -6dB Verstärkung, DRSSI threshold: -79dBm
Locate 1 , 1 : Lcd "Set Baudrate "
Waitms 100
Call Rf12_setbaud(rf12baud) ' 19200 baud
Locate 1 , 1 : Lcd "Set Tx-Power "
Waitms 100
Call Rf12_setpower(0 , 6) ' 1mW Ausgangangsleistung, 120kHz Frequenzshift
Text = "Dies ist ein 433MHz Test !!!!!{013}{010}"
' Je nachdem ob Sender oder Empfänger die entsprechenden Zeilen aktivieren
Do ' Ewigschleife
Pulseout Portb , 1 , 500 ' Schleifenkontrolle
Senden
Locate 1 , 1 : Lcd "Ready "
Wait 1
Loop
End
' ################################################## ######################
' ####### Tranceiverroutinen
' ################################################## ######################
Sub Empfangen
Locate 2 , 1 : Lcd "Empfange "
Waitms 100
Call Rf12_rxdata(maxchar)
Locate 2 , 1
For Count = 1 To Maxchar
Lcd Chr(rfdata(count)) ;
Waitms 100
Next Count
End Sub
Sub Senden
Locate 1 , 1 : Lcd "Sende "
Waitms 100
Call Rf12_txdata(maxchar)
Waitms 10
End Sub
' ################################################## ######################
' ###### Unterroutinen
' ################################################## ######################
Sub Rf12_init:
Waitms 150
Temp = Rf12_trans(&Hc0e0)
Temp = Rf12_trans(&H80d7)
Temp = Rf12_trans(&Hc2ab)
Temp = Rf12_trans(&Hca81)
Temp = Rf12_trans(&He000)
Temp = Rf12_trans(&Hc800)
Temp = Rf12_trans(&Hc4f7)
End Sub
Sub Rf12_setfreq(byval Freq As Single)
Freq = Freq - 430.00
Temp = Freq / 0.0025
If Temp < 96 Then
Temp = 96
Elseif Temp > 3903 Then
Temp = 3903
End If
Temp = Temp + &HA000
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_setbandwith(byval Bandwith As Byte , Byval Gain As Byte , Byval Drssi As Byte)
Drssi = Drssi And 7
Gain = Gain And 3
Temp = Bandwith And 7
Shift Temp , Left , 2
Temp = Temp + Gain
Shift Temp , Left , 3
Temp = Temp + Drssi
Temp = Temp + &H9400
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_setbaud(byval Rfbaud As Long )
Local Ltemp As Long
If Rfbaud < 663 Then Exit Sub
If Rfbaud < 5400 Then
Temp = 43104 / Rfbaud
Temp = Temp + &HC680
Else
Ltemp = 344828 / Rfbaud
Temp = Ltemp
Temp = Temp + &HC600
End If
Decr Temp
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_setpower(byval Outpower As Byte , Byval Fskmod As Byte)
Outpower = Outpower And 7
Temp = Fskmod And 15
Shift Temp , Left , 4
Temp = Temp + Outpower
Temp = Temp + &H9800
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_txdata(byval Maxchar As Byte)
Temp = Rf12_trans(&H8238)
Rf12_ready
Temp = Rf12_trans(&Hb8aa)
Rf12_ready
Temp = Rf12_trans(&Hb8aa)
Rf12_ready
Temp = Rf12_trans(&Hb8aa)
Rf12_ready
Temp = Rf12_trans(&Hb82d)
Rf12_ready
Temp = Rf12_trans(&Hb8d4)
Rf12_ready
For Count = 1 To Maxchar
Rf12_ready
Temp = &HB800 + Rfdata(count)
Temp = Rf12_trans(temp)
Next Count
Rf12_ready
Temp = Rf12_trans(&H8208)
End Sub
Sub Rf12_rxdata(byval Maxchar As Byte)
Temp = Rf12_trans(&H82c8)
Temp = Rf12_trans(&Hca81)
Temp = Rf12_trans(&Hca83)
For Count = 1 To Maxchar
Rf12_ready
Temp = Rf12_trans(&Hb000)
Rfdata(count) = Temp
Next Count
Temp = Rf12_trans(&H8208)
End Sub
Function Rf12_trans(byval Wert As Word) As Word
Local Lowbyte As Byte
Local Highbyte As Byte
Lowbyte = Wert And 255
Shift Wert , Right , 8
Reset Spi_cs
Highbyte = Spimove(wert)
Lowbyte = Spimove(lowbyte)
Set Spi_cs
Temp = Highbyte * 256
Temp = Temp + Lowbyte
Rf12_trans = Temp
End Function
Sub Rf12_ready ' ready Senden
Reset Spi_cs
While Spi_sdo = 0
Wend
End Sub
und vom Empfänger :
' Atmega8
' VDD -> VCC
' GND -> GND
' SDI -> MOSI (PB3, Pin 17)
' SDO -> MISO (PB4, Pin 18)
' SCK -> SCK (PB5, Pin 19)
' nSel -> SS (PB2, Pin 16)
' Fsk - > R 10k
' Atmega16
' VDD -> VCC
' GND -> GND
' SDI -> MOSI (PB5, Pin 6)
' SDO -> MISO (PB6, Pin 7)
' SCK -> SCK (PB7, Pin 8)
' nSel -> SS (PB4, Pin 5)
' Fsk - > R 10k
$regfile = "m16def.dat"
$crystal = 1000000 '
$hwstack = 32
$swstack = 32
$framesize = 40
Declare Sub Rf12_init
Declare Function Rf12_trans(byval Wert As Word) As Word
Declare Sub Rf12_setfreq(byval Freq As Single)
Declare Sub Rf12_setbandwith(byval Bandwith As Byte , Byval Gain As Byte , Byval Drssi As Byte)
Declare Sub Rf12_setbaud(byval Rfbaud As Long)
Declare Sub Rf12_setpower(byval Outpower As Byte , Byval Fskmod As Byte)
Declare Sub Rf12_ready
Declare Sub Rf12_readys
Declare Sub Rf12_txdata(byval Maxchar As Byte)
Declare Sub Rf12_rxdata(byval Maxchar As Byte)
Declare Sub Senden
Declare Sub Empfangen
Const Rf12freq = 433.92
Const Rf12baud = 19200
Const Maxchar = 32
Config Lcdpin = Pin , Db4 = Porta.7 , Db5 = Porta.6 , Db6 = Porta.5 , Db7 = Porta.4 , E = Portc.1 , Rs = Portc.0
Config Lcd = 16 * 2 , Chipset = Dogm162v3
Cursor Off Noblink
Cls
' config the SPI in master mode.The clock must be a quarter of the slave cpu
' Hier ggf. den SoftSPI reinmachen
Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 128 , Noss = 1
Config Portd.7 = Output ' LED zur Schleifenkontrolle
' werden benötigt für rf12_ready
Spi_cs Alias Portb.4 ' SS-Pin
Config Spi_cs = Output
Spi_sdo Alias Pinb.6 ' MISO-PIN
Set Spi_cs
' init the spi pins
Spiinit
Dim Count As Byte
Dim Temp As Word
Dim Rfdata(32) As Byte
Dim Text As String * Maxchar At Rfdata Overlay
Dim S As String * 10
Locate 1 , 1 : Lcd "Init RFM12 "
Waitms 100
Call Rf12_init ' ein paar Register setzen (z.B. CLK auf 10MHz)
Locate 1 , 1 : Lcd "Set Frequenz "
Waitms 100
Call Rf12_setfreq(rf12freq) ' Sende/Empfangsfrequenz auf 433,92MHz einstellen
Locate 1 , 1 : Lcd "Set Bandwith "
Waitms 100
Call Rf12_setbandwith(4 , 1 , 4) ' 200kHz Bandbreite, -6dB Verstärkung, DRSSI threshold: -79dBm
Locate 1 , 1 : Lcd "Set Baudrate "
Waitms 100
Call Rf12_setbaud(rf12baud) ' 19200 baud
Locate 1 , 1 : Lcd "Set Tx-Power "
Waitms 100
Call Rf12_setpower(0 , 6) ' 1mW Ausgangangsleistung, 120kHz Frequenzshift
Text = "Dies ist ein 433MHz Test !!!!!{013}{010}"
' Je nachdem ob Sender oder Empfänger die entsprechenden Zeilen aktivieren
Do ' Ewigschleife
Empfangen
Pulseout Portd , 7 , 500 ' Schleifenkontrolle
Locate 1 , 1 : Lcd "Ready "
Wait 1
Loop
End
' ################################################## ######################
' ####### Tranceiverroutinen
' ################################################## ######################
Sub Empfangen
Locate 1 , 1 : Lcd "Empfange "
Waitms 100
Call Rf12_rxdata(maxchar)
Locate 2 , 1
For Count = 1 To Maxchar
Lcd Chr(rfdata(count)) ;
Waitms 100
Next Count
End Sub
Sub Senden
Locate 1 , 1 : Lcd "Sende "
Waitms 100
Call Rf12_txdata(maxchar)
Waitms 10
End Sub
' ################################################## ######################
' ###### Unterroutinen
' ################################################## ######################
Sub Rf12_init:
Waitms 150
Temp = Rf12_trans(&Hc0e0)
Temp = Rf12_trans(&H80d7)
Temp = Rf12_trans(&Hc2ab)
Temp = Rf12_trans(&Hca81)
Temp = Rf12_trans(&He000)
Temp = Rf12_trans(&Hc800)
Temp = Rf12_trans(&Hc4f7)
End Sub
Sub Rf12_setfreq(byval Freq As Single)
Freq = Freq - 430.00
Temp = Freq / 0.0025
If Temp < 96 Then
Temp = 96
Elseif Temp > 3903 Then
Temp = 3903
End If
Temp = Temp + &HA000
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_setbandwith(byval Bandwith As Byte , Byval Gain As Byte , Byval Drssi As Byte)
Drssi = Drssi And 7
Gain = Gain And 3
Temp = Bandwith And 7
Shift Temp , Left , 2
Temp = Temp + Gain
Shift Temp , Left , 3
Temp = Temp + Drssi
Temp = Temp + &H9400
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_setbaud(byval Rfbaud As Long )
Local Ltemp As Long
If Rfbaud < 663 Then Exit Sub
If Rfbaud < 5400 Then
Temp = 43104 / Rfbaud
Temp = Temp + &HC680
Else
Ltemp = 344828 / Rfbaud
Temp = Ltemp
Temp = Temp + &HC600
End If
Decr Temp
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_setpower(byval Outpower As Byte , Byval Fskmod As Byte)
Outpower = Outpower And 7
Temp = Fskmod And 15
Shift Temp , Left , 4
Temp = Temp + Outpower
Temp = Temp + &H9800
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_txdata(byval Maxchar As Byte)
Temp = Rf12_trans(&H8238)
Rf12_ready
Temp = Rf12_trans(&Hb8aa)
Rf12_ready
Temp = Rf12_trans(&Hb8aa)
Rf12_ready
Temp = Rf12_trans(&Hb8aa)
Rf12_ready
Temp = Rf12_trans(&Hb82d)
Rf12_ready
Temp = Rf12_trans(&Hb8d4)
Rf12_ready
For Count = 1 To Maxchar
Rf12_ready
Temp = &HB800 + Rfdata(count)
Temp = Rf12_trans(temp)
Next Count
Rf12_ready
Temp = Rf12_trans(&H8208)
End Sub
Sub Rf12_rxdata(byval Maxchar As Byte)
Temp = Rf12_trans(&H82c8)
Temp = Rf12_trans(&Hca81)
Temp = Rf12_trans(&Hca83)
For Count = 1 To Maxchar
Rf12_ready
Temp = Rf12_trans(&Hb000)
Rfdata(count) = Temp
Next Count
Temp = Rf12_trans(&H8208)
End Sub
Function Rf12_trans(byval Wert As Word) As Word
Local Lowbyte As Byte
Local Highbyte As Byte
Lowbyte = Wert And 255
Shift Wert , Right , 8
Reset Spi_cs
Highbyte = Spimove(wert)
Lowbyte = Spimove(lowbyte)
Set Spi_cs
Temp = Highbyte * 256
Temp = Temp + Lowbyte
Rf12_trans = Temp
End Function
Sub Rf12_ready
Reset Spi_cs
While Spi_sdo = 0
Wend
End Sub
Wie man unschwer erkennen kann, verwende ich für den Sender ein Atmega8L und für den Empfänger ein Atmega16L mit einem DOG-M Display zur Ausgabe. Ich benutze beides Mal den internen Quarz mit 1,0MHz. Liegts daran ? Senden tu ich eigentlich immer nur den Text ""Dies ist ein 433MHz Test !!!!!{013}{010}" jede Sekunde.
Das kann noch nicht mehr viel sein, jetzt hats bis hierher so gut geklappt :-k
Thomas
Hallo Knickohr,
wenn Du "Müll "überträgst bist Du schon weiter als viele Andere.
1 Mhz und Baudrate hat grosse Fehler.
Stell doch ein Gerät auf senden, und lese mit einen Terminalprogramm
erst mal aus.
Versuch es mal mit intern 8 Mhz mach ich auch immer.
Wigbert
Hallo Knickohr
Beim Empfang Dein Wait 1 aus der Schleife raus.Wie soll er was empfangen wenn er wartet.
konnte die Sub Schleifenkontrolle nicht sehen.
Wigbert
Knickohr
07.07.2007, 13:17
Hallo :) :) :)
Es funktioniert !!! \:D/ \:D/ \:D/
Habe die Dinger zum Laufen gebracht. Ich habe einfach die Baudrate auf 1200 Baud gesetzt und seit dem kommts auch an. Zwar ist immer noch des letzte übertragene Zeichen Müll, aber das ist eine Kleinigkeit. Seltsamerweise setzt die erste Übertragung auch nicht an der ersten Stelle auf, sondern irgendwo mittendrin. Es sind immer ein paar Blanks am Anfang. Naja, halt beim ersten Mal senden.
OK, hab Programm noch ein wenig angepaßt.
Sender:
' Atmega8
' VDD -> VCC
' GND -> GND
' SDI -> MOSI (PB3, Pin 17)
' SDO -> MISO (PB4, Pin 18)
' SCK -> SCK (PB5, Pin 19)
' nSel -> SS (PB2, Pin 16)
' Fsk - > R 10k nach VDD
' Atmega16
' VDD -> VCC
' GND -> GND
' SDI -> MOSI (PB5, Pin 6)
' SDO -> MISO (PB6, Pin 7)
' SCK -> SCK (PB7, Pin 8)
' nSel -> SS (PB4, Pin 5)
' Fsk - > R 10k nach VDD
$regfile = "m8def.dat"
$crystal = 1000000 '
$hwstack = 32
$swstack = 32
$framesize = 40
Declare Sub Rf12_init
Declare Function Rf12_trans(byval Wert As Word) As Word
Declare Sub Rf12_setfreq(byval Freq As Single)
Declare Sub Rf12_setbandwith(byval Bandwith As Byte , Byval Gain As Byte , Byval Drssi As Byte)
Declare Sub Rf12_setbaud(byval Rfbaud As Long)
Declare Sub Rf12_setpower(byval Outpower As Byte , Byval Fskmod As Byte)
Declare Sub Rf12_ready
Declare Sub Rf12_readys
Declare Sub Rf12_txdata(byval Maxchar As Byte)
Declare Sub Rf12_rxdata(byval Maxchar As Byte)
Declare Sub Senden
Declare Sub Empfangen
Const Rf12freq = 433.92
Const Rf12baud = 1200
Const Maxchar = 16
Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0
Config Lcd = 16 * 2 , Chipset = Dogm162v3
Cursor Off Noblink
Cls
' config the SPI in master mode.The clock must be a quarter of the slave cpu
' Hier ggf. den SoftSPI reinmachen
Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 128 , Noss = 1
Config Portb.1 = Output ' LED zur Schleifenkontrolle
' werden benötigt für rf12_ready
Spi_cs Alias Portb.2 ' SS-Pin
Config Spi_cs = Output
Spi_sdo Alias Pinb.4 ' MISO-PIN
Set Spi_cs
' init the spi pins
Spiinit
Dim Count As Byte
Dim Temp As Word
Dim Rfdata(32) As Byte
Dim Text As String * Maxchar At Rfdata Overlay
Dim J As Byte
Locate 1 , 1 : Lcd "Init RFM12 "
Waitms 100
Call Rf12_init ' ein paar Register setzen (z.B. CLK auf 10MHz)
Locate 1 , 1 : Lcd "Set Frequenz "
Waitms 100
Call Rf12_setfreq(rf12freq) ' Sende/Empfangsfrequenz auf 433,92MHz einstellen
Locate 1 , 1 : Lcd "Set Bandwith "
Waitms 100
Call Rf12_setbandwith(4 , 1 , 4) ' 200kHz Bandbreite, -6dB Verstärkung, DRSSI threshold: -79dBm
Locate 1 , 1 : Lcd "Set Baudrate "
Waitms 100
Call Rf12_setbaud(rf12baud) ' 19200 baud
Locate 1 , 1 : Lcd "Set Tx-Power "
Waitms 100
Call Rf12_setpower(0 , 6) ' 1mW Ausgangangsleistung, 120kHz Frequenzshift
'Text = "Dies ist ein 433MHz Test !!!!!{013}{010}"
' Je nachdem ob Sender oder Empfänger die entsprechenden Zeilen aktivieren
Do ' Ewigschleife
Pulseout Portb , 1 , 500 ' Schleifenkontrolle
Text = "433MHz Test #" + Str(j)
Senden
Locate 1 , 1 : Lcd "Ready "
Incr J
Wait 3
Loop
End
' ################################################## ######################
' ####### Tranceiverroutinen
' ################################################## ######################
Sub Empfangen
Locate 2 , 1 : Lcd "Empfange "
Waitms 100
Call Rf12_rxdata(maxchar)
Locate 2 , 1 : Lcd " "
Locate 2 , 1
For Count = 1 To Maxchar
Lcd Chr(rfdata(count)) ;
Waitms 100
Next Count
End Sub
Sub Senden
Locate 1 , 1 : Lcd "Sende "
Waitms 100
Call Rf12_txdata(maxchar)
Waitms 10
End Sub
' ################################################## ######################
' ###### Unterroutinen
' ################################################## ######################
Sub Rf12_init:
Waitms 150
Temp = Rf12_trans(&Hc0e0)
Temp = Rf12_trans(&H80d7)
Temp = Rf12_trans(&Hc2ab)
Temp = Rf12_trans(&Hca81)
Temp = Rf12_trans(&He000)
Temp = Rf12_trans(&Hc800)
Temp = Rf12_trans(&Hc4f7)
End Sub
Sub Rf12_setfreq(byval Freq As Single)
Freq = Freq - 430.00
Temp = Freq / 0.0025
If Temp < 96 Then
Temp = 96
Elseif Temp > 3903 Then
Temp = 3903
End If
Temp = Temp + &HA000
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_setbandwith(byval Bandwith As Byte , Byval Gain As Byte , Byval Drssi As Byte)
Drssi = Drssi And 7
Gain = Gain And 3
Temp = Bandwith And 7
Shift Temp , Left , 2
Temp = Temp + Gain
Shift Temp , Left , 3
Temp = Temp + Drssi
Temp = Temp + &H9400
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_setbaud(byval Rfbaud As Long )
Local Ltemp As Long
If Rfbaud < 663 Then Exit Sub
If Rfbaud < 5400 Then
Temp = 43104 / Rfbaud
Temp = Temp + &HC680
Else
Ltemp = 344828 / Rfbaud
Temp = Ltemp
Temp = Temp + &HC600
End If
Decr Temp
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_setpower(byval Outpower As Byte , Byval Fskmod As Byte)
Outpower = Outpower And 7
Temp = Fskmod And 15
Shift Temp , Left , 4
Temp = Temp + Outpower
Temp = Temp + &H9800
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_txdata(byval Maxchar As Byte)
Temp = Rf12_trans(&H8238)
Rf12_ready
Temp = Rf12_trans(&Hb8aa)
Rf12_ready
Temp = Rf12_trans(&Hb8aa)
Rf12_ready
Temp = Rf12_trans(&Hb8aa)
Rf12_ready
Temp = Rf12_trans(&Hb82d)
Rf12_ready
Temp = Rf12_trans(&Hb8d4)
Rf12_ready
For Count = 1 To Maxchar
Rf12_ready
Temp = &HB800 + Rfdata(count)
Temp = Rf12_trans(temp)
Next Count
Rf12_ready
Temp = Rf12_trans(&H8208)
End Sub
Sub Rf12_rxdata(byval Maxchar As Byte)
Temp = Rf12_trans(&H82c8)
Temp = Rf12_trans(&Hca81)
Temp = Rf12_trans(&Hca83)
For Count = 1 To Maxchar
Rf12_ready
Temp = Rf12_trans(&Hb000)
Rfdata(count) = Temp
Next Count
Temp = Rf12_trans(&H8208)
End Sub
Function Rf12_trans(byval Wert As Word) As Word
Local Lowbyte As Byte
Local Highbyte As Byte
Lowbyte = Wert And 255
Shift Wert , Right , 8
Reset Spi_cs
Highbyte = Spimove(wert)
Lowbyte = Spimove(lowbyte)
Set Spi_cs
Temp = Highbyte * 256
Temp = Temp + Lowbyte
Rf12_trans = Temp
End Function
Sub Rf12_ready
Local I As Word
Reset Spi_cs
For I = 1 To 65000
If Spi_sdo = 1 Then Exit For
Next
End Sub
Empfänger:
' Atmega8
' VDD -> VCC
' GND -> GND
' SDI -> MOSI (PB3, Pin 17)
' SDO -> MISO (PB4, Pin 18)
' SCK -> SCK (PB5, Pin 19)
' nSel -> SS (PB2, Pin 16)
' Fsk - > R 10k
' Atmega16
' VDD -> VCC
' GND -> GND
' SDI -> MOSI (PB5, Pin 6)
' SDO -> MISO (PB6, Pin 7)
' SCK -> SCK (PB7, Pin 8)
' nSel -> SS (PB4, Pin 5)
' Fsk - > R 10k
$regfile = "m16def.dat"
$crystal = 1000000 '
$hwstack = 32
$swstack = 32
$framesize = 40
Declare Sub Rf12_init
Declare Function Rf12_trans(byval Wert As Word) As Word
Declare Sub Rf12_setfreq(byval Freq As Single)
Declare Sub Rf12_setbandwith(byval Bandwith As Byte , Byval Gain As Byte , Byval Drssi As Byte)
Declare Sub Rf12_setbaud(byval Rfbaud As Long)
Declare Sub Rf12_setpower(byval Outpower As Byte , Byval Fskmod As Byte)
Declare Sub Rf12_ready
Declare Sub Rf12_readys
Declare Sub Rf12_txdata(byval Maxchar As Byte)
Declare Sub Rf12_rxdata(byval Maxchar As Byte)
Declare Sub Senden
Declare Sub Empfangen
Const Rf12freq = 433.92
Const Rf12baud = 1200
Const Maxchar = 16
Config Lcdpin = Pin , Db4 = Porta.7 , Db5 = Porta.6 , Db6 = Porta.5 , Db7 = Porta.4 , E = Portc.1 , Rs = Portc.0
Config Lcd = 16 * 2 , Chipset = Dogm162v3
Cursor Off Noblink
Cls
' config the SPI in master mode.The clock must be a quarter of the slave cpu
' Hier ggf. den SoftSPI reinmachen
Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 128 , Noss = 1
Config Portd.7 = Output ' LED zur Schleifenkontrolle
' werden benötigt für rf12_ready
Spi_cs Alias Portb.4 ' SS-Pin
Config Spi_cs = Output
Spi_sdo Alias Pinb.6 ' MISO-PIN
Set Spi_cs
' init the spi pins
Spiinit
Dim Count As Byte
Dim Temp As Word
Dim Rfdata(32) As Byte
Dim Text As String * Maxchar At Rfdata Overlay
'Dim J As Byte
Locate 1 , 1 : Lcd "Init RFM12 "
Waitms 100
Call Rf12_init ' ein paar Register setzen (z.B. CLK auf 10MHz)
Locate 1 , 1 : Lcd "Set Frequenz "
Waitms 100
Call Rf12_setfreq(rf12freq) ' Sende/Empfangsfrequenz auf 433,92MHz einstellen
Locate 1 , 1 : Lcd "Set Bandwith "
Waitms 100
Call Rf12_setbandwith(4 , 1 , 4) ' 200kHz Bandbreite, -6dB Verstärkung, DRSSI threshold: -79dBm
Locate 1 , 1 : Lcd "Set Baudrate "
Waitms 100
Call Rf12_setbaud(rf12baud) ' 19200 baud
Locate 1 , 1 : Lcd "Set Tx-Power "
Waitms 100
Call Rf12_setpower(0 , 6) ' 1mW Ausgangangsleistung, 120kHz Frequenzshift
'Text = "Dies ist ein 433MHz Test !!!!!{013}{010}"
'Text = "433MHz Test #" + J
' Je nachdem ob Sender oder Empfänger die entsprechenden Zeilen aktivieren
Do ' Ewigschleife
Empfangen
Pulseout Portd , 7 , 500 ' Schleifenkontrolle
Locate 1 , 1 : Lcd "Ready "
Wait 1
Loop
End
' ################################################## ######################
' ####### Tranceiverroutinen
' ################################################## ######################
Sub Empfangen
Locate 1 , 1 : Lcd "Empfange "
Waitms 100
Locate 2 , 1 : Lcd " "
Locate 2 , 1
Call Rf12_rxdata(maxchar)
For Count = 1 To Maxchar
Lcd Chr(rfdata(count)) ;
Waitms 100
Next Count
End Sub
Sub Senden
Locate 1 , 1 : Lcd "Sende "
Waitms 100
Call Rf12_txdata(maxchar)
Waitms 10
End Sub
' ################################################## ######################
' ###### Unterroutinen
' ################################################## ######################
Sub Rf12_init:
Waitms 150
Temp = Rf12_trans(&Hc0e0)
Temp = Rf12_trans(&H80d7)
Temp = Rf12_trans(&Hc2ab)
Temp = Rf12_trans(&Hca81)
Temp = Rf12_trans(&He000)
Temp = Rf12_trans(&Hc800)
Temp = Rf12_trans(&Hc4f7)
End Sub
Sub Rf12_setfreq(byval Freq As Single)
Freq = Freq - 430.00
Temp = Freq / 0.0025
If Temp < 96 Then
Temp = 96
Elseif Temp > 3903 Then
Temp = 3903
End If
Temp = Temp + &HA000
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_setbandwith(byval Bandwith As Byte , Byval Gain As Byte , Byval Drssi As Byte)
Drssi = Drssi And 7
Gain = Gain And 3
Temp = Bandwith And 7
Shift Temp , Left , 2
Temp = Temp + Gain
Shift Temp , Left , 3
Temp = Temp + Drssi
Temp = Temp + &H9400
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_setbaud(byval Rfbaud As Long )
Local Ltemp As Long
If Rfbaud < 663 Then Exit Sub
If Rfbaud < 5400 Then
Temp = 43104 / Rfbaud
Temp = Temp + &HC680
Else
Ltemp = 344828 / Rfbaud
Temp = Ltemp
Temp = Temp + &HC600
End If
Decr Temp
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_setpower(byval Outpower As Byte , Byval Fskmod As Byte)
Outpower = Outpower And 7
Temp = Fskmod And 15
Shift Temp , Left , 4
Temp = Temp + Outpower
Temp = Temp + &H9800
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_txdata(byval Maxchar As Byte)
Temp = Rf12_trans(&H8238)
Rf12_ready
Temp = Rf12_trans(&Hb8aa)
Rf12_ready
Temp = Rf12_trans(&Hb8aa)
Rf12_ready
Temp = Rf12_trans(&Hb8aa)
Rf12_ready
Temp = Rf12_trans(&Hb82d)
Rf12_ready
Temp = Rf12_trans(&Hb8d4)
Rf12_ready
For Count = 1 To Maxchar
Rf12_ready
Temp = &HB800 + Rfdata(count)
Temp = Rf12_trans(temp)
Next Count
Rf12_ready
Temp = Rf12_trans(&H8208)
End Sub
Sub Rf12_rxdata(byval Maxchar As Byte)
Temp = Rf12_trans(&H82c8)
Temp = Rf12_trans(&Hca81)
Temp = Rf12_trans(&Hca83)
For Count = 1 To Maxchar
Rf12_ready
Temp = Rf12_trans(&Hb000)
Rfdata(count) = Temp
Next Count
Temp = Rf12_trans(&H8208)
End Sub
Function Rf12_trans(byval Wert As Word) As Word
Local Lowbyte As Byte
Local Highbyte As Byte
Lowbyte = Wert And 255
Shift Wert , Right , 8
Reset Spi_cs
Highbyte = Spimove(wert)
Lowbyte = Spimove(lowbyte)
Set Spi_cs
Temp = Highbyte * 256
Temp = Temp + Lowbyte
Rf12_trans = Temp
End Function
Sub Rf12_ready
Local I As Word
Reset Spi_cs
For I = 1 To 65000
If Spi_sdo = 1 Then Exit For
Next
End Sub
@Wigbert:
Die 1 Sekunde Warten war offensichtlich kein Problem. Ja OK, wenn während der Zeit was gesendet wurde gings natürlich ins Nirwana.
Ist da eigentlich ein Schreibfehler ?
Sub Rf12_setbaud(byval Rfbaud As Long )
Local Ltemp As Long
If Rfbaud < 663 Then Exit Sub
If Rfbaud < 5400 Then
Temp = 43104 / Rfbaud
Temp = Temp + &HC680
Else
Ltemp = 344828 / Rfbaud
Temp = Ltemp
Temp = Temp + &HC600
Decr Temp
Temp = Rf12_trans(temp)
End Sub
Das rot markierte meine ich. Das würde zumindest bei mir den Fehler mit der herunter gesetzten Baudrate erklären.
Thomas
Der Code sieht ok aus.
Die Baudrate sollte er selbsständig berechnen.
Was Oben als constant steht wird im rfm12 eingetragen.
bis 4,8K sollte bei 1MHz möglich sein.
danach ist ein zu hoher Baudratenfehler.
Dein Display ist schnell genug?
Wigbert
Knickohr
07.07.2007, 21:11
Sodale,
jetzt habe ich auch eine 2-Wege-Verbindung zu Stande gebracht. Der Empfänger sendet einfach den empfangenen String wieder zurücck. Funktioniert richtig gut, habe auch mal die Reichweite getestet. Mit den beiden Stückchen 15cm Draht funktioniert es im ganzen 3-Familienhaus selbst bis in den Keller problemlos. Bis in einer Entfernung von 25 Meter um das Haus auch. Wohlgemerkt, der Sender ist immer noch im Haus ! Ab so ca. 30 bis 50 Meter kommen dann die ersten einzelnen Übertragungsfehler. Und ab 50 Meter setzt die Verbindung dann vereinzelt komplett aus. Aber selbst mit über 100 Meter Entfernung konnte ich hin und wieder verkrüppelte Daten empfangen, teilweise sogar vollständig.
Ich denke, man kann die Reichweite durch die Abstimmung der beiden Antennen noch etwas verbessern. Vermutlich bring auch eine kleinere Baudrate eine sauberere Übertragung. Wie weit kann man eigentlich mit der Baudrate runter ? Kann man die Leistung der Sender noch softwaremäßig erhöhen ?
Die Dinger sind richtig gut, wenn sie mal laufen. Jetzt muß ich irgendwie noch eine Fehlerkorrektur einbauen und vielleicht die Übertragung mit einer Identifikation versehen, damit die Übertragung eindeutig wird. Ich denke da an so was wie ID-Byte und Acknowledge.
@Wigbert:
Das DOG-M ist eigentlich recht schnell für ein LCD. Die meiste Zeit geht mir in den waitms verloren. Senden, Empfangen, das empfangene zurücksenden und wieder vom Sender empfangen, und die Anzeige im Display (mit den Statustexten) dauert zusammen weniger als 1 Sekunde.
\:D/ \:D/ \:D/ \:D/ \:D/
Thomas
Eisbaeeer
08.07.2007, 11:49
Hi Knickohr
Hast du überhaupt noch Zeit, bei der Massenproduktion, die du da machst :-)
Respekt.
Grüße Eisbaeeer
Knickohr
08.07.2007, 12:04
Hallo Eisbär,
nein eigentlich nicht. Aber momentan ist meine Lötstation kaputt und die neue noch nicht da. Also hatte ich freies Wochenende ;)
Genau die richtige Zeit für eine Weiterentwicklung.
Werde aber trotzdem heute ein paar Timer mir einem alten "Bunsenbrenner" zusammen basteln.
Thomas
Hallo Knickohr,
Seltsamerweise setzt die erste Übertragung auch nicht an der ersten Stelle auf, sondern irgendwo mittendrin. Es sind immer ein paar Blanks am Anfang. Naja, halt beim ersten Mal senden.
Ich kenne die RF12-Module nicht aus eigener Erfahrung, aber das beschriebene Phänomen dürfte an der fehlenden Präambel liegen, wenn die Module nur die reinen Daten senden und kein Protokoll.
Vor der eigentlichen Datenübertragung braucht der Empfänger etwas Zeit, um sich mit dem Sender zu synchroniseren und die Komparatoren zu stabiliseren.
Um das zu erreichen, kann man einige (z.B. 6) Bytes mit einem 0/1-Bitwechsel (z.B. binär 01010101) immer beim ersten Senden vorwegschicken. Den Beginn der Übertragung der Datenbytes könnte man z.B. mit Hex 00-00-FF beginnen, danach folgen die Daten.
Die Fehlerprüfung im Empfänger würde dann die letzten 6 Bytes (also die Hälfte der 01-Bytes und 00-00-FF bewerten:
Die müßten dann binär so aussehen:
01010101-01010101-01010101-00000000-00000000-11111111
Dann ist die Sendung erfolgreich gestartet worden.
Am Ende der Daten kann man nochmal 00-00-FF senden, auch das kann im Empfänger benutzt werden, um die Intaktheit aller Daten zu kennzeichnen.
Wenn die Daten vor dem Senden vollständig bekannt sind, kann man natürlich auch eine Prüfsumme über alle Daten errechnen und z.B. am Ende mit verschicken. Auch die Bytezahl könnte man dann mit verschicken, z.B. vor der Ende-Markierung:
Daten-00-00-FF-PP-PP-ZZ-ZZ-00-00-FF
(P=Prüfsumme, Z=Bytezahl)
Da ist Phantasie gefragt, wie man seine Daten absichern will. Natürlich kostet das auch Sendezeit, so dass man abwägen muss.
Gruß Dirk
Knickohr
08.07.2007, 14:01
Hallo Dirk,
das ist genau das, was ich schon verzweifelt suche !
Für die Daten und eine Adresse würden mir jeweils ein Byte reichen. Würde dann nach Deinem Vorschlag ungefähr so aussehen :
AA-AA-AA-00-00-FF-Adressbyte-Datenbyte-00-00-FF-PP-PP-ZZ-ZZ-FF
Wären genau 16 Bytes, was ich für eine saubere und gesicherte Übertragung als vollkommen angemessen finde. Die Daten und Adressen sind genau bekannt. Wie wird die Prüfsumme gebildet ? Nur über die Daten- und Adress-Bytes oder über die gesamte Übertragung ? Wie kann ich das anstellen ?
Wie geschrieben, ich brauche im Prinzip nur eine Handvoll Befehle im Datenbyte und ein Byte Adressen reichen auch vollkommen aus.
Thomas
Hallo Knickohr,
du hast ja schon die Erfahrung gemacht, wie viele Bytes am Anfang einer Sendung meistens "Müll" sind. Nehmen wir an, es sind maximal 3 Bytes, die am Anfang unsicher empfangen werden.
Dann müßtest du ja zur Sicherheit 4 Bytes zur Synchronisierung an den Anfang stellen. Danach würde ich noch einmal 4 Bytes stellen, danach die Abfolge 00-00-FF. Dann folgen die beiden Datenbytes.
Das ganze Protokoll:
AA-AA-AA-AA-[highlight=red:927fd02520]AA-AA-AA-AA-00-00-FF[/highlight:927fd02520]-Daten(2 Bytes)-00-00-FF-PP-00-00-FF
Das wären dann 20 Byte.
Wenn du fest nur 2 Datenbytes überträgst, brauchst du ja die Bytezahl nicht zu übertragen. Es bleibt die Prüfsumme (PP). Man kann sie z.B. durch Addition von Datenbyte 1 und 2 bilden (Byte-Überlauf ist egal!).
Im Empfänger prüft man dann (nach korrektem Eintreffen des 1. 00-00-FF) auch die letzten 4 Bytes davor (AA-AA-AA-AA, d.h. die 2. Hälfte der AAs) auf Unversehrtheit (also insgesamt die roten Bytes oben). Die 4 AAs ganz am Anfang werden natürlich nicht gestestet, denn da ist ja der Müll drin.
Der Empfänger setzt je nach Ergebnis ein Error-Flag, das er z.B. als erneute Datenanforderung zum Sender zurückschickt. Dieses Error-Flag wird auch gesetzt, wenn am Ende die Prüfsumme oder die übertragene Bytezahl nicht stimmt.
Wenn der Sender eine solche Datenanforderung bekommt, wiederholt er z.B. die Datensendung. Bekommt er ein OK vom Empfänger, wird nicht wiederholt.
Auch hier kann man die Sicherheit weiter erhöhen. Zusätzlich zur Datenanforderung nach einem Fehler kann der Empfänger auch die Daten selbst wieder zurück schicken. Erkennt der Sender, dass die Daten identisch mit seinen gesendeten Daten sind, gibt er das letzte OK an den Empfänger, der dann die Aktion (Bild machen o.ä.) ausführt.
Dazu braucht man noch ein "Kontroll-Protokoll".
Z.B.:
AA-...-AA-00-00-FF-(Error-Flag/Sendeanforderung)-00-00-FF-Empfangene Daten(2 Bytes)-00-00-FF-PP-00-00-FF
Wie gesagt: Die Sicherheit läßt sich erhöhen, wenn man das braucht! Man kann das alles voll automatisieren, so dass man im Idealfall gar nicht mehr mitbekommt, ob z.B. eine Sendung verloren ging.
Gruß Dirk
nikolaus10
20.07.2007, 15:23
Hallo
Was bedeuten genau diese Zeilen:
Sub Rf12_init:
Waitms 150
Temp = Rf12_trans(&Hc0e0)
Temp = Rf12_trans(&H80d7)
Temp = Rf12_trans(&Hc2ab)
Temp = Rf12_trans(&Hca81)
Temp = Rf12_trans(&He000)
Temp = Rf12_trans(&Hc800)
Temp = Rf12_trans(&Hc4f7)
End Sub
Kennt jemand den Hersteller dieser Module ?
MFG
Knickohr
20.07.2007, 16:01
Hallo,
wenn das auch wissen tät, was die Zeilen da genau machen. Ist irgendeine Initialisierungsroutine. Hab auch schon gesucht, was für "Schalter" da im Funkmodul gesetzt werden.
Der Hersteller ist Hope RF
http://www.hoperf.com
Thomas
Eisbaeeer
20.07.2007, 16:26
Hallo,
wenn das auch wissen tät, was die Zeilen da genau machen. Ist irgendeine Initialisierungsroutine. Hab auch schon gesucht, was für "Schalter" da im Funkmodul gesetzt werden.
Der Hersteller ist Hope RF
http://www.hoperf.com
Thomas
Im Datenblatt ist es beschrieben. Ich hab mal dahinterkommentiert, was ich auf die Schnelle gefunden hab. Den rest müsst ihr Euch selbst raussuchen.
Temp = Rf12_trans(&Hc0e0)
Temp = Rf12_trans(&H80d7) 'EL, EF, 433 MHZ Band, 12.0 pF
Temp = Rf12_trans(&Hc2ab)
Temp = Rf12_trans(&Hca81) 'FIFO8, Sync, !ff, DR
Temp = Rf12_trans(&He000) 'NOT USE
Temp = Rf12_trans(&Hc800) 'NOT USE
Temp = Rf12_trans(&Hc4f7)
Es wäre schön, mehr kommentierten Source zu lesen. Schade eigentlich.
Das ganze ist unter Init beschrieben. Mit Flussdiagramm. Die PDF Datei heisst RF12_code.pdf.
Beginnt auf der Seite 1 Unterpunkt 2. --> Configuration Setting Command
Ein Tip. Rechnet mal Hex in Binär um. Dann seht ihr, welches Bit gesetzt ist und welches nicht.
Hoffe ich konnte helfen.
Grüße Eisbaeeer
Torsten_G
20.07.2007, 20:56
Hallo Leute,
ja, ich habe auch eine ganze Weile in detektivischer Kleinarbeit geforscht - das Ergebnis deckt sich mit Eisbaeeeers Feststellungen.
Sollte aber auch kein Problem sein, die Init-Werte als Bitmuster statt im Hex-Code zu übergeben, dann würde es etwas eindeutiger.
Ich stehe grade am Anfang meiner Forschungen mit den Funkmodulen, bei Bedarf werde ich gerne berichten.
Der gesamte Code hier basiert wohl auf Bastelbär´s Grundlagen, die er im Paralleluniversum gepostet hat. Klar, ein paar mehr Comments wären schön, aber wollen wir mal froh sein, dass wir überhaupt was haben... \:D/
Grüße
Torsten
Knickohr
23.08.2007, 15:31
Hallo :)
Nach ein paar Wochen auch mal wieder was von mir. Hab die letzten beiden Tage damit verbracht, den Code durchzuflöhen und mir ein paar Antworten zu den abgesetzten Befehlen geholt.
Die genaue Beschreibung der Register gibt es hier : http://www.hoperf.com/pdf/RF12_code.pdf
' Atmega8
' VDD -> VCC
' GND -> GND
' SDI -> MOSI (PB3, Pin 17)
' SDO -> MISO (PB4, Pin 18)
' SCK -> SCK (PB5, Pin 19)
' nSel -> SS (PB2, Pin 16)
' Fsk - > R 10k nach VDD
' Atmega16
' VDD -> VCC
' GND -> GND
' SDI -> MOSI (PB5, Pin 6)
' SDO -> MISO (PB6, Pin 7)
' SCK -> SCK (PB7, Pin 8)
' nSel -> SS (PB4, Pin 5)
' Fsk - > R 10k nach VDD
$regfile = "m8def.dat"
$crystal = 1000000 '
$hwstack = 32
$swstack = 32
$framesize = 40
Declare Sub Rf12_init
Declare Function Rf12_trans(byval Wert As Word) As Word
Declare Sub Rf12_setfreq(byval Freq As Single)
Declare Sub Rf12_setbandwith(byval Bandwith As Byte , Byval Gain As Byte , Byval Drssi As Byte)
Declare Sub Rf12_setbaud(byval Rfbaud As Long)
Declare Sub Rf12_setpower(byval Outpower As Byte , Byval Fskmod As Byte)
Declare Sub Rf12_ready
Declare Sub Rf12_readys
Declare Sub Rf12_txdata(byval Maxchar As Byte)
Declare Sub Rf12_rxdata(byval Maxchar As Byte)
Const Rf12freq = 433.92 ' Sende-/Empfangsfrequenz in 0,0025MHz-Schritten
Const Rf12baud = 700 ' Baudrate (>663)
Const Maxchar = 17 ' Anzahl der übertragenen Zeichen
'Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0
'Config Lcd = 16 * 2 , Chipset = Dogm162v3
'Cursor Off Noblink
'Cls
' config the SPI in master mode.The clock must be a quarter of the slave cpu
' Hier ggf. den SoftSPI reinmachen
Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 128 , Noss = 1
Config Portb.1 = Output ' LED zur Schleifenkontrolle
' werden benötigt für rf12_ready
Spi_cs Alias Portb.2 ' SS-Pin
Config Spi_cs = Output
Spi_sdo Alias Pinb.4 ' MISO-PIN
Set Spi_cs
Spiinit
Dim Count As Byte
Dim Temp As Word
Dim Rfdata(32) As Byte
Dim Text As String * Maxchar At Rfdata Overlay
'Locate 1 , 1 : Lcd "Init RFM12 "
'Waitms 100
Call Rf12_init ' ein paar Register setzen
'Locate 1 , 1 : Lcd "Set Frequenz "
'Waitms 100
Call Rf12_setfreq(rf12freq) ' Sende/Empfangsfrequenz einstellen
'Locate 1 , 1 : Lcd "Set Bandwith "
'Waitms 100
Call Rf12_setbandwith(4 , 0 , 4) ' 200kHz Bandbreite, 0dB Verstärkung, DRSSI threshold: -79dBm
'Locate 1 , 1 : Lcd "Set Baudrate "
'Waitms 100
Call Rf12_setbaud(rf12baud) ' Setzt Baud
'Locate 1 , 1 : Lcd "Set Tx-Power "
'Waitms 100
Call Rf12_setpower(0 , 6) ' 0dBm Ausgangangsleistung, 105kHz Frequenzshift
'Text = "Dies ist ein 433MHz Test !!!!!{013}{010}"
' Je nachdem ob Sender oder Empfänger die entsprechenden Zeilen aktivieren
Do ' Ewigschleife
' Pulseout Portb , 1 , 500 ' Schleifenkontrolle
' Locate 1 , 1 : Lcd "Empfange "
' Locate 2 , 1 : Lcd " "
Call Rf12_rxdata(maxchar)
' Locate 2 , 1 : Lcd Text
Waitms 25
' Pulseout Portb , 1 , 500 ' Schleifenkontrolle
' Locate 1 , 1 : Lcd "Sende "
Call Rf12_txdata(maxchar)
' Locate 1 , 1 : Lcd "Ready "
' Waitms 100
Loop
End
' ################################################## ######################
' ###### Unterroutinen
' ################################################## ######################
Sub Rf12_init:
Waitms 150
Temp = Rf12_trans(&Hc0e0) ' Low Battery Detector and Microcontroller Clock Divider Command
Temp = Rf12_trans(&H80d7) ' Configuration Setting Command
Temp = Rf12_trans(&Hc2ab) ' Data Filter Command
Temp = Rf12_trans(&Hca81) ' Output and FIFO mode Command
Temp = Rf12_trans(&He000) ' Wake-Up Timer Command
Temp = Rf12_trans(&Hc800) ' Low Duty-Cycle Command
Temp = Rf12_trans(&Hc4f7) ' AFC Command Part 1
End Sub
Sub Rf12_setfreq(byval Freq As Single)
Freq = Freq - 430.00
Temp = Freq / 0.0025
If Temp < 96 Then
Temp = 96
Elseif Temp > 3903 Then
Temp = 3903
End If
Temp = Temp + &HA000 ' Frequency Setting Command
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_setbandwith(byval Bandwith As Byte , Byval Gain As Byte , Byval Drssi As Byte)
Drssi = Drssi And 7
Gain = Gain And 3
Temp = Bandwith And 7
Shift Temp , Left , 2
Temp = Temp + Gain
Shift Temp , Left , 3
Temp = Temp + Drssi
Temp = Temp + &H9400 ' Receiver Control Command, VDI Output
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_setbaud(byval Rfbaud As Long )
Local Ltemp As Long
If Rfbaud < 663 Then Exit Sub
If Rfbaud < 5400 Then
Temp = 43104 / Rfbaud
Temp = Temp + &HC680 ' Data Rate Command
Else
Ltemp = 344828 / Rfbaud
Temp = Ltemp
Temp = Temp + &HC600 ' Data Rate Command
End If
Decr Temp
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_setpower(byval Outpower As Byte , Byval Fskmod As Byte)
Outpower = Outpower And 7
Temp = Fskmod And 15
Shift Temp , Left , 4
Temp = Temp + Outpower
Temp = Temp + &H9800 ' AFC Command Part 2
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_txdata(byval Maxchar As Byte)
Temp = Rf12_trans(&H8238) ' Power Management Command, Sender einschalten
Rf12_ready
Temp = Rf12_trans(&Hb8aa) ' Transmit Register Write Command (sendet AA zur Synchronisation)
Rf12_ready
Temp = Rf12_trans(&Hb8aa) ' Transmit Register Write Command (sendet AA zur Synchronisation)
Rf12_ready
Temp = Rf12_trans(&Hb8aa) ' Transmit Register Write Command (sendet AA zur Synchronisation)
Rf12_ready
Temp = Rf12_trans(&Hb82d) ' Transmit Register Write Command (sendet 2D für was auch immer)
Rf12_ready
Temp = Rf12_trans(&Hb8d4) ' Transmit Register Write Command (sendet D4 für was auch immer)
Rf12_ready
For Count = 1 To Maxchar
Rf12_ready
Temp = &HB800 + Rfdata(count) ' Transmit Register Write Command (sendet Daten)
Temp = Rf12_trans(temp)
Next Count
Rf12_ready
Temp = Rf12_trans(&H8208) ' Power Management Command, Sender + Empfänger ausschalten
End Sub
Sub Rf12_rxdata(byval Maxchar As Byte)
Temp = Rf12_trans(&H82c8) ' Power Mangement Command, Empfänger einschalten
Temp = Rf12_trans(&Hca81) ' Output and FIFO Mode Command
Temp = Rf12_trans(&Hca83) ' Output and FIFO Mode Command
For Count = 1 To Maxchar
Rf12_ready
Temp = Rf12_trans(&Hb000) ' Receiver FIFO Read Command
Rfdata(count) = Temp
Next Count
Temp = Rf12_trans(&H8208) ' Power Management Command, Sender + Empfänger ausschalten
End Sub
Function Rf12_trans(byval Wert As Word) As Word
Local Lowbyte As Byte
Local Highbyte As Byte
Lowbyte = Wert And 255
Shift Wert , Right , 8
Reset Spi_cs
Highbyte = Spimove(wert)
Lowbyte = Spimove(lowbyte)
Set Spi_cs
Temp = Highbyte * 256
Temp = Temp + Lowbyte
Rf12_trans = Temp
End Function
Sub Rf12_ready
Local I As Word
Reset Spi_cs
Do
Loop Until Spi_sdo = 1
End Sub
Hab den Code ein wenig dokumentiert. Jetzt sollte es eigentlich jedem möglich sein, raus zu finden was das Programm macht. Ein paar Fragen sind aber trotzdem noch offen. Warum muß man in der Senderoutine noch ein paar Daten vorher senden ???
Sub Rf12_txdata(byval Maxchar As Byte)
Temp = Rf12_trans(&H8238) ' Power Management Command, Sender einschalten
Rf12_ready
Temp = Rf12_trans(&Hb8aa) ' Transmit Register Write Command (sendet AA zur Synchronisation)
Rf12_ready
Temp = Rf12_trans(&Hb8aa) ' Transmit Register Write Command (sendet AA zur Synchronisation)
Rf12_ready
Temp = Rf12_trans(&Hb8aa) ' Transmit Register Write Command (sendet AA zur Synchronisation)
Rf12_ready
Temp = Rf12_trans(&Hb82d) ' Transmit Register Write Command (sendet 2D für was auch immer)
Rf12_ready
Temp = Rf12_trans(&Hb8d4) ' Transmit Register Write Command (sendet D4 für was auch immer)
Rf12_ready
For Count = 1 To Maxchar
Rf12_ready
Temp = &HB800 + Rfdata(count) ' Transmit Register Write Command (sendet Daten)
Temp = Rf12_trans(temp)
Next Count
Rf12_ready
Temp = Rf12_trans(&H8208) ' Power Management Command, Sender + Empfänger ausschalten
End Sub
Und was macht DRSSI threshold ? Wofür braucht man das ?
Thomas
Hallo Leute,
hab in Vorbereitung einer Master-Slave RFM12 Kommunikation
unter
http://www.iphpbb.com/board/ftopic-10138836nx63949-87.html
lauffähige Bascom Testcode (Master/Slave) fürs Datenprotokoll hinterlegt.
Downloadlink sollte auch da zu finden sein.
Die Code werden nach und nach vervollständigt.
Wigbert
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.