Datenstring einem Ausgang zuordnen

Hallo,

kurz zu meinem Projekt, ich habe einen Barcodescanner mit dem ich vier verschiedene Barcodes
(vier verschidenen Produkte) scannen möchte, dabei möchte ich jeweils einen Datenstring von einem Barcode, einem Ausgang an der Arduino zuordnen bzw. setzen. Der Barcodescanner ist mit einer Arduino UNO über RS 232 mit dem PC verbunden (siehe Blockschaltbild).

Ich habe leider nicht so gute Kenntnisse um das Programm zu schreiben, kann mir da jemand weiterhelfen, mein Programm siehe unten.

Mein Programm:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);

void setup() {
mySerial.begin(2400);
Serial.begin(2400);

}

void loop() {
 if(mySerial.available() > 0) { // >0 hinzugefuegt
   char a=mySerial.read();
   Serial.write(a);
 }
 if(Serial.available() > 0) {
   char a = Serial.read();
   mySerial.print(a);
 }
}

Folgende Datenstrings:

(empfangene Datenstrings vom Barcodescanner, ausgelesen mit Terminalprogramm)

Produckt 1:

[STX]TT=_7450ms MG=__8% n=_1[CR ]
[LF ]Produkt 1[CR ]
[LF ]C128 __1% ST=0 CP=_44 CL=_9 CA=258 CS=__3 CK=__1[CR ]
[LF ][LF ][CR ]
[ETX]

Produkt 2:

[STX]TT=_2040ms MG=__8% n=_1[CR ]
[LF ]Produkt 2[CR ]
[LF ]C128 __7% ST=0 CP=_44 CL=_9 CA=_40 CS=__3 CK=__1[CR ]
[LF ][LF ][CR ]
[ETX]

Produkt 3:

[STX]TT=__290ms MG=__7% n=_1[CR ]
[LF ]Produkt 3[CR ]
[LF ]C128 _25% ST=0 CP=_42 CL=_9 CA=_12 CS=__3 CK=__2[CR ]
[LF ][LF ][CR ]
[ETX]

Produkt 4:

[STX]TT=_3120ms MG=__7% n=_1[CR ]
[LF ]Produkt 4[CR ]
[LF ]C128 _15% ST=0 CP=_43 CL=_9 CA=_19 CS=__3 CK=__1[CR ]
[LF ][LF ][CR ]
[ETX]

Fehllesung:

[STX]TT=_1300ms MG=__7% n=_0[CR ]
[LF ]kein Code ![CR ]
[LF ][CR ]
[LF ][LF ][CR ]
[ETX]

Vielen Dank im Voraus

Gruß mc000

Blockschaltbild.jpg

mc000:
Folgende Datenstrings:

(empfangene Datenstrings vom Barcodescanner, ausgelesen mit Terminalprogramm)

Produckt 1:

[STX]TT=_7450ms MG=__8% n=_1[CR ]
[LF ]Produkt 1[CR ]
[LF ]C128 __1% ST=0 CP=_44 CL=_9 CA=258 CS=__3 CK=__1[CR ]
[LF ][LF ][CR ]
[ETX]

Merkwürdige Ausgaben.

Die Barcodescannner, die ich kenne, liefern beim Scannen von EAN-Barcodes auf Produktverpackungen entweder eine 8-stellige oder 13-stellige Zahl, je nachdem, ob man einen EAN-8 oder EAN-13 Barcode scannt. Ggf. gefolgt von Steuerzeichen für Zeilenende CR und LF.

Mit dem Roman, den Dein Scanner ausgibt, kann ich nichts anfangen.

Gibt es zu Deiner Scanner-Hardware eine technische Dokumentation?

Du scannst doch EAN-Barcodes, oder irgendwelche andere Barcodetypen?

Hallo jurs,

ich lese den Code 128 mit einer Modulbreite von 0,33 mm aus. Mein Barcodescanner liest das wie von Hersteller vorgesehen aus (siehe Quick Start Anleitung). Auf der Seite 6 wird das genau beschrieben.

Gruß mc000

Betriebsanleitung - CLV210.pdf (521 KB)

mc000:
Hallo jurs,

ich lese den Code 128 mit einer Modulbreite von 0,33 mm aus. Mein Barcodescanner liest das wie von Hersteller vorgesehen aus (siehe Quick Start Anleitung). Auf der Seite 6 wird das genau beschrieben.

Gruß mc000

Also das " n=_1" in der Ausgabe steht wohl dafür, dass ein Barcode gelesen wurde, aber ich sehe nicht, welcher Klartext bei dir aus dem Barcode gelesen wurde.

Der Klartext ist Produkt 1, Proudukt 2 ....Wird in der BA als Code Content bezeichnet.

mc000:
Der Klartext ist Produkt 1, Proudukt 2 ....Wird in der BA als Code Content bezeichnet.

Eine brauchbare Einleselogik würde dann wohl ungefähr so aussehen:

  • alle eintreffenden ASCII-Zeichen zeilenweise einlesen
  • wenn eine eingelesene Zeile länger als null ist und KEIN Gleicheitszeichen '=' enthält, ist es der Barcode-Klartext.

Bei einer Fehllesung würdest Du zurückbekommen "kein Code !"

Und je nachdem soll im Programm dann etwas bestimmtes passieren, oder?

Und dafür kannst Du keinen Code schreiben?

Also immer wenn Produkt 1,2,3,4 oder kein code gescannt wird, dann soll ein Ausgang z.B 4,5,6,7 oder 8 gesetzt werden.

Und wenn ich mich nicht irre dann ist z.B. pinMode(4, OUTPUT); der befehl dafür. Und jetzt muss man das ganze in ein ganzes Programm schreiben, wo ich Hilfe benötige.

mc000:
Also immer wenn Produkt 1,2,3,4 oder kein code gescannt wird, dann soll ein Ausgang z.B 4,5,6,7 oder 8 gesetzt werden.

Und wenn ich mich nicht irre dann ist z.B. pinMode(4, OUTPUT); der befehl dafür. Und jetzt muss man das ganze in ein ganzes Programm schreiben, wo ich Hilfe benötige.

Also der Barcodereader soll über SoftwareSerial mit 2400 Baud ausgelesen werden, wie es aussieht:

mySerial.begin(2400);

OK, ich probiere mal was zusammenzuschreiben, das Du dann testen kannst.

Vielen dank !!

mc000:
Vielen dank !!

Hier ein Code zum Testen:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);



char* readSerialLine()
// reads serial command lines that are finished with a carriage return (CR, ASCII-13)
// non blocking version
// returns true if command is finished with CR (ASCII-13, '\n')
// return false if no input from Serial is available or if command is not yet finished
{
  static char str[26]; // read a command up to 25 chars length + '\0' 
  static byte count=0;
  if (mySerial.available())
  {
    while (mySerial.available())
    {
      if (count==0) memset(str,0,sizeof(str)); // delete string by writing zeros to it
      char c=mySerial.read();
      if (c>=32 && count<sizeof(str)-1) // valid ASCII char
      {
        str[count]=c;
        count++;
      }
      else if (c==13 && count>0) // if carriage return received
      {
        count=0;
        return str;
      }
    }
  }
  return NULL;  
}

void setup() {
mySerial.begin(2400);
Serial.begin(2400);
}

void loop() 
{
  char* barcode=readSerialLine();
  if(barcode==NULL) return;
  if(strchr(barcode,'=')==NULL) // kein Gleichheitszeichen?
  Serial.println(barcode); // auf dem seriellen Monitor ausgeben
}

Wenn es funktioniert, dann soll der Code das machen:

  • Zeichen mit 2400 Baud von mySerial (vom Barcodereader) einlesen
    und gelesene Zeilen an den seriellen Monitor senden (auch mit 2400 Baud)

Teste mal!

Ok ! Jetzt wird auf dem Seriellen Monitor nur Produkt 1, Produkt 2,... und kein Code !, beim einlesen Anzeigt und nicht mehr der ganze String.

Jetzt muss ich nur noch wissen wie ich diese Wörter den Ausgängen zuordne, also so ungefähr:

Produkt 1 = 4 ( word, int ????)

Produkt 2 = 5

Produkt 3 = 6

Produkt 4 = 7

kein Code ! = 8

void setup()

{
pinMode(Produkt 1, OUTPUT); // sets the digital pin as output

pinMode(Produkt 2, OUTPUT);

pinMode(Produkt 3, OUTPUT);

pinMode(Produkt 4, OUTPUT);

pinMode(kein Code !, OUTPUT);
}

void loop()
{

if digitalWrite(Produkt 1, HIGH);
delay(1000);

if digitalWrite(Produkt 2, HIGH);
delay(1000);

if digitalWrite(Produkt 3, HIGH);
delay(1000);

if digitalWrite(Produkt 4, HIGH);
delay(1000);

if digitalWrite(kein Code !, HIGH);
delay(1000);

}

mc000:
Ok ! Jetzt wird auf dem Seriellen Monitor nur Produkt 1, Produkt 2,... und kein Code !, beim einlesen Anzeigt und nicht mehr der ganze String.

Jetzt muss ich nur noch wissen wie ich diese Wörter den Ausgängen zuordne, also so ungefähr:

Produkt 1 = 4 ( word, int ????)

Zur Feststellung, ob ein (nullterminierter) String innerhalb eines anderen nullterminierten Strings vorkommt, kannst Du in C/C++ die strstr() Funktion verwenden, >siehe http://www.cplusplus.com/reference/cstring/strstr/

Also beispielsweise in der loop Funktion mit so einer if-Abfrage vergleichen:

if(strstr(barcode,"Produkt 1")) tueDies();
else if(strstr(barcode,"Produkt 2"))tueDas();

Hallo jurs,

ich habe da nochmal eine Frage, um die Ausgänge zu setzen, habe ich das wie unten geschrieben, beim überprüfen tritt ein Fehler auf:

exit status 1
'barcode' was not declared in this scope

und erkennt er den Befehl pinmode bzw. weiß er jetzt zu welchem Ausgang er die Produkte zuordnen muss?

void loop()
{
if(strstr(barcode,"Produkt 1")) pinmode(4,Output);
else if(strstr(barcode,"Produkt 2")) pinmode(5,Output);
else if(strstr(barcode,"Produkt 3")) pinmode(6,Output);
else if(strstr(barcode,"Produkt 4")) pinmode(7,Output);
else if(strstr(barcode,"kein Code !"))pinmode(8,Output);
}
char* barcode=readSerialLine();
if(barcode==NULL) return;
if(strchr(barcode,'=')==NULL) // kein Gleichheitszeichen
Serial.println(barcode); // auf dem seriellen Monitor ausgeben

}

Gruß mc000

mc000:
exit status 1
'barcode' was not declared in this scope

Ja, in meinem Beispielcode in Antwort#9 ist barcode als Sringpointer-Variable innerhalb(!) der loop()-Funktion deklariert, in Deinem Code jedoch NICHT.

Mit nicht-deklarierten Variablen kann der Compiler in einer Funktion nichts anfangen.

Ich hab etwas probiert, was leider nicht funktioniert. Ich bin ratlos. Ich bin mir nichtmal sicher ob ich den Befehl pinmode verwenden kann, was normalerweise funktioniert, aber ob das in dem Code so ist, weiß ich leider nicht.

In diesem Code wird beim überprüfen , bei der deklarieren von pinmode gemerkert^^.
und wenn ich Pinmode so deklariere dann geht das auch nicht, so z.B.:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);

int Produkt 1 = 4
int Produkt 2 = 5
int Produkt 3 = 6
int Produkt 4 = 7
int kein Code ! = 8

char* readSerialLine()
// reads serial command lines that are finished with a carriage return (CR, ASCII-13)
// non blocking version
// returns true if command is finished with CR (ASCII-13, '\n')
// return false if no input from Serial is available or if command is not yet finished
{
static char str[26]; // read a command up to 25 chars length + '\0'
static byte count=0;
if (mySerial.available())
{
while (mySerial.available())
{
if (count==0) memset(str,0,sizeof(str)); // delete string by writing zeros to it
char c=mySerial.read();
if (c>=32 && count<sizeof(str)-1) // valid ASCII char
{
str[count]=c;
count++;
}
else if (c==13 && count>0) // if carriage return received
{
count=0;
return str;
}
}
}
return NULL;

}

void setup()
{
mySerial.begin(2400);
Serial.begin(2400);
}

void loop()
{

char* barcode=readSerialLine();
if(barcode==NULL) return;
if(strchr(barcode,'=')==NULL) // kein Gleichheitszeichen
Serial.println(barcode); // auf dem seriellen Monitor ausgeben

if(strstr(barcode,"Produkt 1")) pinmode(4, Output);
else if(strstr(barcode,"Produkt 2"))pinmode(5, Output);
else if(strstr(barcode,"Produkt 3"))pinmode(6, Output);
else if(strstr(barcode,"Produkt 4"))pinmode(7, Output);
else if(strstr(barcode,"kein Code !"))pinmode(8, Output);
}

Hast du eine Idee ?

mc000:
Ich hab etwas probiert, was leider nicht funktioniert. Ich bin ratlos. Ich bin mir nichtmal sicher ob ich den Befehl pinmode verwenden kann, was normalerweise funktioniert, aber ob das in dem Code so ist, weiß ich leider nicht.

Für den Compiler kommt es bei Variablen- und Funktionsnamen nicht nur auf die richtige Reihenfolge von Buchstaben an, sondern auch auf die richtige Gross- und Kleinschreibung, z.B. in "pinMode" und "OUTPUT"

Die Programmiersprache C/C++ toleriert keine Falschschreibung!Auch nicht falsche Gross- und Kleinschreibung!

Die Schreibweise muss immer der Deklaration entsprechen!

Also beispielsweise pinMode und OUTPUT und nicht irgendwie.

Also jetzt haut es hin, nach dem kompilieren scheint der Code zu stimmen. Siehts du einen Fehler, ich werde es morgen testen.

Ich habe keine Leerzeichen mehr, also zwischen Produkt und 1, etc
Bei kein Code ! entfallen die Leerzeichen und das !.
Die Frage ist hier ob er jetzt den String bzw. Klartext erkannt wird, da unten im Code ja die Leerzeichen vorhanden sind. Wenn ich die Leerzeichen und das ! lasse, kommt die Fehlermeldung:

expected initializer before numeric constant

int Produkt1 = 4;
int Produkt2 = 5;
int Produkt3 = 6;
int Produkt4 = 7;
int keinCode = 8;

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);

char* readSerialLine()
// reads serial command lines that are finished with a carriage return (CR, ASCII-13)
// non blocking version
// returns true if command is finished with CR (ASCII-13, '\n')
// return false if no input from Serial is available or if command is not yet finished
{
static char str[26]; // read a command up to 25 chars length + '\0'
static byte count=0;
if (mySerial.available())
{
while (mySerial.available())
{
if (count==0) memset(str,0,sizeof(str)); // delete string by writing zeros to it
char c=mySerial.read();
if (c>=32 && count<sizeof(str)-1) // valid ASCII char
{
str[count]=c;
count++;
}
else if (c==13 && count>0) // if carriage return received
{
count=0;
return str;
}
}
}
return NULL;

}

void setup()
{
mySerial.begin(2400);
Serial.begin(2400);
}

void loop()

{

char* barcode=readSerialLine();
if(barcode==NULL) return;
if(strchr(barcode,'=')==NULL) // kein Gleichheitszeichen
Serial.println(barcode); // auf dem seriellen Monitor ausgeben

if(strstr(barcode,"Produkt 1")) pinMode(4,OUTPUT);
else if(strstr(barcode,"Produkt 2"))pinMode(5,OUTPUT);
else if(strstr(barcode,"Produkt 3"))pinMode(6,OUTPUT);
else if(strstr(barcode,"Produkt 4"))pinMode(7,OUTPUT);
else if(strstr(barcode,"kein Code !"))pinMode(8,OUTPUT);
}

mc000:
Also jetzt haut es hin, nach dem kompilieren scheint der Code zu stimmen. Siehts du einen Fehler, ich werde es morgen testen.

Ich habe keine Leerzeichen mehr, also zwischen Produkt und 1, etc
Bei kein Code ! entfallen die Leerzeichen und das !.
Die Frage ist hier ob er jetzt den String bzw. Klartext erkannt wird, da unten im Code ja die Leerzeichen vorhanden sind. Wenn ich die Leerzeichen und das ! lasse, kommt die Fehlermeldung:

expected initializer before numeric constant

Ja natürlch. In einem Bezeichner (identifier) für einen Variablen- oder Funktionsnamen sind keine Leerzeichen erlaubt.

Leer- und Sonderzeichen können dagegen in einer Zeichenkette(String) problemlos enthalten sein.

Hallo jurs,

ich habe die Zuordnung mit hilfe von LEDs getestet, es funktioniert alles super. Ich musste noch lediglich eine Kleinigkeit ändern.

void setup()
{
mySerial.begin(2400);
Serial.begin(2400);

pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);

}
void loop()

{
char* barcode=readSerialLine();
if(barcode==NULL) return;
if(strchr(barcode,'=')==NULL) // kein Gleichheitszeichen
Serial.println(barcode); // auf dem seriellen Monitor ausgeben

if(strstr(barcode,"Produkt 1")) digitalWrite(4,HIGH);
else if(strstr(barcode,"Produkt 2"))digitalWrite(5,HIGH);
else if(strstr(barcode,"Produkt 3"))digitalWrite(6,HIGH);
else if(strstr(barcode,"Produkt 4"))digitalWrite(7,HIGH);
else if(strstr(barcode,"kein Code !"))digitalWrite(8,HIGH);
}

Da digitalWrite der richtige Befehl ist, um einen Ausgang zu setzten.
Hierzu habe ich noch eine Frage: Der Augang soll nach einer Zeit wieder zurückgesetzt werden, man könnte hier das so schreiben:

void setup()
{
mySerial.begin(2400);
Serial.begin(2400);

pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);

}
void loop()

{
char* barcode=readSerialLine();
if(barcode==NULL) return;
if(strchr(barcode,'=')==NULL) // kein Gleichheitszeichen
Serial.println(barcode); // auf dem seriellen Monitor ausgeben

if(strstr(barcode,"Produkt 1")) digitalWrite(4,HIGH); delay(1000);digitalWrite(4,LOW); delay(1000)
else if(strstr(barcode,"Produkt 2"))digitalWrite(5,HIGH);
else if(strstr(barcode,"Produkt 3"))digitalWrite(6,HIGH);
else if(strstr(barcode,"Produkt 4"))digitalWrite(7,HIGH);
else if(strstr(barcode,"kein Code !"))digitalWrite(8,HIGH);
}

Wenn ich das auf diese Weise mache, dann gibt er mir folgenden Fehler: 'else' without a previous 'if'. Was ist hier jetzt falsch ?

Gruß mc000

Dein Programm würde sich über ein paar geschweifte Klammern mehr freuen. Grundsätzlich so:

if() {} else if() {} else {}

Sowas {digitalWrite(8,HIGH);} darf man dann in digitalWrite(8,HIGH); abkürzen.