PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Probleme mit RFM12 868Mhz Code und Snap



mat-sche
22.08.2010, 10:03
Hallo liebe Gemeinde,

ich versuche nun schon seit Wochen den Code aus: www.comwebnet.de zum Laufen zu bekommen.

Grundausstattung: mega32 und RFM12 868Mhz
Code 1 als Hauptprogramm:



$regfile = "m32def.dat"
$hwstack = 100
$swstack = 100
$framesize = 100
$crystal = 14745600
$baud = 57600
'Baud = 57600
'$sim
'------------------------------------------------------------------------------- 2x16 LCD Display an Port c =>Conector
Config Lcdpin = Pin , Db4 = Portc.4 , Db5 = Portc.5 , Db6 = Portc.6 , Db7 = Portc.7 , E = Portc.3 , Rs = Portc.2
Config Lcd = 20 * 4
Config Lcdbus = 4
Initlcd
Cursor Off
Cls
Dim Rs232_flash As Byte , Za1 As Byte
Dim Rs232_str As Byte '


Const Rf12freq = 868.35 'Kanal-Einstellung
Const Rf12baud = 9600 'Baudrate
Const Myadress = 20 'Nodeadresse vom Teilnehmer
Const Snap_sync = &H54 'Synczeichen SNAP-Protokoll
Const Maxchar = 22

Declare Sub Rf_cmd(byval Tmp As Word)
Dim Cmd(2) As Byte , Tmpo As Word
Dim Lv As Byte , Readycount As Byte , Count2 As Byte
Dim Temp As Word
Dim Rf12_data(40) As Byte , Rf12_s As String * Maxchar At Rf12_data Overlay
Dim Rf_rxd As Bit , Rf_sync As Bit
Dim Ndb As Byte , Framelength As Byte , Crc As Byte
Dim Byteanzahl As Byte 'Anzahl Sendebytes
Dim S As String * 10
Sync Alias Rf12_data(1)
Hdb1 Alias Rf12_data(2)
Hdb2 Alias Rf12_data(3)
Dab1 Alias Rf12_data(4)
Sab1 Alias Rf12_data(5)

'----------[Hardwaresetup für Pollin Funkboard]---------------------------------------------
'PortD.3-->INT1 an FFIT --Interrupt(High) wenn FiFO-Buffer voll (ef-Bit set)
Led1 Alias Portb.2
Config Portb.2 = Output
Led2 Alias Portb.3
Config Portb.3 = Output

Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 128 , Noss = 1

Config Portd.5 = Output
Fsk Alias Portd.5
Set Fsk
Spi_cs Alias Portb.4 : Ddrb.4 = 1 'Config Spi_cs = Output chipselect
Spi_sdo Alias Pinb.6 ' MISO-PIN
Set Spi_cs
Spiinit 'init the spi pins
Goto Startup

$include "inc_RF12-Treiber.bas" 'RF12 Treiber einbinden
Startup:
Config Int1 = Rising

On Int1 Ffit_isr:
'On Urxc Rxd_isr:
Empfange String von RXD
'Enable Urxc
Enable Interrupts

Set Led2
Locate 1 , 1 : Lcd "Init RF12 ..."

Call Rf_cmd(&H0000)
Call Rf_cmd(&Hc0e0)
Call Rf_cmd(&H80e7)
Call Rf_cmd(&H82d8)
Call Rf_cmd(&Hc2ac)
Call Rf_cmd(&Ha686)

Call Rf_cmd(&Hc611)

Call Rf_cmd(&H94a1)
Call Rf_cmd(&Hc2ac)
Call Rf_cmd(&Hc483)
Call Rf_cmd(&H9850)
Call Rf_cmd(&He000)
Call Rf_cmd(&Hc800)
Call Rf_cmd(&Hca81)
Call Rf_cmd(&Hca83)
Call Rf_cmd(&H0000)
Locate 1 , 1 : Lcd "Init RF12 Done"
Reset Led2

Rf12_s = ""
Gosub Rf12_rxd_on

Do
Toggle Led2

Rs232_flash = Ischarwaiting()
If Rs232_flash = 1 Then
Rs232_str = Inkey()
If Rs232_str = 123 Then
Goto &HF800
End If
End If




If Rf_rxd = 1 Then
Locate 2 , 1 : Lcd "RX rdy,Frame " ; Framelength
Gosub Framehandler
Gosub Rf12_rxd_on
End If
'do anything....
'Incr Za1
Print "Za1 " ; Za1

Locate 3 , 1 : Lcd "neuer Mainloop " ; Za1
Print "Lv " ; Lv
' Wait 1
Loop
End


Sub Rf_cmd(byval Tmpo As Word)
Cmd(2) = Tmpo And 255
Shift Tmp , Right , 8
Cmd(1) = Tmpo
Spiout Cmd(1) , 2
End Sub


Framehandler:
Set Led1
Locate 1 , 1 : Lcd "Frame: ";
For Lv = 1 To Framelength
Print Hex(rf12_data(lv)) ; " ";
Next Lv
Print
Print "Sync alias RF_Data(1) " ; Sync
If Sync = Snap_sync Then
If Hdb2 = &H50 Then
'if HDB2= NDB then
If Dab1 = Myadress Then
Swap Dab1 , Sab1
Crc = Framelength - 2
Crc = Crc8(rf12_data(2) , Crc)
If Crc = Rf12_data(framelength) Then
Locate 1 , 1 : Lcd "CRC OK! => " ; Crc
' Send ACK (i.e tell master that packet was OK)
' Set ACKs bit in HDB2 (xxxxxx10)
Hdb2 = Hdb2 Or &B00000010
Hdb2 = Hdb2 And &B11111110
'do ...
Gosub Senden 'Anwortframe senden--> nur als Slave
Gosub Cmd_handler
'RF12_data(2 <--- ackno machen
Else
Locate 1 , 1 : Lcd "CRC Bad => " ; Crc
' Send NAK (i.e tell master that packet was bad)
' Set ACK bits in HDB2 (xxxxxx11)
Hdb2 = Hdb2 Or &B00000011
Gosub Senden 'Anwortframe senden--> nur als Slave
End If
Else
Locate 1 , 1 : Lcd "geht mich nix an!...von Nr.:" ; Rf12_data(5)
End If
'Else
'Print "Framelength NIO!!!"
'End If
Else
Locate 1 , 1 : Lcd "no 1Byte Adress!!!"
End If
Else
Locate 1 , 1 : Lcd "no Syncbyte!!!"
End If

Waitms 10
Reset Led1
Return




Cmd_handler: 'Auswertung der Nutzdaten.... nur als Denkhilfe :)
'(
Select Case Rf12_data(7)
Case 0 :
Case 1 : Gosub Rolloaufmachen
Case 2 : Gosub Rollozumachen
Case 10 : Gosub Holetemperatur
End Select
')
For Lv = 1 To 20
Toggle Led2 'mache was...
Waitms 100
Next Lv
Return




Rf12_rxd_on:
Lv = 1
Rf_sync = 0 'sync-Flag
Rf_rxd = 0
Rf12_s = ""
Framelength = 6 'erst mit 3.Byte kann die Framelänge berechnet werden
Temp = Rf12_trans(&H82c8) 'Power CMD: Empfänger an, Quarz-clk läuft weiter
Temp = Rf12_trans(&Hca81) 'FIFO&Reset CMD: sensitiver Reset aus (Brownout)
Temp = Rf12_trans(&Hca83) 'FIFO&Reset CMD: Synchroner Zeichenemfang (warte auf Startzeichen: 2DD4)
Print "rf12_rxd_on "
Enable Int1
Return


Senden:
Set Led2
' Waitms 1
Locate 2 , 1 : Lcd "Sende: "
For Lv = 1 To Framelength
Print Hex(rf12_data(lv)) ; " ";
Next Lv
Call Rf12_txdata(framelength)
Waitms 10
Reset Led2
Return

Rxd_isr:
S = S + Chr(udr)
Return
')

Ffit_isr:
Incr Za1


Temp = Rf12_trans(&Hb000)

Temp = Temp And &H00FF

If Temp = &H54 And Rf_sync = 0 Then
Rf_sync = 1
'Lv = 1
End If
Rf12_data(lv) = Temp
'Locate 1 , 1 : Lcd "RF12Dat " ; Rf12_data(lv)
If Lv = 3 Then
Ndb = Temp And &H0F
Select Case Ndb
Case 0 To 8 : Framelength = 6 + Ndb '6-14 (0--8 Datebyte)
Case 9 : Framelength = 6 + 16 '22 (16 Datenbyte)
Case 10 : Framelength = 6 + 32 '38 (32 Datenbyte)
End Select
End If

If Lv >= Framelength Then 'alles eingetroffen
Rf_rxd = 1 'Flag setzen und Empfänger abschalten
Temp = Rf12_trans(&H8208)
Disable Int1
End If
Incr Lv 'Zeiger incr
Return


hierzu kommt noch die include Datei dazu:


Declare Sub Rf12_init()
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_txdata(byval Txlen As Byte)
Declare Sub Rf12_rxdata(byval Maxchar As Byte)
Declare Function Rf12_trans(byval Wert As Word) As Word

Dim Rf12_timeout As Word
Dim Rf12_err As Byte
Dim Rf12_status As Word


'------[Sende Daten]-------------------
Sub Rf12_txdata(byval Txlen As Byte)
Temp = Rf12_trans(&H8238) : Rf12_ready
Temp = Rf12_trans(&H8230) : Rf12_ready
Temp = Rf12_trans(&H0000) : Rf12_ready
Rf12_status = Temp
Temp = Rf12_trans(&Hb8aa) : Rf12_ready 'Preamble
Temp = Rf12_trans(&Hb8aa) : Rf12_ready 'Preamble
Temp = Rf12_trans(&Hb8aa) : Rf12_ready 'Preamble in FIFO schieben
Temp = Rf12_trans(&Hb82d) : Rf12_ready 'Startzeichen: 2D für den Empfänger
Temp = Rf12_trans(&Hb8d4) : Rf12_ready 'Startzeichen: D4 für den Empfänger
Print "sende1"
For Lv = 1 To Txlen
Rf12_ready
Temp = &HB800 + Rf12_data(lv)
Temp = Rf12_trans(temp)
'Toggle Led2
'Print "temp" ; Temp
Next Lv
Temp = Rf12_trans(&Hb8aa) : Rf12_ready
Temp = Rf12_trans(&H8208) : Rf12_ready
Temp = Rf12_trans(&H8209) : Rf12_ready
Print "sende2"
End Sub

'------[Empfange Daten]---------------
Sub Rf12_rxdata(byval Maxchar As Byte)
Temp = Rf12_trans(&H82c8)
Temp = Rf12_trans(&H0000)
Rf12_status = Temp
Temp = Rf12_trans(&Hca81)
Temp = Rf12_trans(&Hca83)
For Lv = 1 To Maxchar
Rf12_ready :
Temp = Rf12_trans(&Hb000)
Rf12_data(lv) = Temp
Next Lv
Temp = Rf12_trans(&H8208)
Temp = Rf12_trans(&H8209)
Rf12_data(40) = 0
End Sub


'------[SPI Busroutinen]----------------
Function Rf12_trans(byval Wert As Word) As Word
Local Lowbyte As Byte
Local Highbyte As Byte

Lowbyte = Low(wert) : Highbyte = High(wert)
Reset Spi_cs
Highbyte = Spimove(highbyte) : Lowbyte = Spimove(lowbyte)
Set Spi_cs
Temp = Makeint(lowbyte , Highbyte)

Rf12_trans = Temp
End Function


'------[Busy check]-----------------------
Sub Rf12_ready
Rf12_timeout = 50000
Reset Spi_cs RF12
While Spi_sdo = 0
If Rf12_timeout > 0 Then
Decr Rf12_timeout
Else
Rf12_err = 1
Exit While
End If
Waitus 20
Wend
End Sub


'------[INIT]-------------------------------------
Sub Rf12_init()
Waitms 150

Temp = Rf12_trans(&H0000) ': print Temp '0000 -Status
Temp = Rf12_trans(&Hc0e0) ': print Temp 'C0E0 -Clock Output 10MHz
Temp = Rf12_trans(&H80e7) ': print Temp '80D7 -Datareg used,FIFO enabled,433MHz,CL=15pF
Temp = Rf12_trans(&Hc2ab) ': print Temp 'C2AB -Datafilter:Autolock-slow mode-Digital Filter,f1=1;f0=1
Temp = Rf12_trans(&Hcaf3) ': print Temp 'CA81 -FIFO/ResetMode (Brownoutdektion ausgeschaltet)
Temp = Rf12_trans(&He000) ': print Temp 'E000 -WakeUP Timer
Temp = Rf12_trans(&Hc800) ': print Temp 'C800 -LowDuty Cycle
Temp = Rf12_trans(&Hc4f7) ': print Temp 'C4F7 -AFC-command -eingeschaltet

Temp = Rf12_trans(&Hc2ac) 'data filter:
Temp = Rf12_trans(&Hc483) 'AFC:
Temp = Rf12_trans(&H9850) 'TX control
Temp = Rf12_trans(&He000) 'wake-up
Temp = Rf12_trans(&Hc800) 'low duty-cycle
Temp = Rf12_trans(&Hca81) 'Reset FIFO
Temp = Rf12_trans(&Hca83) 'enable FIFO
Temp = Rf12_trans(&H0000)

Temp = Rf12_trans(&H0000)
Temp = Rf12_trans(&Hc0e0)
Temp = Rf12_trans(&H80e7)
Temp = Rf12_trans(&H8200)
Temp = Rf12_trans(&Hc2ac)
Temp = Rf12_trans(&Ha686)
Temp = Rf12_trans(&Hc611)
Temp = Rf12_trans(&H94a1)
Temp = Rf12_trans(&Hca81)
Temp = Rf12_trans(&Hc483)
Temp = Rf12_trans(&H9852) '
Temp = Rf12_trans(&He000)
Temp = Rf12_trans(&Hc800)
End Sub


Sub Rf12_setfreq(byval Freq As Single)
Freq = Freq - 860.00
Temp = Freq / 0.0050
If Temp < 96 Then
Temp = 96
Elseif Temp > 3903 Then
Temp = 3903
End If
Temp = Temp + &HA000
Temp = Rf12_trans(temp) 'Axxx - Frequenzsetting (Kanal Einstellung)
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) 'Revicer Control Command (Pin20 VDI output)
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


'------[Sendeleistung einstelllen]-----------------
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



Mein Problem ist, dass ich die Ersten 2 Byte von dem Frame empfangen kann und dann ist Schluss. Irgend wie wird die Int-ISR nicht mehr angesprungen, aus welchem Grunde auch...

Nutze ich einen anderen Code kann ich ohne Probleme die Datenpakete empfangen.

Hat nun jemand von Euch ein RFM12 im 868Mhz Bereich mit Interruptabfrage als Empfänger/Sender am Laufen?
Hilfe... ich verzweifle nun langsam.

Gruß MAT

Dino Dieter
26.10.2010, 20:38
Hallo Mat

Brauchst du noch Hilfe, oder hast es am laufen.

Habe hier 2 Pollin Bords mit INT am laufen.

Werde auch sowas in der Art machen.

MFG
Dieter

mat-sche
27.10.2010, 07:38
Guten Morgen Dino Dieter,

es wäre super einige Tips & Hilfe von Dir zu bekommen! Nach sooo langer Zeit noch eine Antwort auf eine Frage zu bekommen ist doch SUPER, ein + ans Forum & Mitstreiter!
Ich würde mich über ein paar Codeschnipsel freuen!
Grüße MAT

Dino Dieter
27.10.2010, 18:37
Hallo Mat

Ich wollte gerade dein Programm mal testen, da ist mir aufgefallen, das du ein anderes Pollin Board haben mußt. Ich habe das Funk AVr Board.

Ich muß das erst anpaasen zum testen.

Ich habe den Code aus dem Nachbarforum genommen. www.Bascom-Forum.de unter Codebeispiele.

Das größte Problem was ich bis jetzt hatte, das man die Daten schnell genug abholen muß, sonst kommt der INT nicht mehr. Ist aber in den Griff zu bekommen.

Hier mal ein Bild beim empfanen des ersten bytes



MFG
Dieter

Dino Dieter
27.10.2010, 23:38
Hallo Mat

Ich habe dein Programm mal soweit angepaßt und getestet.



'Empfang von Daten mit Pollin RFM AVR Funkboard
'angeschlossen wie auf dem Board
'Empfang über fallende Flanke an INT0
'basiert auf dem Code von "Holli" aus dem http://bascom-forum.de/
'geändert und angepaßt von Dino DIeter 26.10.2010
'Status: läuft
'Sender steht ca 8 m entfernt hinter dicken Mauern und sendet alle 2 Sekunden
' 32 Bytes

$regfile = "m8def.dat"
$hwstack = 32
$swstack = 50
$framesize = 50
$crystal = 12000000
$baud = 57600
Baud = 57600

'Nsel Alias Portb.2
'Clk Alias Portb.5
'Mosi Alias Portb.3
'Miso Alias Pinb.4

Config Portd.2 = Input
Nirq Alias Pind.2

Config Portd.3 = Input
Ffit Alias Pind.3

Led2 Alias Portd.5
Config Portd.5 = Output 'LED zur Kontrolle

Led1 Alias Portd.6
Config Portd.6 = Output 'LED zur Kontrolle

Dim Taste As Byte
Dim Fifo(2) As Byte
Dim A As Byte

'Hardware einstellen
Config Com1 = 57600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 64 , Noss = 0 , Spiin = &HB0
'Config Spi = Soft , Din = Pinb.4 , Dout = Portb.3 , Ss = Portb.2 , Clock = Portb.5 , Spiin = 0

'init the spi
Spiinit

'Interrupt 0 einstellen
Config Int0 = Falling
On Int0 Ffit_isr

Waitms 100

'$include "inc_RF12-Treiber.bas" brauchen wir nicht
Declare Sub Rf_init()
Declare Sub Rf_cmd(byval Wert As Word)
Declare Sub Rf12_rxd_off()
Declare Sub Rf12_rxd_on()
Declare Sub Framehandler()

'Definition von Konstanen
Const Rf12freq = 868.35 'Kanal-Einstellung
Const Rf12baud = 9600 'Baudrate
Const Myadress = 20 'Nodeadresse vom Teilnehmer
'Const Snap_sync = &H54 'Synczeichen SNAP-Protokoll
Const Snap_sync = &H31 'Synczeichen
Const Maxchar = 22
'const HDB2_ = &H50
Const Hdb2_ = &H32
Const Sync_byte = &H31
Const My_adress = &H34
Const Recive_buffer_size = 40


Dim Cmd(2) As Byte , Tmpo As Word
Dim Lv As Byte , Readycount As Byte , Count2 As Byte
Dim Temp As Word
Dim Tmp As Word
Dim Rs232_flash As Byte , Za1 As Byte
Dim Rs232_str As Byte '
Dim Ndb As Byte , Framelength As Byte , Crc As Byte
Dim Byteanzahl As Byte 'Anzahl Sendebytes
Dim S As String * 10
Dim Rf12_data(recive_buffer_size) As Byte , Rf12_s As String * Maxchar At Rf12_data Overlay
Sync Alias Rf12_data(1)
Hdb1 Alias Rf12_data(2)
Hdb2 Alias Rf12_data(3)
Dab1 Alias Rf12_data(4)
Sab1 Alias Rf12_data(5)
Dim Rf_rxd As Bit , Rf_sync As Bit

Set Led1

'RFM 12 einstellen auf senden erstmal
Call Rf_init()

Reset Led1

Enable Interrupts
Enable Int0

'Array löschen
Rf12_s = ""

'Endlosschleife
Do

'nur zum debuggen
Taste = Inkey()

If Taste = "a" Then
Call Rf_cmd(&H0000) 'read status
Call Rf_cmd(&Hca81) 'Reset FIFO
Call Rf_cmd(&Hca83) 'enable FIFO
End If

If Taste = "x" Then
'Empfänger an
Call Rf12_rxd_on:
End If

If Taste = "c" Then
'Empfänger aus
Call Rf12_rxd_off:
End If

'empfangenes Frame auswerten
If Rf_rxd = 1 Then
Rf_rxd = 0
Call Framehandler()
End If

Loop

'Befehl zum RFM senden geändert Dino Dieter
Sub Rf_cmd(byval Wert As Word)
Cmd(2) = Wert And 255
Shift Wert , Right , 8
Cmd(1) = Wert
Spiout Cmd(1) , 2
End Sub

'Einstellen des RFM 12
Sub Rf_init()
Call Rf_cmd(&H0000) 'Read Status
Call Rf_cmd(&Hc0e0) 'low battery, clock 10 MHz
Call Rf_cmd(&H80e7) 'Configuration: 868MHzband, 12pf, enable FIFO
Call Rf_cmd(&H82d8) 'power management: enable receiver, enable clock output
Call Rf_cmd(&Hc2ac) 'data filter command
Call Rf_cmd(&Ha686) 'Frequency: 868,35MHz
Call Rf_cmd(&Hc611) 'Datarate: 19,2 kbit
Call Rf_cmd(&H94a1) 'receiver setting: 134kHz, -97dbm
Call Rf_cmd(&Hc2ac) 'data filter:
Call Rf_cmd(&Hc483) 'AFC:
Call Rf_cmd(&H9850) 'TX control
Call Rf_cmd(&He000) 'wake-up
Call Rf_cmd(&Hc800) 'low duty-cycle
Call Rf_cmd(&Hca81) 'Reset FIFO
Call Rf_cmd(&Hca83) 'enable FIFO
Call Rf_cmd(&H0000) 'read Status
End Sub

Sub Framehandler() 'habe ich mir nicht angeschaut
Set Led2
'Print "Frame: ";
'For Lv = 1 To Framelength
' Print Hex(rf12_data(lv)) ; " ";
' Next Lv
Print "Sync alias RF_Data(1) " ; Sync
If Sync = Snap_sync Then
If Hdb2 = Hdb2_ Then
'if HDB2= NDB then
If Dab1 = Myadress Then
Swap Dab1 , Sab1
Crc = Framelength - 2
Crc = Crc8(rf12_data(2) , Crc)
If Crc = Rf12_data(framelength) Then
Print "CRC OK! => " ; Crc
' Send ACK (i.e tell master that packet was OK)
' Set ACKs bit in HDB2 (xxxxxx10)
Hdb2 = Hdb2 Or &B00000010
Hdb2 = Hdb2 And &B11111110
'do ...
' Gosub Senden 'Anwortframe senden--> nur als Slave
'Gosub Cmd_handler
'RF12_data(2 <--- ackno machen
Else
Print "CRC Bad => " ; Crc
' Send NAK (i.e tell master that packet was bad)
' Set ACK bits in HDB2 (xxxxxx11)
Hdb2 = Hdb2 Or &B00000011
' Gosub Senden 'Anwortframe senden--> nur als Slave
End If
Else
Print "geht mich nix an!...von Nr.:" ; Rf12_data(5)
End If
'Else
Print "Framelength NIO!!!"
'End If
Else
Print "no 1Byte Adress!!!"
End If
Else
Print "no Syncbyte!!!"
End If

Waitms 10
Reset Led2
End Sub

Cmd_handler: 'Auswertung der Nutzdaten.... nur als Denkhilfe :)
'(
Select Case Rf12_data(7)
Case 0 :
Case 1 : Gosub Rolloaufmachen
Case 2 : Gosub Rollozumachen
Case 10 : Gosub Holetemperatur
End Select
')
For Lv = 1 To 20
Toggle Led2 'mache was...
Waitms 100
Next Lv
Return
Rf12_rxd_on:
Lv = 1
Rf_sync = 0 'sync-Flag
Rf_rxd = 0
Rf12_s = ""
' Framelength = 6 'erst mit 3.Byte kann die Framelänge berechnet werden
Call Rf_cmd(&H0000) 'Status lesen
Call Rf_cmd(&Hca81) 'FIFO&Reset CMD: sensitiver Reset aus (Brownout)
Call Rf_cmd(&Hca83) 'FIFO&Reset CMD: Synchroner Zeichenemfang (warte auf Startzeichen: 2DD4)
' Print "rf12_rxd_on "
Enable Int0
Return


Rf12_rxd_off:
Call Rf_cmd(&H0000) 'Status lesen
Call Rf_cmd(&Hca81) 'FIFO&Reset CMD: sensitiver Reset aus (Brownout)
' Print "rf12_rxd_off "
Disable Int0

Return


Senden: 'habe ich mir nicht angeschaut Dino Dieter
Set Led2
' Waitms 1
' Locate 2 , 1 : Lcd "Sende: "
For Lv = 1 To Framelength
Print Hex(rf12_data(lv)) ; " ";
Next Lv
' Call Rf12_txdata(framelength)
Waitms 10
Reset Led2
Return

Rxd_isr:
S = S + Chr(udr)
Return

'Interrupt Routine zum empfangen der bytes aus dem RFM 12
Ffit_isr:
Set Led1 ':zum debuggen für LA
Reset Led1
Spiin Fifo(1) , 2 '1 Byte lesen
Temp = Fifo(2)

If Temp = Snap_sync And Rf_sync = 0 Then
Rf_sync = 1
Lv = 1
Framelength = 6
End If

If Lv = 3 Then
Ndb = Temp And &H0F 'Anzahl Datenbytes berechnen
Ndb = 9 'zum debuggen
Select Case Ndb
Case 0 To 8 : Framelength = 6 + Ndb '6-14 (0--8 Datebyte)
Case 9 : Framelength = 6 + 16 '22 (16 Datenbyte)
Case 10 : Framelength = 6 + 32 '38 (32 Datenbyte)
'Case 11 : Framelength = 6 + 64 '70 (64 Datenbyte)
End Select
End If

If Lv >= Framelength And Rf_sync = 1 Then 'alles eingetroffen
Rf_rxd = 1 'Flag setzen und Empfänger zurück setzen
Rf_sync = 0
Call Rf_cmd(&H0000) 'read status
Call Rf_cmd(&Hca81) 'Reset FIFO wir warten wieder auf SYNC vom RFM 12
Call Rf_cmd(&Hca83) 'enable FIFO
End If

Rf12_data(lv) = Temp


Incr Lv
' Überlauf abgefangen , passend zum Empfangsbuffer
If Lv >= Recive_buffer_size Then
'Überlauf
Rf_sync = 0
Lv = 1
Rf12_s = "" 'buffer löschen
End If
Return


End


Das erste Problem, welches mir schnell aufgefallen war, ist die Sub Rf_cmd(byval Wert As Word) . Die hat nur Nullen gesendet. Nach Änderung der Variable ( temp0 oder so ) ging die SUB. Wieso, keine Ahnung.

So mal, ob du das so ans laufen bekommst.

Im Anhang noch eine Datei. Lade dir bei http://www.saleae.com/downloads/ mal die Software runter. Dann solttest du das File öffnen könne. Der Rest erklärt sich dann.

MFG
Dieter

mat-sche
28.10.2010, 18:28
Hallo Dino,

Danke für Deine Hilfe!
Ich habe meine RFM Boards eigentlich nur an einem AVR über die SPI-Schnittstelle angeschlossen, wie die Pinbezeichnung hergibt. Werde jetzt mal dein Programm testen. Hatte ja mit meinem ja auch Erfolg, nur das ich nicht alle Bytses auslesen konnte.
Melde mich später dann wieder.

MAT

mat-sche
29.10.2010, 20:46
Hallo Dieter,

jetzt bin ich dazu gekommen Deine Code zu probieren und..... es funzt!
Ich weiß nicht was ich bei mir falsch hatte! Mal schauen ob ich alle anderen Funktionen auch noch inplementiert bekomme.
Noch eine Frage:
in der Einstellungen zur SPI configuration hast Du "Clockrate = 64" & "Spiin = &HB0" => kannst Du mir bitte diese Größen erklären?

UNd jetzt geht es ans senden...

Grüße Matthias

Dino Dieter
29.10.2010, 21:08
Hallo Matthias

Schön das es jetzt geht.

Clockrate = 64 gibt den Takt der SPI an . Taktfrequenz des AVr / 64 = ??

Spiin = &HB0 wir müssen ja, wenn wir Daten lesen wollen in dem ersten Byte &hB0 übergeben, das wird damit angegeben. Ansonsten würde die SPI nur &H00 ausgeben.

Bei höheren Übertragungsgeschwindigkeiten, mußt du den SPI Takt mit einer kleineren Clockrate hochsetzen, sonst kommt es zu Aussetzern. Bis ca 20 MHz SPI Clock sollte es gehen.

MFG
Dieter

mat-sche
30.10.2010, 14:51
Hallo Dieter,

ok, mit der Clockrate hab eich verstanden, der max. SPI-Takt hängt sicherlich dann vom verwendeten IC ab.
Jetzt muss ich mir überlegen welche und in welcher Form ich die Daten übertragen werden. Bei weiteren Fragen meld ich mich ;)

Danke & Grüße
MAT

Dino Dieter
07.11.2010, 19:12
Hallo Matthias

Wie sieht es aus ? Bist du weiter gekommen mit dem RFM12 & SNAP.

Bei mir sieht e ganz gut aus. Wenn du Lust hast, können wir uns ja mal austauschen.

Hier mein Stand.
Sender läuft, Empfänger läuft, CRC Prüfung OK, NACK wird gerade eingebaut, Stromsparmodus geht, ACK OK, Logger Software PC läuft, Temperatur DS18B20 läuft.

Plane gerade den ersten Protoypen

Später soll das ganze zentral über einen MBED im Netzwerk verfügbar sein. Liegt hier, geiles Teil.

Ich suche noch einen Energiemesser zum auswerten mit einem AVR. Hat da jemand einen Tip. Auslösung von 0,1 KWh würde mir reichen.

MFG
Dieter

www.mbd.com

mat-sche
07.11.2010, 20:04
Hallo Dieter,
leider bin ich noch weiter gekommen, in der Woche fehlte mir die Zeit (arbeiten & Haus ausbauen)
Heute wollte ich etwas machen aber....
Nun gut. Das Protokoll habe ich soweit verstanden und bin eigentlich noch dran den Fehler zu suchen warum der Ursprungscode bei mir nicht läuft. Dieser hat mir deswegen gefallen, weil dieser mit einer Lib fungiert. Noch habe ich viele Fragen zu der Initialisierung des RFM12, vielleicht funktioniert deswegen der code nicht, da anders initialisiert wird. Melde mich die Woche noch einmal...
Zu einem Energiemonitor habe ich keine Idee, wo soll dieser ANwendung finden?
Schönen Sonntag noch.
Grüße MAT

raptor_79
11.11.2010, 23:45
hallo ihr zwei!

ich hab das gerade gefunden.... weil ich auch gerad an einem RFM12 (433Mhz) herumwerkle.
ich habe aber gerade mal angefangen, schaltung (pollin avr-funk-eval-board) ist noch nicht mal kalt.... also gerade zusammen gelötet.

mir ist bei den boards so einiges noch unklar. aber wie gesagt, habe gerade angefangen. noch nicht mal den schaltplan richtig angesehen, und die doku zum board/modul gelesen. nur mal überflogen.

ja, ich hoffe, da bekommen wir was hin.


viel erfolg wollte ich euch nur mal wünschen.



ja, wegen energiemonitor.... schon mal dran gedacht, das ganze übe eine induktionsspule zu messen? also draht über das 230V kabel wickeln und mit dem adc messen. vorher halt über eine diode und C gleichrichten.....

Holli_
12.11.2010, 01:34
Hallo Matthias
Spiin = &HB0 wir müssen ja, wenn wir Daten lesen wollen in dem ersten Byte &hB0 übergeben, das wird damit angegeben. Ansonsten würde die SPI nur &H00 ausgeben.


Der Code war übrigens von mir, daher habe ich noch eine Anmerkung. Es gibt 2 Möglichkeiten den FIFO zu Lesen. Einmal mit "FIFO read command", dafür wird Spiin = &HB0 verwendet. Es geht auch mit dem "Status read command" dann muss Spiin = 0 benutzt werden. Beim "Status read command" müssen 3 Byte gelesen werden, in den ersten beiden sind die Statusbits, danach kommen Fifo Daten.

mat-sche
13.11.2010, 22:17
HAllo Holli & Dieter,

mit dem Code von oben

'Interrupt Routine zum empfangen der bytes aus dem RFM 12
Ffit_isr:
Set Led1 ':zum debuggen für LA
Reset Led1
Spiin Fifo(1) , 2 '1 Byte lesen
Temp = Fifo(2)

If Temp = Snap_sync And Rf_sync = 0 Then
Rf_sync = 1
Lv = 1
Framelength = 6
End If

If Lv = 3 Then
Ndb = Temp And &H0F 'Anzahl Datenbytes berechnen
Ndb = 9 'zum debuggen
Select Case Ndb
Case 0 To 8 : Framelength = 6 + Ndb '6-14 (0--8 Datebyte)
Case 9 : Framelength = 6 + 16 '22 (16 Datenbyte)
Case 10 : Framelength = 6 + 32 '38 (32 Datenbyte)
'Case 11 : Framelength = 6 + 64 '70 (64 Datenbyte)
End Select
End If

If Lv >= Framelength And Rf_sync = 1 Then 'alles eingetroffen
Rf_rxd = 1 'Flag setzen und Empfänger zurück setzen
Rf_sync = 0
Call Rf_cmd(&H0000) 'read status
Call Rf_cmd(&Hca81) 'Reset FIFO wir warten wieder auf SYNC vom RFM 12
Call Rf_cmd(&Hca83) 'enable FIFO
End If

Rf12_data(lv) = Temp


Incr Lv
' Überlauf abgefangen , passend zum Empfangsbuffer
If Lv >= Recive_buffer_size Then
'Überlauf
Rf_sync = 0
Lv = 1
Rf12_s = "" 'buffer löschen
End If
Return


kann ich gut meine Daten empfangen. Nur leider habe ich festgestellt, dass das letzte Byte nicht mit dem gesendeten übereinstimmt. Woran kann das liegen?

Grüße Matthias

Holli_
14.11.2010, 10:54
Auf der Senderseite musst du am Ende noch 2 Byte zusätzlich zu den Daten senden z.B. &Haa. Damit werden die Datenbytes aus dem Sendepuffer noch gesendet. Sonst bleiben die nämlich im Puffer stecken.

Dino Dieter
14.11.2010, 12:43
Hallo Holli_

Ich habe auch mit dem Code von dir angefangen und es hat direkt gut geklappt. Schreibe den Code jetzt nach meinen Bedürfnissen um. Viel ist von deinem Code leider nicht mehr übrig geblieben, das liegt aber auch an den neuen Versionen von Bascom, welche heute andere Möglichkeiten haben.


An dieser Stelle eine großes Danke für den leichten Einstieg.

MFG
Dieter

mat-sche
14.11.2010, 14:26
@ Holli,

werde ich mal ausprobieren. Nur was mir spanisch vorkommt ist, dass ja ein letztes byte gesendet wird...

Holli_
14.11.2010, 15:03
Es braucht aber 2 Byte, da der TX-Puffer auch 16 bit groß ist. Ebenso ist der RX-Puffer 16 bit, es werden meistens aber nur 8 bit genutzt. Außerdem kann nur für den RX-Puffer die Größe eingestellt werden, "Fifo IT level" im Register &HCAxx. Der TX-Puffer ist immer 16 bit.

mat-sche
14.11.2010, 19:55
N'Abend,

laut meinem Code schiebe ich ja noch 2 Bytes hinterher:


Sub Rf12_txdata(byval Txlen As Byte)
Temp = Rf12_trans(&H8238) : Rf12_ready 'Power CMD: synt.& PLL on
Temp = Rf12_trans(&H8230) : Rf12_ready
Temp = Rf12_trans(&H0000) : Rf12_ready 'Status holen
Rf12_status = Temp 'Status einlesen
Temp = Rf12_trans(&Hb8aa) : Rf12_ready 'Preamble
Temp = Rf12_trans(&Hb8aa) : Rf12_ready 'Preamble
Temp = Rf12_trans(&Hb8aa) : Rf12_ready 'Preamble in FIFO schieben
Temp = Rf12_trans(&Hb82d) : Rf12_ready 'Startzeichen: 2D für den Empfänger
Temp = Rf12_trans(&Hb8d4) : Rf12_ready 'Startzeichen: D4 für den Empfänger
Print "sende1"
For Lv = 1 To Txlen
Rf12_ready
Temp = &HB800 + Rf12_data(lv) 'Sende Nutzdaten
Temp = Rf12_trans(temp)
'Toggle Led2
Print "temp" ; Temp
Next Lv
Temp = Rf12_trans(&Hb8aa) : Rf12_ready
Temp = Rf12_trans(&Hb8aa) : Rf12_ready 'Dummybyte nachschieben
Temp = Rf12_trans(&H8208) : Rf12_ready 'Power CMD: synt.& PLL off, Quarz-clk läuft weiter
Print "sende2"
End Sub


und hier wird es über SPI übertragen:


Function Rf12_trans(byval Wert As Word) As Word
Local Lowbyte As Byte
Local Highbyte As Byte

Lowbyte = Low(wert) : Highbyte = High(wert)
Reset Spi_cs
Highbyte = Spimove(highbyte) : Lowbyte = Spimove(lowbyte)
Set Spi_cs
Temp = Makeint(lowbyte , Highbyte) 'debug
Rf12_trans = Temp
Print "SPI receive: " ; Hex(temp)
Print "SPI send " ; Hex(highbyte)
End Function


Irgend eine Idee warum das letzte Byte dennoch falsch sein kann?

Holli_
14.11.2010, 21:57
Folgendes habe ich bei diesem Code gefunden:
- Print Ausgaben während des Sendezyklus (von TX on bis TX off) sollten nicht sein, da die recht viel Zeit brauchen und der Sendepuffer rechtzeitig gefüllt werden muss.
- Rf12_ready brauchst du nur zur Übertragung der Sendedaten in den Puffer, nicht zum Beschreiben der Register selbst. Zuerst rf12_ready, dann rf12_trans ausführen. Mit Rf12_ready bekommt der RFM erst dann Daten, wenn er diese braucht.
- Zwischen der Übertragung der Nutzdaten und dem Dummybyte ist kein Rf12_ready, damit wird das Byte unkontrolliert in den Puffer geschrieben. Damit die Übertragung entweder gestört oder das Byte wird intern verworfen.
- Prinzipiell kann man auf das Senden der Preambel an den RFM verzichten, da der TX-Puffer selbst eine 2 Byte lange Preambel erzeugt.


So sollte der Code dann aussehen:


Sub Rf12_txdata(byval Txlen As Byte)
Temp = Rf12_trans(&H8238) 'Power CMD: synt.& PLL on
Temp = Rf12_trans(&H8230)
Temp = Rf12_trans(&H0000) 'Status holen
Rf12_status = Temp
Rf12_ready 'Status einlesen
Temp = Rf12_trans(&Hb8aa) 'Preamble
Rf12_ready 'Status einlesen
Temp = Rf12_trans(&Hb8aa)
Rf12_ready 'Preamble
Temp = Rf12_trans(&Hb8aa)
Rf12_ready 'Preamble in FIFO schieben
Temp = Rf12_trans(&Hb82d)
Rf12_ready 'Startzeichen: 2D für den Empfänger
Temp = Rf12_trans(&Hb8d4) 'Startzeichen: D4 für den Empfänger
'Print "sende1"
For Lv = 1 To Txlen
Rf12_ready
Temp = &HB800 + Rf12_data(lv) 'Sende Nutzdaten
Temp = Rf12_trans(temp)
'Toggle Led2
'Print "temp" ; Temp
Next Lv
Rf12_ready 'Status einlesen
Temp = Rf12_trans(&Hb8aa)
Rf12_ready 'Status einlesen
Temp = Rf12_trans(&Hb8aa) 'Dummybyte nachschieben
Temp = Rf12_trans(&H8208) 'Power CMD: synt.& PLL off, Quarz-clk läuft weiter
Print "sende2"
End Sub