Sunday, June 10, 2012

Arduino - Control ESC/Motor (Arduino Code)


Summary
This is only the Arduino sketch for the tutorial "Arduino - Control ESC/Motor Tutorial".  This is a tutorial of how to control an electronic speed control (ESC)and brushless motor using an Arduino.


/*
*  This code is in the public domain.
*  (Do whatever you want with it.)
*/

// Need the Servo library
#include <Servo.h>

// This is our motor.
Servo myMotor;

// This is the final output
// written to the motor.
String incomingString;


// Set everything up
void setup()
{
  // Put the motor to Arduino pin #9
  myMotor.attach(9);

  // Required for I/O from Serial monitor
  Serial.begin(9600);
  // Print a startup message
  Serial.println("initializing");
}


void loop()
{
  // If there is incoming value
  if(Serial.available() > 0)
  {
    // read the value
    char ch = Serial.read();
 
    /*
    *  If ch isn't a newline
    *  (linefeed) character,
    *  we will add the character
    *  to the incomingString
    */
    if (ch != 10){
      // Print out the value received
      // so that we can see what is
      // happening
      Serial.print("I have received: ");
      Serial.print(ch, DEC);
      Serial.print('\n');
   
      // Add the character to
      // the incomingString
      incomingString += ch;
    }
    // received a newline (linefeed) character
    // this means we are done making a string
    else
    {
      // print the incoming string
      Serial.println("I am printing the entire string");
      Serial.println(incomingString);
   
      // Convert the string to an integer
      int val = incomingString.toInt();
   
      // print the integer
      Serial.println("Printing the value: ");
      Serial.println(val);
   
      /*
      *  We only want to write an integer between
      *  0 and 180 to the motor.
      */
      if (val > -1 && val < 181)
     {
       // Print confirmation that the
       // value is between 0 and 180
       Serial.println("Value is between 0 and 180");
       // Write to Servo
       myMotor.write(val);
     }
     // The value is not between 0 and 180.
     // We do not want write this value to
     // the motor.
     else
     {
       Serial.println("Value is NOT between 0 and 180");
     
       // IT'S a TRAP!
       Serial.println("Error with the input");
     }
   
      // Reset the value of the incomingString
      incomingString = "";
    }
  }
}

10 comments:

  1. Hello,

    I'm a little desperate. I want to settle with my 4 brushless Duemillenova. 3 motors work that is no longer the fourth.

    ESC and motors are teste and OK.

    here is mey code:
    #include
    #include

    Servo rotor_1;
    Servo rotor_2;
    Servo rotor_3;
    Servo rotor_4;

    #define PINESC1 5
    #define PINESC2 6
    #define PINESC3 10
    #define PINESC4 11
    #define ARM_TIME 10000
    typedef enum {
    STARTROTOR1,
    STARTROTOR2,
    STARTROTOR3,
    STARTROTOR4,
    } rotation_t;

    int rotorSpeed = 0;
    int rotorMillis = 0;

    unsigned long currentMillis = 0;

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

    rotor_1.attach(PINESC1);
    rotor_2.attach(PINESC2);
    rotor_3.attach(PINESC3);
    rotor_4.attach(PINESC4);
    arm_esc(ARM_TIME);
    }
    void loop()
    {
    ReadKeybord();
    start();
    currentMillis = millis();
    Serial.print("Current Millis - ");Serial.println(currentMillis);

    }

    void start()
    {
    static rotation_t rotation = STARTROTOR1;
    static int wait = 1;
    static unsigned long newMillis = 0;

    switch(wait)
    {
    case 1:
    newMillis = currentMillis;
    wait = 2;
    break;
    case 2:
    if (currentMillis - newMillis >= 25)
    {
    Serial.print("New Mills - ");Serial.println(newMillis);

    switch(rotation)
    {
    case STARTROTOR1:
    rotor_1.writeMicroseconds(rotorMillis);
    Serial.print("CW1 MS - ");Serial.println(rotorMillis);
    rotation = STARTROTOR2;
    break;
    case STARTROTOR2:
    rotor_2.writeMicroseconds(rotorMillis);
    Serial.print("CCW1 MS - ");Serial.println(rotorMillis);
    rotation = STARTROTOR3;
    break;
    case STARTROTOR3:
    rotor_3.writeMicroseconds(rotorMillis);
    Serial.print("CW2 MS - ");Serial.println(rotorMillis);
    rotation = STARTROTOR4;
    break;
    case STARTROTOR4:
    rotor_4.writeMicroseconds(rotorMillis);
    Serial.print("CCW2 MS - ");Serial.println(rotorMillis);
    rotation = STARTROTOR1;
    break;
    }
    wait = 3;
    }
    break;

    case 3:
    wait = 1;
    break;
    }
    }

    void arm_esc(int ArmTime)
    {
    delay(ArmTime);

    Serial.println("Sending lowest throttle Motor 1");
    rotor_1.writeMicroseconds(1000);
    delay(2000);
    Serial.println("Sending lowest throttle Motor 2");
    rotor_2.writeMicroseconds(1000);
    delay(2000);
    Serial.println("Sending lowest throttle Motor 3");
    rotor_3.writeMicroseconds(1000);
    delay(2000);
    Serial.println("Sending lowest throttle Motor 4");
    rotor_4.writeMicroseconds(1000);
    delay(2000);


    Serial.println("Low throttle sent");
    }

    void ReadKeybord()
    {
    int key = 0;

    if(Serial.available() > 0)
    {
    key = Serial.read();

    switch(key)
    {
    case '2':
    rotorMillis = mapSpeedToMicrosec(rotorSpeed += 1);
    Serial.print(" - Speed steigern - ");Serial.println(rotorSpeed);
    break;

    case '8':
    rotorMillis = mapSpeedToMicrosec(rotorSpeed -= 1);
    Serial.print(" - Speed senken - ");Serial.println(rotorSpeed);
    break;

    case '5':
    rotorMillis = mapSpeedToMicrosec(0);
    rotorSpeed = 0;
    Serial.print(" - Stop - ");Serial.println(rotorSpeed);
    break;
    }
    }
    }

    int mapSpeedToMicrosec(int speed)
    {
    int _MS = 0;

    _MS = map(speed, 0, 150, 1000, 2500);

    Serial.print(" - setSpeed Millis - ");Serial.println(_MS);

    return(_MS);
    }

    ReplyDelete
    Replies
    1. I'll take a look tonight. Are you using a shield?

      Just posted another example. It uses the Servo library but may help as another example.

      http://techvalleyprojects.blogspot.com/2012/10/arduino-control-escmotor-arduino-code.html

      Delete
  2. i have test with my RC CAR esc but it only can move forward when i sent "val" above 90. it just stop and not move reverse when i sent "val" below 90. how can i move it reverse??

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. To turn on the ESC with this program. Fits 10 and nothing happens

    ReplyDelete
  5. Hello friends,

    I was using the same code given in this blog. i.e. :

    /*
    * This code is in the public domain.
    * (Do whatever you want with it.)
    */

    // Need the Servo library
    #include

    // This is our motor.
    Servo myMotor;

    // This is the final output
    // written to the motor.
    String incomingString;


    // Set everything up
    void setup()
    {
    // Put the motor to Arduino pin #9
    myMotor.attach(9);

    // Required for I/O from Serial monitor
    Serial.begin(9600);
    // Print a startup message
    Serial.println("initializing");
    }


    void loop()
    {
    // If there is incoming value
    if(Serial.available() > 0)
    {
    // read the value
    char ch = Serial.read();

    /*
    * If ch isn't a newline
    * (linefeed) character,
    * we will add the character
    * to the incomingString
    */
    if (ch != 10){
    // Print out the value received
    // so that we can see what is
    // happening
    Serial.print("I have received: ");
    Serial.print(ch, DEC);
    Serial.print('\n');

    // Add the character to
    // the incomingString
    incomingString += ch;
    }
    // received a newline (linefeed) character
    // this means we are done making a string
    else
    {
    // print the incoming string
    Serial.println("I am printing the entire string");
    Serial.println(incomingString);

    // Convert the string to an integer
    int val = incomingString.toInt();

    // print the integer
    Serial.println("Printing the value: ");
    Serial.println(val);

    /*
    * We only want to write an integer between
    * 0 and 180 to the motor.
    */
    if (val > -1 && val < 181)
    {
    // Print confirmation that the
    // value is between 0 and 180
    Serial.println("Value is between 0 and 180");
    // Write to Servo
    myMotor.write(val);
    }
    // The value is not between 0 and 180.
    // We do not want write this value to
    // the motor.
    else
    {
    Serial.println("Value is NOT between 0 and 180");

    // IT'S a TRAP!
    Serial.println("Error with the input");
    }

    // Reset the value of the incomingString
    incomingString = "";
    }
    }
    }

    I am using 30amp esc (http://hobbyking.com/hobbyking/store/uh_viewitem.asp?idproduct=25365) for
    850 kv turnigy multistar motor (http://hobbyking.com/hobbyking/store/uh_viewitem.asp?idproduct=25365)

    When I gave 170 input through serial monitor after arming the motor, the motor started rotating. however after nearly 30 sec, the motor suddenly stopped.

    After that when i again tried to run it, it didnt run with the same ESC where as it was working fine with another ESC. Now none of my motors are working with that particular ESC.

    I know my esc is damaged but I am not able to find out how?. The motor was running at no load. In no way its capable of taking more than 30 amp at no load. Plz expain what wrong i have done.

    ReplyDelete
  6. hey
    im currently working on a project that requires to control the esc & dc brushless motor from an arduino. i've show the codes u wrote but im not sure what are those integer figures. u wrote 0 and 180 to the motor. what are this figures and how am i suppose to know what is the correct figure for my motor ?

    thank you

    ReplyDelete
    Replies
    1. This was written as an example sketch for the ESC/motors that I have. In the previous article, http://techvalleyprojects.blogspot.com/2012/06/arduino-control-escmotor-tutorial.html , go to section 5. There you can see what 0 to 180 means. Also, it shows how I got the settings for the ESC/motor I was using. Yours will probably be different, but you should be able to do it the same way I did.

      Delete
    2. """Very nice post. I just stumbled upon your blog and wanted to say that I've really enjoyed browsing your blog posts. Thanks for sharing thsi post on
      Monitor and Control Your Projects
      it improves project time management, Maximizes Productivity and improve busines"""

      Delete
  7. Hey Sean

    I tried your code with hobbyking esc 20A on a bldc motor from a old hdd .I tried all the numbers. But, nothing seems to work .I get a fast one beep sound from the motor.

    ReplyDelete