首页 > 解决方案 > 将延迟编写的代码转换为millis()

问题描述

我有一个我在 Arduino 上编写的基本代码,但是,我需要将延迟更改为 Millis。

无论我做什么,我都无法让它工作,它总是卡在红灯上,永远不会变绿。

我发布了原始延迟代码,因为我使用 Millis 编写的代码似乎没用,并且可能会混淆我正在尝试做的事情。

const int redPin = 2;
const int yellowPin = 3;
const int greenPin = 4;

int redDuration = 10000;
int greenDuration = 5000;

void setup() {
  pinMode(redPin, OUTPUT);
  pinMode(yellowPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
}

void loop() {
  setTrafficLight(1,0,0);
  delay(redDuration);
  setTrafficLight(1,1,0);
  delay(2000);
  setTrafficLight(0,0,1);
  delay(greenDuration);
  setTrafficLight(0,1,0);
  delay(2000);
}

void setTrafficLight(int redState, int yellowState, int greenState) {
  digitalWrite(redPin, redState);
  digitalWrite(yellowPin, yellowState);
  digitalWrite(greenPin, greenState);
}

标签: c++arduinoarduino-unoarduino-idearduino-c++

解决方案


  1. 节省开始等待的时间。
  2. 如果当前时间与开始时间之差成为等待时间,则进入下一个状态。
const int redPin = 2;
const int yellowPin = 3;
const int greenPin = 4;

int redDuration = 10000;
int greenDuration = 5000;

unsigned long startTime;
int status = 0; // using enum may be better

void setup() {
  pinMode(redPin, OUTPUT);
  pinMode(yellowPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  startTime = millis();
  status = 0;
}

void loop() {
  unsigned long currentTime = millis();
  switch (status) {
    case 0: // initial state
      setTrafficLight(1, 0, 0);
      status = 1;
      break;
    case 1: // waiting instead of delay(redDuration)
      if (currentTime - startTime >= redDuration) {
        setTrafficLight(1, 1, 0);
        startTime = currentTime;
        status = 2;
      }
      break;
    case 2: // waiting instead of first delay(2000)
      if (currentTime - startTime >= 2000) {
        setTrafficLight(0, 0, 1);
        startTime = currentTime;
        status = 3;
      }
      break;
    case 3: // waiting instead if delay(greenDuration)
      if (currentTime - startTime >= greenDuration) {
        setTrafficLight(0, 1, 0);
        startTime = currentTime;
        status = 4;
      }
      break;
    case 4: // waiting instead of second delay(2000)
      if (currentTime - startTime >= 2000) {
        startTime = currentTime;
        status = 0;
      }
      break;
    default: // for in-case safety
      status = 0;
      break;
  }
}

void setTrafficLight(int redState, int yellowState, int greenState) {
  digitalWrite(redPin, redState);
  digitalWrite(yellowPin, yellowState);
  digitalWrite(greenPin, greenState);
}

推荐阅读