Why does my Arduino seem to freeze when I don't hold the button connected to pin 10?

My project doesn't respond unless I constantly hold down the button on pin 10. As soon as I take my finger off the button, pin 19 is no longer low and the project stops responding until I press the button again. How can I make it so it stays low even after I pressed the button as long as state is not 0?

#include <RTClib.h>

#include <debounce.h>
#include <TM1637Display.h>
TM1637Display display(21, 18);
int state;
int status;
float test_led;
float time=0;
unsigned long long t_in_ms;
unsigned long long time_in_ms;
uint32_t counter = 0;
float start_time=0;
unsigned long state_change_time;
bool mode;
RTC_DS1307 rtc;
const uint8_t off[] {
  0x00,
	SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F,                           // O
	SEG_A | SEG_E | SEG_F | SEG_G, //F
  SEG_A | SEG_E | SEG_F | SEG_G,           // F
};
const uint8_t no[]{
  SEG_G, SEG_G, SEG_G, SEG_G
};
const uint8_t on[] {
  0x0,
	SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F,                           // O
	SEG_C | SEG_E | SEG_G,
  0x0   // n
};
void buttonHandler(uint8_t btnId, uint8_t btnState) {
  if (btnState == BTN_PRESSED && !mode) {
    state+=1;
    if (state>2){state=0;}
    state_change_time=millis();
  }
}
void update_time(){
  if (status){
    DateTime now = rtc.now();
    time_in_ms=now.hour()*3600000+now.minute()*60000;
  }else{
    time_in_ms=-1;
  }
}
static Button myButton(0, buttonHandler);
void on_mode_change(){
  myButton.update(digitalRead(10));
  if (digitalRead(0)){
    mode=false;
    state=0;
  }else{
    mode=true;
    state=int(!digitalRead(7));
  }
  state_change_time=millis();
}
void on_state_change(){
  myButton.update(digitalRead(10));
  Serial.println(7);
  if (mode){
  state=int(!digitalRead(7));
  state_change_time=millis();
  }
}
void setup() {
  display.clear();
  display.setBrightness(0x0f);
  pinMode(19, INPUT);
  Serial.begin(9600);
  status=rtc.begin();
  if(status){
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
  myButton.setPushDebounceInterval(75);
  pinMode(10, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(0, INPUT_PULLUP);
  on_mode_change();
}
void loop() {
  myButton.update(digitalRead(10));
  update_time();
  attachInterrupt(digitalPinToInterrupt(0), on_mode_change, CHANGE); // Attach interrupt on change
  attachInterrupt(digitalPinToInterrupt(7), on_state_change, CHANGE); // Attach interrupt on change
  if(state_change_time>millis()){
    state_change_time=0;
  }
  if (state==1){
    pinMode(19, OUTPUT);
    digitalWrite(19, LOW);
    display.setBrightness(7);
    update_time();
    if(millis()-state_change_time<3000){
    display.setSegments(on, 4);
    }else{
      if (time_in_ms==-1){
        display.setSegments(no);
      }else{
      display.showNumberDecEx(int((time_in_ms/3600000>=1) ? time_in_ms/3600000 : 12)*100+int(time_in_ms/60000)%60,(millis()%1000>500) ? 0b11100000 : 0, false, 4, 0);
    }
    }
    TXLED1;
  }else if (state==2){
  pinMode(19, OUTPUT);
  digitalWrite(19, LOW);
  time=999;
  start_time=millis();
  display.setBrightness(7);
  while (time>0 && state==2){
    update_time();
    TXLED1;
    if(start_time>millis()){
    start_time=0;
    }
    myButton.update(digitalRead(10));
    time=1800-int((millis()-start_time)/1000);
    display.showNumberDecEx(int(time/60)*100+int(time)%60, 0b11100000, false, 4, 0);
  }
  state=0;
  state_change_time=millis();
  }else{
    if(millis()-state_change_time<3000){
    display.setSegments(off);
    }else{
      if (time_in_ms==-1){
        display.setSegments(no);
      }else{
      display.showNumberDecEx(int((time_in_ms/3600000>=1) ? time_in_ms/3600000 : 12)*100+int(time_in_ms/60000)%60,(millis()%1000>500) ? 0b11100000 : 0, false, 4, 0);
    }
    }
    display.setBrightness(2);
    pinMode(19, INPUT);
    TXLED0;
  }
}

post circuit diagram ( NOT Fritzing)
Include everything (power supply etc)

What Arduino are you using?

Sparkfun Pro Micro

Explain the use of pin 19.

I see it made an INPUT, and also an OUTPUT that is written LOW. This seems unusual.

a7

@bluejets @alto777 my full schematic
image

Nice, THX.

Modern practice is to omit the croquet wickets on lines that cross, and just use (or omit) a dot if crossing line connect (or do not). It makes a diagram easier to read.

There is 100 ohms pulling up SDA but nothing on SCL. Please explain that.

Also, please say why pin 19 is being switched from high impedance to OUTPUT driven LOW.

Where did any code that you borrowed or took come from? Can you post the sketches that you used to make this one?

a7

@alto777
#1: The DS1307 requires an external pullup on SDA but it doesn’t on SCL.

#2: In the ATX spec, PS_ON has to be pulled low to turn the PS on or open circuited to turn the PS off. In this case, pinMode(19, INPUT) turns the pin back to floating.

#3: I did not borrow any code except for the libraries.

I think that, at least for troubleshooting, you should keep the previous version of the variable state when it changes and, in the loop(), print a message every time state does change. Printing messages in an interrupt service routine, as you are doing, is not reliable.

It should a simple matter to keep a pin LOW if state != 0. That you are having difficulties indicates that state is changing unexpectedly.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.