Hello All,
I am controlling a stepper motor with an Arduino, and I have a camera simultaneously taking images of an object that the motor is moving. I would like to send the current position of the stepper motor (currently being counted in the variable "Distance") every time I take a snapshot in Matlab. Unfortunately when I run this program with the Serial.println line in the stepper code, the motor slows down tremendously as it spends time sending the serial info to MATLAB.
Is there a better way to send serial information from the Arduino without noticeably affecting my motor function? Or keep the information in a buffer so that it can be quickly sent only when I use the fread code from Matlab?
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 up Serial library at 9600 bps
}
void loop() {
//menu(); //call the menu
while (!Serial.available()){ //wait until a serial value is available from MATLAB
}
parsemenu(Serial.read()); //decide what to do
}
//void menu(){
// //decide what to do
// //use serial command in arduino window for this first test
// Serial.println("What should I do?");
// Serial.println("enter b for move back, enter f for 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
for (int Distance = 0; Distance <STEPS; Distance++){ //move a certain 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
for (int Distance = STEPS; Distance >=0; Distance--){ //move a certain 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);
}
}
Matlab code:
clear all
close all
clc
%% Lets define some variables
steps = 1; %Number of milliseconds per step (higher is 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 to check around circle
stepsintest = 17000; %number of steps that the conveyer will travel
%% Lets open up the camera
vid = imaq.VideoDevice('dcam', 1, 'Y8_640x480');
%src = getselectedsource(vid);
vid.DeviceProperties.ShutterControl = 'absolute';
vid.DeviceProperties.ShutterAbsolute = 0.04;
release(vid);
%% Start a serial connection with the Arduino
s=serial('/dev/cu.usbmodemFA131','BAUD', 9600);
% Make sure the baud rate and COM port is same as in Arduino IDE
fopen(s);
%% Send one frame through algorithm to establish baseline angle
current = double(round(255*step(vid)));
imageheight=size(current,1);
imagewidth=size(current,2);
% Take a first image to define the properties
[startang, ~] = angle_centroid(current,imageheight,imagewidth,startang);
% Create a matrix with 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 this twice
distance = 0;
servalue= input('Enter the value 101 to move forward 100 to move backward:');
fprintf(s,servalue); %This command will send entered value to 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);