Hallo
Das Skript soll auf einem Tiny84 dafür sorgen,
das empfangene Daten weitergesendet werden.
Nur leider schaffen wir es nicht, die Daten im gänze zu senden.
Es werden nur die ersten beiden Zeichen des Strings übertragen.
Kann von euch jemand sehen, ob wir den String so richtig zusammen bauen?
Danke und Gruß
Kolja
Hier die vermeintlich problematische Stelle:
1
// Buffer to store incoming data
2
constchar*inData;
3
inti;
4
for(bytei=0;i<*radio.DataLen;i++)//can also use radio.GetDataLen() if you don't like pointers
5
#ifdef DEBUG
6
mySerial.print((char)radio.Data[i]);
7
#endif
8
inData+=(char)radio.Data[i];
9
10
if(LEDpin){
11
blink(LEDpin,2);
12
}
13
if(radio.ACKRequested()){
14
radio.SendACK();
15
#ifdef DEBUG
16
mySerial.print(" - ACK sent");
17
#endif
18
}
Und hier nochmal der Code im Ganzen:
1
voidloop(){
2
if(radio.ReceiveComplete()){
3
if(radio.CRCPass()){
4
intsupplyV=readVcc();// Get supply voltage
5
//node ID of TX, extracted from RF datapacket. Not transmitted as part of structure
6
bytetheNodeID=radio.GetSender();
7
// Buffer to store incoming data
8
constchar*inData;
9
inti;
10
for(bytei=0;i<*radio.DataLen;i++){//can also use radio.GetDataLen() if you don't like pointers
Das funktioniert so nicht. Lest Euch mal in Strings in C ein. Ein
char-Pointer funktioniert nicht so einfach wie ein String in
zivilisierten Programmiersprachen.
Erst legt ihr einen Zeiger an, der irgendwo hin zeigt, dann
inkrementiert ihr ihn abhängig vom Inhalt der empfangenen Daten, so dass
er sonstwo hin zeigt, dan sendet ihr die Daten, die an dieser (halbwegs
zufälligen) Stelle im RAM stehen.
Nabend Tom
Dann liegt das Problem ja wirklich da wo wir es vermuteten.
Kostet das was wir zum Auslesen des Strings machen müssen
viel Platz auf dem Tiny?
Wenn noch eine library hinzugefügt werden muss,
müssten wir uns nach einer anderen Lösung umschauen...
Der String sieht in etwa so aus:
v=4321_0079=2409_0a28=2343
und wir bräuchten ihn schon im Ganzen.
Gruß Kolja
for(i=0;i<*radio.DataLen;i++)//can also use radio.GetDataLen() if you don't like pointers
6
inData[i]=(char)radio.Data[i];
7
inData[*radio.DataLen]='\0';// nötig, sofern das Nullzeichnen nicht in der empfangenen Zeichenkette schon vorkommt
MAX_LENGTH sollte dabei die maximal zu erwartende Länge des Strings + 1
sein. Strings werden in C mit 0 terminiert. Die strlen()-Funktion sucht
das Nullzeichen um das Ende des Strings zu finden und damit die Länge zu
berechnen.
Das Konstrukt *radio.DataLen sieht auch ziemlich komisch aus. Sicher,
dass das nicht radio.DataLen heißen soll?
Moin Thorsten
Danke für die Codezeilen.
Ich werds (hoffentlich) gleich noch mal einbauen.
Muss die exakte Länge des Strings angegeben werden?
Da drei der Werte Temperaturen sind und diese eine Stelle kürzer werden,
wenn unter 10°C gemessen wird, kann das natürlich problematisch werden.
Zur Not muss der Sender einfach auf jeden Wert 10 aufaddieren
und im Empfänger werden diese wieder subtrahiert.
Gruß&Dank
Kolja
Nein, MAX_LENGTH ist nur die maximale Länge des Strings. Er kann
natürlich auch kürzer sein, dann ist aber eben der RAM für die nicht
genutzten Zeichen futsch. Jedoch darf der String nicht länger als
MAX_LENGTH sein, sonst kann es passieren, dass dir Daten überschrieben
werden. Also sofern nicht irgendwie anders sicher gestellt ist, dass die
Länge der empfangenen Daten MAX_LENGTH nicht überschreitet, kannst du
zur Sicherheit die noch prüfen:
keinen strlen benutzen. Denn ich kenne ja die Länge des 'Strings'. Die
muss logischerweise *radio.DataLen sein.
Kein strlen -> keine Notwendigkeit, dass die Eingangswerte \0-terminiert
sind.
Die Funktion gibt dann einfach nur das weiter, was sie gekriegt hat. Was
immer das auch war.
Eine ganz andere Frage lautet: Warum muss das Array überhaupt umkopiert
werden? Würde ein
1
radio.Send(T_GATEWAYID,
2
(uint8_t*)radio.data,
3
*radio.DataLen,
4
requestACK);
nicht einfacher sein? Es kann jetzt natürlich sein, dass das radio
Objekt in den dazwischenliegenden Aufrufen den Datenbuffer löscht oder
aber das der Data Member kein Array von Bytes ist (halte ich aber eher
für unwahrscheinlich). In diesen Fällen müsste man natürlich umkopieren.
Und ja. Das *radio.Datalen sieht in der Tat merkwürdig aus. So ein
Konstrukt ist höchst ungewöhnlich. Es muss aber nicht notwendigerweise
falsch sein, wenn die Klasse des radio Obektes so etwas wie ein
Double-Buffering macht, um empfangene Daten für die Weiterverarbeitung
bereit zu stellen, während im Hintergrund der Empfang neuer Daten
bereits läuft.
Nabend Heinz & co
Vielen Dank für die Hilfe!
Der Vorschlag aus dem letzen Post ließ den kleinen Repeater alles senden
was er auch empfangen hat!
Wir waren gerade in dem Gebäude in welchem wir die Messungen durchführen
werden
und mit einem Repeater können alle Sensoren aus allen Räumen empfangen
werden
und an den RaspberryPi in den Keller gesendet werden.
Wenn wir die Dokumentation fertig haben,
werde ich hier den entsprechenden Teil verlinken.
Wer vorher schon Fragen hat, gerne!
Gruß Kolja
Eine eigene Frage?
Dieser Thread ist über 11 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.