Change 2 pins state when respective buttons are pressed and go to sleep

Hi guys, I’m trying to modify a switch pedal to work with my guitar amp. It is kinda working but there is a little problem. I am a beginner with arduino, I mean really a beginner, so please be kind :slight_smile:

I found some code online and I am trying to modify it to my setup. Author’s name will obviously stay on the code if I ever post it on a forum, or somwhere else… :slight_smile:

Here is what I want to achieve. When the attiny85 is doing nothing, it is sleeping (battery is always connected and it will last a long time). This part seems toi be working.

There are 2 push buttons and 2 output pins.

“button” should turn ON LED1 when pressed once for more than 500ms, and OFF when pressed again for more than 500ms.

“button2” should turn ON LED2 when pressed for more than 500ms, and OFF when pressed again for more than 500ms.

After changing state, the attiny goes to sleep again, and will wake up again if one of the buttons is pressed.

The changing state part is working, as well as going to sleep. My problem is that LED2 seems not to wait for 500ms sometimes, and sometimes it does wait… So, it is a bit erratic. LED1 works as it should. I am obviously doing something wrong due to my lack of knowledge… If someone could help me on this one it would be very much appreciated. The code is quoted below.

Thank you very much for your help

João

/*
 * Pin Change Interrupt Example
 * Version: 1.0
 * Author: Alex from Inside Gadgets (http://www.insidegadgets.com)
 * Created: 25/02/2011
 *
 * Demonstration of the pin change interrupt
 * LED on digital pin 0
 * Interrupt on digital pin 1
 * 10k resistor on digital pin 1 to GND
 *
 */
 
#include <avr/sleep.h>

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

int LED1 = 4;
int LED2 = 3;
int button = 0;
int button2 = 1;
boolean LED1State = true;
boolean LED2State = true;


long buttonTimer = 0;
long longPressTime = 500;

long buttonTimer2 = 1;
long longPressTime2 = 500;

boolean buttonActive = false;
boolean longPressActive = false;

boolean buttonActive2 = false;
boolean longPressActive2 = false;

void setup(){
 pinMode(LED1, OUTPUT);
  digitalWrite(LED1, HIGH);
   pinMode(LED2, OUTPUT);
  digitalWrite(LED2, HIGH);
  pinMode(button, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  
  sbi(GIMSK,PCIE); // Turn on Pin Change interrupt
  sbi(PCMSK,PCINT1); // Which pins are affected by the interrupt
  sbi(PCMSK,PCINT0);
}

void loop()
{
  if (digitalRead(button) == LOW)
  {
    
    if (buttonActive == false)
    {
      buttonActive = true;
      buttonTimer = millis();
    }

    if ((millis() - buttonTimer > longPressTime) && (longPressActive == false))
    {
      longPressActive = true;
      LED1State = !LED1State;
      digitalWrite(LED1, LED1State);
    }
  }
  else
  
 if (digitalRead(button2) == LOW)
  {
    
    if (buttonActive2 == false)
    {
      buttonActive2 = true;
      buttonTimer2 = millis();
    }

    if ((millis() - buttonTimer2 > longPressTime2) && (longPressActive2 == false))
    {
      longPressActive2 = true;
      LED2State = !LED2State;
      digitalWrite(LED2, LED2State);
    }
  }
  else
  
  {
    if (buttonActive == true)
    {
      if (longPressActive == true)
      {
        longPressActive = false;
      }
      else
      {
        buttonActive = false;
      }
    
  }
 
  

    if (buttonActive2 == true)
    {
      if (longPressActive2 == true)
      {
        longPressActive2 = false;
      }
      else
      {
        buttonActive2 = false;
      }
  }
      system_sleep();
  }

 


 
 } 

 

 

// From http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/
void system_sleep() {
  cbi(ADCSRA,ADEN); // Switch Analog to Digital converter OFF
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Set sleep mode
  sleep_mode(); // System sleeps here
  sbi(ADCSRA,ADEN);  // Switch Analog to Digital converter ON
}

ISR(PCINT0_vect) {
   buttonActive = true;
      buttonTimer = millis();
 }     
ISR(PCINT1_vect) {
   buttonActive2 = true;
      buttonTimer2 = millis();      
}

The ATtiny85 doesn't have a PCINT1_vect, all pin change interrupts are handled by PCINT0_vect. Check the state of both buttons in the PCINT0 ISR.

Thanks a lot, your advice did it..

ISR(PCINT0_vect) {
   buttonActive = true;
      buttonTimer = millis();

   buttonActive2 = true;
      buttonTimer2 = millis();      
}

I would never get there without your help.. I did search and try everything. Been here all day :( Forgot the most important rule. Check the datasheet :(

Thanks a lot.. You have saved my day and my mental health..

João

Found another problem. I decreased the "long longPressTime = 500;" to 20mS, so the LEDs switch state immediately.

My problem is that if I keep one button pressed I cannot change the state of the other. it would be nice if they worked independently.. Can't find a solution for that..

Thank you

João

The two buttons trigger the same interrupt routine, check which button is pressed with a digitalRead() and set the active flag for that button only.

Sorry guys, I can't do it.. As I said I am a beginner, so I went googling about interrupts.. But Im stuck.. :(

This is what i have, but it is not even compiling with some errors that i have no idea how to clear :(
One of them is some int to void conversion problem..

Sorry about that..  :( 

João

[code/*
 * Pin Change Interrupt Example
 * Version: 1.0
 * Author: Alex from Inside Gadgets (http://www.insidegadgets.com)
 * Created: 25/02/2011
 *
 * Demonstration of the pin change interrupt
 * LED on digital pin 0
 * Interrupt on digital pin 1
 * 10k resistor on digital pin 1 to GND
 *
 */
 
#include <avr/sleep.h>

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

int LED1 = 4;
int LED2 = 3;
int button = 0;
int button2 = 1;
boolean LED1State = false;
boolean LED2State = false;


long buttonTimer = 0;
long longPressTime = 20;

long buttonTimer2 = 1;
long longPressTime2 = 20;

boolean buttonActive = false;
boolean longPressActive = false;

boolean buttonActive2 = false;
boolean longPressActive2 = false;

void setup(){
 pinMode(LED1, OUTPUT);
  digitalWrite(LED1, LOW);
   pinMode(LED2, OUTPUT);
  digitalWrite(LED2, LOW);
  pinMode(button, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
   attachInterrupt(0, button, FALLING);
   attachInterrupt(1, button2, FALLING);
  
  sbi(GIMSK,PCIE); // Turn on Pin Change interrupt
  sbi(PCMSK,PCINT1); // Which pins are affected by the interrupt
  sbi(PCMSK,PCINT0);
}

void loop(){
  

  void button()
  
  
   if (digitalRead(button) == LOW)
    {
    if (buttonActive == false)
    {
      buttonActive = true;
      buttonTimer = millis();
    }

    if ((millis() - buttonTimer > longPressTime) && (longPressActive == false))
    {
      longPressActive = true;
      LED1State = !LED1State;
      digitalWrite(LED1, LED1State);
    }
  }
  else
  
  {
    if (buttonActive == true)
    {
      if (longPressActive == true)
      {
        longPressActive = false;
      }
      else
      {
        buttonActive = false;
      }
    
  }
 system_sleep();
 }
       
  
 
 void button2()
 
 
       if (digitalRead(button2) == LOW)
    {
    
    if (buttonActive2 == false)
    {
      buttonActive2 = true;
      buttonTimer2 = millis();
    }

    if ((millis() - buttonTimer2 > longPressTime2) && (longPressActive2 == false))
    {
      longPressActive2 = true;
      LED2State = !LED2State;
      digitalWrite(LED2, LED2State);
    }
  }
  else
  
    
     { 
    if (buttonActive2 == true)
    {
      if (longPressActive2 == true)
      {
        longPressActive2 = false;
      }
      else
      {
        buttonActive2 = false;
      }
  }
  system_sleep();
  }
  
     

 
 } 
 

// From http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/
void system_sleep() {
  cbi(ADCSRA,ADEN); // Switch Analog to Digital converter OFF
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Set sleep mode
  sleep_mode(); // System sleeps here
  sbi(ADCSRA,ADEN);  // Switch Analog to Digital converter ON
}

ISR(PCINT0_vect) {
   buttonActive = true;
      buttonTimer = millis();

   buttonActive2 = true;
      buttonTimer2 = millis();      
}
]

Problem is solved… Thanks for your help…

João

#include <avr/sleep.h>

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

int LED1 = 4;
int LED2 = 3;
int button = 0;
int button2 = 1;
boolean LED1State = false;
boolean LED2State = false;


long buttonTimer = 0;
long longPressTime = 20;

long buttonTimer2 = 1;
long longPressTime2 = 20;

boolean buttonActive = false;
boolean longPressActive = false;

boolean buttonActive2 = false;
boolean longPressActive2 = false;

void setup(){
 pinMode(LED1, OUTPUT);
  digitalWrite(LED1, LOW);
   pinMode(LED2, OUTPUT);
  digitalWrite(LED2, LOW);
  pinMode(button, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  
  sbi(GIMSK,PCIE); // Turn on Pin Change interrupt
  sbi(PCMSK,PCINT1); // Which pins are affected by the interrupt
  sbi(PCMSK,PCINT0);
}

void loop()
{
  if ( (digitalRead(button) == LOW) || (digitalRead(button2) == LOW) )
  {
    if (digitalRead(button) == LOW)
    {
     
      if (buttonActive == false)
      {
        buttonActive = true;
        buttonTimer = millis();
      }

      if ((millis() - buttonTimer > longPressTime) && (longPressActive == false))
      {
        longPressActive = true;
        LED1State = !LED1State;
        digitalWrite(LED1, LED1State);
      }
    }
    if (digitalRead(button2) == LOW)
    {
     
      if (buttonActive2 == false)
      {
        buttonActive2 = true;
        buttonTimer2 = millis();
      }

      if ((millis() - buttonTimer2 > longPressTime2) && (longPressActive2 == false))
      {
        longPressActive2 = true;
        LED2State = !LED2State;
        digitalWrite(LED2, LED2State);
      }
    }
  }
  else
  {
    if (buttonActive == true)
    {
      if (longPressActive == true)
      {
        longPressActive = false;
      }
      else
      {
        buttonActive = false;
      }
   
    }
 
 

    if (buttonActive2 == true)
    {
      if (longPressActive2 == true)
      {
        longPressActive2 = false;
      }
      else
      {
        buttonActive2 = false;
      }
    }
    system_sleep();
  }
 
 }

// From http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/
void system_sleep() {
  cbi(ADCSRA,ADEN); // Switch Analog to Digital converter OFF
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Set sleep mode
  sleep_mode(); // System sleeps here
  sbi(ADCSRA,ADEN);  // Switch Analog to Digital converter ON
}

ISR(PCINT0_vect) {
   buttonActive = true;
      buttonTimer = millis();

   buttonActive2 = true;
      buttonTimer2 = millis();      
}