Controlling LED with external software

149 views
Skip to first unread message

Roman Doronin

unread,
Jun 16, 2021, 5:15:15 AM6/16/21
to Miniscope
Hello everyone!
I would like to control Miniscope V4 parameters (LED power, EWL focus, etc.) with the external software (I am using Labview 2020).
As far as I understand from videostreamocv.cpp, 6 bytes of the command that are sent sending are split to 2 bytes to Contrast, Gamma, and Sharpness attributes of the camera and the order of the command is : data2 data1 | data0 reg0 | packet.length address and packet.length is 2+number of data chunks. So data2 and data1 go to Sharpness (if there is no data2 and data1, it is just 0), data0 reg0 to Gamma and packet.length address - to Contrast. 
I managed to control EWL focus - for this I am writing the following hex values (that get transformed to int): "04EE" to Contrast, "Focus_value 08" to Gamma and "0002" to Sharpness, according to the commands specified in videoDevices.json (I am curious though what's the purpose of writing 0x02 data after focus value).

But I can't manage to control LED: there are 2 possible commands, and each is sent to a different address. I tried to send both these commands and it doesn't work. Do you have ideas about what I could do wrong? As I can control EWL focus, it means that the problem is not in Labview/DAQ not receiving commands. As side questions, I wonder what these 2 possible commands represent and why in the second command we need to send 114 as data0?

LED hex strings that I am sending (to set LED to half the power - I assume that value 127 (0x7F) means half of the power):
command1: "00 00 7F 01 03 20" (reg0=0x01, length=3, addressW=0b00100000=0x20)
command2: "00 7F 72 00 04 58" (reg0=0x00, length=4, addressW=0b01011000=0x58, data0=114=0x72).

Maybe it is not relevant, but to make EWL focus work, I had to divide int values of Contrast and Gamma by 100 as I noticed (in NI MAX explorer) that max values for Contrast and Gamma attributes are 655.36 - exactly 2 bytes divided by 100, which is peculiar. For Sharpness I didn't have to do any division.

Thanks!

Daniel Aharoni

unread,
Jun 16, 2021, 3:49:01 PM6/16/21
to Miniscope
Hi,
Looks like you have a very good grasp on how communication is done over the UVC control channel. It definitely is very hacky and we will be switching over to a much more reasonable approach once we finish moving fully away from the UVC protocol. That being said, the approach currently implemented is designed to give us the ability to send a packet of data that will be converted to an arbitrary I2C communication by the Miniscope DAQ.

For controlling the excitation LED, you generally need to send an I2C command to two I2C slaves on the Miniscope itself. One is the MCU which controls the enable/disable pin of the LED driver. The other is a digital potentiometer that controls the brightness of the LED.

Your command1 is talking to the MCU and telling it what LED brightness is going to be set. The LED brightness ranges from 0 to 255 where 255 is off and 0 is brightest. If the MCU sees you wanting to set this value to 255, it will disable the LED driver. For all other values it will enable the LED driver. Below is the Miniscope MCU code that handles this:
case (SET_LED1_STATE):
            OCR0A = received_data;
            ledValue1 = received_data;
                            
            if (received_data == 0xFF)
                LED_ENT1_PORT &= ~(1<<LED_ENT1_PIN); //Set ENT pin to off
            else
                LED_ENT1_PORT |= (1<<LED_ENT1_PIN); //Make sure ENT pin is on
            pastI2CWord = NO_WORD; //Idle state
            break;
Your command2 goes to the digital potentiometer which  needs to update two of its registers. The hardcoded 114 is used to set the potentiometer value of one of the 2 potentiometers and this acts like a voltage divider to generate ~1.2V which then feeds into the second potentiometer which your data1 controls.

The commands you are sending look correct to me but it has been a while since I wrote and looked at this portion of the code. Do you have an oscilloscope that can decode I2C? If so you can attach to the I2C lines on the DAQ and see what these commands look like when using the Miniscope software. If not, let me know and we will hook up a system quickly and post a screen grab of the I2C protocol.

Roman Doronin

unread,
Jun 17, 2021, 10:04:55 AM6/17/21
to Miniscope
Thank you very much for your help! 
The issue is resolved now, turned out the problem was in Labview and it was sending the wrong commands.
First thing I was doing wrong is that I only tried to run either of these commands, but not the sequence of them, thanks for clarifying that I need to run both. But even when I was sending 2 commands in a sequence, it wasn't working. Turned out the issue is in some obscure rounding thing of Labview: when I was trying to send 0x7200 to Gamma, I was converting them to decimal and dividing by 100: so the number being sent was 291.84. Somewhere along the way Labview was interpreting this number incorrectly and instead of 0x7200 it was sending 0x71FF (checked with USB sniffer Wireshark) so the command was sent to the nonexistent register. Especially weird is that this shift by 1 digit was observed only for some numbers (e.g. for 7100 it was sending incorrect command, but for 7500 - correct). After I artificially added small number (so the sent number is 291.841) led obeyed.
Reply all
Reply to author
Forward
0 new messages