Arduino延迟替代方案
Arduino alternative for delays?
我想做的是同时运行2个交通信号灯(例如,北部和南方)。除了Millis之外,还有延迟的替代方案吗?我尝试使用blinkwithoutdelay,但作为新手,我非常复杂。
digitalWrite(greenled, HIGH); //Green on for 1 seconds
delay(greenDuration);
digitalWrite(greenled, LOW); //Green off, yellow on for 1 seconds
digitalWrite(yellowled, HIGH);
delay(1000);
digitalWrite(yellowled, LOW); //yellow off, red on for 1 seconds
digitalWrite(redled, HIGH);
delay(1000);
digitalWrite(redled, LOW); //Red off
digitalWrite(greenled2, HIGH); //Green on for 1 seconds
delay(1000);
digitalWrite(greenled2, LOW); //Green off, yellow on for 1 seconds
digitalWrite(yellowled2, HIGH);
delay(1000);
digitalWrite(yellowled2, LOW); //yellow off, red on for 1 seconds
digitalWrite(redled2, HIGH);
delay(1000);
digitalWrite(redled2, LOW); //Red off
完成代码:
int beam = 2;//Beam sensor
int greenled = 4;
int redled = 7;
int yellowled = 13;
int greenDuration =1000; //normal time
int greenShortDuration = 1000;
int greenIncrement = 5000; //5 seconds
void setup()
{
// set the digital pin as output:
pinMode(greenled, OUTPUT);
pinMode(redled, OUTPUT);
pinMode(greenled, OUTPUT);
pinMode(beam,INPUT);
Serial.begin(9600);
}
void loop()
{
Serial.println("Status:low");
digitalWrite(greenled, HIGH); //Green on for 5 seconds
delay(greenDuration);
digitalWrite(greenled, LOW); //Green off, yellow on for 2 seconds
digitalWrite(yellowled, HIGH);
delay(1000);
digitalWrite(yellowled, LOW); //yellow off, red on for 5 seconds
digitalWrite(redled, HIGH);
delay(1000);
digitalWrite(redled, LOW); //Red and Yellow off
digitalWrite(greenled2, HIGH); //Green on for 1 seconds
delay(1000);
digitalWrite(greenled2, LOW); //Green off, yellow on for 1 seconds
digitalWrite(yellowled2, HIGH);
delay(1000);
digitalWrite(yellowled2, LOW); //yellow off, red on for 1 seconds
digitalWrite(redled2, HIGH);
delay(1000);
digitalWrite(redled2, LOW); //Red off
if(digitalRead(beam)==HIGH){
for(int i=1; i<=10; i++){
Serial.println(i);
while(i>=10){
Serial.println("Motion Detected");
greenDuration +=greenIncrement; //Add 5 seconds everytime
Serial.println(greenDuration);
break;
}
}
}
if(!digitalRead(beam)==HIGH){
Serial.println("hey"); //indication of code is working
greenDuration=greenShortDuration;
return;
}
}
我试图使用blinkwithoutdelay,但作为新手,它非常复杂 为我使用它。
您必须更努力地:)
想象loop()不是"程序",而是任何时刻的描述。总的来说,它检测到既没有进行更改的时间,也没有新的pushbutton请求,因此循环立即退出。即使应该发生什么事情,任何新反应都不会花费任何时间,并且循环立即退出。
有一个简单的解决方案来解决给定的交通灯样本。
而不是调用延迟功能,您可以调用特殊延迟功能:
int globalFlagSomeonePressedBeam = false; // store global if someone pushed the beam button
void delay_and_check_for_beam (int msDelay) {
for (int i=0; i<msDelay; ++i) {
if(digitalRead(beam)==HIGH){ // check beam button
globalFlagSomeonePressedBeam = true; // store information
}
delay(1);
}
}
在您延迟功能的呼叫之间,您设置了正确的灯(数字出口)检查globalflagsomeOnePressedBeam后,您需要将其设置回false
op。
解决方案unsigned long curGoStopDuration, defGoStopDuration = 5000, maxGoStopDuration = 30000;
unsigned long currentMillis;
#pragma region SensorFields
int durationIncrement = 2500;
unsigned long greenPrevMillis;
float DetectionTime = 2500;
bool triggered;
#pragma endregion
enum LightState { Green, Yellow, Red };
class Stoplight
{
private:
int greenLed, yellowLed, redLed;
unsigned long previousMillis;
float CurInterval;
LightState state;
public:
unsigned long GreenDuration = 5000;
unsigned long RedDuration = 5000;
int YellowDuration = 1000;
Stoplight(int gLed, int yLed, int rLed) :greenLed(gLed), yellowLed(yLed), redLed(rLed)
{
pinMode(greenLed, OUTPUT);
pinMode(redLed, OUTPUT);
pinMode(yellowLed, OUTPUT);
}
void Loop()
{
if (currentMillis - previousMillis >= CurInterval)
{
previousMillis = currentMillis;
//Transitions
switch (state)
{
case Green:
ToYellow();
break;
case Yellow:
ToRed();
break;
case Red:
ToGreen();
break;
}
}
}
void ToGreen()
{
digitalWrite(redLed, LOW);
digitalWrite(greenLed, HIGH);
CurInterval = GreenDuration - YellowDuration;
state = Green;
}
void ToYellow()
{
digitalWrite(greenLed, LOW);
digitalWrite(yellowLed, HIGH);
CurInterval = YellowDuration;
state = Yellow;
}
void ToRed()
{
digitalWrite(yellowLed, LOW);
digitalWrite(redLed, HIGH);
CurInterval = RedDuration;
state = Red;
}
};
Stoplight SL_01(2, 3, 4), SL_02(5, 6, 7);
int beamSensor = 8;
void setup()
{
//Set default values
curGoStopDuration = defGoStopDuration;
SL_01.ToGreen();
SL_02.ToRed();
pinMode(beamSensor, INPUT);
Serial.begin(9600);
}
void loop()
{
currentMillis = millis();
Sensor();
//Manipulate durations
SL_01.GreenDuration = curGoStopDuration;
SL_02.RedDuration = curGoStopDuration;
SL_01.Loop();
SL_02.Loop();
}
void Sensor()
{
//If sensor detects something
if (digitalRead(beamSensor) == HIGH)
{
if (!triggered)
{
greenPrevMillis = currentMillis;
triggered = true;
}
if (currentMillis - greenPrevMillis >= DetectionTime)
{
if(curGoStopDuration < maxGoStopDuration)
curGoStopDuration += durationIncrement; //Add seconds
greenPrevMillis = currentMillis;
Serial.print("Green light duration is now: ");
Serial.println(curGoStopDuration);
}
}
else //No detection
{
curGoStopDuration = defGoStopDuration;
triggered = false;
}
}
您需要在光束上中断,快速,只需计数器,但是对于更精确的计数(clogine =))...这对我有用:
#define redPin1 40
#define yellowPin1 41
#define greenPin1 42
#define beamPin1 21
#define redDuration 1000
#define yellowDuration 1000
#define greenDuration 1000
#define durationIncrement 500
byte carCounter1 = 0;
byte state1 = 1;
void setup()
{
pinMode(redPin1, OUTPUT);
pinMode(yellowPin1, OUTPUT);
pinMode(greenPin1, OUTPUT);
pinMode(beamPin1, INPUT);
attachInterrupt(digitalPinToInterrupt(beamPin1), beamCount1, RISING);
}
void beamCount1()
{
carCounter1++;
}
void wait(long duration)
{
int wait = 0;
long last = millis();
while (wait == 0)
{
long now = millis();
if (now - last >= duration) { wait = 1;}
else {}
}
}
void redLight(byte redLightPin)
{
digitalWrite(redLightPin, HIGH);
wait(redDuration);
state1 = 2;
}
void yellowLight1(byte redLightPin, byte yellowLightPin)
{
digitalWrite(yellowLightPin, HIGH);
wait(yellowDuration);
digitalWrite(redLightPin, LOW);
digitalWrite(yellowLightPin, LOW);
state1 = 3;
}
void yellowLight2(byte yellowLightPin)
{
digitalWrite(yellowLightPin, HIGH);
wait(yellowDuration);
digitalWrite(yellowLightPin, LOW);
state1 = 1;
}
void greenLight(byte greenLightPin)
{
digitalWrite(greenLightPin, HIGH);
long incremented = greenDuration + (carCounter1 * durationIncrement);
wait(incremented);
digitalWrite(greenLightPin, LOW);
carCounter1 = 0;
state1 = 4;
}
void trafficLight(byte red, byte yellow, byte green)
{
switch (state1){
case 1:
redLight(red);
break;
case 2:
yellowLight1(red, yellow);
break;
case 3:
greenLight(green);
break;
case 4:
yellowLight2(yellow);
break;
}
}
void loop()
{
trafficLight(redPin1, yellowPin1, greenPin1);
}
否延迟,只需跟踪Millis的等待功能...如果您想要更精确,请计算每个灯所需的时间,然后将其从等待...
相关文章:
- 运行同一解决方案的另一个项目的项目
- Project Euler问题4的错误解决方案
- 如何仅为一个函数添加延迟
- 计算每个节点的树高,帮助我解释这个代码解决方案
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- visual c++,如何获取解决方案目录中的代码
- 以在Qt中的IF语句中设置时间延迟
- 有没有办法在远程设备上打开和编辑visual Studio 2017解决方案
- C++Matching Brackets 2解决方案不起作用
- 在 ubuntu3 上C++ goto 定义有什么解决方案吗16.04?
- C++11 中不同类型的对象的 std::array 的替代方案
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 模板化类中静态成员的延迟初始化
- 别名模板的专业化 C++11 中没有开销的最佳替代方案
- 在 Windows 8/10 技术中完全实时的屏幕捕获,没有延迟
- 我的固定时间步长与增量时间和插值的解决方案是错误的吗?
- 无法在问题解决方案中执行输出逻辑
- 将自定义函数传递到基抽象类中以延迟执行
- 我希望改进或要求我目前的延迟/睡眠方法。C++
- Arduino延迟替代方案