How to run in real-time five servos connected to arduino board?

11 views (last 30 days)
Hello everybody, I have already posted to the arduino forum, however no one seems to be able to help me there. I would like to real-time control 5 servos connected to my arduino mega 2560 Mikrocontroller via Matlab`s serial port (instead of using the slow Arduino I/O package). The servos are properly connected to ports 2,4,6,8,9 and work fine, if I use the Arduino I/O package.
I have also accomplished to write a code that does correctly move the servos via Matlabs serial; and if I type in the required values into the Arduino serial monitor itself, it also outputs the values in the right way. Thus, the serial port communication Matlab and Arduino generally works.
!!! However my code only works, if I add up a lot of breaks into the Matlab code !!!
Here the Matlab-code:
% Commands:
% 140 --> attach all servos and bring them to position 40
% 000 --> detach all servos
% xy --> move servo x to y (y must be an integer between 0 and 180)
clear all
close all
delete(instrfind('Type', 'serial')); % Assure that no serial port is open anymore
s = serial('com5'); % Create new serial port object.
%set(s,'DataBits',8); % ???
%set(s,'StopBits',1); % ???
%set(s,'Parity','none'); % ???
set(s,'BaudRate',9600); % Use same baudrate specified in Arduino
fopen(s); % Open Serial port
% Attach motors and bring them to default position
pause(2); % give servo some time to initialize
fprintf(s, '%s\n','141') % say arduino to attach the servos and bring them 41 degree.
pause(2);
% Try to move servos
for i=1:100
if rem(i,2) % if i is an equal number
disp(i)
fprintf(s, '%s\n','240') % sent servo number, 40 degree servo position (in string format, ended by an \n)
pause(0.5)
fprintf(s, '%s\n','440')
pause(0.5)
fprintf(s, '%s\n','640')
pause(0.5)
fprintf(s, '%s\n','840')
pause(0.5)
fprintf(s, '%s\n','940')
else % if i is an unequal number
disp(i)
fprintf(s, '%s\n','2100') % sent servo number, 100 degree servo position
pause(0.5)
fprintf(s, '%s\n','4100')
pause(0.5)
fprintf(s, '%s\n','6100')
pause(0.5)
fprintf(s, '%s\n','8100')
pause(0.5)
fprintf(s, '%s\n','9100')
pause(0.5)
end
pause(1)
end
And here the Arduino-code:
// Responds to the following commands:
// 140 --> attach all servos and bring them to position 40
// 000 --> detach all servos
// xy --> move servo x (can be either 2,4,6,8,9 ) to y (y must be an integer between 0 and 180)
#include <Servo.h>
Servo servo2;
Servo servo4;
Servo servo6;
Servo servo8;
Servo servo9;
String posString = "";
void setup()
{
//Serial.begin(115200); // communicate fast !
Serial.begin(9600);
}
void loop()
{
if( Serial.available()>=4) // >=4 because the \n character also has to be counted
{
int nr = Serial.read()- '0'; //
Serial.println("Servo");
Serial.println(nr);
delay(2);
posString = "";
while (Serial.available() > 0) {
//Serial.println("drinnen");
char tmp = Serial.read();
if (tmp == '\n') {
Serial.println("new line");
break;
}
else
{
posString += tmp;
Serial.println("Position");
Serial.println(posString);
}
}
int pos = posString.toInt();
switch(nr)
{
case 2:
servo2.write(pos);
break;
case 4:
servo4.write(pos);
break;
case 6:
servo6.write(pos);
break;
case 8:
servo8.write(pos);
break;
case 9:
servo9.write(pos);
break;
// Just for attaching and detaching servos out of Matlab:
case 0: // to detach servos: sent 000 plus another integer to detach servos and spare energy
servo2.detach();
servo4.detach();
servo6.detach();
servo8.detach();
servo9.detach();
delay(1000);
break;
case 1: // to attach servos: send 1xx, in order to attach the servos and bring them to xx position
servo2.attach(2);
servo4.attach(4);
servo6.attach(6);
servo8.attach(smiley-cool;
servo9.attach(9);
delay(1000);
servo2.write(pos);
servo4.write(pos);
servo6.write(pos);
servo8.write(pos);
servo9.write(pos);
delay(1000);
break;
}
}
}
As I said, if I remove the pause statements in Matlab, either Matlab crashes or Arduino. Does anybody have an idea how I can improve my code so that I can remove the pause statements in Matlab (or reduce them to a minimum) and get it running more stable and in real-time. Do I need some pause statements in the Arduino code? Do I need to use something instead of the fprintf-command? Do I have to change the baudrate? Or do I have to use a different servo control functions?
I would be very very thankful, if someone could help me out. Thank you very much in advance
  1 Comment
Valmir Sadiku
Valmir Sadiku on 27 May 2014
There are several issues for your behavior: at first you can't expect real-time control via the usb - if your OS thinks they have to do somthing another - they will do it and pause the comunication! Of course you can improve the speed if you set higher buadrate. Why you send the data value by value? pause(0.5)
fprintf(s, '%s\n','4100')
pause(0.5)
fprintf(s, '%s\n','6100')
pause(0.5)
fprintf(s, '%s\n','8100')
pause(0.5)
fprintf(s, '%s\n','9100')
pause(0.5)
You should send also the whole data within one fprintf call and destruct it on the arduino, which will do this work without reaching the limits. hope this will help you

Sign in to comment.

Answers (0)

Categories

Find more on MATLAB Support Package for Arduino Hardware in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!