Scale example added

This commit is contained in:
Oleg Mazurov 2013-09-06 17:03:19 -06:00
parent 6993e811c6
commit 254ff72e55
3 changed files with 279 additions and 0 deletions

View file

@ -0,0 +1,56 @@
/* Digital Scale Output. Written for Stamps.com Model 510 */
/* 5lb Digital Scale; any HID scale with Usage page 0x8d should work */
#include <avr/pgmspace.h>
#include <avrpins.h>
#include <max3421e.h>
#include <usbhost.h>
#include <usb_ch9.h>
#include <Usb.h>
#include <usbhub.h>
#include <avr/pgmspace.h>
#include <address.h>
#include <hid.h>
#include <hiduniversal.h>
#include "scale_rptparser.h"
#include <printhex.h>
#include <message.h>
#include <hexdump.h>
#include <parsetools.h>
USB Usb;
USBHub Hub(&Usb);
HIDUniversal Hid(&Usb);
Max_LCD LCD(&Usb);
ScaleEvents ScaleEvents(&LCD);
ScaleReportParser Scale(&ScaleEvents);
void setup()
{
Serial.begin( 115200 );
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();
}

View file

@ -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...
}

View file

@ -0,0 +1,73 @@
#if !defined(__SCALERPTPARSER_H__)
#define __SCALERPTPARSER_H__
#include <inttypes.h>
#include <avr/pgmspace.h>
#include "avrpins.h"
#include "max3421e.h"
#include "usbhost.h"
#include "usb_ch9.h"
#include "Usb.h"
#include "Max_LCD.h"
#if defined(ARDUINO) && ARDUINO >=100
#include "Arduino.h"
#else
#include <WProgram.h>
#endif
#include "printhex.h"
#include "hexdump.h"
#include "message.h"
#include "confdescparser.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__