Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read weight from a Fairbanks SCB-9000 USB Scale

Tags:

c#

usb

hid

I am trying to create an executable that can be called and pass back a weight from a Fairbanks SCB-9000 USB scale. I have found some code that was for a different model scale, but it is not quite working for me. I am specifically having an issue with the following method. It is giving me an error: "Cannot Implicity Convert Type 'System.Collections.Generic.IEnumerable' to 'HidLibrary.HidDevice[]'." I have tried several ways of casting this, but I can't get it to work. Any suggestions here, or has anyone ever written any code for this particular scale?

Thank you,

Rob

Here is the method in question:

    public HidDevice[] GetDevices()
    {
        HidDevice[] hidDeviceList;

        // Fairbanks Scale
        hidDeviceList = HidDevices.Enumerate(0x0B67, 0x555E);

        if (hidDeviceList.Length > 0)

            return hidDeviceList;

    }

Sorry should have added that I am using Mike Obrien's HidLibrary from here: http://nuget.org/packages/hidlibrary

UPDATE WITH FULL CODE...

Here is the code that I am using...

program.cs

using System;
using System.Threading;
using HidLibrary;
using Scale;

namespace ScaleReader
{
    class Program
    {
        public static void Main(string[] args)
        {
            decimal? weight;
            bool? isStable;

            USBScale s = new USBScale();
            s.Connect();

            if (s.IsConnected)
            {
                s.GetWeight(out weight, out isStable);
                s.DebugScaleData();
                Console.WriteLine("Weight: {0:0.00} LBS", weight);
            }
            else
            {
                Console.WriteLine("No Scale Connected.");
            }

            s.Disconnect();
            Thread.Sleep(500);
        }
    }
}

Scale.cs

using HidLibrary;
using System.Threading;
using System;
using System.Collections.Generic;
using System.Text;

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() 
{ 
    return HidDevices.Enumerate(0x0B67, 0x555E).Cast<HidDevice>().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? weight, out bool? isStable)
        {
            weight = 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) / 100;

                switch (Convert.ToInt16(inData.Data[2]))
                {
                    case 3:  // Kilos
                        weight = weight * (decimal?)2.2;
                        break;
                    case 11: // Ounces
                        weight = weight * (decimal?)0.625;
                        break;
                    case 12: // Pounds
                        // already in pounds, do nothing
                        break;
                }
                isStable = inData.Data[1] == 0x4;
            }
        }
    }
}
like image 610
user1599271 Avatar asked Aug 14 '12 21:08

user1599271


2 Answers

What you have won't compile since you don't always return something. Based on the error message, this is all you really need. I can't find any reference for HidDevice or HidDevices so I can't say this will work with absolute certainty.

public HidDevice[] GetDevices()
{
    return HidDevices.Enumerate(0x0B67, 0x555E).Cast<HidDevice>().ToArray();
}

You'll have to add this line for it to compile:

using System.Linq;

As a side-note, get ReSharper.

like image 64
Austin Salonen Avatar answered Nov 15 '22 09:11

Austin Salonen


Wanted to add a few notes to this to help others. I'm specifically looking at the FIXME comment in the code referring to the division question.

I've been working with Mettler Toledo PS family of scales, PS-60, PS-15, and PS-90. In the HID data return the third element returns 255 for PS-15 and both PS-60 and PS-90 return 254.

Using calibration weights I found PS-15 needed division by 10 to get the weight right and PS-60/90 required Division by 100.

like image 20
Larry Avatar answered Nov 15 '22 09:11

Larry