Problem with detecting a difference between FLOATING and LOW?

I'm trying to use an Arduino Uno with just two pins. When the input pin is connected to ground, I need the output pin to go HIGH for two seconds after the FALLING logic level of the input pin. Otherwise, the input pin is connected to an open circuit (the input is an open drain signal), so I tried pulling the input pin HIGH with INPUT_PULLUP. Unfortunately, testing this code has proven unpredictable results. Sometimes the output pin is always HIGH and at other times it is always LOW. I've tried several different pin numbers to see if one of the pins is broken, also with unpredictable results. My wiring is correct, I've checked it many times. Am I implementing my solution in the code correctly?

Input pin: Ground or Open Circuit (open drain signal) Output pin: High for two seconds when activated

const int BMSDischargeEnablePin = 3; //BMS discharge enable open drain output
const int buzzerPin = 5; //to buzzer circuit
//Interrupts can only be used for pins 2 and 3 on the Arduino Uno


void setup()
{
    pinMode(buzzerPin, OUTPUT);
    pinMode(BMSDischargeEnablePin, INPUT_PULLUP);
    attachInterrupt(BMSDischargeEnablePin, buzz, FALLING);    
    
    //Pulled HIGH when discharge enable off (open circuit)
    //Low when discharge enable on (closed circuit)
}

void loop()
{

}

void buzz()
{
  digitalWrite(buzzerPin, HIGH); // switch buzzer on
  delay(2000); // wait for two seconds
  digitalWrite(buzzerPin, LOW); // switch buzzer off
}

If the signal is either floating or HIGH then you have to pull it LOW with an external pull down resistor.

The signal should be either FLOATING or LOW. Presumably, that's why I need to pull the input HIGH with the internal resistor...

What exactly is connected to this pin?

void buzz()
{
  digitalWrite(buzzerPin, HIGH); // switch buzzer on
  delay(2000); // wait for two seconds
  digitalWrite(buzzerPin, LOW); // switch buzzer off
}

Ooops. Didn’t see that. That middle line will hang that ISR. ISR should be super short, set a flag and get out. The delay() function relies on interrupts to function and those interrupts are disabled inside your ISR, so delay can never get through and it will hang.

Thank you, I did not know the delay function used interrupts. I hope that is the only problem. I will test new code tonight sometime probably, and update this thread.

RTDS.jpg

Try to get a sketch to detect the levels without interrupts. Just something simple to tell if you can see it or not. Once you know the hardware is good, then you can go back to :/ trying to set up an interrupt on it.

Alright guys so I got some working code. For some reason, I couldn't get interrupts to work with INPUT_PULLUP. I also couldn't get INPUT_PULLUP to work at all for pin 3. Not sure what the problem is, though.

const int BMSDischargeEnablePin = 2; //BMS discharge enable open drain output
const int buzzerPin = 5; //to buzzer circuit
int state;//False for off, True for Buzz
//Interrupts can only be used for pins 2 and 3 on the Arduino Uno


void setup()
{
    state = 1;
    pinMode(buzzerPin, OUTPUT);
    pinMode(BMSDischargeEnablePin, INPUT_PULLUP); 
    
    //Pulled HIGH when discharge enable off (open circuit)
    //Low when discharge enable on (closed circuit)
}

void loop()
{
    if ((state == 1) && (digitalRead(BMSDischargeEnablePin) == LOW)){
      digitalWrite(buzzerPin, HIGH); // switch buzzer on
      delay(2000); // wait for two seconds
      digitalWrite(buzzerPin, LOW); // switch buzzer off
      state = 0;
    }
    else if (digitalRead(BMSDischargeEnablePin) == HIGH){
      delay(100);
      state = 1;
    }
}

That code looks like it should work, as long as your input pin falling events are more than 2 seconds apart.

palomban: I couldn't get interrupts to work

That'll be because you were using delay within your ISR. That doesn't work. delay uses interrupts and is therefore not useable within an ISR.

Another approach would be to just set a flag within your ISR and then use your loop to do the output and "delaying" (yuk).