Arduino with usb host shield and 2d Scanner

Hello Processing World. I am new to Processing, but not to Arduino. i am working with a 2d Scanner connected to a USB Host Shield in which is mounted onto an Arduino MEGA . Well the thing is that the Arduino sees the Scanner fine and works flawlessly. but when i try to read with Processing, it wont just work for me. I tried  many forms of Processing Serial read codes that i have found online and i figured i post the basic one that made sense to me and someone sees the scanner.   Any suggestion, 

Thanks in Advance

 below are the Arduino and the Procossing code.

Arduino Code

#include <usbhid.h>
#include <usbhub.h>
#include <hiduniversal.h>
#include <hidboot.h>
#include <SPI.h>


class MyParser : public HIDReportParser {
  public:
    MyParser();
    void Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
  protected:
    uint8_t KeyToAscii(bool upper, uint8_t mod, uint8_t key);
    virtual void OnKeyScanned(bool upper, uint8_t mod, uint8_t key);
    virtual void OnScanFinished();
};

MyParser::MyParser() {}

void MyParser::Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) {
  // If error or empty, return
  if (buf[2] == 1 || buf[2] == 0) return;

  for (uint8_t i = 7; i >= 2; i--) {
    // If empty, skip
    if (buf[i] == 0) continue;

    // If enter signal emitted, scan finished
    if (buf[i] == UHS_HID_BOOT_KEY_ENTER) {
      OnScanFinished();
    }

    // If not, continue normally
    else {
      // If bit position not in 2, it's uppercase words
      OnKeyScanned(i > 2, buf, buf[i]);
    }

    return;
  }
}

uint8_t MyParser::KeyToAscii(bool upper, uint8_t mod, uint8_t key) {
  
  // Letters
  if (VALUE_WITHIN(key, 0x04, 0x1d)) {
    if (upper) return (key - 4 + 'A');
    else return (key - 4 + 'a');
  }

  // Numbers
  else if (VALUE_WITHIN(key, 0x1e, 0x27)) {
    return ((key == UHS_HID_BOOT_KEY_ZERO) ? '0' : key - 0x1e + '1');
  }

  return 0;
}

void MyParser::OnKeyScanned(bool upper, uint8_t mod, uint8_t key) {
  uint8_t ascii = KeyToAscii(upper, mod, key);
  Serial.print((char)ascii);
  delay(1);
}

void MyParser::OnScanFinished() {
  //Serial.println(" - Finished");
  Serial.println(F("\r"));
 
}

USB          Usb;
USBHub       Hub(&Usb);
HIDUniversal Hid(&Usb);
MyParser     Parser;

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

  if (Usb.Init() == -1) {
   // Serial.println("OSC did not start.");
   
  }

  delay( 200 );

  Hid.SetReportParser(0, &Parser);
}

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

Processing basic serial read code

import processing.serial.*;
Serial port;
int val;

void setup() {
size (500, 200); 
  port = new Serial(this, "COM29", 115200);// com29 is the Arduino mega port currently used
}

void draw() {
  
  if (port.available()>0) {
    val=port.read();
    println(val);
    delay(100);
  }
}
1 Like

you have a processing code
? and are connected to Arduino with correct port and speed?

? but your processing program not prints anything?

the basic thing is that it is not obvious from your Arduino code WHAT you send.

so please run the Arduino ide // monitor // 115200 /
and copy to here what you have as data.

after that we talk about a better processing serial code

here is the Arduino Code. and how can i improve from my basic Processing to something that can display my bar codes…

sorry if i ask for so much. i just want to understand how the communication between processing and arduino work.

#include <usbhid.h>
#include <usbhub.h>
#include <hiduniversal.h>
#include <hidboot.h>
#include <SPI.h>

class MyParser : public HIDReportParser {
  public:
    MyParser();
    void Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
  protected:
    uint8_t KeyToAscii(bool upper, uint8_t mod, uint8_t key);
    virtual void OnKeyScanned(bool upper, uint8_t mod, uint8_t key);
    virtual void OnScanFinished();
};

MyParser::MyParser() {}

void MyParser::Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) {
  // If error or empty, return
  if (buf[2] == 1 || buf[2] == 0) return;

  for (uint8_t i = 7; i >= 2; i--) {
    // If empty, skip
    if (buf[i] == 0) continue;

    // If enter signal emitted, scan finished
    if (buf[i] == UHS_HID_BOOT_KEY_ENTER) {
      OnScanFinished();
    }

    // If not, continue normally
    else {
      // If bit position not in 2, it's uppercase words
      OnKeyScanned(i > 2, buf, buf[i]);
    }

    return;
  }
}

uint8_t MyParser::KeyToAscii(bool upper, uint8_t mod, uint8_t key) {
  // Letters
  if (VALUE_WITHIN(key, 0x04, 0x1d)) {
    if (upper) return (key - 4 + 'A');
    else return (key - 4 + 'a');
  }

  // Numbers
  else if (VALUE_WITHIN(key, 0x1e, 0x27)) {
    return ((key == UHS_HID_BOOT_KEY_ZERO) ? '0' : key - 0x1e + '1');
  }

  return 0;
}

void MyParser::OnKeyScanned(bool upper, uint8_t mod, uint8_t key) {
  uint8_t ascii = KeyToAscii(upper, mod, key);
  Serial.print((char)ascii);
  delay(1);
}

void MyParser::OnScanFinished() {
  //Serial.println(" - Finished");
  Serial.println(F("\r"));
 
}

USB          Usb;
USBHub       Hub(&Usb);
HIDUniversal Hid(&Usb);
MyParser     Parser;

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

  if (Usb.Init() == -1) {
   // Serial.println("OSC did not start.");
   
  }

  delay( 200 );

  Hid.SetReportParser(0, &Parser);
}

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

here is the basic Processing Code.

import processing.serial.*;

Serial myPort;
void setup()
{
  String portName = "COM4";
    
   myPort = new Serial(this, portName, 9600);
}
void draw()
{
  if(myPort.available()>0)
  {
  println(myPort.read());
  delay(1000);
  }
  else
  {
  println("no devices found");
  }
}
1 Like

the changed processing serial code now has

  • a different baud rate as the arduino? why
  • a other port ? is that now correct?
  • what you see on console?
  • DO NOT use the delay line!

i am sorry, but i can not understand the arduino code insofar
that i could guess what it is sending to processing.

i asked you to show us THE DATA your arduino is sending.
( by logging the data in the Arduino IDE serial monitor )
you must with this proof also that you are sending data from Arduino at all also.

1 Like

I am so sorry i thought you ment to show you the codes. The data that it is showing the arduino Serial Monitor is showing is the Bar Code number. I was aware about the COM Diffrecnces thanks for pointing that out.

keep in mind i am new to processing and i am not a graphic guru…

But that doesnt keep me from trying. here is the latest code i have been working on Processing.
now i get to ssee the Bard nuber now but i dont know how to maintain to stay .

is it okay if i ask you how i may improve.


import processing.serial.*;

Serial myPort;
float value;
PFont myFont;


void setup(){ //same as arduino program

   // screen size of the program
  size(1200, 200);
  
  printArray(Serial.list());   //prints all available serial ports
  
   //println(Serial.list());
  myPort = new Serial(this, "COM8", 115200);//i have connected arduino to com8, 
  
  //lets add buton to empty window 
  myFont = createFont("verdana", 30);    // custom fonts for buttons and title
  
  
}
  
  void draw(){  //same as loop in arduino
 
  background(0); // background color of window (r, g, b) or (0 to 255)
    //lets give title to our window
  fill(234);              //text color (r, g, b) 
  textFont(myFont);
  text("Scanner Code", 480, 25);
  serialEvent();
  
  }
  void serialEvent() {
  // get message till line break (ASCII > 13)
  String data1 = myPort.readStringUntil(13);
  if (data1 != null) {
    print(data1);
    text(data1, 450, 50);

    
  }  
}

Sorry, my english is alot better then that. My computer was lagging on my previous reply.

that is not a language problem,
my English is actually below what is needed to work here,
but on the other side, it is a world wide forum,
even with Spanish and English pages you not cover the majority of the people.
( Chinese Hindi …)


but looks like you again avoid showing us what the Arduino is sending,
but if you see in processing console

print(data1);

what you need to, communication is no issue anymore.


but i noticed that now using COM8 not COM4 or COM29
hm
you work with Arduino and upload code from Arduino IDE
and adjust a com port for upload and monitor…
so i can not understand how you can not know the correct com port
when you write the processing program…
as windows usually use same port for same device
unless you juggle with connecting many usb devices??


ok, your serial event code uses a local variable data1
++ the print to console works,
– the text to canvas only for 1/60 of a second

but you have the global variable
float value ?? is that what you expect? to get from Arduino a float number?
better start with a global string ( could make data1 global but actually not good style )

String data_in;

void serialEvent() {
  String data1 = myPort.readStringUntil(13);
  if (data1 != null) {
    print(data1);
    // later evaluate that data1 more on length or convert to number...
    data_in = data1; // change only if new good data come in
  }
}

void draw() {
   background(0);
   text(data_in, 450, 50);  //__ show last good Arduino string ( 60 times per sec )
}
1 Like

Yes, communication between the Arduino and Processing is not an issues.

I think i am not understanding processing.

  1. i call out all my libraries that i required
  2. i configure the serial ports according to arduino
  3. i call out my fonts and size
  4. create the void draw function where my data for my serial port is going to be displayed
  5. gather my data from the serial port and display it.

Now once I press my scanner to read the barcode(information from the Serial port). it reads it and it disappears, it doesnt stay. is there a press button release function that I missing>?

Here is my clean and readable code for processing. I havent touched the code for the Arduino as that one is working fine.


import processing.serial.*;
Serial myPort;
PFont myFont;


void setup(){ //same as arduino program

   // screen size of the program
  size(800, 200);
  
  printArray(Serial.list());   //prints all available serial ports
  
   //println(Serial.list());
  myPort = new Serial(this, "COM8", 115200);//i have connected arduino to com8, 
  
  //lets add buton to empty window 
  myFont = createFont("verdana", 50);    // custom fonts for buttons and title
  
}
  
  void draw(){  //same as loop in arduino
 
  background(255); // background color of window (r, g, b) or (0 to 255)
    //lets give title to our window
  fill(25, 180, 255);              //text color (r, g, b) 
  textFont(myFont);
  text("Scanner Code", 200, 50);
  serialEvent();
  
  }
  void serialEvent() {
  // get message till line break (ASCII > 13)
  String data1 = myPort.readStringUntil(13);
  if (data1 != null) {    
    text(data1, 200, 70);
   

    
  }  
}

again you do the text() from inside serial event with a local variable,
like you not read above post.
also i now see that you call the serial event from draw?? where you got that code from?

here i give you a working combination of arduino sensor code and processing terminal code
arduino:

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.print( analogRead(0) );          // A0
  Serial.print(",");
  Serial.print( analogRead(1) );          // A1
  Serial.println(",");
  delay(1000);                            // every second
}


/* if A0 at 5V see on arduino monitor
1023,868,
1023,867,
1023,866,
1023,865,
1023,866,
*/

processing:

// rev 0.1 add a list of records

import processing.serial.*;

Serial myPort;
String data; // latest arduino line
int[] datai; // as array of integers
StringList list = new StringList(); // stored lines
int listlong = 18; // many

int w= 640, h = 360; // canvas settings

void setup_serial() { // USB arduino..
  printArray(Serial.list());
  String portName = Serial.list()[0]; // adjust 0.. x port
  myPort = new Serial(this, portName, 9600);
  myPort.clear();
  myPort.bufferUntil('\n');
  println("try connect to "+portName);
}

void serialEvent(Serial p) { // handle serial data
  data = trim(p.readStringUntil('\n'));
  if (data != null) {
    //println(data); // print every GOOD line
    datai = int( split(data, ",") ); // create int array (unused example )
    list.append( data ); // OR store line as String list
    if ( list.size() >= listlong ) list.remove(0); // erase the oldest? // for ( int i = 0; i }
  }
}

void settings() {
  size(w, h);
}

void setup() {
  setup_serial();
}

void draw() {
  background(0, 0, 80);
  for ( int i = 0; i < list.size(); i++ ) text( list.get(i), 10, 20+i*20 ); // running list of arduino lines
}

my idea is you ignore your project for 10 minutes and
load a arduino with above code
and start above processing code

1 Like

Thank you so much for your help. As for changing the Arduino Code, I dont want to change much in it, as it is working fine with the other programs that i need it for.I figured since I am already getting a Serial display coming out it, it would be easier to adapt Processing to it. But it seems more complicated then what I thought. In the arduino Code the Scanner bar codes are being displayed by the following code lines. Adding to the void loop or void setup will not do much, but maybe interrupt from displaying the scanned bar code in Serial Monitor, and that is working fine.

Here is the code from where the bar code is scanned and displayed in Serial Monitor…

void MyParser::OnKeyScanned(bool upper, uint8_t mod, uint8_t key) {
  uint8_t ascii = KeyToAscii(upper, mod, key);
  Serial.print((char)ascii);  
}

As you reply , i will keep on playing around with the codes as there is much to learn.

1 Like

Kll, I got the scanner working with the Sketch code you shared with me, and of course with some minor changes, and with out making changes to the Arduino Sketch.

Once again thank you.

1 Like