Matlab & Arduino Serial Communication_control between stepper motor and camera

Hardware:

  1. Arduino UNO;
  2. Arduino Motor Shield Rev3;
  3. 4 wires stepper motor (0.9° step angle);
  4. uEye USB CCD camera;
  5. 12V power supply.

Goal:
The camera take several pictures once the motor move one step. The rotation range from -117 to 117 degree.
①The camera start capture; ②once the camera finish, send information to motor; ③and motor move to the next step; ④and then camera start capture again.

Question:
I try do simple serial communication from Matlab to Aruino, it works, but just don't know how to send data from Arduino to Matlab, can anyone help me, plz?

Code in Arduino:

#include<Stepper.h>

const int stepsPerRevolution = 400;
const int dirA = 12;
const int dirB = 13;
const int pwmA = 3;
const int pwmB = 11;
const int brakeA = 9;
const int brakeB = 8;
int matlabData;
Stepper myStepper(stepsPerRevolution, dirA, dirB);
int x = 0;
int stepCount = 0;
void setup(){
  pinMode(pwmA, OUTPUT);
  pinMode(pwmB, OUTPUT);
  pinMode(brakeA, OUTPUT);
  pinMode(brakeB, OUTPUT);
  digitalWrite(pwmA,HIGH);
  digitalWrite(pwmB,HIGH);
  digitalWrite(brakeA,LOW);
  digitalWrite(brakeB,LOW);
  Serial.begin(9600);
  myStepper.setSpeed(60);
}

void loop() 
{
   
   if(Serial.available()>0) 
   {
    matlabData=Serial.read();
    delay(10); 
     if (matlabData==3)
         delay(10);
         myStepper.step(200);
         delay(300);
      if(matlabData==4)
      delay(10);
      myStepper.step(-200);
      delay(300);
  }
}

Code in Matlab:

ar = serial('COM4','BaudRate',9600);
fopen(ar);
fprintf(ar,'%s',char(3));
pause(20);
t = 5;
interval = 1;
ROIxcentre = 540;
ROIycentre = 380;
ROIsize = 300;

n = t/interval;
xstart = ROIxcentre - (ROIsize/2) + 1;
ystart = ROIycentre - (ROIsize/2) + 1;
xend = ROIxcentre + (ROIsize/2);
yend = ROIycentre + (ROIsize/2);

allImgs = zeros(ROIsize,ROIsize,n);

for i = 1:n
    img = Camera(1);
    imageDataROI = img(xstart:xend,ystart:yend);
    figure(1)
    imshow(imageDataROI,[0 255])
    allImgs(:,:,i) = imageDataROI;
    pause(interval)
end

allImgs = mat2gray(reshape(allImgs,ROIsize*ROIsize,t/interval));


fprintf(ar,'%s',char(4));
pause(5);
t = 3;
interval = 1;
ROIxcentre = 540;
ROIycentre = 380;
ROIsize = 300;

n = t/interval;
xstart = ROIxcentre - (ROIsize/2) + 1;
ystart = ROIycentre - (ROIsize/2) + 1;
xend = ROIxcentre + (ROIsize/2);
yend = ROIycentre + (ROIsize/2);

allImgs = zeros(ROIsize,ROIsize,n);

for i = 1:n
    img = Camera(1);
    imageDataROI = img(xstart:xend,ystart:yend);
    figure(1)
    imshow(imageDataROI,[0 255])
    allImgs(:,:,i) = imageDataROI;
    pause(interval)
end

allImgs = mat2gray(reshape(allImgs,ROIsize*ROIsize,t/interval));

fprintf(ar,'%s',char(3));
pause(5);

fclose(ar);

Code to initialize camera:

function out = Camera(noPics)
% Obtains single frame from camera

%   Add NET assembly if it does not exist
%   May need to change specific location of library

asm = System.AppDomain.CurrentDomain.GetAssemblies;
if ~any(arrayfun(@(n) strncmpi(char(asm.Get(n-1).FullName), ...
        'uc480DotNet', length('uc480DotNet')), 1:asm.Length))
    NET.addAssembly(...
        'C:\Thorcam\DCx_Camera_SDK\Develop\DotNet\signed\uc480DotNet.dll');
end

%   Create camera object handle
cam = uc480.Camera;

%   Open 1st available camera
%   Returns if unsuccessful
if ~strcmp(char(cam.Init), 'SUCCESS')
    error('Could not initialize camera');
end

%   Set display mode to bitmap (DiB)
if ~strcmp(char(cam.Display.Mode.Set(uc480.Defines.DisplayMode.DiB)), ...
        'SUCCESS')
    error('Could not set display mode');
end

%   Set colormode to 8-bit RAW
if ~strcmp(char(cam.PixelFormat.Set(uc480.Defines.ColorMode.SensorRaw8)), ...
        'SUCCESS')
    error('Could not set pixel format');
end

%   Set trigger mode to software (single image acquisition)
if ~strcmp(char(cam.Trigger.Set(uc480.Defines.TriggerMode.Software)), 'SUCCESS')
    error('Could not set trigger format');
end

%   Allocate image memory
[ErrChk, img.ID] = cam.Memory.Allocate(true);
if ~strcmp(char(ErrChk), 'SUCCESS')
    error('Could not allocate memory');
end

%   Obtain image information
[ErrChk, img.Width, img.Height, img.Bits, img.Pitch] ...
    = cam.Memory.Inquire(img.ID);
if ~strcmp(char(ErrChk), 'SUCCESS')
    error('Could not get image information');
end

%   Acquire image
if ~strcmp(char(cam.Acquisition.Freeze(true)), 'SUCCESS')
    error('Could not acquire image');
end

%   Extract image
[ErrChk, tmp] = cam.Memory.CopyToArray(img.ID); 
if ~strcmp(char(ErrChk), 'SUCCESS')
    error('Could not obtain image data');
end

%   Reshape image
img.Data = reshape(uint8(tmp), [img.Width, img.Height, img.Bits/8]);
imageData = double(img.Data).*checkerboard10(img.Width, img.Height);
fixed = conv2(imageData, [0 1 0;1 0 1;0 1 0]/4,'same');
RBmask = find(imageData == 0);
imageData(RBmask) = fixed(RBmask);
% imageData = img.Data;     
% discard edges
imageData = imageData(2:img.Width-1,2:img.Height-1);
out = imageData;
      
%   Close camera
if ~strcmp(char(cam.Exit), 'SUCCESS')
    error('Could not close camera');
end

cam.Exit;

Many thanks!

What is the observed behaviour?

Please do a tools -> auto format in the IDE; it might make clear what goes wrong. You might be familiar with Python but C++ is not Python; indentations mean nothing. As an example (your code with auto-format applied

    if (matlabData == 3)
      delay(10);
    myStepper.step(200);
    delay(300);

Only the delay is depending on the condition in the if. myStepper will always step 200 and the delay of 300ms,

Note:
no experience with matlab so can't advise on that.

I've deleted your other cross post @XuechunWang.

Cross posting is against the rules of the forum. The reason is that duplicate posts can waste the time of the people trying to help. Someone might spend 15 minutes writing a detailed answer on this thread, without knowing that someone else already did the same in the other thread.

Repeated cross posting will result in a suspension from the forum.

In the future, please take some time to pick the forum section that best suits the topic of your question and then only post once to that forum section. This is basic forum etiquette, as explained in the sticky "How to use this forum - please read." post you will find at the top of every forum section. It contains a lot of other useful information. Please read it.

Thanks in advance for your cooperation.