Trying to use Arduino Uno R3 - with USB Host Shield, LCD, and USB Sensor

I am trying to use my Uno and USB Host Shield to send and receive messages to/from a USB sensor (3 axis accel & magnetometer) that uses NMEA communication. Also, I want to display orientation data on the LCD as it becomes available. This will be used on a pointing device to display real time azimuth, pitch, and roll.The USB sensor can operated @ 9600-115200 baud. I have the LCD displaying “Pit | Roll | Az”, but nothing shows up below it. Also, the only thing that shows in my serial monitor is the commands I am trying to send to the usb sensor. I have used Oleg’s test USB code (2.0) to verify the usb host shield is working. I really have no clue how to get strings and parse data and the like. The current code I have is:

#include <SoftwareSerial.h>
#include <Usb.h>
#include <usbhost.h>
#include <LiquidCrystal.h>

USB Usb;
LiquidCrystal lcd(14, 6, 5, 4, 3, 2);

byte PSPA=0;
byte HCHDM=0;
byte mLength=0;

void setup()
 {
 Serial.begin(115200);
 Serial.write("nmeaecho 1 set\r");  //command to echo characters
 lcd.begin(16,2);
 lcd.setCursor(0,0);
 lcd.write("Pit | Roll | Az");
 }
 

 void loop()
 {
lcd.setCursor(1,1);   
Usb.Task();
Serial.write("$PSPA,PR\r\n");  //command to get pitch and roll


///////////////////////////////////////////////////////////////////////

{PSPA=Serial.read();
    if (PSPA == '!')
    {
     // Get Length of NMEA Sentence
      mLength = Serial.read();
     // Initialise Array
      byte messageIn[mLength];
      int cnt = 0;
 
     // Get NMEA Sentence 
      while ((PSPA != 10) && (cnt <= (mLength - 2)))
      {
        PSPA = Serial.read();
        messageIn[cnt] = PSPA;
      // Display NMEA Sentence 
        Serial.print(messageIn[cnt]);
        lcd.print(messageIn[cnt]);
        cnt++;
      }
  }
  delay(100);
}
////////////////////////////////////////////////////////////////////////
Usb.Task();
Serial.write("$xxHDT\r\n");  //command to get azimuth
{HCHDM=Serial.read();
    if (HCHDM == '!')
    {
     // Get Length of NMEA Sentence
      mLength = Serial.read();
     // Initialise Array
      byte messageIn[mLength];
      int cnt = 0;
 
     // Get NMEA Sentence 
      while ((HCHDM != 10) && (cnt <= (mLength - 2)))
      {
        HCHDM = Serial.read();
        messageIn[cnt] = HCHDM;
      // Display NMEA Sentence 
        Serial.print(messageIn[cnt]);
        lcd.print(messageIn[cnt]);
        cnt++;
      }
  }
}
delay(1000);
 }

Thanks for the help in advance!

Serial.write("$PSPA,PR\r\n");  //command to get pitch and roll


///////////////////////////////////////////////////////////////////////

{PSPA=Serial.read();
    if (PSPA == '!')
    {
     // Get Length of NMEA Sentence
      mLength = Serial.read();

Make a request. Expect a response within a few nanoseconds. I doubt that your device is THAT fast.

Just tweaked my code and now I am getting back in my serial monitor:

nmeaecho 1 set
$PSPA,PR
255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255$xxHDT
$PSPA,PR
255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255$xxHDT
$PSPA,PR
255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255$xxHDT

This is not pulling from the usb sensor, because I can have it unplugged from the shield and the data still comes. Current code is:

#include <SoftwareSerial.h>

#include <Usb.h>
#include <usbhost.h>

#include <LiquidCrystal.h>

USB Usb;
LiquidCrystal lcd(14, 6, 5, 4, 3, 2);

byte PSPA=0;
byte HCHDM=0;
byte mLength=0;

void setup()
 {
 Serial.begin(115200);
 Serial.write("nmeaecho 1 set\r");
 lcd.begin(16,2);
 lcd.setCursor(0,0);
 lcd.write("Pit | Roll | Az");
 }
 

 void loop()
 {
lcd.setCursor(1,1);   
Usb.Task();
Serial.write("$PSPA,PR\r\n");
delay(75);

///////////////////////////////////////////////////////////////////////

{PSPA=Serial.read();
    if (PSPA == '!')
    Serial.print("DC4 Online");
    {
     // Get Length of NMEA Sentence
      mLength = Serial.read();
     // Initialise Array
      byte messageIn[mLength];
      int cnt = 0;
 
     // Get NMEA Sentence 
      while ((PSPA != 10) && (cnt <= (mLength - 2)))
      {
        PSPA = Serial.read();
        messageIn[cnt] = PSPA;
      // Display NMEA Sentence 
        Serial.print(messageIn[cnt]);
        lcd.print(messageIn[cnt]);
        cnt++;
      }
  }
  delay(100);
}
////////////////////////////////////////////////////////////////////////

Serial.write("$xxHDT\r\n");  
delay(75);
{HCHDM=Serial.read();
    if (HCHDM == '!')
    {
     // Get Length of NMEA Sentence
      mLength = Serial.read();
     // Initialise Array
      byte messageIn[mLength];
      int cnt = 0;
 
     // Get NMEA Sentence 
      while ((HCHDM != 10) && (cnt <= (mLength - 2)))
      {
        HCHDM = Serial.read();
        messageIn[cnt] = HCHDM;
      // Display NMEA Sentence 
        Serial.print(messageIn[cnt]);
        lcd.print(messageIn[cnt]);
        cnt++;
      }
  }
}
delay(1000);
 }
{PSPA=Serial.read();

Why is there a curly brace there? Why is the code jammed up tight against it? Why are you not calling Serial.available() first?

    if (PSPA == '!')

What is the body of this if statement? Most likely not what you think it is. Using curly braces after every if statement (and matching else, if present) AND inserting additional code IN the curly braces is useful.

      mLength = Serial.read();
     // Initialise Array
      byte messageIn[mLength];

What size array are you creating if Serial.read() returns -1?

Current code is:

#include <Usb.h>

#include <LiquidCrystal.h>

USB Usb;
LiquidCrystal lcd(14, 6, 5, 4, 3, 2);

byte PSPA=0;
byte HCHDM=0;
byte mLength=0;

void setup()
 {
 Serial.begin(115200);
 Serial.write("nmeaecho 1 set\r");
 lcd.begin(16,2);
 lcd.setCursor(0,0);
 lcd.write("Pit | Roll | Az");
 }
 

 void loop()
 {
lcd.setCursor(1,1);   
Usb.Task();
Serial.write("$PSPA,PR\r\n");
delay(75);

///////////////////////////////////////////////////////////////////////
if (Serial.available()>0);
Serial.print("DC4 is ON");

PSPA=Serial.read();
    if (PSPA == '!')
    Serial.print("DC4 Online");
    {
     // Get Length of NMEA Sentence
      mLength = Serial.read();
     // Initialise Array
      byte messageIn[mLength];
      int cnt = 0;
 
     // Get NMEA Sentence 
      while ((PSPA != 10) && (cnt <= (mLength - 2)))
      {
        PSPA = Serial.read();
        messageIn[cnt] = PSPA;
      // Display NMEA Sentence 
        Serial.print(messageIn[cnt]);
        lcd.print(messageIn[cnt]);
        cnt++;
      }
  }
  delay(100);

////////////////////////////////////////////////////////////////////////

Serial.write("$xxHDT\r\n");  
delay(75);
HCHDM=Serial.read();
    if (HCHDM == '!')
    {
     // Get Length of NMEA Sentence
      mLength = Serial.read();
     // Initialise Array
      byte messageIn[mLength];
      int cnt = 0;
 
     // Get NMEA Sentence 
      while ((HCHDM != 10) && (cnt <= (mLength - 2)))
      {
        HCHDM = Serial.read();
        messageIn[cnt] = HCHDM;
      // Display NMEA Sentence 
        Serial.print(messageIn[cnt]);
        lcd.print(messageIn[cnt]);
        cnt++;
      }
  }

delay(1000);
 }

I am getting the following with/without my sensor plugged into my USB host shield…

nmeaecho 1 set
$PSPA,PR
DC4 is ON255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255$xxHDT
$PSPA,PR
DC4 is ON255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255$xxHDT
$PSPA,PR
DC4 is ON255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255$xxHDT
$PSPA,PR
DC4 is ON255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255$xxHDT
$PSPA,PR
DC4 is ON255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255$xxHDT

I really am not sure what to respond with on the 2nd comment other than I am trying to put together stuff from http://slab.concordia.ca/2008/arduino/gps/

On the 3rd comment, here is some info from the software manual on the sensor I have…

"NMEA commands use ASCII text strings to communicate with the digital compass through the UART interface. All commands should follow the command syntax exactly. No white space should be included in NMEA command strings. Data is formatted with the first character being “$” to signify the start of a NMEA command and include a “*” to signify the start of the checksum. It is not necessary to include any checksum characters in commands sent to the digital compass."

I really am in over my head as far as communicating with digital sensors. I have only ever used analogue sensors.

if (Serial.available()>0);

The body of this statement is the semicolon on the end. Is that what you want?

PSPA=Serial.read();
    if (PSPA == '!')
    Serial.print("DC4 Online");
    {
     // Get Length of NMEA Sentence
      mLength = Serial.read();

If you expect to read two bytes from the serial buffer, you need to make sure that there are two to read.

    if (PSPA == '!')
    Serial.print("DC4 Online");

Why is printing "DC4 Online" conditional on PSPA being '!', when no other code is?

You have { and } in places that they are not needed and missing from places where they are.

Using Tools + Auto Format would help, too.

Response #1:
No, thanks for pointing that out. Fixed it.

Response #2:
Changed it to something new.
Check out my code.

Response #3:
Took out the print statement, and realized PSPA ==’$’, not ‘!’.

Latest Code:

#include <Usb.h>
#include <LiquidCrystal.h>

USB Usb;
LiquidCrystal lcd(14, 6, 5, 4, 3, 2);

byte PSPA=0;
byte HCHDM=0;
byte messageLine[128];

void setup()
{
  Serial.begin(115200);
  Serial.write("nmeaecho 1 set\r\n");
  lcd.begin(16,2);
  lcd.setCursor(0,0);
  lcd.write("Pit | Roll | Az");
}


void loop()
{
  lcd.setCursor(1,1);   
  Usb.Task();

 ///////////////////////////////////////////////////////////////////////  
  
  Serial.write("$PSPA,PR\r\n");
  delay(75);
if (Serial.available()>0)
lcd.write("DC4 Activated");
  
    PSPA=Serial.read();
    if(PSPA == '

Output:

nmeaecho 1 set
$PSPA,PR
$xxHDT
$PSPA,PR
$xxHDT
$PSPA,PR
$xxHDT
$PSPA,PR
$xxHDT

)
  {
    // Clear out the previous NMEA Message
    for(int i =0; i< 128; i++) { messageLine[i] = ‘1’; }

// Message Length Counter
    int index = 9;

while(PSPA != ‘\n’)
    {
      /*
      * Insert ’


Output:

§DISCOURSE_HOISTED_CODE_1§


 at position 1 in MessageLine, as position 0 is reserved
      * for the total number of chars contained in NMEA Message.
      */
      messageLine[index] = PSPA;
      index++;
      PSPA = Serial.read();
      lcd.print('PSPA');
      Serial.print('PSPA');
    }
  }
    delay(100);
  
  ////////////////////////////////////////////////////////////////////////

  Serial.write("$xxHDT\r\n");  
    delay(75);
    HCHDM=Serial.read();
    if(HCHDM == '

Output:

§_DISCOURSE_HOISTED_CODE_1_§

)
  {
    // Clear out the previous NMEA Message
    for(int i =0; i< 128; i++) { messageLine[i] = ‘1’; }

// Message Length Counter
    int index = 9;

while(HCHDM != ‘\n’)
    {
      /*
      * Insert ’


Output:

§DISCOURSE_HOISTED_CODE_1§


 at position 1 in MessageLine, as position 0 is reserved
      * for the total number of chars contained in NMEA Message.
      */
      messageLine[index] = HCHDM;
      index++;
      HCHDM = Serial.read();
      lcd.print('HCHDM');
      Serial.print('HCHDM');
  delay(1000);
}
  }
}

Output:

§_DISCOURSE_HOISTED_CODE_1_§

Do you still have a problem? Id so, what it it?

Yeah, the output I am seeing in my Serial monitor is just the commands I am trying to send through my usb host shield to my usb navigation sensor. How do I get these commands to go to the sensor? I should receive back something like "$HCHDM,300.4,M*2E" from the sensor in response to the "$xxHDM\r\n" command.

I seems like my commands our just not going where I want them to...

Yeah, the output I am seeing in my Serial monitor is just the commands I am trying to send through my usb host shield to my usb navigation sensor.

Other than Usb.Task(), I don't see that you are sending data to/getting data from the USB Host shield. Where are you doing that?

The Serial stuff is talking to the PC, not to the navigation sensor.

That is where I am lost. I don’t know how to specify where it is going… Is there a USB.print() command or something easy I am missing?

Is there a USB.print() command or something easy I am missing?

There is something you are missing. Easy? No. What you need to be doing is writing a driver for the device, which is not a beginner task, by a long shot.

How come the device works with a Terminal Emulator when plugged into my machine by usb? I didn't download a driver to the windows machine before trying this. Would the usb device load the driver to the windows machine when plugged in?

I have the cd that came with the sensor that downloads an .exe file that is a nice GUI. Any way I can glean a driver from the cd?

Device is DC-4 : https://thedigitalcompass.com/navigation-sensors/products/dc-4-compass/ Similar to what was used on: https://thedigitalcompass.com/uploads/pdf/ERAU%20Blackfinn.pdf

Anybody? :.

Your PC has a bunch of USB drivers. Presumably the sensor USB interface corresponds to one of them. If you want to connect the device to your USB host shield, you will have to provide the corresponding drivers on the Arduino. Do do that, you would have to first discover what type of USB device the sensor presents itself as. Maybe it's a plain old virtual serial port, but there's no point guessing - you need to find out, and then find/write the corresponding USB driver for the host shield.

You should be able to find example sketches using the USB host shield that give you an idea of what would be involved, but I'd regard that as quite an advanced project.

Here is what I have as far as if it is a serial port etc… also, what the drivers used are .