PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : seriellen Datenstrom formatieren für funk RT868F5



cyberFreak
25.01.2010, 19:37
Hallo zusammen,

habt ein Tolles Forum hab schon einige Fragen beantworten können.
Aber dazu hab ich nichts gefunden, vlt. habt ihr eine Idee.
Ich arbeite mit einem PIC18f4680 und der C18 Library.

Ich möchte mittels Funkchip RT868F5 einen analogen Spannungswert
einlesen und diesen versenden und auf der Empfängerseite in einer
Variablen ablegen.
Nun, das einlesen des Wertes funktioniert ´, auch die A/D-Wandlung geht
es wird richtig über USART gesendet und empfangen.
Aus der A/D-Wandlung kommt eine int-Wert raus und wird mittel
WriteUSART versendet und mittels ReadUSART wieder ausgelesen.
Jedoch passt mir das Format der empfangenen und gesendeten Daten nicht.
Angenommen ich möchte eine 4,2V versenden, dann verschickt mir mein Code
z.zt. "42", auf der Empfängerseite kommt 42 an und ich verschieben das
komma um eine Position. Funktioniert.

Jedoch, die Werte sind teils ziemlich ungenau bei kleineren
Spannungswerten kommt es sogar vor das statt einer 0,8 eine 0,6
versendet wird. nehme an dies hängt jedoch mit der internen Vref
zusammen.

Jetz kam die Idee mittels Long-Wert zu arbeiten.
Jedoch kann der Funkchip nur 8-Bit, hat jedoch angeblich einen Puffer von 240Byte welchen er erst sendet wenn nach dem konstanten senden von Daten eine Pause eingelegt wird. Das funktioniert jedoch nicht, er sendet nur die letzten 8 Bit.

Kennt ihr eine Möglichkeit die Daten zu splitten, d.h. als erstes 8-Bit
zusenden und dann nochmals 8-Bit?
Dies funktioniert zwar, jedoch kommt es vor das die 2 Zahlen vertauscht
sind auf der Empfängerseite, da er ja irgendwann anfängt zu empfangen.

Ich dachte ursprünglich so:

Version 1 - SENDER


x=conv_AD(0,1,1);
x1=x<<8;
x2=x;
while (1)
{
WriteUSART(x1);
for (i=0;i<10000;i++);
WriteUSART(x2);
for (i=0;i<10000;i++);
}

oder diese Version2
wobei hier aus der AD-Wandlung ein Long-Wert kommt



x=conv_AD(0,1,1);
while (1)
{
WriteUSART(x);
for (i=0;i<10000;i++);
}

Bie Version 2 empfängt er nur die letzten 8 Bit, und bei Version1 weiß er nicht welcher Wert zuerst kommt. Sondern würfelt mit das am Empfänger wild durcheinander.

Hat jemand eine Idee wie ich 2 getrennte Zahlen übertragen kann und diese eindeutig auseinander halten kann???
Zusammenfassung: Zahl aufteilen in 2x8-Bit und in der richtigen
Reihenfolge empfangen.
Ich hab vieles versucht, nichts funktioniert :(
DANKE !

Richard
26.01.2010, 10:29
Dein Code ist etwas seltsam, Du Willst 2 Byte übertragen
und läßt eine Schleife bis 10000 zählen?

Wenn Du a(1), a(2) sendest sollte auch A(1) els erstes ankommen,
da KANN nix verdreht werden, außer DU liest "verdeht" ein?

Teste das mal gaaanz langsam ohne Schleife.....

Do

Sende A
Empange A
Sende B
Empange B

Loop

Gruß Richard

sast
26.01.2010, 12:07
Schön wäre es, wenn du mal die Empfangsfunktion hier zeigen könntest. Ich nehme an, da liegt der Hase im Pfeffer.

Beim Empfang weiß deine Funktion sicher nicht, wann das erste oder zweite Byte kommt. Du brauchst also eine Synchronisation. Ansonsten empfängt dein Empfänger vielleicht zuerst ein zweites Byte und dann das erste vom nächsten Wert usw..

Zu deiner 2. Variante kann ich nur soviel sagen, dass deine WriteUSART() Funktion vermutlich nur jeweils ein Byte sendet und deshalb ein cast von 16bit auf 8bit gemacht wird.

sast

cyberFreak
26.01.2010, 15:25
Das Problem dabei ist das das FUnkmodul die Pause braucht das es sendet. d.h. es Buffert (angeblich, das funktioniert nicht, die Daten) und sobald eine Pause kommt sendet es.

Es ist richtig das ich keine Synchronisation habe beim Empfang.
Das ist genau das Problem, er weiß nicht wo das zweite Byte anfängt und das erste endet.
Bzw. das weiß er schon, nur empfängt er mal das erste und mal das zweite.
Nur wie bekomm ich das ihm gesagt?

Die Empfangsfunktion ist einfach ReadUSART()

sast
26.01.2010, 16:14
Dafür gibt es jetzt verschiedene Ansätze, die von deiner Verarbeitung und den Wiederholungsintervallen abhängen.
Z.B. könntest du zum Start einer jeden Sendung, sagen wir mal, 3 gleiche Bytes voranstellen. Wenn die vorbei sind kommt dein relevanter Datensatz.
Oder du nutzt die Delayzeit die du für das Aktivieren einer Sendung mit deiner Schleife ja sowieso erzeugst zur Erkennung.

WriteUSART(x1);
WriteUSART(x2);
for (i=0;i<100000;i++);

Nach deinen Aussagen sollte er sich ja dann zum Puffer leeren genötigt fühlen. Und zwischen den zwei Bytes ist die Lücke relativ klein. Wenn das zweite Byte nicht in einer angemessenen Zeit kommt, kannst du das erste auch wieder verwerfen und fängst von vorn an.

sast

Ceos
26.01.2010, 16:21
idealerweise hat das modul eine "busy-leitung" so kenn cih das vom easyradio zumindest, wenn die auf low wechselt, besteht keine empfangsbereitschaft mehr!

ich hab mir mit 2erlei dingen beholfen, zum einem habe ich meine daten immer in einer paketstruktur mit preambel (0xff, 0xaa oder 0x55), dann ein identifikationsbyte, dann falls erforderlich ein größenbyte und darauf folgend die datenbytes und abschließend einen crc prüfsumme (XOR verrichtet gute dienste und geht schnell) und zum anderen sende ich wie folgt meine daten mit hilfe der TX-ISR


#define CONTINUE SENDING if(READY_PIN_HIGH & !Sending & ReadPtr < WritePtr){ \
UDR = Buffer[ReadPtr++]; \
Sending = 1; \
}

ISR(TX_COMPLETE)
{
if(READY_PIN_HIGH & ReadPtr < WritePtr) {
UDR = Buffer[ReadPtr++];
}
else Sending = 0;
}

void writeBus(unsiogned char databyte)
{
Buffer[WritePtr++] = databyte;
CONTINUE_SENDING;
}

int main(void)
{
while(1) {
...
CONTINUE_SENDING;
...
}
return 0;
}



durch WriteBus wird das ganze angeschoben:

byte für byte wandern in den puffer ...
dann überprüft das CONTINUE-makro ob gesendet wird, ist dem nicht so, wird das senden eingeleitet

jedes gesendete byte löst dann die ISR aus in der die empfangsbereitschaft des funkmodul überprüft wird, ist das modul nicht mehr READY wird das senden einfach unterbrochen

in der hauptschleife wird dann regelmäßig das CONTINUE-makro aufgerufen, welches dann neben der sendeaktivität auch noch die sendebereitschaft überprüft und gegebenenfalls anstößt

cyberFreak
27.01.2010, 16:06
@sast

genau diese Routine habe ich versucht, dabei bekommt der empfänger jedoch das Byte wie es ihm beliebt. mal x1, mal x2.
Der Datenbuffer des RT scheint so nicht angesprochen zu werden.

@ceost

eine solche Busy-Funktion ist mir jetzt nicht bekannt des RT.
ich werde aber mal schaun ob ich dahingehend noch was finde.
danke erstmal für den Beispielcode

Richard
27.01.2010, 16:41
Moin moin.

Lese Dir einmal http://www.funkmodul.com/funkmodule/transceiver_daten/RT868F5.pdf

Durch, dort ist beschrieben wie das mit den Datenbuffer klappt, dann
sollte auch die Übertragung ohne Fehler möglich sein. :-)

Gruß Richard

sast
31.01.2010, 18:21
Also ich gehe mal davon aus, dass du mit DIESER Routine den kurzen code-Schnipsel meinst, denn ich da hingeschrieben habe.
Ich hab mir mal das pdf von Richard angesehen und finde, dass auf Seite 5 alles zum Timing wichtige steht. Du solltest also vielleicht mal alles für deine Konfiguration durchrechnen. Ich kenn mich leider mit pics nicht aus aber die Daten wie Taktfrequenz usw weißt du ja. Möglicherweise ist nur deine Pause für das Senden etwas kurz.

sast