Zitat von
Manado:
ich bin ganz baff was für Unterstützung man hier im Forum bekommt.
Zitat von
Manado:
1.Ich sende mit dem µC am besten eine binäre 13 als Ende der Nachricht, angenommen ich will den wert 255 übertragen, sende ich : | 1111 1111 | 0000 1101 |
Was das Senden angeht, richtig. Aber das am Besten stimmt nicht ganz. Ich möchte an dieser Stelle einfach nur mal kleinlich sein, um Missverständnissen vorzubeugen. Ob Du am Ende eine binäre 13, eine 1 oder eine 255 überträgst ist deiner persönlichen Vorliebe überlassen. Du kannst auch gänzlich auf eine spezielle Markierung am Ende verzichten. Der RS-232-Schnittstelle/UART ist das völlig egal, alles wird auf gleiche Art und Weise übertragen. Nur Dein Programm (oder anders gesagt Du) kann eventuell besser mit einer solchen Markierung arbeiten als ohne (muss auch nicht immer der Fall sein).
Zitat von
Manado:
2.Der PC empfängt ständig , und speichert das Empfangene in einem Puffer.
Im Prinzip richtig, aber eigentlich ist es bei Asynchroner Kommunikation so, dass Du nur wissen musst, dass Empfangen wird, sobald mal was gesendet wurde. Wo man es etwas deutlicher sieht ist vielleicht der Email-Verkehr. Auch diese Kommunikation ist asynchron, irgendwann schickt jmd. eine mail ab und die wird ausgeliefert. Die wird einfach sofort abgeschickt, da wird nicht erst gewartet ob der Empfänger gerade bereit ist eine mail zu empfangen. Damit die mail nicht verloren geht, wird die vom Provider also in einen Puffer (das mail-Fach) gespeichert und irgendwann mal von dem eigentlichen Empfänger abgeholt (der sich dann über das Interesse verschiedener Damen oder Angebote für Viagra freut
).
Zitat von
Manado:
3. Ich sage mit EventChar , das bei dem empfangenen Wert 13 ein Ereignis ausgelöst wird, Das Ereignis kann eine Prozedur mit Namen OnRxFlag , oder OnRxChar sein
Hm, das habe ich wohl etwas falsch erklärt. Die zwei Ereignisse musst Du unterscheiden. OnRxChar tritt
immer ein wenn Daten im Puffer landen. Wird also mal was verschickt und kommt an, wirst Du durch das Ereignis OnRxChar darüber informiert (egal ob EventChar einen bestimmten Wert hat und egal was im Puffer steht).
OnRxFlag hingegen wird dann und nur dann ausgelöst, wenn unter den neuen Daten (die im Puffer landen) das EventChar bei war. Kommt z.B. das Datum $1,$1,$1 gefolgt von $1,$2 und dein EventChar ist $2, dann würde hier OnRxChar zwei mal aufgerufen werden und Du hättest erst ein Datum der Länge 3, dann ein Datum der Länge 2 im Puffer.
Das OnRxFlag würde hingegen nur einmal ausgelöst werden, nämlich dann wenn das zweite Datum empfangen wurde, im Puffer wären in diesem Fall dann schon 5 Byte.
Zitat von
Manado:
Heisst im Prinzip, wenn ich mit dem µC nach jedem Messergebnis, das er sendet, einmal 13 anhänge, und per InputCount praktisch sage wie gross das gesendete Messergebnis ist (im µC definiert), kann ich aus der Byteflut im Puffer den Wert den ich haben will rausfiltern.
Ist das so?
Äh, ich glaube da ist jetzt einiges durcheinander? Die 13 hängst Du nur an, um aus einem Puffer die einzelnen Daten zu extrahieren. Nehmen wir einfach mal die 13, wird das Datum 'Hallo Welt'#13'Test'#13'Blubb' übertragen, wobei ein String natürlich nur ein Array von Bytes ist, dann weißt Du nicht wie dieses Datum in deinem Puffer landet. Jede Zerlegung wäre halt denkbar. Ein mögliche Belegung (o.B.d.A.) wäre dann 'Hallo', ' Welt'#13'Tes', 't'#13'Blubb'. Entspricht ja ein wenig dem was Du schon beobachtet hast, im Puffer steht nicht immer das vollständige Datum. In diesem Fall hilft Dir dann einfach die Endmarkierung (die eben nur Markierung ist) zu sehen, dass Hallo noch nicht das vollständige Datum war, sondern noch ' Welt' folgt. Auch Test kannst Du somit zusammensetzen. Dem Blubb folgt aber keine #13 Markierung, hier musst Du davon ausgehen, dass noch etwas folgt.
Was Du jetzt mit InputCount sagen möchtest ist mir ehrlich gesagt unklar. InputCount gibt an wieviele Daten schon im Puffer liegen (die Funktion InputCount). Da es sich um eine Funktion handelt, kannst Du der nichts sagen, die gibt Dir nur einen Wert zurück. Dem Puffer ist es völlig egal wieviele Bytes Du erwartest, Du kannst nur aus ihm lesen was schon da ist. Liest Du mehr Bytes aus, würdest Du Speicher lesen, dessen Wert undefiniert/zufällig ist. Deshalb wird die Komponente das schon für Dich abfangen.
Das eigentliche rausfiltern geschieht dann dadurch, dass Du ebend einfach alles was ankommt einer eigenen Variable speicherst und hier nach den Trennzeichen suchst. Findest Du eins, so kannst Du an dieser Stelle trennen und erhälst das gewünschte Datum.
Zitat von
Manado:
Jetzt noch 2 Sachen:
Wie gross ist der Puffer, bzw. Wann läuft er über und wird wieder resettet?
Zum Resetten gibt es Funktionen (denke die hieß FlushBuffer oder so ähnlich, schau einfach mal in die Hilfe). Die wirst Du aber kaum brauchen. Wichtiger ist die erste Frage, denn natürlich sollte der Puffer nie so weit gefüllt werden, dass er überläuft. Was eigentlich passiert, wenn er mal überlaufen würde kann ich Dir auch gar nicht sagen (da kenne ich mich dann zuwenig mit RS-232 aus). Egal was passiert (Verdrängung, Fehler, ...) es ist nichts was man gerne hätte.
Die Größe des Puffers lässt sich sicherlich auslesen (müsste auch in die Hilfe schauen wo und wie, also verweise ich nochmal auf eben diese), sie sollte Dir aber egal sein. Wichtig ist einfach, dass die Größe unterschiedlich sein kann/ist. Der eigentliche Puffer hängt schon mit der eingesetzten HW zusammen. Im Embedded Bereich wird man Platz und kosten sparen und eher sehr sehr kleine Puffer einsetzen (jeder Speicher benötigt auch Energie). Im PC kann das schon anders aussehen (z.B. kann man die Daten im HW-Puffer cachen und in einen größeren Speicher übernehmen). Hier wäre dann eine Art virtueller Puffer (durch den Treiber) denkbar (und eine Festplatte dürfte schon einiges aufnehmen).
Man sollte sich einfach nie darauf verlassen, dass genug Platz zur Verfügung steht. Am Besten ist es deshalb, wenn Du immer auf das OnRxChar Event reagierst. Liest Du den vollen Inhalt des Puffers aus, so brauchst Du Dir keine Sorgen zumachen, dass der Puffer voll wird. Da ein Datum aber in mehreren Schritten übertragen werden kann, musst Du dann immer die neu empfangenen Bytes anhängen und selbst prüfen, wann ein vollständiges Datum in deiner Variablen steht. Das wäre das, was halt das OnRxFlag für Dich übernimmt (die Prüfung ob das spezielle Zeichen empfangen wurde). Mit der OnRxChar-Variante hast Du dann den Vorteil, dass Du wirklich sicher bist, was die Füllung des Puffers angeht (wird mit dem Lesen auch geleert). Der Nachteil ist die Einbusse an Komfort (die sich aber sehr sehr stark in Grenzen hält). Speicherst Du die empfangenen Daten in einem String, so liegt der Unterschied in einer Zeile (kannst die Pos Funktion verwenden). Mehr als zu prüfen ob das entsprechende Zeichen im String ist wird Dir das OnRxFlag-Event nicht abnehmen. Das trennen der Daten ist weiterhin deine Aufgabe.
Um es also nochmal klar zu sagen, Du verwendest einfach immer OnRxChar, hängst die neuen Daten an eine Instanz-Variable an. Die eigentlichen Daten erhälst Du dann, indem Du sie aus dieser Variablen extrahierst. Wie Du das machst, kannst Du selbst entscheiden. Du kannst Trennzeichen verwenden, Du kannst die Länge der Daten festlegen, Du kannst beides mischen, Du kannst ganz anders vorgehen.
Haben Daten bei Dir immer eine feste Länge, so wirst Du kein Trennzeichen benötigen. Allerdings hast Du natürlich ein Problem, wenn Du hier irgendwann die Länge der Daten änderst. Natürlich kannst Du das leicht in der Software anpassen (wenn Du z.B. die Länge als Konstante an einer Stelle definiert hast). Aber da bleibt dann natürlich die Abwärtskompatiblität auf der Strecke.
Ist natürlich für dein jetziges Problem eher unwichtig, aber allgemein solltest Du das halt immer im Hinterkopf behalten. Das gleiche gilt dann natürlich sehr generell für dein Protokoll. Die RS-232-Schnittstelle übernimmt nur den Transport für Dich. Ob alle Daten korrekt übertragen wurden wird ebenso wenig geprüft wie bestätigt (oder eben negiert).
Das alles solltest Du halt berücksichtigen. Was davon wirklich nötig ist hängt natürlich sehr stark vom Einsatzgebiet ab. Ich denke nicht wirklich, dass Du hier mit dem Overhead einer Checksumme (oder ähnlichem) arbeiten solltest, aber mag ja Gebiete und Situationen geben, wo das mal nötig wäre. I.d.R. hat man aber wirklich kurze Strecken mit wirklich geringer Störranfälligkeit. Wie gesagt, letztlich kannst Du alles deinen Ansprüchen/Wünschen anpassen, die Schnittstelle dient nur zur Übertragung der Daten.
Gruß Der Unwissende