Digitalwrite not working after other program code runs, but works when run immediately

I'm trying to make an alarm system for a sump pump in the crawl space of a house that sets off an alarm and starts an alarm and sends an email notification when the temperature is too low, the temperature sensor fails, or the test button or sump pump overflow float switch (These are wired together) is closed. I noticed that if I forced the variable that controls if the alarm should be on to the alarm setting (0 in this case), the alarm works, but if I run the code as intended, running through the temperature sensing and button-checking cycle first, the alarm doesn't sound.

This project is based off an Arduino Uno clone with the following wired to it:

  • Arduino Ethernet Shield 2 (used to send the email notification)

  • LED and buzzer connected to pin 13

  • Normally open push button attached to pin 7 (this triggers the alarm)

  • DHT11 temperature sensor attached to pin 2

The alarm issue listed above is the only problem I have with the code. I have tried different things to fix this issue, but I can't seem to figure this out and I figured that the people on the forum would know how to fix this issue better than me. I understand how the code works, but I am not that experienced with Arduino yet.

Here is the code (I removed the URLs for security):

#include <SPI.h>  //Libraries
#include <Ethernet.h>
#include "DHT.h"

const int buttonPin = 7;  //TEST/ALARM
const int ledPin = 13;    //using the built in LED
int buttonState = 0;
int tempflag = 0;
int noalarm = 1;

int ledState = LOW;
unsigned long previousMillis = 0;
const long interval = 1000;

byte mac[] = {0xA8, 0x61, 0x0A, 0xAE, 0x88, 0x22}; //Ethernet Shield MAC address

EthernetClient client; // Ethernet shield data
int    HTTP_PORT   = 80;
String HTTP_METHOD = "GET";
char   HOST_NAME[] = "maker.ifttt.com";
String PATH_NAME   = "/trigger/sensor_read_fail/with/key/cq0RSP57PdjoEmdyEqE1qd";//Replace PATH_NAME with /trigger/ and so on.

DHT dht(2, DHT11); //Initialize DHT Sensor

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(13, OUTPUT);
  Serial.begin(9600);
  delay(500);
  Serial.println(tempflag);
  Serial.println(noalarm);
  Serial.println("Welcome to the Alert System!");
  dht.begin();
}

void loop() {
  if (noalarm == 0) {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      // save the last time you blinked the LED
      previousMillis = currentMillis;

      // if the LED is off turn it on and vice-versa:
      if (ledState == LOW) {
        ledState = HIGH;
      } else {
        ledState = LOW;
      }

      // set the LED with the ledState of the variable:
      digitalWrite(13, ledState);
      Serial.println("test");
    }
  }
  if (noalarm == 1) {
    Serial.println("Alarm is Not Active.  No further action needed");
    //digitalWrite(13, HIGH);
    delay(2000);
    buttonState = digitalRead(buttonPin);
    if (buttonState == HIGH) {
      String PATH_NAME   = "*REDACTED*";
      Serial.println("Pump alert or test button triggered!");
      AlarmOn();
    }//END OF ALARM INIT
    float f = dht.readTemperature(true);
    if (isnan(f)) {
      Serial.println(F("Failed to read from DHT sensor!"));
      tempflag++;
      Serial.println(tempflag);
      if (tempflag > 4) {
        String PATH_NAME   = "*REDACTED*";
        Serial.println("DHT sensor failure limit reached!");
        AlarmOn();
      }
    }// END OF TEMP FAIL ALARM
    Serial.print("Current Temperature from sensor:");
    Serial.print(f);
    Serial.print(F("°F"));
    Serial. println();
    if (45.001 > f) {
      String PATH_NAME   = "*REDACTED*";
      Serial.println("Low Temperature detected!");
      AlarmOn();
    }// END OF TEMP LOW ALARM
  }
}
void AlarmOn() {
  //MAKE SURE THAT String PATH is set to the desired email prior to running this function
  Serial.println("Starting alarm...");
  noalarm = 0;
  Serial.println("Attempting to obtain IP address...");
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to obtain an IP address using DHCP");
  }
  // connect to web server on port 80:
  Serial.println("Connecting...");
  if (client.connect(HOST_NAME, HTTP_PORT)) {
    // if connected:
    Serial.println("Connected to server");
    client.println("GET " + PATH_NAME + " HTTP/1.1");
    client.println("Host: " + String(HOST_NAME));
    client.println("Connection: close");
    client.println(); // end HTTP header

    while (client.connected()) {
      if (client.available()) {
        // read an incoming byte from the server and print it to serial monitor:
        char c = client.read();
        Serial.print(c);
      }
    }
    // the server's disconnected, stop the client:
    client.stop();
    Serial.println();
    Serial.println("disconnected");
    Serial.println("Email send completed!");
  } else {// if not connected:
    Serial.println("connection failed");
    Serial.println("Email send failed");
  }
  Serial.println("Starting audio and light alarm...");
  noalarm = 0;
  delay(500);
}

Here is a quick sketch of the electrical layout:


(Yes, it isn't a perfect schematic. I tried to throw it together quickly for the purpose of asking this question)

Welcome to the forum

Let's start with the obvious question which is, how is the button pin wired ? You are testing whether its state goes HIGH but what, if anything, keeps it in a LOW state when the button is not pressed ? Do you have a pulldown resistor in place or is the pin floating at an unknown voltage, maybe HIGH, maybe LOW, maybe changing due to outside influences ?

The button is wired to a pull-down resistor as seen in my drawing. The button has worked fine for me in my testing. It is mainly the LED that I have problems with, which I believe is not a hardware issue due to the fact that it works if I have the noalarm variable set to trigger the alarm on startup.

I see it initialised to 1, printed, tested and set to 0 variously in the code.

Nowhere do I see it set to 1 because of program logic.

I am looking through the tiny window, have I missd something?

a7

If the code is set to 1, the alarm doesn't go off, instead leading it to read the temperature and button state. If the alarm is triggered, it should be set to 0, which will make the loop run forever until the Arduino is reset with either the reset button or a power cycle. I see how the way I originally wrote this in the code is confusing.

What output do you get in the serial console?

DHT Sensor is not connected. This triggers the alarm.

Where the output is "test", the LED should be blinking but isn't.

17:24:21.431 -> 0
17:24:21.431 -> 1
17:24:21.431 -> Welcome to the Alert System!
17:24:21.431 -> Alarm is Not Active. No further action needed
17:24:23.471 -> Failed to read from DHT sensor!
17:24:23.518 -> 1
17:24:23.518 -> Current Temperature from sensor:nan°F
17:24:23.565 -> Alarm is Not Active. No further action needed
17:24:25.607 -> Failed to read from DHT sensor!
17:24:25.607 -> 2
17:24:25.607 -> Current Temperature from sensor:nan°F
17:24:25.654 -> Alarm is Not Active. No further action needed
17:24:27.696 -> Failed to read from DHT sensor!
17:24:27.742 -> 3
17:24:27.742 -> Current Temperature from sensor:nan°F
17:24:27.789 -> Alarm is Not Active. No further action needed
17:24:29.832 -> Failed to read from DHT sensor!
17:24:29.832 -> 4
17:24:29.832 -> Current Temperature from sensor:nan°F
17:24:29.878 -> Alarm is Not Active. No further action needed
17:24:31.921 -> Failed to read from DHT sensor!
17:24:31.968 -> 5
17:24:31.968 -> DHT sensor failure limit reached!
17:24:32.014 -> Starting alarm...
17:24:32.014 -> Attempting to obtain IP address...
17:25:32.784 -> Failed to obtain an IP address using DHCP
17:25:32.831 -> Connecting...
17:25:32.831 -> connection failed
17:25:32.878 -> Email send failed
17:25:32.878 -> Starting audio and light alarm...
17:25:33.343 -> Current Temperature from sensor:nan°F
17:25:33.390 -> test
17:25:34.366 -> test
17:25:35.338 -> test
17:25:36.359 -> test
17:25:37.381 -> test
17:25:38.355 -> test
17:25:39.376 -> test
17:25:40.396 -> test
17:25:41.371 -> test
17:25:42.391 -> test
17:25:43.368 -> test
17:25:44.390 -> test
17:25:45.367 -> test

I cut out the real DHT and all the internet stuff. Carefully enough I hope to preserve your logic.

I put it in the wokwi simulator, play with it here.

I added pushbutton to simunlate DHT failure and low temp conditions.

As far as I can tell, it functions correctly. I haven't taken a good look, and I will reread your complaint as of this moment.

Naturally I can only print, not actually make the real alarm process play out. But the printing looks plausible.

Could take the link above, give it a spin and tell us in what way is it not working yet?

// https://wokwi.com/projects/348890323831751250

const int buttonPin = 7;  // TEST/ALARM

const int noDHT = 6;
const int lowTemp = 5;

const int ledPin = 12;    // not using the built in LED
int buttonState = 0;
int tempflag = 0;
int noalarm = 1;

int ledState = LOW;
unsigned long previousMillis = 0;
const long interval = 1000;

void setup() {
  pinMode(ledPin, OUTPUT);

// I got no hardware, so these simunlate two fault conditions
  pinMode(noDHT, INPUT_PULLUP);
  pinMode(lowTemp, INPUT_PULLUP);

  Serial.begin(9600);
  delay(500);
  Serial.println(tempflag);
  Serial.println(noalarm);
  Serial.println("Welcome to the Alert System!");
}

void loop() {
  if (noalarm == 0) {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      // save the last time you blinked the LED
      previousMillis = currentMillis;

      // if the LED is off turn it on and vice-versa:
      if (ledState == LOW) {
        ledState = HIGH;
      } else {
        ledState = LOW;
      }

      // set the LED with the ledState of the variable:
      digitalWrite(ledPin, ledState);
      Serial.println("since noalarm == 0");
    }
  }
  if (noalarm == 1) {
    Serial.println("Alarm is Not Active.  No further action needed");
    //digitalWrite(ledPin, HIGH);
    delay(2000);
    buttonState = digitalRead(buttonPin);
    if (buttonState == HIGH) {
      String PATH_NAME   = "*REDACTED*";
      Serial.println("Pump alert or test button triggered!");
      AlarmOn();
    }//END OF ALARM INIT

    float f = 47.0 - 4.0 * (digitalRead(lowTemp) ? 0.0 : 1.0);
   
    if (!digitalRead(noDHT)) {
      Serial.println(F("Failed to read from DHT sensor!"));
      tempflag++;
      Serial.println(tempflag);
      if (tempflag > 4) {
        String PATH_NAME   = "*REDACTED*";
        Serial.println("DHT sensor failure limit reached!");
        AlarmOn();
      }
    }// END OF TEMP FAIL ALARM
    Serial.print("Current Temperature from sensor:");
    Serial.print(f);
    Serial.print(F("°F"));
    Serial. println();
    if (45.001 > f) {
      String PATH_NAME   = "*REDACTED*";
      Serial.println("Low Temperature detected!");
      AlarmOn();
    }// END OF TEMP LOW ALARM
  }
}

void AlarmOn() {
  //MAKE SURE THAT String PATH is set to the desired email prior to running this function
  Serial.println("Starting alarm...");
  noalarm = 0;

  // connect to web server on port 80:
  Serial.println("Connecting...");


    Serial.println("connection failed");
    Serial.println("Email send failed");

  Serial.println("Starting audio and light alarm...");

  noalarm = 0;
  delay(500);
}

TIA

a7

OK, if I read you, it is only the failure for the LED to blink that is vexing you.

I don't like using pin 13 (unlucky!), so my LED is on pin 12 and... it blinks. Proving that pin 13 is unlucky. :expressionless:

a7

ok, I'll try pin 12 and see how that goes

Is it maybe because you've setup pin 13 twice?
pinMode(ledPin, OUTPUT);
pinMode(13, OUTPUT);
These are both pin 13. I'm not sure if it would cause the problem though? Try take one of those lines out and see what happens.

That is not a problem, just a waste of a few bytes and a few us. Or maybe optimised out.

And I just moved to pin 13 in the simulator and it works. As it should IRL.

a7

I tried pin 12 and that didn't work, but I tried pin 10 and it appears to be working. Thank you all for your help. I'll test all parts of my code more extensively and see if it keeps working.

Yeah, test those output pins with nothing connected.

And/or look for something your attached hardware does that isn't simulated.

I don't see how there would be any interaction, but I am not looking either. Nothing seemed very alarming in your code. <- See what I did there?

a7

:rofl: :rofl: :rofl:

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