Download the source code and project files (Visual C# 2013 Desktop/Arduino)
This project connects to a USB postal scale (A Dymo 25 lb. postal scale in this example) and spews out readings every few seconds in a console. It's a very simple program, obviously, just to make sure I could connect to and get readings from a scale. The program is made up two files - Program.cs and Scale.cs.
Scale.cs is almost totally derived from the code located in this stackoverflow question. Thanks very much, "user1599271"!
//Program.cs
using System;
using System.Threading;
using HidLibrary;
using Scale;
using System.Timers;
namespace ScaleReader
{
class Program
{
private static System.Timers.Timer aTimer;
public static void Main(string[] args)
{
aTimer = new System.Timers.Timer(1000);
aTimer.Elapsed += OnTimedEvent;
aTimer.Enabled = true;
Console.WriteLine("Let the scale do it's thing...");
Console.ReadLine();
}
static void OnTimedEvent(object sender, System.EventArgs e)
{
decimal? weightInLb, weightInG, weightInOz;
bool? isStable;
USBScale s = new USBScale();
s.Connect();
if (s.IsConnected)
{
s.GetWeight(out weightInLb, out weightInG, out weightInOz, out isStable);
s.DebugScaleData();
Console.WriteLine("Weight: {0:0.00} g", weightInG);
Console.WriteLine("Weight: {0:0.00} LBS", weightInLb);
Console.WriteLine("Weight: {0:0.00} oz", weightInOz);
Console.WriteLine("--------------------- {0}", DateTime.Now);
s.Disconnect();
}
else
{
Console.WriteLine("No Scale Connected.");
}
}
}
}
//Scale.cs
//Original code source: http://stackoverflow.com/questions/11961412/read-weight-from-a-fairbanks-scb-9000-usb-scale
using HidLibrary;
using System.Threading;
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
namespace Scale
{
class USBScale
{
public bool IsConnected
{
get
{
return scale == null ? false : scale.IsConnected;
}
}
public decimal ScaleStatus
{
get
{
return inData.Data[1];
}
}
public decimal ScaleWeightUnits
{
get
{
return inData.Data[2];
}
}
private HidDevice scale;
private HidDeviceData inData;
public HidDevice[] GetDevices()
{
//The next line contains the product/vendor ID numbers for the Dymo 25lb Postal Scale, change these depdending on what scale you're using
return HidDevices.Enumerate(0x0922, 0x8004).Cast().ToArray();
}
public bool Connect()
{
// Find a Scale
HidDevice[] deviceList = GetDevices();
if (deviceList.Length > 0)
return Connect(deviceList[0]);
else
return false;
}
public bool Connect(HidDevice device)
{
scale = device;
int waitTries = 0;
scale.OpenDevice();
// sometimes the scale is not ready immedietly after
// Open() so wait till its ready
while (!scale.IsConnected && waitTries < 10)
{
Thread.Sleep(50);
waitTries++;
}
return scale.IsConnected;
}
public void Disconnect()
{
if (scale.IsConnected)
{
scale.CloseDevice();
scale.Dispose();
}
}
public void DebugScaleData()
{
for (int i = 0; i < inData.Data.Length; ++i)
{
Console.WriteLine("Byte {0}: {1}", i, inData.Data[i]);
}
}
public void GetWeight(out decimal? weightInLb, out decimal? weightInG, out decimal? weightInOz, out bool? isStable)
{
decimal? weight;
weight = null;
weightInG = null;
weightInLb = null;
weightInOz = null;
isStable = false;
if (scale.IsConnected)
{
inData = scale.Read(250);
// Byte 0 == Report ID?
// Byte 1 == Scale Status (1 == Fault, 2 == Stable @ 0, 3 == In Motion, 4 == Stable, 5 == Under 0, 6 == Over Weight, 7 == Requires Calibration, 8 == Requires Re-Zeroing)
// Byte 2 == Weight Unit
// Byte 3 == Data Scaling (decimal placement)
// Byte 4 == Weight LSB
// Byte 5 == Weight MSB
// FIXME: dividing by 100 probably wont work with
// every scale, need to figure out what to do with
// Byte 3
//weight = (Convert.ToDecimal(inData.Data[4]) + Convert.ToDecimal(inData.Data[5]) * 256) / 10;
switch (Convert.ToInt16(inData.Data[2]))
{
case 2: // Scale reading in g
weight = (Convert.ToDecimal(inData.Data[4]) + Convert.ToDecimal(inData.Data[5]) * 256);
weightInG = weight;
weightInLb = weight * (decimal?)0.00220462;
weightInOz = weight * (decimal?)0.035274;
//weightInG = weightInG * (decimal?)0.625;
break;
case 11: // Ounces
weight = (Convert.ToDecimal(inData.Data[4]) + Convert.ToDecimal(inData.Data[5]) * 256) / 10;
weightInLb = weight * (decimal?)0.0625;
weightInOz = weight;
weightInG = weight * (decimal?)28.3495;
break;
case 12: // Pounds
// already in pounds, do nothing
break;
}
isStable = inData.Data[1] == 0x4;
}
}
}
}