Motor Control without delay

Hey folks,

trying to build a school project and was having some trouble with my code. My problem is I wanna run some vibration motors and leds at the same time. I have read through the blink without delay example and tried enacting a few different lines of code, but then things start screwing up. Also I need to execute a time out function. So my code will run for say 15 minutes and then stop. How could I do that?

I have declared a couple functions but anytime I try to remove the delay on the motors it messes up. I tried using an incrementing variable for delay and that still fails. Anyone else know of a way to fix this?

const int intensityLow = 0;
const int intensityHigh = 1024;
const int timerLow = 0;
const int timerHigh = 1024;

int musicPin = 24;
int redPin = A8, greenPin = A9, bluePin = A10;

long currentMillis = millis();
long previousMillis = 0;
long interval = 1000;
int i=1;
int j=0;

void setup() {
  
  //Setup Channel A
  pinMode(12, OUTPUT); //Initiates Motor Channel A pin
  pinMode(9, OUTPUT);  //Initiates Brake Channel A pin

  //Setup Channel B
  pinMode(13, OUTPUT); //Initiates Motor Channel A pin
  pinMode(8, OUTPUT);  //Initiates Brake Channel A pin
  
  pinMode(redPin, OUTPUT);     // Sets Red (A8) as an output
  pinMode(greenPin, OUTPUT);   // Sets Green (A9) as an ouput
  pinMode(bluePin, OUTPUT);    // Sets Blue (A10) as an output
}



void loop(){
  
      doAllLoops();

}

void lightControl(){
  
  digitalWrite(musicPin, HIGH);
  
  if(currentMillis - previousMillis > interval){
     i++;
    previousMillis = currentMillis;
   
  }
  
  if(i==7) i = 1;
    if(i==1) setColor(255, 0, 0);      // Red
    if(i==2) setColor(0, 255, 0);      // Gree
    if(i==3) setColor(0, 0, 255);      // Blue
    if(i==4) setColor(255, 255, 0);    // Red + Green
    if(i==5) setColor(0, 255, 255);    // Green + Blue
    if(i==6) setColor(255, 0, 255);    // Red + Blue
}

 void sensorControl(){

 }   
     
 void motorControl(){
   
    int intensityRead = analogRead(A0); 
    int intensity = map(intensityRead, intensityLow, intensityHigh, 0,3);

   
  switch (intensity) {
    case 0:
      //Motor A forward @ full speed
      digitalWrite(12, HIGH);  //Establishes backward direction of Channel A
      digitalWrite(9, LOW);    //Disengage the Brake for Channel A
      analogWrite(3, 100);     //Spins the motor on Channel A at half speed
      //Motor B forward @ full speed
      digitalWrite(13, HIGH);  //Establishes forward direction of Channel B
      digitalWrite(8, LOW);    //Disengage the Brake for Channel B
      analogWrite(11, 255);    //Spins the motor on Channel B at full speed
      
      Serial.println("No Time");
      delay(3000);
  
      digitalWrite(9, HIGH);   //Engage the Brake for Channel A
      
      delay(1000);
      break;
      
    case 1:
      
       //Motor A forward @ full speed
      digitalWrite(12, HIGH);  //Establishes backward direction of Channel A
      digitalWrite(9, LOW);    //Disengage the Brake for Channel A
      analogWrite(3, 255);     //Spins the motor on Channel A at half speed
      //Motor B forward @ full speed
      digitalWrite(13, HIGH);  //Establishes forward direction of Channel B
      digitalWrite(8, LOW);    //Disengage the Brake for Channel B
      analogWrite(11, 255);    //Spins the motor on Channel B at full speed
      
      Serial.println("Time 1");
      delay(3000);
  
      digitalWrite(9, HIGH);   //Engage the Brake for Channel A
      
      delay(1000);
      break;
   
    case 2:
    
       //Motor A forward @ full speed
      digitalWrite(12, HIGH);  //Establishes backward direction of Channel A
      digitalWrite(9, LOW);    //Disengage the Brake for Channel A
      analogWrite(3, 255);     //Spins the motor on Channel A at half speed
      //Motor B forward @ full speed
      digitalWrite(13, HIGH);  //Establishes forward direction of Channel B
      digitalWrite(8, LOW);    //Disengage the Brake for Channel B
      analogWrite(11, 255);    //Spins the motor on Channel B at full speed
      
      Serial.println("Time 2");
      delay(3000);
  
      digitalWrite(9, HIGH);   //Engage the Brake for Channel A
  
      delay(1000);
      break;
      
    case 3:
    
       //Motor A forward @ full speed
      digitalWrite(12, HIGH);  //Establishes backward direction of Channel A
      digitalWrite(9, LOW);    //Disengage the Brake for Channel A
      analogWrite(3, 255);     //Spins the motor on Channel A at half speed
      //Motor B forward @ full speed
      digitalWrite(13, HIGH);  //Establishes forward direction of Channel B
      digitalWrite(8, LOW);    //Disengage the Brake for Channel B
      analogWrite(11, 255);    //Spins the motor on Channel B at full speed
  
      Serial.println("Time 3");
      delay(3000);
  
      digitalWrite(9, HIGH);   //Engage the Brake for Channel A
  
      delay(1000);
      break;
      
  }
}
   void setColor(int red, int green, int blue){
    analogWrite(redPin, 255-red);
    analogWrite(greenPin, 255-green);
    analogWrite(bluePin, 255-blue);
  }
  
   void doAllLoops(){
     lightControl();
     sensorControl();
     motorControl();
   }

You seem to run your motors, then do a delay() and then apply the brake. Obviously if you remove that delay the program will jump instantly from full speed to brake.

You should probably store the time (millis()) as soon as the motor starts and then only apply the brake if a suitable period has elapsed after the start time. For exampl (pseudo code)

motorStartTime = millis()

if (millis() - motorStartTime) > 3000 {
   apply brake
   motorStartTime = 0
}

However you will also need to record the fact that the motor is running so that you can skip the motor start code unless it is necessary. You could probably use "if motorStartTime = 0" for that.

...R

I pulled the code out by itself and got it to work finally, but now my light function isn't working. Could this be a scope issue? If so how do I fix it? Here is my new code. Got rid of the switch case cause i'm not gonna use it anymore. Plus I think this will make it eaier to get everything working.

int motorPinA = 12, brakePinA = 9, motorPinB = 13, brakePinB = 8;
int redPin = A8, greenPin = A9, bluePin = A10;
int musicPin = 24;

int brakeState = LOW;

long interval = 1000;
long previousMillis = 0;

void setup() {
  
  unsigned long currentMillis = millis();
  //Setup Channel A
  pinMode(motorPinA, OUTPUT); //Initiates Motor Channel A pin
  pinMode(brakePinA, OUTPUT); //Initiates Brake Channel A pin
  pinMode(motorPinB, OUTPUT); //Initiates Motor Channel B pin
  pinMode(brakePinB, OUTPUT); //Initiates Brake Channel B pin
  
  pinMode(redPin, OUTPUT);     // Sets Red (A8) as an output
  pinMode(greenPin, OUTPUT);   // Sets Green (A9) as an ouput
  pinMode(bluePin, OUTPUT);    // Sets Blue (A10) as an output
}

void loop(){
   doControlLoops();
}

void motorControl(){
  
      unsigned long currentMillis = millis();
      digitalWrite (motorPinA, HIGH);  //Establishes forward direction of Channel A
      analogWrite(3,255);    //Spins the motor on Channel A at half speed
 
      if(currentMillis - previousMillis >= interval){
        previousMillis = currentMillis;
      
      if(brakeState == LOW) brakeState = HIGH;
      else brakeState = LOW;
      
      digitalWrite(brakePinA, brakeState);
      }      
      
}
void lightControl(){
  
  unsigned long currentMillis = millis();
  digitalWrite(musicPin, HIGH);
  
  long previousMillis = 0;
  int i = 0;
  
  if(currentMillis - previousMillis >= interval){
     i++;
    previousMillis = currentMillis;   
  }
    if(i==1) setColor(255, 0, 0);      // Red
    if(i==2) setColor(0, 255, 0);      // Gree
    if(i==3) setColor(0, 0, 255);      // Blue
    if(i==4) setColor(255, 255, 0);    // Red + Green
    if(i==5) setColor(0, 255, 255);    // Green + Blue
    if(i==6) setColor(255, 0, 255);    // Red + Blue
    if(i==7) i = 1;
    
   //Motor B forward @ full speed
    digitalWrite(motorPinB, HIGH);  //Establishes forward direction of Channel B
    digitalWrite(brakePinB, LOW);    //Disengage the Brake for Channel B
    analogWrite(11, 255);    //Spins the motor on Channel B at full speed
}
  void setColor(int red, int green, int blue){
    analogWrite(redPin, 255-red);
    analogWrite(greenPin, 255-green);
    analogWrite(bluePin, 255-blue);
  }
  
 void doControlLoops(){
      motorControl();
      lightControl();
 }

Its a bit cleaner I think. Also could there be an issue with using the same variables for the timing. I tried others but it didn't seem to fix anything.

currentMillis isn't changing with time. Change all your currentMillis to millis().
millis() IS the current time and is updated every millisecond.
Once set, currentMillis doesn't change with time, only when you reset it.

Um. I think that may be OK. I think currentMillis gets set each time you enter the motorControl() or the lightControl() function (unless you declare it static, which you didn't) and it doesn't need to change.