ESC Signal - Choppy throttle

Hi everyone,

I’m currently building a quadcopter and making my own flight controller using Arduino. I’m using the Servo library to control my ESCs, and I’m writing an Android app to communicate over bluetooth. I’m having two problems, both related to the ESC signal:

  1. I calibrated my ESCs to respond to 800ms-2000ms pulses. This works, however they really don’t engage until about 850ms. I tried making the lower bound 850, but then they wouldn’t respond until about 900ms…Is there an obvious reason for this? Up until now, I have just been dealing with it and ignoring signal changes below 850ms.

  2. I’m getting very choppy throttle transitions in my motors. I’ve set up my Android app with a SeekBar which sends out values 0 - 1000. These are mapped to 800 - 2000 in the Arduino code. Whenever I send a constant signal (e.g. 1000) the motors run at that speed without any problem. However, when I send a series of throttle changes (sliding the bar on the Android app up or down), the motors frequently get bursts or surges of speed. For example, say I was sending the following series of signals : 850, 851, 852, 853, 854, 855, etc… The motor would increase in speed as it should, and then all of a sudden sound like it went up to 900 for a split second and then get back on track. If I leave it on any speed though, it runs fine without any surges.

Is it maybe changing the pulse width too quickly? Is it possible that the ESCs are losing track of the phase? The input values received through the bluetooth are all correct and don’t have any jumps in between them, so I don’t think the problem is there. I’ve also tried mapping the input to 850 - 1000 to target a smaller range and moved the bar very slowly, but these surges still occur…

This is the Arduino code I’m using:

#include <Servo.h>
#include <SoftwareSerial.h>

Servo m1, m2, m3, m4;


int bluetoothTx = 2;
int bluetoothRx = 3;
int val = 800;
int pos = 800;
String message = "";

SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);

void setup()
{
  //Setup usb serial connection to computer
  Serial.begin(9600);
  
  //Setup Bluetooth serial connection to android
  bluetooth.begin(115200);
  bluetooth.print("$$");
  delay(100);
  bluetooth.println("U,9600,N");
  bluetooth.begin(9600);
  
  m1.attach(6);
  m2.attach(9);
  m3.attach(10);
  m4.attach(11);
}


void loop()
{
   m1.writeMicroseconds(pos);
   m2.writeMicroseconds(pos);
   m3.writeMicroseconds(pos);
   m4.writeMicroseconds(pos);

  //Read from bluetooth and write to usb serial
  if(bluetooth.available())
  {
    // Reading one byte in at a time until reaching newline
    char byteIn = (char)bluetooth.read();
    
    if (byteIn != '\n') 
    {
      message += byteIn;
    } 
    else 
    {
      val = atoi(message.c_str());
      val = map(val, 0, 1000, 850, 2000); 
      
      if (val > 850 && val < 2000)
          pos = val;
      
      Serial.println(pos);
      message = "";
    }
  }
  
}

Additional information about my hardware:

Arduino Pro Mini board
Sparkfun BlueSmirf Gold bluetooth module
12A ESCs
2300KV motors
1300mAh 3S Battery

Thanks for any help!

Ryan

I just did a test, increasing and decreasing the speed in a loop and that worked fine -- the throttle transitioned smoothly. So it looks like I just need to optimize my code...I think I just need to find a more efficient way to send and receive the data.

You may need to check to see if the two below are compatible in the same code.

#include <Servo.h>
#include <SoftwareSerial.h>

zoomkat:
You may need to check to see if the two below are compatible in the same code.

#include <Servo.h>

#include <SoftwareSerial.h>

It turns out there are conflicts between the two libraries :frowning: . I removed that and switched my bluetooth module to pins 0 and 1, and now it works perfectly! I was using SoftwareSerial so that I could still read from the Arduino…from what I understand, it’s not possible to do this with another connection in the tx/rx pins because the USB is hard wired to them?

SoftwareSerial and Servo both use timer1 interrupts - you cannot use both. I suspect there's a hacked version of one or the other using timer2 you could track down.