Go Down

Topic: simple program to run on matlab to control servo motor,using serial port. (Read 5 times) previous topic - next topic

andever

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..

robtillaart

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)

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

andever

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.

robtillaart


based upon - http://playground.arduino.cc/Learning/SingleServoExample -

ity can be as simple as

Code: [Select]

#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
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

andever

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.

andever

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!!
Code: [Select]
Serial.begin(9600);
   
 servo1.attach(6);
 
 
}


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

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


robtillaart


something like

Code: [Select]

... 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
}

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

andever

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);??
Code: [Select]
void loop() {

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


robtillaart

Quote
anyone??

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

Quote
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 ,
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

andever

Quote
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.

andever

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.

robtillaart


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,

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

zoomkat

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

Code: [Select]

//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
    }
  }
}

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   8)

brainybrown86

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: http://www.matlabarduino.org/serial-communication.html --> 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):

Quote

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:
Quote

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

Go Up