Hallo zusammen, ich habe eine Füllanlage und bekomme über einen RS232 Ausgang verschiedene Meldungen. Es gab einmal einen DOS Rechner zur Steuerung bzw. Ablaufkontrolle. Ich kann auch über einen MAX 232 die Daten empfangen. Die Daten sehen wie folgt aus. Die Zahlen können sich sehr unterscheiden, sind aber für die Steuerung nicht wichtig. Über eine Hilfe würde ich mich sehr freuen.
Grüße Alex
+Input1: 1,0,0,1,0
+Band1: 1,1,0,1,1,1
+Input2: 2,0,0,1,0
+STOER: 2,3,Zu Voll
Ich möchte je eine LED leuchten lassen wenn +Input1, +Input2, +Input3 und Input4 kommt und die vorherige LED löschen beim nächsten Schritt. Das funktioniert auch so, ebenfalls kann ich auch Text auf einem LCD Display anzeigen lassen. Die Störungsmeldungen +STOER: kann verschiedene Meldungen bringen. Z.b. "Zu Voll" "leer" "Glas pruefen" diese Meldungen möchte ich auf dem Display anzeigen lassen. Im Moment kommt "Stoerung", ich möchte aber die Fehler angezeigt haben.
Die Störungsmeldungen +STOER: kann verschiedene Meldungen bringen. Z.b. "Zu Voll" "leer" "Glas pruefen" diese Meldungen möchte ich auf dem Display anzeigen lassen. Im Moment kommt "Stoerung", ich möchte aber die Fehler angezeigt haben.
dann solltest im if von +STOER auch die weiteren Daten lesen und nach dem zweiten Komma den folgenden Text für die Feldermeldung am Display verwenden.
Leichter ist es aber vermutlich du liest immer alles von + zu + (oder Zeitablauf!) und parst dann ersten Teil für die Art der Meldung, und im Falle der +STOER eben auch den hinteren Teil.
Klingt sehr gut, aber wie kann ich anstatt ":" das Zeilenende als Eingabeschluss nehmen und wie teile ich den Inhalt mit einem Trennzeichen "," ?
Ich habe schon einiges gelesen komme aber noch nicht auf den "grünen Zweig".
Als hoffentlich letztes; wie bekomme ich dann das nach dem 2. "," auf das Display.
Ich habe vor ca. 3 Wochen mit dem Arduino angefangen und bin schon ganz glücklich über mein Ergebniss.
Ach du hättest eh ein LF oder CR am Ende einer Ausgabe?
Finde raus ob LF oder CR.
Kannst dich drauf verlassen dass das zweite Komma immer an der gleichen Stelle steht oder können da auch mehrstellige Zahlen kommen?
012345678901
+STOER: 2,3,Zu Voll
im einfacheren Fall könntest also einfach ab stelle 12 bis EOL lesen.
geht das?
und wenn nicht, ich sehe du nimmst eh schon ein String Objekt. Da gibts ja eh viele Funktionen zum durchsuchen:
wenn du auf dieser Codebasis weiterarbeiten willst ... lies bis zum Zeilenende, mach deine Vergleiche über substrings oder startsWith und nur im +STOER suchst halt nach dem letzten Beistrich
... da gibts sicher auch was ... z.B. lastIndexOf ...
und dann bis zum Ende und du hast deinen Text.
schön ist es nicht, aber so für die ersten 3 Wochen schon ok
ach ja und bitte pack deinen code in code tags ...(eckige Klammer code eckige klammer zu)
vielen Dank an euch, ich lese dann mal den Beitrag durch, leider sind die Zahlenwerte von unterschiedlicher Länge. Also enfach die Stellen abzählen kann ich da nicht machen.
Aus den vielen Beispielen im Forum hab ich mal ein weiteres Beispiel gebastelt
Es teilt die Zeichenketten (die "Telegramme") aus dem Ausganspost in einzelne Teile auf:
/* Telegrammauswertung
* Ein Datentelegramm soll in seine Bestandteile zerlegt werden.
* Jedes Telegramm wird durch CR oder LF abgeschlossen.
* Beispiele:
* +Input1: 1,0,0,1,0
* +Band1: 1,1,0,1,1,1
* +Input2: 2,0,0,1,0
* +STOER: 2,3,Zu Voll
*
* siehe:
* https://de.wikibooks.org/wiki/C-Programmierung:_Zeichenkettenfunktionen#strtok
*/
const int SERIAL_BUFFER_SIZE = 30; // die maximale Telegrammlänge (die Endzeichen nicht vergessen)
char serial_buffer[SERIAL_BUFFER_SIZE];
void setup() {
Serial.begin(9600);
}
void loop() {
if (read_serial())
{
parse_serial();
}
}
// Einlesen einzelner Zeichen und Anhängen an ein Char-Array.
// True, wenn das Zeilenende (CR oder LF) erreicht ist.
bool read_serial() {
static byte index;
while (Serial.available()) {
char c = Serial.read();
if (c >= 32 && index < SERIAL_BUFFER_SIZE - 1) {
serial_buffer[index++] = c;
}
else if (c == '\r' || c == '\n') { // \r ist CR, \n = LF
serial_buffer[index] = '\0'; // Array abschließen
index = 0;
return true;
}
}
return false;
}
// Trennen und Ausgeben der einzelnen Abschnitte des Telegramms
void parse_serial() {
char trennzeichen[] = {"+:,"};
char *abschnitt;
abschnitt = strtok(serial_buffer, trennzeichen); // Zerteilen
while (abschnitt != NULL) { // Ausgabe
Serial.println(abschnitt);
abschnitt = strtok(NULL, trennzeichen);
}
Serial.println();
}
Du musst das natürlich noch auf deine Gegebenheiten anpassen.
Sowohl die Eingabe als auch die Ausgabe erfolgen über den seriellen Monitor.
Getrennt wird bei folgenden Zeichen: Plus, Doppelpunkt, Komma (+:,)
Die folgenden Schritte könnten sein: Weitere Auswertungen der Abschnitte im Telegramm.
Also zum Beispiel ob "Input1", "Input2", "STOER" u.s.w. vorkommt (das geht mit strcmp - siehe Link unten)
Oder eine Auswertung der Zahlenwerte (dazu gibt es atoi).
Je nachdem, was du brauchst.
Ich habe nun folgendes gefunden und angepasst. Leider finde ich keine Möglichkeit meinen Sting "cmd" in einen char* zu wandeln.
Wer kann mir da einen Tipp geben?
hiermit kann ich ein Char* teilen und Einzelteile anzeigen lassen.
Hallo zusammen,
ich habe nun in Ruhe die Link´s und Kommentare durchgeackert. Es waren sehr hilfreiche Tipps, die mir hilfreich zu einem funktionierenden Ergebniss geholfen haben. Vielen Dank für Eure Hilfe. Wahrscheinlich ist meine Lösung nicht optimal, aber es funktioniert
Grüße Alex
hier noch mein CODE:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <stdio.h>
#include <string.h>
const int SERIAL_BUFFER_SIZE = 38; // die maximale Telegrammlänge (die Endzeichen nicht vergessen)
char serial_buffer[SERIAL_BUFFER_SIZE];
LiquidCrystal_I2C lcd(0x27,20,4);
void setup()
{
Serial.begin(9600);
lcd.begin(); //startet lcd
lcd.backlight();
Serial.println("Fuellanlage");
lcd.print("Fuellanlage");
delay(1000);
lcd.clear();
}
void loop() {
if (read_serial())
{
parse_serial();
}
}
// Einlesen einzelner Zeichen und Anhängen an ein Char-Array.
// True, wenn das Zeilenende (CR oder LF) erreicht ist.
bool read_serial() {
static byte index;
while (Serial.available()) {
char c = Serial.read();
if (c >= 32 && index < SERIAL_BUFFER_SIZE - 1) {
serial_buffer[index++] = c;
}
else if (c == '\r' || c == '\n') { // \r ist CR, \n = LF
serial_buffer[index] = '\0'; // Array abschließen
index = 0;
return true;
}
}
return false;
}
// Trennen und Ausgeben der einzelnen Abschnitte des Telegramms
void parse_serial() {
char trennzeichen[] = {"+:,"};
char* token = strtok(serial_buffer, ":,");
char* ta = token;
token= strtok(0, ",");
char* tb = token;
token = strtok(0, ",");
char* tc = token;
token = strtok(0, ",");
char* td = token;
token = strtok(0, ",");
char* te = token;
char Steor = ("Stoer");
char In1 = ("Input1");
if(strcmp(ta, Stoer) == 0)
{
digitalWrite(13, HIGH);//Nur zum Testen
Serial.println("Stoer");
Serial.println(td);
lcd.print(td);
}
if(strcmp(ta, In1) == 0)
{
Serial.println("Input1");
digitalWrite(13, LOW);//Nur zum Testen
}
}