Untitled
unknown
plain_text
10 months ago
5.2 kB
15
Indexable
#include <SoftwareSerial.h>
// -------------------- Pins --------------------
const int trigPin = 7;
const int echoPin = 6;
const int gsmRx = 8; // Arduino RX <= SIM800 TX
const int gsmTx = 9; // Arduino TX => SIM800 RX (use divider!)
SoftwareSerial gsm(gsmRx, gsmTx);
// ---- Buzzer (powered from 5V pin, switched via D4) ----
const int buzzerPin = 4; // buzzer - to D4, buzzer + to 5V
// -------------------- Config --------------------
const char phoneNumber[] = "+1234567890"; // <-- replace with your phone number
const int floodLevel_cm = 10; // alert if distance < this
const unsigned long smsCooldown = 60000UL; // 1 minute between SMS
const int samples = 5; // smoothing samples
// -------------------- State --------------------
unsigned long lastSmsTime = 0;
bool highWaterLatched = false;
// -------------------- Helpers --------------------
bool waitFor(const char* token, unsigned long timeoutMs) {
unsigned long start = millis();
size_t idx = 0;
while (millis() - start < timeoutMs) {
while (gsm.available()) {
char c = (char)gsm.read();
if (c == token[idx]) {
idx++;
if (token[idx] == '\0') return true;
} else {
idx = (c == token[0]) ? 1 : 0;
}
}
}
return false;
}
void flushGSM() {
while (gsm.available()) Serial.write(gsm.read());
}
bool sendAT(const char *cmd, const char *expect, unsigned long timeoutMs = 2000) {
gsm.println(cmd);
bool ok = waitFor(expect, timeoutMs);
flushGSM();
return ok;
}
bool initGSM() {
Serial.println(F("Initializing GSM..."));
for (int i = 0; i < 5; i++) {
gsm.println(F("AT"));
if (waitFor("OK", 1000)) break;
delay(500);
}
sendAT("ATE0", "OK", 1000); // echo off
sendAT("AT+CMEE=2", "OK", 1000); // verbose errors
sendAT("AT+CMGF=1", "OK", 1000); // text mode
sendAT("AT+CSCS=\"GSM\"", "OK", 1000);
// Wait for network registration
for (int tries = 0; tries < 20; tries++) {
gsm.println(F("AT+CREG?"));
if (waitFor("+CREG:", 1000)) {
if (waitFor(",1", 200) || waitFor(",5", 200)) {
flushGSM();
Serial.println(F("Network registered."));
return true;
}
}
flushGSM();
delay(1000);
}
Serial.println(F("Network registration failed (timeout)."));
return false;
}
bool sendSMS(const char* number, const char* msg) {
Serial.println(F("Sending SMS..."));
gsm.print(F("AT+CMGS=\""));
gsm.print(number);
gsm.println(F("\""));
// Wait for '>' prompt
if (!waitFor(">", 5000)) {
flushGSM();
Serial.println(F("No '>' prompt; SMS aborted."));
return false;
}
gsm.print(msg);
gsm.write(26); // Ctrl+Z
bool gotRef = waitFor("+CMGS:", 15000);
bool gotOK = waitFor("OK", 5000);
flushGSM();
if (gotRef && gotOK) {
Serial.println(F("SMS sent OK."));
return true;
} else {
Serial.println(F("SMS send failed."));
return false;
}
}
// -------------------- Ultrasonic --------------------
long readDistanceOnce() {
digitalWrite(trigPin, LOW);
delayMicroseconds(3);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
unsigned long duration = pulseIn(echoPin, HIGH, 30000UL);
if (duration == 0) return -1;
return (long)(duration * 0.034 / 2.0); // cm
}
long readDistanceSmoothed() {
long vals[samples];
int count = 0;
for (int i = 0; i < samples; i++) {
long d = readDistanceOnce();
if (d > 0 && d < 400) vals[count++] = d;
delay(20);
}
if (count == 0) return -1;
// simple sort for median
for (int i = 1; i < count; i++) {
long key = vals[i];
int j = i - 1;
while (j >= 0 && vals[j] > key) { vals[j + 1] = vals[j]; j--; }
vals[j + 1] = key;
}
return vals[count / 2];
}
// -------------------- Buzzer control --------------------
void buzzerOn() {
digitalWrite(buzzerPin, LOW); // sink current to GND (buzzer + tied to 5V)
}
void buzzerOff() {
digitalWrite(buzzerPin, HIGH); // stop current (both sides at 5V)
}
// -------------------- Arduino --------------------
void setup() {
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(buzzerPin, OUTPUT);
buzzerOff(); // start silent
Serial.begin(9600);
gsm.begin(9600);
delay(1000);
initGSM();
Serial.println(F("SIM800L Flood Alert System Ready"));
}
void loop() {
long distance = readDistanceSmoothed();
if (distance < 0) {
Serial.println(F("Invalid reading."));
buzzerOff(); // keep silent on invalid read
delay(1000);
return;
}
Serial.print(F("Distance (cm): "));
Serial.println(distance);
bool waterHigh = (distance > 0 && distance < floodLevel_cm);
// SMS on first entry to high water (with cooldown)
if (waterHigh && !highWaterLatched && (millis() - lastSmsTime > smsCooldown)) {
bool ok = sendSMS(phoneNumber, "FLOOD ALERT! Water level is HIGH.");
if (ok) lastSmsTime = millis();
highWaterLatched = true;
}
// Reset latch when water clearly recedes
if (!waterHigh && distance > (floodLevel_cm + 2)) {
highWaterLatched = false;
}
// Drive buzzer: continuous ON when water high
if (waterHigh) {
buzzerOn();
} else {
buzzerOff();
}
delay(200); // small delay for loop
}Editor is loading...
Leave a Comment