simple program to run on matlab to control servo motor,using serial port.

i would like to have a basic program to rotate the servo motor to 60 degree clockwise,i would use it as reference for my project,for my project i need to control 3 servo's using arduino uno,but the program code should be using "serial" so as to avoid delay.please help me..

Don't know how to help you as your description is minimal

What have you tried sofar?
Can you post the code?

Have you read the Arduino serial documentation?
Have you looked at the servo and serial examples in the tutorial section?
These contain all information (and 99% of the code) you need (at least the arduino side)

yes i have seen few tutorials and i have managed to connect the matlab with arduino uno with the program
% connect the board
a=arduino('COM21');

% attach servo #1
a.servoAttach(9);

% move servo #1 to 50 degrees position
a.servoWrite(9,50);

% reads angle from servo #1
val=a.servoRead(9);

% attach servo #1
a.servoDetach(9);

% close session
delete(a)
and i have uploaded adiosvr into the arduino uno, but i didn't understand how to use serial port,so if u give me a example for using it for a single or two servo motor i will follow it,i needed serial port because i heard its sends signal faster.for coonecting above code in matlab-arduino and for servo motor to run it takes about 10 seconds,but i need this actuation in less than a second.

based upon - Arduino Playground - SingleServoExample -

ity can be as simple as

#include <Servo.h>

Servo servo1; 

void setup() 
{
  servo1.attach(10);    

  Serial.begin(115200);
  Serial.println();  // signal to matlab arduino is ready to receive
}

void loop() 
{
  static int value = 0;
  if ( Serial.available() > 0) 
  {
    char ch = Serial.read();

    switch(ch) 
    {
      case '0'...'9':
        value = value  *10 + ch - '0';
        break;
      case 'w':
        servo1.write(value);
        v = 0;
        break;
      case 'r':  // reset position
        servo1.write(0);
        break;
      default:
        break;
    }
  }

  Servo::refresh();
}

you can send over a serial monitor "160w" , "90w", "r", "123r" etc

thank u for reply,now i am able to understand better,but i don't want to send signal by sending/typing in serial monitor, where as by using matlab code to run motor by using serial communication.

this is the code to attach,read write one servo, what would the code be in void loop if i had to read and write more that 1 servo like 5 servos?? plz needed urgently!!

Serial.begin(9600);
    
  servo1.attach(6);
   
   
}


//LOOP--------------------------------
void loop() {

 if( Serial.available() ) 
    {
        int x = Serial.read();
        servo1.write(x);
    }
  
}

something like

... some include here

void setup()
{
  Serial.begin(115200); // communicate fast !

  servo1.attach(6);
  servo2.attach(7);
  servo3.attach(8);
}



void loop() 
{
  if( Serial.available() >=2) 
  {
    int nr = Serial.read();  // read the servo number
    int position = Serial.read();
    switch(nr)
    {
    case 1: 
      servo1.write(position); 
      break;
    case 2: 
      servo2.write(position); 
      break;
    case 3: 
      servo3.write(position); 
      break;
    default: 
      servo1.write(0); 
      servo2.write(0); 
      servo3.write(0);  // reset all servos on invalid data
      break; 
    }
  }
  sleep(100); // give the servo's some time
}

if i want all three servo to act at single time then "will case 1, case 2 and case 3 act at same time"?or can i simply add servo2.write(x); servo3.write(x);....after servo1write(x);??

void loop() {

 if( Serial.available() ) 
    {
        int x = Serial.read();
        servo1.write(x);
    }

anyone??

anyone??

Have you tried the code I proposed?
if yes, did it work as you expect?
if no, why not?

if i want all three servo to act at single time then "will case 1, case 2 and case 3 act at same time"?or can i simply add servo2.write(x); servo3.write(x);....after servo1write(x);??

Have you tried this idea?
if yes, did it work? as expected or almost?

what do you mean by the same time, servos are 10,000 times slower than the microprocessor clock, and human are 10x slower than servo's still (order of magnitude)

you really learn the most by doing and yes that includes making mistakes and yes it takes time...

And yes, you are on the right track with your ideas ,

if i want all three servo to act at single time then "will case 1, case 2 and case 3 act at same time"?or can i simply add servo2.write(x); servo3.write(x);....after servo1write(x);??

it didn't work, motor was like making sound but never rotated, i am sending signal to arduino from matlab like
fprintf(arduino,'%s','p8m45g') %servo on pin 7 to 45 degree
fprintf(arduino,'%s','p9m135g') % servo on pin 6 to 135 degree
is there any prb above codes??
and about yours will try it tomorrow, and yes i need to run three motor's simultaneously such condition exist on my matlab code.

ur code is working ,but then if i give command to pin 8 servo,pin 9 and pin 10 servo are also working, i want only 8 to work if i give signal to 8.

That means your wiring is not correct, can you post your schematics how you connected the servo's

Other tip: in the code I posted I used case 1,2 and 3. These numbers might need to change if you want to use number 8,9,10.
Also the code to handle the serial input depends whether you send ASCII or BINARY data,

Multi servo test code for the arduino. You will need to develop the matlab code to send the commands.

//zoomkat 11-22-12 simple delimited ',' string parse 
//from serial port input (via serial monitor)
//and print result out serial port
//multi servos added 

String readString;
#include <Servo.h> 
Servo myservoa, myservob, myservoc, myservod;  // create servo object to control a servo 

void setup() {
  Serial.begin(9600);

  //myservoa.writeMicroseconds(1500); //set initial servo position if desired

  myservoa.attach(6);  //the pin for the servoa control
  myservob.attach(7);  //the pin for the servob control
  myservoc.attach(8);  //the pin for the servoc control
  myservod.attach(9);  //the pin for the servod control 
  Serial.println("multi-servo-delimit-test-dual-input-11-22-12"); // so I can keep track of what is loaded
}

void loop() {

  //expect single strings like 700a, or 1500c, or 2000d,
  //or like 30c, or 90a, or 180d,
  //or combined like 30c,180b,70a,120d,

  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      if (readString.length() >1) {
        Serial.println(readString); //prints string to serial port out

        int n = readString.toInt();  //convert readString into a number

        // auto select appropriate value, copied from someone elses code.
        if(n >= 500)
        {
          Serial.print("writing Microseconds: ");
          Serial.println(n);
          if(readString.indexOf('a') >0) myservoa.writeMicroseconds(n);
          if(readString.indexOf('b') >0) myservob.writeMicroseconds(n);
          if(readString.indexOf('c') >0) myservoc.writeMicroseconds(n);
          if(readString.indexOf('d') >0) myservod.writeMicroseconds(n);
        }
        else
        {   
          Serial.print("writing Angle: ");
          Serial.println(n);
          if(readString.indexOf('a') >0) myservoa.write(n);
          if(readString.indexOf('b') >0) myservob.write(n);
          if(readString.indexOf('c') >0) myservoc.write(n);
          if(readString.indexOf('d') >0) myservod.write(n);
        }
         readString=""; //clears variable for new input
      }
    }  
    else {     
      readString += c; //makes the string readString
    }
  }
}

Hello everybody,
I have actually a very similar problem to the original posting: I would like to control 5 servos at real-time (or as fast as possible I can get to this) via Matlab`s serial port (instead of using the Arduino I/O package).

What I have achieved so far is the following:

  • Connecting my Arduino mega 2560 via USB (com5)
  • Connecting my servos to pwm pins 2,4,6,8,10
  • Controlling my servos via Matlab using the Arduino I/O package. --> This works really fine, apart from the insufficient timing. So I am sure that every servo is connected properly and that the arduino board is accessible via Matlab.
  • Establishing a general communication between Arduino and Matlab via serial port, following this video: Connecting the Arduino UNO to Matlab via the USB port for serial communication --> This also works.

However, what I am struggling with is how to properly write (Matlab) and read (Arduino) data from the serial port. Based on your suggestions here, my idea was to use integers for serial port communication between matlab and arduino: The first integer (nr) to say arduino which servo shall be moved, and the second integer (position) to say arduino to which degree the servo shall be moved.

This is the Matlab code that I have so far (trying to move the servo on pin 2 from 40 to 80 degree, in a for loop):

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,'BaudRate',9600); % Use same baudrate specified in Arduino
%set(s,'Parity','none'); % ???
fopen(s); % Open Serial port

nr = '2'; % servo to be moved
position = '40'; % degree

% Try to move servo 2 every second
for i=1:100

if rem(i,2) % if equal
position = '80';
fprintf(s, '%i',nr); % sent servo number (in integer format)
fprintf(s, '%i',position); % sent servo position (in integer format)
else % if unequal
position = '40';
fprintf(s, '%i',nr);
fprintf(s, '%i',position);
end
pause(1); % wait one second
end

And this is the corresponding arduino code:

void loop()
{
servo2.write(60);
servo4.write(60);
servo6.write(60);
servo8.write(60);
servo10.write(60); // This works!!!

if( Serial.available() >=2)
{

int nr = Serial.read(); // read in servo number
int position = Serial.read(); // read in servo position
switch(nr)
{
case 2:
servo2.write(position);
break;
case 4:
servo4.write(position);
break;
case 6:
servo6.write(position);
case 8:
servo8.write(position);
case 10:
servo10.write(position);
break;
default:
servo2.write(60);
servo4.write(60);
servo6.write(60); // default position
servo8.write(60);
servo10.write(60);
break;
}
}
//sleep(100); // give the servo's some time --> Throws an "'sleep' was not declared in this scope"-error!!!
}

The problem is now that although matlab seems to be connecting with the serial port, nothing really happens (apart from moving the servos once to the default position). Hence, it seems to be the case that the arduino cannot really read the integers that I sent by Matlab.

Does anybody know what is wrong with my code?
I would be very very thankful if someone could help me out and give me some advice.

Cheers

PS: I have also two further questions:

  1. As I stated I would like to have as few delays as possible (We would like to compete with the nervous system). Can you give me some recommendations regarding the optimal baude rate for serial port communication?
  2. the sleep command (last line in the arduino code) does not compile. Has anyone an idea why this is the case
        fprintf(s, '%i',nr);       
        fprintf(s, '%i',position);

This converts the values to strings.

  if( Serial.available() >=2)
  {

   
    int nr = Serial.read();          // read in servo number
    int position = Serial.read();    // read in servo position

This assumes that the data is binary.

One of them is not compatible with the other. Your choice as to which you change.

Thank your for very much your reply. Unfortunately I am not completeley sure what you mean or whether your are right.
Regarding the Matlab code:

fprintf(s, '%i',nr);
fprintf(s, '%i',position);

I thought, that my code produces integers, because the first parameter (s) just specifies the serial port, whereas the second parameter specifies the format ('%i')? See the doc of the fprintf command. And this is also what seems happen, if you for instance just type

fprintf('%i',10);

fprintf('%i','any string');

into your console, thus sending the fprintf command to your console.
What was probably wrong with my code was the third parameter, because here I handed over a string, instead of an integer (and this string was then transformed to a loooong integer). However, this fix does not solve the problem.
The servos are still not responding.

Regarding the Arduino Code, I do not understand how I can specifically say Arduino that it shall read integers from the serial port and whether they will be unsigned or not
Any Ideas, how I have to change the code in either Matlab or Arduino?

Here my slightly adapted codes that I have at the moment:
Matlab

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,'BaudRate',9600); % Use same baudrate specified in Arduino
%set(s,'Parity','none'); % ???
fopen(s); % Open Serial port

nr = 2; % servo to be moved
position = 40; % degree

% Attach motors and bring them to default position
fprintf(s, '%i',1) % sent servo number (in integer format)
fprintf(s, '%i',position) % sent servo position (in integer format)

% Try to move servo 2 every second
for i=1:100

if rem(i,2) % if equal
position = 80;
disp(i)
fprintf(s, '%i',nr) % sent servo number (in integer format)
fprintf(s, '%i',position) % sent servo position (in integer format)
else % if unequal
disp(i)
position = 40;
fprintf(s, '%i',nr)
fprintf(s, '%i',position)
end
pause(1); % wait one second
end

Arduino

#include <Servo.h>

Servo servo2;
Servo servo4;
Servo servo6;
Servo servo8;
Servo servo10;

void setup()
{
//Serial.begin(115200); // communicate fast !
Serial.begin(9600);
//servo2.attach(2);
//servo4.attach(4);
//servo6.attach(6);
//servo8.attach(8);
//servo10.attach(10);
}

void loop()
{
//servo2.write(60); % move servos ones to default position
//servo4.write(60);
//servo6.write(60);
//servo8.write(60);
//servo10.write(60); // This works!!!

if( Serial.available() >=2)
{

int nr = Serial.read(); // read in servo number
int pos = Serial.read(); // read in servo position
switch(nr)
{
case 2:
servo2.write(pos);
break;
case 4:
servo4.write(pos);
break;
case 6:
servo6.write(pos);
case 8:
servo8.write(pos);
case 10:
servo10.write(pos);
break;
case 0: // sent 0 plus another integer to detach servos and spare energy
servo2.detach();
servo4.detach();
servo6.detach();
servo8.detach();
servo10.detach();
break;
case 1: // send 1 plus plus default position, in order to attach the servos and bring them to default position
servo2.attach(2);
servo4.attach(4);
servo6.attach(6);
servo8.attach(8);
servo10.attach(10);
servo2.write(pos);
servo4.write(pos);
servo6.write(pos);
servo8.write(pos);
servo10.write(pos);
break;
default:
servo2.write(60);
servo4.write(60);
servo6.write(60); // default position
servo8.write(60);
servo10.write(60);
break;
}
}
//sleep(100); // give the servo's some time --> Throws an "'sleep' was not declared in this scope"-error!!!
}

Again, I would be again very thankful for any help.
Cheers

Hello,
unfortunately, I'm still struggling with my real-time control of five servos via Matlab.
I have now a code, that does move the servos in the expected manner and if I type in the required values into the Arduino serial monitor, it outputs the values in the right way. Thus, Matlab and Arduino at least seem to speak the same language now.

However my code only works, if I add up a lot of breaks into the Matlab code.

Here is 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

Here is 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(8);
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?
Or do I have to use a different servo control functions?

Again I would be very very thankful, if someone could help me out.

Although its a old thread, but helpful for me. I was also searching for ways to run servo using matlab and found this page. I have ran the servo using below tutorial, it was simple:
Servo Motor Control using MATLAB and Arduino
If some wants some deep knowledge then mathwork have done the good job:
Servo control 1
Servo control 2