Go Down

Topic: Brushed Motor Control through ESC (Read 8876 times) previous topic - next topic

3Dawn

Hello, I'm new to the arduino forum. I am looking for help to control my R/C car (Team Associated RC18B) with my Duemilanove. I can't seem to get the motor to move at all. The car has this motor:
http://www.teamassociated.com/parts/details/21210/

and this speed controller:
http://www.teamassociated.com/xpdigital/parts/details/29136/

I have been able to intercept the signal coming from the receiver and analyze it on Pin 8. I found some code that reads the number of Ticks. I think these ticks represent the pulse length sent to the ESC. This is what I know about the tick numbers:
If the between 3040 and 3055 the transmitter is "neutral".
Greater than 3055 it goes forward
Less than 3040 and it goes in reverse.

I've measure the voltage that gets applied to the motor when I am not intercepting the signals. At neutral the motor sees 7.2V but doesn't turn. When I begin to accelerate the voltage rises to about 7.5 V. In reverse the voltage goes from -0.0 to -7.2V.

By the way, I have the arduino ground same as the battery voltage, and have only tried to send signals on various digital pins.

I've tried using the servo sweep example in Arduino and some other sketches from other posts with regards to ESC controllers and nothing has worked.

Can anyone give me any suggestions of things to try?
Is it possible to convert the ticks to understand what kind of signal the ESC is looking for?

Thank you for any help!!!

zoomkat

I thought ESCs were made for use with "brushless" motors.
Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

Ran Talbott

It probably runs off the same sort of signal as a digital servo (which I'm not really familiar with, but I'm sure google will turn up examples of people using Arduinos and other micros to control them).

(for zoomkat) There are ESCs out there for both types of motors.

Peter_B

The ESC looks like a standard pulse position control device, the standard servo library should drive this fine.
What connections have you made from Arduino to the ESC, The ESC has  RED, Black and White wires to go to a normal RC receiver where did you connect these wires on the Arduino?
If you have an oscilloscope you should see the pulse on your PWN pin go from 1ms to 2ms apart to cover the range of the conroller. 1.5ms is the neutral position.
What type or Arduino are you using and which PWN pin did you use for the ESC control signal?

... peter b.

peter_b

zoomkat

If you are not running an "arming' sequence for the ESC, then that could be a problem. Search the old forum for ESC to see the many previous post on the subject.
Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

3Dawn

Ran, I am able to plug in the steering servo and use the standard servo sweep example without a problem.

Zoomkat, yes, I tried one of the posted codes that does the arming sequence. The interesting thing is they refer to beeping once it is armed. My doesn't beep - ever. Even when using just the standard  pistol transmitter.

Peter, power line is untouched from the ESC to the receiver (straight connection I mean). I tapped into ground so that the Arduino is on the same ground as the battery. I clipped the white wire. I got my readings from the  white wire coming from the receiver which is how I got my data. I tried then using various sketches to send data to the esc on the white wire through the PWM 9 line on the Duemilanove.

Here is my code that I used to read the receiver info. I'm still learning the Arduino programming code and thought I understood it until I got this code. I hardly understand any of it but I'll attach it in case it helps.

Thanks for you suggestions everyone. I really appreciate it!

Code: [Select]

volatile unsigned int Ticks;    // holds the pulse count as .5 us ticks
int icpPin = 8;      // this interrupt handler must use pin 8


ISR(TIMER1_CAPT_vect){
   if( bit_is_set(TCCR1B ,ICES1)){ // was rising edge detected ?
TCNT1 = 0; // reset the counter
   }
   else {   // falling edge was detected
  Ticks = ICR1;
   }
   TCCR1B ^= _BV(ICES1);      // toggle bit value to trigger on the other edge
}

void setup()   // run once, when the sketch starts
{
  Serial.begin(9600);
  pinMode(icpPin,INPUT);
  TCCR1A = 0x00;    // COM1A1=0, COM1A0=0 => Disconnect Pin OC1 from Timer/Counter 1 -- PWM11=0,PWM10=0 => PWM Operation disabled
  TCCR1B = 0x02;    // 16MHz clock with prescaler means TCNT1 increments every .5 uS (cs11 bit set
  Ticks = 0; // default value indicating no pulse detected
  TIMSK1 = _BV(ICIE1);   // enable input capture interrupt for timer 1
}

int getTick() {
  int akaTick; // holds a copy of the tick count so we can return it after re-enabling interrupts
  cli(); //disable interrupts
  akaTick = Ticks;
  sei(); // enable interrupts
  return akaTick;
}

void loop()    // run over and over again
{
  static int prevTick = 0;

  if( getTick()  != prevTick)
     {
     prevTick = getTick();
     if (prevTick > 3040 && prevTick < 3055)  //  .760 milliseconds?
        {
        //Serial.println("Transmitter is on standby");
        }
     if (prevTick > 3055 && prevTick < 3460) //Accelerating  > 0.764 milliseconds  and <.860 milliseconds
        Serial.println("Forward"); //prevTick);     // print the tick value only when it changes
     if (prevTick > 2460 && prevTick < 3040) //Reverse > 0.615 milliseconds and < .076 ms
       Serial.println("Reverse"); //prevTick);
     if (prevTick > 3460) //You are in trouble!!!
         Serial.println("Lost Commnunication with transmitter");
    }
}

3Dawn

I've got it working and wanted to post a thank you to all for your help. To get it working was surprisingly simple but still not quite sure why it works.

Instead of using the servo.write command I used servo.writeMicroseconds

Here is the code for others to use as well:
Code: [Select]
// Drive RC18B
// based on Sweep tutorial code by
// by BARRAGAN <http://barraganstudio.com>
// This example code is in the public domain.


#include <Servo.h>

Servo myservo;  // create servo object to control a servo
                // a maximum of eight servo objects can be created

int pos = 1500;    // variable to store the servo position

void setup()
{
  Serial.begin(9600);
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  //myservo.writeMicroseconds(1580);
}


void loop()
{
  myservo.writeMicroseconds(1580);  //Minimum Forward Speed
  //myservo.writeMicroseconds(1495); Minimum Reverse Speed
  //delay(15);
 
  /*for(pos = 1500; pos < 1800; pos += 1)  // goes from 0 degrees to 180 degrees
  {                                  // in steps of 1 degree
    Serial.print("Forward: ");
    Serial.println(pos);
    myservo.writeMicroseconds(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
 
  for(pos = 1500; pos > 1250; pos -= 10)     // goes from 180 degrees to 0 degrees
  {                               
    Serial.print("Backward: ");
    Serial.println(pos);
    myservo.writeMicroseconds(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  */
}

Hey 3Dawn, I'm also interfacing a Duemilanove with my RC car. I'm running a HPI E10, though, so it's more of a Driftduino. Haha. Glad to see you got it working. I used different code to test and work out the range of my ECS, though. I got it...somewhere, don't remember. It may even be one of the example sketches. lol Anyways, I'll post it up here if you're interested.

Code: [Select]
#include <Servo.h> 
Servo throttle;     
int pos = 0;
void setup()
{
  throttle.attach(8);
  Serial.begin(9600);
  Serial.println("Enter number and press 's' to send it to servo. Send 'stop' to stop moving.");
}
void loop()
{
  static int val = 0;
  if (Serial.available())
  {
    char ch = Serial.read();
    switch(ch)
    {
      case '0'...'9':
        val = val * 10 + ch - '0';
        break;
      case 's':
        throttle.write(val);
        Serial.print("Servos is set to: ");
        Serial.print(val, DEC);
        Serial.println(" degrees");
        val = 0;
        break;
    }
}
Servo refresh();
}


Also, here's my Driftduino sketch as well, just in case you ever feel like coming to the cooler side of RC racing. XD It's a bit rough (no sensors yet), but it's a work in progress.

Code: [Select]
#include <Servo.h>
Servo steering;  // create servo object called "steering" to control the steering servo
Servo throttle;
int pos = 0;    // variable to store the steering position
void setup()
{
  steering.attach(9);  // tells the arduino that the object "steering" should be associated with digital pin 9
  throttle.attach(8);  // and the throttle to pin 8
}
void loop()
{
  delay(4000);
  steering.write(90); //Center the steering
   //arm the Electronic Speed Controller (ESC)
  delay(1000); //gonna waggle the front wheels a bit to test the steering
  int max = 5;
  int i = 0;
  for(i = 0; i < max;i++){
    for(pos = 58; pos < 132; pos += 10)  // goes from 58 degrees (full right) to 132 degrees (full left)
    {                                  // in steps of 10 degree (fast)
      steering.write(pos);              // writes the position to the servo
      delay(15);                       // waits 30ms for the servo to reach the position
    }
    for(pos = 132; pos>=58; pos-=10)     // goes from 132 degrees to 58 degrees
    {                               
      steering.write(pos);              // writes the position to the servo
      delay(15);                       // waits 30ms for the servo to reach the position 
    }
  }
  delay(2000); //On your marks...
  steering.write(90); //get set...
  delay(100);
  throttle.write(130); //GO!
  delay(3000); //build up speed before the flick
  for(pos = 58; pos < 132; pos += 10)  // goes from 58 degrees (full right) to 132 degrees (full left)
  {                                   // in steps of 10 degree (fast)
    throttle.write(30);                  //BRAKE!
    steering.write(pos);              // writes the position to the servo
    delay(30);                       // waits 30ms for the servo to reach the position
  }
  for(pos = 132; pos>=58; pos-=10)     // goes from 132 degrees to 58 degrees
  {                                   
    throttle.write(170);    //Power on!
    steering.write(pos);              // writes the position to the servo
    delay(30);    // waits 30ms for the servo to reach the position
  }
  delay(1000);                   //holds the steering at full right lock for one second
  throttle.write(140);
  int maxd = 5;
  int d = 0;
  for(d = 0; d < maxd;d++){
  {
    steering.write(90);              //Sets the steering position to center
    delay(10);                       // waits 10ms for the servo to reach the position
  }
  delay(1000);                    //holds the steering at center for 1 second
  {                               
    steering.write(58);              // tell servo to go to position in variable 'pos'
    delay(30);                       // waits 15ms for the servo to reach the position
  }
  delay(500);
  }
  throttle.write(90);
  steering.write(60);
  delay(60000);                   //Now Sit. Good boy.
}


AndroidAndroid88

Ok, I wrote some code for a rc plane ESC. SKYARTEC BMC-25A

Not sure if it will work with your ESC but it works with this one.


#include <Servo.h>

Servo m1;

void setup () {
m1.attach(9);//attach to pin 9 (digital)
delay(1);//just a delay to let stuff get started
m1.write(10);//writing the minimum value (Arming it)
delay(1500);//delay to let it process that
m1.write(180);//Writes max value
delay(1500);//delay to let it process
m1.write(90);//writes neutral
delay(1500);//delay
m1.write(138); //max is 138 min is 95
}

void loop() {
}

AndroidAndroid88

Updated code

I'm sort of new to arduino so don't judge my shitty code


//Written byAndroidAndroid88
#include <Servo.h>

Servo m1;

void setup () {
m1.attach(9);//attach to pin 9 (digital)
delay(100);//just a delay to let stuff get started
m1.write(10);//writing the minimum value (Arming it)
delay(1500);//delay to let it process that
m1.write(180);//Writes max value
delay(1500);//delay to let it process
m1.write(90);//writes neutral
delay(1500);//delay
m1.write(170); //motor speed max is 180 min is 90  best 96><170
}

void loop() {
}

Go Up