你能用Arduino Uno(c代码)同时运行一个函数多次吗



我有八个LED,四个红色和四个黄色。两行都有一个按钮。当你按下按钮时,一排LED会发出脉冲。这意味着它们以0.1秒的间隔连续发光。我现在的问题是:当另一个脉冲还在处理时,我能发送一个脉冲吗?目前,调用了一个函数,其中for循环将LED的状态设置为高和低,但在完成之前,我无法再次运行它。

void setup()
{
  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, INPUT);
  pinMode(13, INPUT);
  Serial.begin(9600);
}
boolean wait(unsigned int j, unsigned int time) <-- test if 0.1 seconds have passed
{ 
  if (millis()>=time+j){
    return true;
  }
  else return false;
}
void pulse(int start)
{
    for(int j = start;j < start + 4;j++)
    {
      digitalWrite(j, HIGH);
      unsigned int time = millis();
     while(wait(100, time)==false){};
     digitalWrite(j, LOW);
    }
}
void loop()
{
  if (digitalRead(12) == HIGH)
  {
    Serial.println("yellow");
    pulse(2);                   <-- I have to wait for this function
  }
  if (digitalRead(11) == HIGH)
  {
    Serial.println("red");
    pulse(6);                   <-- I have to wait for this function
  }
}

这就是我为这个项目编写代码的方式。

unsigned long yellowButtonPress = 0;
unsigned long yellowTimeElapsed = 0;
int yellowLED = 2
unsigned long redButtonPress = 0;
unsigned long redTimeElapsed = 0;
int redLED = 6
unsigned long MAX_Time = 400;
void setup(){
  //Setup the INPUT and OUTPUT pins
  for (int x=2; x<10; x++){
    pinMode(x, OUTPUT);
  }
    pinMode(12, INPUT);  //Yellow Button
    pinMode(13, INPUT);  //Red Button
}
void loop{
  yellowTimeElapsed = millis() - yellowButtonPress;
  redTimeElapsed = millis() - redButtonPress;
  //Check if yellow button has been pressed
  if(digitalRead(12) == HIGH && yellowTimeElapsed > MAX_Time){
    yellowButtonPress = millis();
  }
  //Check if red button has been pressed
  if(digitalRead(13) == HIGH && redTimeElapsed > MAX_Time){
    redButtonPress = millis();
  }
  //Identify which yellow LED needs to be on at this time
  if (yellowTimeElapsed > Max_Time){
    yellowLED=0; //This will turn off all yellow LEDs
  } else {
    yellowLED = map(yellowTimeElapsed, 0, MAX_Time, 2,5);
  }
  //Identify which red LED needs to be on at this time
  if (redTimeElapsed > Max_Time){
    redLED=0;  //This will turn off all red LEDs
  } else {
    redLED = map(redTimeElapsed, 0, MAX_Time, 6,9);
  }
  //Turn the yellow and/or red LEDs on and off
  for (int i = 2; i<10; i++){
    if (i == yellowLED || i == redLED){
      digitalWrite(i,HIGH);
    } else {
      digitalWrite(i,LOW);
    }
  }
}

您需要使用一个事件循环。问题是,你会陷入wait()和pulse()循环,而没有检查将状态重置为"脉冲x秒"的条件。

这包括把你想做的每件事都分解成小块,这样你就可以把它们交织在一起。它要求您记住您在特定子流程中所处的位置,以便稍后返回。在某种程度上,您需要通过使用state来说明在特定函数中应该从哪里开始运行来模拟协同例程。

此外,谷歌"退出"。如果你不松开按钮,你会看到很多奇怪的行为。实际上,我建议暂停这个项目,直到你可以可靠地取消按钮按下,使其显示为一次按下(因为这是一个更基本的问题)。

不要轻易放弃。这是绝对可能的。这个挑战是具体的和有趣的。我希望我有时间给你写一些代码,但我明天要去一次非常重要的旅行,我没有机会。

至少试试我的主意。你的循环正在扼杀这个概念,当你已经使用了最好的计数工具:millis()时,你就依赖于在代码中停止和计数

创建一个循环,使LED处于默认关闭状态,除非由以下时间触发:毫秒()+"按下开关后的时间"

每个led都有一个超过红色按钮按钮或黄色按钮按钮按钮的开和关偏移(这些是在按下相应按钮时存储毫秒()的整数)

例如,引脚4(或黄色led数字3)从yellowButtonPush+200到yellowButton Push+299 打开

每次循环检查你按下的按钮,然后循环通过每个Led,看看你是否应该根据其偏移打开、关闭、保持打开或关闭

编码快乐!

谢谢大家。这是我的最后一个代码。

unsigned long redButtonPress = 0;
unsigned long yellowButtonPress = 0;
void setup()
{
  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, INPUT);
  pinMode(13, INPUT);
}
void loop()
{
  if (digitalRead(12) == HIGH && yellowButtonPress+399 < millis())
  {
    yellowButtonPress = millis();
  }
  if (digitalRead(11) == HIGH && redButtonPress+399 < millis())
  {
    redButtonPress = millis();
  }

  if (millis() <= yellowButtonPress+99 && millis() >= yellowButtonPress+2)
  {
    digitalWrite(2, HIGH);
  }else{digitalWrite (2, LOW);}
  if (millis() <= redButtonPress+99 && millis() >= redButtonPress+2)
  {
    digitalWrite(6, HIGH);
  }else{digitalWrite (6, LOW);}
  if (millis() >= yellowButtonPress+100 && millis() <= yellowButtonPress+199)
  {
    digitalWrite(3, HIGH);
  }else{digitalWrite (3, LOW);}
  if (millis() >= redButtonPress+100 && millis() <= redButtonPress+199)
  {
    digitalWrite(7, HIGH);
  }else{digitalWrite (7, LOW);}
  if (millis() >= yellowButtonPress+200 && millis() <= yellowButtonPress+299)
  {
    digitalWrite(4, HIGH);
  }else{digitalWrite (4, LOW);}
    if (millis() >= redButtonPress+200 && millis() <= redButtonPress+299)
  {
    digitalWrite(8, HIGH);
  }else{digitalWrite (8, LOW);}
  if (millis() >= yellowButtonPress+300 && millis() <= yellowButtonPress+399)
  {
    digitalWrite(5, HIGH);
  }else{digitalWrite (5, LOW);}
  if (millis() >= redButtonPress+300 && millis() <= redButtonPress+399)
  {
    digitalWrite(9, HIGH);
  }else{digitalWrite (9, LOW);}
}

我不想说"不,你不能",所以让我说微处理器一次只能处理一个计算。

你要么需要一个以上的微处理器——你可以使用arduino纳米

--或者,你需要比我或任何人了解更多关于一些非常深入的电子产品的知识,以计算处理器告诉输出和实际发生之间需要多长时间,然后你必须做一些真正了不起的技巧,将这些知识包含到你的代码中。

最新更新