# define trigPin 13
# define echoPin 12
# define led 11
# define rele 10
# define buzzer 9
# define ACK 7 // must acknowledge fault to egenrize
int buzzerState = 0;
unsigned long currentMillis;
unsigned long previousMillis;
const long interval = 777; // was 5000 - life too short!
void setup()
{
Serial.begin (115200); // it's 2022, not 1984
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(ACK, INPUT_PULLUP);
pinMode(led, OUTPUT);
pinMode(rele, OUTPUT);
pinMode(buzzer, OUTPUT);
}
void loop()
{
long distance;
distance = getEcho();
currentMillis = millis();
bool acknowledge = !digitalRead(ACK); // reset alarm mecahnism?
static bool operate = true;
bool enteredAlarm = false; // edges
static unsigned char alarmState; // 1 = too close
if (distance < 10) {
if (acknowledge) enteredAlarm = true; // no reset if we still on the ceiling
if (!alarmState) {
alarmState = 1;
enteredAlarm = 1;
}
digitalWrite(led, HIGH);
digitalWrite(rele, LOW);
operate = false; // lockout open relay, LED on
}
else { // distance > 10
if (alarmState) {
alarmState = 0;
}
if (operate) {
digitalWrite(led, LOW);
digitalWrite(rele, HIGH);
}
else if (acknowledge) operate = true;
}
beepMachine(enteredAlarm);
// delay(20); // until I am sure I don't need to
}
enum {IDLE, OFF, ON,}; // yuck. anonynous enum. So sue me.
# define BEEPS 3 // beep three times each
void beepMachine(bool enter)
{
static unsigned long lastBeep;
static unsigned char beepCount;
static unsigned char beepState = IDLE;
unsigned long now = currentMillis; // I know I know
bool timeTo = now - lastBeep > 125;
switch (beepState) {
case IDLE :
if (!enter) break; //idling, no alarm raised, so
beepCount = BEEPS;
timeTo = true;
beepState = OFF;
enter = false;
case OFF :
if (!timeTo) break;
if (!beepCount) {
beepState = IDLE;
break;
}
tone(buzzer, 440);
beepState = ON;
lastBeep = now;
break;
case ON :
if (!timeTo) break;
noTone(buzzer);
beepState = OFF;
beepCount--;
lastBeep = now;
break;
}
if (enter) { // an entry not handled by having been IDLE
// just makes the alarm keep sounding
beepCount = BEEPS;
}
}
long getEcho()
{
long duration, distance;
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration / 2) / 29.1;
return distance;
}