Arduino - 执行循环时读取串行数据

时间:2014-08-13 20:44:58

标签: c arduino

前几天我刚收到我的arduino。我目前正在用java创建一个程序来控制我的arduino使用串行通信。到目前为止,我只有程序打开或关闭它。但是我遇到了一个问题。我的arduino褪色了两个rgb leds,遍布各种颜色。我在这里遇到了我的问题。当我按下按钮将其关闭(java程序)时,它不会关闭,直到它遍历每种颜色(完成for循环)。我想让它立即关闭。有什么方法可以在for循环中读取串行数据,或者有什么方法可以立即将其关闭,而不必等待for循环完成?这是代码:

const int redPins[] = {11,6};
const int greenPins[] = {10,5};
const int bluePins[] = {9, 3};

const int pinCountPerColor = 2;

const int sensorPin = 0;
int lightLevel;
int val = 0;
boolean isOn;

void setup() {
  Serial.begin(9600);
  setColourRgb(0,0,0);
  isOn = true;
}

void loop() {
  if(isOn) {
    unsigned int rgbColour[3];

    lightLevel = analogRead(sensorPin);

    if(lightLevel >= 400) { 
      rgbColour[0] = 255;
      rgbColour[1] = 0;
      rgbColour[2] = 0;  

      for (int decColour = 0; decColour < 3; decColour += 1) {
        int incColour = decColour == 2 ? 0 : decColour + 1;

        for(int i = 0; i < 255; i += 1) {
          lightLevel = analogRead(sensorPin);
          if(lightLevel <= 400) { 
            setColourRgb(255, 255, 255);
          } else {
            rgbColour[decColour] -= 1;
            rgbColour[incColour] += 1;

            setColourRgb(rgbColour[0], rgbColour[1], rgbColour[2]);
            delay(5);
          }
        }
      } 
    } else {
      setColourRgb(255, 255, 255);
    }
  }
}

void setColourRgb(unsigned int red, unsigned int green, unsigned int blue) {
  for(int r = 0; r < pinCountPerColor; r++) {
    analogWrite(redPins[r], red);
  }
  for(int g = 0; g < pinCountPerColor; g++) {
    analogWrite(greenPins[g], green);
  }
  for(int b = 0; b < pinCountPerColor; b++) {
    analogWrite(bluePins[b], blue);
  }
}

void serialEvent() 
{
  while (Serial.available())
  {
    val = Serial.parseInt();
    if(val == 1)   
    {
      isOn = true;
      //do nothing
    }
    else if(val == 0) 
    {
      setColourRgb(255, 255, 255);
      isOn = false;
    }
  }

  Serial.println("Succesfully received.");
}

2 个答案:

答案 0 :(得分:1)

最好为颜色创建一个状态机,它没有任何阻塞循环,特别是有延迟的循环。因此循环中的每个循环都会改变颜色并轮询Serial。

这是编写实时代码或简单无阻塞代码的艺术。

请注意,可以创建计时器中断以更好地安排RGB更新。请参阅Answer about Timer Interrupts以编写精确更新。

答案 1 :(得分:1)

@mpflaga正确回答了你的问题。

我想补充一点,如果你的项目变得比只有两个LED衰落更大,你可能想要使用比手工制造状态机更可靠的东西。

这称为实时操作系统(RTOS),它允许您以不同的频率运行不同的线程。

我个人对ChibiOS/RT使用robot project。有一个Arduino端口你可以下载here,它非常好documented,一旦你掌握了基础知识,我会说很容易使用。最好的办法是添加更高级别的层来管理线程。

以下是描述它和其他解决方案的页面:Arduino rtoslibs

以下是一些实时教程和Arduino的ChibiOS:

希望它有所帮助! :)