Преобразование штрих кода в строку

ZmeyGo
Offline
Зарегистрирован: 06.03.2018

Здравствуйте! не могу решить проблемму при сканировании штрих кода выдает только первый символ. Сканер USB подлюченный через Shield. 

#include <hid.h>
#include <hiduniversal.h>
#include <usbhub.h>
#include <Usb.h>
#include <hidboot.h>
#include <avr/pgmspace.h>
#include <Wire.h> //I2C
#include <LiquidCrystal_I2C.h> //LCD 
#include <Ultrasonic.h> //Sonar 
#include <SoftwareSerial.h> 

SoftwareSerial mySerial(6, 5);//RX, TX
LiquidCrystal_I2C lcd(0x3F,16,2);  // set the LCD address to 0x27  or 0x3F  for a 16 chars and 2 line display
Ultrasonic axisX(8,9);   // (Trig PIN,Echo PIN)
Ultrasonic axisY(10,11);  // (Trig PIN,Echo PIN)
Ultrasonic axisZ(12,13);  // (Trig PIN,Echo PIN)

String SSID ="meest";

String PASS="sash5845";
#define DST_IP "8.8.8.8" //DIST_IP




class BarcodeReader : public KeyboardReportParser
{
    USB Usb;
    USBHub Hub;
    HIDUniversal Hid;
    HIDBoot<HID_PROTOCOL_KEYBOARD> Keyboard;

    uint8_t buffer[15];
    byte length;
    bool valid;

    void addCharacter(uint8_t c);

  public:
    BarcodeReader();
    void begin();
    void task();
    const uint8_t* barcode();
    void reset();

  protected:
    virtual void OnKeyDown(uint8_t mod, uint8_t key);
};

BarcodeReader::BarcodeReader()
  : Usb()
  , Hub(&Usb)
  , Hid(&Usb)
  , Keyboard(&Usb)
  , length(0)
  , valid(false)
{
}

void BarcodeReader::begin()
{
  if (Usb.Init() == -1) {
    Serial.println("OSC did not start.");
  }
  Hid.SetReportParser(1, this);
}

void BarcodeReader::task()
{
  Usb.Task();
}

void BarcodeReader::addCharacter(uint8_t c)
{
  if (valid) {
    // already have a barcode, new one will overwrite it
    reset();
  }



  buffer[length++] = c;
  //buffer[length] = '\0';
  
  if (buffer[length] == '\0') 
  {
    valid = true;
  }
};


const uint8_t* BarcodeReader::barcode()
{
  return (valid) ? buffer : 0;
}

void BarcodeReader::reset()
{
  length = 0;
  valid = false;
}

void BarcodeReader::OnKeyDown(uint8_t mod, uint8_t key) {
  uint8_t c = OemToAscii(mod, key);
  if (c) addCharacter(c);
}

BarcodeReader barcodeReader;

void setup() {

 
  Serial.begin(9600);
  mySerial.begin(115200);
lcd.begin();                      
lcd.begin();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Hello"); 
  
delay(5000);

Serial.println("Init");
mySerial.println("AT+RST"); // сброс и проверка, если модуль готов
delay(1000);
if(mySerial.find("OK"))
{Serial.println("WiFi - Module is ready");}
else
{Serial.println("Module dosn't respond.");
while(1);
}
delay(1000);
// соединение по wifi
boolean connected=false;
for(int i=0;i<5;i++)
{
if(connectWiFi())
{connected = true;
mySerial.println("Connected to Wi-Fi...");
break;
}
}
if (!connected)
{
mySerial.println("Coudn't connect to Wi-Fi.");
while(1);
}
delay(5000);
mySerial.println("AT+CIPMUX=0"); // режим одиночного соединения
  
  barcodeReader.begin();
 }

void loop() {
  barcodeReader.task();
 char* barcode = barcodeReader.barcode();
  
  if  (barcode) {
      
  String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += DST_IP;
cmd += "\",8283";
Serial.println(cmd);
mySerial.println(cmd);
if(mySerial.find("Error"))
return;
 double width = 100-axisX.Ranging(CM);
  Serial.println(width);
  delay(50);
  

  double lenght = 100-axisY.Ranging(CM);
  Serial.println(lenght);
  
  delay(50);

  double height = 100-axisZ.Ranging(CM);
  Serial.println(height);
  delay(50);

delay(10000);

  long format = (width*lenght*height)/1000000;
 
  Serial.println(format);
  lcd.clear();
  lcd.setCursor (2,0);
  
  lcd.print(width);
  lcd.print("x");
  
  lcd.print(lenght);
  lcd.print("x");
  
  lcd.print(height);
  lcd.print("cm");
   
  lcd.setCursor (4,1);
  lcd.print ("V=" );
  lcd.print(format);
  lcd.print ("M.kyb");
  
cmd = "#A0:F3:C1:70:AA:94\n#2881C4BA0200003B1#"+String(format)+"\n##"+barcode;
delay(3000);
mySerial.print("AT+CIPSEND=");
mySerial.println(cmd.length());
Serial.println(">");
mySerial.print(cmd);
Serial.println(cmd);
mySerial.println("AT+CIPCLOSE");
barcodeReader.reset();
        
    }
}
// процедура установки Wi-Fi-соединения
boolean connectWiFi()
{

  
String cmd="AT+CWJAP=\"" +SSID+"\",\"" + PASS + "\"";

mySerial.println(cmd);
Serial.println(cmd);
delay(2000);
if(mySerial.find("OK"))
{
Serial.println("OK, Connected to Wi-Fi.");
return true;
}
else
{
Serial.println("Can not connect to the Wi-Fi.");
return false;
}
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

В Вашем сообщении не было вопроса (было лишь утверждение, что Вы не можете решить проблему). Обычно в таких случаях я отвечаю "принято к сведению", но так и быть ... только впредь формулируйте свои вопросы чётко.

Ну, а чего Вы хотели?

Изначально вся память глобальных переменных обнулена.  Вот пришёл к Вам самый первый символ, вызывается функция addCharacter. В ней Вы проверяете valid, и, поскольку он false, добавляете этот символ в буфер. Затем в строке 85 Вы проверяете, а не ноль ли в следующем символе в буфере (а там именно 0, т.к. изначально буфер весь заполнен нулями). Ну, а раз 0, то Вы делаете valid истиной и больше никаких символов в буфер не добавляете, та.к. срабатывает проверка в строке 75.

ZmeyGo
Offline
Зарегистрирован: 06.03.2018

Спасибо за подсказку, попробовал но тогда не отрабатывает 157 и соответственно 159 строчки

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Я не знаю, что Вы пробовали. То, что я видел больше одного символа в принципе вводить не предназначено, а что Вы там пробовали ... Вы держите в секрете.

ZmeyGo
Offline
Зарегистрирован: 06.03.2018

Пробовал кучу всего. И не могу понять почему сканер возвращает только первый символ. Хочу чтоб штрих код передвался по вай фай в переменной cmd Подскажите новичку люди добрые.

#include <hid.h>
#include <hiduniversal.h>
#include <usbhub.h>
#include <Usb.h>
#include <hidboot.h>
#include <avr/pgmspace.h>
#include <Wire.h> //I2C
#include <LiquidCrystal_I2C.h> //LCD 
#include <Ultrasonic.h> //Sonar 
#include <SoftwareSerial.h> 

SoftwareSerial mySerial(6, 5);//RX, TX
LiquidCrystal_I2C lcd(0x3F,16,2);  // set the LCD address to 0x27  or 0x3F  for a 16 chars and 2 line display
Ultrasonic axisX(8,9);   // (Trig PIN,Echo PIN)
Ultrasonic axisY(10,11);  // (Trig PIN,Echo PIN)
Ultrasonic axisZ(12,13);  // (Trig PIN,Echo PIN)

String SSID ="net";

String PASS="Programm21";
#define DST_IP "8.8.8.8" //DIST_IP




class BarcodeReader : public KeyboardReportParser
{
    USB Usb;
    USBHub Hub;
    HIDUniversal Hid;
    HIDBoot<HID_PROTOCOL_KEYBOARD> Keyboard;

    uint8_t buffer[15];
    byte length;
    bool valid;

    void addCharacter(uint8_t c);

  public:
    BarcodeReader();
    void begin();
    void task();
    const uint8_t* barcode();
    void reset();

  protected:
    virtual void OnKeyDown(uint8_t mod, uint8_t key);
};

BarcodeReader::BarcodeReader()
  : Usb()
  , Hub(&Usb)
  , Hid(&Usb)
  , Keyboard(&Usb)
  , length(0)
  , valid(false)
{
}

void BarcodeReader::begin()
{
  if (Usb.Init() == -1) {
    Serial.println("OSC did not start.");
  }
  Hid.SetReportParser(1, this);
}

void BarcodeReader::task()
{
  Usb.Task();
}

void BarcodeReader::addCharacter(uint8_t c)
{
  if (valid) {
//    already have a barcode, new one will overwrite it
   reset();
  }

//   could check for \n or \r if necessary, or even implement a timing
 //  mechanism for detecting end of barcode input, but for now we just
 //  assume fixed width field with no output separators

  buffer[length++] = c;
  buffer[length] = '\0';
  
  if (buffer[length] == '\0') 
  {
   valid = true;
  }
};

// return value no longer valid after another call to task()
const uint8_t* BarcodeReader::barcode()
{
  return (valid) ? buffer : 0;
}

void BarcodeReader::reset()
{
  length = 0;
  valid = false;
}

void BarcodeReader::OnKeyDown(uint8_t mod, uint8_t key) {
  uint8_t c = OemToAscii(mod, key);
  if (c) addCharacter(c);
}

BarcodeReader barcodeReader;

void setup() {

 
  Serial.begin(9600);
  mySerial.begin(115200);
lcd.begin();                      
lcd.begin();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Hello"); 
  
delay(5000);

Serial.println("Init");
mySerial.println("AT+RST"); // сброс и проверка, если модуль готов
delay(1000);
if(mySerial.find("OK"))
{Serial.println("WiFi - Module is ready");}
else
{Serial.println("Module dosn't respond.");
while(1);
}
delay(1000);
// соединение по wifi
boolean connected=false;
for(int i=0;i<5;i++)
{
if(connectWiFi())
{connected = true;
mySerial.println("Connected to Wi-Fi...");
break;
}
}
if (!connected)
{
mySerial.println("Coudn't connect to Wi-Fi.");
while(1);
}
delay(1000);
mySerial.println("AT+CIPMUX=0"); // режим одиночного соединения
  
  barcodeReader.begin();
 }

void loop() {

  barcodeReader.task();
 const char* barcode = barcodeReader.barcode();
   

  if  (barcode) {
   
    String message = "";
 
    message.concat((char*) barcode);
 
    Serial.println(message);
 
          
          
  String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += DST_IP;
cmd += "\",8283";
Serial.println(cmd);
mySerial.println(cmd);
if(mySerial.find("Error"))
return; 
  
cmd =String (format());

delay(3000);
mySerial.print("AT+CIPSEND=");
mySerial.println(cmd.length());
Serial.println(">");
mySerial.print(cmd);
Serial.print(message);
mySerial.print(message);
Serial.println(cmd);
barcodeReader.reset();
mySerial.println("AT+CIPCLOSE");
Serial.println("AT+CIPCLOSE");

      
    }
}
// процедура установки Wi-Fi-соединения
boolean connectWiFi()
{

  
String cmd="AT+CWJAP=\"" +SSID+"\",\"" + PASS + "\"";

mySerial.println(cmd);
Serial.println(cmd);
delay(2000);
if(mySerial.find("OK"))
{
Serial.println("OK, Connected to Wi-Fi.");
return true;
}
else
{
Serial.println("Can not connect to the Wi-Fi.");
return false;
}
}

long format(){
  double width = 100-axisX.Ranging(CM);
  Serial.println(width);
  delay(50);
  

  double lenght = 100-axisY.Ranging(CM);
  Serial.println(lenght);
  
  delay(50);

  double height = 100-axisZ.Ranging(CM);
  Serial.println(height);
  delay(50);



  long format = (width*lenght*height)/1000000;
 
  Serial.println(format);
  lcd.clear();
  lcd.setCursor (2,0);
  
  lcd.print(width);
  lcd.print("x");
  
  lcd.print(lenght);
  lcd.print("x");
  
  lcd.print(height);
  lcd.print("cm");
   
  lcd.setCursor (4,1);
  lcd.print ("V=" );
  lcd.print(format);
  lcd.print ("M.kyb");
  return format;
}

Вот вывод в консоль 

Init
WiFi - Module is ready
AT+CWJAP="net","Programm21"
Can not connect to the Wi-Fi.
AT+CWJAP="net","Programm21"
OK, Connected to Wi-Fi.
4
AT+CIPSTART="TCP","8.8.8.8",8283
49.00
49.00
49.00
0
>
40
AT+CIPCLOSE
4
AT+CIPSTART="TCP","8.8.8.8",8283
49.00
49.00
49.00
0
>
40
AT+CIPCLOSE

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Даже не знаю, что Вам ещё сказать. 

Ошибка подробно описана в посте #1. А в посте #4 Вы публикуете скетч в котором эта самая ошибка не только не исправлена, а даже усугублена (уж для верности).

Вот Ваш код из поста  #4

void BarcodeReader::addCharacter(uint8_t c) {
  if (valid) {
    //    already have a barcode, new one will overwrite it
    reset();
  }
  //   could check for \n or \r if necessary, or even implement a timing
  //  mechanism for detecting end of barcode input, but for now we just
  //  assume fixed width field with no output separators

  buffer[length++] = c;
  buffer[length] = '\0';

  if (buffer[length] == '\0')
  {
    valid = true;
  }
};

Смотрите на строку 11. Вы точно понимаете, что она делает? На всякий случай, она делает buffer[length] рвным '\0'.

А что делается в строке 13? А в строке 13 Вы проверяеете а равна ли buffer[length] значению '\0' или, может, не равна.

ну и каков результат проверки, если Вы её только что принудительно сделали '\0'.

Разумеется, "равна". Вот Вы и заканчиваете чтение баркода после первого же символа.

Исправляйте ошибки-то, а не усугубляйте их.

ZmeyGo
Offline
Зарегистрирован: 06.03.2018

Спасибо, да что-то я натупил. Подправил, но всеравно не так как хочу работает. Буду ковырять дальше

ZmeyGo
Offline
Зарегистрирован: 06.03.2018

Я конечно обнаглел, но Вы смогли б написать как оно должно работать. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Не мог бы, т.к. у меня нет ни этой приблуды, для чтения кодов, ни документации по ней, и я понятия не имею как она должна работать. То, как у Вас написано работать не должно, это я вижу. А как должно - я просто не знаю. 

sadman41
Offline
Зарегистрирован: 19.10.2016

ZmeyGo пишет:

//   could check for \n or \r if necessary, or even implement a timing
 //  mechanism for detecting end of barcode input, but for now we just
 //  assume fixed width field with no output separators

Вот это пытались переводить или просто копипастили код с arduino.cc ?