Waveshare Barcode Scanner und Arduino

Guten Abend zusammen,

Mein Vorhaben:
Ich habe folgendes vor, ich möchte jeden Barcode Scanner mit einem NodeMCU Lolin V3 bestücken,
(Ins 4 Stück) Dann möchte ich über Telegram einen Text schicken, dieser wird dann verarbeitet und alle parametrierten Scanner sollen einen Barcode Scannen, und diesen dann untereinander vergleichen. das Ergebnis soll mir dann über Telegram geschickt werden.

Mein Equipment:
NodeMCU lolin V3
Waveshare Barcode Scanner
Anleitung vom Scanner
Logiclvl Converter

Mein aktueller Stand:
Ich habe mit dem NodeMCU schon erfolgreich Temperatur und Füllstandswerte abgefragt und über Telegram geschickt bekommen.
Da ich die Lvl converter noch nicht habe, habe ich den Barcode Scanner noch nicht an dem NodeMCU angeschlossen sondern erstmal mit einem Arduino Uno Nachbau herum probiert.
Ich kriege ausgelesen was der Scanner liest (UART). Jedoch nur wenn ich den dafür vorgesehenen Knopf drücke.

Mein aktuelles Problem:
Ich schaffe es nicht dem Scanner über software Serial zu sagen, dass er jetzt scannen soll.

Hier der Code mit dem das auslesen funktioniert, wenn ich den Knopf drücke:

// QR
// Restore Factory Settings 
// UART Output     
// Continuous Mode 
// Non-Scanning Interval 
// Lighting - No light 

#include <Arduino.h>                              
#include <wiring_private.h>
#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); // RX, TX


// data coming from the serial port
String inputString = "";        
// the line has arrived
boolean stringComplete = false;  
int countstr=0;
// to search for an ending
unsigned long millisendstr=0;



void setup() {
  // 
  Serial.begin(9600);
  mySerial.begin(9600);               // Begin Serial1

  inputString.reserve(50);
}

void loop() {
  // 
  serialScanerEvent();
  //
  if (stringComplete) {
    Serial.println(inputString);
    inputString = "";
    stringComplete = false;
    countstr=0;
   }
  
}

void serialScanerEvent() {
  //
  if (mySerial.available()>0) {
    // get the new byte:
    char inChar = (char)mySerial.read();
    // add it to the inputString:
    inputString += inChar;
    countstr++;
    millisendstr=millis();
  }
  else {
    if(millis()-millisendstr>1000 && countstr>0) {
       stringComplete=true;
    }
  }
}

Meine Versuche zum schicken eines Scan Befehls:

Das hier habe ich dazu gefunden:
4. Command Mode
In command mode, scanner will begin scanning after receive the command from
MCU. (That is set bit0 to 1 on address 0x0000).
Note: The scanning command (UART) is that:7E 00 08 01 00 02 01 AB CD. The
scanner module will response bytes (02 00 00 01 00 33 31) for the command and
begin scanning at the same time.

Mein Versuch war der hier:

    Serial.println("Sende einschalten");
    byte message[] = {0x7E, 0x00, 0x08, 0x01, 0x00, 0x02, 0x01, 0xAB, 0xCD };   // Sende Einschalten
    mySerial.write(message, sizeof(message));

jedoch kriege ich darauf keine Antowort.
Ich habe noch gelesen dass man jeden Abschnitt auch einzeln einfach nur über
mySerial.write(0x7E);
mySerial.write(0x00);
mySerial.write(0x08);
mySerial.write(0x01);
mySerial.write(0x00);
mySerial.write(0x02);
mySerial.write(0x01);
mySerial.write(0xAB);
mySerial.write(0xCD);
schicken kann, da kriege ich aber dann Fehlermeldungen die ich nicht nachvollziehen kann.





C:\Users\Sven\Documents\Arduino\ArduinoBarCodeReaderKnopf\ArduinoBarCodeReaderKnopf.ino: In function 'void loop()':
ArduinoBarCodeReaderKnopf:36:22: error: call of overloaded 'write(int)' is ambiguous
   mySerial.write(0x00);
                      ^
In file included from C:\Users\Sven\Documents\Arduino\ArduinoBarCodeReaderKnopf\ArduinoBarCodeReaderKnopf.ino:10:0:
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SoftwareSerial\src/SoftwareSerial.h:102:18: note: candidate: virtual size_t SoftwareSerial::write(uint8_t)
   virtual size_t write(uint8_t byte);
                  ^~~~~
In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Stream.h:26:0,
                 from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h:29,
                 from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:233,
                 from C:\Users\Sven\Documents\Arduino\ArduinoBarCodeReaderKnopf\ArduinoBarCodeReaderKnopf.ino:8:
C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:52:12: note: candidate: size_t Print::write(const char*)
     size_t write(const char *str) {
            ^~~~~
ArduinoBarCodeReaderKnopf:39:22: error: call of overloaded 'write(int)' is ambiguous
   mySerial.write(0x00);
                      ^
In file included from C:\Users\Sven\Documents\Arduino\ArduinoBarCodeReaderKnopf\ArduinoBarCodeReaderKnopf.ino:10:0:
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SoftwareSerial\src/SoftwareSerial.h:102:18: note: candidate: virtual size_t SoftwareSerial::write(uint8_t)
   virtual size_t write(uint8_t byte);
                  ^~~~~
In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Stream.h:26:0,
                 from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h:29,
                 from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:233,
                 from C:\Users\Sven\Documents\Arduino\ArduinoBarCodeReaderKnopf\ArduinoBarCodeReaderKnopf.ino:8:
C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:52:12: note: candidate: size_t Print::write(const char*)
     size_t write(const char *str) {
            ^~~~~
exit status 1
call of overloaded 'write(int)' is ambiguous

Hatte mir schon überlegt, mir es einfacher zu machen und an dem Knopf zum starten Scan einfach eine Ader anzulöten und diesen über einen Pin zu schalten.

Hat einer von euch noch eine Idee?

Wenn Sie die ambiguous call of overloaded 'write(int)' nicht möchten, teilen Sie dem Compiler mit, dass Ihre Zahl ein Byte und kein Int (Standard) ist.

mySerial.write((byte) 0x7E);
mySerial.write((byte) 0x00);
mySerial.write((byte) 0x08);
mySerial.write((byte) 0x01);

aber das war OK

    byte message[] = {0x7E, 0x00, 0x08, 0x01, 0x00, 0x02, 0x01, 0xAB, 0xCD };   // Sende Einschalten
    mySerial.write(message, sizeof(message));

Haben Sie auch überprüft, ob Ihr Modul mit 3,3 V kompatibel ist (und keine 5 V auf Tx sendet)?

Deswegen teste ich zurzeit auf einem Arduino Uno weil ich noch keine Lvl Converter habe.

9600Baud sind standard bei dem Scanner eingestellt.
Laut dem Datenblatt, müsste es 8-N-1 sein.(Seite 51)

Entschuldigung, das habe ich nicht verstanden.

Ich teste die Scanner aktuell nur mit einem Arduino Uno R3, weil ich die Logic Lvl converter von 5v zu 3,3v noch nicht bei mir liegen habe. Deswegen habe ich den Barcode Scanner noch nicht an einem NodeMCU Lolin v3 angeschlossen. Soweit ich weiß arbeitet der Arduino Uno R3 doch mit 5v oder?

stimmt, Können Sie das testen?

#include <Arduino.h>
#include <SoftwareSerial.h>

SoftwareSerial waveshareSerial(2, 3); // RX, TX

const byte scanningCommand[] = {0x7E, 0x00, 0x08, 0x01, 0x00, 0x02, 0x01, 0xAB, 0xCD };   // Sende Einschalten

void printByte(byte b) {
  if (b < 0x10) Serial.write('0');
  Serial.print(b, HEX);
  Serial.write(' ');
}

void setup() {
  Serial.begin(115200);
  waveshareSerial.begin(9600); // Waveshare Barcode Scanner
  Serial.println("Sende einschalten");
  waveshareSerial.write(scanningCommand, sizeof(scanningCommand));
}

void loop() {
  int r = waveshareSerial.read();
  if (r != -1) printByte(r);
}


Stellen Sie sicher, dass GND angeschlossen ist.
Arduino Pin 2 (Rx) verbunden mit Waveshares Tx
Arduino Pin 3 (Tx) verbunden mit Waveshares Rx

Ich glaube, scannen will er jetzt da kommen aber jetzt nur umgedrehte Fragezeichen anstelle von dem gescannten barcode.

image

Es gibt keinen Grund, langsam zu gehen

➜ auf 115200 Baud umstellen :wink: weil ich Serial.begin (115200); verwendet habe.

Ahh nicht gesehen, danke.

Leider kommt egal welchen Barcode ich davor halte, immer die selbe Antwort. Ich glaube so langsam der Befehl ist noch nicht der richtige.

Okay, ich musste noch auf Seite 21 den QR Code scannen um den Scanner in den Command Mode zu schalten. Jetzt scannt er.

Wie Sie erhalten

image

und die spezifikation sagt

Zumindest wissen Sie, dass das Modul den Command richtig empfängt.

Haben Sie das Modul richtig konfiguriert? (indem Sie die richtigen Konfigurationscodes gescannt haben?)

Ich musste noch diesen QR Code Scannen:

Jetzt scannt er den Code.

Ich habe deinen Teil vom Code jetzt so in meinem eingearbeitet:

// QR
// Restore Factory Settings 
// UART Output     
// Continuous Mode 
// Non-Scanning Interval 
// Lighting - No light 

#include <Arduino.h>                              
#include <wiring_private.h>
#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); // RX, TX
const byte scanningCommand[] = {0x7E, 0x00, 0x08, 0x01, 0x00, 0x02, 0x01, 0xAB, 0xCD };   // Sende Einschalten



// data coming from the serial port
String inputString = "";        
// the line has arrived
boolean stringComplete = false;  
int countstr=0;
// to search for an ending
unsigned long millisendstr=0;



void setup() {
  // 
  Serial.begin(9600);
  mySerial.begin(9600);               // Begin Serial1

  inputString.reserve(50);
  Serial.println("Sende einschalten");
  mySerial.write(scanningCommand, sizeof(scanningCommand));
}

void loop() {
  //
  serialScanerEvent();
  //
  if (stringComplete) {
    Serial.println(inputString);
    inputString = "";
    stringComplete = false;
    countstr=0;
   }
  
}

void printByte(byte b) {
  if (b < 0x10) Serial.write('0');
  Serial.print(b, HEX);
  Serial.write(' ');
}
void serialScanerEvent() {
  //
  if (mySerial.available()>0) {
    // get the new byte:
    char inChar = (char)mySerial.read();
    // add it to the inputString:
    inputString += inChar;
    countstr++;
    millisendstr=millis();
  }
  else {
    if(millis()-millisendstr>1000 && countstr>0) {
       stringComplete=true;
    }
  }
}

Da habe ich dann die Zahl die unter dem Barcode steht direkt so zur verfügung, oder ist es wenig aufwand 34 30 36 30 31 33 37 30 35 37 34 36 35 0D so eine Ausgabe von Hexadezimal in Dezimal umzuwandeln?

Sie machen gute Fortschritte!

könnten Sie diesen Code ausführen?

#include <Arduino.h>
#include <SoftwareSerial.h>

SoftwareSerial waveshareSerial(2, 3); // RX, TX

const byte scanningCommand[] = {0x7E, 0x00, 0x08, 0x01, 0x00, 0x02, 0x01, 0xAB, 0xCD };   // Sende Einschalten

void printByte(byte b) {
  if (b < 0x10) Serial.write('0');
  Serial.print(b, HEX);
  Serial.write('\t');
}

void setup() {
  Serial.begin(115200);
  waveshareSerial.begin(9600); // Waveshare Barcode Scanner
  Serial.println("Sende einschalten");
  waveshareSerial.write(scanningCommand, sizeof(scanningCommand));
}

void loop() {
  int r = waveshareSerial.read();
  if (r != -1) {
    printByte(r);
    if (isalnum(r)) Serial.println((char) r); else Serial.println(F("--"));
  }
}


Die Ausgabe sieht jetzt so aus:

Im späteren Verlauf möchte ich mehrere Barcodes miteinander vergleichen
gibt es so eine einfache Möglichkeit, um alles an Daten was ich nicht brauche einfach raus zu schneiden um nur noch die reinen Zahlen 4060137057465 mit z.b. 4060137057466 zu vergleichen?

Cool

Sie müssen also die Kopfzeile überspringen
dann kommen die Daten und der Scan wird mit einem 0x0D (Carriage Return in ASCII) beendet.

Sie könnten den Text einfach in einem char-Array speichern, stoppen, wenn Sie 0x0D erhalten, und ein Nullzeichen '\ 0' in Ihrem Array speichern. Sie haben dann einen cString, der dem Scan entspricht und können ihn mit strcmp() mit anderen cStrings vergleichen.

Vielen Dank für deine Hilfe, dann werde ich mich da mal ran setzen

Da das Modul anscheinend nur nicht alphanumerische Zeichen für die Konfiguration sendet, können Sie diese einfach ignorieren und nur die Daten speichern if (isalnum(r)) .... bis Sie ein 0x0D erhalten

Sie können auch ein Timeout verwenden, um die Eingabe zu ignorieren, wenn Sie das 0x0D . nicht erhalten haben

Viel Glück