Ich bin begeistert. Das ist genau das, was ich gesucht habe. Hatte schon Angst, dass das nie was wird mit dem Funk, nachdem ich hier all die Berichte über Manchester usw gelesen und nur Bahnhof verstanden habe. Kenn die zwar vom Fuball her, aber in diesem Zusammenhang? Nee, das war nichts für mich. Ich wollte schon immer nur etwas mit Print hin und Print zurück... So eine Black-Box, die ich mit einfachen Befehlen beherrschen kann. Genau das ist RN-Funk!

Ich habe hier soviel gelernt - mache diese Mikrocomputer-Dinge erst seit drei Monaten - , möchte ich jetzt auch einen Beitrag leisten. Hier ist der Code zum Senden und Empfangen der Dallas DS 18S20 Temperaturdaten. Hoffe, dass ich nichts vergessen habe, da ich den Code aus einem über 12 KByte großen Projekt ausschneiden musste.

Hardware: RT868F4 an RN-Mega8 als Sendemodul mit dem Dallas dran. Über RS 232 Kabel dreiadrig verbunden. Befindet sich momentan im Keller und sendet munter vor sich hin. 2 Stockwerke drüber ist das RN Control Mega 32 mit RT..empfänger. Ebenfalls mit RS232 verbunden. Hier ist eine Anzeige mit dem SAA 1064 angeschlossen. Dieses Modul fragt alle 12 Sec nach Daten, die er dann beim Sender anfordert.

Das Sendemodul erzeugt alle 5 Sec Messdaten, so dass gewährleistet ist, dass bei der Anfrage auch Daten vorhanden sind.

Hier also der Code:
Sender
Code:
' ----------------------------------------------------------------
' Temperatur mit Dallas DS1820,
' mit 0.1 C Auflösung
' ----------------------------------------------------------------

$regfile = "m8def.dat"
$crystal = 7372800            'Quarzfrequenz

$baud = 9600

'***** DS1820 Befehle
Const Read_rom = &H33
Const Skip_rom = &HCC
Const Convertt = &H44
Const Read_ram = &HBE
Const Write_ram = &H4E
Const Copy_ram = &H48
Const Recall_ee = &HB8
Const Read_power = &HB4
Const Match_rom = &H55


Declare Sub 18s20_auslesen
Declare Sub Temperatur

Dim Bd(9) As Byte
Dim I As Byte , Tmp As Byte
Dim Crc As Byte
Dim T As Integer , T1 As Single , Grad As Single
Dim V As Byte
Dim Temp_anzeige As String * 7 , Zeichen As Byte
Dim Temp As Word
Dim Messen As Bit , Empfang As Byte

Config 1wire = Portb.2        ' DS18s20 an Pin b.2
Config Pind.2 = Output

Config Timer1 = Timer , Prescale = 1024

Sende_led Alias Portd.2
On Timer1 Timer_irq

Const Timervorgabe = 29536    '**** 5 sec
Const True = 1
Const False = 0

Enable Timer1
Enable Interrupts


Reset Sende_led

'***** alle 5 sec messen
'***** Temperaturstation sendet ein Zeichen als Signal, dass
'***** er auf die Daten wartet
'***** wenn Befehl "!" kommt senden

Do
      If Messen = True Then
        Toggle Sende_led
        Temperatur
        Messen = False
        Toggle Sende_led
      End If
      Zeichen = Inkey()
      If Zeichen > 0 Then     '***** läuft durch, wenn kein Zeichen
         'If Zeichen = 33 Then '***** Ascii für "!"
            Temp_anzeige = "A" + Temp_anzeige + "#"
            Printbin Temp_anzeige       '*** ohne crlf
            Waitms 100
         'End If
      End If
Loop

End


'//////////////////////////////////////////////////////////////////////////////
Sub Temperatur

1wwrite Skip_rom
1wwrite Convertt              ' Messung starten

'**** warten bis abgeschlossen
   Do
      Temp = 1wread()
   Loop Until Temp.7 = 1      '***** Bit 8 muss 1 sein!

   18s20_auslesen             ' 9 bytes einlesen

   If Err = 1 Then            ' if there is no sensor
      'Print "kein Sensor"
        Temp_anzeige = "----"
   Else
         Temp_anzeige = Fusing(grad , "##.#" )       '**** um aufzurunden!
   End If
End Sub

'//////////////////////////////////////////////////////////////////////////////
Sub 18s20_auslesen
    1wreset                   ' Reset
    1wwrite Skip_rom          ' Chip ansprechen
    1wwrite Read_ram          ' Befehl zum Auslesen des Rams
    Bd(1) = 1wread(9)         ' 9 Bytes lesen
    1wreset                   'Reset

    Temp = Bd(2)
    Shift Temp , Left , 8
    Temp = Temp + Bd(1)
    T = Temp
    T = T / 2
    Grad = Bd(8) - Bd(7)
    Grad = Grad / Bd(8)
    Grad = Grad + T
    Grad = Grad - 0.25
End Sub

Timer_irq:
Messen = True
Return

Empfänger:

Code:
'***** ----------------------------------------------------------------
'***** Thermometer mit DS18S20,
'***** mit 0.1 C Auflösung und CRC-Abfrage
'***** Anzeige mit SAA 1064
' ----------------------------------------------------------------
$regfile = "m32def.dat"       ' Mega 32

$baud = 9600
$crystal = 16000000
'$sim

'***** für Anzeige
Const Befbyte = 0
Const Displays = 4
Const Sensoren = 2
Const Digit_dezpunkt = 3      '**** 3. Stelle Dez.Punkt
Const Kontrollbyte = &B00110111       '**** 9 ma Segmentstrom,Mux-Betrieb, alle Digits aktiv
Const Slave = &B01110000      '***** Adr.Pin an GND

'**** Allgemein
Const True = 1
Const False = 0

Const Interrupt_intervall = 3 '***** ca 12 sec

Dim Zeichen As String * 1 , Länge As Byte
Dim Zähler As Byte , Z As Byte
Dim I As Byte , Tmp As Byte
Dim Interrupt_zähler As Byte


'***** SAA64
Dim Saa64_bytes(7) As Byte
Dim Display_zeichen(displays) As String * 1
Dim Funk_anzeige As String * 7

Dim Temp As Word , Wert As Word


'**** für Temperatur
Declare Sub Temperatur_holen

'**** für SAA Anzeige
Declare Sub Schicke_bytes(byval Anz As Byte)
Declare Function Bitmuster_saa1064(byval Digitnr As Byte , Byval Zeichen As String ) As Byte

Declare Sub Wert_anzeigen_saa
Declare Sub Display_zeichen_bilden(byval Beginn As Byte , Byval Ende As Byte , Byval Zeichen As String)


'***** für LEDs
Config Pinc.2 = Output        '**** Interrupt-LED
Config Pinc.3 = Output        '**** Sende/EmpFANGS-LED


LED_interrupt Alias Portc.2
LED_empfang Alias Portc.3

Const Timervorgabe = 3036     '**** 4 sec


'**** Anzeige mit saa 1064
'**** Beide Pins haben Pullup!!(auf dem RN-Control 1.4)
'**** sonst selbst einsetzen, wichtig
Config Scl = Portc.0
Config Sda = Portc.1


'***** Timer und der Teiler festgelegt
Config Timer1 = Timer , Prescale = 1024
On Timer1 Timer_irq

'**** am Anfang aus, dann kann durch toggle an aus gemacht werden
Set Led_interrupt
Set Led_empfang

Enable Timer1
Enable Interrupts

Do

    If Interrupt_zähler = Interrupt_intervall Then       '**** 12 sec
        Interrupt_zähler = 0

        '****** Interrupt-LED an
        Toggle LED_interrupt

        Temperatur_holen

        '****** Interrupt-LED aus
        Toggle LED_interrupt
   End If
Loop

End


'//////////////////////////////////////////////////////////////////////////////
Sub Temperatur_holen

'***** sende Anforderung
Zeichen = "!"
Printbin Zeichen
Waitms 100

Toggle LED_empfang

'**** Temperatur empfangen mit Inputbin
'**** Klasse Befehl!, sehr schnell und roblemlos, ohne crlf
'**** Bytefolge: A-Grad-#
'**** Länge ist unterschiedlich!
'**** passt aber alles, weil dimensioniert mit 7 Bytes
Inputbin Funk_anzeige
Länge = Len(funk_anzeige)
If Left(funk_anzeige , 1) = "A" Then
    If Right(funk_anzeige , 1) = "#" Then
        Länge = Länge - 2
        Funk_anzeige = Mid(funk_anzeige , 2 , Länge)
    Else
        Funk_anzeige = "FFFF"
    End If
Else
    Funk_anzeige = "FFFF"
End If

'***** verzögern, sonst sieht man nicht das Flackern
Waitms 300
Toggle LED_empfang

'***** Aufbereitung der Zeichen für die 4stellige Anzeige
'***** sehr aufwändig, um die Blanks vor den Ziffern hinzubekommen
'***** auch das Minus-Zeichen muss sitzen
Display_zeichen_bilden 1 , 4 , Funk_anzeige
Wert_anzeigen_saa

End Sub


'//////////////////////////////////////////////////////////////////////////////
Sub Schicke_bytes(byval Anz As Byte)
I2cstart
For Zähler = 1 To Anz
      I2cwbyte Saa64_bytes(zähler)
Next
I2cstop
Waitms 10
End Sub

'//////////////////////////////////////////////////////////////////////////////
Sub Wert_anzeigen_saa
Saa64_bytes(1) = Slave
Saa64_bytes(2) = Befbyte
Saa64_bytes(3) = Kontrollbyte '**** wird von LDR gesteuert!

For Z = 1 To Displays
Saa64_bytes(z + 3) = Bitmuster_saa1064(z , Display_zeichen(z))
Next

Schicke_bytes 7
End Sub

'//////////////////////////////////////////////////////////////////////////////
Sub Display_zeichen_bilden(byval Beginn As Byte , Byval Ende As Byte , Byval Zeichen As String * Displays )
Local Temp_zeichen As String * 1
      '**** erst Array löschen
      For Z = Beginn To Ende
            Display_zeichen(z) = ""
      Next

       '***** rückwärts den TempWert durchgehen
       Zähler = Ende
       For Z = Len(zeichen) To 1 Step -1
            Temp_zeichen = Mid(zeichen , Z , 1)
            '*** nur wenn kein Dez.Punkt, übernehmen
            If Temp_zeichen <> "." Then
                  Display_zeichen(zähler) = Temp_zeichen
                  Decr Zähler
            End If
       Next
       '**** fehlende Zeichen sind nun leere Strings!!!
End Sub

'//////////////////////////////////////////////////////////////////////////////
Function Bitmuster_saa1064(byval Digitnr As Byte , Byval Zeichen As String * 1 ) As Byte
Local Segmente As Byte
Select Case Zeichen
      Case "0"
            Segmente = &B00111111
      Case "1"
            Segmente = &B00000110
      Case "2"
            Segmente = &B01011011
      Case "3"
            Segmente = &B01001111
      Case "4"
            Segmente = &B01100110
      Case "5"
            Segmente = &B01101101
      Case "6"
            Segmente = &B01111101
      Case "7"
            Segmente = &B00000111
      Case "8"
            Segmente = &B01111111
      Case "9"
            Segmente = &B01101111
      Case "-"
            Segmente = &B01000000
      Case ""                 '**** leer
            Segmente = &B00000000
      Case Else
           Segmente = &B01110001       '**** F
End Select
If Digitnr = Digit_dezpunkt Then
      '***** oberstes Bit auf 1
      Segmente = Segmente Or 128
End If
Bitmuster_saa1064 = Segmente
End Function


'//////////////////////////////////////////////////////////////////////////////
Timer_irq:
  Timer1 = Timervorgabe
  Incr Interrupt_zähler
Return
Das Ganze läuft jetzt seit über 24 Stunden. Habe noch keinen einzigen Aussetzer auf dem Display entdeckt. An den Funkboards wurde nichts eingestellt, verstellt. Es war wirklich so: Strom und Datenkabel dran, funktionierte auf Anhieb.
Wolfgang