Manipulating data from a USB Barcode Scanner does not work

Hi there again.

Few months ago I have posted a question on a problem reading data from RS232 barcode scanner to Arduino. It was solved and thanks to everyone who helped me.

But now I’m doing some experiment with a USB Barcode Scanner. The code is taken from example at https://www.circuitsathome.com/mcu/connecting-barcode-scanner-arduino-usb-host-shield/

And I modified it a bit and it my barcode scanner output the barcode number in LCD and serial monitor(though serial monitor has a square character at the end of the code. an end marker perhaps?).

Here’s my code

#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<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 );
    
    if ((char)key == 882020554)
    {
      lcd.setCursor(0,1);
      lcd.print("TEST PRODUCT 1");
    }
};
 
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();
}

However, nothing besides the barcode number is printed on the LCD when I scan “882020554”.

Is my if-else wrong? Or do I need to implement it the same way as serial input(by using null terminated char array).

Thank you.

how do you ever expect this to work out?

    if ((char)key == 882020554)

what is a char? what's the largest value you can store in a char?

    if ((char)key == 882020554)

Why type is key? Why are you casting it to a char to compare it? Is there a snowball's chance in hell that key will contain that value?

   Serial.print( (char)key );      //Add char to print correct number in ASCII

Casting that value to a char might not be a good idea, if the value does not represent a printable character.

After printing this value, print a space. I'm certain that you will not see 882020554 being printed.

J-M-L:
how do you ever expect this to work out?

    if ((char)key == 882020554)

what is a char? what's the largest value you can store in a char?

  1. But changing it to long would not work also.

PaulS:

    if ((char)key == 882020554)

Why type is key? Why are you casting it to a char to compare it? Is there a snowball's chance in hell that key will contain that value?

   Serial.print( (char)key );      //Add char to print correct number in ASCII

Casting that value to a char might not be a good idea, if the value does not represent a printable character.

After printing this value, print a space. I'm certain that you will not see 882020554 being printed.

    lcd.print( (char)key );
    lcd.print(" ");

It prints "8 8 2 0 2 0 5 5 ". It prints with a space for every character.

So what's the solution?

So what’s the solution?

Add the character to an array, unless the character is the “end of barcode data” marker.

Then, when the end of barcode data marker arrives, add a NULL terminator to the array, and use strcmp() to see if the value in the string is “882020554”.

Or, multiply the value in some variable by 10 and add the value in key minus ‘0’. When the end of barcode data marker arrives, use the value in that variable in an if statement: if(value == 882020554).

I believe the barcode scanner does not send any end marker because when I use it with notepad or any text editor it just scans the barcode number. Besides the manual does not state that it has an end marker.

Mind sharing me a good tutorial to store the character to an array. I got confused everytime with array.

Mind sharing me a good tutorial to store the character to an array. I got confused everytime with array.

  1. But changing it to long would not work also.

exactly, that's because key is just the last key, not the buffer of everything received (which you would not compare this way either but with a strcmp() for example)

look at the code in answer #88 of this thread where I proposed a quick hack to the class KbdRptParser : public KeyboardReportParser to add a QRCodeBuffer as a public data that would hold the string.

the use case was a bit specific, so if you don't read french use a bit of google translate to see what's going on, but that could give you ideas

Hi there. I am back again with problems.

Thanks for replying.

Okay now I have make the barcode number as char terminated array but still my if else does not work.

#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 <SPI.h>
#include <MFRC522.h>
#include <avr/pgmspace.h>
#include <Usb.h>
#include <usbhub.h>
#include <avr/pgmspace.h>
#include <hidboot.h>


int inbyte;
char barcode[9];
byte index = 0;
unsigned long serial = 0;


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<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   

  inbyte = key;
  barcode[index++] = (char)inbyte;
  barcode[index] = '\0';
  serial = atol(barcode);
  
 
      
       if (serial == 882020554)
       {
         Serial.print("ITEM 1");
       }
       
       else
       {
         Serial.print("FAILED");
       }
         
   
  
  index = 0;
  barcode[0] = '\0';

};
 
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);
}

void loop()
{
  Usb.Task();
}

I have removed the LCD code as I am only using serial monitor to debug.

The output that I get is FAILEDFAILEDFAILEDFAILEDFAILEDFAILEDFAILEDFAILEDFAILED.

This actually corresponds to the number of the the barcode number for example “882020554”. It has 9 characters and the word “FAILED” is 9 also.

Is there something I missed here?

J-M-L:
exactly, that's because key is just the last key, not the buffer of everything received (which you would not compare this way either but with a strcmp() for example)

look at the code in answer #88 of this thread where I proposed a quick hack to the class KbdRptParser : public KeyboardReportParser to add a QRCodeBuffer as a public data that would hold the string.

the use case was a bit specific, so if you don't read french use a bit of google translate to see what's going on, but that could give you ideas

Hi there J-M-L. Thanks for spending your time to assist me.

I have done a deep search on Arduino Forum and there's actually a lot of question similar to me.

This for example

and this

I think you are right in hacking the class of the USB itself. However, I'm struggling to understand the link you posted since that one wants to read only specific part of the barcode number.

I hope there is another solution.

Look at the code I posted - before extracting a subpart of the qrcode, the full code is read. So keep that part, get rid of the code extracting the subset

I copied all the part you add in the code including the part that extracts the code. I only remove the LCD code.

I got an error when trying to compile.

“usbbs2:57: error: ISO C++ forbids initialization of member ‘newCar’
usbbs2:57: error: making ‘newCar’ static
usbbs2:57: error: ISO C++ forbids in-class initialization of non-const static member ‘newCar’”

Here is my code for reference anyway

#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 <avr/pgmspace.h>
#include <Usb.h>
#include <usbhub.h>
#include <avr/pgmspace.h>
#include <hidboot.h>

#define MAXQRCODE  20


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<HID_PROTOCOL_KEYBOARD>    Keyboard(&Usb);
 
class KbdRptParser : public KeyboardReportParser
{
  public:
    bool newCar = false;
    char QRCodeBuffer[MAXQRCODE + 1];
  
        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 ) { //temps écoulé on reset le buffer
    current_cursor = 0;
  }
    QRCodeBuffer[current_cursor++] = key;
  QRCodeBuffer[current_cursor] = '\0';
  if (current_cursor >= MAXQRCODE) current_cursor = MAXQRCODE - 1; // on va écraser le dernier caractère, tant pis
  {
  newCar = true;
  next_time = millis() + 200;
}
};
 
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);

}

void loop()
{
  Usb.Task();
  if (Prs.newCar) { // on a reçu un nouveau caractère, on va voir si on a "E00000-abcdef9999" --> 17 caractères
    if ((strlen(Prs.QRCodeBuffer) >= 17)  && (strchr (Prs.QRCodeBuffer, '-') != NULL)) {
      // le QRCodeBuffer est compatible avec ce que l'on veut
      char lcdBuffer1[7];
      strncpy(lcdBuffer1, strchr (Prs.QRCodeBuffer, '-') + 1, 6); // on extrait 6 caractères en trouvant le '-' et on commence au caractère suivant
      lcdBuffer1[6] = '\0'; // on marque la fin de chaine
      Serial.print("                "); // on efface
      Serial.print(lcdBuffer1); // on affiche le nouveau  (was wrongly lcd.print(Prs.QRCodeBuffer); // on affiche le nouveau) cf ci dessous dans la discussion
    } else { // on efface à améliorer car fait Bêtement 16 fois pour les 16 premiers (tester la longueur du buffer par exemple)
        Serial.print("                "); 
    }
    Prs.newCar = false; // on a traité le nouveau caractère
  }
}

what’s the deal with all the includes at the beginning?

#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 <avr/pgmspace.h>
#include <Usb.h>
#include <usbhub.h>
#include <avr/pgmspace.h>
#include <hidboot.h>

I would suggest you try with something simple like this; This is a HACK on the KbdRptParser class as I’m exposing inner variables directly

Prs.[color=blue]newCar[/color] which tells you when a new character has been received from the USB

The current and possibly final string received is stored in the Prs.[color=blue]QRCodeBuffer[/color] char array (a correctly formatted c-string with a ‘\0’ null character at the end).

You need to ensure that this buffer is appropriately sized, which is done with the #define [color=blue]MAXQRCODE[/color] (set at 50 below, might be way too much)

in the loop I just check the boolean to see if something has happened on the reader.

The first check will let you see the string being built-up character by character as they come in from the USB barcode reader (side note: what I do there for printing while receiving from the USB is not a great idea because you might trick the timeout).

Then I check for timeout. if nothing has happened from the reader for a while, then I know I’ve the final string in the buffer. Don’t forget to instruct the class to reset the buffer once you’ve dealt with the string.

give it a try - it’s totally untested, I don’t have access to any hardware to test at the moment, so just typed in the code.

#include <hidboot.h>

#define MAXQRCODE  50 // NEEDS TO BE LONG ENOUGH TO FIT YOUR LONGEST BARCODE SCAN

class KbdRptParser : public KeyboardReportParser
{
  public:
    KbdRptParser();
    void resetString();
    bool newCar;
    bool newString;
    uint8_t currentCursor;
    char QRCodeBuffer[MAXQRCODE + 1];
  protected:
    virtual void OnKeyDown (uint8_t mod, uint8_t key);
    virtual void OnKeyPressed(uint8_t key);
};

KbdRptParser::KbdRptParser(): KeyboardReportParser()
{
  resetString();
}

void KbdRptParser::resetString()
{
  newCar = false;
  newString = false;
  currentCursor = 0;
  QRCodeBuffer[0] = '\0';
}

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)
{
  QRCodeBuffer[currentCursor++] = key;
  QRCodeBuffer[currentCursor] = '\0';
  if (currentCursor >= MAXQRCODE) currentCursor = MAXQRCODE - 1; // not enough space, next character will overwrite last one
  newCar = true;
  newString = true;
}


// ====================================================

USB     Usb;
HIDBoot<USB_HID_PROTOCOL_KEYBOARD> HidKeyboard(&Usb);
KbdRptParser Prs;
const unsigned long timeOutDuration = 200ul;

void setup()
{
  Serial.begin(115200);
  Serial.println("Start");

  if (Usb.Init() == -1) {
    Serial.println("OSC did not start. Stop here.");
    while (1); // No need to continue.
  }

  HidKeyboard.SetReportParser(0, &Prs);
}


void loop()
{
  static uint32_t lastKeyTime = 0;      //watchdog
  static bool timedOut = false;

  Usb.Task(); // this gives a chance to read from the barcode scanner

  if (Prs.newCar) { // we just got a new char; you'll see the string building up
    Serial.print("["); Serial.print(Prs.QRCodeBuffer); Serial.println("]");
    Prs.newCar = false; // new char has been handled
    lastKeyTime = millis(); // memorize the last char entry time
  }

  // here we check if there has been no activity from the barcode reader for a while
  if (Prs.newString && (millis() - lastKeyTime >= timeOutDuration)) { //timeout, we just finsihed entering a new string
    Serial.print("Final string = ["); Serial.print(Prs.QRCodeBuffer); Serial.println("]");
    Prs.resetString(); // tell the Prs instance that the new string has been handled.
  }
}

I’ve been doing some editing within this post - make sure you test with this now and not what was there previously

I could not compile your code.

sketch_jan22b:52: error: 'USB_HID_PROTOCOL_KEYBOARD' was not declared in this scope
sketch_jan22b:52: error: template argument 1 is invalid
sketch_jan22b:52: error: invalid type in declaration before '(' token

All the includes are needed for the barcode scanner to work.

EDIT:

I have modified this line

USB     Usb;
HIDBoot<USB_HID_PROTOCOL_KEYBOARD> HidKeyboard(&Usb);
KbdRptParser Prs;
const unsigned long timeOutDuration = 200ul;

to

USB     Usb;
USBHub     Hub(&Usb);     
HIDUniversal      Hid(&Usb);  
HIDBoot<HID_PROTOCOL_KEYBOARD>  Keyboard(&Usb);
KbdRptParser Prs;
const unsigned long timeOutDuration = 200ul;

and

HidKeyboard.SetReportParser(0, &Prs)

to

Hid.SetReportParser(0, (HIDReportParser*)&Prs);

And again I have included all the header files.

The code from Oleg Mazurov actually didn’t work. I modified it according to another tutorial and my barcode works.

Unless you know a better way to do it, please tell so.

EDIT 2:

After the editing, the code compiled successfully and my output is

[8]
[88]
[882]
[8820]
[88202]
[882020]
[8820205]
[88202055]
[882020554]
Final string = [882020554]

So now the real question is, which string or variable do I need to put in my if-else?

For now, I would play around for awhile to test my if-else.

Really a big thank to you J-M-L.

Okay J-M-L. Hands down. You frigging awesome. How the hell you know what to do. I mean HOW? Like seriously HOW?

How the string builds up only after modifying the Hid blablabla class?

Why isn't char terminated array working?

I will try and study your code thoroughly. The problem is solved but I'm afraid I will be having more question regarding this topic so please don't close it yet.

Again, thanks J-M-L.

I knew this thing is beyond my level currently but I hope I can do the same kind of hack in the future too.

:slight_smile: good it's working

I think you should get rid of all your headers, other classes, remove that from your system to avoid any confusion and go download Oleg Mazurov's USB_Host_Shield_2.0 collection of class

there is no magic happening there.

the KbdRptParser class inherits most of the behavior from KeyboardReportParser and is basically being used to handle what happens when a key is pressed. When that happens, the OnKeyDown function (method) is called which does a bit of checking and calls OnKeyPressed function with a parameter which is the ascii representation of the character.

So you should do your stuff in this function. Here what you want to do is capture everything arriving form your scan and build a string. So I declared a buffer in the class to keep the string in memory, and I wrote a small piece of code that is basically building up the string by adding into QRCodeBuffer each new character received (and checking I don't overflow that buffer) + putting some flags that you can check in the main loop to see what has been received.

QRCodeBuffer[currentCursor++] = key; [color=blue]// add the key to the end of the string[/color]
QRCodeBuffer[currentCursor] = '\0';[color=blue] // put the null in the next character[/color]
if (currentCursor >= MAXQRCODE) [color=blue]// check  if we are at the end of the buffer[/color]
currentCursor = MAXQRCODE - 1; [color=blue]// and if so not enough space, next character will overwrite last one[/color]
newCar = true; [color=blue]// flag: just got a new character, this is exposed to the loop()[/color]
newString = true; [color=blue]// flag: we have changed the string. this is exposed to the loop()[/color]

So in the loop, if you want to do something everytime a character is received, you check the boolean newCar. this is the first if in the loop(), printing the string as it is being built.

The challenge with a barcode reader is that usually there is nothing telling you the string has been fully read. So in the loop I used a small trick: when you read from the barcode reader, all the data arrives super fast. So if no new character arrives for a while (200ms) then I consider that the barcode reader is done sending the info and I consider I've the final string. this is the second if in my loop().

So if you have the timeOut and that a newString was read, then QRCodeBuffer has the string (within the instance of the class --> so if you want to access it in the loop you work with Prs.QRCodeBuffer) until the next read.

In order to tell the Prs instance to start a new string, that's the function I added which does the reset: void KbdRptParser::resetString()

see no magic, just a bit of thinking

How can I compare it:

char Str1 = 882020554;
if (Prs.QRCodeBuffer == Str1) { 

do someting...
}

well you don't like this... you need to work with c-strings

const char * Str1 = "882020554";

if (!strcmp(Prs.QRCodeBuffer, Str1)) { // match, do something

} else {
   // no match do something else

}

you could explore the standard functions for c-strings as defined here stdlib.h or string.h

many THX...

and with switch case?

You can’t with switch/case given the contion/constant expression would not be an integral value

any expression of integral or enumeration type, or of a class type contextually implicitly convertible to an integral or enumeration type, or a declaration of a single non-array variable of such type with a brace-or-equals initializer.

constant_expression - a constant expression of the same type as the type of condition after conversions and integral promotions

You can handle that throught nested if/else or define an array of strings of interest and use a for loop to find the right one, note its index and do the switch based on that

here is a piece of code demonstrating a way to do this

const char * stringsOfInterst[] = {
  "Hello", "Salut", "Hallo", "Ciao", "Ahoj", "Bog", "Marhaba", "Hej", "Ni Hao", "Shalom", "Namaste"
};

// to simplify the swicth case
enum {
  _Hello_, _Salut_, _Hallo_, _Ciao_, _Ahoj_, _Bog_, _Marhaba_, _Hej_, _NiHao_, _Shalom_, _Namaste_
};

// or to handle things through index
const char * language[] = {
  "English", "French", "German", "Italian", "Czech", "Croatian", "Turkish", "Swedish", "Chinese", "Hebrew", "Hindi"
};

const byte nbWords = sizeof(stringsOfInterst) / sizeof(stringsOfInterst[0]);


// ************************************************************************
// ************ small function to read the Serial input *******************
// ************************************************************************
// when entry is complete (found the endMark), function returns true
// and the c-string message has the text we entered
// ************************************************************************

const byte maxInput = 20;
char message[maxInput + 1]; // +1 for a trailing '\0'


boolean getInputTillEndMarker(const char endMark)
{
  boolean endOfMessage = false;
  static byte index = 0;
  if (Serial.available()) {
    int r = Serial.read();
    if (r != -1) {
      if (r == endMark) {
        endOfMessage = true;
        index = 0; // get ready for next one
      }
      else {
        if (r != '\r') { // Ignore CR
          message[index++] = (char) r;
          message[index] = '\0'; // denote the end of the c-string
          if (index >= maxInput) index = maxInput - 1; // don't overflow if input too long for bufer
        }
      }
    }
  }
  return endOfMessage;
}


// ************************************************************************
void setup() {
  Serial.begin(115200);
  Serial.println("*** Hello tester ***");

  for (byte i = 0; i < nbWords; i++) {
    Serial.print(stringsOfInterst[i]); Serial.print(" ");
  }

  Serial.print("\n\nEnter Hello in one language: ");
}

// ************************************************************************
void loop() {
  // read an input from the Serial line
  if (getInputTillEndMarker('\n')) {
    int languageIndex;
    boolean found = false;

    Serial.print("\""); Serial.print(message); Serial.println("\"");

    // try to find which word we entered
    for (languageIndex = 0; languageIndex < nbWords; languageIndex++) {
      if (!strcmp(message, stringsOfInterst[languageIndex])) {
        found = true;
        break;
      }
    }

    if (found) {
      Serial.print("This is "); Serial.println(language[languageIndex]);

      // you can also use languageIndex for more complicated stuff now per language in a switch / case and the enum makes it readable
      switch (languageIndex) {
        case   _Hello_ :
          Serial.println("I live in London");
          break;

        case  _Salut_ :
          Serial.println("je vis en France");
          break;

        case  _Hallo_ :
          Serial.println("Sauerkraut!");
          break;

        case  _Ciao_ :
          Serial.println("I love pizza");
          break;

        case  _Ahoj_ :
          Serial.println("You get the idea");
          break;

        case  _Bog_ :
          break;

        case  _Marhaba_ :
          break;

        case  _Hej_ :
          break;

        case  _NiHao_ :
          break;

        case  _Shalom_ :
          break;

        case  _Namaste_ :
          break;
      }

    } else {
      Serial.print("Sorry \""); Serial.print(message); Serial.println("\" is not in my dictionnary.");
    }
    Serial.print("\nEnter 'Hello' in one language: ");
  }
}

it reads an entry form the Serial Console (Hello in one of the known languages) and does something based on the input

Give it a try