Is there any way to continuously write a varying values to a motor?

Hey guys,

I am currently working on a project that requires me to vary the speed of a brushless DC motor randomly. I have chosen to vary the speed by using random numbers, where I have a range of values and in the lower half of the range, the motor spins at a specific speed and in the upper half it spins at a different speed. The problem I am having is that when the code runs, between each cycle of the loop, the motor stops spinning because no value is being written to it, is there anyway that I can keep the motor spinning between loop cycles. here's the code:

#include <Servo.h>
Servo ESC1;

int pos = 0; //Sets position variable
int speed = 30; // Sets speed value

void arm(){
setSpeed(0); //Sets speed variable
}

//this function sets the speed of the motor
void setSpeed(int speed){
int angle = map(speed, 0, 100, 0, 180); //Sets servo positions to different speeds
ESC1.write(angle);
}

void setup() {
Serial.begin(9600);
srand(2); // seeds random generator

ESC1.attach(9);
}

void loop() {
while(millis() > 0){ //loop continues as there is power supply//
int randNum = rand() % 11; // generates a number between 0 and 10 //
int speedTime = random(2500, 7000); // speed delay variable set between 2.5 and 7 seconds //
//int speed = 30;
setSpeed(speed);
Serial.println((speed + 1));
Serial.println(randNum);
delay(1000);

if(randNum <= 5){ // speed ups motor to a low rpm in 0-5 range //
for (speed = 30; speed <= 50; speed += 5){
setSpeed(speed);
Serial.println(speed);
delay(500);
}
}
else{
for (speed = 30; speed <= 70; speed += 5){ // speeds up motor in 6-10 range //
setSpeed(speed);
Serial.println(speed);
delay(500);
}
}
delay(speedTime); // holds this speed for the length of the time delay variable //
while(speed < 30){
speed += 5; //maybe try explicitly changing speed to 30.
setSpeed(speed);
Serial.println(speed);
delay(500);
}
while(speed > 30){
speed -= 5; //maybe try explicitly changing speed to 30.
setSpeed(speed);
Serial.println(speed);
delay(500);
}

}
}

void loop() {   
    while(millis() > 0){                            //loop continues as there is power supply//

What do you suppose that the first line does, then?

Creating an infinite loop inside an infinite loop() suggests that you don't have a clue.

     int randNum = rand() % 11;                     // generates a number between 0 and 10 //

So does

int randNum = rand(0, 11);

but at a far lower cost in terms of speed and resources. RTFM.

     setSpeed(speed);
     Serial.println((speed + 1));

Use one value. Print another value. What have you learned? Not a damned thing.

The problem I am having is that when the code runs, between each cycle of the loop, the motor stops spinning because no value is being written to it

Wrong. A value IS being written, but that value is 0.

is there anyway that I can keep the motor spinning between loop cycles.

Yes. Stop spinning the motor down to a stop. It's YOUR code that is making that happen.

Id actually want help and not somebody trying to be a smart mouth, I have serial printed the values to see what the motor is doing and at no point is there a zero being written to the motor, the problem comes between the loops. Is there anything that you know that can be done?

Hi syoung96943,

If you're using an Arduino Uno you could try using hardware PWM to drive your ESC. The hardware PWM works independently of the processor, so will continue to whirr away with an output signal even if your sketch is held up.

The following code sets up hardware PWM on pins 9 and 10 on the Arduino Uno and uses the 16-bit timer 1. It's been written for servos, but works just as well with ESCs and allows you to load the OCR1x registers with a value between 1000 and 2000, just like the servo library's writeMicroseconds() function.

I guess the actual minimum and maximum values will depend on how your ESC is calibrated, (usually around 1100 minimum through to 1900 maximum), but in this example I've loaded the OCR1A (for D9) or OCR1B (for D10) registers with 1000 = min throttle, 1500 = mid throttle and 2000 = max throttle.

If you want to run the ESC's PWM signal at a higher frequency, say 400Hz, just change the ICR1 register from 20000 to 2500.

// Set-up hadware PWM on the Arduino UNO 50Hz on pins 9 and 10
void setup() { 
  // Initialise timer 1 for phase and frequency correct PWM
  pinMode(9, OUTPUT);                         // Set digital pin 9 (D9) to an output
  pinMode(10, OUTPUT);                        // Set digital pin 10 (D10) to an output
  TCCR1A = _BV(COM1A1) | _BV(COM1B1);         // Enable the PWM outputs OC1A, and OC1B on digital pins 9, 10
  TCCR1B = _BV(WGM13) | _BV(CS11);            // Set phase and frequency correct PWM and prescaler of 8 on timer 1
  ICR1 = 20000;                               // Set the PWM frequency to 50Hz
  OCR1A = 1500;                               // Centre the servo on D9
  OCR1B = 1500;                               // Centre the servo on D10
}

void loop() {
  OCR1A = 1000;                               // Move the servo to min position on D9  
  OCR1B = 1000;                               // Move the servo to min position on D10
  delay(1000);                                // Wait for 1 second
  OCR1A = 2000;                               // Move the servo to max position on D9
  OCR1B = 2000;                               // Move the servo to max position on D10
  delay(1000);                                // Wait for 1 second
}

thank a lot, I will try this and let you know how it goes