Reading a USB stream from a DYMO M10 scales

Post

Posted
Rating:
#1 (In Topic #102)
Avatar
Administrator
sholzy is in the usergroup ‘unknown’
Hi all.

Anyone have any experience reading usb hid streams? This is new territory for me and I might not be doing this correctly, so any help is greatly appreciated.

I have a Dymo M10 scale that I would like to read the output stream, along trying to decode it.  My first issues is an "access forbidden" error…

Code

hFile = Open "/dev/hidraw3" For Read Watch
Any ideas (short of running as root) to get around access permission? Changing access permissions only work until the scale goes into auto power-off. The hidraw file is recreated once the scale is powered on again and permissions are reset.

I'm not 100% sure what type of data type to use. When changing access permission on hidraw3, and running, this…

Code

Public Sub File_Read()

    Dim iByte As Byte

    Read #hFile, iByte
    Print "Got one byte: "; iByte

End
just outputs a steady stream of "3"'s. Using other data types just give me different output numbers.

From what I can find on the 'net, there should be a data packet of 6 elements. If I'm able to get this worked out, I'd like to tie the scale into the inventory system I wrote this past week.


If this output from dmesg is of any help…

Code

[1221565.175330] usb 2-8: USB disconnect, device number 34
[1221626.550068] usb 2-8: new low-speed USB device number 35 using ohci-pci
[1221626.744476] usb 2-8: New USB device found, idVendor=0922, idProduct=8003
[1221626.744489] usb 2-8: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[1221626.744496] usb 2-8: Product: M10 10 lb Digital Postal Scale
[1221626.744501] usb 2-8: Manufacturer: DYMO
[1221626.744506] usb 2-8: SerialNumber: 0071431044934
[1221626.772802] hid-generic 0003:0922:8003.0026: hiddev0,hidraw3: USB HID v1.01 Device [DYMO M10 10 lb Digital Postal Scale] on usb-0000:00:02.0-8/input0

Thanks!

sholzy
Gambas One Site Director

To report bugs in the Gambas IDE:
Official Gambas Bug Tracker
Online now: No Back to the top

Post

Posted
Rating:
#2
Avatar
Regular
jornmo is in the usergroup ‘Regular’
This is a hard question that would demand a bit of research on my part in order to answer :) Perhaps you must direct the question to the mailing list? If you find a solution, we will be happy to hear how you solved it :)

Have a great day!

Online now: No Back to the top

Post

Posted
Rating:
#3
Avatar
Guru
cogier is in the usergroup ‘Guru’
 I am interested in reading a USB port and have tried various ideas but I'd like to know which Distro you are using. Ialso need to sort out closing a process, see another post.
Online now: No Back to the top

Post

Posted
Rating:
#4
Avatar
Guru
cogier is in the usergroup ‘Guru’
OK I have got a result. I have not been able to avoid the need for root permissions and as I don't have your scales so I experimented with a USB bar-code gun. I use Linux Mint which is based on the Ubuntu family so there may be other issues to deal with.

I have used 'gksu' to get root access. The output is full of all-sorts but I was able to get what I wanted. The bar-code I used is correctly displayed above the 'Convert' button.
Attachment

Hopefully you can pick something out of this: -
Image

(Click to enlarge)

Online now: No Back to the top

Post

Posted
Rating:
#5
Avatar
Administrator
sholzy is in the usergroup ‘unknown’
 Sorry for the late reply, been side-tracked on other things for a few weeks and I've set this project aside for awhile.

I've tried your project, cogier, but without any success. I do know the stream coming from the scale is binary. I've found a couple python scripts for the scale that I'll try to get working (and/or try to convert over to Gambas). I know nothing about python so it's going to take awhile once I pick up my project again.

Thanks everyone for your help. I'll post again once I'm working on this again.

sholzy
Gambas One Site Director

To report bugs in the Gambas IDE:
Official Gambas Bug Tracker
Online now: No Back to the top

Post

Posted
Rating:
#6
Avatar
Administrator
sholzy is in the usergroup ‘unknown’
I've picked this up again. I found a perl script tonight that got me pointed in the right direction. Now to get the scales working with Gambas…

I made 2 changes to cogier's code (marked as comment in the code):

Code

Public Sub Form_Open()

hProc = Exec ["sudo", "cat", "/dev/hidraw3"] For Read As "plugin"
' used 'sudo'. changed to '/dev/hidraw3'

End
The above changes are for obvious reasons. ;)

Code

Public Sub plugin_read()
Dim sTemp As String

sTemp = Read #Last As Byte   ' changed '#Last, -255' to '#Last As Byte'
TextArea1.text &= sTemp

End

This change allowed the binary stream to display correctly without any extra code:
341125536034112553603411255360341125536034112553603411255360341125536034112553603411255360341125536034112553603411255360341125536034112553603411255360341125536034112553603411255360341125536034112553603411255360341125536034112553603

The above is a 6-element array repeated constantly, but with different values depending the state of the scales (ie: weight, unit of weight [ounces/kilograms], if weight has stabilized, etc). So now that brings me to the actual bits needed…
3411255360

This can be broken down into the individual elements of the array…
3  4  11  255  36  0

My current goal is to get this stream into an array so I can easily read each element. Any advice/suggestions?

sholzy
Gambas One Site Director

To report bugs in the Gambas IDE:
Official Gambas Bug Tracker
Online now: No Back to the top

Post

Posted
Rating:
#7
Avatar
Administrator
sholzy is in the usergroup ‘unknown’
 Putting the stream into an array was much easier than I was expecting.

Since the scale has an auto-off after 3 minutes idle time, I need to test for a lack of stream so I can display a message. Is there a way to test for a stream?

sholzy
Gambas One Site Director

To report bugs in the Gambas IDE:
Official Gambas Bug Tracker
Online now: No Back to the top

Post

Posted
Rating:
#8
Avatar
Regular
jornmo is in the usergroup ‘Regular’
This is more or less of a guess work from my side, but perhaps you can check the Stream.EndOfFile boolean value, and send the Stream.Close() signal to kill it. Then you could monitor the hidraw3 file for changes with the gb.inotify component?

Online now: No Back to the top

Post

Posted
Rating:
#9
Avatar
Regular
jornmo is in the usergroup ‘Regular’
And, when there are changes you re-create the stream.

Online now: No Back to the top

Post

Posted
Rating:
#10
Avatar
Administrator
sholzy is in the usergroup ‘unknown’
I discovered using a _kill() sub works a treat. I can put whatever is needed in there to alert the user the scales is off-line.

I have to put this project to the side for awhile again. Next go around I should have enough to work this into my inventory project.

sholzy
Gambas One Site Director

To report bugs in the Gambas IDE:
Official Gambas Bug Tracker
Online now: No Back to the top

Post

Posted
Rating:
#11
Avatar
Administrator
sholzy is in the usergroup ‘unknown’
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:
<LIST>
  • <LI>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.</LI>
</LIST>

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

' 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.]

.

sholzy
Gambas One Site Director

To report bugs in the Gambas IDE:
Official Gambas Bug Tracker
Online now: No Back to the top

Post

Posted
Rating:
#12
Avatar
Regular
jornmo is in the usergroup ‘Regular’
 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)

Online now: No Back to the top

Post

Posted
Rating:
#13
Avatar
Administrator
sholzy is in the usergroup ‘unknown’
 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.

sholzy
Gambas One Site Director

To report bugs in the Gambas IDE:
Official Gambas Bug Tracker
Online now: No Back to the top

Post

Posted
Rating:
#14
Avatar
Regular
jornmo is in the usergroup ‘Regular’
My second question referes to this:

Code

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.

Online now: No Back to the top

Post

Posted
Rating:
#15
Avatar
Administrator
sholzy is in the usergroup ‘unknown’
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.

sholzy
Gambas One Site Director

To report bugs in the Gambas IDE:
Official Gambas Bug Tracker
Online now: No Back to the top

Post

Posted
Rating:
#16
Avatar
Administrator
sholzy is in the usergroup ‘unknown’
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


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

sholzy
Gambas One Site Director

To report bugs in the Gambas IDE:
Official Gambas Bug Tracker
Online now: No Back to the top

Post

Posted
Rating:
#17
Avatar
Regular
jornmo is in the usergroup ‘Regular’
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: Regular-Expressions.info - Regex Tutorial, Examples and Reference - Regexp Patterns

Online now: No Back to the top

Post

Posted
Rating:
#18
Avatar
Administrator
sholzy is in the usergroup ‘unknown’
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].

sholzy
Gambas One Site Director

To report bugs in the Gambas IDE:
Official Gambas Bug Tracker
Online now: No Back to the top
1 guest and 0 members have just viewed this.