Questions about millis() and running four functions

Hello,

Thank you for taking the time to read my post. I am quite new to arduino and programming as a whole.

I’m working on a device to bleed the early ABS unit in my 1995 Toyota Land Cruiser. Unfortunately there is a now discontinued and very expensive tool to do so, or one finds some dirt road and gets the ABS to actuate to bleed by intentionally getting the brakes to lock up. The skid to get it to actuate doesn’t work all that well, and really requires multiple trips to the dirt to activate and then return home to bleed again.

The factory tool simply cycles the pump and activates the solenoids, consequently, seemed like a reasonably simple arduino project.

I don’t have an overall schematic for the project, but I am breadboarding it with LEDs w/330 Ohm resistors in series), and normally open pushbuttons pulling circuit low-(INPUT_PULLUP). Eventually, the Arduino Nano will drive 4 IRL540s. One will activate a 30A relay and cycle the pump for the desired time. The other three IRL540s will drive the solenoids by switching the solenoid grounds.

Button Functions:
PumpButtonPin: When depressed and released, this will run the pump( switch onPumpLEDPin) for 2000 milliseconds. Only 2 “state changes” so press and release button will result in pump being turned on (LED lit on breadboard for now) for 2 seconds, with no repeat.

FLButtonPin: When depressed and released, this will cycle the Front Left solenoid(switch on FLLEDPin) for X milliseconds, X number of times. Currently, I would like to have the duty cycle be 500 milliseconds, and repeat 5 times(10 state changes) and then stop in the off position.

FRButtonPin: When depressed and released, this will cycle the Front Right solenoid(switch on FRLEDPin) for X milliseconds, X number of times. Currently, I would like to have the duty cycle be 500 milliseconds, and repeat 5 times(10 state changes) and then stop in the off position.

RRButtonPin: When depressed and released, this will cycle the Rear solenoid(switch on RRLEDPin) for X milliseconds, X number of times. Currently, I would like to have the duty cycle be 500 milliseconds, and repeat 5 times(10 state changes) and then stop in the off position.

The button pushes are dependent on which hydraulic brake circuit I am bleeding and do not require any sequencing based on other button pushes. I might for example want to run the pump 3 times, then cycle the FL solenoid, and then bleed that circuit. After that, I might not opt run the pump and instead just activate the FR solenoid and bleed. In effect, would like to operate any button at any time. Given the short nature of the actions for any button push, I don’t think I need to worry about what happens if I push the PumpButtonPin and immediately push the FLButtonPin, butideally both sequences would continue to execute, which does seem to happen currently, but see problem below.

Problem:
I borrowed some code from some millis() examples and apparently made a mess out of it by adding the extra inputs, code and outputs; as I can get the PumpButtonPin(the first sequence in the loop) to function mostly as desired, but I get undesired random results from the three other Buttons. FLButtonPin, FRButtonPin and RRButtonPin will sometimes flash the respective output 5 times as desired, but other times seem to follow the pump sequence and flash on for 2 seconds and turn off.

A minor, but not serious issue is related to the PumpButtonPin. There seems to be a delay in turning on the related output equal to the length of the desired on state; 2 seconds. Not sure what I did wrong to have that happen…

In my very limited programming experience(barely beginning to understand old 68HC11 code) it seems like a loop to poll the 4 switches, with jumps to section of code for the specific button function output would make the most sense, but I have no idea how to do that…

Anyhow, here is the code as loaded to the IDE:

const byte PumpButtonPin = 2;
const byte FLButtonPin = 3;
const byte FRButtonPin = 4;
const byte RRButtonPin = 5;
const byte PumpLEDPin = 9;
const byte FLLEDPin = 10;
const byte FRLEDPin = 11;
const byte RRLEDPin = 12;
unsigned long PumpstartTime;
unsigned long FLstartTime;
unsigned long FRstartTime;
unsigned long RRstartTime;
unsigned long Pumpperiod = 2000;
unsigned long Solenoidperiod = 500;
boolean Pumpflashing = false;
boolean FLflashing = false;
boolean FRflashing = false;
boolean RRflashing = false;
byte Pumpcount = 0;
byte FLcount = 0;
byte FRcount = 0;
byte RRcount = 0;
byte previousPumpButtonState;
byte previousFLButtonState;
byte previousFRButtonState;
byte previousRRButtonState;

void setup()
{
  Serial.begin(115200);
  pinMode(PumpLEDPin, OUTPUT);
  pinMode(FLButtonPin, OUTPUT);
  pinMode(FRButtonPin, OUTPUT);
  pinMode(RRButtonPin, OUTPUT);
  pinMode(PumpButtonPin, INPUT_PULLUP);
  pinMode(FLButtonPin, INPUT_PULLUP);
  pinMode(FRButtonPin, INPUT_PULLUP);
  pinMode(RRButtonPin, INPUT_PULLUP);
  digitalWrite(PumpLEDPin, LOW);
  digitalWrite(FLLEDPin, LOW);
  digitalWrite(FRLEDPin, LOW);
  digitalWrite(RRLEDPin, LOW);
}

void loop()
{
  ////////////////////////////////////////////////////////////////////////////////////////
  //PumpSequence//
  if (!Pumpflashing)
  {
    byte currentPumpButtonState = digitalRead(PumpButtonPin);
    if (currentPumpButtonState != previousPumpButtonState && currentPumpButtonState == LOW)
    {
      Pumpflashing = true;
      Pumpcount = 0;
      PumpstartTime = millis();
    }
    previousPumpButtonState = currentPumpButtonState;
  }
  else
  {
    unsigned long PumpcurrentTime = millis();
    if (PumpcurrentTime - PumpstartTime >= Pumpperiod)
    {
      digitalWrite(PumpLEDPin, !digitalRead(PumpLEDPin));
      PumpstartTime = PumpcurrentTime;
      Pumpcount++;
      if (Pumpcount == 2)
      {
        Pumpflashing = false;
        digitalWrite(PumpLEDPin, LOW);
      }
    }
  }
  //////////////////////////////////////////////////////////////////////////////////////////
  //FL Solenoid Sequence//
  if (!FLflashing)
  {
    byte currentFLButtonState = digitalRead(FLButtonPin);
    if (currentFLButtonState != previousFLButtonState && currentFLButtonState == LOW)
    {
      FLflashing = true;
      FLcount = 0;
      FLstartTime = millis();
    }
    previousFLButtonState = currentFLButtonState;
  }
  else
  {
    unsigned long FLcurrentTime = millis();
    if (FLcurrentTime - FLstartTime >= Solenoidperiod)
    {
      digitalWrite(FLLEDPin, !digitalRead(FLLEDPin));
      FLstartTime = FLcurrentTime;
      FLcount++;
      if (FLcount == 10)
      {
        FLflashing = false;
        digitalWrite(FLLEDPin, LOW);
      }
    }
  }
  //////////////////////////////////////////////////////////////////////////////////////////
  //FR Solenoid Sequence//
  if (!FRflashing)
  {
    byte currentFRButtonState = digitalRead(FRButtonPin);
    if (currentFRButtonState != previousFRButtonState && currentFRButtonState == LOW)
    {
      FRflashing = true;
      FRcount = 0;
      FRstartTime = millis();
    }
    previousFRButtonState = currentFRButtonState;
  }
  else
  {
    unsigned long FRcurrentTime = millis();
    if (FRcurrentTime - FRstartTime >= Solenoidperiod)
    {
      digitalWrite(FRLEDPin, !digitalRead(FRLEDPin));
      FRstartTime = FRcurrentTime;
      FRcount++;
      if (FRcount == 10)
      {
        FRflashing = false;
        digitalWrite(FRLEDPin, LOW);
      }
    }
  }

  //////////////////////////////////////////////////////////////////////////////////////////
  //RR Solenoid Sequence//
  if (!RRflashing)
  {
    byte currentRRButtonState = digitalRead(RRButtonPin);
    if (currentRRButtonState != previousRRButtonState && currentRRButtonState == LOW)
    {
      RRflashing = true;
      RRcount = 0;
      RRstartTime = millis();
    }
    previousRRButtonState = currentRRButtonState;
  }
  else
  {
    unsigned long RRcurrentTime = millis();
    if (RRcurrentTime - RRstartTime >= Solenoidperiod)
    {
      digitalWrite(RRLEDPin, !digitalRead(RRLEDPin));
      RRstartTime = RRcurrentTime;
      RRcount++;
      if (RRcount == 10)
      {
        RRflashing = false;
        digitalWrite(RRLEDPin, LOW);
      }
    }
  }
  //any other non blocking code can go here
}

The pump code seems to be a copy of the solenoid code for no good reason.

When you see a button press, turn on the pump (right after Pumpflashing = true;). Use the existing two second check to turn it off, but PumpCount is not necessary.

I don't see why the solenoid code isn't working - I suggest you add some serial prints in there to find out what's going on.

I left the count function in there incase I discovered that a specific sequence of starting and stopping the pump worked better than a single start/stop. Wanted to be able to play around with the pump running features.

the FL, FR and RR button pins are initially configured as OUTPUTs instead of the corresponding LED pins

lots of redundant cut&paste. makes the code hard to read and review

1 Like

I'm new to this game. What is serial.print, and how do I implement it?

Thank you!

#undef MyHW
#ifdef MyHW
enum { Off = HIGH, On = LOW };

const byte PumpButtonPin = A1;
const byte FLButtonPin   = A2;
const byte FRButtonPin   = A3;
const byte RRButtonPin   = A4;

const byte PumpLEDPin = 13;
const byte FLLEDPin   = 10;
const byte FRLEDPin   = 11;
const byte RRLEDPin   = 12;

#else
enum { On = HIGH, Off = LOW };

const byte PumpButtonPin = 2;
const byte FLButtonPin = 3;
const byte FRButtonPin = 4;
const byte RRButtonPin = 5;

const byte PumpLEDPin = 9;
const byte FLLEDPin = 10;
const byte FRLEDPin = 11;
const byte RRLEDPin = 12;
#endif

unsigned long PumpstartTime;
unsigned long FLstartTime;
unsigned long FRstartTime;
unsigned long RRstartTime;
unsigned long Pumpperiod = 2000;
unsigned long Solenoidperiod = 500;
boolean Pumpflashing = false;
boolean FLflashing = false;
boolean FRflashing = false;
boolean RRflashing = false;
byte Pumpcount = 0;
byte FLcount = 0;
byte FRcount = 0;
byte RRcount = 0;
byte previousPumpButtonState = Off;
byte previousFLButtonState   = Off;
byte previousFRButtonState   = Off;
byte previousRRButtonState   = Off;

char s [80];

void setup ()
{
    Serial.begin (115200);

    pinMode (PumpLEDPin,  OUTPUT);
    pinMode (FLLEDPin, OUTPUT);
    pinMode (FRLEDPin, OUTPUT);
    pinMode (RRLEDPin, OUTPUT);

    pinMode (PumpButtonPin, INPUT_PULLUP);
    pinMode (FLButtonPin,   INPUT_PULLUP);
    pinMode (FRButtonPin,   INPUT_PULLUP);
    pinMode (RRButtonPin,   INPUT_PULLUP);

    digitalWrite (PumpLEDPin, Off);
    digitalWrite (FLLEDPin,   Off);
    digitalWrite (FRLEDPin,   Off);
    digitalWrite (RRLEDPin,   Off);
}

void loop ()
{
    ////////////////////////////////////////////////////////////////////////////
    //PumpSequence//
    if (! Pumpflashing)
    {
        byte currentPumpButtonState = digitalRead (PumpButtonPin);

        if (currentPumpButtonState != previousPumpButtonState && currentPumpButtonState == On)
        {
            Serial.println ("pump button");
            Pumpflashing = true;
            Pumpcount = 0;
            PumpstartTime = millis ();
        }
        previousPumpButtonState = currentPumpButtonState;
    }
    else
    {
        unsigned long PumpcurrentTime = millis ();
        if (PumpcurrentTime - PumpstartTime >= Pumpperiod)
        {
            digitalWrite (PumpLEDPin, !digitalRead (PumpLEDPin));
            PumpstartTime = PumpcurrentTime;
            Pumpcount++;
            if (Pumpcount == 2)
            {
                Pumpflashing = false;
                digitalWrite (PumpLEDPin, Off);
            }
        }
    }

    ////////////////////////////////////////////////////////////////////////////
    //FL Solenoid Sequence//
    if (!FLflashing)
    {
        byte currentFLButtonState = digitalRead (FLButtonPin);
        if (currentFLButtonState != previousFLButtonState && currentFLButtonState == On)
        {
            Serial.println ("FL button");
            FLflashing = true;
            FLcount = 0;
            FLstartTime = millis ();
        }
        previousFLButtonState = currentFLButtonState;
    }
    else
    {
        unsigned long FLcurrentTime = millis ();
        if (FLcurrentTime - FLstartTime >= Solenoidperiod)
        {
            digitalWrite (FLLEDPin, !digitalRead (FLLEDPin));
            FLstartTime = FLcurrentTime;
            FLcount++;
            if (FLcount == 10)
            {
                FLflashing = false;
                digitalWrite (FLLEDPin, Off);
            }
        }
    }

    ////////////////////////////////////////////////////////////////////////////
    //FR Solenoid Sequence//
    if (!FRflashing)
    {
        byte currentFRButtonState = digitalRead (FRButtonPin);
        if (currentFRButtonState != previousFRButtonState && currentFRButtonState == On)
        {
            Serial.println ("FR button");
            FRflashing = true;
            FRcount = 0;
            FRstartTime = millis ();
        }
        previousFRButtonState = currentFRButtonState;
    }
    else
    {
        unsigned long FRcurrentTime = millis ();
        if (FRcurrentTime - FRstartTime >= Solenoidperiod)
        {
            digitalWrite (FRLEDPin, !digitalRead (FRLEDPin));
            FRstartTime = FRcurrentTime;
            FRcount++;
            if (FRcount == 10)
            {
                FRflashing = false;
                digitalWrite (FRLEDPin, Off);
            }
        }
    }

    ////////////////////////////////////////////////////////////////////////////
    //RR Solenoid Sequence//
    if (!RRflashing)
    {
        byte currentRRButtonState = digitalRead (RRButtonPin);
        if (currentRRButtonState != previousRRButtonState && currentRRButtonState == Off)
        {
            RRflashing = true;
            RRcount = 0;
            RRstartTime = millis ();
        }
        previousRRButtonState = currentRRButtonState;
    }
    else
    {
        unsigned long RRcurrentTime = millis ();
        if (RRcurrentTime - RRstartTime >= Solenoidperiod)
        {
            digitalWrite (RRLEDPin, !digitalRead (RRLEDPin));
            RRstartTime = RRcurrentTime;
            RRcount++;
            if (RRcount == 10)
            {
                RRflashing = false;
                digitalWrite (RRLEDPin, Off);
            }
        }
    }
    //any other non blocking code can go here
}

Wow. Thank you. I didnt catch the setting wrong pins as outputs.

I really appreciate your help.

Thank you for the help! Sketch works perfectly now!