【问题标题】:Arduino countdown within delay loop延迟循环内的 Arduino 倒计时
【发布时间】:2013-12-07 06:36:39
【问题描述】:

我的第一个 Arduino 项目结果是多么棒的学习体验。我现在想添加一个倒计时,直到读取并显示传感器读数,这将无限重复。我的传感器和 LCD 显示屏工作正常,但我的循环不太正确。我应该使用某种 while() 吗?如何在读数之间的大延迟期间保持计时器滴答作响?

/*Code for self-watering plant with LCD readout*/
// value for LCD params
char ESC = 0xFE;
// analog input pin that the soil moisture sensor is attached to
const int analogInPin = A1;  
// value read from the soil moisture sensor
int sensorValue = 0;
// if the readings from the soil sensor drop below this number, then turn on the pump
int dryValue;  
// countdown timer until next soil reading
int timerValue = 9; 

void setup() {
  pinMode(12, OUTPUT); 
  // initialize serial communications at 9600 bps:
  Serial.begin(9600); 
  // Set the "dry" value of soil on turning on the device
  dryValue = analogRead(analogInPin); 
  // pause before intialize LCD
  delay(2000);
  // Initialize LCD module
  Serial.write(ESC);
  Serial.write(0x41);
  Serial.write(ESC);
  Serial.write(0x51);
  // Set Contrast
  Serial.write(ESC);
  Serial.write(0x52);
  Serial.write(40);
  // Set Backlight
  Serial.write(ESC);
  Serial.write(0x53);
  Serial.write(5);

  //print the dry value to serial
  Serial.print("Dry = " ); 
  Serial.print(dryValue);
  Serial.print("   ");
}

void loop(){
  watering();
  // wait some time (really should be delay(86400000))
  delay(10000);                
}

void printTimer(){  
  // Set cursor line 1, column 16
  Serial.write(ESC);
  Serial.write(0x45);
  Serial.write(0x0F);
  // print the timer value
  Serial.print(timerValue);
  timerValue = timerValue - 1;
  if(timerValue == 0){
  timerValue = 9;
  }
}

void printVal(){
  // set cursor line 2, column 1
  Serial.write(ESC);
  Serial.write(0x45); 
  Serial.write(0x40);  
  // print the sensor to the serial monitor:
  Serial.print("Sensor = " );                       
  Serial.print(sensorValue);
  Serial.print("   ");
  printTimer();
  } 

void watering(){
  // read the analog in value:
  sensorValue = analogRead(analogInPin);                   
  //turn on the water pump for some time if the soil is too dry
  if(sensorValue < dryValue){
    digitalWrite(12, HIGH);
    delay(2000);
    digitalWrite(12, LOW);
  }
  else {
  printVal();
  }
}

【问题讨论】:

    标签: arduino


    【解决方案1】:

    其实很简单:不要拖延。相反,初始化一个计时器以在它溢出或达到某个值时运行例程。检查您的 Arduino 中使用的微控制器的数据表,了解要查找的特定位(请注意,Arduino 库自己使用定时器 0 溢出向量),以及 avr-libc documentation 以了解如何表示定时器的 ISR。然后你的loop() 会变成一个大的sleep,而计时器会为你运行整个节目。

    【讨论】:

    • 感谢您的回复!我将对此进行调查,因为它似乎允许不断检查,但仍允许我最终想要的监控级别..
    【解决方案2】:

    我会像这样为 Arduino 使用定时器库 http://playground.arduino.cc//Code/SimpleTimer

    只需下载库,将其放入速写本的“库”文件夹中,然后重新启动 Arduino IDE 以加载新库。

    那么您的代码将如下所示。基本上,它会在每个循环中更新屏幕,然后每 86400000 毫秒检查一次“浇水”功能。只是为了让您知道此代码每 24 小时(86400000 毫秒)只会检查一次土壤。我认为更好的解决方案是在需要时随时检查土壤和水。但我不是园丁,所以也许有理由每天检查一次。

     #include <SimpleTimer.h>
    
    // the timer object
    SimpleTimer timer;
    
    void setup() {
      Serial.begin(9600);
      timer.setInterval(86400000, watering); // how often you would call your watering function is set with the first variable
    }
    
    void loop() {
      timer.run();
      printTimer();
    }
    
    void printTimer(){  
      // Set cursor line 1, column 16
      Serial.write(ESC);
      Serial.write(0x45);
      Serial.write(0x0F);
      // print the timer value
      Serial.print(timerValue);
      timerValue = timerValue - 1;
      if(timerValue == 0){
        timerValue = 9;
      }
    }
    
    void printVal(){
      // set cursor line 2, column 1
      Serial.write(ESC);
      Serial.write(0x45); 
      Serial.write(0x40);  
      // print the sensor to the serial monitor:
      Serial.print("Sensor = " );                       
      Serial.print(sensorValue);
      Serial.print("   ");
      printTimer();
    } 
    
    void watering(){
      // read the analog in value:
      sensorValue = analogRead(analogInPin);                   
      // send it to the display
      printVal();
      //turn on the water pump for some time if the soil is too dry
      if(sensorValue < dryValue){
        digitalWrite(12, HIGH);
        delay(2000);
        digitalWrite(12, LOW);
      }
    }
    

    【讨论】:

    • 这太完美了,太简单了!非常感谢.. 每天一次的检查是基于(非常)主观的人工监控,所以计时器可能会在测试后调整.. 旁注:我借来的原始代码只是不断检查并根据需要浇水。
    • 编辑:当我运行这个时,“计时器”输出闪烁太快(我猜是每毫秒)没有用..我想我需要多读一点或重新设计整个概念.
    猜你喜欢
    • 2019-02-17
    • 1970-01-01
    • 1970-01-01
    • 2013-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-06
    相关资源
    最近更新 更多