Page 2 of 2

Re: Reading a USB stream from a DYMO M10 scales

Posted: Saturday 24th December 2016 4:01am
by Got2BeFree
I've change the subject to better fit what this thread is about.

I was able to read (and decode) the USB stream from the DYMO M10 scale using Gambas and a couple shell commands. During this exercise I've learned the dymo scales uses a raw stream to output an array of 6 elements. After finding a Perl script that allowed me to see what the actual output was, it was just a matter of replicating it in Gambas. This turned out much easier than I had originally thought it would be. Below is the final code showing exactly how easy it was. Thanks to cogier for posting his example that I was able to build off of.

Starting with cogier's code, I move the hProc from the Form_Open() sub to a buttonStart_Click() sub so I could restart the process whenever the scales went into auto-off.

Next I needed to make sure I was using the correct HID device so I grep'd a single line in dmesg for "DYMO M10" and took it's output and pulled the correct HID device from it, plugging that into the hProc command.

Reading the stream output as Byte correctly displayed the stream which allowed each element to be added to an array (iData[0-5]).
The 6 elements are:
  • The 1st element is unknown. It could be an error state with '3' being normal operation.
    The 2nd element indicates the state the scale is in. (values: 2, 4, 5, 6) '2' = zero weight, '4' = positive weight, '5' = negative weight, '6' = over max weight
    The 3rd element (either 2 or 11) is what the unit of weight mode the scale is in (ounces/kilograms).
    The 4th element is for calculating the scaling factor while the scale is in ounce mode. (values: 0, 254, 255)
    The 5th and 6th elements are used for calculating the weight.
And finally, when the scales go off-line, the _Kill() sub clears the TextBoxes and displays a message.

A Timer can be used to continuously check for when the scales come on-line.

Hopefully someone can use this as a starting point to read other scales (or usb/hidraw devices).

Code: Select all

' Gambas class file

Public hProc As Process

Public Sub Form_Open()

    Label1.Text = "Make sure power is on, then press the start button."

End

Public Sub buttonStart_Click()

    Dim sOutput As String

    Shell "dmesg | grep \"DYMO M10\" | head -n 1" To sOutput
    sOutput = Mid$(sOutput, InStr(sOutput, "hidraw"), 7)
    hProc = Exec ["sudo", "cat", "/dev/" & sOutput] For Read As "plugin"
    Label1.Text = "Ready to weigh."

End

Public Sub plugin_Kill()

    TextBox1.Text = Null
    TextBox2.Text = Null
    TextBox3.Text = Null
    TextBox4.Text = Null
    TextBox5.Text = Null
    TextBox6.Text = Null
    Label1.Text = "Scales is off-line."

End

Public Sub plugin_Read()

    Dim iTemp As Integer
    Dim iData As New Integer[]
    Dim i As Integer

    For i = 0 To 5
        iTemp = Read #Last As Byte
        iData.Add(iTemp, i)
    Next

    TextBox1.Text = iData[0]
    TextBox2.Text = iData[1]
    TextBox3.Text = iData[2]
    TextBox4.Text = iData[3]
    TextBox5.Text = iData[4]
    TextBox6.Text = iData[5]

End 

Public Sub Form_Close()

    Try hProc.Kill

End

Public Sub ButtonExit_Click()

    Try hProc.Kill
    Me.Close

End

The form is simply 2 buttons, 1 Label, and 6 TextBoxes.


[edit: corrected/updated element list.]

.

Re: Reading a USB stream from a DYMO M10 scales

Posted: Sunday 25th December 2016 7:05pm
by jornmo
Have you disabled password for sudo on your linux user for this to work?
What if you got more than 9 hidraw files? (Hint: gb.pcre -> regex)

Re: Reading a USB stream from a DYMO M10 scales

Posted: Monday 26th December 2016 3:13am
by Got2BeFree
I've set up sudo to let my user be root for certain commands.

Not sure what you are referring to with the second question, so I'll answer it this way... If you grep the device's name (eg: "dymo" in my case) and extract the hid device name (eg: "hidraw3" in my case) and feed that to the 'cat' command, it shouldn't matter how many hid files, or even if the device changes each time they are plugged in. At least I don't think it would matter. I haven't had a chance to test this by moving the scales to a different computer.

Re: Reading a USB stream from a DYMO M10 scales

Posted: Monday 26th December 2016 10:09am
by jornmo
My second question referes to this:

Code: Select all

sOutput = Mid$(sOutput, InStr(sOutput, "hidraw"), 7)
If you've got a file named "hidraw10" it will not work, it needs to be 8, not 7 in that case.

Re: Reading a USB stream from a DYMO M10 scales

Posted: Monday 26th December 2016 6:50pm
by Got2BeFree
Ah, I see what you're referring to now. In that case, you will need to modify the code to fit your situation. :P ;) I doubt I'll ever have more than 10 hid devices attached, so this works for me. The computer this will eventually be used on is a dedicated pc for my inventory system.

There's probably a better way also than grep'ing the dmesg file to find the device name/file pair since that would mean that the device would have had to been plugged in at some point after the dmesg file was cleaned.

Re: Reading a USB stream from a DYMO M10 scales

Posted: Tuesday 27th December 2016 12:35am
by Got2BeFree
I decided to try to do this the right way so hidraw file numbers higher than 9 would be found, so I've spent the past 45 minutes trying to understand how the gb.pcre function works.

Since I couldn't understand gb.pcre, I decided to go back to the basics and just add an additional grep to the shell command. It worked on a test file, but since I only have 4 hidraw devices connected, I couldn't test for greater than a single digit in real use.

This change should find any hidraw file with 1 or more digits (ie: hidraw10) associated with the search string "dymo m10".

Code: Select all


    Shell "dmesg | grep \"DYMO M10\" | head -n1 | grep -o 'hidraw[0-9]*'" To sOutput
' old : Shell "dmesg | grep \"DYMO M10\" | head -n1" To sOutput

    hProc = Exec ["sudo", "cat", "/dev/" & Trim$(sOutput)] For Read As "Data"
' old: hProc = Exec ["sudo", "cat", "/dev/" & sOutput] For Read As "Data"

I had to Trim$ the output of the shell command since the additional grep added a newline that's only present using the shell command and not while using a terminal.
.

Re: Reading a USB stream from a DYMO M10 scales

Posted: Wednesday 28th December 2016 11:03am
by jornmo
Well, what you just did in the shell here, is what gb.pcre does. [0-9]* is regular expression for any digits between 0-9, which is the same as any digit. That mean you could use \d instead of [0-9]. When you just leave it there it will stop looking at the first match, but when you added * it will continue til it finds no more digits. This site holds good info on regular expressions: http://www.regular-expressions.info/

Re: Reading a USB stream from a DYMO M10 scales

Posted: Wednesday 28th December 2016 6:16pm
by Got2BeFree
I know that gb.pcre does what I did, I just haven't figured out how to use it.

\d doesn't work with grep, you have to use [0-9].