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);
}
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.
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.
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);
}
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.
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.