Code help

Hi all, First time posting here, so apolgies if i'm in the wrong place. I've got a small bit of code that i'm looking for help or pointers in. First off, this is my first project using an arduino so i'm a complete novice!
I'm using a 'UNO' to program an attiny85 chip. The chip will g into a pcb and will be used to trigger a small lacthing relay with the use of a SPST momentary switch. Everything works fine, but was wondering if there was a way to implement a code aswell as the code already there, so the relay would latch whilst the footswitch is being held down after a couple of seconds of holding or so, then release when let go.

Here's the code:

const int led = 2;
const int button = 4;
const int setRelay = 1;
const int clearRelay = 0;
const int muteOutput = 3;
int led_state = LOW;

// Button states and debounce
int buttonState = 0;
int lastButtonState = HIGH;
unsigned long lastDebounceTime = 0;

void setup() {

pinMode(led, OUTPUT);
pinMode(button, INPUT_PULLUP);
pinMode(setRelay, OUTPUT);
pinMode(clearRelay, OUTPUT);
pinMode(muteOutput, OUTPUT);

digitalWrite(muteOutput, LOW);

relayOff();

// Blink LED to show code running
digitalWrite(led, HIGH);
delay(200);
digitalWrite(led, LOW);
delay(200);
digitalWrite(led, HIGH);
delay(200);
digitalWrite(led, LOW);
}

void loop() {

int reading = digitalRead(button);
if (reading != lastButtonState)
lastDebounceTime = millis();

if ((millis() - lastDebounceTime) > 50) {

if (reading != buttonState) {
buttonState = reading;

if (buttonState == LOW) {
led_state = !led_state;
if (led_state == LOW) { relayOff(); }
if (led_state == HIGH) { relayOn(); }
}

}
}

lastButtonState = reading;

digitalWrite(led, led_state);
}

void relayOn() {
digitalWrite(muteOutput, HIGH);
digitalWrite(setRelay, HIGH);
delay(50);
digitalWrite(setRelay, LOW);
digitalWrite(muteOutput, LOW);
}

void relayOff() {
digitalWrite(muteOutput, HIGH);
digitalWrite(clearRelay, HIGH);
delay(50);
digitalWrite(clearRelay, LOW);
digitalWrite(muteOutput, LOW);
}

Firstly, please use code tags, as such

const int led = 2;
const int button = 4;
const int setRelay = 1;
const int clearRelay = 0;
const int muteOutput = 3;
int led_state = LOW;

// Button states and debounce
int buttonState = 0;
int lastButtonState = HIGH;
unsigned long lastDebounceTime = 0;

void setup() {

  pinMode(led, OUTPUT);
  pinMode(button, INPUT_PULLUP);
  pinMode(setRelay, OUTPUT);
  pinMode(clearRelay, OUTPUT);
  pinMode(muteOutput, OUTPUT);   

  digitalWrite(muteOutput, LOW);

  relayOff();

// Blink LED to show code running
  digitalWrite(led, HIGH);
  delay(200);
  digitalWrite(led, LOW);
  delay(200);
  digitalWrite(led, HIGH);
  delay(200);
  digitalWrite(led, LOW);
}


void loop() {

  int reading = digitalRead(button);
  if (reading != lastButtonState)
    lastDebounceTime = millis();

  if ((millis() - lastDebounceTime) > 50) {
   
    if (reading != buttonState) {
      buttonState = reading;
     
      if (buttonState == LOW) {
        led_state = !led_state;
            if (led_state == LOW) { relayOff(); }
            if (led_state == HIGH) { relayOn(); }     
      }
     
    }
  }

  lastButtonState = reading;

  digitalWrite(led, led_state);
}


void relayOn() {
  digitalWrite(muteOutput, HIGH);
  digitalWrite(setRelay, HIGH);
  delay(50);
  digitalWrite(setRelay, LOW);
  digitalWrite(muteOutput, LOW); 
}

void relayOff() {
  digitalWrite(muteOutput, HIGH);
  digitalWrite(clearRelay, HIGH);
  delay(50);
  digitalWrite(clearRelay, LOW);
  digitalWrite(muteOutput, LOW);
}

Secondly, what is it exactly you want? It's not fully clear to me. You want to add a footswitch to this? Or is it already there and do you want to change it's behaviour?

The way the sketch is written, each time the button is pressed the "led_state" is toggled and the relay is set to match the led_state. Press on, press off, press on, press off...

My understanding of what you want to do is keep that functionality and add: If the button is pressed for 'on' and held more than a second, the release of the button causes the relay to be switched off (instead of being turned off by a future button press)? Do I have that correct?

I can help with the programming. I just want to make sure I understand the goal first.

For a first Arduino project it's in quite good shape.

Why a latching relay? Post a link to or brand name and part number for the relay.

johnwasser:
The way the sketch is written, each time the button is pressed the "led_state" is toggled and the relay is set to match the led_state. Press on, press off, press on, press off...

My understanding of what you want to do is keep that functionality and add: If the button is pressed for 'on' and held more than a second, the release of the button causes the relay to be switched off (instead of being turned off by a future button press)? Do I have that correct?

I can help with the programming. I just want to make sure I understand the goal first.

For a first Arduino project it's in quite good shape.

This is exactly what i'm looking for! If i'm being honest, it's an open source code i found online that fits my needs, apart from the added functionality that i'm looking for. I've been binge watching youtube videos about coding, and come up with not much haha, but i guess it's a learning curve!

TimMJN:
Firstly, please use code tags, as such

const int led = 2;

const int button = 4;
const int setRelay = 1;
const int clearRelay = 0;
const int muteOutput = 3;
int led_state = LOW;

// Button states and debounce
int buttonState = 0;
int lastButtonState = HIGH;
unsigned long lastDebounceTime = 0;

void setup() {

pinMode(led, OUTPUT);
 pinMode(button, INPUT_PULLUP);
 pinMode(setRelay, OUTPUT);
 pinMode(clearRelay, OUTPUT);
 pinMode(muteOutput, OUTPUT);

digitalWrite(muteOutput, LOW);

relayOff();

// Blink LED to show code running
 digitalWrite(led, HIGH);
 delay(200);
 digitalWrite(led, LOW);
 delay(200);
 digitalWrite(led, HIGH);
 delay(200);
 digitalWrite(led, LOW);
}

void loop() {

int reading = digitalRead(button);
 if (reading != lastButtonState)
   lastDebounceTime = millis();

if ((millis() - lastDebounceTime) > 50) {
 
   if (reading != buttonState) {
     buttonState = reading;
   
     if (buttonState == LOW) {
       led_state = !led_state;
           if (led_state == LOW) { relayOff(); }
           if (led_state == HIGH) { relayOn(); }    
     }
   
   }
 }

lastButtonState = reading;

digitalWrite(led, led_state);
}

void relayOn() {
 digitalWrite(muteOutput, HIGH);
 digitalWrite(setRelay, HIGH);
 delay(50);
 digitalWrite(setRelay, LOW);
 digitalWrite(muteOutput, LOW);
}

void relayOff() {
 digitalWrite(muteOutput, HIGH);
 digitalWrite(clearRelay, HIGH);
 delay(50);
 digitalWrite(clearRelay, LOW);
 digitalWrite(muteOutput, LOW);
}




Secondly, what is it exactly you want? It's not fully clear to me. You want to add a footswitch to this? Or is it already there and do you want to change it's behaviour?

Thanks for the advice, i’ll update that now. Yeah it’s a guitar effect pedal, for the bypass switch. the code i’ve got does a stellar job of flipping the relay and turning on the LED, but doesn’t have the ‘hold’ feature i’m after. i’ve switched over to using relays rather than mechanical switches for a number of reasons, and this so far has been the best way to do so.

This should do the trick. I changed some of the variable names, particularly the pin numbers, to fit my favorite convention. The globals that are only used in one function can be made static locals or just locals so the declaration is closer to where they are used.

// ATMEL ATTINYx5 / ARDUINO
//
//                           +-\/-+
//  Ain0       (D  5)  PB5  1|    |8   VCC
//  Ain3       (D  3)  PB3  2|    |7   PB2  (D  2)  INT0  Ain1
//  PWM  Ain2  (D  4)  PB4  3|    |6   PB1  (D  1)        PWM (OC0B)
//  OC1B               GND  4|    |5   PB0  (D  0)        PWM (OC0A)
//                           +----+


const byte Mute_DOPin = 3;   // Physical Pin 2
const byte FootButton_DIPin = 4;       // Physical Pin 3
const byte ClearRelay_DOPin = 0;   // Physical Pin 5
const int SetRelay_DOPin = 1;     // Physical Pin 6
const int LED_DOPin = 2;          // Physical Pin 7


boolean PedalStateActive = false;


void setup()
{
  pinMode(LED_DOPin, OUTPUT);
  pinMode(FootButton_DIPin, INPUT_PULLUP);
  pinMode(SetRelay_DOPin, OUTPUT);
  pinMode(ClearRelay_DOPin, OUTPUT);
  pinMode(Mute_DOPin, OUTPUT);


  digitalWrite(Mute_DOPin, LOW);


  relayOff();


  // Blink LED to show code running
  digitalWrite(LED_DOPin, HIGH);
  delay(200);
  digitalWrite(LED_DOPin, LOW);
  delay(200);
  digitalWrite(LED_DOPin, HIGH);
  delay(200);
  digitalWrite(LED_DOPin, LOW);
}




void loop()
{
  unsigned long currentMillis = millis();
  static unsigned long lastStateChangeTime = 0;


  static boolean buttonWasPressed = false;
  boolean buttonIsPressed = digitalRead(FootButton_DIPin) == LOW;


  // First, is that a change and, if so, has it been a while since we saw a change (debounce)
  if (buttonIsPressed != buttonWasPressed  && currentMillis - lastStateChangeTime > 50)
  {
    // Yes, the state has made its first change in a while
    buttonWasPressed = buttonIsPressed;  // Note the new state


    // This is the new part: 
    //    If the button activated the pedal and has just been released after more than 1000 milliseconds
    if (PedalStateActive && !buttonIsPressed && currentMillis - lastStateChangeTime > 1000)
    {
      // Released after a long press.
      PedalStateActive = false;
      relayOff();
    }


    lastStateChangeTime = currentMillis;


    // Now handle the normal toggle on press
    if (buttonIsPressed) // just pressed
    {
      PedalStateActive = !PedalStateActive;


      if (PedalStateActive)
        relayOn();
      else
        relayOff();
    }
  }


  digitalWrite(LED_DOPin, PedalStateActive);
}

void relayOn()
{
  digitalWrite(Mute_DOPin, HIGH);
  digitalWrite(SetRelay_DOPin, HIGH);
  delay(50);
  digitalWrite(SetRelay_DOPin, LOW);
  digitalWrite(Mute_DOPin, LOW);
}


void relayOff()
{
  digitalWrite(Mute_DOPin, HIGH);
  digitalWrite(ClearRelay_DOPin, HIGH);
  delay(50);
  digitalWrite(ClearRelay_DOPin, LOW);
  digitalWrite(Mute_DOPin, LOW);
}

johnwasser:
This should do the trick. I changed some of the variable names, particularly the pin numbers, to fit my favorite convention. The globals that are only used in one function can be made static locals or just locals so the declaration is closer to where they are used.

// ATMEL ATTINYx5 / ARDUINO

//
//                          ±/-+
//  Ain0      (D  5)  PB5  1|    |8  VCC
//  Ain3      (D  3)  PB3  2|    |7  PB2  (D  2)  INT0  Ain1
//  PWM  Ain2  (D  4)  PB4  3|    |6  PB1  (D  1)        PWM (OC0B)
//  OC1B              GND  4|    |5  PB0  (D  0)        PWM (OC0A)
//                          ±—+

const byte Mute_DOPin = 3;  // Physical Pin 2
const byte FootButton_DIPin = 4;      // Physical Pin 3
const byte ClearRelay_DOPin = 0;  // Physical Pin 5
const int SetRelay_DOPin = 1;    // Physical Pin 6
const int LED_DOPin = 2;          // Physical Pin 7

boolean PedalStateActive = false;

void setup()
{
  pinMode(LED_DOPin, OUTPUT);
  pinMode(FootButton_DIPin, INPUT_PULLUP);
  pinMode(SetRelay_DOPin, OUTPUT);
  pinMode(ClearRelay_DOPin, OUTPUT);
  pinMode(Mute_DOPin, OUTPUT);

digitalWrite(Mute_DOPin, LOW);

relayOff();

// Blink LED to show code running
  digitalWrite(LED_DOPin, HIGH);
  delay(200);
  digitalWrite(LED_DOPin, LOW);
  delay(200);
  digitalWrite(LED_DOPin, HIGH);
  delay(200);
  digitalWrite(LED_DOPin, LOW);
}

void loop()
{
  unsigned long currentMillis = millis();
  static unsigned long lastStateChangeTime = 0;

static boolean buttonWasPressed = false;
  boolean buttonIsPressed = digitalRead(FootButton_DIPin) == LOW;

// First, is that a change and, if so, has it been a while since we saw a change (debounce)
  if (buttonIsPressed != buttonWasPressed  && currentMillis - lastStateChangeTime > 50)
  {
    // Yes, the state has made its first change in a while
    buttonWasPressed = buttonIsPressed;  // Note the new state

// This is the new part:
    //    If the button activated the pedal and has just been released after more than 1000 milliseconds
    if (PedalStateActive && !buttonIsPressed && currentMillis - lastStateChangeTime > 1000)
    {
      // Released after a long press.
      PedalStateActive = false;
      relayOff();
    }

lastStateChangeTime = currentMillis;

// Now handle the normal toggle on press
    if (buttonIsPressed) // just pressed
    {
      PedalStateActive = !PedalStateActive;

if (PedalStateActive)
        relayOn();
      else
        relayOff();
    }
  }

digitalWrite(LED_DOPin, PedalStateActive);
}

void relayOn()
{
  digitalWrite(Mute_DOPin, HIGH);
  digitalWrite(SetRelay_DOPin, HIGH);
  delay(50);
  digitalWrite(SetRelay_DOPin, LOW);
  digitalWrite(Mute_DOPin, LOW);
}

void relayOff()
{
  digitalWrite(Mute_DOPin, HIGH);
  digitalWrite(ClearRelay_DOPin, HIGH);
  delay(50);
  digitalWrite(ClearRelay_DOPin, LOW);
  digitalWrite(Mute_DOPin, LOW);
}

Thanks for the input! I’ve gone to program the board, and it’s showing up with 'stray ‘\302’ in program, Any idea what that means? Thanks!

Nevermind, managed to sort it, and it works perfectly! Thanks a bunch!