PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Funkübertragung mit Bascom ( Lösungsansatz )



Dino Dieter
27.12.2004, 21:13
Hallo

Hier mal 2 Programme zur Datenübertragung mittels der preiswerten Funkmodulen.

Gesendet werden zum testen 7 Bytes. 1 Startbyte, 4 Datenbytes und 2 Bytes mit der CRC Püfsumme. Der Empfänger prüft nach Empfang aller 7 Bytes die CRC Summe und gibt die Daten dann frei. Sie stehen dann in einem Array zur weiteren Verarbeitung zur Verfügung.

Die zu sendenen Bytes werden mit Manchestercode codiert und dann übertragen. Ich komme mit meinen Modulen auf eine Rate von ca 200 Bytes / Sekunde. Ncht viel aber für die meisten Sachen reicht das voll und ganz.


Hier der Coder des Senders


'
' Programm überträgt 7 Bytes über ein Funkmodul. Dazu werden die Bytes
' in Manchestercode codiert und eine CRC Prüfsumme berechnet.
' Datenformat: 1 Startbyte, 4 Datenbytes und 2 Bytes mit der CRC Prüfsumme
' Verwendete Funkmodule
' Sender: UHF - FM - Sendemodul SM 433 Frequenz: 433,93 MHz ( von ELV, Bestnr. 16191, Preis 15,95 Euro )
' Empfänger: UHF - FM - Empfangsmodul HFS 526 Frequenz: 433,92 MHZ ( von ELV Bestnr.: 22816, Preis 25,95 Euro )
' Sollte aber auch mit allen anderen Funkmodulen gehen.

'Datenrate: ca 200 Bytes pro Sekunde beim ständigen senden
'Reichweite: in der ganzen Wohnung ohne Probleme, im Freien ??? zu kalt


$regfile = "M32DEF.DAT"
$baud = 19200 'zum Debuggen
$crystal = 7362700

'Deklaration der SUB und Functions
Declare Function Make_manchester(byval Daten As Byte) As Word
Declare Sub Send_code(byval Daten As Word)
Declare Sub Send_start()
Declare Sub Send_byte(byval Daten As Byte , Byval Crc_select As Byte)


Const Crc_poly = &H1021 'CRC Polynom
Const Sync_byte = &B01010100 'Startbyte, kommt aus dem SNAP Prtokoll

'Definition der Variablen
Dim Crc As Word
Dim Tempw_1 As Word
Dim Tempw_2 As Word
Dim Temp As Word
Dim Daten(9) As Byte 'Sendebuffer
Dim Temp1 As Byte
Dim Temp2 As Byte
Dim Zaehler As Byte


'Werte für die Funkübertragung einstellen
Const Bit_zeit = 500 'in us für LOW/HIGH -- > Manchesterbit = 2 * Bitzeit
Const Bit_wait_start = Bit_zeit * 2.5 'Wartezeit zum erkennen des nächsten Bytes
Const Bit_zeit_1_2 = Bit_zeit / 4 'Bitzeit beim einschwingen
Const Anzahl_bit_wechsel = 150 'kommt auf das Modul an


'Einstellen der Ports
Funk Alias Porta.7 'Bezeichner für Funkport
Config Pina.7 = Output 'Port für Funkmodul

Daten(1) = "S"
Daten(2) = "N"
Daten(3) = "A"
Daten(4) = "P"

'Hauptschleife
'Kleine Schleife zum testen des Programms
Do
'Bitmuster zum einschwingen des Funkempfängers senden
Call Send_start()

'Startbyte senden
Call Send_byte(sync_byte , 1)

'4 Datenbytes senden
For Zaehler = 1 To 4
Call Send_byte(daten(zaehler) , 1)
Next Zaehler

'CRC zerlegen und senden
Temp1 = High(crc)
Call Send_byte(temp1 , 0)
Temp1 = Low(crc)
Call Send_byte(temp1 , 0)

'kleine Pause, bis es weiter geht
Wait 2
Loop


End

'+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++
'Unterprogramm zum senden eines Bytes
'Übergabe: Daten, zu sendenes Byte
'crc_select = 0 --> kein CRC, 1 --> mit CRC
'Rückgabe: CRC Wert steht am Schluß in der Variablen crc
Sub Send_byte(byval Daten As Byte , Byval Crc_select As Byte)

If Crc_select = 1 Then 'CRC berechnen = ja ???
Temp1 = Daten
Gosub Calc_crc ' Crc Berechnen
End If
Temp = Make_manchester(daten) 'Variable in Manchester Code umrechnen
Call Send_code(temp) 'und senden

End Sub

'+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++
'Bitwechsel zum einschwingen senden
'Der empfänger braucht eine gewisse Zeit, um sich auf die Frequenz des Senders einzustellen.
'Bei meinen Modulen von ELV, steht im Datenblatt, das sie bis zu 200 ms dafür brauchen.
'Bei einigen Tests haben sich diese Werte als ausreichend herausgestellt.
'Dauer ca 26,6 ms
'Rückgabe: keine
Sub Send_start()
Crc = 0 'Variable für neue CRC berechnung löschen
Local Count As Byte

Count = 0

Do
Set Funk
Waitus Bit_zeit_1_2
Reset Funk
Waitus Bit_zeit_1_2
Incr Count
Loop Until Count = Anzahl_bit_wechsel

Waitus Bit_wait_start 'kleine Pause zum erkennen des Startes

End Sub



'+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++
'Manchester Code ausgeben auf Portpin "Funk", definiert weiter oben
'Hier wird die Variable manchester Bitweise ausgegeben und über den Funksender
'übertragen. Zwischen dem senden einzelner Bytes sollte die Pause nicht größer
'als 500 ms sein, sonst verliert der Empfäger die Frequenz des Senders und die
'Daten sind verloren.
'Vor dem ersten senden von Daten, muß mit dem Aufruf send_start() erstmal die
'Bitmuster zum einschwingen gesendet werden.
'Dauer ca 9,7 ms
'Übergabe: zu sendene Variable (word) Manchestercodiert
'Rückgabe: keine
Sub Send_code(byval Daten As Word)

Local Bit_number As Byte

'Startbit senden
Set Funk
Waitus Bit_zeit

'Anzahl der zu übertragenen Bits
Bit_number = 16

Do
Decr Bit_number

'Bit abfragen und reagieren
If Daten.bit_number = 1 Then
Set Funk
Else
Reset Funk
End If

'benötigte Zeit warten
Waitus Bit_zeit

Loop Until Bit_number = 0

Reset Funk

'kleine Pause, damit der Empfäger das Ende/Start erkennen kann
Waitus Bit_wait_start

End Sub


'+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++
'Umrechnen eiens Bytes in Manchester Code
'Hier wird das übergebene Byte mit Manchestercode codiert.
'Dauer ca
' Übergabe: byte, umzurechene Byte
' Rückgabe: word, umgerechnete Variable
Sub Make_manchester(byval Daten As Byte)

Local Bit_number As Byte
Local Manchester As Word

'Anzahl der zu umzurechnen Bits
Bit_number = 8

Do
Shift Manchester , Left , 2
Decr Bit_number

If Daten.bit_number = 1 Then
Manchester = Manchester + 1 '01
Else
Manchester = Manchester + 2 '10
End If

Loop Until Bit_number = 0

Make_manchester = Manchester
End Sub


'+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++
'Routine zum berechnen der CRC 16 Cecksumme, aus Bascom Buch
'Crc steht am Ende in der Varablen crc
'Übergabe: umzurechene Variable in temp1
Calc_crc:

Tempw_1 = Temp1 * 256
Crc = Tempw_1 Xor Crc
For Temp2 = 0 To 7
If Crc.15 = 0 Then Goto Shift_only
Tempw_2 = Crc * 2
Crc = Tempw_2 Xor Crc_poly
Goto Nxt

Shift_only:
Crc = Crc * 2

Nxt:
Next

Return





und der Empfänger



'Programm zum empfangen der Temperatur, welches über Funk übertragen wird.

'Ein paar Berehnungen anstellen
Const Takt = 4 * 10 ^ 6 '4 MHZ
Const Reload = 256 'Timerreload


$regfile = "M8DEF.DAT"
$baud = 19200
$crystal = Takt


'Ein paar Werte für die Empfangsroutine berechnen
Const Pulse_soll = 1 * 10 ^ -3 'Bitzeit für ein Manchesterbit 01 / 10 in ms
Const Pulse_min_temp = Takt / Reload * Pulse_soll * 0.4 * 0.8
Const Pulse_1_2_temp = Takt / Reload * Pulse_soll * 0.8 * 0.8
Const Pulse_max_temp = Takt / Reload * Pulse_soll * 1.2 * 0.8

Const Start_bit = 8 '9 Bit ist das Startbit, muß 1 sein
Const Pruef_bit = Start_bit + 1 '10 Bit ist ein Prüfbit, muß immer 0 sein
Const Timer0_reload = - Reload '--> 65535 - reload
Const Crc_poly = &H1021
Const Sync_byte = &B01010100
Const Byte_counter = 7 'Anzahl der zu empfangenen Bytes


'Definition der Variablen
Dim Daten_temp As Word
Dim Crc As Word
Dim Tempw_1 As Word
Dim Tempw_2 As Word
'wegen dem Typcast, ungeschickt, aber sonst geht es nicht
Dim Pulse_min As Byte
Dim Pulse_1_2 As Byte
Dim Pulse_max As Byte
Pulse_min = Pulse_min_temp
Pulse_1_2 = Pulse_1_2_temp
Pulse_max = Pulse_max_temp
Dim Daten As Byte
Dim Signal_count As Byte
Dim Signal_old As Byte 'Merker für BIT Zustand
Dim Zaehler As Byte
Dim Daten_buffer(8) As Byte
Dim Temp1 As Byte
Dim Temp2 As Byte
Dim Crc_error_count As Byte
Dim Daten_empfangen As Bit ' Status Register


'Einstellen der Ports ++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++
Signal Alias Pinb.1 'Eingang für Funkmodul
Config Signal = Input
Led Alias Portc.5
Config Pinc.5 = Output



'Timer einstellen, wird noch auf Timer0 geändert +++++++++++++++++++++++++++++++++++
Config Timer0 = Timer , Prescale = 1
On Timer0 Timer0_overflow
Enable Timer0
Enable Interrupts

'Hauptschleife. Wenn ein Byte empfangen wurde, wird geprüft ob es das Startbyte war.
'Wenn ja, dann werden die restichen zu empfangenen Bytes in die Variable Daten_Buffer
'geschoben. Wenn alle Bytes da sind, wird die CRC berechnet berechnet und entschieden,
'ob die Daten gültig sind oder nicht. CRC = 0 --> Daten gültig

Do
If Daten_empfangen = 1 Then 'Daten empfangen

If Daten = Sync_byte Then Zaehler = 1 'Zeiger auf Anfang stellen

Daten_buffer(zaehler) = Daten 'Daten in Buffer schieben
Daten_empfangen = 0 'Status ändern

If Zaehler = Byte_counter Then 'alle Bytes da ???

Gosub Check_crc 'CRC berechnen

If Crc <> 0 Then
'Hier sin die Daten ungültig
Incr Crc_error_count
Print " CRC Error :" ; Crc_error_count
Else
'Ab hier sind die Daten gültig

Zaehler = 1
'Daten ausgeben, ohne Startbyte und die beiden CRC Bytes
Do
Incr Zaehler
Print Chr(daten_buffer(zaehler)) ;
Loop Until Zaehler = 5
Print 'neue Zeile

Zaehler = 0
End If

End If

Daten = 0
Incr Zaehler
End If
Loop

End

'Die CRC Werte der empfangenen Daten berechnen. Am Schluß muß CRC = 0 sein
Check_crc:
Crc = 0
Temp1 = Daten_buffer(1)
Gosub Calc_crc
Temp1 = Daten_buffer(2)
Gosub Calc_crc
Temp1 = Daten_buffer(3)
Gosub Calc_crc
Temp1 = Daten_buffer(4)
Gosub Calc_crc
Temp1 = Daten_buffer(5)
Gosub Calc_crc
Temp1 = Daten_buffer(6)
Gosub Calc_crc
Temp1 = Daten_buffer(7)
Gosub Calc_crc

Return



'+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++
'Routine zum berechnen der CRC 16 Cecksumme, aus Bascom Buch
'Crc steht am Ende in der Varablen crc
'Übergabe: umzurechene Variable in temp1
Calc_crc:

Tempw_1 = Temp1 * 256
Crc = Tempw_1 Xor Crc
For Temp2 = 0 To 7
If Crc.15 = 0 Then Goto Shift_only
Tempw_2 = Crc * 2
Crc = Tempw_2 Xor Crc_poly
Goto Nxt
Shift_only:
Crc = Crc * 2

Nxt:
Next

Return


'Hier werden die Daten empfangen und geprüft auf die Bitzeiten
'Aufruf alle 80 µs
Timer0_overflow:

Timer0 = Timer0_reload
Incr Signal_count


'Ende gefunden oder Signal zu lang
If Signal_count > Pulse_max Then

'Startbit = 1 and Pruef_bit = 0 dann Daten übergeben
If Daten_temp.pruef_bit = 0 And Daten_temp.start_bit = 1 Then
Daten = Daten_temp
Set Daten_empfangen
End If

Daten_temp = 0

End If

'Flankenwechsel ??
If Signal <> Signal_old.1 Then

'neuen Zustand merken
Toggle Signal_old

'Pulse zu kurz ??
If Signal_count < Pulse_min Then Daten_temp = 0



'Start oder Abfragezeitpunkt ??
If Daten_temp = 0 Or Signal_count > Pulse_1_2 Then

'wenn noch nicht zuviele Daten, dann eine Stelle schieben
If Daten_temp.start_bit = 0 Then Shift Daten_temp , Left , 1

'Bit setzen wenn 0, da der Empfänger das Signal um 180° dreht, 0 = 1 1 =0
If Signal_old = 0 Then Incr Daten_temp


Signal_count = 0

End If


End If


Return

Da meine Module mit FM Modulation arbeiten, sind sie nicht ganz so störanfällig wie die Module mit AM Modulation. Dann sollte Mann/Frau mal mit der Bitzeit etwas hoch gehen.

Der Empfang läuft im Timer0 INT ab.

MFG
Dieter

=P~

RCO
28.12.2004, 13:37
Saubere Arbeit! Werde es demnächst mal testen.
Welche Funkmodule genau hast du denn verwendet (Wo gekauft)?

MFG Moritz

28.12.2004, 15:00
Toll, das kann ich bestimmt mal gebrauchen.

@RCO:
Das steht doch ausführlichst im Code. O:)

Gruß
Uwe

RCO
28.12.2004, 16:19
:-# Ich hab nix gesagt ;-)
Da war ich wohl ein wenig voreilig

MFG Moritz

ELJO
12.03.2005, 07:46
Hallo Dino Dieter,
bitte melde dich bei mir unter Email ELJO@gmx.com. Es geht um die Manchester Codierung. Habe ein Unternehmen und könnte dir eventuell nebenher ein paar Aufgaben übermitteln

13.08.2005, 21:31
Hallo Dino Dieter,

super Programm !

ich habe jedoch ein kleines Problem
Wenn ich Dein Programm auf einem µC laufen lasse und mit das Ausgangsignal auf einem Oszi anschaue kommt der Start und 7 einzelne Impulse von ca. 500µs Länge - aber eben alle gleich
Also gesucht und gefunden ...

************************************************** ***********
Sub Send_byte(byval Daten As Byte , Byval Crc_select As Byte)

If Crc_select = 1 Then
Temp1 = Daten
Gosub Calc_crc
End If
Temp = Make_manchester(daten)

Print "manch_daten " ; Make_manchester(daten)
Print "Temp " ; Temp

Call Send_code(temp)

End Sub

************************************************** ***********

folgendes:

das erste Print gibt eine 5 stellige Zahl aus
das zweite Print gibt immer nur 0 aus
wie kann das sein ? funkt da mein Bascom nicht richtig ?

mfg Tobias

13.08.2005, 22:04
Hallo Tobias

Schön das dir das Programm gefällt.


Print "manch_daten " ; Make_manchester(daten)
Print "Temp " ; Temp

bringt bei mir im Simulator die Gleichen Ausgaben für temp & Make_manchester(daten) .


kommt der Start und 7 einzelne Impulse von ca. 500µs Länge

Schau ich mir Morgen mal an.

Klappt die Übertragung denn ?

MFG
Dieter

spatz2222
02.09.2005, 20:38
Hallo Dieter,

nein die Überptragung funkt. auch nicht !!!
mfg Tobias

Goldenflash
03.09.2005, 12:02
Welche Funkmodule genau hast du denn verwendet (Wo gekauft)?


Das würd mich auch mal interessieren...

Gruß Florian

Dino Dieter
03.09.2005, 12:40
Hallo Florian


'
Verwendete Funkmodule
' Sender: UHF - FM - Sendemodul SM 433 Frequenz: 433,93 MHz ( von ELV, Bestnr. 16191, Preis 15,95 Euro )
' Empfänger: UHF - FM - Empfangsmodul HFS 526 Frequenz: 433,92 MHZ ( von ELV Bestnr.: 22816, Preis 25,95 Euro )
' Sollte aber auch mit allen anderen Funkmodulen gehen.

Sollte doch alles sagen. Also die Module sind von ELV und arbeiten mit FSK. Habe jetzt auch die preiswerten von Conrad hier, aber keine Zeit zum testen. Der Code läuft mit den ELV Teilen gut.

Werde die Tage mal die anderen testen, kann aber dauern, da ich im Momnet mit einem Lantronix X-Port spiele.

Vielleicht baue ich mal ein komplettes Modul mit Tiny 45 .


MFG
Dieter

Goldenflash
03.09.2005, 13:36
Oha, das ist mir jetzt aber peinlich! :oops:
Das hab ich zwar gelesen, hatte aber als ich durchwar wieder vergessen was am Anfang stand...
*schäm*

Space Teddy
22.10.2005, 15:35
Hallo,
ich habe da nochmal ne frage zu dem Programm.
Jedenfalls habe ich das Sendemodul Easy TX 868 FM und das Empfängermodul Easy RX 868 FM von http://www.ikhf.de .
habe das Sendeprogramm auf einen 2313 mit 7,3728Mhz laufen und das Empfängerprogramm auf einen mega163 mit den angegebenen 4MHz.
Ich habe nur die Portpin´s angepasst, aber leider funktioniert das leider mit der Übertragung nicht so ganz. Mit dem Oszi kann ich sehen, das eine bitfolge gesendet wird, welche auch am Empfänger ankommt.
Das Empfängerprogramm zeigt aber nicht an. Scheint so als würde der mega168 die Bits nicht richtig erkennen zu können.

If Daten_empfangen = 1 Then 'Daten empfangen

bleibt immer "0"

Laut Beschreibung wird die Erkennung der bits hier gemacht:

'Hier werden die Daten empfangen und geprüft auf die Bitzeiten
'Aufruf alle 80 µs
Timer0_overflow:

Timer0 = Timer0_reload
Incr Signal_count


'Ende gefunden oder Signal zu lang
If Signal_count > Pulse_max Then

'Startbit = 1 and Pruef_bit = 0 dann Daten übergeben
If Daten_temp.pruef_bit = 0 And Daten_temp.start_bit = 1 Then
Daten = Daten_temp
Set Daten_empfangen
End If

Daten_temp = 0

End If

'Flankenwechsel ??
If Signal <> Signal_old.1 Then

'neuen Zustand merken
Toggle Signal_old

'Pulse zu kurz ??
If Signal_count < Pulse_min Then Daten_temp = 0

'Start oder Abfragezeitpunkt ??
If Daten_temp = 0 Or Signal_count > Pulse_1_2 Then

'wenn noch nicht zuviele Daten, dann eine Stelle schieben
If Daten_temp.start_bit = 0 Then Shift Daten_temp , Left , 1

'Bit setzen wenn 0, da der Empfänger das Signal um 180° dreht, 0 = 1 1 =0
If Signal_old = 0 Then Incr Daten_temp
Signal_count = 0
End If
End If
Return


... aber wo genau wird denn der Port abgefragt, der ja hier definiert wird:

'Einstellen der Ports
++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++
Signal Alias Pinb.1 'Eingang für Funkmodul
Config Signal = Input
-----------------------------------------------

wenn jemand diesen Thread noch ließt, bitte melden, ob es jemand geschafft hat das programm zum laufen zu bekommen.
vielen dank

22.10.2005, 15:41
Hallo


Das Signal wird an dieser Stelle "eingelesen"


'Flankenwechsel ??
If Signal <> Signal_old.1 Then

Ist ja oben defieniert


'Einstellen der Ports ++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++
Signal Alias Pinb.1 'Eingang für Funkmodul



MFG
Dieter

Space Teddy
23.10.2005, 11:28
Hallo Dieter,
vielen Dank für deine Antwort. Entschuldige bitte wenn ich noch ein, zwei Fragen stelle. Bin wirklich sehr interessiert daran und grübele und probiere schon fast eine Woche, das es bei mir läuft.

a) Du benutzt ja für den Sender und Empfänger jeweils einen Mega8, bzw m32. Denkst du das es einen Unterschied macht, wenn ich für den Sender einen 2313 und für den Empfänger einen mega 163 nehme? ich denke nicht, aber vieleicht ist es doch nicht egal.
Dann benutze ich einen anderen Quarz wie du. In deinem projekt ist für den Sender ein $crystal = 7362700 drin. Ich benutze einen 7.3728MHz Quarz. Muß ich noch auf der Empfängerseite Timings anpassen? -> ich denke auch wieder nicht, da du die bitzeiten ja mit "waitus bitzeit" einstellst.

b)
zum debuggen habe ich den empfänger nicht an der seriellen Schnittstelle angeschlossen, sondern die Ausgaben kommen über ein LCD mit der standard Bascom Ansteuerung. Denkst du das die LCD ansterung das timing verfäschen könnte?

c)
Ich sehe beim debuggen, das die variable Daten_empfangen immer 0 bleibt und dementsprechend nix ankommt, mit dem scope sieht man aber am portpin, das die daten da sind. Hast du noch eine Idee, wie ich weiter debuggen kann?

d) besteht bei 434mhz und 863mhz ein prinzipieller unterscheid beim senden und empfangen?

hoffe du nimmst dir paar minuten zeit um mir zu helfen.

Vielen dank

mfg

Christian

23.10.2005, 12:00
Hallo

Die µC sollten egal sein, sofern sie die benötigten Hardware Module enthalten.

Macht dein Empfangsmodul denn eine Phasendrehung des Signals ? Bei meinen Modulen wirde das Signal um 180° Grad gedreht.


'Bit setzen wenn 0, da der Empfänger das Signal um 180° dreht, 0 = 1 1 =0
If Signal_old = 0 Then Incr Daten_temp

Wenn dein Signal keine Phasendrehung macht, probier es mal so


'Bit setzen wenn 0, da der Empfänger das Signal um 180° dreht, 0 = 1 1 =0
If Signal_old = 1 Then Incr Daten_temp


Teste auch mal, ob die Signallängen zwischen Sender und Empfänger verändert werden.

Die Empfangsroutine beruht auf dem Code von Peter Dannegger aus diesem Thread

http://www.mikrocontroller.net/forum/read-4-74473.html#247053


zu b) Da die Senderoutinen ja über waitus geproggt sind, sehe ich da kein Problem, solnage kein Int. dawischen funkt.

zu c) Lass dir nach

'Flankenwechsel ??
If Signal <> Signal_old.1 Then

mal die Variable Signal_Count ausgeben. Entspricht ja der Länge des Impluses



MFG
Dieter

Space Teddy
23.10.2005, 13:02
hallo Dieter,
toll das du so schnell antwortest.

das mit dem invertierten Signal habe ich auch schon probiert, aber daran lag es nicht.

die "signal_count habe ich auch schon ausgegeben:



Flankenwechsel! 0
Pulse zu kurz -> Signal_count=238
Flankenwechsel! 1
Pulse zu kurz -> Signal_count=1
Flankenwechsel! 0
Pulse zu kurz -> F F F F F F F F F Fl Fl F Fl Fl F F F F F F Fl F F Flan F F Flankenwechsel! 0
Pulse zu kurz -> Signal_count=5
Flankenwechsel! 1
Pulse zu kurz -> Signal_count=2
Flankenwechsel! 0
Pulse zu kurz -> Sig F F F F F F F F F Fl Fl F Fl Fl F F F F F F Fl F F Flan F F Flankenwechsel! 0
Pulse zu kurz -> Signal_count=5
Flankenwechsel! 1
Pulse zu kurz -> Signal_count=2
Flankenwechsel! 0
Pulse zu kurz -> Sig F F F F F F F F F Fl Fl F Fl Fl F F F F F F Fl F F Flan F F Flankenwechsel! 0
Pulse zu kurz -> Signal_count=5
Flankenwechsel! 1
Pulse zu kurz -> Signal_count=3
Flankenwechsel! 0
Pulse zu kurz -> Sig F F F F F F F F Fl Fl F Fl Fl F F F F F F Fl F F Flan F F Flankenwechsel! 0
Pulse zu kurz -> Signal_count=5
Flankenwechsel! 1
Pulse zu kurz -> Signal_count=2
Flankenwechsel! 0
Pulse zu kurz -> Sig F F F F F F F F Fl Fl F Fl Fl F F F F F F Fl F F Flan F F



dies sind kleine Werte , Pulse_min_temp ist IHMO auf 5 eingestellt.
Signal_count ist aber manchmal auch höher. 6-7.

ich klemme mal alle pins von den interrupt eingängen ab, mal sehen, ob es etwas besser wird.

vielen dank schon einmal

mfg.

Space Teddy
24.10.2005, 18:40
Hallo Dieter,
habe den Sender un empänger mal mit in die Firma geschleppt um zu sehen, ob die Übertragung prinzipiell richtig funktioniert. bild -> daten.png

Die Einschwingpulse liegen bei ca. 125us oder gesamte Periodendauer 250us.
siehe bild einschwingen.png

man sieht, der Empfänger macht keine Phasendrehung:
051024_113951.png

Hier nochmal die startbits ausgezoomt
051024_114026.png

sieht also alles sehr gut aus. Ich schaue mir nochmal die empfangsroutine an.

mfg.

Dino Dieter
24.10.2005, 21:12
Hallo

So wie es aussieht, sind deine signal_count zu kurz. Poste mal deinen Code hier rein.

Sobald ein signal_count unter 5 empfangen wird, werden die empfangen Bits ja wieder verworfen und von neuem angefangen. Der Timer Int sollte ja alle 64 µs kommen, bitte mal prüfen.

MFG
Dieter

Space Teddy
24.10.2005, 21:34
Hi Dieter,

also der code ist so gut wie 100% deiner.

Sendecode:



$regfile = "2313DEF.DAT"
$baud = 19200 'zum Debuggen
$crystal = 7362700

'Deklaration der SUB und Functions
Declare Function Make_manchester(byval Daten As Byte) As Word
Declare Sub Send_code(byval Daten As Word)
Declare Sub Send_start()
Declare Sub Send_byte(byval Daten As Byte , Byval Crc_select As Byte)


Const Crc_poly = &H1021 'CRC Polynom
Const Sync_byte = &B01010100 'Startbyte, kommt aus dem SNAP Prtokoll

'Definition der Variablen
Dim Crc As Word
Dim Tempw_1 As Word
Dim Tempw_2 As Word
Dim Temp As Word
Dim Daten(9) As Byte 'Sendebuffer
Dim Temp1 As Byte
Dim Temp2 As Byte
Dim Zaehler As Byte


'Werte für die Funkübertragung einstellen
Const Bit_zeit = 500 'in us für LOW/HIGH -- > Manchesterbit = 2 * Bitzeit
Const Bit_wait_start = Bit_zeit * 2.5 'Wartezeit zum erkennen des nächsten Bytes
Const Bit_zeit_1_2 = Bit_zeit / 4 'Bitzeit beim einschwingen
Const Anzahl_bit_wechsel = 150 'kommt auf das Modul an


'Einstellen der Ports
Funk Alias Portb.4 'Bezeichner für Funkport
Config Pinb.4 = Output 'Port für Funkmodul

Daten(1) = "S"
Daten(2) = "N"
Daten(3) = "A"
Daten(4) = "P"

'Hauptschleife
'Kleine Schleife zum testen des Programms
Do
'Bitmuster zum einschwingen des Funkempfängers senden
Call Send_start()

'Startbyte senden
Call Send_byte(sync_byte , 1)

'4 Datenbytes senden
For Zaehler = 1 To 4
Call Send_byte(daten(zaehler) , 1)
Next Zaehler

'CRC zerlegen und senden
Temp1 = High(crc)
Call Send_byte(temp1 , 0)
Temp1 = Low(crc)
Call Send_byte(temp1 , 0)

'kleine Pause, bis es weiter geht
Wait 2
Loop


End

'+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++
'Unterprogramm zum senden eines Bytes
'Übergabe: Daten, zu sendenes Byte
'crc_select = 0 --> kein CRC, 1 --> mit CRC
'Rückgabe: CRC Wert steht am Schluß in der Variablen crc
Sub Send_byte(byval Daten As Byte , Byval Crc_select As Byte)

If Crc_select = 1 Then 'CRC berechnen = ja ???
Temp1 = Daten
Gosub Calc_crc ' Crc Berechnen
End If
Temp = Make_manchester(daten) 'Variable in Manchester Code umrechnen
Call Send_code(temp) 'und senden

End Sub

'+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++
'Bitwechsel zum einschwingen senden
'Der empfänger braucht eine gewisse Zeit, um sich auf die Frequenz des Senders einzustellen.
'Bei meinen Modulen von ELV, steht im Datenblatt, das sie bis zu 200 ms dafür brauchen.
'Bei einigen Tests haben sich diese Werte als ausreichend herausgestellt.
'Dauer ca 26,6 ms
'Rückgabe: keine
Sub Send_start()
Crc = 0 'Variable für neue CRC berechnung löschen
Local Count As Byte

Count = 0

Do
Set Funk
Waitus Bit_zeit_1_2
Reset Funk
Waitus Bit_zeit_1_2
Incr Count
Loop Until Count = Anzahl_bit_wechsel

Waitus Bit_wait_start 'kleine Pause zum erkennen des Startes

End Sub



'+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++
'Manchester Code ausgeben auf Portpin "Funk", definiert weiter oben
'Hier wird die Variable manchester Bitweise ausgegeben und über den Funksender
'übertragen. Zwischen dem senden einzelner Bytes sollte die Pause nicht größer
'als 500 ms sein, sonst verliert der Empfäger die Frequenz des Senders und die
'Daten sind verloren.
'Vor dem ersten senden von Daten, muß mit dem Aufruf send_start() erstmal die
'Bitmuster zum einschwingen gesendet werden.
'Dauer ca 9,7 ms
'Übergabe: zu sendene Variable (word) Manchestercodiert
'Rückgabe: keine
Sub Send_code(byval Daten As Word)

Local Bit_number As Byte

'Startbit senden
Set Funk
Waitus Bit_zeit

'Anzahl der zu übertragenen Bits
Bit_number = 16

Do
Decr Bit_number

'Bit abfragen und reagieren
If Daten.bit_number = 1 Then
Set Funk
Else
Reset Funk
End If

'benötigte Zeit warten
Waitus Bit_zeit

Loop Until Bit_number = 0

Reset Funk

'kleine Pause, damit der Empfäger das Ende/Start erkennen kann
Waitus Bit_wait_start

End Sub


'+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++
'Umrechnen eiens Bytes in Manchester Code
'Hier wird das übergebene Byte mit Manchestercode codiert.
'Dauer ca
' Übergabe: byte, umzurechene Byte
' Rückgabe: word, umgerechnete Variable
Sub Make_manchester(byval Daten As Byte)

Local Bit_number As Byte
Local Manchester As Word

'Anzahl der zu umzurechnen Bits
Bit_number = 8

Do
Shift Manchester , Left , 2
Decr Bit_number

If Daten.bit_number = 1 Then
Manchester = Manchester + 1 '01
Else
Manchester = Manchester + 2 '10
End If

Loop Until Bit_number = 0

Make_manchester = Manchester
End Sub


'+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++
'Routine zum berechnen der CRC 16 Cecksumme, aus Bascom Buch
'Crc steht am Ende in der Varablen crc
'Übergabe: umzurechene Variable in temp1
Calc_crc:
'Crc = Crc16(temp1 , 8)
Tempw_1 = Temp1 * 256
Crc = Tempw_1 Xor Crc
For Temp2 = 0 To 7
If Crc.15 = 0 Then Goto Shift_only
Tempw_2 = Crc * 2
Crc = Tempw_2 Xor Crc_poly
Goto Nxt

Shift_only:
Crc = Crc * 2

Nxt:
Next

Return


Empfangscode:


Const Takt = 4 * 10 ^ 6 '4 MHZ
Const Reload = 256 'Timerreload


$regfile = "m163DEF.DAT"
$baud = 19200
$crystal = Takt

Config Serialout = Buffered , Size = 200

'Ein paar Werte für die Empfangsroutine berechnen
Const Pulse_soll = 1 * 10 ^ -3 'Bitzeit für ein Manchesterbit 01 / 10 in ms
Const Pulse_min_temp = Takt / Reload * Pulse_soll * 0.4 * 0.8
Const Pulse_1_2_temp = Takt / Reload * Pulse_soll * 0.8 * 0.8
Const Pulse_max_temp = Takt / Reload * Pulse_soll * 1.2 * 0.8

Const Start_bit = 8 '9 Bit ist das Startbit, muß 1 sein
Const Pruef_bit = Start_bit + 1 '10 Bit ist ein Prüfbit, muß immer 0 sein
Const Timer0_reload = - Reload '--> 65535 - reload
Const Crc_poly = &H1021
Const Sync_byte = &B01010100
Const Byte_counter = 7 'Anzahl der zu empfangenen Bytes


'Definition der Variablen
Dim Daten_temp As Word
Dim Crc As Word
Dim Tempw_1 As Word
Dim Tempw_2 As Word
'wegen dem Typcast, ungeschickt, aber sonst geht es nicht
Dim Pulse_min As Byte
Dim Pulse_1_2 As Byte
Dim Pulse_max As Byte
Pulse_min = Pulse_min_temp
Pulse_1_2 = Pulse_1_2_temp
Pulse_max = Pulse_max_temp
Dim Daten As Byte
Dim Signal_count As Byte
Dim Signal_old As Byte 'Merker für BIT Zustand
Dim Zaehler As Byte
Dim Daten_buffer(8) As Byte
Dim Temp1 As Byte
Dim Temp2 As Byte
Dim Crc_error_count As Byte
Dim Daten_empfangen As Bit ' Status Register


'Einstellen der Ports ++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++
Signal Alias Pina.2 'Eingang für Funkmodul
Config Signal = Input
'Led Alias Porta.2
'Config Pina.2 = Output



'Timer einstellen, wird noch auf Timer0 geändert +++++++++++++++++++++++++++++++++++
Config Timer0 = Timer , Prescale = 1
On Timer0 Timer0_overflow
Enable Timer0
Enable Interrupts

'Hauptschleife. Wenn ein Byte empfangen wurde, wird geprüft ob es das Startbyte war.
'Wenn ja, dann werden die restichen zu empfangenen Bytes in die Variable Daten_Buffer
'geschoben. Wenn alle Bytes da sind, wird die CRC berechnet berechnet und entschieden,
'ob die Daten gültig sind oder nicht. CRC = 0 --> Daten gültig

Print "Funkempfänger 0.1b (c)"
Print "Pulse_min_temp=" ; Pulse_min_temp
Print "Pulse_max_temp=" ; Pulse_max_temp
Print "Pulse_soll=" ; Pulse_soll
Print "Pulse_1_2_temp=" ; Pulse_1_2_temp

Do
If Daten_empfangen = 1 Then 'Daten empfangen

If Daten = Sync_byte Then Zaehler = 1 'Zeiger auf Anfang stellen

Daten_buffer(zaehler) = Daten 'Daten in Buffer schieben
Daten_empfangen = 0 'Status ändern

If Zaehler = Byte_counter Then 'alle Bytes da ???

Gosub Check_crc 'CRC berechnen

If Crc <> 0 Then
'Hier sin die Daten ungültig
Incr Crc_error_count
Print " CRC Error :" ; Crc_error_count
Else
'Ab hier sind die Daten gültig

Zaehler = 1
'Daten ausgeben, ohne Startbyte und die beiden CRC Bytes
Do
Incr Zaehler
Print "Datenausgabe= " ; Chr(daten_buffer(zaehler)) ;
Loop Until Zaehler = 5
Print 'neue Zeile

Zaehler = 0
End If

End If

Daten = 0
Incr Zaehler
End If
Loop

End

'Die CRC Werte der empfangenen Daten berechnen. Am Schluß muß CRC = 0 sein
Check_crc:
Crc = 0
Temp1 = Daten_buffer(1)
Gosub Calc_crc
Temp1 = Daten_buffer(2)
Gosub Calc_crc
Temp1 = Daten_buffer(3)
Gosub Calc_crc
Temp1 = Daten_buffer(4)
Gosub Calc_crc
Temp1 = Daten_buffer(5)
Gosub Calc_crc
Temp1 = Daten_buffer(6)
Gosub Calc_crc
Temp1 = Daten_buffer(7)
Gosub Calc_crc

Return



'+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++
'Routine zum berechnen der CRC 16 Cecksumme, aus Bascom Buch
'Crc steht am Ende in der Varablen crc
'Übergabe: umzurechene Variable in temp1
Calc_crc:

Tempw_1 = Temp1 * 256
Crc = Tempw_1 Xor Crc
For Temp2 = 0 To 7
If Crc.15 = 0 Then Goto Shift_only
Tempw_2 = Crc * 2
Crc = Tempw_2 Xor Crc_poly
Goto Nxt
Shift_only:
Crc = Crc * 2
Nxt:
Next

'Crc = Crc16(temp1 , 8) 'Alternetive zu manuell
Return


'Hier werden die Daten empfangen und geprüft auf die Bitzeiten
'Aufruf alle 80 µs
Timer0_overflow:

Timer0 = Timer0_reload
Incr Signal_count


'Ende gefunden oder Signal zu lang
If Signal_count > Pulse_max Then

'Startbit = 1 and Pruef_bit = 0 dann Daten übergeben
If Daten_temp.pruef_bit = 0 And Daten_temp.start_bit = 1 Then
Daten = Daten_temp
Set Daten_empfangen
End If

Daten_temp = 0

End If

'Flankenwechsel ??
If Signal <> Signal_old.1 Then
Print " Flankenwechsel! " ; Signal_old.1
'neuen Zustand merken
Toggle Signal_old

'Pulse zu kurz ??
If Signal_count < Pulse_min Then Daten_temp = 0 : Print "Pulse zu kurz -> Signal_count=" ; Signal_count


'Start oder Abfragezeitpunkt ??
If Daten_temp = 0 Or Signal_count > Pulse_1_2 Then

'wenn noch nicht zuviele Daten, dann eine Stelle schieben
If Daten_temp.start_bit = 0 Then Shift Daten_temp , Left , 1

'Bit setzen wenn 0, da der Empfänger das Signal um 180° dreht, 0 = 1 1 =0 -> nicht notwendig
If Signal_old = 1 Then Incr Daten_temp ' hier 1 da receiver keine Phasenverschiebung macht


Signal_count = 0

End If


End If


Return


mfg.

Chris

24.10.2005, 22:09
Hallo

Deine Debug Ausgaben sind nach meinem Geschmack zu lang. Ich nehme dafür immer nur ein Zeichen, damit es schnell geht, auch mit Sendebuffer.



'Hier werden die Daten empfangen und geprüft auf die Bitzeiten
'Aufruf alle 80 µs
Timer0_overflow:

Timer0 = Timer0_reload
Incr Signal_count


'Ende gefunden oder Signal zu lang
If Signal_count > Pulse_max Then
print "A"
'Startbit = 1 and Pruef_bit = 0 dann Daten übergeben
If Daten_temp.pruef_bit = 0 And Daten_temp.start_bit = 1 Then
Print "B"
Daten = Daten_temp
Set Daten_empfangen
End If

Daten_temp = 0

End If

'Flankenwechsel ??
If Signal <> Signal_old.1 Then
Print Signal_count

'neuen Zustand merken
Toggle Signal_old

'Pulse zu kurz ??
If Signal_count < Pulse_min Then
Daten_temp = 0
Print "C"
End if


'Start oder Abfragezeitpunkt ??
If Daten_temp = 0 Or Signal_count > Pulse_1_2 Then
print "D"
'wenn noch nicht zuviele Daten, dann eine Stelle schieben
If Daten_temp.start_bit = 0 Then
Shift Daten_temp , Left , 1
Print "E"
End if

'Bit setzen wenn 0, da der Empfänger das Signal um 180° dreht, 0 = 1 1 =0 -> nicht notwendig
If Signal_old = 1 Then
Incr Daten_temp ' hier 1 da receiver keine Phasenverschiebung macht
Print "F"
end if


Signal_count = 0

End If


End If


Return


Probier das mal so

MFG
Dieter

Space Teddy
31.10.2005, 17:17
Hallo Dieter,

also ich habe es nochmal ohne Funk sondern mit einer drahtverbindung probiert. leider hat es auch nicht geklappt. es wundert mich wirklich das es bei dir funktioniert. könntest du mir vieleicht mal dein komplettprogramm an spaceteddy1@gmx.net schicken? vieleicht wurde ja was übersehen.
ansonsten versuche ich mal eine biterkennung über int0 zu verwirklichen.

vielen dank

mfg.
chris

Dino Dieter
01.11.2005, 09:49
Hallo chris


So, jetzt mich mein Ehrgeiz gepackt und ich habe die Schaltung noch mal aufgebaut. Habe den Code von ganz oben genommen und .... er geht nicht. Mann Mann Mann welch eine Blamage.


Nun ja, ein wenig geforscht und jetzt geht es. Fehler ??

Die Taktfrequenz des Empfängers stimmt nicht. Die 4 MHz die ich oben angegeben habe passen nicht. Dadurch wird die Abtastung der empfangenen Signale zu ungenau. Habe den Takt auf 16 MHz erhöht und jetzt läuft es wie gewollt.

Auch haben keine Print Befehle in der Timer0 Int. Routine was zu suchen, da sie den Abtastintervall aus dem Takt bringen. ( Höchstens zum debuggen, dann werden aber keine gültigen Daten mehr empfangen )

Die Signale :

Das Signal wird alle 19,3 µs abgetastet. Bascom braucht 53 Takte zum Einsprung in die Int Routine. 16 MHz / ( 256 +53) -- > 19,3 µs.

Alle Signale kürzer 386 µs werden verworfen à Puls_min = 20
Das Nutzbit wird nach 772 µs abgetastet à Puls_1_2 = 40
Alle Signale länger als 1158 µs werden verworfen. Puls_max = 60


Du musst halt nur die Taktfrequenz ändern und der Empfangroutine ändern, das du ein nicht invertierendes Empfangssignal hast, dann sollte es laufen.


Für die Zeit und den Ärger den ich dir verursacht habe, entschuldige ich mich .

Deine Idee, das Empfangssignal mit einem Int0 zu erfassen, halte ich nicht für klug. Beim rauschen des Empfängers bekommt dein AVR so viele Int Anforderungen, das er sonst nicht mehr viel machen kann.

Mit freundlichen Grüßen
Dieter

Space Teddy
01.11.2005, 11:59
Hallo Dieter,

super, das du dich nochmal genau hingeschaut hast. Ok, ich habe jetzt viel Zeit damit verbracht, aber ich sehe das jetzt nicht als schlimm an, da man daraus immer wieder was lernt und das habe ich definitiv :)
Ich versuche dann mal den Takt zu erhöhen, aber leider habe ich nur einen 2313 10Mhz, mal sehen, ob er mit 16Mhz noch arbeitet. Zum kurzzeitigen testen mache ich erstmal einen 11,xMhz quarz rein. Dann liege ich wenigstens so halb in der spec vom 2313.
So, mit 11MHz geht es auch noch nicht. JEtzt bestelle ich mir erstmal nen 16MHz quarz.

Vielen Dank nochmal.

melde mich dann

Space Teddy
05.11.2005, 13:34
hallo dieter,

Ich versuche momentan das programm so umzuschreiben, damit es auch mit einem 8Mhz quarz passt.

Hier ist das fertige und überprüfte Programm:

Sender:


$regfile = "2313DEF.DAT"
$baud = 19200 'zum Debuggen
$crystal = 7362700

'Config Serialout = Buffered , Size = 20

'Deklaration der SUB und Functions
Declare Function Make_manchester(byval Daten As Byte) As Word
Declare Sub Send_code(byval Daten As Word)
Declare Sub Send_start()
Declare Sub Send_byte(byval Daten As Byte , Byval Crc_select As Byte)


Const Crc_poly = &H1021 'CRC Polynom
Const Sync_byte = &B01010100 'Startbyte, kommt aus dem SNAP Prtokoll

'Definition der Variablen
Dim Crc As Word
Dim Tempw_1 As Word
Dim Tempw_2 As Word
Dim Temp As Word
Dim Daten(9) As Byte 'Sendebuffer
Dim Temp1 As Byte
Dim Temp2 As Byte
Dim Zaehler As Byte
Dim A As Byte

'Werte für die Funkübertragung einstellen
Const Bit_zeit = 1000 'in us für LOW/HIGH -- > Manchesterbit = 2 * Bitzeit
'original = 500
Const Bit_wait_start = Bit_zeit * 2.5 'Wartezeit zum erkennen des nächsten Bytes
Const Bit_zeit_1_2 = Bit_zeit / 4 'Bitzeit beim einschwingen
Const Anzahl_bit_wechsel = 50 'kommt auf das Modul an hier 150
'geändert auf 10 da 1000us/4=250us*10=2,5ms
'Empfänger braucht 1,6ms zum einschwingen


'Einstellen der Ports
Funk Alias Portd.6 'Bezeichner für Funkport
Config Pind.6 = Output 'Port für Funkmodul
'Enable Interrupts

Daten(1) = "S"
Daten(2) = "N"
Daten(3) = "A"
Daten(4) = "P"

'Hauptschleife
'Kleine Schleife zum testen des Programms

Print "Transmitter 1.0"
Wait 1

Do
'Bitmuster zum einschwingen des Funkempfängers senden
Call Send_start()

'Startbyte senden
Call Send_byte(sync_byte , 1)

'4 Datenbytes senden
For Zaehler = 1 To 4
Call Send_byte(daten(zaehler) , 1)
'Print Daten(zaehler)
Next Zaehler

'CRC zerlegen und senden
Temp1 = High(crc)
Call Send_byte(temp1 , 0)
Temp1 = Low(crc)
Call Send_byte(temp1 , 0)

'kleine Pause, bis es weiter geht
Wait 1
Loop


End

'+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++
'Unterprogramm zum senden eines Bytes
'Übergabe: Daten, zu sendenes Byte
'crc_select = 0 --> kein CRC, 1 --> mit CRC
'Rückgabe: CRC Wert steht am Schluß in der Variablen crc
Sub Send_byte(byval Daten As Byte , Byval Crc_select As Byte)

If Crc_select = 1 Then 'CRC berechnen = ja ???
Temp1 = Daten
Gosub Calc_crc ' Crc Berechnen
End If
Temp = Make_manchester(daten) 'Variable in Manchester Code umrechnen
Call Send_code(temp) 'und senden

End Sub

'+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++
'Bitwechsel zum einschwingen senden
'Der empfänger braucht eine gewisse Zeit, um sich auf die Frequenz des Senders einzustellen.
'Bei meinen Modulen von ELV, steht im Datenblatt, das sie bis zu 200 ms dafür brauchen.
'Bei einigen Tests haben sich diese Werte als ausreichend herausgestellt.
'Dauer ca 26,6 ms
'Rückgabe: keine
Sub Send_start()
Crc = 0 'Variable für neue CRC berechnung löschen
Local Count As Byte

Count = 0

Do
Set Funk
Waitus Bit_zeit_1_2
Reset Funk
Waitus Bit_zeit_1_2
Incr Count
Loop Until Count = Anzahl_bit_wechsel

Waitus Bit_wait_start 'kleine Pause zum erkennen des Startes

End Sub



'+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++
'Manchester Code ausgeben auf Portpin "Funk", definiert weiter oben
'Hier wird die Variable manchester Bitweise ausgegeben und über den Funksender
'übertragen. Zwischen dem senden einzelner Bytes sollte die Pause nicht größer
'als 500 ms sein, sonst verliert der Empfäger die Frequenz des Senders und die
'Daten sind verloren.
'Vor dem ersten senden von Daten, muß mit dem Aufruf send_start() erstmal die
'Bitmuster zum einschwingen gesendet werden.
'Dauer ca 9,7 ms
'Übergabe: zu sendene Variable (word) Manchestercodiert
'Rückgabe: keine
Sub Send_code(byval Daten As Word)

Local Bit_number As Byte

'Startbit senden
Set Funk
Waitus Bit_zeit

'Anzahl der zu übertragenen Bits
Bit_number = 16

Do
Decr Bit_number

'Bit abfragen und reagieren
If Daten.bit_number = 1 Then
Set Funk
Else
Reset Funk
End If

'benötigte Zeit warten
Waitus Bit_zeit

Loop Until Bit_number = 0

Reset Funk

'kleine Pause, damit der Empfäger das Ende/Start erkennen kann
Waitus Bit_wait_start

End Sub


'+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++
'Umrechnen eiens Bytes in Manchester Code
'Hier wird das übergebene Byte mit Manchestercode codiert.
'Dauer ca
' Übergabe: byte, umzurechene Byte
' Rückgabe: word, umgerechnete Variable
Sub Make_manchester(byval Daten As Byte)

Local Bit_number As Byte
Local Manchester As Word

'Anzahl der zu umzurechnen Bits
Bit_number = 8

Do
Shift Manchester , Left , 2
Decr Bit_number

If Daten.bit_number = 1 Then
Manchester = Manchester + 1 '01
Else
Manchester = Manchester + 2 '10
End If

Loop Until Bit_number = 0

Make_manchester = Manchester
End Sub


'+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++
'Routine zum berechnen der CRC 16 Cecksumme, aus Bascom Buch
'Crc steht am Ende in der Varablen crc
'Übergabe: umzurechene Variable in temp1
Calc_crc:

Tempw_1 = Temp1 * 256
Crc = Tempw_1 Xor Crc
For Temp2 = 0 To 7
If Crc.15 = 0 Then Goto Shift_only
Tempw_2 = Crc * 2
Crc = Tempw_2 Xor Crc_poly
Goto Nxt
Shift_only:
Crc = Crc * 2
Nxt:
Next

Return


Empfänger:


'-------------------------------------------------------------------------------
' Datenübertragung Empfangsroutine
'-------------------------------------------------------------------------------

'Ein paar Berehnungen anstellen
Const Takt = 8000000 '8 MHZ
Const Reload = 256 'Timerreload


$regfile = "2313DEF.DAT"
$baud = 38400
$crystal = Takt

Config Serialout = Buffered , Size = 20

'Ein paar Werte für die Empfangsroutine berechnen
Const Pulse_soll = 2 * 10 ^ -3 'Bitzeit für ein Manchesterbit 01 / 10 in ms
'Pulse_soll muß doppelt so hoch sein wie "Bit_zeit" im Sender
Const Pulse_min_temp = Takt / Reload * Pulse_soll * 0.4 * 0.8 '20
Const Pulse_1_2_temp = Takt / Reload * Pulse_soll * 0.8 * 0.8 '40
Const Pulse_max_temp = Takt / Reload * Pulse_soll * 1.2 * 0.8 '60

Const Start_bit = 8 '9 Bit ist das Startbit, muß 1 sein
Const Pruef_bit = Start_bit + 1 '10 Bit ist ein Prüfbit, muß immer 0 sein
Const Timer0_reload = - Reload '--> 65535 - reload
Const Crc_poly = &H1021
Const Sync_byte = &B01010100
Const Byte_counter = 7 'Anzahl der zu empfangenen Bytes


'Definition der Variablen
Dim Daten_temp As Word
Dim Crc As Word
Dim Tempw_1 As Word
Dim Tempw_2 As Word
'wegen dem Typcast, ungeschickt, aber sonst geht es nicht
Dim Pulse_min As Byte
Dim Pulse_1_2 As Byte
Dim Pulse_max As Byte
Pulse_min = Pulse_min_temp
Pulse_1_2 = Pulse_1_2_temp
Pulse_max = Pulse_max_temp
Dim Daten As Byte
Dim Signal_count As Byte
Dim Signal_old As Byte 'Merker für BIT Zustand
Dim Zaehler As Byte
Dim Daten_buffer(8) As Byte
Dim Temp1 As Byte
Dim Temp2 As Byte
Dim Crc_error_count As Byte
Dim Daten_empfangen As Bit ' Status Register


'Einstellen der Ports ++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++

Signal Alias Pind.6 'Eingang für Funkmodul
Config Signal = Input

'Led Alias Porta.2
'Config Pina.2 = Output

Print "Funkempfänger"
'Wait 1

'Timer einstellen++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++
Config Timer0 = Timer , Prescale = 1
On Timer0 Timer0_overflow
Enable Timer0
Enable Interrupts

'Hauptschleife. Wenn ein Byte empfangen wurde, wird geprüft ob es das Startbyte war.
'Wenn ja, dann werden die restichen zu empfangenen Bytes in die Variable Daten_Buffer
'geschoben. Wenn alle Bytes da sind, wird die CRC berechnet berechnet und entschieden,
'ob die Daten gültig sind oder nicht. CRC = 0 --> Daten gültig


Do

If Daten_empfangen = 1 Then 'Daten empfangen

If Daten = Sync_byte Then Zaehler = 1 'Zeiger auf Anfang stellen

Daten_buffer(zaehler) = Daten 'Daten in Buffer schieben
Daten_empfangen = 0 'Status ändern

If Zaehler = Byte_counter Then 'alle Bytes da ???

Gosub Check_crc 'CRC berechnen

If Crc <> 0 Then
'Hier sin die Daten ungültig
Incr Crc_error_count
Print "CRC Error: " ; Crc_error_count
Else
'Ab hier sind die Daten gültig

Zaehler = 1
'Daten ausgeben, ohne Startbyte und die beiden CRC Bytes
Do
Incr Zaehler
Print Chr(daten_buffer(zaehler)) ;
Loop Until Zaehler = 5
Print 'neue Zeile
Zaehler = 0
End If
End If
Daten = 0
Incr Zaehler
End If
Loop
End

'Die CRC Werte der empfangenen Daten berechnen. Am Schluß muß CRC = 0 sein
Check_crc:
Crc = 0
Temp1 = Daten_buffer(1)
Gosub Calc_crc
Temp1 = Daten_buffer(2)
Gosub Calc_crc
Temp1 = Daten_buffer(3)
Gosub Calc_crc
Temp1 = Daten_buffer(4)
Gosub Calc_crc
Temp1 = Daten_buffer(5)
Gosub Calc_crc
Temp1 = Daten_buffer(6)
Gosub Calc_crc
Temp1 = Daten_buffer(7)
Gosub Calc_crc
Return

'+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++
'Routine zum berechnen der CRC 16 Cecksumme, aus Bascom Buch
'Crc steht am Ende in der Varablen crc
'Übergabe: umzurechene Variable in temp1
Calc_crc:

Tempw_1 = Temp1 * 256
Crc = Tempw_1 Xor Crc
For Temp2 = 0 To 7
If Crc.15 = 0 Then Goto Shift_only
Tempw_2 = Crc * 2
Crc = Tempw_2 Xor Crc_poly
Goto Nxt
Shift_only:
Crc = Crc * 2
Nxt:
Next
Return

'-------------------------------------------------------------------------------

'Hier werden die Daten empfangen und geprüft auf die Bitzeiten
'Aufruf alle 41 µs bei 8Mhz
'-------------------------------------------------------------------------------
Timer0_overflow:

Timer0 = Timer0_reload
Incr Signal_count


'Ende gefunden oder Signal zu lang
If Signal_count > Pulse_max Then
'Print Signal_count
'Startbit = 1 and Pruef_bit = 0 dann Daten übergeben
If Daten_temp.pruef_bit = 0 And Daten_temp.start_bit = 1 Then
Daten = Daten_temp
Set Daten_empfangen
End If

Daten_temp = 0

End If

'Flankenwechsel ??
If Signal <> Signal_old.1 Then
'Print Signal_count
'neuen Zustand merken
Toggle Signal_old

'Pulse zu kurz ??
If Signal_count < Pulse_min Then
Daten_temp = 0
'Print Signal_count
End If


'Start oder Abfragezeitpunkt ??
If Daten_temp = 0 Or Signal_count > Pulse_1_2 Then

'wenn noch nicht zuviele Daten, dann eine Stelle schieben
If Daten_temp.start_bit = 0 Then
Shift Daten_temp , Left , 1

End If

'Bit setzen wenn der Empfänger das Signal 1:1 ausgibt. Signal_old.1 = 0 wenn es 180° gedreht ist
If Signal_old.1 = 1 Then
Incr Daten_temp

End If

Signal_count = 0

End If


End If


Return


Dieter,
Vielen Dank für deinen tollen support. Ich denke da kann sich so mancher eine Scheibe von abschneiden.

[/quote]

Space Teddy
06.11.2005, 17:00
Hallo Dieter,

habe gerade einen Wald und Wiesenversuch gemacht und
mein 868Mhz Sender/Empfänger schafft eine Entfernung von ca. 100m ohne Probleme.
Empfänger liegt bei mir aufm Schreibtisch und bin mit dem Sender ca. 100m die Straße entlang gelaufen.
Super Spitze :-)

07.11.2005, 20:55
@Space Teddy
Ist das im Code richtig: verschieden Baudraten und Quarze?

Space Teddy
08.11.2005, 17:58
Hallo Gast,
ja es funktioniert definitiv so. Da der Sender die Bit nur über waitms statements ausgibt kannst du aber auch einen 8Mhz quarz nehmen. Das sollte kein Problem sein. Dir Baudrate ist nur zum debuggen gedacht und kann geändert werden.


bis dann

jeffrey
19.04.2006, 15:37
Hi,
irgendwie funktioniert der code bei mir nicht, ich verwende 2 mega8 mit jeweils 8MHz.
Selbst wenn ich Sender und Empfänger mit einem Kabel verbinde funktioniert es nicht.
Der Sender scheint zu funktionieren, allerdings wird beim Empfänger Daten_empfangen nie 1.
Ich versteh auch nicht, warum du den Timerreload auf -256 machst, bei einem 8 bit Timer.
Es wäre nett, wenn du mir das erklären könntest.
Vielleicht bekomme ich es dann bei mir ja auch zum laufen.
MfG jeffrey

Space Teddy
21.04.2006, 19:49
hallo,
was für ein Funksystem verwendest duß

cu

jeffrey
21.04.2006, 21:39
Hi,
das Funkset von Conrad für 868MHz, hat bisle mehr wie 15 euro gekostet. Die Daten werden vom Funkset übertragen. Selbst wenn ich Sender und Empfänger mit einem Kabel verbinde funktioniert der Empfänger nicht.
MfG Jeffrey

Space Teddy
22.04.2006, 14:44
hallo, hast du auch wirklich den sender auf 7,362700 Mhz eingestellt?
wenn nicht mußt du das Programm adapieren oder schnell einen richtigen quarz dran klemmen.
Beachte aber auch bitte dieses hier im code


...
'Bit setzen wenn der Empfänger das Signal 1:1 ausgibt. Signal_old.1 = 0 wenn es 180° gedreht ist
If Signal_old.1 = 1 Then
Incr Daten_temp

End If

Signal_count = 0

End If
...


du mußt wissen was der Empfänger macht und gegebenenfalls anpassen.

cu

elcomportal
14.12.2006, 22:50
Funktionieren die Programme auch mit HFS868 und HFE868? Muss man das Signal vom Empfänger invertieren?
Mfg
Torsten

AVR_Noob
19.01.2010, 13:48
Hallo an alle,
der artikel ist zwar ein wenig älter, aber vllt liest das ja jemand.

Ich würde gerne eingänge abfragen und mit funk übertragen,um auf der anderen seite ausgänge zu setzen, aber ich habe keine ahnung wie ich das in den code einbinden muss.
vllt kann mir ja jemand einen tipp geben. als funkmodul würde ich die teile vom großen C nehmen.
ich hab leider noch nicht so viel ahnung vom programieren.

Gruß Nils

guenter1604
19.01.2010, 16:04
Hallo Nils,

guck mal hier:

http://www.gerold-online.de/cms/wheelie/mein-wheelie/telemetrie.html

AVR_Noob
20.01.2010, 09:30
Hallo,
danke für die Schnelle antwort!
Sehe ich das richtig,das strout,die variable ist,die eingelesen wird,dann in ein daten paket umgewandelt und anschließend gesendet wird??
Das heißt,ich müsste beide programme so umstricken,das der prozessor die eingänge einliest,in eine variabl gibt, umwandelt, und dann sendet??
Das Problem ist nur,das ich ein Funkmodul habe,das mit dieser Manchestercodierung arbeitet.
Aber ich werde mal ein wenig testen

Gruß Nils

Loety
19.10.2011, 21:28
Hallo Dino Dieter und Space Teddy und alle anderen :-)

Ich beschäftige mich gerade mit 2 Funkmodulen die ich beim großen C gekauft habe.

Empfängermodul : http://www.conrad.de/ce/de/product/191605/AM-RECEIVER-MODULE-TX-AM8SF
Sendermodul : http://www.conrad.de/ce/de/product/191564/AM-TRANSMITTER-MODUL-TX-8L25IA

Das Sendemodul soll so ca alle 1,5 Sekunden ein kurzes Datentelegramm in einer Endlosschleife versenden.
Es soll an einer bestimmten Stelle befestigt werden und dort munter vor sich hinsenden :-)
Die Daten die versendet werden sollen haben z.B. nur die Buchstaben FKON als Inhalt also wirklich nicht viel.

Meine Fragen an euch :

1. Kann ich den Bascom Code von Dino Dieter/Space Teddy für meine Module verwenden ?

2. Wenn ja wie genau muss ich den Controller mit dem Funkmodul verbinden ? (Schaltplan ?)

3. Warum bekomme ich beim Compilieren des Empfängercodes in Bascom folgende Fehlermeldung ?
Error : 49 Line : 158 Value doesn't fit into BYTE[-256]

Mein Bascom ist die 1.11.9.8 Vollversion !

Der Code für den Sender läßt sich ohne Probleme compilieren ! Komisch oder ?

Ich bin mir bewußt das der Tread einen Bart hat der so lang ist wie von all unseren Opa's zusammen :-) aber hoffe trotzdem auf eure Hilfe.

Bin euch auch sehr dankbar !!

Mit vielen Grüßen

Loety

PS Das Datenblatt von den Funkmodulen ist echt das Letzte :-(

Ripper121
11.01.2013, 13:56
Habe das Modul von Pollin:
Funk-Sender/Empfänger-Set 868 MHz
http://www.pollin.de/shop/dt/NDQyOTQ0OTk-/Bausaetze_Module/Module/Funk_Sender_Empfaenger_Set_868_MHz.html

hat damit schon jemand gearbeitet?

lema67
17.02.2013, 16:23
Hallo
Ich arbeite gerade mit den 433 MHz RF Link Modulen von Wattenrott
Ich bin gerade dabei mir ein Funkthermometer zu entwickeln dazu habe ich den Source angepasst.Als Sender dient ein Atmega8 und ein DS1820 als Temp Sensor, als Empfänger werkelt ein Atmega16.
Beide werden von einem 7,372800 MHz Quarz angetrieben.

Den Source von Seite 3 habe ich auch wenn da steht 'Hier ist das fertige und überprüfte Programm:' so nicht zum laufen bekommen.

Mein Timer0_overflow wird alle 40us aufgerufen. Die Bit_zeit habe ich erstmal auf 2000us angehoben und die Pause zum Signal zu lang / Ende erkennen auf 5000us.
Als Anzahl_Bit_wechsel zum Einschwingen haben sich 200 Takte als gut herausgestellt mit einer Bit_zeit_1_2 von 250us.

Den Code hänge ich drann sobald die Temperatur geschichte so funktioniert wie ich mir das vorstelle.

Gruß lema67

Hier mal ein Bild auf dem die Signale schön zu sehen sind.
24550

Ziemlich Frostig im Eisfach:) Empfänger steht im Wohnzimmer, Sender liegt im Eisfach in der Küche.
Entfernung ca 10m 1x Kalksandsteinwand + Eisfach
24551