{"id":205462,"date":"2013-12-10T09:45:03","date_gmt":"2013-12-10T05:45:03","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=205462"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=205462","title":{"rendered":"<span class=\"post_title\">\u0427\u0442\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u0432\u0435\u0441\u043e\u0432 Mettler Toledo PS60<\/span>"},"content":{"rendered":"<div class=\"content html_format\">   \t\u041d\u0435 \u0442\u0430\u043a \u0434\u0430\u0432\u043d\u043e \u0432\u044b\u0438\u0433\u0440\u0430\u043b \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430 Elance \u2014 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0435 WinForms \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 Visual Basic, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u0432\u0435\u0441\u043e\u0432 Mettler Toledo PS60. <br \/>  \u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u0435\u0441\u044b \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f HID-\u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u043c, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c\u043e\u043c \u043f\u043e USB.<br \/>  \u0412 \u044d\u0442\u043e\u043c \u043f\u043e\u0441\u0442\u0435 \u044f \u043e\u043f\u0438\u0448\u0443 \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u043c\u0438 HID \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438 \u0432 Visual Basic (\u0434\u0430 \u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u0432 .Net)<\/p>\n<p>  <a name=\"habracut\"><\/a><\/p>\n<p>  \u041f\u043e\u0438\u0441\u043a\u0430\u043b \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0433\u0443\u0433\u043b\u043e\u043c, \u043d\u0430\u0448\u0435\u043b \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0445 \u0441\u0441\u044b\u043b\u043e\u043a.<br \/>  \u0412 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c, \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 <a href=\"https:\/\/github.com\/mikeobrien\/HidLibrary\">\u00abMike O\u2019Brien\u2019s USB HID library\u00bb<\/a>.<br \/>  \u0412\u043e\u0442 \u0441\u0442\u0430\u0442\u044c\u044f, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u044d\u0442\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0447\u0438\u0442\u0430\u044e\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u043f\u043e\u0445\u043e\u0436\u0438\u0445 \u0432\u0435\u0441\u043e\u0432:<br \/>  <a href=\"http:\/\/nicholas.piasecki.name\/blog\/2008\/11\/reading-a-stamps-com-usb-scale-from-c-sharp\/\">nicholas.piasecki.name\/blog\/2008\/11\/reading-a-stamps-com-usb-scale-from-c-sharp\/<\/a><br \/>  \u0427\u0442\u043e \u043c\u043d\u0435 \u043d\u0435 \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u043e\u0441\u044c \u2014 \u044d\u0442\u043e \u0443\u0433\u0430\u0434\u044b\u0432\u0430\u043d\u0438\u0435 \u0444\u043e\u0440\u043c\u0430\u0442\u0430 \u0434\u0430\u043d\u043d\u044b\u0445. \u041a \u0442\u043e\u043c\u0443 \u0436\u0435, \u043f\u043e\u0434\u0435\u043b\u0438\u0432\u0448\u0438\u0441\u044c \u0441\u0441\u044b\u043b\u043a\u043e\u0439 \u0441 \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a\u043e\u043c, \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u043e\u0442\u0432\u0435\u0442, \u0447\u0442\u043e \u0432\u0441\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0435\u043c\u0443 \u043d\u0435 \u043d\u0443\u0436\u043d\u0430 \u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u043e\u043d \u0431\u044b \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0435\u043b \u0447\u0442\u043e\u0431\u044b \u044f \u0440\u0435\u0448\u0438\u043b \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e.<br \/>  \u0425\u043e\u0440\u043e\u0448\u043e, \u0432\u043e\u043e\u0440\u0443\u0436\u0430\u0435\u043c\u0441\u044f MSDN \u0430 \u0442\u0430\u043a\u0436\u0435 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0435\u0439 \u043d\u0430 \u0432\u0435\u0441\u044b:<br \/>  \u00ab64067860 PS scales Operation and Technical Manual.pdf\u00bb \u2014 \u043b\u0435\u0433\u043a\u043e \u0438\u0449\u0435\u0442\u0441\u044f \u0433\u0443\u0433\u043b\u043e\u043c.<\/p>\n<p>  \u0427\u0442\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 HID \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u044b\u0435 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 (\u043f\u043e\u043f\u0440\u043e\u0431\u0443\u044e \u043f\u043e\u0437\u0436\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u043e \u0447\u0442\u0435\u043d\u0438\u0435 ACS NFC SmartCard Reader), \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e:<br \/>  1) \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c DevicePath \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u043d\u0430\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430, \u0432\u043e\u0442 \u0442\u0430\u043a\u043e\u0433\u043e \u0432\u0438\u0434\u0430:<br \/>  (\\?\\usb#vid_04a9&#038;pid_1097#207946#{28d78fad-5a12-11d1-ae5b-0000f803a8c2})<br \/>  2) \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u044d\u0442\u043e\u0442 DevicePath \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0430\u043c\u043e\u0439 \u043e\u0431\u044b\u0447\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 CreateFile \u0441 \u0434\u043e\u0441\u0442\u0443\u043f\u043e\u043c GENERIC_READ  <\/p>\n<pre><code class=\"vbscript\">NativeMethods.CreateFile(DeviceInterfaceDetailData.DevicePath, NativeMethods.GENERIC_READ, NativeMethods.FILE_SHARE_READ + NativeMethods.FILE_SHARE_WRITE, security, NativeMethods.OPEN_EXISTING, 0, 0) <\/code><\/pre>\n<p>  3) \u0427\u0438\u0442\u0430\u0435\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e ReadFile  <\/p>\n<pre><code class=\"vbscript\">res = NativeMethods.ReadFile(ioHandle, bufPtr, 10, bytesRead, IntPtr.Zero) <\/code><\/pre>\n<p>  \u041a\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c DevicePath. \u0417\u0430\u0434\u0430\u0447\u0430 \u043d\u0435\u0441\u043b\u043e\u0436\u043d\u0430\u044f. \u041d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432, \u043d\u0430\u0439\u0442\u0438 \u0432\u0435\u0441\u044b, \u0438 \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 HIDD_ATTRIBUTES \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 HidD_GetAttributes(hidHandle, deviceAttributes)<br \/>  \u041f\u043e \u0448\u0430\u0433\u0430\u043c:<br \/>  1) \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c Guid \u043a\u043b\u0430\u0441\u0441\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432  <\/p>\n<pre><code class=\"vbscript\">NativeMethods.HidD_GetHidGuid(hidClass) <\/code><\/pre>\n<p>  2) \u0421\u043e\u0437\u0434\u0430\u0435\u043c Enumerator \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432  <\/p>\n<pre><code class=\"vbscript\">DeviceInfoSet = NativeMethods.SetupDiGetClassDevs(hidClass, IntPtr.Zero, 0, NativeMethods.DIGCF_PRESENT + NativeMethods.DIGCF_DEVICEINTERFACE) <\/code><\/pre>\n<p>  3) \u0418\u0434\u0435\u043c \u043f\u043e \u0441\u043f\u0438\u0441\u043a\u0443 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432  <\/p>\n<pre><code class=\"vbscript\">Do While NativeMethods.SetupDiEnumDeviceInfo(DeviceInfoSet, deviceIndex, DeviceInfoData) <\/code><\/pre>\n<p>  4) \u0412\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u043c \u0446\u0438\u043a\u043b\u043e\u043c \u0438\u0434\u0435\u043c \u043f\u043e \u0441\u043f\u0438\u0441\u043a\u0443 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430  <\/p>\n<pre><code class=\"vbscript\">Do While NativeMethods.SetupDiEnumDeviceInterfaces(DeviceInfoSet, DeviceInfoData, hidClass, deviceIfaceIndex, DeviceInterfaceData) <\/code><\/pre>\n<p>  5) \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c DevicePath  <\/p>\n<pre><code class=\"vbscript\">                success = NativeMethods.SetupDiGetDeviceInterfaceDetailBuffer(DeviceInfoSet, DeviceInterfaceData, IntPtr.Zero, 0, RequiredSize, IntPtr.Zero) ' Obtain buffer size                 success = NativeMethods.SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, DeviceInterfaceData, DeviceInterfaceDetailData, RequiredSize, RequiredSize, DeviceInfoData) ' Get device information using previously recieved buffer size <\/code><\/pre>\n<p>  \u0417\u0434\u0435\u0441\u044c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0443\u0445\u0438\u0449\u0440\u0435\u043d\u0438\u0435 \u0441 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435\u0439 null \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0431\u0443\u0444\u0435\u0440\u0430 \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u044b\u0445. \u041f\u043e\u043b\u043e\u0432\u0438\u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0438 \u0441\u0434\u0435\u043b\u0430\u043d\u0430 \u2014 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c DevicePath. <br \/>  6) \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c, \u0442\u043e \u043b\u0438 \u044d\u0442\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e.   <\/p>\n<pre><code class=\"vbscript\">NativeMethods.CreateFile(DeviceInterfaceDetailData.DevicePath, NativeMethods.ACCESS_NONE, NativeMethods.FILE_SHARE_READ + NativeMethods.FILE_SHARE_WRITE, security, NativeMethods.OPEN_EXISTING, 0, 0) <\/code><\/pre>\n<p>  \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0441 ACCESS_NONE (\u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e pid&#038;vid, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u0442 \u043d\u0443\u0436\u0434\u044b \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u043d\u0430 \u0447\u0442\u0435\u043d\u0438\u0435, \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432 \u043d\u0430\u043c \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0442 \u0438 \u0437\u0434\u0435\u0441\u044c \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435)<br \/>  7) \u0418 \u0447\u0438\u0442\u0430\u0435\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b  <\/p>\n<pre><code class=\"vbscript\">                    Dim deviceAttributes As NativeMethods.HIDD_ATTRIBUTES                     deviceAttributes.cbSize = Marshal.SizeOf(deviceAttributes)                      NativeMethods.HidD_GetAttributes(hidHandle, deviceAttributes) <\/code><\/pre>\n<p>  8) \u0422\u0435\u043f\u0435\u0440\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0440\u0430\u0432\u043d\u0438\u043c deviceAttributes.VendorID \u0438 deviceAttributes.ProductID \u0441 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430\u043c\u0438 \u0438 \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u0442\u043e \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u2014 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0445\u043e\u0434\u0438\u0442\u044c \u0438\u0437 \u0446\u0438\u043a\u043b\u043e\u0432<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043a \u0432\u0435\u0441\u0430\u043c. \u041f\u0440\u0438 \u0447\u0442\u0435\u043d\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u043d\u0438 \u0432\u044b\u0434\u0430\u044e\u0442 \u043d\u0430\u043c 6 \u0431\u0430\u0439\u0442, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043d\u0443\u0436\u043d\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f.<br \/>  \u0421\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438, \u043f\u0435\u0440\u0432\u044b\u0439 \u0431\u0430\u0439\u0442 \u043f\u043e\u0441\u044b\u043b\u043a\u0438 \u2014 \u044d\u0442\u043e report id.<br \/>  \u0412\u0442\u043e\u0440\u043e\u0439 \u2014 \u0441\u0442\u0430\u0442\u0443\u0441 \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f. \u0411\u044b\u0432\u0430\u0435\u0442: \u043e\u0448\u0438\u0431\u043a\u0430, \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0439 \u0432\u0435\u0441, \u043c\u0435\u043d\u044c\u0448\u0435 \u043d\u0443\u043b\u044f, \u043a\u043e\u043b\u0435\u0431\u0430\u043d\u0438\u044f, \u0438 \u0442.\u043f. \u041f\u043e\u043b\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u2014 \u0432 \u043a\u043e\u0434\u0435 \u0438 \u0432 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.<br \/>  \u0422\u0440\u0435\u0442\u0438\u0439 \u2014 \u0435\u0434\u0438\u043d\u0438\u0446\u044b \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f. \u042d\u0442\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u043e \u2014 \u043c\u0438\u043b\u0438\u0433\u0440\u0430\u043c\u043c\u044b, \u0433\u0440\u0430\u043c\u043c\u044b, \u043a\u0438\u043b\u043e\u0433\u0440\u0430\u043c\u043c\u044b, \u0438 \u0442.\u0434. \u0425\u043e\u0442\u044c \u0442\u0440\u043e\u0439\u0441\u043a\u0430\u044f \u0443\u043d\u0446\u0438\u044f.<br \/>  \u0422\u0440\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0431\u0430\u0439\u0442\u0430 \u2014 \u044d\u0442\u043e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u0435\u0441.<br \/>  \u041f\u0435\u0440\u0432\u044b\u0439 \u0431\u0430\u0439\u0442 \u0432\u0435\u0441\u0430 \u2014 \u0441\u0442\u0435\u043f\u0435\u043d\u044c \u0434\u0435\u0441\u044f\u0442\u043a\u0438, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0434\u0432\u0430 \u2014 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435.<br \/>  \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u0435\u0441\u0430, \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435\u0445\u0438\u0442\u0440\u0443\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e:<br \/>  (b[5]*256+b[4])*10^b[3]<\/p>\n<p>  \u0412\u043e\u0442 \u0442\u0430\u043a \u2014 \u0432\u0441\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e.<\/p>\n<p>  \u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434:<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">NativeMethods.vb<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"vbscript\">Public Class NativeMethods     Public Const DIGCF_PRESENT = &H2     Public Const DIGCF_DEVICEINTERFACE = &H10      Public Const FILE_FLAG_OVERLAPPED = &H40000000     Public Const FILE_SHARE_READ = 1     Public Const FILE_SHARE_WRITE = 2     Public Const GENERIC_READ = &H80000000     Public Const GENERIC_WRITE = &H40000000     Public Const ACCESS_NONE = 0     Public Const INVALID_HANDLE_VALUE = -1 \tPublic Const OPEN_EXISTING = 3      &lt;StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)&gt; _     Public Structure SP_DEVICE_INTERFACE_DETAIL_DATA         Public cbSize As UInt32         &lt;MarshalAs(UnmanagedType.ByValTStr, SizeConst:=256)&gt; _         Public DevicePath As String     End Structure      Public Structure SP_DEVICE_INTERFACE_DATA         Public cbSize As Integer         Public InterfaceClassGuid As System.Guid         Public Flags As Integer         Public Reserved As UIntPtr     End Structure      Public Structure SP_DEVINFO_DATA         Public cbSize As Integer         Public ClassGuid As System.Guid         Public DevInst As Integer         Public Reserved As UIntPtr     End Structure      Public Const HIDP_INPUT = 0     Public Const HIDP_OUTPUT = 1     Public Const HIDP_FEATURE = 2      Public Structure HIDD_ATTRIBUTES         Public cbSize As Integer         Public VendorID As UShort         Public ProductID As UShort         Public VersionNumber As Short     End Structure      Public Structure SECURITY_ATTRIBUTES         Public nLength As Integer         Public lpSecurityDescriptor As IntPtr         Public bInheritHandle As Boolean     End Structure      Public Declare Auto Function CreateFile Lib &quot;kernel32.dll&quot; (lpFileName As String, dwDesiredAccess As Integer, dwShareMode As Integer, ByRef lpSecurityAttributes As SECURITY_ATTRIBUTES, dwCreationDisposition As Integer, dwFlagsAndAttributes As Integer, hTemplateFile As Integer) As IntPtr     Public Declare Auto Function ReadFile Lib &quot;kernel32.dll&quot; (ByVal hFile As IntPtr, ByVal Buffer As IntPtr, ByVal nNumberOfBytesToRead As Integer, ByRef lpNumberOfBytesRead As Integer, ByVal Overlapped As IntPtr) As Integer     Public Declare Auto Function CloseHandle Lib &quot;kernel32.dll&quot; (hObject As IntPtr) As Boolean      Public Declare Auto Function SetupDiGetClassDevs Lib &quot;setupapi.dll&quot; (ByRef ClassGuid As System.Guid, ByVal Enumerator As Integer, ByVal hwndParent As IntPtr, ByVal Flags As Integer) As IntPtr     Public Declare Auto Function SetupDiDestroyDeviceInfoList Lib &quot;setupapi.dll&quot; (deviceInfoSet As IntPtr) As Boolean      Public Declare Auto Function SetupDiEnumDeviceInfo Lib &quot;setupapi.dll&quot; (ByVal DeviceInfoSet As Integer, ByVal MemberIndex As Integer, ByRef DeviceInfoData As SP_DEVINFO_DATA) As Boolean     Public Declare Auto Function SetupDiEnumDeviceInterfaces Lib &quot;setupapi.dll&quot; (ByVal DeviceInfoSet As IntPtr, ByRef DeviceInfoData As SP_DEVINFO_DATA, ByRef InterfaceClassGuid As System.Guid, ByVal MemberIndex As UInteger, ByRef DeviceInterfaceData As SP_DEVICE_INTERFACE_DATA) As Boolean      Public Declare Auto Function SetupDiGetDeviceInterfaceDetailBuffer Lib &quot;setupapi.dll&quot; Alias &quot;SetupDiGetDeviceInterfaceDetail&quot; (ByVal DeviceInfoSet As IntPtr, ByRef DeviceInterfaceData As SP_DEVICE_INTERFACE_DATA, ByVal DeviceInterfaceDetailData As IntPtr, ByVal DeviceInterfaceDetailDataSize As Integer, ByRef RequiredSize As Integer, ByRef DeviceInfoData As IntPtr) As Boolean     Public Declare Auto Function SetupDiGetDeviceInterfaceDetail Lib &quot;setupapi.dll&quot; (ByVal DeviceInfoSet As IntPtr, ByRef DeviceInterfaceData As SP_DEVICE_INTERFACE_DATA, ByRef DeviceInterfaceDetailData As SP_DEVICE_INTERFACE_DETAIL_DATA, ByVal DeviceInterfaceDetailDataSize As Integer, ByRef RequiredSize As Integer, ByRef DeviceInfoData As SP_DEVINFO_DATA) As Boolean       Public Declare Auto Sub HidD_GetHidGuid Lib &quot;hid.dll&quot; Alias &quot;HidD_GetHidGuid&quot; (ByRef hidGuid As Guid)     Public Declare Auto Function HidD_GetAttributes Lib &quot;hid.dll&quot; (hidDeviceObject As IntPtr, ByRef attributes As HIDD_ATTRIBUTES) As Boolean  End Class <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<div class=\"spoiler\"><b class=\"spoiler_title\">ScaleReader.vb<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"vbscript\">Public Class ScaleReader     Private Const VendorId = &HEB8      ' 0EB8 = Toledo, see http:\/\/usb-ids.gowdy.us\/read\/UD\/     Private Const ProductId = &HF000    ' F000 = PS60      ' Scale status enumeration     Public Enum ScaleStatus         Fault         StableAtZero         InMotion         WeightStable         UnderZero         OverWeight         RequiresCalibration         RequiresRezeroing         RequiresGEO         Unknown     End Enum      ' Scale weighing unit     Public Enum WeightUnit         UnitMilligram         UnitGram         UnitKilogram         UnitCarats         UnitTaels         UnitGrains         UnitPennyweights         UnitMetricTon         UnitAvoirTon         UnitTroyOunce         UnitOunce         UnitPound         UnitUnknown     End Enum      ' Scale measure report     Public Structure ScaleReport         Public ReportId As UShort       ' Scale report id         Public Status As ScaleStatus    ' Scale status         Public Unit As WeightUnit       ' Weighing unit         Public Scaling As SByte          ' Scaling, power of 10         Public WeightLsb As UShort      ' Least-significant byte of weight value         Public WeightMsb As UShort      ' Most-significant byte of weight value         Public ErrorCode As Integer     ' Error code          ' Calculates weight from LSB, MSB and scaling         Public Function GetWeight() As Double             GetWeight = (WeightMsb * 256 + WeightLsb) * (10 ^ Scaling)         End Function      End Structure      Private ioHandle As IntPtr  ' handle to read from device      ' Opens device with desired access rights     Private Function OpenDeviceIO(devicePath As String, deviceAccess As Integer) As IntPtr         Dim security As NativeMethods.SECURITY_ATTRIBUTES          security.lpSecurityDescriptor = IntPtr.Zero         security.bInheritHandle = True         security.nLength = Marshal.SizeOf(security)          OpenDeviceIO = NativeMethods.CreateFile(devicePath, deviceAccess, NativeMethods.FILE_SHARE_READ + NativeMethods.FILE_SHARE_WRITE, security, NativeMethods.OPEN_EXISTING, 0, 0)     End Function      ' Close previously opened device     Private Sub CloseDeviceIO(handle As IntPtr)         NativeMethods.CloseHandle(handle)     End Sub      ' Disconnect from scale     Public Sub Disconnect()         CloseDeviceIO(ioHandle)     End Sub      ' Find Toledo PS60 scale and open to read weight values     Public Function Connect() As Boolean         Dim hidClass As Guid         NativeMethods.HidD_GetHidGuid(hidClass) ' Obtain hid device class Guid to enumerate all hid devices          Dim DeviceInfoSet As IntPtr         Dim DeviceInfoData As NativeMethods.SP_DEVINFO_DATA         Dim DeviceInterfaceData As NativeMethods.SP_DEVICE_INTERFACE_DATA         Dim DeviceInterfaceDetailData As NativeMethods.SP_DEVICE_INTERFACE_DETAIL_DATA = Nothing         Dim RequiredSize As Integer         Dim success As Boolean          DeviceInfoSet = NativeMethods.SetupDiGetClassDevs(hidClass, IntPtr.Zero, 0, NativeMethods.DIGCF_PRESENT + NativeMethods.DIGCF_DEVICEINTERFACE) ' Open hid device enumeration          DeviceInterfaceData.cbSize = Marshal.SizeOf(DeviceInterfaceData)         DeviceInterfaceDetailData.cbSize = 6         DeviceInfoData.cbSize = Marshal.SizeOf(DeviceInfoData)          Dim deviceIndex As Integer ' Current deviec index         deviceIndex = 0          Do While NativeMethods.SetupDiEnumDeviceInfo(DeviceInfoSet, deviceIndex, DeviceInfoData) ' Loop through all hid devices             Dim deviceIfaceIndex As Integer ' Device interface index             deviceIfaceIndex = 0             Do While NativeMethods.SetupDiEnumDeviceInterfaces(DeviceInfoSet, DeviceInfoData, hidClass, deviceIfaceIndex, DeviceInterfaceData) ' Loop through all interfaces of current device                 success = NativeMethods.SetupDiGetDeviceInterfaceDetailBuffer(DeviceInfoSet, DeviceInterfaceData, IntPtr.Zero, 0, RequiredSize, IntPtr.Zero) ' Obtain buffer size                 success = NativeMethods.SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, DeviceInterfaceData, DeviceInterfaceDetailData, RequiredSize, RequiredSize, DeviceInfoData) ' Get device information using previously recieved buffer size                  Dim hidHandle As IntPtr                 hidHandle = OpenDeviceIO(DeviceInterfaceDetailData.DevicePath, NativeMethods.ACCESS_NONE) ' Open device with no access rights to get pid&vid                  If hidHandle &lt;&gt; NativeMethods.INVALID_HANDLE_VALUE Then                      Dim deviceAttributes As NativeMethods.HIDD_ATTRIBUTES                     deviceAttributes.cbSize = Marshal.SizeOf(deviceAttributes)                      success = NativeMethods.HidD_GetAttributes(hidHandle, deviceAttributes) ' Read device attributes, including PID, VID and Version                      If success And deviceAttributes.VendorID = VendorId And deviceAttributes.ProductID = ProductId Then ' If it matches Toledo PS60                         CloseDeviceIO(hidHandle)    ' Close device                         ioHandle = OpenDeviceIO(DeviceInterfaceDetailData.DevicePath, NativeMethods.GENERIC_READ) ' And reopen with access rights to read reports                         NativeMethods.SetupDiDestroyDeviceInfoList(DeviceInfoSet) ' Close enumeration                         Connect = True                         Exit Function                     End If                      CloseDeviceIO(hidHandle)                 End If                 deviceIfaceIndex = deviceIfaceIndex + 1             Loop              deviceIndex = deviceIndex + 1         Loop         NativeMethods.SetupDiDestroyDeviceInfoList(DeviceInfoSet) ' Close enumeration          Connect = False     End Function      ' Reads current weight from scale     Public Function ReadValue() As ScaleReport         Dim bytesRead As Integer         Dim buffer(10) As Byte         Dim bufPtr As IntPtr          bufPtr = Marshal.AllocHGlobal(10) ' Allocate 10 bytes for report          ReadValue = Nothing          Dim res As Integer         res = NativeMethods.ReadFile(ioHandle, bufPtr, 10, bytesRead, IntPtr.Zero) ' Read 10 bytes from scale          If res &gt; 0 Then ' 0=Failure, any positive is success             Marshal.Copy(bufPtr, buffer, 0, 10) ' Copy unmamanged buffer to managed byte array             If bytesRead &lt; 6 Then ' Report must be 6 bytes or greater (for compatibility)                 ReadValue.Status = ScaleStatus.Fault                 Marshal.FreeHGlobal(bufPtr)                 Exit Function             End If              Dim rep As ScaleReport              rep.ReportId = buffer(0) ' byte #0 is report id             Select Case buffer(1)    ' byte #1 is scale status                 Case &H1                     rep.Status = ScaleStatus.Fault                 Case &H2                     rep.Status = ScaleStatus.StableAtZero                 Case &H3                     rep.Status = ScaleStatus.InMotion                 Case &H4                     rep.Status = ScaleStatus.WeightStable                 Case &H5                     rep.Status = ScaleStatus.UnderZero                 Case &H6                     rep.Status = ScaleStatus.OverWeight                 Case &H7                     rep.Status = ScaleStatus.RequiresCalibration                 Case &H8                     rep.Status = ScaleStatus.RequiresRezeroing                 Case &H9                     rep.Status = ScaleStatus.RequiresGEO                 Case Else                     rep.Status = ScaleStatus.Unknown             End Select              Select Case buffer(2)       ' byte #2 is scale unit                 Case &H1                     rep.Unit = WeightUnit.UnitMilligram                 Case &H2                     rep.Unit = WeightUnit.UnitGram                 Case &H3                     rep.Unit = WeightUnit.UnitKilogram                 Case &H4                     rep.Unit = WeightUnit.UnitCarats                 Case &H5                     rep.Unit = WeightUnit.UnitTaels                 Case &H6                     rep.Unit = WeightUnit.UnitGrains                 Case &H7                     rep.Unit = WeightUnit.UnitPennyweights                 Case &H8                     rep.Unit = WeightUnit.UnitMetricTon                 Case &H9                     rep.Unit = WeightUnit.UnitAvoirTon                 Case &HA                     rep.Unit = WeightUnit.UnitTroyOunce                 Case &HB                     rep.Unit = WeightUnit.UnitOunce                 Case &HC                     rep.Unit = WeightUnit.UnitPound                 Case Else                     rep.Unit = WeightUnit.UnitUnknown             End Select              rep.Scaling = IIf(buffer(3) &lt; 128, buffer(3), buffer(3) - 256)     ' byte #3 is scaling             rep.WeightLsb = buffer(4)   ' byte #4 is LSB             rep.WeightMsb = buffer(5)   ' byte #5 is MSB              ReadValue = rep         Else             Dim err = Marshal.GetLastWin32Error             ReadValue.Status = ScaleStatus.Fault             ReadValue.ErrorCode = err         End If         Marshal.FreeHGlobal(bufPtr)     End Function   End Class <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<div class=\"clear\"><\/div>\n<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/205462\/\"> http:\/\/habrahabr.ru\/post\/205462\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"content html_format\">   \t\u041d\u0435 \u0442\u0430\u043a \u0434\u0430\u0432\u043d\u043e \u0432\u044b\u0438\u0433\u0440\u0430\u043b \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430 Elance \u2014 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0435 WinForms \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 Visual Basic, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u0432\u0435\u0441\u043e\u0432 Mettler Toledo PS60. <br \/>  \u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u0435\u0441\u044b \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f HID-\u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u043c, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c\u043e\u043c \u043f\u043e USB.<br \/>  \u0412 \u044d\u0442\u043e\u043c \u043f\u043e\u0441\u0442\u0435 \u044f \u043e\u043f\u0438\u0448\u0443 \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u043c\u0438 HID \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438 \u0432 Visual Basic (\u0434\u0430 \u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u0432 .Net)<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-205462","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/205462","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=205462"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/205462\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=205462"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=205462"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=205462"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}