Strobe light using LED strips

Hi everyone,

I have a little project where I want to build a strobe light to showcase some fun effects with water.

However using this code, it seems like the strobe does not flash at the correct frequency...
Here's the code I'm using.

#define RED_PIN 2
#define GREEN_PIN 4
#define BLUE_PIN 7
#define POT_PIN 3

#define BRIGHTNESS 255

#define FREQUENCY_MIN 30
#define FREQUENCY_MAX 120

#define DUTY_CYCLE 0.2

#define ON 1
#define OFF 0

int state;
float frequency;
int val;

void setup() {
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(RED_PIN, OUTPUT);
  pinMode(BLUE_PIN, OUTPUT);

  state = ON;

  
  Serial.begin(57600);
}

void loop() {
  val = analogRead(POT_PIN);    // read the value from the sensor

  frequency = FREQUENCY_MIN + ((val/10)*(FREQUENCY_MAX - FREQUENCY_MIN))/102;

  Serial.println(frequency);
  
  if (state == ON)
  {
    analogWrite(RED_PIN, BRIGHTNESS);
    analogWrite(GREEN_PIN, BRIGHTNESS);
    analogWrite(BLUE_PIN, BRIGHTNESS);

    delay((1000 / (frequency))*DUTY_CYCLE);

    state = OFF;
  }
  
  else
  {
    analogWrite(RED_PIN, 0);
    analogWrite(GREEN_PIN, 0);
    analogWrite(BLUE_PIN, 0);

    delay((1000 / (frequency))*(1-DUTY_CYCLE));

    state = ON;
  }

  
}

I've read around a little bit (for instance, this A strobe light with accurate frequencies - Project Guidance - Arduino Forum and this Arduino Snippets: LED Stroboscopic Tachometer – The Smell of Molten Projects in the Morning ), which mention that creating accurate frequencies with the loop/ delay functions will not yield good results, and to use timers.

I'm familiar with timers, and understand why I should have used them in the first place, but what makes the delay version not work? Is there too much going on around in the background which creates this uncertainty in the execution frequency?

Also, the RGB led strips I'm using should be absolutely fast enough (https://www.amazon.fr/gp/product/B07F9R5L2C/ref=ppx_yo_dt_b_asin_title_o07_s00?ie=UTF8&psc=1), but I'm looking to maybe use individually addressable LEDs (WS2811) for some nicer effects. From what I've calculated, if I have 100 LEDs, each at 24bits, with an update frequency of 800kHz, I should be able to reach 333 Hz, correct?

Finally, I'm looking for a cheap light sensor (photoresistor or photodiode) that can measure the frequency of the strobe (<200Hz), could any of you point me towards one that would the trick?

Thanks a bunch!

Since there's an analog pot involved I'm not sure what kind of "accuracy" you expect.

I haven't studied your code but I'm thinking there's something wrong with your "math".

I'm familiar with timers, and understand why I should have used them in the first place, but what makes the delay version not work? Is there too much going on around in the background which creates this uncertainty in the execution frequency?

Yes. Every instruction in your program takes some time so that time gets added to the delay(). That may, or may not, be significant but it will lower the frequency.

Thanks for the answer!

However, I am outputting the computed frequency to the serial plotter, and the frequency is stable. I have a small enough frequency span that the pot is accurate enough and analog noise is ironed out. Frequency computation stays constant when I'm not touching the pot.