Sending smaller signal to ESC

Hello all!

I'm currently trying to control a very large (65CC equivalent :o ) brushless motor (it is designed for RC airplanes), with my UNO. The motor has an excellent range of speed/power, but with any little bit too "throttle" the motor spins WAY too fast for my purposes. I would ideally like to create a code that allows me to control the power with a potentiometer, but have it limited so that even if the potentiometer is turned to "full" the motor still only turns at about ~20% (very rough estimate) "Throttle".

I am very new to coding, so I figured I'd try my luck at simply creating a test code to spin a RC car/truck motor (with a quite high KV rating), but am only able to get the motor to spin at very high throttle, and in reverse :confused: . I have attempted quite a few a few codes, and have not been able to get the motor spinning at a lower speed.

I should explain that I am doing my testing on this motor/esc combo, because I am rather afraid of setting the other motor (with so much speed and power) to 100% as it might take off some fingers..

#include <Servo.h>

Servo myservo;

void setup(){

  myservo.attach(6);
  delay(1);
  myservo.write(0);
}


void loop(){
  myservo.write(40);
}

Servo test code that might be of use. You can send various values to see how the ESC responds to various command values.

// zoomkat 12-25-13 serial servo test
// type servo position 0 to 180 in serial monitor
// or for writeMicroseconds, use a value like 1500
// Send an a to attach servo or d to detach servo
// for IDE 1.0.5 and later
// Powering a servo from the arduino usually *DOES NOT WORK*.

#include <Servo.h> 
String readString; //String captured from serial port
Servo myservo;  // create servo object to control a servo 
int n; //value to write to servo

void setup() {
  Serial.begin(9600);
  myservo.writeMicroseconds(1500); //set initial servo position if desired
  myservo.attach(7, 500, 2500);  //the pin for the servo control, and range if desired
  Serial.println("servo all-in-one test code 12-25-13"); // so I can keep track of what is loaded
  Serial.println();
}

void loop() {
  while (Serial.available()) {
    char c = Serial.read();  //gets one byte from serial buffer
    readString += c; //makes the string readString
    delay(2);  //slow looping to allow buffer to fill with next character
  }

  if (readString.length() >0) {
    Serial.println(readString);  //so you can see the captured string 

      // attach or detach servo if desired
    if (readString == "d") { 
      while (digitalRead(7)) {} //delay loop until pin 7 is low
      myservo.detach(); //detach servo
      Serial.println("servo detached");
      goto bailout; //jump over writing to servo
    }
    if (readString == "a") {
      myservo.attach(7); //reattach servo to pin 7
      Serial.println("servo attached");
      goto bailout;
    }    

    n = readString.toInt();  //convert readString into a number

    // auto select appropriate value
    if(n >= 500)
    {
      Serial.print("writing Microseconds: ");
      Serial.println(n);
      myservo.writeMicroseconds(n);
    }
    else
    {   
      Serial.print("writing Angle: ");
      Serial.println(n);
      myservo.write(n); 
    }

bailout: //reenter code loop
    Serial.print("Last servo command position: ");    
    Serial.println(myservo.read());
    Serial.println();
    readString=""; //empty for next input
  }
}

zoomkat:
Servo test code that might be of use. You can send various values to see how the ESC responds to various command values.

So what should I be adjusting exactly? Sorry, I'm quite overwhelmed by the code...

Below is some simpler code. Try sending between 45 and 135 or 1000 and 2000 from the serial monitor to see how the ESC responds. Have you successfully armed and had the ESC operate the motor?

// zoomkat 10-22-11 serial servo test
// type servo position 0 to 180 in serial monitor
// or for writeMicroseconds, use a value like 1500
// for IDE 0022 and later
// Powering a servo from the arduino usually *DOES NOT WORK*.

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

void setup() {
  Serial.begin(9600);
  myservo.writeMicroseconds(1500); //set initial servo position if desired
  myservo.attach(7, 500, 2500);  //the pin for the servo control, and range if desired
  Serial.println("servo-test-22-dual-input"); // so I can keep track of what is loaded
}

void loop() {
  while (Serial.available()) {
    char c = Serial.read();  //gets one byte from serial buffer
    readString += c; //makes the string readString
    delay(2);  //slow looping to allow buffer to fill with next character
  }

  if (readString.length() >0) {
    Serial.println(readString);  //so you can see the captured string 
    int n = readString.toInt();  //convert readString into a number

    // auto select appropriate value, copied from someone elses code.
    if(n >= 500)
    {
      Serial.print("writing Microseconds: ");
      Serial.println(n);
      myservo.writeMicroseconds(n);
    }
    else
    {   
      Serial.print("writing Angle: ");
      Serial.println(n);
      myservo.write(n);
    }
    Serial.print("Last servo command position: ");    
    Serial.println(myservo.read());
    readString=""; //empty for next input
  } 
}

zoomkat:
Below is some simpler code. Try sending between 45 and 135 or 1000 and 2000 from the serial monitor to see how the ESC responds. Have you successfully armed and had the ESC operate the motor?

Right, so upon using that code (I adjusted the writeMicroseconds to 1550 for this particular motor) and that got it spinning quickly, but not at a ludicrous rate. I did notice that the motor seemed quite jerky (compared to normally hooking the ESC to a RC radio). I'm not sure if that's the code, or my ESC just being stubborn.

Regarding this code, it seems to be awfully complicated (in comparison to that faulty code I posted in the main post), is there any way of simplifying it at all, or using a different code? I initially saw this video, and attempted using that code, but just got an "ISO C++ forbids declaration of 'setup' with no type" error

Below code is about as simple as it gets.

// zoomkat 7-30-10 serial servo test
// type servo position 0 to 180 in serial monitor
// for writeMicroseconds, use a value like 1500
// Powering a servo from the arduino usually *DOES NOT WORK*.

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);
    myservo.writeMicroseconds(n);
    //myservo.write(n);
    readString="";
  } 
}

Removing the prop saves fingers when testing.
you should be using the end use motor for your testing.
read up on the MAP command.
You can then adjust the PWM values to the correct range for the signal level from the pot.

Well, upon the advice/aid of zoomkat (and, Michal Rinott's potentiometer servo code) I believe I've made my final code: (some numbers need to be experimented with based on the demands of my ESC/Motor, but this is the general idea)

#include <Servo.h> 
 
Servo myservo;  // create servo object to control a servo 
 
int potpin = 0;  // analog pin used to connect the potentiometer
int val;    // variable to read the value from the analog pin 
 
void setup() 
{ 
  myservo.attach(6);  // attaches the servo on pin 9 to the servo object 
} 
 
void loop() 
{ 
  val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023) 
  val = map(val, 0, 1023, 1450, 1500);     // scale it to use it with the servo (value between stopped/engage point and top speed setting) 
  myservo.writeMicroseconds(val);    // turns motor to set value (from above)
  delay(1);                           // slight delay
}