1

I'm currently working on an arduino project. Were the arduino is communicating with a NodeJS server via web sockets.

The socket connection is working fine and has no problems. But the problem I currently have is that I want to be able interupt an infinite while loop with a socket emit from the NodeJS server.

I found a page that had a solution for this problem but only with a button attached to the arduino.

Link to page (Interrupt with button)

This is the loop I want to be able to interrupt with a socket:

bool loopRunning = true;

void rainbow(int wait) {
while(loopRunning == true) {

      for(long firstPixelHue = 0; firstPixelHue < 3*65536; firstPixelHue += 256) {
        for(int i=0; i<strip.numPixels(); i++) { 
          int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
          strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
        }
        strip.show(); 
        delay(wait);  
      }
    }
}

I want to set loopRunning to false when I recieve a socket emit.

Anyone have any ides how I can implement this?

Page to the socket functionality that I use

2 Answers 2

1

There are two ways to handle events: interrupts (hardware triggered) and polling (software triggered). Interrupts are much more efficient but also more difficult to use. SocketIoClient uses polling.

The necessary part of polling is... polling. That is, many times per second, you (or your library) needs to check if anything interesting is happening.

With this library, you have to call SocketIoClient::loop() many times a second. That's why SocketIoClient::loop() exists. So it needs to be added to your outer for loop.

(If your delay(wait) takes too long, you may need to break it up into a series of several shorter ones, but I think you can get away with it in this case.)

Then all you need to do is use SocketIoClient::on() to perform an action when an event happens. There is an example in the documentation. You will need to make loopRunning into a global variable.

0

The problem is the while loop trapping execution. When you have a small section of your loop that you want to stick in, you can do it two ways. You can do what you did with a while loop, that keeps execution stuck inside the while loop with nothing else happening. Or you can let the loop function be the loop and use flags and if statements to decide what's running.

Imagine this code:

void loop() {
  if(loopRunning){
     // do the stuff in your while loop
  }
  else {
     // all the other stuff in loop that you don't want running during that
  }
  // all the stuff you want to run regardless, like listening to your socket.  
}

When you do it like that you still get to have the stuff you were going to while loop to happen on it's own without the rest of loop, but you can also have some stuff that runs both ways. That logic can be extended in all kinds of ways. Maybe you want that part to always run but the rest of loop to be skipped when loopRunning is false.

void loop(){
   //  all the stuff that should run all the time (like your socket)
   if(!loopRunning) {
       // all the stuff you would put into a while(!loopRunning) code
       // but wouldn't be able to catch the socket.  
   }
}
1
  • You'll also have to ditch the delay calls and go to a "Blink Without Delay" style use of millis if you really want to be responsive to your socket. Those for loops are also blocking, you could have that code take one step at a time and wait to be called from loop to take the next step. Google around for Arduino neopixel and non-blocking. You aren't the first person to realize that the demo stuff for neopixels doesn't work out in larger programs. It's not hack-and-paste code, it's just for demo.
    – Delta_G
    Commented May 2, 2020 at 17:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.