如何在不中断的情况下同时实现serialEvent和循环?

时间:2013-02-21 21:07:34

标签: loops serial-port arduino

我一直在研究传感器阅读器/齿轮传动RC车载机器人,但是我坚持不懈。 我已经介绍了一个void loop()和一个void serialEvent()作用域。 serialEvent获取值,累积并调用其他函数,如turnRight(),turnLeft()或reverseGear()。但是今天我试着为这辆车做一个速度显示器。但是我发现串行事件会中断连续显示动画。换句话说,我想在serialEvent上连续接收数据,同时我在void循环上成功完成其他连续事件。我附加了我认为可能是问题的代码部分。我使用的是Arduino Mega 1280.任何答案都会非常感激。感谢。

注意:请注意,对于灵敏度调整的电机,serialEvent应连续接收数据(延迟1秒)。

串行事件就像..

void serialEvent(){
  if ( Serial.available() > 0 ){ 
      int val = Serial.read() - '0'; 
      if(val == 0){ .......................

循环范围就像..

void loop() 
{ 
  displayModule.setDisplayToDecNumber(15, 0, false);
  for(int k =0; k<=7; k++){
    displayModule.setLED(TM1638_COLOR_GREEN, k);
    delay(100);
    ............................

3 个答案:

答案 0 :(得分:3)

Arduino论坛的座右铭始终适用:如果您发布整个草图,而不仅仅是您认为问题所在的片段,它会更容易帮助。

那就是说,我认为这里有一个严重的问题:

for(int k =0; k<=7; k++){
    displayModule.setLED(TM1638_COLOR_GREEN, k);
    delay(100);

对于循环来说,这将基本上暂停你的草图至少800毫秒。

如果您希望草图为“多任务”,则必须停止使用delay()并将思维模式从顺序编程切换到基于状态(或基于事件)的编程。通常的建议是研究“无延迟闪烁”的例子。

在第二个注释中,我不明白你的意思

  

我引入了一个void loop()

如果你不编写循环函数,草图将不会首先编译。

答案 1 :(得分:1)

我不知道这是否有帮助。这是我制作的一个串行代码示例,根据传入的串行数据绘制2个小节。它是一个处理文件,但它应该与Arduino草图类似。至少在serialEvent意义上。如果之前没有处理过,则draw方法类似于循环方法。也许这段代码中有一些东西可以帮助你。

import processing.serial.*;

Serial myPort;
float[] floatArray;
float f1; float f2;

void setup() {
  size(400, 400);
  // Prints lists of serial ports
  println(Serial.list());
  // Usually arduino is port [0], but if not then change it here
  myPort = new Serial(this, Serial.list()[0], 9600);
  // Don't call serialEvent until new line character received
  myPort.bufferUntil('\n');
  // Creates and array of floating decimal numbers and initializes its length to 2
  floatArray = new float[2];
}

void draw() {
  // Draws 2 bars to represent incoming data in patriotic fashion
  background(0, 0, 255);
  fill(255, 0, 0);
  rect(0, f1, 100, height);
  fill(255);
  rect(100, f2, 100, height); 
}

void serialEvent(Serial myPort) {
  // Reads input until it receives a new line character
  String inString = myPort.readStringUntil('\n');
  if (inString != null) {
    // Removes whitespace before and after string
    inString = trim(inString);
    // Parses the data on spaces, converts to floats, and puts each number into the array
    floatArray = float(split(inString, " "));
    // Make sure the array is at least 2 strings long.   
    if (floatArray.length >= 2) {
      // Assign the two numbers to variables so they can be drawn
      f1 = floatArray[0];
      f2 = floatArray[1];
      println(f2);
      // You could do the drawing down here in the serialEvent, but it would be choppy
    }
  } 
}

答案 2 :(得分:0)

我认为您需要设置串行接收中断来实现目标。

我会使用Peter Fluery的AVR Serial库:

http://homepage.hispeed.ch/peterfleury/avr-software.html

它使用循环环形缓冲区实现串行中断。