ok danke sehr.
d.h. const int size = 50;
float array1;
float array2;
ok werde es versuchen
ok danke sehr.
d.h. const int size = 50;
float array1;
float array2;
ok werde es versuchen
Ja. Du brauchst nur die Namen in Datentypen anzupassen. Und statt atoi() -> atof() für Float bei der Konvertierung.
Da beide Puffer wohl die gleiche Größe haben kann man natürlich auch eine Konstante dafür nehmen.
Konstanten schreibt man normal in Großbuchstaben. Dann kann man sie von Variablen unterscheiden.
Ich weiß übrigens nicht was du sonst noch da machen willst, aber 200 Floats verbrauchen 800 Bytes RAM. Das ist fast die Hälfte.
Hi so habe es getestet, es funktioniert iwie nicht sauber bekomme nicht alle Werte rein besonders der Wert. schau im Anahng das was der Coordinator enpfängt. Habe es folgendermaßen gemascht, dass erst dann was vom Endgerät gesendet wird, wenn der aktuell ausgelesene Wert ein bestimmten Wert übersteigt.
bekomme aber folgendes raus.
Irgendwie klappt das mit dem neline am ende nicht immer
Irgendwie klappt das mit dem neline am ende nicht immer
Wenn man es richtig macht geht dieser Code locker mit 250.000 oder 500.000 Baud.
Zeig mal her was du sendest und dann beim Empfänger die Array Definition und die Parse Funktion.
hmm also der Sender is folgendermaßen:
altserial.print("Aktueller MAgnituden-Wert: ");
altserial.print(MagAccel[put_index]);
altserial.print(";");
altserial.println(MagGyro[put_index]);
if(MagAccel[put_index] >= 15)
{
// Serial.println("$");
//delay(10);
for (int j = 0; j == put_index; j++)
{
Serial.print('A');
altserial.print("Inhalt von MagAccel & Gyro ");
Serial.print(MagAccel[j]);
altserial.print(MagAccel[j]);
delay(5);
Serial.print(';');
altserial.print(';');
delay(5);
Serial.println(MagGyro[j]);
altserial.println(MagGyro[j]);
}//end for
}//end if
put_index = (put_index+1) % maxIndex;
delay(10);
Der Empfänger
void loop()
{
if (leseSerial(Serial))
{
altserial.print("lesen: "); altserial.println(SerialBuffer);
SplitSerial();
}//end if leseSerial
}//end loop
void SplitSerial()
{
//SerialBuffer + 1
float wert1 = atof(strtok(SerialBuffer + 1, ";"));
float wert2 = atof(strtok(NULL, ";"));
altserial.print(wert1);
altserial.print(';');
altserial.println(wert2);
if (SerialBuffer[0] == 'A')
{
MagAccel_B[put_indexB] = wert1;
MagGyro_B[put_indexB] = wert2;
put_indexB = (put_indexB+1)%MaxIndex;
altserial.println(F("Values_A:"));
for (int i = 0; i < 50; i++)
{
altserial.print(MagAccel_B[i]);
altserial.print(';');
altserial.println(MagGyro_B[i]);
}
altserial.println(F("---"));
}
else if (SerialBuffer[0] == 'B')
{
MagAccel_O[put_indexO] = wert1;
MagGyro_O[put_indexO] = wert2;
put_indexO = (put_indexO+1)%MaxIndex;
altserial.println(F("Values_A:"));
for (int j = 0; j < 50; j++)
{
altserial.print(MagAccel_O[j]);
altserial.print(';');
altserial.println(MagGyro_O[j]);
}
altserial.println(F("---"));
}
}
bool leseSerial(Stream& stream)
{
static byte index;
while(stream.available())
{
char c = stream.read();
if (c == '\n')
{
SerialBuffer[index] ='\0';
index = 0;
return true;
}//end if c
else if (c >= 32 && index < BUFFER_SIZE -1 )
{
SerialBuffer[index++]=c;
}//end else if
}//end while
return false;
}//end fu
Was soll das sein?
for (int j = 0; j == put_index; j++)
for-Schleifen gehen anders. Der Vergleich in der Mitte ist wie eine while-Bedingung
Und wieso überhaupt eine Schleife da? Nach meinem Verständnis sollte da nur der aktuelle Wert gesendet werden.
Was ich auf gar keinen Fall machen würde ist jedesmal alle 50 Indizes ausgeben wenn etwas empfangen wurde. Das kostet nur unnötig Zeit und blockiert bei niedrigen Baudraten lange, da der Ausgangspuffer voll läuft (damit sind die Puffer in der jeweiligen Serial Klasse gemein. Nicht deine im Programm)! In der Zwischenzeit sendet aber die andere Seite weiter. Es hat schon seinen Grund gehabt wieso ich das nur einmal gemacht habe wenn der Puffer voll ist.
Also nicht ständig den Prozessor blockieren in dem du andauernd Romane auf Serial ausgibst. Und wenn du nur den Puffer ausgibst wenn er voll ist, eventuell auf dem Sender etwas warten wenn der letzte Wert ausgegeben wurde um den Empfänger Zeit zu geben das zu versenden. Sauberer könnte man da auch Software-Handshaking machen. Aber du bist schon jetzt überfordert.
also bzgl der For schleife for (int j = 0; j == put_index; j++) die benötige ich dazu, sodass ich sobald der Wert vom sensor > 15 ist , soll der inhalt des Arrays inlusive des Auslösewert > 15 an den Coordinator gesendet werden.
Wie soll ich das sonst machen?
Außerdem splittet der Coordinator falsch bzw nicht alle Werte, die vom Empfänger gesendet werden kommen an.
milito:
also bzgl der For schleife for (int j = 0; j == put_index; j++) die benötige ich dazu, sodass ich sobald der Wert vom sensor > 15 ist , soll der inhalt des Arrays inlusive des Auslösewert > 15 an den Coordinator gesendet werden.
Wenn du alle Werte bis zu einem bestimmten Index senden willst, muss das trotzdem "< index" heißen
Und das Problem kann immer noch sein, dass das komplette Array mit 50 Einträgen auf Serial ausgibst. Der serielle Ausgangspuffer hat nur 68 Byte. Wenn der Sender dann weiter sendet gehen Daten verloren. Da wird einfach Busy Waiting gemacht:
while (tx_buffer_tail == head) ; // wait until space in buffer
Lass mal die delay(5) weg. Das ist überflüssig wenn man schnell genug einliest. Aber mache nach dem Versenden des kompletten Arrays ein etwas größeres delay() um dem Empfänger Zeit zu geben das auszugeben. 10ms reichen da bei weitem nicht. Ein Zeichen braucht 1 / Baudrate * 10 Sekunden!
Die Baudrate zum PC etwas höher zu machen kann auch ein wenig helfen. 19200 sollte bei altSoftSerial noch gehen. Aber das ist alleine keine Lösung.
Wie gesagt, wenn man es richtig machen würde, würde man da Software Handshaking einführen, so dass der Empfänger meldet wenn er nichts mehr Empfangen kann. Das lassen wir aber erst mal sein.
aber theoretisch is die logik richtig oder?
deshalb verstehe ich nicht warum auch falsch gesplittet wird.
Mit den 10ms ich brauche jeden 10ms einen neuen wert.
Das Problem liegt sicherlich nicht am Splitten. Sondern eher daran dass Daten verloren gehen, weil du den Prozessor zu lange mit der seriellen Ausgabe blockierst. Sicher bin ich mir nicht. Aber wenn du ständig mehrere hundert Zeichen auf Serial ausgibst brauchst du dich über sowas nicht zu wundern.
Mit den 10ms ich brauche jeden 10ms einen neuen wert.
Wenn das so schnell gehen soll, dann musst du mal etwas mehr darüber nachdenken was da eigentlich abläuft, wie lange das dauert (kann man anhand der Baudrate ausrechnen) und wie sich verschiedene Aktionen gegenseitig beeinflussen.
Das geht schon wenn man einfach die Baudrate der XBee Module erhöht. Aber der Flaschenhals ist die Übertragung zum PC.
hmm verstehe ok. N´Danke sehr Inwiefern der Flaschenhals?
1.) AltSoftSerial ist besser als SoftwareSerial aber kann trotzdem keine allzu große Baudrate
2.) Die Datenmenge zum PC ist riesig. Rechne doch mal aus wie viele Bytes das sind wenn du 100 Floats als ASCII ausgibst! Dazu dann noch 50 Delimter. Und 50 mal CR + LF. Alleine das sind schon 150 Bytes!
Wie gesagt, berechne mal was du da überträgst und wie lange das dauert.
Soll die Ausgabe zum PC auch im fertigen Programm erfolgen oder nur als Test? Erstes ist kein großes Problem. Das könnte man umgehen. Bei letzterem hast du Pech gehabt. Dann bräuchtest du einen Controller mit mehreren Hardware UARTs. Dann könnte man mit der Baudrate weit nach oben gehen.
Wobei es auch dein Limit gibt wie schnell das geht. Ich weiß nicht was die XBee Module maximal können. Das solltest du mal nachschlagen. Man könnte die Datenmenge reduzieren wenn man statt ASCII Binär-Daten sendet. Dann bräuchte man nur 4 Bytes pro Float. Man könnte es weiter reduzieren wenn du es als 2 Byte Integer überträgst. z.B: 98.25 = 9825. Der Werte-Bereich ist dann aber beschränkt.
Und da du schon Strings nicht richtig beherrscht, wird das nur noch komplizierter.
ne Die ausgabe is nur zum Testen ich will diese ins Array abspeichern und daraus eine csv datei erstellen. Sber ich sehe den walt vor lauter Bäumen nicht mehr deshalb stelle ich mich so blöd an
Ein Zeichen dauert 1 / Baudrate * 10 Sekunden. Mal 10 da man 1 Start-Bit, 8 Daten-Bits und 1 Stop-Bit hat.
Also dauert bei 9600 Baud ein Zeichen ca. 1ms (1 / 9600 * 10)! Das ist sehr lange. Dann zähle mal zusammen was du da jedesmal überträgst. Daran hast du wohl noch überhaupt nicht gedacht.
Auch mit XBee <-> XBee bekommst du Probleme. Von den 10ms würde ich mich mal verabschieden. Oder von der Puffergröße 50. Du solltest vielleicht statt println() am Ende print('\n') machen. Das spart ein Zeichen (das CR), aber viel Ersparnis ist das angesichts der anderen Daten nicht. Auch da musst du schauen wie lange deine Übertragung maximal dauert. So kannst du berechnen wieviele Daten du in einem Zeitfenster unterbringst (wenn die Puffergröße variabel ist) oder wie oft du die Daten senden kannst (wenn die Wiederholungsrate variabel ist).
Wie gesagt, man kann das optimieren wenn man bei der XBee Kommunikation von Strings auf Binär umsteigt. Aber du musst erst mal ein Gefühl dafür bekommen wie das zeitlich aussieht.
ok d.h. ich muss anstatt 10 ms das höher setzen und den buffer anstatt 50 reduzieren?
Habe erneut geteste und naja er empfängt ab und an folgendermaßen.
siehe bild.
Der nimmt einen dritten wert auf der verloren geht.
milito:
ok d.h. ich muss anstatt 10 ms das höher setzen und den buffer anstatt 50 reduzieren?
Eines davon. Oder beides. Und die Baudrate anpassen. Kommt darauf an was man letztlich machen will.
Ich würde zum Test erst mal die Zeit höher setzten. Damit gibt es du dem Empfänger Zeit das ganze an den PC zu senden. Dadurch sieht man dann ob der Empfang an sich korrekt funktioniert. Wenn das geht, braucht man die Ausgabe auf dem PC nicht mehr.
Aber danach musst du die Baudrate, Zeiten und Datenmenge so wählen, dass auch genug Zeit ist das zu übertragen und zu verarbeiten. Und nicht einfach willkürlich was nehmen und Daten schneller auf Serial schreiben als sich diese Bewegen.
Software Handshaking ist wie gesagt eine Option. Vor allem wenn nicht garantieren kannst, dass der Empänger in der Zeit auch fertig ist. Aber dadurch hast du nicht mehr genau definierte Zeitscheiben, da sich die nächste Übertragung verzögern kann.
Die sicherste Lösung wäre als Empfänger ein Mega oder Leonardo-basierender Arduino. Die haben mehrere Hardware Schnittstellen. Dann könnte man mit bis zu 500.000 Baud zum PC senden.
ok was macht es aber für einen Unterschied als nur die Schnittstelle der Fio hat zwar eine aber er nüsste es doch auch schaffen
Ich gebe auf....
Es geht um die Schnittstelle zum PC die nur als Software-Emulation existiert und somit nur mit niedrigen Baudraten richtig arbeitet.
Aber wie gesagt auch mal bei der XBee Kommunikation rechnen. Selbst mit hohen Baudraten wird das nichts mit alle 10ms ein paar hundert Zeichen zu senden.
Ok. Danke dir. Habe die Baudrate auf 19200 gesetzt und mal auf beiden seiten gedebuggt und ein teil wird kommt an der andere teil garnicht.
Danke für deine Mühe ich komm einfach nicht mehr weiter bzw bin komplett verwirrt.
auserdem es geht nicht darum 10ms über XBEE zu senden ich lese jede 10ms den Sensorwert aus(Enddevice-Seite) und speichere es in einem Ringbuffer. falls der gelesene Sensorwert >15 ist, soll er diesen in den Ringbuffer schreiben und den aktuellen Inhalt des Ringbuffers an den Coordinator senden. Das kann doch ja nicht so schnell sein oder?