Barcode scanner con arduino mega y usb shield

Hola, muy buenas a toda la comunidad de Arduino.

Vengo aquí al foro en busca de alguien que pueda ayudarme o asesorarme, soy novato en esto de la programación, razón por la cual llegue a este foro. Les platico un poco resumido lo que quiero hacer para no llevarla a la larga.

Tengo un proyecto para mi uni, en el cual estoy usando una Arduino Mega 2560 con una USB Host Shield, este ultimo para poder trabajar con un escaner de código de barras de la marca symbol modelo LS2208, el cual se alimenta con los 9v de la fuente que le coloqué al arduino. Encontré en internet un código con el cual puedo trabajar con el sistema y poder escanear el código de barras de algún producto y poder visualizar el numero serial en una LCD agregada en el circuito, a continuación anexo el código.

#include <HID.h>

#include <hid.h>                           //Add to Oleg Mazurov code to Bar Code Scanner
#include <hiduniversal.h>                  //Add to Oleg Mazurov code to Bar Code Scanner
#include <usbhub.h>

#include <LiquidCrystal.h>
#include <avr/pgmspace.h>
#include <Usb.h>
#include <usbhub.h>
#include <avr/pgmspace.h>
#include <hidboot.h>
#define DISPLAY_WIDTH 16
 
//initialize the LCD library with the numbers of the interface pins//

LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
 
USB     Usb;
USBHub     Hub(&Usb);                                          //I enable this line
HIDUniversal      Hid(&Usb);                                  //Add this line so that the barcode scanner will be recognized, I use "Hid" below 
HIDBoot<USB_HID_PROTOCOL_KEYBOARD>    Keyboard(&Usb);
 
class KbdRptParser : public KeyboardReportParser
{
        void PrintKey(uint8_t mod, uint8_t key);             // Add this line to print character in ASCII
protected:
	virtual void OnKeyDown	(uint8_t mod, uint8_t key);
	virtual void OnKeyPressed(uint8_t key);
};
 
void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key)	
{
    uint8_t c = OemToAscii(mod, key);
 
    if (c)
        OnKeyPressed(c);
}
 
/* what to do when symbol arrives */
void KbdRptParser::OnKeyPressed(uint8_t key)	
{
static uint32_t next_time = 0;      //watchdog
static uint8_t current_cursor = 0;  //tracks current cursor position  
 
    if( millis() > next_time ) {
      lcd.clear();
      current_cursor = 0;
      delay( 5 );  //LCD-specific 
      lcd.setCursor( 0,0 );
    }//if( millis() > next_time ...
 
    next_time = millis() + 200;  //reset watchdog
 
    if( current_cursor++ == ( DISPLAY_WIDTH + 1 )) {  //switch to second line if cursor outside the screen
      lcd.setCursor( 0,1 );
    }
 
    Serial.print( (char)key );      //Add char to print correct number in ASCII
    lcd.print( (char)key );          //Add char to print correct number in ASCII
};
 
KbdRptParser Prs;
 
void setup()
{
    Serial.begin( 115200 );
    Serial.println("Start");
 
    if (Usb.Init() == -1) {
        Serial.println("OSC did not start.");
    }
 
    delay( 200 );
 
    Hid.SetReportParser(0, (HIDReportParser*)&Prs);        //Here I change  "Keyboard" for "Hid"
    // set up the LCD's number of columns and rows: 
    lcd.begin(DISPLAY_WIDTH, 2);
    lcd.clear();
    lcd.noAutoscroll();
    lcd.print("Ready");
    delay( 200 );
}
 
void loop()
{
  Usb.Task();
}

Como mencione antes, este código lo saque de internet ya que se basa en lo que quiero hacer. Ahora bien, la parte faltante del proyecto seria la siguiente, en la que solicito ayuda:

La idea es crear con el sistema del arduino mega y el escáner, un sistema o estructura de indicadores visuales, con leds, implementado en un rack o exhibidor con espacio para 6 contenedores o charolas, en las cuales irían 6 familias u ordenes de productos con un mismo numero de parte o serial cada una que las diferencia, cada charola tendría su LED, que se activaría de forma intermitente al momento de que yo escaneé el código de barras del producto dándome a entender que en ese charola va ir depositado ese producto, así como también con los demás familias u ordenes de productos, con la finalidad de de evitar material mezclado por x o y motivo.

Cómo puedo agregar esta funcionalidad en el código?

Eh intentado buscando proyectos parecidos en el foro pero no he tenido suerte en encontrar alguno.
Soy novato en esto de la programación y agradecería cualquier apoyo o ayuda.
Una disculpa con los moderadores si infringí alguna regla en la realización de este post.

Hola @Asazin bienvenido al foro Arduino en Español.

Primero felicitarte, has posteado muy bien con etiquetas y todo. En la sección correcta. Me preocupa porque veo que ya mas gente comienza a hacerlo debidamente, tal vez alguien este leyendo las normas o los post, lo importante es que da gusto leer una buena presentación, gracias por eso.

Vamos a tu consulta. Tienes un código que supongo hace lo que esperas, o sea te reconoce el código de barras y si eso ya funciona te aseguro que tienes el 90% listo y se porque lo digo.

Lo que quieres hacer

en un rack o exhibidor con espacio para 6 contenedores o charolas, en las cuales irían 6 familias u ordenes de productos con un mismo numero de parte o serial cada una que las diferencia, cada charola tendría su LED, que se activaría de forma intermitente al momento de que yo escaneé el código de barras del producto dándome a entender que en ese charola va ir depositado ese producto, así como también con los demás familias u ordenes de productos, con la finalidad de de evitar material mezclado por x o y motivo.

  1. Mismo número de parte.. comencemos identificando eso
  2. Las charolas (no se que es charola ) tendrán un led que se activa intermitentemente. O sea una máquina de estados que controle eso.. no hay problema. Ve a Documentación => Indice de temas tutoriales => millis() y también lee máquina de estados.

No termino de entender el final, como discriminas el producto pero eso se debe a que no has puesto como esta estructurado el código de barras.

Esperando mas detalles te saludo.

Buenas mi estimado surbyte, agradezco mucho tu atención en haber respondido mi post, el cual me alegra saber que cumple con las normas.

En efecto el código cumple con la función de poder trabajar con el escaner, y que este, al escanear un código de barras (ya sea el de algún producto comercial, por ejemplo el de un paquete de galletas) me muestra el numero serial del barcode en la LCD. Anexo imagen de evidencia.

Hasta aqui todo bien, lo que hace el sistema seria por decirlo asi la mitad de mi proyecto, la otra mitad o parte es la funcion que busco que haga. Tratare de explicar un poco mas claro, lo que quiero lograr es lo siguiente:

Son 6 charolas (cajas, para que se entienda mejor) acomodadas con un rack o estante, esas cajas estarian asignadas para guardar 6 familias o grupos de productos, cada familia de productos tienen número de parte diferente, y por consiguiente cada producto que integre una familia compartiran el mismo, este número de parte viene como codigo de barras en sus etiquetas que los identifica, lo que busco que haga el sistema es que cuando escaneé el número de parte del producto este me mandé la señal hacia el LED que este puesto en la caja que corresponda a ese número de parte, verificando que ese producto ira a esa caja, anexo el concepto como imagen.

Me llega un producto con el codigo de barras que tenga serial 104 (llamado numero de parte), lo escaneo y me enciende el led de la caja asiganada para el 104, luego, me llega otro producto con diferente diferente serial en el barcode por ejemplo el 789, lo escaneo y me enciende el led de la caja para ese producto, ese es el objetivo al que deseo llegar

Por ultimo, anexo una imagen de la etiqueta con el codigo de barras con el serial que identifica a la familia de X o Y cantidad de productos ya sean 50, 100, 200 o 300, conocido donde trabajo como “número de parte”, definido en la etiqueta como Product Code, este es en el que me basare. Se puede ver que lo muestra de forma gráfica al escanearlo sin ningún problema.

Mi pregunta es como puedo agregar esta funcionalidad en el código que ya tengo.

Bueno, veniamos bien pero te falto como mostar las imágenes. Ahora revisa la parte de las normas COMPLEMENTARIO Como visualizar imágenes adjuntas y edita tu post anterior.

y bueno es muy fácil pero eso ocurre porque lo que has mostrado lo copiaste y pegaste y ahora una simpleza como la que te falta y no sabes por donde continuar.

Existe una instrucción que se llama switch() case

switch justamente asigna segun el dato de la variable que contiene entre () al sitio o case que corresponda. Resulta que el código que tienes hasta ahora entrega cada digito o valor alfanumerico y lo presenta uno a uno entonces tampoco los tienes como gustas. Si tuvieras 123 456 789 101 103 104 como valores enteros o del tipo long

switch(Barcode) {
    case 123: // lo que corresponda
                    break;
    //y asi paa los demas
}

Ahora debemos convertir la presentación en una variable que luego exprese tus categorias de este modo.

Hola de nuevo @surbyte!

Seguí tu consejo y he editado el post a modo de que las imagenes se visualicen, gracias por el dato, poco a poco iré mejorando en la realización de estos.

Leí un poco sobre el consejo que me has dado sobre utilizar el switch () case, ahora bien, tengo aqui mi lista con 6 codigos de barras con numeros de parte, denominadas como Product Code en las etiquetas, como lo he mostrado en la imagen de mi respuesta anterior, en si son la representación real de los que vienen en la imagen del concepto del proyecto:

123 sería FDXLCLC42-M9F035 456 sería FEWLCLC42-JXM003 789 sería 860644153 101 sería 860644152 103 sería 860644155 104 sería 860644154

No se si estoy en lo correcto en implementar el código que me has sugerido de la siguiente manera:

switch(Barcode) {
     case FDXLCLC42-M9F035: 
            // aqui iria la instrucción de que encienda el led en tal salida?
                                 break;
     case FEWLCLC42-JXM003;
           // aqui iría otra instrucción que encienda el led en otra salida?
                                 break;
}

Sería de esta forma y así sucesivamente con los demás números de parte? Gracias de antemano por el soporte que me estas brindando.

No. Asi no se puede consultar las etiquetas.

No prestaste atención a este comentario

Si tuvieras 123 456 789 101 103 104 como valores enteros o del tipo long

Asi que tienes que separar el comienzo de cada etiqueta y luego convertirlo a entero para usar lo que te he sugerido o bien, hacerlo con una serie de consultas usando Strings o cadenas.

Primero veamos donde tienes la etiqueta cargada, una vez leída.

void KbdRptParser::OnKeyPressed(uint8_t key)  
{
static uint32_t next_time = 0;      //watchdog
static uint8_t current_cursor = 0;  //tracks current cursor position 
 
    if ( millis() > next_time ) {
        lcd.clear();
        current_cursor = 0;
        delay( 5 );  //LCD-specific
        lcd.setCursor( 0,0 );
    } //if( millis() > next_time ...
 
    next_time = millis() + 200;  //reset watchdog
 
    if ( current_cursor++ == ( DISPLAY_WIDTH + 1 )) {  //switch to second line if cursor outside the screen
         lcd.setCursor( 0,1 );
    }
 
    Serial.print( (char)key );      //Add char to print correct number in ASCII
    lcd.print( (char)key );          //Add char to print correct number in ASCII
};

Esta es la rutina princiipal que si supera los 200mseg simplemente borra la pantalla

lcd.clear();
        current_cursor = 0;
        delay( 5 );  //LCD-specific
        lcd.setCursor( 0,0 );

Asi que eso lo podemos tomar como un fin de etiqueta.
Entonces solo hay que acumular los datos que necesitamos o todos y luego descartar los que no hacen falta por ahora.

veamos si esto que acabo de hacer medio rápido funciona y luego podemos usar
Voy a usar Strings para acumular la etiqueta y luego ver si con ello es mas fácil el resto.

Veamos si este paso funciona

#include <HID.h>
#include <hid.h>                           //Add to Oleg Mazurov code to Bar Code Scanner
#include <hiduniversal.h>                  //Add to Oleg Mazurov code to Bar Code Scanner
#include <usbhub.h>

#include <LiquidCrystal.h>
#include <avr/pgmspace.h>
#include <Usb.h>
#include <usbhub.h>
#include <avr/pgmspace.h>
#include <hidboot.h>
#define DISPLAY_WIDTH 16
 
//initialize the LCD library with the numbers of the interface pins//

LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
 
USB               Usb;
USBHub            Hub(&Usb);                                          //I enable this line
HIDUniversal      Hid(&Usb);                                  //Add this line so that the barcode scanner will be recognized, I use "Hid" below
HIDBoot<USB_HID_PROTOCOL_KEYBOARD>    Keyboard(&Usb);
 
class KbdRptParser : public KeyboardReportParser {
        void PrintKey(uint8_t mod, uint8_t key);             // Add this line to print character in ASCII
protected:
        virtual void OnKeyDown  (uint8_t mod, uint8_t key);
        virtual void OnKeyPressed(uint8_t key);
};
 
void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key)  
{
    uint8_t c = OemToAscii(mod, key);
    if (c)
        OnKeyPressed(c);
}

String etiqueta = "";
bool NuevaRFID = false;
/* what to do when symbol arrives */
void KbdRptParser::OnKeyPressed(uint8_t key)  
{
static uint32_t next_time = 0;      //watchdog
static uint8_t current_cursor = 0;  //tracks current cursor position 
 
    if ( millis() > next_time ) {
        lcd.clear();
        current_cursor = 0;
        delay( 5 );  //LCD-specific
        lcd.setCursor( 0,0 );
        etiqueta = "";
    } //if( millis() > next_time ...
 
    next_time = millis() + 200;  //reset watchdog
 
    if ( current_cursor++ == ( DISPLAY_WIDTH + 1 )) {  //switch to second line if cursor outside the screen
         lcd.setCursor( 0,1 );
    }
 
    Serial.print( (char)key );      //Add char to print correct number in ASCII
    lcd.print( (char)key );          //Add char to print correct number in ASCII
    etiqueta++ = (char) key;
    if (etiqueta.length > 9)  // lo que no controla los primeros dos casos 
        NuevaRFID = true;
    else 
        NuevaRFID = false;
};
 
KbdRptParser Prs;
 
void setup()
{
    Serial.begin( 115200 );
    Serial.println("Start");
 
    if (Usb.Init() == -1) {
        Serial.println("OSC did not start.");
    }
 
    delay( 200 );
 
    Hid.SetReportParser(0, (HIDReportParser*)&Prs);        //Here I change  "Keyboard" for "Hid"
    // set up the LCD's number of columns and rows:
    lcd.begin(DISPLAY_WIDTH, 2);
    lcd.clear();
    lcd.noAutoscroll();
    lcd.print("Ready");
    delay( 200 );
}
 
void loop()
{
  Usb.Task();
  if (NuevaRFID) {
      Serial.println("Etiqueta : " + etiqueta);
  }
}