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:
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.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
Wolfgang







Zitieren

Lesezeichen