diff options
Diffstat (limited to 'lib/usbhost/USB_Host_Shield_2.0/examples/HID/scale')
3 files changed, 256 insertions, 0 deletions
diff --git a/lib/usbhost/USB_Host_Shield_2.0/examples/HID/scale/scale.ino b/lib/usbhost/USB_Host_Shield_2.0/examples/HID/scale/scale.ino new file mode 100644 index 0000000000..f26ff964da --- /dev/null +++ b/lib/usbhost/USB_Host_Shield_2.0/examples/HID/scale/scale.ino @@ -0,0 +1,51 @@ +/* Digital Scale Output. Written for Stamps.com Model 510 */ +/* 5lb Digital Scale; any HID scale with Usage page 0x8d should work */ + +#include <hid.h> +#include <hiduniversal.h> +#include <usbhub.h> + +#include "scale_rptparser.h" + +// Satisfy the IDE, which needs to see the include statment in the ino too. +#ifdef dobogusinclude +#include <spi4teensy3.h> +#include <SPI.h> +#endif + +USB Usb; +USBHub Hub(&Usb); +HIDUniversal Hid(&Usb); +Max_LCD LCD(&Usb); +ScaleEvents ScaleEvents(&LCD); +ScaleReportParser Scale(&ScaleEvents); + +void setup() +{ + Serial.begin( 115200 ); +#if !defined(__MIPSEL__) + while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection +#endif + Serial.println("Start"); + + if (Usb.Init() == -1) + Serial.println("OSC did not start."); + + // set up the LCD's number of rows and columns: + LCD.begin(16, 2); + LCD.clear(); + LCD.home(); + LCD.setCursor(0,0); + LCD.write('R'); + + delay( 200 ); + + if (!Hid.SetReportParser(0, &Scale)) + ErrorMessage<uint8_t>(PSTR("SetReportParser"), 1 ); +} + +void loop() +{ + Usb.Task(); +} + diff --git a/lib/usbhost/USB_Host_Shield_2.0/examples/HID/scale/scale_rptparser.cpp b/lib/usbhost/USB_Host_Shield_2.0/examples/HID/scale/scale_rptparser.cpp new file mode 100644 index 0000000000..01ed980cfb --- /dev/null +++ b/lib/usbhost/USB_Host_Shield_2.0/examples/HID/scale/scale_rptparser.cpp @@ -0,0 +1,150 @@ +/* Parser for standard HID scale (usage page 0x8d) data input report (ID 3) */ +#include "scale_rptparser.h" + +const char* UNITS[13] = { + "units", // unknown unit + "mg", // milligram + "g", // gram + "kg", // kilogram + "cd", // carat + "taels", // lian + "gr", // grain + "dwt", // pennyweight + "tonnes", // metric tons + "tons", // avoir ton + "ozt", // troy ounce + "oz", // ounce + "lbs" // pound +}; + +ScaleReportParser::ScaleReportParser(ScaleEvents *evt) : + scaleEvents(evt) +{} + +void ScaleReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) +{ + bool match = true; + + // Checking if there are changes in report since the method was last called + for (uint8_t i=0; i<RPT_SCALE_LEN; i++) { + if( buf[i] != oldScale[i] ) { + match = false; + break; + } + } + // Calling Game Pad event handler + if (!match && scaleEvents) { + scaleEvents->OnScaleChanged((const ScaleEventData*)buf); + + for (uint8_t i=0; i<RPT_SCALE_LEN; i++) oldScale[i] = buf[i]; + } +} + +ScaleEvents::ScaleEvents( Max_LCD* pLCD ) : + + pLcd( pLCD ) + +{} + +void ScaleEvents::LcdPrint( const char* str ) +{ + + while( *str ) { + + pLcd->write( *str++ ); + + } +} + +void ScaleEvents::OnScaleChanged(const ScaleEventData *evt) +{ + + pLcd->clear(); + pLcd->home(); + pLcd->setCursor(0,0); + + if( evt->reportID != 3 ) { + + const char inv_report[]="Invalid report!"; + + Serial.println(inv_report); + LcdPrint(inv_report); + + return; + + }//if( evt->reportID != 3... + + switch( evt->status ) { + + case REPORT_FAULT: + Serial.println(F("Report fault")); + break; + + case ZEROED: + Serial.println(F("Scale zero set")); + break; + + case WEIGHING: { + + const char progress[] = "Weighing..."; + Serial.println(progress); + LcdPrint(progress); + break; + } + + case WEIGHT_VALID: { + + char buf[10]; + double weight = evt->weight * pow( 10, evt->exp ); + + + + Serial.print(F("Weight: ")); + Serial.print( weight ); + Serial.print(F(" ")); + Serial.println( UNITS[ evt->unit ]); + + LcdPrint("Weight: "); + dtostrf( weight, 4, 2, buf ); + LcdPrint( buf ); + LcdPrint( UNITS[ evt->unit ]); + + break; + + }//case WEIGHT_VALID... + + case WEIGHT_NEGATIVE: { + + const char negweight[] = "Negative weight"; + Serial.println(negweight); + LcdPrint(negweight); + break; + } + + case OVERWEIGHT: { + + const char overweight[] = "Max.weight reached"; + Serial.println(overweight); + LcdPrint( overweight ); + break; + } + + case CALIBRATE_ME: + + Serial.println(F("Scale calibration required")); + break; + + case ZERO_ME: + + Serial.println(F("Scale zeroing required")); + break; + + default: + + Serial.print(F("Undefined status code: ")); + Serial.println( evt->status ); + break; + + }//switch( evt->status... + +} diff --git a/lib/usbhost/USB_Host_Shield_2.0/examples/HID/scale/scale_rptparser.h b/lib/usbhost/USB_Host_Shield_2.0/examples/HID/scale/scale_rptparser.h new file mode 100644 index 0000000000..57fbb033bf --- /dev/null +++ b/lib/usbhost/USB_Host_Shield_2.0/examples/HID/scale/scale_rptparser.h @@ -0,0 +1,55 @@ +#if !defined(__SCALERPTPARSER_H__) +#define __SCALERPTPARSER_H__ + +#include <max_LCD.h> +#include <hid.h> + +/* Scale status constants */ +#define REPORT_FAULT 0x01 +#define ZEROED 0x02 +#define WEIGHING 0x03 +#define WEIGHT_VALID 0x04 +#define WEIGHT_NEGATIVE 0x05 +#define OVERWEIGHT 0x06 +#define CALIBRATE_ME 0x07 +#define ZERO_ME 0x08 + +/* input data report */ +struct ScaleEventData +{ + uint8_t reportID; //must be 3 + uint8_t status; + uint8_t unit; + int8_t exp; //scale factor for the weight + uint16_t weight; // +}; + +class ScaleEvents +{ + + Max_LCD* pLcd; + + void LcdPrint( const char* str ); + +public: + + ScaleEvents( Max_LCD* pLCD ); + + virtual void OnScaleChanged(const ScaleEventData *evt); +}; + +#define RPT_SCALE_LEN sizeof(ScaleEventData)/sizeof(uint8_t) + +class ScaleReportParser : public HIDReportParser +{ + ScaleEvents *scaleEvents; + + uint8_t oldScale[RPT_SCALE_LEN]; + +public: + ScaleReportParser(ScaleEvents *evt); + + virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf); +}; + +#endif // __SCALERPTPARSER_H__ |