// Simple test for receiving data from Serial
// like BU-353S4
//
// This example is in the public domain
#include "USBHost_t36.h"
#define USBBAUD 4800
uint32_t baud = USBBAUD;
uint32_t format = USBHOST_SERIAL_8N1;
USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(myusb);
USBHIDParser hid1(myusb);
USBHIDParser hid2(myusb);
USBHIDParser hid3(myusb);
// There is now two versions of the USBSerial class, that are both derived from a common Base class
// The difference is on how large of transfers that it can handle. This is controlled by
// the device descriptor, where up to now we handled those up to 64 byte USB transfers.
// But there are now new devices that support larger transfer like 512 bytes. This for example
// includes the Teensy 4.x boards. For these we need the big buffer version.
// uncomment one of the following defines for userial
//USBSerial userial(myusb); // works only for those Serial devices who transfer <=64 bytes (like T3.x, FTDI...)
USBSerial_BigBuffer userial(myusb, 1); // Handles anything up to 512 bytes
//USBSerial_BigBuffer userial(myusb); // Handles up to 512 but by default only for those > 64 bytes
USBDriver *drivers[] = { &hub1, &hub2, &hid1, &hid2, &hid3, &userial };
#define CNT_DEVICES (sizeof(drivers) / sizeof(drivers[0]))
const char *driver_names[CNT_DEVICES] = { "Hub1", "Hub2", "HID1", "HID2", "HID3", "USERIAL1" };
bool driver_active[CNT_DEVICES] = { false, false, false, false };
#include <TinyGPS.h>
/* This sample code demonstrates the normal use of a TinyGPS object.
It assumes that you have a 4800-baud serial GPS device hooked up
to a serial port, or SoftwareSerial on pins 4(rx) and 3(tx).
*/
TinyGPS gps;
static void smartdelay(unsigned long ms);
static void print_float(float val, float invalid, int len, int prec);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
static void print_str(const char *str, int len);
void setup() {
pinMode(13, OUTPUT);
while (!Serial && (millis() < 5000))
; // wait for Arduino Serial Monitor
Serial.println("\n\nUSB Host Testing - Serial");
myusb.begin();
Serial.print("Testing TinyGPS library v. ");
Serial.println(TinyGPS::library_version());
Serial.println("by Mikal Hart");
Serial.println();
Serial.println("Sats HDOP Latitude Longitude Fix Date Time Date Alt Course Speed Card Distance Course Card Chars Sentences Checksum");
Serial.println(" (deg) (deg) Age Age (m) --- from GPS ---- ---- to London ---- RX RX Fail");
Serial.println("-------------------------------------------------------------------------------------------------------------------------------------");
}
void loop() {
float flat, flon;
unsigned long age, chars = 0;
unsigned short sentences = 0, failed = 0;
static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
myusb.Task();
// Print out information about different devices.
for (uint8_t i = 0; i < CNT_DEVICES; i++) {
if (*drivers[i] != driver_active[i]) {
if (driver_active[i]) {
Serial.printf("*** Device %s - disconnected ***\n", driver_names[i]);
driver_active[i] = false;
} else {
Serial.printf("*** Device %s %x:%x - connected ***\n", driver_names[i], drivers[i]->idVendor(), drivers[i]->idProduct());
driver_active[i] = true;
const uint8_t *psz = drivers[i]->manufacturer();
if (psz && *psz) Serial.printf(" manufacturer: %s\n", psz);
psz = drivers[i]->product();
if (psz && *psz) Serial.printf(" product: %s\n", psz);
psz = drivers[i]->serialNumber();
if (psz && *psz) Serial.printf(" Serial: %s\n", psz);
// If this is a new Serial device.
if (drivers[i] == &userial) {
// Lets try first outputting something to our USerial to see if it will go out...
userial.begin(baud);
}
}
}
}
digitalWrite(13, !digitalRead(13));
if (userial) {
print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
gps.f_get_position(&flat, &flon, &age);
print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 10, 6);
print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 11, 6);
print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
print_date(gps);
print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 7, 2);
print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2);
print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(gps.f_course()), 6);
print_int(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0xFFFFFFFF : (unsigned long)TinyGPS::distance_between(flat, flon, LONDON_LAT, LONDON_LON) / 1000, 0xFFFFFFFF, 9);
print_float(flat == TinyGPS::GPS_INVALID_F_ANGLE ? TinyGPS::GPS_INVALID_F_ANGLE : TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
print_str(flat == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON)), 6);
gps.stats(&chars, &sentences, &failed);
print_int(chars, 0xFFFFFFFF, 6);
print_int(sentences, 0xFFFFFFFF, 10);
print_int(failed, 0xFFFFFFFF, 9);
Serial.println();
smartdelay(1000);
}
}
static void smartdelay(unsigned long ms) {
unsigned long start = millis();
do {
while (userial.available())
gps.encode(userial.read());
myusb.Task();
} while (millis() - start < ms);
}
static void print_float(float val, float invalid, int len, int prec) {
if (val == invalid) {
while (len-- > 1)
Serial.print('*');
Serial.print(' ');
} else {
Serial.print(val, prec);
int vi = abs((int)val);
int flen = prec + (val < 0.0 ? 2 : 1); // . and -
flen += vi >= 1000 ? 4 : vi >= 100 ? 3
: vi >= 10 ? 2
: 1;
for (int i = flen; i < len; ++i)
Serial.print(' ');
}
smartdelay(0);
}
static void print_int(unsigned long val, unsigned long invalid, int len) {
char sz[32];
if (val == invalid) {
strcpy(sz, "*******");
} else {
sprintf(sz, "%ld", val);
}
sz[len] = 0;
for (int i = strlen(sz); i < len; ++i) {
sz[i] = ' ';
}
if (len > 0) {
sz[len - 1] = ' ';
}
Serial.print(sz);
smartdelay(0);
}
static void print_date(TinyGPS &gps) {
int year;
byte month, day, hour, minute, second, hundredths;
unsigned long age;
gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
if (age == TinyGPS::GPS_INVALID_AGE) {
Serial.print("********** ******** ");
} else {
char sz[32];
sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ",
month, day, year, hour, minute, second);
Serial.print(sz);
}
print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
smartdelay(0);
}
static void print_str(const char *str, int len) {
int slen = strlen(str);
for (int i = 0; i < len; ++i) {
Serial.print(i < slen ? str[i] : ' ');
}
smartdelay(0);
}