如何在 Arduino Uno 中更改来自传感器的输入时仅启用伺服?

问题描述 投票:0回答:1

我尝试为自动浇水系统编写一个 Arduino Uno 程序。 我想让伺服器在 5 秒延迟后关闭并保持禁用状态,直到传感器的输入发生变化。 但是我的伺服器在每次循环迭代中都会重新激活。只有当条件不再满足时,它才会被禁用。我该如何解决?

规格:

  1. 两个电位器(这些电位器将替换为 BH1170 和土壤湿度传感器,但由于 Wokwi 没有这些传感器,我使用电位器作为替代品)。
  2. Arduino Uno R3
  3. 用于水位监测的超声波传感器
  4. LCD I2C 16x2 显示器
  5. 伺服(我用这个代替迷你水泵)
  6. Pienzo 蜂鸣器(当水位过低(低于 80)时应开启)

这是我的代码:

#include <LiquidCrystal_I2C.h>
#include <Servo.h>

#define SOIL_SENSOR A0
#define ULTRASONIC_TRIG 13
#define ULTRASONIC_ECHO A1
#define POTENTIOMETER A2
#define SERVO_PIN 3
#define PIEZO_PIN 9

#define SERVO_DURATION 5000

#define ULTRASONIC_THRESHOLD 80
#define SOIL_THRESHOLD 500
#define POTENTIOMETER_THRESHOLD 500

int soilValue = 0;
int ultrasonicValue = 0;
int potentiometerValue = 0;
int flag = 0;

int new_soilValue = 0;
int new_ultrasonicValue = 0;
int new_potentiometerValue 0;

Servo servo;
LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup() {
  pinMode(PIEZO_PIN, OUTPUT);
  pinMode(ULTRASONIC_TRIG, OUTPUT);
  pinMode(ULTRASONIC_ECHO, INPUT);
  pinMode(SOIL_SENSOR, INPUT);
  pinMode(POTENTIOMETER, INPUT);
  
  servo.attach(SERVO_PIN);
  
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("Soil:");
  lcd.setCursor(0,1);
  lcd.print("Light:");
}

void loop() {

  new_soilValue = analogRead(SOIL_SENSOR);
  new_ultrasonicValue = getUltrasonicDistance();
  new_potentiometerValue = analogRead(POTENTIOMETER);
  
  lcd.setCursor(5, 0);
  lcd.print(new_soilValue);
  lcd.setCursor(6, 1);
  lcd.print(new_potentiometerValue);

  if (new_soilValue != soilValue || new_potentiometerValue != potentiometerValue || new_ultrasonicValue != ultrasonicValue) {
    flag = 1;
    soilValue = new_soilValue;
    potentiometerValue = new_potentiometerValue;
    ultrasonicValue = new_ultrasonicValue;

    if (flag == 1) {
      if(soilValue < SOIL_THRESHOLD && potentiometerValue > POTENTIOMETER_THRESHOLD && ultrasonicValue < ULTRASONIC_THRESHOLD) {
        servo.write(180);
        delay(SERVO_DURATION);
        servo.write(0);
      } else if (new_ultrasonicValue > ULTRASONIC_THRESHOLD) {
        digitalWrite(PIEZO_PIN, HIGH);
        tone(9, 1000);
        delay(500);
        noTone(9);
        delay(500);
      } 
      flag = 0;
    }
  }
  servo.write(0);
}

int getUltrasonicDistance() {
  digitalWrite(ULTRASONIC_TRIG, LOW);
  delayMicroseconds(2);
  digitalWrite(ULTRASONIC_TRIG, HIGH);
  delayMicroseconds(10);
  digitalWrite(ULTRASONIC_TRIG, LOW);
  
  int duration = pulseIn(ULTRASONIC_ECHO, HIGH);
  int distance = duration * 0.034 / 2;
  return distance;
}

这是截图:

arduino iot microcontroller arduino-uno arduino-c++
1个回答
0
投票

显然是导致问题的超声波传感器。即使我没有改变它,它也会不断改变自己的价值。从 if 语句中删除超声波值解决了它。谢谢大家。

if (newSoilValue != soilValue || newPotentiometerValue != potentiometerValue) {
    soilValue = newSoilValue;
    potentiometerValue = newPotentiometerValue;
    ultrasonicValue = newUltrasonicValue;
    sensorValuesChanged = true;
  } else {
    sensorValuesChanged = false;
  }
© www.soinside.com 2019 - 2024. All rights reserved.