Delay gone, Millis in

Hello,

Merry Christmas , Happy Holidays !!!

Can anyone show me how or what I need to do with this sketch to get rid of the Delay function and use Millis instead…

The sketch runs as written, but the delay is an issue when trying to set the train speed…

I know a little about the “blink without delay” but I can’t rap my head around reading the Pot and making a Millis routine to set the delay time…

Thanks

Back_and_Forth_Train.txt (2.53 KB)

The first thing to do is to post your code here (using code tags) rather than attaching it.

#include <AFMotor.h>

AF_DCMotor Motor1(1);
int speed = 0; //preset the speed to 0
const int IRD_A = 22; //Infrared detector at track end  North
const int IRD_B = 23; //Infrared detector at track end  South
const int LED = 53; //Indicates detector trip
const int Speed_Pot = A13; //potentiometer for Speed control of train motion
const int Delay_Pot = A15; //potentiometer for Delay control of train motion
boolean ignore_detector_a = false; //Set IRD to FALSE to start
boolean ignore_detector_b = false; //SET IRD to FALSE to start
int Speed_val = 0; //Clear the Speed_val variable
int Delay_val = 0; //Clear the Delay variable
int Speed_val_C = 25;

void setup()
{
  Serial.begin(9600);
  pinMode (IRD_A, INPUT); //IRD pin set to INPUT
  pinMode (IRD_B, INPUT); //IRD pin set to INPUT
  pinMode (LED, OUTPUT); //LED pin set to OUTPUT
  pinMode (Speed_Pot, INPUT); //Speed potentiometer pin set to INPUT
  pinMode (Delay_Pot, INPUT); //Speed potentiometer set to INPUT
  digitalWrite(22, LOW); //Reset IRD pin to LOW
  digitalWrite(23, LOW); //Reset IRD pin to LOW

}


void loop() {
  //Speed_val_C = (Speed_val, Speed_val <= 24, Speed_val = 25);
  Speed_val = analogRead(Speed_Pot); //Read the Delay_Pot to obtain the Speed_val
  Delay_val = analogRead(Delay_Pot); //Read the Delay_Pot to obtain the  delay_val
  Serial.println(Speed_val_C);
  {
    // Read the Infrared detectors, If the A is blocked and B is not blocked, Stop the train (RELEASE, BRAKE),
    // Delay the direction change by the Delay_val, then send train North (SetSpeed, FORWARD)

    int ir_detected = LOW;
    if (!ignore_detector_a) {
      ir_detected = digitalRead(IRD_A);
      if (ir_detected) {
        ignore_detector_a = true;
        ignore_detector_b = false;
        Motor1.run(RELEASE);
        Motor1.run(BRAKE);
        delay(Delay_val * 30);
        speed = Speed_val/4 ;
        Motor1.setSpeed (speed) ;
        Motor1.run(FORWARD);

      }
      // Read the Infrared detectors, If the B is blocked and A is not blocked, Stop the train (RELEASE, BRAKE),
      // Delay the direction change by the Delay_val, then send train South (SetSpeed, FORWARD)
    } else if (!ignore_detector_b) {
      ir_detected = digitalRead(IRD_B);
      if (ir_detected) {
        ignore_detector_b = true;
        ignore_detector_a = false;
        Motor1.run(RELEASE);
        Motor1.run(BRAKE);
        delay(Delay_val * 30);
        speed = Speed_val/4 ;
        Motor1.setSpeed (speed) ;
        Motor1.run(BACKWARD);


      }
    }
  }
}

Your code was small enough to simply post here:

#include <AFMotor.h>

AF_DCMotor Motor1(1);
int speed = 0; //preset the speed to 0
const int IRD_A = 22; //Infrared detector at track end  North
const int IRD_B = 23; //Infrared detector at track end  South
const int LED = 53; //Indicates detector trip
const int Speed_Pot = A13; //potentiometer for Speed control of train motion
const int Delay_Pot = A15; //potentiometer for Delay control of train motion
boolean ignore_detector_a = false; //Set IRD to FALSE to start
boolean ignore_detector_b = false; //SET IRD to FALSE to start
int Speed_val = 0; //Clear the Speed_val variable
int Delay_val = 0; //Clear the Delay variable
int Speed_val_C = 25;

void setup()
{
  Serial.begin(9600);
  pinMode (IRD_A, INPUT); //IRD pin set to INPUT
  pinMode (IRD_B, INPUT); //IRD pin set to INPUT
  pinMode (LED, OUTPUT); //LED pin set to OUTPUT
  pinMode (Speed_Pot, INPUT); //Speed potentiometer pin set to INPUT
  pinMode (Delay_Pot, INPUT); //Speed potentiometer set to INPUT
  digitalWrite(22, LOW); //Reset IRD pin to LOW
  digitalWrite(23, LOW); //Reset IRD pin to LOW

}


void loop() {
  //Speed_val_C = (Speed_val, Speed_val <= 24, Speed_val = 25);
  Speed_val = analogRead(Speed_Pot); //Read the Delay_Pot to obtain the Speed_val
  Delay_val = analogRead(Delay_Pot); //Read the Delay_Pot to obtain the  delay_val
  Serial.println(Speed_val_C);
  {
    // Read the Infrared detectors, If the A is blocked and B is not blocked, Stop the train (RELEASE, BRAKE),
    // Delay the direction change by the Delay_val, then send train North (SetSpeed, FORWARD)

    int ir_detected = LOW;
    if (!ignore_detector_a) {
      ir_detected = digitalRead(IRD_A);
      if (ir_detected) {
        ignore_detector_a = true;
        ignore_detector_b = false;
        Motor1.run(RELEASE);
        Motor1.run(BRAKE);
        delay(Delay_val * 30);
        speed = Speed_val/4 ;
        Motor1.setSpeed (speed) ;
        Motor1.run(FORWARD);

      }
      // Read the Infrared detectors, If the B is blocked and A is not blocked, Stop the train (RELEASE, BRAKE),
      // Delay the direction change by the Delay_val, then send train South (SetSpeed, FORWARD)
    } else if (!ignore_detector_b) {
      ir_detected = digitalRead(IRD_B);
      if (ir_detected) {
        ignore_detector_b = true;
        ignore_detector_a = false;
        Motor1.run(RELEASE);
        Motor1.run(BRAKE);
        delay(Delay_val * 30);
        speed = Speed_val/4 ;
        Motor1.setSpeed (speed) ;
        Motor1.run(BACKWARD);


      }
    }
  }
}

Changing from delay() to millis() is not just a matter of switching a couple of lines of code. It is a matter, in this case, of completely rewriting the program. On any given pass through loop(), the program is in some state (train is moving, train is stopped, etc.). There may be things that have changed since the last pass through loop(), such as a user pressing a switch, the train having blocked a sensor, or having unblocked one, that change what state the program is in. Enough time might have passed (the train stopped for three seconds) that a change in state is warranted.

You need to separate the change detection code from the change transition code and the what do I do in this state code. Your code will look like this:

int state;

void loop()
{
   detectStateChanges();
   implementStateChange();
   implementState();
}

I think it should be fairly apparent which part of the existing code goes in which function.

Using an enum to assign names to states makes it more obvious what each state means, rather than using an int, but if you document what each state number means, in a small application it doesn’t really matter.

Thanks…

I will make another attempt at the “unknown”… More learning to be done on my part…