Exit status 1 'button_hold_time_ms' was not declared in this scope

why am i getting this error when its been declared already.

void loop()
{
    
  // Check if button has been pressed
  if ( digitalRead( btn ) == LOW )
  {
    const int button_threshold_ms = 2000;   
    int button_press_time_ms = 0;
    int button_release_time_ms = 0;
    int button_hold_time_ms = 0;
    
    // Store millisecond count when button was pressed
    button_press_time_ms = millis();

    // Wait while button is pressed
    while ( digitalRead( btn ) == LOW ) {}

    // Store millisecond count when button was released
    button_release_time_ms = millis();
    
    // Calculate button hold time
    button_hold_time_ms = button_release_time_ms - button_press_time_ms;

    // Determine if button press was longer than threshold
    if ( button_hold_time_ms >= button_threshold_ms )
    {
      Serial.println("Long press detected: ");
      Serial.println(button_hold_time_ms);
      Serial.println("ms");
      btncount = 2;
        Serial.println(btncount);
  }
      
      // Execute long press code here or set flag
      
      if ( btncount < 2){

  return;
  
  // Wait while button is pressed
  while ( btncount > 1 ){}

  // Execute once button has been released
  for ( int thisNote = 0; thisNote < sizeof( melody ) / 2; thisNote++ ) 
  {
    // Calculate note duration and update
    int noteDuration = 2000 / noteDurations[thisNote];
    tone( buzzer, melody[thisNote], noteDuration );
    
    // Calculate and execute note delay
    int pauseBetweenNotes = noteDuration * 1.30;
    delay( pauseBetweenNotes );

    // Check for a button press
    if ( digitalRead( btn ) == LOW )
    --btncount; 
    {
      // Wait while button is pressed
      while ( btncount < 2 ){}

      // Break from loop once button is released
      break;    
    }
  }   
 }
    }
    else
    {

      Serial.println("Short press detected: ");
      Serial.println(button_hold_time_ms);
      Serial.println("ms");
      btncount = 1;
      Serial.println(btncount);
    
    }
   // Execute short press code here or set flag
while(btncount == 1) 
  {
  delay(200);
  float temperature;
  float humidity;
  
  if(dht_sensor.measure(&temperature, &humidity))
  {
    Serial.print( "T = " );
    Serial.print( temperature, 1 );
    Serial.print( " deg. C, H = " );
    Serial.print( humidity, 1 );
    Serial.println( "%" );
  Serial.println(count);
  

full code here

#include "pitches.h"

int melody[] = {
  NOTE_G4, NOTE_C5, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_E4, NOTE_E4, 
  NOTE_A4, NOTE_G4, NOTE_F4, NOTE_G4, NOTE_C4, NOTE_C4, 
  NOTE_D4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5, NOTE_D5, 
  NOTE_E5, NOTE_D5, NOTE_C5, NOTE_D5, NOTE_B4, NOTE_G4, 
  NOTE_C5, NOTE_B4, NOTE_A4, NOTE_B4, NOTE_E4, NOTE_E4, 
  NOTE_A4, NOTE_G4, NOTE_F4, NOTE_G4, NOTE_C4, NOTE_C4, 
  NOTE_C5, NOTE_B4, NOTE_A4, NOTE_G4, NOTE_B4, NOTE_C5, NOTE_D5, 
  NOTE_E5, NOTE_D5, NOTE_C5, NOTE_B4, NOTE_C5, NOTE_D5, NOTE_G4, NOTE_G4, NOTE_B4, NOTE_C5, NOTE_D5,
  NOTE_C5, NOTE_B4, NOTE_A4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_E4, NOTE_E4, NOTE_G4, NOTE_A4, NOTE_B4,
  NOTE_C5, NOTE_A4, NOTE_B4, NOTE_C5, NOTE_A4, NOTE_B4, NOTE_C5, NOTE_A4, NOTE_C5, NOTE_F5,
  NOTE_F5, NOTE_E5, NOTE_D5, NOTE_C5, NOTE_D5, NOTE_E5, NOTE_C5, NOTE_C5,
  NOTE_D5, NOTE_C5, NOTE_B4, NOTE_A4, NOTE_B4, NOTE_C5, NOTE_A4, NOTE_A4,
  NOTE_C5, NOTE_B4, NOTE_A4, NOTE_G4, NOTE_C4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5
};

int noteDurations[] = {
  8, 4, 6, 16, 4, 8, 8, 
  4, 6, 16, 4, 8, 8, 
  4, 8, 8, 4, 8, 8, 4, 8, 8, 2,
  4, 6, 16, 4, 8, 8, 
  4, 6, 16, 4, 8, 8, 
  4, 6, 16, 4, 6, 16, 
  4, 6, 16, 8, 8, 8, 8, 
  2, 8, 8, 8, 8, 3, 8, 8, 8, 8, 8,
  2, 8, 8, 8, 8, 3, 8, 8, 8, 8, 8,
  4, 6, 16, 4, 6, 16, 4, 8, 8, 2,
  2, 8, 8, 8, 8, 3, 8, 2,
  2, 8, 8, 8, 8, 3, 8, 2,
  4, 6, 16, 4, 4, 2, 4, 4, 1
};

#include <dht_nonblocking.h>

#define DHT_SENSOR_TYPE DHT_TYPE_11
//#define DHT_SENSOR_TYPE DHT_TYPE_21
//#define DHT_SENSOR_TYPE DHT_TYPE_22

//Define the pin connection
int CLK = 2;//CLK->D2
int DT = 3;//DT->D3
int SW = 4;//SW->D4
const int interrupt0 = 0;// Interrupt 0 在 pin 2 上
int count = 0;//Define the count
int lastCLK = 0;//CLK initial value

static const int DHT_SENSOR_PIN = 8;
DHT_nonblocking dht_sensor( DHT_SENSOR_PIN, DHT_SENSOR_TYPE );
int btncount;
 int btn =7;                    // switch pin

int relayPin = 10;

int buzzer = 12;



void setup()
{
    Serial.begin(9600);
 
  pinMode(SW, INPUT);
  digitalWrite(SW, HIGH);
  pinMode(CLK, INPUT);
  pinMode(DT, INPUT);
 attachInterrupt(interrupt0, ClockChanged, CHANGE);//Set the interrupt 0 handler, trigger level change
 pinMode(buzzer, OUTPUT);
  noTone(buzzer);
 pinMode(relayPin, OUTPUT);

}


//The interrupt handlers
void ClockChanged()
{  
  int clkValue = digitalRead(CLK);//Read the CLK pin level
  int dtValue = digitalRead(DT);//Read the DT pin level
  if (lastCLK != clkValue)
  {
    lastCLK = clkValue;
    count += (clkValue != dtValue ? 1 : -1);//CLK and inconsistent DT + 1, otherwise - 1

    Serial.print("count:");
    Serial.println(count);
      delay(200);
  } 
}

void loop()
{
    
  // Check if button has been pressed
  if ( digitalRead( btn ) == LOW )
  {
    const int button_threshold_ms = 2000;   
    int button_press_time_ms = 0;
    int button_release_time_ms = 0;
    int button_hold_time_ms = 0;
    
    // Store millisecond count when button was pressed
    button_press_time_ms = millis();

    // Wait while button is pressed
    while ( digitalRead( btn ) == LOW ) {}

    // Store millisecond count when button was released
    button_release_time_ms = millis();
    
    // Calculate button hold time
    button_hold_time_ms = button_release_time_ms - button_press_time_ms;

    // Determine if button press was longer than threshold
    if ( button_hold_time_ms >= button_threshold_ms )
    {
      Serial.println("Long press detected: ");
      Serial.println(button_hold_time_ms);
      Serial.println("ms");
      btncount = 2;
        Serial.println(btncount);
  }
      
      // Execute long press code here or set flag
      
      if ( btncount < 2){

  return;
  
  // Wait while button is pressed
  while ( btncount > 1 ){}

  // Execute once button has been released
  for ( int thisNote = 0; thisNote < sizeof( melody ) / 2; thisNote++ ) 
  {
    // Calculate note duration and update
    int noteDuration = 2000 / noteDurations[thisNote];
    tone( buzzer, melody[thisNote], noteDuration );
    
    // Calculate and execute note delay
    int pauseBetweenNotes = noteDuration * 1.30;
    delay( pauseBetweenNotes );

    // Check for a button press
    if ( digitalRead( btn ) == LOW )
    --btncount; 
    {
      // Wait while button is pressed
      while ( btncount < 2 ){}

      // Break from loop once button is released
      break;    
    }
  }   
 }
    }
    else
    {

      Serial.println("Short press detected: ");
      Serial.println(button_hold_time_ms);
      Serial.println("ms");
      btncount = 1;
      Serial.println(btncount);
    
    }
   // Execute short press code here or set flag
while(btncount == 1) 
  {
  delay(200);
  float temperature;
  float humidity;
  
  if(dht_sensor.measure(&temperature, &humidity))
  {
    Serial.print( "T = " );
    Serial.print( temperature, 1 );
    Serial.print( " deg. C, H = " );
    Serial.print( humidity, 1 );
    Serial.println( "%" );
  Serial.println(count);
  
// max and min encoder settings resets 2 0 
   while( count <= -1 )
   {
    Serial.println("setting not allowed");
     delay(1000);
    Serial.println(count);
    delay(200);
  count = 0;
  delay(1000);

  
}
  
// all is reading temp and adjusting the relay accoridingly
while (temperature <= count)
{
  digitalWrite(relayPin , LOW);
 delay(1000);
 Serial.println("relay off above set temperature");
 Serial.println(count);

 Serial.print( "T = " );
    Serial.print( temperature, 1 );
    Serial.print( " deg. C, H = " );
    Serial.print( humidity, 1 );
    Serial.println( "%" );

while( count >= 34 )
{
    Serial.println("setting not allowed");
     delay(1000);
    Serial.println(count);
    delay(200);
  count = 0;
  delay(1000);
   }

    if (digitalRead( btn ) == LOW)
  {
  //  -- btncount;
    
      digitalWrite(relayPin, LOW); 
    delay(200);
    return;
      }

while (temperature >= count)
{
  digitalWrite(relayPin, HIGH);    // turn the relay off by making the voltage LOW
      delay(1000);
   Serial.println(count);

Serial.print( "T = " );
    Serial.print( temperature, 1 );
    Serial.print( " deg. C, H = " );
    Serial.print( humidity, 1 );
    Serial.println( "%" );
    Serial.println("relay on, below set temperature");
    
    if (digitalRead( btn ) == LOW) 
  {
  //  -- btncount; 
    Serial.println("off");
      digitalWrite(relayPin, LOW); 
    delay(200);
    return;
        }       
      }
    }
  }
 } 

    // encoder 0
  if (!digitalRead(SW) && count != 0) //Read the button press and the count value to 0 when the counter reset
    {
    count = 0;
    Serial.print("count:");
    Serial.println(count);
      }
}  

You declare this variable inside of the if scope, but you try to use it outside of it.

1 Like

ive but the button-hold-time in the else statement still wont work, wont work globaly either.

After you have fixed the variable scope declaration issue, post your new code in a new message, explain wat it's supposed to do and what it does.

If this means that the sketch now compiles, then I think you may have a button debouncing issue. You may want to have a look at the following tutorial.

Or use a button library, I recommend EButton.

The return in this if block means that the code following it will never get executed.

    if ( btncount < 2) {

      return;

      // Wait while button is pressed
      while ( btncount > 1 ) {}

      // Execute once button has been released
      for ( int thisNote = 0; thisNote < sizeof( melody ) / 2; thisNote++ )
      {
        // Calculate note duration and update
        int noteDuration = 2000 / noteDurations[thisNote];
        tone( buzzer, melody[thisNote], noteDuration );

        // Calculate and execute note delay
        int pauseBetweenNotes = noteDuration * 1.30;
        delay( pauseBetweenNotes );

        // Check for a button press
        if ( digitalRead( btn ) == LOW )
          --btncount;
        {
          // Wait while button is pressed
          while ( btncount < 2 ) {}

          // Break from loop once button is released
          break;
        }
      }
1 Like

You should not use Serial or delay() calls in an ISR.

void ClockChanged()
{
  int clkValue = digitalRead(CLK);//Read the CLK pin level
  int dtValue = digitalRead(DT);//Read the DT pin level
  if (lastCLK != clkValue)
  {
    lastCLK = clkValue;
    count += (clkValue != dtValue ? 1 : -1);//CLK and inconsistent DT + 1, otherwise - 1

    Serial.print("count:");
    Serial.println(count);
    delay(200);
  }
}

Since count is being used by the ISR and loop() it needs to be declared with the volatile keyword and also interrupts should be disabled when reading or writing count from loop() otherwise it could get corrupted since it is a multi-byte variable.

1 Like

ive removed the return and its still not working :frowning:

i mean the error is still there the return advice is duly noted many thanks

noted thanks

dont see how this will help me, i understand it though. im assuming it might be my code grammar the button worked fine until i tried to get it to do on or song

i cant get it to fix, the code is meant to. if long press is detected make btncount a 2 while its 2 play song. if its a short press it will let you set the rotary encoder to the temp and turn the relay off and on like an oven

Have a look at your {}s. Scope is inside them so you must declare any local variables within the {} that you intend to use them. Make sure you have a } in the correct place for every {

dont work

    // Check for a button press
    if ( digitalRead( btn ) == LOW )
    --btncount; 
    {
      // Wait while button is pressed
      while ( btncount < 2 ){}

      // Break from loop once button is released
      break;    
    }
  }   
 }
    
    else
    {
   button_hold_time_ms = button_release_time_ms - button_press_time_ms;
      Serial.println("Short press detected: ");
      Serial.println(button_hold_time_ms);
      Serial.println("ms");
      btncount = 1;
      Serial.println(btncount);
    }   

i had the code in 3 chunks pre hand fully tested and worked fine also

That first if looks funny to me. You only have one statement that is conditional on the if and then you open braces which, if I am correct, won’t run (edit, will always run ie won’t run conditionally).

ive took out the error and its working again, guess its not fixable :man_shrugging:

I’m not sure I understand what is not fixable! If you get an error that a variable was not declared in a certain scope then you either need to declare it in that scope or make it global so that it is declared in all scopes or you can pass the value into a new variable contained in the scope that you wish to use that value in.

X
Void Function(){
X visible here
Y
Y visible here
Z not visible here
}
Void other function(){
X visible here
Y not visible here
Z not visible here

If (){
Z
Z visible here
X visible here
Y not visible here
}
}

        // Check for a button press
        if ( digitalRead( btn ) == LOW )
          --btncount;
        {
          // Wait while button is pressed
          while ( btncount < 2 ) {}

          // Break from loop once button is released
          break;
        }

This is really strange for a couple of reasons:

  1. --btncount; gets executed only if digitalRead( btn ) == LOW. The following code block always gets executed:
        {
          // Wait while button is pressed
          while ( btncount < 2 ) {}

          // Break from loop once button is released
          break;
        }

Is that what you intended? I suspect you intended for that code block to be part if the if statement. It is not.

  1. If you ever enter the while loop you will never exit from it since btncount is not modified inside the while loop. If you don't enter the while loop you will break out of the for loop.
1 Like

You need to review the following C++ concepts:

  1. Program structure
  2. Flow control and conditional statements
  3. Looping constructs
  4. Variable scope and lifetime