Quicker way to serial print to Matlab


hello all,

i controlling stepper motor arduino, , have camera simultaneously taking images of object motor moving. send current position of stepper motor (currently being counted in variable "distance") every time take snapshot in matlab. unfortunately when run program serial.println line in stepper code, motor slows down tremendously spends time sending serial info matlab.

is there better way send serial information arduino without noticeably affecting motor function? or keep information in buffer can sent when use fread code matlab?

code: [select]
arduino code:
#include <accelstepper.h>
#include <multistepper.h>


int steps=17000;
int dir = 0;
void setup() {               
  pinmode(8, output);     
  pinmode(9, output);
  digitalwrite(8, low); //high=forward, low=backward
  digitalwrite(9, low);
  serial.begin(9600);           // set serial library @ 9600 bps
}

void loop() {
  //menu(); //call menu
  while (!serial.available()){ //wait until serial value available matlab
 
  }
  parsemenu(serial.read()); //decide do
}
//void menu(){
//  //decide do
//  //use serial command in arduino window first test
//  serial.println("what should do?");
//  serial.println("enter b move back, enter f move forward");
//}

void parsemenu(char c){
  switch (c) {
  case 101:
  move_forward();
  break;
  case 100:
  move_back();
  break;
  default:
  break;
  }
}

void move_forward() {
  digitalwrite(8, high); //conveyor moves forward
  (int distance = 0; distance <steps; distance++){ //move number of steps
  digitalwrite(9, high);
  delay(1); //delay between steps (ms)         
  digitalwrite(9, low);
  delay(1); //delay between steps (ms)
  serial.println(distance);
}
}
void move_back() {
  digitalwrite(8, low); //conveyor moves back
  (int distance = steps; distance >=0; distance--){ //move number of steps
  digitalwrite(9, high);
  //digitalwrite(11, high);
  delay(1); //delay between steps (ms)         
  digitalwrite(9, low);
  //digitalwrite(11, low);
  delay(1); //delay between steps (ms)
  serial.println(distance);
  }
}


code: [select]
matlab code:
clear all
close all
clc

%% lets define variables
steps = 1; %number of milliseconds per step (higher slower) 200 steps per revolution
n = 0; %step counter
d = 16.9/1000; %distance per step [cm]
phi = (.978*pi())/1000*(180/pi()); %rotation per step [deg]
startang = 0; % first point check around circle
stepsintest =  17000; %number of steps conveyer travel

%% lets open camera
 
vid = imaq.videodevice('dcam', 1, 'y8_640x480');
%src = getselectedsource(vid);
vid.deviceproperties.shuttercontrol = 'absolute';
vid.deviceproperties.shutterabsolute = 0.04;
release(vid);

%% start serial connection arduino
s=serial('/dev/cu.usbmodemfa131','baud', 9600);
% make sure baud rate , com port same in arduino ide
fopen(s);
%% send 1 frame through algorithm establish baseline angle
current = double(round(255*step(vid)));
imageheight=size(current,1);
imagewidth=size(current,2);
% take first image define properties
[startang, ~] = angle_centroid(current,imageheight,imagewidth,startang);

% create matrix actual values of angles based
[~,reference] = meshgrid(1:2,0:stepsintest);
reference(:,1)=reference(:,1).*phi;
reference(:,1)=reference(:,1)+startang;

%% start collecting data
for m=1:2 %do twice
distance = 0;
servalue= input('enter value 101 move forward 100 move backward:');
fprintf(s,servalue);          %this command send entered value arduino
i = 1;
while (distance < (stepsintest-5))
    distance = fread(s,'%d');
    current = double(round(255*step(vid)));
    i=i+1;
    pause(0.1);
    lastdistance(i)=distance;
   
end
end

fclose(s);

you can increase baudrate both side understand. not sure matlab can do, but
code: [select]

serial.begin(115200);

will increase baudrate 115200.

at 9600 baud character takes 1ms. worst case you're sending 7 characters (values > 10000, 5 characters digits plus cr/lf). although serial.println interrupt driven, loop fill serial tx buffer because sending more data per 2 milliseconds can moved out. , suspect therefore serial.println starts blocking because buffer full.

you can consider send data in binary form instead of ascii; in case think overhead required able synchronize 2 bytes of integers not give advantage.

alternative:
send command arduino 'distance' @ moment matlab application takes snapshot.

note:
why use 100 , 101 in switch/case in parsemenu? not lot clearer use 'd' , 'e'?


Arduino Forum > Using Arduino > Interfacing w/ Software on the Computer > Quicker way to serial print to Matlab


arduino

Comments

Popular posts from this blog

Error: ‘for’ loop initial declarations are only allowed in C99 or C11 mode - Raspberry Pi Forums

class MPU6050 has no member named begin

missing filename after '-o'