Multithreading with led strip

Hi everyone,
i have a basic (very basic) use case with an arduino and a led strip. i'll try to explain it very simply :
i have a 5meters led strip with 300 leds/pixels connected to my arduino uno, i created a function to light leds one after the other at a specific pace :

void startPace(int speed, int green, int red, int blue){
      for (int i=0; i<300; i++){
        FastLED.clear();
        leds[i] = CRGB(green,red,blue);
        FastLED.show();
        delay(100); // for the fotum each 100ms i light the next led, but in the code it depends on a speed
      }
      FastLED.clear();
      FastLED.show();
}

my need, is to fire a first color, and 10 seconds after fire another, so naively i did this:
startPace(3, 255,0,0);
delay(10000);
startPace(6,0,255,0);
doing this, i expected to fire a green led at 3 kph and 10 seconds after a red one at 6kph so that the red one catches the green one. but i think everyone guessed the problem, the red never catches the green since the red fires only 10 seconds after the green finishes the 5 meters length.
i understand that c++ is not java but is it possible to code this use case with an arduino ?

yes, you need to code it the right way though which means not using delay() in the first place.

look at Using millis() for timing. A beginners guide and Several things at the same time

You have to take things one step at a time with no for() loop inside your function. This will allow other things to get done. You also can not use delay() since nothing else happens while it is executing. Look at the Blink without Delay example in the IDE (File->examples->02.digital->Blink Without Delay)
And then you get something like this:

#include <FastLED.h>

// How many leds in your strip?
#define NUM_LEDS 300

#define DATA_PIN 3
#define CLOCK_PIN 13

unsigned long startTime;
unsigned long lastTime;

bool redRunning = false;

const unsigned long redDelay = 10000;   // 10s delay for red to start

// Define the array of leds
CRGB leds[NUM_LEDS];

int greenIdx = 0;
int redIdx = 0;

void setup() {
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);  // GRB ordering is assumed
  Serial.begin(115200);
  Serial.println("ready");
  startTime = millis();
}

void loop() {
  unsigned long currentTime = millis();

  if ( currentTime - startTime >= redDelay ) {
    redRunning = true;
  }
  greenPace();
  if ( redRunning ) {
    redPace();
  }
}

void greenPace() {
  const byte green = 255;
  const byte red = 0;
  const byte blue = 0;
  const unsigned long interval = 100;

  static unsigned long lastTime;

  if ( millis() - lastTime >= interval ) {
    // time to move led
    lastTime = millis();
    leds[greenIdx] = CRGB(0, 0, 0);
    greenIdx = (greenIdx + 1) % NUM_LEDS;
    leds[greenIdx] = CRGB(green, red, blue);
    FastLED.show();
  }
}

void redPace() {
  const byte green = 0;
  const byte red = 255;
  const byte blue = 0;
  const unsigned long interval = 50;

  static unsigned long lastTime;

  if ( millis() - lastTime >= interval ) {
    // time to move led
    lastTime = millis();
    leds[redIdx] = CRGB(0, 0, 0);
    redIdx = (redIdx + 1) % NUM_LEDS;
    leds[redIdx] = CRGB(green, red, blue);
    FastLED.show();
  }
}

please show how you would have done this in Java

well i didn't really dig the problem in java, but i would take the road of threads if i wanted to execute parallel behaviours in java. what i am saying might be stupid :smiley:

Java can run multi threads on single core?

thank you very much for your help, i was coding a solution using millis(), yours is helping me to overcome some little difficulties.

well obviously no, and i don't see the point of your questions besides humiliating me, i am not very good at conding and i am trying to learn, you are not very helpful so i suggest that we stop here. thank you

Of course it can, just not concurrently. Exactly like you can run multiple RTOS threads using C/C++ with just Core 1 of an ESP32.

You brought up Java, there has to be a reason, probably because you know Java. The question was legit, if you can do this in Java, you certainly can do this in C++.

I don't get the question

Major OSes support threading at the OS level and major JVMs rely on the default platform threads library. So it's up to the OS to schedule threads on multiple or one single core.

The challenge would be more on handling the concurrent use of resources...

Was more of a request to post Java code to see if it was possible to convert it to C++

does this help see how threads would be forked and paused?

public class TestClass {
	static int N;

	public void countUp(int counter, int duration)  {
        while (counter <= N) {
		    System.out.println(Thread.currentThread().getName() + "  " + counter++);
            try {Thread.sleep(duration);}
            catch (Exception e) {
                System.out.println(e);
            }
	    }
	}

	public static void main(String[] args) throws InterruptedException {
		N = 30;
		TestClass tc = new TestClass();
		Thread t1 = new Thread(new Runnable() {public void run() {tc.countUp(10, 100);}});
		Thread t2 = new Thread(new Runnable() {public void run() {tc.countUp(20, 300);}});
		t1.start();
		t2.start();
	}
}

will print

Thread-1  20
Thread-0  10
Thread-0  11
Thread-0  12
Thread-1  21
Thread-0  13
Thread-0  14
Thread-0  15
Thread-1  22
Thread-0  16
Thread-0  17
Thread-0  18
Thread-1  23
Thread-0  19
Thread-0  20
Thread-0  21
Thread-1  24
Thread-0  22
Thread-0  23
Thread-0  24
Thread-1  25
Thread-0  25
Thread-0  26
Thread-0  27
Thread-1  26
Thread-0  28
Thread-0  29
Thread-0  30
Thread-1  27
Thread-1  28
Thread-1  29
Thread-1  30

not sure there is a direct translation to C++ and Arduino world

Could you write the same but that reflects what IP is asking? The different start timing and different speed, sync and all that?

There is no real point going down that route. it does not help OP nor do I see what's the value.

The code does have a variable delay already so that both threads progress at variable speed through the counting. That was the intent of the code - two things progressing in pseudo parallel at their own speed.

if they were to access shared resources then you would need to serialize access to such shared resources. Java has built-in support to prevent collisions over resources (the synchronized keyword). Semaphore, wait etc can be used as well.

Hello again everyone, thanks to @blh64 and the millis() function, i was able to code the solution and pace several lights on the led band

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.