venerdì 30 settembre 2016

OPTOTUNE lens MATLAB communication script

In our photonics laboratory facilities at UCC we have the Optotune controllable lens along with its lens driver controller 4 from Optotune.
I have been using this lens for several experiment and the GUI developed by Optotune works just fine.
However, sometimes I needed to have better control and play with the lens. For a couple of experiments we used this lens as a key component working in an automated environment on where a software was dynamically changing the lens parameter (focal length, therefore electronic lens current) according to different scenarios. This first software was written in C++ code.

Next I have decided to move to the development in MATLAB. To do that I have written a code that is able to simply control the electronic lens (current setting).
Following the instructions of the Optotune datasheet I have used the crc16ibm.

I would like to share this, since so many times I have been on the other side and is nice to give back.

Hopefully someone might find it useful.
Note that the code is not fully optimized and is very simple though but it does the job and was the result of a couple of hours.

It has 3 functions and 1 main.


function  reverse_16:

function [data] = reverse_16(message_byte)
dr = bin2dec(fliplr(dec2bin(message_byte, 16)))
data = dr;
end


function  reverse_8:

function [data] = reverse_8(message_byte)
dr = bin2dec(fliplr(dec2bin(message_byte, 8)))
data = dr;
end

function crc16ibm:

function [data] = crc16ibm(message, n)
% crc16ibm returns a 16 bit number value.
remainder = 0; remainder_bin = '0000000000000000'; %initializations
polynomial = 32773; % is the polynomail used in the CRCIBM16 - in hexadecimal is 0x8005.
%message = [hex2dec('41'), hex2dec('77'), 5, 117, 0, 0]; %
for i=1 : n
    if i == 3;
    end
    a = reverse_8(message(i));
    a_bin = dec2bin(a);
    a_bin_str = num2str(a_bin);
    size_a = length(a_bin_str);
    remainder = a_bin_str;
    while size_a <16 font="">
        remainder = strcat(remainder,'0');
        size_a = length(remainder);
    end;
    remainder_array= []; remainder_bin_array = []; %need to define these for the EXOR operation
    for k = 1 : 16
        remainder_array(k) = str2num(remainder(k));
        remainder_bin_array(k) = str2num(remainder_bin(k));
    end;
    remainder_bin_array = xor(remainder_array , remainder_bin_array);
    remainder_bin='';
    for i = 1 :length(remainder_bin_array)
        remainder_bin = strcat(remainder_bin,num2str(remainder_bin_array(i)));
    end;
    
    for j = 1 : 8
        if remainder_bin(1) == '1'
            remainder_bin = strcat(remainder_bin,'0'); %is a shift to the left therefore adding '0'
            remainder_bin = remainder_bin(2:end); %need to remove the first value to keep it as a 16-bit number
            %need to perform the exor operation
            polynomial_bin = dec2bin(polynomial);
            pol_array= []; remainder_array = [];
            for k=1:length(polynomial_bin)
                pol_array(k) = str2num(polynomial_bin(k));
                remainder_array(k) = str2num(remainder_bin(k));
            end;
            C = xor(remainder_array, pol_array); % the result of the EXOR operation
            remainder_bin = ''; %need to transfrom back to char string...
            for i = 1 :length(C)
                remainder_bin = strcat(remainder_bin,num2str(C(i)));
            end;
        else
            remainder_bin = strcat(remainder_bin,'0'); %is a shift to the left therefore adding '0'
            remainder_bin = remainder_bin(2:end); %need to remove the first value to keep it as a 16-bit number
        end
        pippo(j) = bin2dec(remainder_bin); %temp variable, debug purposes
    end
end
remainder_bin;

% need to make a reverse 16..
remainder = bin2dec(remainder_bin);
data= reverse_16(remainder);

end


Main:

% ECVFL control using matlab the Optotune Lensdriver 

clear all; close all; clc; %clear all

s = serial('COM6'); %depends could change 
set(s,'BaudRate',115200); %specfication according to Optotune datasheet
fopen(s); %open COM port
fprintf(s,'Start'); %initial command just to check the ECVFL
out = fscanf(s) %prompt print of 'Ready' string in command window

%% processing
current_value = 0; %something between 0 and 200
current_value =(current_value  * 4096) / 293; %from the ECVFL datasheet
low = 0; high = 0; %variable definition
current_value_bin = dec2bin(current_value); %convertion to binary
size_number = length(current_value_bin);
while size_number <16 font="">
    current_value_bin = strcat('0',current_value_bin);
    size_number = length(current_value_bin);
end;

high_bin = current_value_bin(1:8);
low_bin = current_value_bin(9:end);
high = bin2dec(high_bin);
low = bin2dec(low_bin);

data_command = [hex2dec('41'), hex2dec('77'), high, low, 0, 0];

crc_value = crc16ibm(data_command, 4); %4=data length
% crc16ibm returns a 16 bits number. As before need to split it in 2 8 bit
% number
crc_value_bin = dec2bin(crc_value); %convertion to binary
size_number = length(crc_value_bin);
while size_number <16 font="">
    crc_value_bin = strcat('0',crc_value_bin);
    size_number = length(crc_value_bin);
end;
crc_value_high_bin = crc_value_bin(1:8); %upper part
crc_value_low_bin = crc_value_bin(9:end); %lower part

crc_value_high = bin2dec(crc_value_high_bin);
crc_value_low = bin2dec(crc_value_low_bin);

data_command = [hex2dec('41'), hex2dec('77') high low crc_value_low crc_value_high];

%% Send data throught the serial COM port communication

fwrite(s, data_command, 'uint8');

%test
%fprintf(s,'Start');
%out = fscanf(s)
%%
fclose(s); delete(s); clear s;
delete(instrfindall); % to make sure we really close the COM port



Pablo

2 commenti:

  1. Dear Pablo,

    Thank you very much for sharing your code.

    I am trying to run it for controlling an optotune lens, but the statement " while size_number <16 font="">" produces a message error in Matlab. I am not sure what is the correct statement. Could you help me correct it, please?

    RispondiElimina
  2. Hi Elie!!
    Did you receive the answer or came out with any other solution? Actually I'm also struggling for the same.

    RispondiElimina