简体   繁体   English

您可以使用Arduino Uno(C代码)同时运行一个函数多次吗?

[英]Can you run a function multiple times at the same time with Arduino Uno (c code)?

I have eight LEDs, four red ones and four yellow ones. 我有八个LED,四个红色和四个黄色。 There is one button for both rows. 两行都有一个按钮。 When you push a button, a row of LEDs gets a pulse. 按下按钮时,一行LED会发出脉冲。 That means they light up in a row in 0.1 second intervals. 这意味着它们以0.1秒的间隔连续点亮。 My question is now: Can I send a pulse while another one is still being processed? 我的问题现在是:我是否可以在处理另一个脉冲时发送脉冲? At the moment a function is called in which a for loop sets the state of the LEDs to HIGH and low, but I can not run it again, before it is finished. 目前,调用了一个函数,其中一个for循环将LED的状态设置为HIGH和Low,但是在完成之前,我无法再次运行它。

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
  }
}

You need to use an event loop. 您需要使用事件循环。 The problem is that you get stuck in the wait() and pulse() loops without checking for the condition that would reset the state to "pulsing for x seconds". 问题是您陷入了wait()和pulse()循环中,而没有检查将状态重置为“脉冲x秒”的条件。

This involves breaking each thing you want to do down into smaller chunks so that you can interleave them together. 这涉及将您想做的每件事分解成较小的块,以便可以将它们交错在一起。 It requires you to remember where you were in a particular sub-process so that you can return to it later. 它要求您记住您在特定子流程中的位置,以便稍后返回。 In a way you need to emulate co-routines by using state to say where in a particular function you should start running. 在某种程度上,您需要通过使用状态来说明应在特定函数中的何处开始运行来仿真协同例程。

Also, google "debouncing". 此外,谷歌“反跳”。 You're going to see a lot of weird behaviour if you don't debounce the button presses. 如果不对按钮按下进行反跳操作,将会看到很多奇怪的行为。 I would actually recommend putting this project on hold until you can reliably debounce a button press to appear as a single press (as it's a more fundamental issue). 实际上,我建议您搁置该项目,直到您可以可靠地反跳按钮按下时显示为一次按下为止(因为这是一个更基本的问题)。

Don't give up so easy. 不要轻易放弃。 This is absolutely possible. 这绝对是可能的。 This challenge is tantilising and fun. 这项挑战既诱人又有趣。 I wish I had time to write you some code but I'm heading on a big and very important trip tomorrow and I don't have a chance. 我希望我有时间为您编写一些代码,但明天我将进行一次非常重要的重要旅行,所以我没有机会。

At least try my idea. 至少尝试我的想法。 Your loop is what is killing the concept, you are relying on stopping and counting in code when you are already using the best counting tool available to you: millis() 循环是杀死概念的原因,当您已经在使用可用的最佳计数工具时,依赖于停止并计数代码:millis()

Create a loop that turns goes through your LEDs and has them in a default state of off unless triggered by timings that are based on: millis() + "time after pushing the switch" 创建一个循环,使其循环通过您的LED,并使它们处于默认关闭状态,除非基于以下情况触发计时:millis()+“按下开关后的时间”

Each led has an on and off offset beyond either redButtonPush or yellowButtonPush (these are ints that store the millis() when the corresponding button was pushed) 每个led的开关偏移量都超过redButtonPush或yellowButtonPush(当按下相应按钮时,这些整数存储millis())

For example pin4 (or yellow led number 3) is on from yellowButtonPush + 200 to yellowButtonPush + 299 例如,pin4(或黄色LED数字3)从yellowButtonPush + 200变为yellowButtonPush + 299

Each loop check for your button push somehow then cycle through each Led to see whether you should either turn it on, turn it off, keep it on or keep it off based on its offset 每次按下按钮的循环检查都将以某种方式循环,然后遍历每个LED,以查看是否应基于其偏移量将其打开,关闭,保持打开或关闭

Happy coding! 编码愉快!

Thank's everyone. 感谢大家。 This is my final code. 这是我的最终代码。

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);}
}

This is how I would write the code for this project. 这就是我为该项目编写代码的方式。

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);
    }
  }
}

I don't want to say "no, you can't," so let me just say the microprocessor can only process one calculation at a time. 我不想说“不,你不能”,所以我只想说微处理器一次只能处理一个计算。

You either need more than one microprocessor--you could use arduino nanos 您要么需要多个微处理器,要么可以使用arduino nanos

--or you need to learn much more than I or anyone does about some very deep electronics to calculate how long it takes between when the processor tells an output to put out and when that actually happens, and then you'd have to do some truly remarkable acrobatics to include that knowledge into your code. -或者您需要比我或任何其他人更深入地了解一些非常深的电子产品,以计算从处理器告诉输出到实际输出之间需要多长时间,然后您必须做一些真正出色的杂技,可以将这些知识纳入您的代码中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM