简体   繁体   中英

Arduino - Reading Serial Data while performing for loop

I just got my arduino the other day. I am currently making a program in java to control my arduino using serial communication. So far, I only have the program turn it on or off. But I ran into an issue. I have my arduino fade two rgb leds, looping through every color. I run into my issue here. When I press the button to turn it off(java program), it doesn't turn off until its ran through every color(complete the for loops). I want it to instantly shut off. Is there any way I can read serial data in the for loops, or is there any possible way I can turn it off instantly, not having to wait for the for loops to complete? Here is the code:

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

It is best to create a state machine for the colors, that does not have any blocking for loops, to dwell in. Especially loops with delays. So that each cycle through the loop changes the color and polls the Serial.

This is the art to writing real time code, or simply non-blocking code.

Note it is possible to create a timer interrupt to better schedule RGB updates. See Answer about Timer Interrupts to write precision updates.

@mpflaga answered your question correctly.

I would add that if you projects get bigger than just two leds fading, you might want to use something more reliable than a hand-made state machine.

That is called a Real Time Operating System (RTOS) and it allows you to have different threads running at different frequencies.

I personally use ChibiOS/RT for my robot project . There is a port for Arduino you can download here , it's very well documented and I'd say pretty easy to use once you get the basics. The nice thing to do is to add a higher level layer to manage the threads.

Here is a page with describing it and other solutions : Arduino rtoslibs

And here are some tutorials on real time and ChibiOS for Arduino:

Hope it helps! :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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