miked63017 / dinolite_uvc_led_control

Python module to control LEDs, AE, and other UVC controls for the Dino Lite USB microscopes
26 stars 11 forks source link

Modifying the focus point #4

Closed buongiorgio closed 5 years ago

buongiorgio commented 6 years ago

Hi there, I have a very similar Dino Lite microscope (a0168:990) and I successfully got it working adding a specific module in /device (just copied the a0168:980 one, changing the names here and there). I succeeding switching leds on and off, dimming the light and controlling the individual leds. There is still one feature that is available under Windows, but is missing under Linux: the focus distance. I have noticed that under Windows the focus distance is lower than in Linux, so I can put the microscope closer to the sample (this is relevant to me, because in my project I have to enclose the microscope in a case and the user is not able to handle it, so if the focus point is closer, the case can be smaller). I got in contact with the support to try to fix it and they came back to me with a bunch of C lines:

            byte[] buffer = new byte[255];
            connection.controlTransfer(UsbConstants.USB_DIR_OUT | UsbConstants.USB_TYPE_CLASS | UsbConstants.USB_INTERFACE_SUBCLASS_BOOT, 0x1, 0x200, 0x400, new byte[]{(byte)0xe0, 0x00, 0x00 , 0x50, 0x0, 0x62, 0x0}, 7, 1000);//970
            connection.controlTransfer(UsbConstants.USB_DIR_IN | UsbConstants.USB_TYPE_CLASS | UsbConstants.USB_INTERFACE_SUBCLASS_BOOT, 0x81, 0x200, 0x400, buffer, 5, 1000);//970
            connection.controlTransfer(UsbConstants.USB_DIR_OUT | UsbConstants.USB_TYPE_CLASS | UsbConstants.USB_INTERFACE_SUBCLASS_BOOT, 0x1, 0x200, 0x400, new byte[]{0x05, (byte)buffer[1], 0x00 , 0x00 , 0x00 , 0x46, 0x0}, 7, 1000);//970

change buffer[0] , then change force.

I am not expert in programming devices, so I gave up and decided I could deal with a more distant focus point. I guess that those hex numbers are a sort of "code" that could be sent to the microscope with uvcdynctrl, but - again - I am no expert in this field. It would be really nice if someone could "decode" the C lines above: if you need some testing from my side I am available.

miked63017 commented 5 years ago

Sorry for the late reply, I have not been getting notifications on this repo for some reason.

If you want to add a PR for what you have so far I would be happy to merge it, I am not really working on this project anymore and I don't have any other devices then the 2 listed so this is pretty much as far as this module is going to go in terms of support.

With that said, it looks like(by that comment) they are sending you the hex code for a 970 device and they are suspecting it will work for a 990. Since this module just wraps uvcdynctrl I am not sure you can send the hex unless the control name(focus distance) shows up in uvcdynctrl. If it does show up in uvcdynctrl you can try stripping the 0x pieces off their byte array and sending that hex string to the device under whatever control name the focus distance is registered as. For example

uvcdynctrl -d /dev/video0 -s Focus Distance -- e00050006200

This is just a shot in the dark though honestly, I don't consider myself an expert in programming devices either and it took a lot of reverse engineering to get to the point that this module is currently. But it could be worth a shot if you are still tinkering. Everything I've got here involved minimal C, and I don't program in C a lot, I know just enough to be dangerous lol. Basically I used debugfs, wireshark, and virtual box to MITM the packets their Windows program was sending, and emulated them the best I could by wrapping uvcdynctrl with python.