我正在使用 arduino 构建一个呼气测醉器系统,该系统会在用户单击按钮时执行测试。如果测试成功(落在阈值内),则引擎将打开。否则,发动机根本不会启动,如果低于某个阈值,液晶显示屏上会显示一条消息,表明未执行任何测试。系统还会在每 40 秒过去后定期检查一次。系统进行此检查后,如果用户的酒精浓度高于阈值,则会触发蜂鸣器并关闭引擎。如果低于此阈值,则发动机保持开启状态,液晶显示屏显示(测试完成,安全驾驶)
#include Wire.h
#include LiquidCrystal_I2C.h
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int BUZZER_PIN = 2;
const int BUTTON_PIN = 3;
const int LED_PIN = 4;
const int RELAY_PIN = 5;
const int MQ3_PIN = A0;
const int CHECK_INTERVAL = 40000; // 40secs
const int ALCOHOL_THRESHOLD = 700; // alcohol threshold
const int NO_TEST_THRESHOLD = 190; // alcohol level below which the test is considered invalid
我在这里初始化了引脚和系统的阈值
unsigned long lastCheckTime = 0; bool engineOn = false; unsigned long lastTestTime = 0; // Add this variable
这里我设置了变量来保存最后一次检查时间和测试时间以及引擎状态
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(LED_PIN, OUTPUT);
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, HIGH); // trigger relay off
lcd.init();
lcd.backlight();
lcd.begin(16, 2);
lcd.print("Breathalyzer");
// Wait for MQ3 sensor to warm up
delay(20000);
lcd.clear();
lcd.print("system-ready");
}
用于初始化系统的无效设置
void loop() {
if (millis() - lastCheckTime \> CHECK_INTERVAL) {
lastCheckTime = millis();
if (engineOn && analogRead(MQ3_PIN) \> ALCOHOL_THRESHOLD) {
// Engine is on and alcohol level is too high, turn off engine
digitalWrite(LED_PIN, HIGH);
tone(BUZZER_PIN, 5000);
lcd.clear();
lcd.print("Turning engine");
lcd.setCursor(0, 1);
lcd.print("off...");
delay(3000);
digitalWrite(RELAY_PIN, HIGH);
digitalWrite(LED_PIN, LOW);
noTone(BUZZER_PIN);
engineOn = false;
}
lastTestTime = millis();
}
// Check if it's time to perform a test
if (engineOn && (millis() - lastTestTime >= CHECK_INTERVAL)) {
digitalWrite(LED_PIN, HIGH);
tone(BUZZER_PIN, 5000);
lcd.clear();
lcd.print("Performing test...");
delay(2000);
int alcoholLevel = analogRead(MQ3_PIN);
if (alcoholLevel < NO_TEST_THRESHOLD) {
// No test was performed, don't start engine
noTone(BUZZER_PIN);
digitalWrite(LED_PIN, LOW);
lcd.clear();
lcd.print("No test");
lcd.setCursor(0, 1);
lcd.print("performed!");
digitalWrite(RELAY_PIN, HIGH);
} else if (alcoholLevel > ALCOHOL_THRESHOLD) {
// Alcohol level is too high, don't start engine
noTone(BUZZER_PIN);
digitalWrite(LED_PIN, HIGH);
delay(2000);
lcd.clear();
lcd.print("Alcohol level");
lcd.setCursor(0, 1);
lcd.print("too high!");
digitalWrite(RELAY_PIN, HIGH); // Turn off relay to prevent engine from starting
digitalWrite(LED_PIN, LOW);
} else {
// Alcohol level is acceptable, start engine
tone(BUZZER_PIN, 4000);
noTone(BUZZER_PIN);
lcd.clear();
lcd.print("test done");
lcd.setCursor(0, 1);
lcd.print("Drive safely");
digitalWrite(RELAY_PIN, LOW); // Turn on relay to start engine
delay(1000);
engineOn = true;
}
digitalWrite(LED_PIN, LOW); // Turn off LED after testing
lastTestTime = millis();
}
// Wait for button press
while (digitalRead(BUTTON_PIN) == LOW) {
// Wait for button press
delay(100);
}
// Debounce delay after button is pressed
delay(100);
// Check button state
if (digitalRead(BUTTON_PIN) == LOW) {
digitalWrite(LED_PIN, HIGH); // Turn off LED before alcohol test
delay(1000);
if (engineOn) {
// Engine is already on, turn it off
digitalWrite(RELAY_PIN, HIGH);
engineOn = false;
lcd.clear();
lcd.print("Engine off");
delay(1000);
digitalWrite(LED_PIN, LOW);
} else {
// Button is pressed, do alcohol test
tone(BUZZER_PIN, 5000);
lcd.clear();
lcd.print("breathe into sensor");
delay(2000); // Wait for the buzzer to complete its sound
lcd.clear();
lcd.print("Testing...");
delay(2000);
noTone(BUZZER_PIN);
digitalWrite(LED_PIN, HIGH); // Turn on LED to indicate testing
int alcoholLevel = analogRead(MQ3_PIN);
if (alcoholLevel < NO_TEST_THRESHOLD) {
// No test was performed, don't start engine
noTone(BUZZER_PIN);
digitalWrite(LED_PIN, LOW);
lcd.clear();
lcd.print("No test");
lcd.setCursor(0, 1);
lcd.print("performed!");
delay(1000);
digitalWrite(RELAY_PIN, HIGH);
lcd.clear();
lcd.print("restart engine");
}
else if (alcoholLevel > ALCOHOL_THRESHOLD) {
// Alcohol level is too high, don't start engine
noTone(BUZZER_PIN);
digitalWrite(LED_PIN, HIGH);
delay(2000);
lcd.clear();
lcd.print("Alcohol level");
lcd.setCursor(0, 1);
lcd.print("too high!");
digitalWrite(RELAY_PIN, HIGH); // Turn off relay to prevent engine from starting
digitalWrite(LED_PIN, LOW);
}
else {
// Alcohol level is acceptable, start engine
tone(BUZZER_PIN, 4000);
noTone(BUZZER_PIN);
lcd.clear();
lcd.print("Starting Engine");
digitalWrite(RELAY_PIN, LOW); // Turn on relay to start engine
delay(1000);
lcd.clear();
lcd.print("Engine on");
engineOn = true;
}
digitalWrite(LED_PIN, LOW); // Turn off LED after testing
}
}
}
void 循环基本上描述了运行并处理按钮状态的代码。
所以这就是我遇到问题的地方。
void loop() {
if (millis() - lastCheckTime > CHECK_INTERVAL) {
lastCheckTime = millis();
if (engineOn && analogRead(MQ3_PIN) > ALCOHOL_THRESHOLD) {
// Engine is on and alcohol level is too high, turn off engine
digitalWrite(LED_PIN, HIGH);
tone(BUZZER_PIN, 5000);
lcd.clear();
lcd.print("Turning engine");
lcd.setCursor(0, 1);
lcd.print("off...");
delay(3000);
digitalWrite(RELAY_PIN, HIGH);
digitalWrite(LED_PIN, LOW);
noTone(BUZZER_PIN);
engineOn = false;
}
lastTestTime = millis();
}
// Check if it's time to perform a test
if (engineOn && (millis() - lastTestTime >= CHECK_INTERVAL)) {
digitalWrite(LED_PIN, HIGH);
tone(BUZZER_PIN, 5000);
lcd.clear();
lcd.print("Performing test...");
delay(2000);
int alcoholLevel = analogRead(MQ3_PIN);
if (alcoholLevel < NO_TEST_THRESHOLD) {
// No test was performed, don't start engine
noTone(BUZZER_PIN);
digitalWrite(LED_PIN, LOW);
lcd.clear();
lcd.print("No test");
lcd.setCursor(0, 1);
lcd.print("performed!");
digitalWrite(RELAY_PIN, HIGH);
} else if (alcoholLevel > ALCOHOL_THRESHOLD) {
// Alcohol level is too high, don't start engine
noTone(BUZZER_PIN);
digitalWrite(LED_PIN, HIGH);
delay(2000);
lcd.clear();
lcd.print("Alcohol level");
lcd.setCursor(0, 1);
lcd.print("too high!");
digitalWrite(RELAY_PIN, HIGH); // Turn off relay to prevent engine from starting
digitalWrite(LED_PIN, LOW);
} else {
// Alcohol level is acceptable, start engine
tone(BUZZER_PIN, 4000);
noTone(BUZZER_PIN);
lcd.clear();
lcd.print("test done");
lcd.setCursor(0, 1);
lcd.print("Drive safely");
digitalWrite(RELAY_PIN, LOW); // Turn on relay to start engine
delay(1000);
engineOn = true;
}
digitalWrite(LED_PIN, LOW); // Turn off LED after testing
lastTestTime = millis();
}
我似乎无法理解使这项工作有效的逻辑。我希望系统每 40 秒检查一次酒精含量,并且仅在发动机开启时检查一次。进行此检查时,它会关闭引擎或显示驱动器安全消息。