Loop within a Loop in my code

Hi all,

After a little help with a piece of code I have written that's already working in one way, I'm modifying it to add a new feature.

Essentially, the code sits on an Arduino Pro Mini 5.5v and installs into a Nissan 350 or 370z and when a button is pushed in the car, it disabled the Traction control and Vehicle Dynamic control systems to enable you to push the limits on a track day without traction control getting in the way.

This is all done by simply "faulting" the traction control system by disconnecting its ground pin for a second, then reconnecting it using the relay on a PCB I have designed.

I now want to add a "Brake Boost" option of this, which I have created the PCB mods for and written most of the extra code to control the second relay. However if my system is "armed" the code also needs to look out for a brake input signal and de-activate the Brake_Control_Relay for a second, then activate it again.

On the line that starts with else if (button_state == 0) This is the part when the "enable" button is pressed, the system sees the module was previously disabled (State 0) then sets the State to 1 (enabled) and activates both of the the relays.

However, in this section, how would I then go about both listening for a new button press (the code already handles this with the "waitButtonPress" void ) but ALSO looking for a high input on pin 7, this is the signal from the car the brake has been pressed. If the module sees this, it needs to de-activate the BRAKE_CONTROL_RELAY again for 1 second, then activate it again.

This looking for the extra input should only happen when the "button_state" is 1 (system is enabled) when the button state is 0, it just needs to sit and wait for a new button press as it already does.

#include <EEPROM.h>

// Pin Definitions
#define BUTTON_PIN A0
#define VDC_RELAY_PIN 6
#define LED_PIN A1
#define BRAKE_SENSE 7
#define BRAKE_RELAY_PIN 5


// 1 for debugging mode, 0 for turning it off
#define DEBUG 1

bool button_state = 0;
int address = 0;

void setup()
{
  // initialize pins
  pinMode(VDC_RELAY_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT);
  pinMode(LED_PIN, OUTPUT);
  pinMode(BRAKE_RELAY_PIN, OUTPUT);
  pinMode(BRAKE_SENSE, INPUT);
    
  // initialize serial for debugging
  Serial.begin(9600);

  // read the last button state from the memory for VDC Status
  button_state = EEPROM.read(address);

  #if DEBUG == 1
    Serial.print("Button state read from the memory: ");
    Serial.println(button_state);
  #endif
}

void loop()
{
  // saved state is 1
  if (button_state == 1)
  {
    // activate the relays
    VDCrelayControl();
	BRAKErelayControl();

    //turn off led
    digitalWrite(LED_PIN, LOW);
  }
  // saved state is 0
  else if (button_state == 0)
  {
    // do nothing with the relay
    //turn on the LED
    digitalWrite(LED_PIN, HIGH);
  }

  // wait for button press
  waitButtonPress();

  // saved state was 1
  if (button_state == 1)
  {
    // set state to 0 system is now safe and LED illuminated to show VDC can be disabled again and brakes are at OEM
    button_state = 0;
    digitalWrite(LED_PIN, HIGH);

    // save the state in memory
    EEPROM.write(address, button_state);

    #if DEBUG == 1
    Serial.print("new Button state read from the memory: ");
    Serial.println(button_state);
    #endif
  }
  // saved state was 0
  else if (button_state == 0)
  {
    // set state to 1 system is now disabled and LED turned off to show VDC is disabled and brake boost mod is waiting
    button_state = 1;
    digitalWrite(LED_PIN, LOW);

    // save the state in memory
    EEPROM.write(address, button_state);
    
    #if DEBUG == 1
    Serial.print("new Button state read from the memory: ");
    Serial.println(button_state);
    #endif
    
    // activate the relays
    VDCrelayControl();
	BRAKErelayControl();
  }
}

// Latches, waits and unlatches the VDC relay
void VDCrelayControl()
{
  // latch the relay
  digitalWrite(VDC_RELAY_PIN, 1);

  // wait for 1 second
  delay(1000);

  // un-latch the relay
  digitalWrite(VDC_RELAY_PIN, 0);
  Serial.println("VDC Latch Enabled and System Faulted ");
}

// Latches, the brake relay
void BRAKErelayControl()
{
  // latch the relay
  digitalWrite(BRAKE_RELAY_PIN, 1);

  Serial.println("BRAKE Latch Enabled ");
}

// Pull-down resistor is connected
// When button is not pressed, 0 volts should be read.
void waitButtonPress()
{
  // wait until button is pressed
  while (digitalRead(BUTTON_PIN) == LOW);

  #if DEBUG == 1
    Serial.println("Button has been pressed.");
  #endif

  // allow some time for debouncing
  delay(1000);
}

Im not the best at Arduino code, so im trying to pick up things as I go. Its taken me a long while to get the code to a working state, but as I say, doing a loop, whilst waiting for another input has got me confused a little!

Appreciate any replies or advice :slight_smile:

Appreciate any replies or advice

Advice, don't write blocking code such as

  // wait until button is pressed
  while (digitalRead(BUTTON_PIN) == LOW);

Instead let loop() do what it is best at, ie looping

Instead of while use if which would allow you to test more than one input on each pass through loop(). If you only want the code to read and act on one or more inputs under certain condition then have the reading/not reading controlled by a boolean and turn the reading on/off by changing the state of the boolean.

By the way, by making modifications to the vehicle you have quite possibly invalidated your insurance. Apart from anything else, a car is a very harsh environment for an Arduino to operate in.

This looking for the extra input should only happen when the "button_state" is 1 (system is enabled)

bool button_state = 0;

Boolean variables should be assigned true or false.

button_state is a lousy name when you refer to the value of the variable as meaning "armed".

Personally, I think you'd have a much easier time with the coding if you used names for variables that made sense in terms of the system you are coding for, not the fact that there is a switch involved.

int address = 0;

Address? How is anyone supposed to know what this is the address of? q15 would be as meaningful.

The first bit of code in loop() uses the value that you read from EEPROM, in setup(). That part belongs in setup().

 // allow some time for debouncing
  delay(1000);

If you have a switch that bounces for a full second, GET THAT ARDUINO AND SWITCH OUT OF YOUR CAR NOW!

Thanks for the advice.

Like I said, im no expert at Arduino code, and kind of have to learn as I go, so it makes sense my code isn't going to be as well written as people with 20,000+ and 90,000+ forum posts in somewhere such as this. Yes, I know forum posts doesn't = Arduino code experience, but based on the subject of this forum, its probably a good indicator.

@PaulS, the button doesn't bounce for a full second, much less than that, but im allowing for the button to be held down for a very short time too so im not seeing a button being pressed multiple times if I decide to hold the button for half a second.

@UKHeliBob, I know the risks RE insurance and that the Arduino isn't a automotive rated component. Thanks :slight_smile: The mod has a switch for that very reason (insurance) and is for track use only. Im not stupid enough to turn off two very useful safety systems on the road.

I know the risks RE insurance and that the Arduino isn't a automotive rated component. Thanks :slight_smile: The mod has a switch for that very reason (insurance) and is for track use only. Im not stupid enough to turn off two very useful safety systems on the road.

It is not the fact that you will/won't turn off the safety systems, it is the fact that you could turn them off using your modification that matters.

Have you told your insurance company that you have modified the vehicle ?

UKHeliBob:
It is not the fact that you will/won't turn off the safety systems, it is the fact that you could turn them off using your modification that matters.

Have you told your insurance company that you have modified the vehicle ?

Of course (and no im not just saying that, I actually don't want to get stung IF I ever do need to claim, so everything on my vehicle is declared correctly). But that isn't the point of this post.

I think I have enough to go on for now, thankyou.

@PaulS, the button doesn't bounce for a full second, much less than that, but im allowing for the button to be held down for a very short time too so im not seeing a button being pressed multiple times if I decide to hold the button for half a second.

You need to have a look at the state change detection example. It shows how to perform an action when the switch BECOMES pressed, not IS pressed.

So, you can press the switch for 3 milliseconds, or 3 months, and the action will occur ONCE.