Thursday, October 11, 2012

Arduino - Control ESC/Motor (Arduino Code Ex.2)

The following code below is posted as another example of how to control more than one motor/esc with an Arduino.

I am using the Servo library to control two motor/esc.  The first motor is called the left and the second motor is called the right motor.  I send the speed in the following format (without quotes):

"l76;r88;n"

In the example above, "l76;" is the speed that I want to send to the left motor.  In the example above, "r88; is the speed that I want to send to the right motor.  In the example above, "n" is how I tell the arduino that the message is complete and done.  

When using the Servo library, we can arm the esc/motors by incrementally stepping up to 60.  NOTE:  This may vary for your esc/motor,  test with caution.  For me, setting the value above 65 put the motors in motion.  Writing anything less than 65 to the motors will stop the motors.  For this to happen,  

The code below is posted as additional content that is free to do whatever you want.  (use, manipulate, copy, learn).  I'm publishing this as something that is not as clean because I believe people want/need more examples.  There is one reference I have for this project that helped me to understand the arming procedure. I can't find it at the moment, and will post it later. 





 #include "Servo.h"  
 #define MOTOR_PIN  9 // This is the left motor  
 #define MOTOR_PIN_R           10  
 #define MOTOR_MAX_SPEED     90 // NOT REALLY NEEDED  
 #define MOTOR_START_SPEED        60  
 /*  
  * This is the max/min speed values restriction  
  */  
 int motor_left_minimum = 68;  
 int motor_left_maximum = 118;  
 int motor_right_minimum = 68;  
 int motor_right_maximum = 118;  
 int motor_current_speed = 0;  
 Servo motor; // This is the left motor  
 Servo motorRight;  
 String left;  
 String right;  
 void setup()  
 {  
  // 115200 default for blusmirf gold  
  //Serial.begin(115200);  
     // 9600 default for the xbee pro series1  
     Serial.begin(9600);  
  // Motor  
  delay(1000);  
  motor.attach(MOTOR_PIN); // This is the left motor  
     motorRight.attach(MOTOR_PIN_R);  
  motorStartAt(MOTOR_START_SPEED); // Arming procedure  
  delay(1500);  
 }  
 void loop()  
 {  
  //Serial.println("in loop");  
  if(Serial.available()>0){  
  //String myString = Serial.readStringUntil('\n');  
  //Serial.println(myString);  
   char ch = Serial.read();  
    if(ch == 'l')  
    {  
     do{  
      if(ch > 47 && ch < 58)  
       {  
       //Serial.print("I have received: ");  
       //Serial.print(ch, DEC);  
       //Serial.print('\n');  
       left += ch;  
       }  
       ch = Serial.read();  
      }while(ch != ';');  
    }  
    else if(ch == 'r')  
     do{  
      if(ch > 47 && ch < 58)  
      {  
      //Serial.print("I have received: ");  
      //Serial.print(ch,DEC);  
      //Serial.print('\n');  
      right += ch;  
      }  
      ch = Serial.read();  
      }while(ch != ';');  
    else if(ch == 'n')  
    {  
    int leftValue = left.toInt();  
    int rightValue = right.toInt();  
    Serial.print("Left value is: ");  
    Serial.print(leftValue);  
    Serial.print(" : ");// + " and " + right);  
    Serial.print("Right value is: ");  
    Serial.print(rightValue);  
    Serial.print('\n');  
    Serial.println();  
    if(leftValue >= motor_left_minimum && leftValue <= motor_left_maximum && rightValue >= motor_right_minimum && rightValue <= motor_right_maximum)  
    {  
     if(leftValue == motor_left_minimum)  
     {  
     motor.write(60);  
     //Serial.println("Left motor set to 60");  
     }  
     else  
     {  
     motor.write(leftValue);  
     /*Serial.print("Left motor set to ");  
     Serial.print(leftValue);  
     Serial.println();  
   */  
     }  
     if(rightValue == motor_right_minimum)  
     {  
     motorRight.write(60);  
     //Serial.println("Right motor set to 60");  
     }  
     else  
     {  
     motorRight.write(rightValue);  
     /*Serial.print("Right motor set to ");  
     Serial.print(rightValue);  
     Serial.println();*/  
     }  
    }  
    left = "";  
    right = "";  
    leftValue = 0;  
    rightValue = 0;  
   }  
  }  
 }  
 // Wrapper function for Servo's ".write(*speed*)" function  
 void motorSetSpeed(int speed)  
 {  
   // Don't let the motor go above or below pre-determined max and min  
  if (speed > MOTOR_MAX_SPEED)  
  speed = MOTOR_MAX_SPEED;  
  else if (speed < MOTOR_START_SPEED)  
  speed = MOTOR_START_SPEED;  
  motor.write(speed);  
     motorRight.write(speed);  
  motor_current_speed = speed;  
  //Serial.print("current motor speed = ");  
  //Serial.println(motor_current_speed);  
 }  
 void motorStartAt(int start_speed)  
 {  
  int i;  
  for (i=0; i < start_speed; i+=5) {  
  motorSetSpeed(i);  
  //Serial.println(i);  
  delay(100);  
  }  
 }  

20 comments:

  1. I think there is some mistake in the code , I tried a lot but its not working..
    data recovery philadelphia

    ReplyDelete
    Replies
    1. Out of curiosity and learning (for myself and others reading), what equipment are you using (arduino, motor,esc,battery type / number of cells)?

      To test if the code is working correctly, uncomment all lines that have "Serial.print", open the serial monitor in the Arduino IDE (Ctrl + M) and type "l75;r85;n" (without quotes). If you get the message "Left motor set to 75. Right motor set to 85." Then the code is uploaded correctly. I retried this code recently and it still works fine.
      I have only used this with one type of motor. This is significant because the arming sequence may be different for other motors. In this sketch, the motors get armed by writing 0-60 in increments of 5 when the arduino starts up.

      Delete
  2. Hi, this is using 2 ESC or 1 ESC for 2 motors ?

    ReplyDelete
    Replies
    1. This example is using 2 ESC for 2 motors. One ESC for each motor.

      Delete
    2. Thank you for replying. And i do want to ask from your code, i saw only pin no.9 only been used. how about another esc ? where should i connect to ?

      Delete
    3. Simple answer, pin 10. Make sure that both esc's are conencted to the same ground (gnd).

      Long answer:
      In this example "pin 9" is the left motor and "pin 10" is the right motor. Here's the initial references to both pins.
      Before the setup() function:
      #define MOTOR_PIN 9 // This is the left motor
      #define MOTOR_PIN_R 10

      Servo motor; // This is the left motor
      Servo motorRight;

      Inside setup():
      motor.attach(MOTOR_PIN); // This is the left motor
      motorRight.attach(MOTOR_PIN_R);

      Thats it.

      Delete
    4. This comment has been removed by the author.

      Delete
    5. Thank you so so much. I'm really appreciate the help you gave me.

      Do you have any example code for quad motors ?

      Delete
    6. I have modified your coding to a quad motor. And i have done with hardware testing on it, is working nicely. And now i have a new challenge, whereby how can i combine the 6DOF(ITG3200 & ADXL345), magnetometer(HMC5883L),and a barometer (BMP085) to work together along with the motors ?

      Delete
    7. You got it before I got to comment, I'm slow. You are looking for the following:

      https://code.google.com/p/ardupilot-mega/source/browse/ArduCopter/sensors.pde

      Getting sensor data can be tricky, but that's a good start.

      Out of interest, are you posting your work anywhere? It would be really fun to see and would help others on the same path.

      Delete
    8. I'm willing to share my code to you all. Hope i can help others on the same projects like mine.

      I will post out my code for the 4 motors here by this 2 days. I'm still testing it out. I'm not sure it is perfect working well or not.

      And i wish you can share it out somewhere for those who need it.

      Thank you.

      Delete
    9. Can u send me your email address ? The code here is too big to upload like that.

      I send you the .ino file direct to you.

      Delete
    10. I've added a "Contact Me" page, located on the right side of the page.

      Delete
    11. Got the code you sent. It looks awesome! It's good to see how it worked out. Really glad that it helped.

      Delete
    12. Funny gnkira mentioned the 6DOF - i am planning to build a quadcopter that uses the 6DOF to auto-hover and i am here to find code to arm my hobbyking esc with turnigy brushless motors.

      I will try this code over the next couple days and see how it turns out.

      Would you mind sharing your ino for me to look at. I would also like to share my work with you guys as I get further into the project.

      Delete
    13. Late reply, sorry - work and what not.
      I'll try to send you some stuff that you can paste into the Arduino IDE to help get started through google+. If you have another way you want to get the text or files, send me a note through the contact me page, always happy to help.

      Another discussion that might be relevant to the subject of controlling your motors can be seen at:
      http://letsmakerobots.com/node/35684

      How's the progress going, any results?

      Delete
    14. is that wireless control ?

      Delete
  3. I am using this using lpc2148, plz guide me how to do it using lpc2148 and programming section...

    ReplyDelete
  4. I have a 3-phase brushless motor 1100 kv, an esc to 30 A, a battery of 5 Ah LiPo 3-cell and when I sent a progression from 0 to 180 and then 180 to 0 went well and then I disconnected; I repeated and it went well. The third time I hear sound, but no longer turns.
    I'm desperate, I know you help?

    ReplyDelete