Arduino doesn't write to ESC

Hello,

We tried to make a test controller which if we are done should statbilize our quadcopter(we’re nowhere near done so don’t mind that it’s incomplete), but when we tried making one we ran into a problem in the beginning. Our corrected(m0,m1,m2,m3) value doesn’t write to our ESC for some reason (the write is in the flightcontroller). We thought it was because the value we try to write changes to fast but we made a delay and that didn’t work either. So we hope some of you have an idea of why it doesn’t write to the ESC.

The code is in the attachment and thank you for your time.

project.rar (5.49 KB)

All that code to test writing to the ESC? I, for one, am not going to bother wading through hundreds of lines of code to see what you are doing wrong, when there shouldn't be more than 20 lines of code to test the ESC.

Oww sorry i thought it would be more clear this way but the only thing that does the actual writing is

float MotorVoltagePitch;
float MotorVoltageRoll;
void PController(){
  
 //calculate the motorvoltage vor the Pitch axis
 float pitchDegree = buffer[1]*radToDeg; //making degrees from the measured radials
 pitchDegree = pitchDegree - Gyro_Offset_Pitch;
 float pitcherror = AngleSet - pitchDegree; //calculating the offset to the desired position (0.0 degrees to stay balanced)
 float ScaleErrorPitch = pitcherror * Kppitch; //calculating how much the motor need to compensate 
 MotorVoltagePitch = ScaleErrorPitch; //adding the scaleerror to the stable voltage (which makes the quadcopter stable)



  //calculate the motorvoltage vor the roll axis.
  //Works the same as P for the pitch
 float rollDegree = buffer[2]*radToDeg;
 rollDegree=rollDegree-Gyro_Offset_Roll;
 float rollerror = AngleSet - rollDegree;
 float ScaleErrorRoll = rollerror * Kproll;
 MotorVoltageRoll = -ScaleErrorRoll;



  float m0speed = MotorVoltageRoll + MotorVoltagePitch + StableVoltage; 
  float m1speed = -MotorVoltageRoll + MotorVoltagePitch + StableVoltage;
  float m2speed = MotorVoltageRoll - MotorVoltagePitch + StableVoltage;
  float m3speed = -MotorVoltageRoll - MotorVoltagePitch + StableVoltage;


 motor0.write(m0speed);
 motor1.write(m1speed);
 motor2.write(m2speed);
 motor3.write(m3speed);

 #ifdef debug_led
 digitalWrite(ledp,HIGH);
 delay(500);
 digitalWrite(ledp,LOW);
 delay(500);
 #endif


  
 #ifdef debug_mvp
 Serial.print(MotorVoltagePitch);
 Serial.print("\t");
 Serial.print(pitchDegree);
 Serial.print("\t");
 Serial.print(pitcherror);
 Serial.print("\t");
 Serial.print(ScaleErrorPitch);
 Serial.print("\t");
 #endif

 #ifdef debug_mvr
 Serial.print(MotorVoltageRoll);
 Serial.print("\t");
 Serial.print(rollDegree);
 Serial.print("\t");
 Serial.print(rollerror);
 Serial.print("\t");
 Serial.println(ScaleErrorRoll);
 #endif

 #ifdef debug_motor_speeds
 Serial.print(m0speed);
 Serial.print("\t");
 Serial.print(m1speed);
 Serial.print("\t");
 Serial.print(m2speed);
 Serial.print("\t");
 Serial.println(m3speed);

 #endif

}

Some ESCs require calibration, and will not arm until that is complete. Read this page, especially this section. http://copter.ardupilot.com/wiki/initial-setup/esc-motor/#About_ESC_Calibration

That is STILL way to much code. How many ESC's do you have? Do ANY of them work?

If any of them work, then it is one thing to determine why the other(s) don't work.

If none of them work, then write a SIMPLE sketch to control ONE ESC. Do NOT try to write a sketch to control all FOUR of them.

We know that the ESC's work when we used our Radio Controller to just write throttle to them then it works just fine and when we try to use the current code then the arming works fine as well.

I can't open a rar file from the computer I am on now, so I am guessing here.

If I understand this correctly, your Arduino sends the ESC control signals to a radio controller that relays the data to the quadcopter. Is that correct? If so, you should post a link to the radio controller and the motor library you are using. These functions are in a library, correct?

 motor0.write(m0speed);
 motor1.write(m1speed);
 motor2.write(m2speed);
 motor3.write(m3speed);

motor0 to 3 are Servo instances.

Thanks, Paul. So the Arduino is on the quadcopter? If that is true, why send a float data type to those calls? Just curious. The Servo library uses an integer data type.

SurferTim: Thanks, Paul. So the Arduino is on the quadcopter? If that is true, why send a float data type to those calls? Just curious. The Servo library uses an integer data type.

Yes the arduino is on the quadcopter. We thought we should sent a float because it is more accurate, and probably produce a more fluent move of the quadcopter. We have tried it with an integer instead of a float, but the motors still dont move. You hear a "beep" from the ESC when we arm it and when the values of the m0speed/m1speed.......... flow in the serial monitor. Maybe it just writes for a very short duration and then stops (because of the beeps) (?) The xxxx.write(angle) is from the servo library, because ESC's take servo signals

EDIT: we are using a quadcopter on the quadcopter and we have a "rc toys" receiver+transmitter from hobbyking : https://www.hobbyking.com/hobbyking/store/uh_viewItem.asp?idProduct=9041 But we have not yet implemented any throttle in the mxspeed, we are just using the output signals from the IMU to let the motors rotate. ESC's we are using: https://www.hobbyking.com/hobbyking/store/__25364__Turnigy_Multistar_20_Amp_Multi_rotor_Brushless_ESC_2_4S.html

It requires an integer data type. If you are using the Servo.write() function, the value sent must be from 0 to 180, representing the degrees of rotation required.

If you want to send the value in microseconds, use the Servo.writeMicroseconds() function.

We thought we should sent a float because it is more accurate, and probably produce a more fluent move of the quadcopter.

The function expects an int. It will truncate the value you specify as a float to an int, so your perception of more accuracy is incorrect.

zazakra:
We know that the ESC’s work when we used our Radio Controller to just write throttle to them then it works just fine and when we try to use the current code then the arming works fine as well.

You may need to factor in that most RC equipment probably only uses the equivalent servo position commands for ~45-135 degrees, not 0-180. If you have successfully calibrated and operated the ESC using RC gear, then try staying in the 45-135 deg band when sending command values from the arduino. Below is some simple servo test code that can be used with the serial monitor for testing.

edit: note that for safety reasons most ESCs require an arming sequence prior to being able to control the motor.

// zoomkat 7-30-10 serial servo test
// type servo position 0 to 180 in serial monitor

String readString;
#include <Servo.h> 
Servo myservo;  // create servo object to control a servo 

void setup() {
  Serial.begin(9600);
  myservo.attach(9);
}

void loop() {

  while (Serial.available()) {

    if (Serial.available() >0) {
      char c = Serial.read();  //gets one byte from serial buffer
      readString += c; //makes the string readString
      delay(3);
    } 
  }

  if (readString.length() >0) {
    Serial.println(readString);
    int n = readString.toInt();
    Serial.println(n); //print to serial monitor for debug
    myservo.write(n);
    readString="";
  } 
}

If you are using this as a stabilizer (modifying the servo pulse length), then the Arduino is probably reading the length of the servo pulse (edit: sent by the radio), then adding or subtracting from that a small amount for stabilization. That would most likely be in microseconds, not degrees of rotation. .

That would most likely be in microseconds, not degrees of rotation.

I think the use of "degrees" is just a shell as used in the servo library, and is mapped to the equivalent in us values.

You are correct, zoomkat. But if the Arduino is measuring the input pulse length in microseconds from the radio, then adding or subtracting from that value without converting the result in microseconds to degrees, then the modified value will be in microseconds, not degrees.

I could be wrong. I could not unpack the rar file with the entire sketch.

This is similar to anther thread here. The basic question is still the same - how does ESC operates using Servo library which expects int in range 540 and up to somewhere 2000 plus? ( The actual numbers are immaterial for discussion ). For example - how are these values converted to direction of the motor? I really have to ask this, like it or not - do you RC guys know anything about datasheets / device specification etc.? Or are you literary flying by the seat of your pants? Sure looks that way. No offence , OK.

Cheers Vaclav

Thanks, Vaclav. Your input is appreciated. Your questions are what we are trying to figure out. If the Arduino is measuring the input pulse in microseconds, then adding or subtracting a small amount for stabilization, then sending that value to the servo function without converting it to degrees, then the Servo.writeMicroseconds() function should be used, not the Servo.write() function.

Like I said before, I can't see the entire sketch due to the inability to unpack a rar file with the computer I am using. I could be wrong. If I am, please point out where that would be.

Thanks! Tim :)

For example - how are these values converted to direction of the motor?

An ESC for a quadcopter wouldn't need (or want) direction control.

Just a thought. ;)

just to be clear: we arent using the Radio signals yet, we are just using a p controller to stabilize the quadcopter with a gyroscope. I changed the "stable voltage"(just some random voltage we added to the m0speed so we could see it turn and maybe even hover) to 50 so it would be between 45/135, but the motors still wont rotate. xxxx.write does work, as we tested with the RX and some other sketches.