-1

I need help for my little project. I don't know Arduino so I used ChatGPT to write me the code. After few hours of testing I almost got what I need. The scheme is the following: LED ring, push button and potentiometer. I use the potentiometer to control the brightness and the button cycle through different modes (effects). After trying to figuring out what is going on I think I found the issue but I don't know how to fix it... In the code bellow the toggleMode function is the problem. This expression: mode = (mode + 1) % 3 brakes the correct execution. All 3 effects can be cycled only once and then it stuck on the last effect. Is there any other expression I can use for calculating the "mode"? Thank you in advance! Here is the complete code (also there are some lines for debugging as you can see):

#include <FastLED.h>
#include <Arduino.h> // Include the Arduino core library for Serial support

// Define the number of LEDs in the LED ring
#define NUM_LEDS 24

// Define the data pin
#define DATA_PIN 6

// Define the LED type
#define LED_TYPE WS2812B

// Define the color order
#define COLOR_ORDER GRB

// Create an array of CRGB objects to store the colors of each LED
CRGB leds[NUM_LEDS];

// Define the pin for the potentiometer
#define POTENTIOMETER_PIN A0

// Define the pin for the button
#define BUTTON_PIN 2

// Define the minimum and maximum brightness values
#define MIN_BRIGHTNESS 0
#define MAX_BRIGHTNESS 255

// Variable to store the current mode (0: static rainbow, 1: sparkle)
int mode = 0;


int previousButtonState = HIGH;

void setup() {
  // Initialize Serial communication at a baud rate of 9600
 Serial.begin(9600);

  mode = 2;
  // Initialize FastLED library
 FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
 
  // Set initial brightness
 FastLED.setBrightness(MAX_BRIGHTNESS / 2);
 
  // Set the button pin as input with internal pull-up resistor
 pinMode(BUTTON_PIN, INPUT_PULLUP);
}

void loop() {
  // Read the value from the potentiometer
 int potValue = analogRead(POTENTIOMETER_PIN);
 
  // Map the potentiometer value to the brightness range
 int brightness = map(potValue, 0, 1023, MIN_BRIGHTNESS, MAX_BRIGHTNESS);
 
  // Set the brightness of the LED ring
 FastLED.setBrightness(brightness);
 
  // Check the button state with debouncing
 int buttonState = digitalRead(BUTTON_PIN);
 if (buttonState == LOW && previousButtonState == HIGH) {
    // Button is pressed for the first time
    // Toggle the mode when button is pressed
 toggleMode();
  }
 
  previousButtonState = buttonState;

  // Call the appropriate function based on the mode
 if (mode == 0) {
 Serial.println("Mode: Rainbow");
 rainbow();
  } else if (mode == 1) {
 Serial.println("Mode: Sparkle");
 sparkle();
  } else if (mode == 2) {
 Serial.println("Mode: Static Rainbow Fade");
 staticRainbowFade();
  }
 
  // Display the updated LED colors
 FastLED.show();
 
  // Delay to control the loop rate
 delay(30);
}

// Function to toggle the mode between rainbow and sparkle
void toggleMode() {
  mode = (mode + 1) % 3;
 
    //DEbugging code
 Serial.print("Mode toggled: ");
 Serial.println(mode);
}

// Function to create a rainbow effect
void rainbow() {
  // Hue increment value determines the speed of the rainbow
 static uint8_t hue = 0;
 
  // Fill the LED ring with colors
 for(int i = 0; i < NUM_LEDS; i++) {
 leds[i] = CHSV(hue + (i * 255 / NUM_LEDS), 255, 255);
  }

  // Increment the hue value for the next iteration
  hue++;
}


// Function to create a sparkle effect with smooth fading and color change
void sparkle() {
  // Probability of an LED sparkling (adjust as needed)
 const float sparkleProbability = 0.02; // Adjust this value to change the density of the sparkle
 
  // Loop through each LED
 for (int i = 0; i < NUM_LEDS; i++) {
    // Check if the LED should sparkle
 if (random(0, 1000) < (sparkleProbability * 1000)) {
      // Set a random color to the sparkling LED
      CRGB sparkleColor = CHSV(random(0, 255), 255, 255); // Random color
 leds[i] = sparkleColor;
    }
    // Fade out all LEDs
 leds[i].fadeToBlackBy(10); // Adjust the fade rate (lower value fades faster)
  }
}


// Function to create a static rainbow effect with fading in and out
void staticRainbowFade() {
  // Fill the LED ring with rainbow colors
 rainbow();

  // Fade in
 for (int brightness = 0; brightness <= 255; brightness++) {
    // Set the brightness of all LEDs
 FastLED.setBrightness(brightness);
 
    // Display the updated LED colors
 FastLED.show();
 
    // Delay to control the fading speed (adjust as needed for desired effect)
 delay(7); // Adjust this value for fading in speed
  }
 
  // Delay between fade in and fade out
 delay(1000); // Adjust this value for the delay between fade in and fade out
 
  // Fade out smoothly
 for (int brightness = 255; brightness >= 0; brightness--) {
    // Set the brightness of all LEDs
 FastLED.setBrightness(brightness);
 
    // Display the updated LED colors
 FastLED.show();
 
    // Delay to control the fading speed (adjust as needed for desired effect)
 delay(7); // Adjust this value for fading out speed
  }
}
5
  • just increment mode mode++ ... then set to 0 if it reaches 3
    – jsotola
    Commented May 16 at 5:08
  • Thank you! That looks much easier solution! The problem is I don't know where to add that... I tried to add it in the toggleMode() but nothing happens.
    – Niki
    Commented May 16 at 11:44
  • @Niki Did you read my answer? Replacing one working code with another working code will not heal your error, which has an unrelated reason. Commented May 16 at 11:56
  • @thebusybee Yes, I checked the Nordic link. I thought that Blinky example is from the Arduino SDK's examples but now I found it and will check it out.
    – Niki
    Commented May 16 at 14:38
  • @Niki this might help you ... something I wrote as a demo ... wokwi.com/projects/362275278547275777
    – jsotola
    Commented May 16 at 18:12

1 Answer 1

0

The mode changing line is correct. jsotola mentions an alternative form, like this:

void toggleMode() {
  mode++;
  if (mode == 3) {
    mode = 0;
  }

  // Debugging code
  Serial.print("Mode toggled: ");
  Serial.println(mode);
}

But this is not the error, and it will not help.

The error is that your staticRainbowFade() delays for about 4.5 seconds. Only after that time the button is read.

The relevant parts are condensed here:

void loop() {
  //...
  int buttonState = digitalRead(BUTTON_PIN);
  //...
  } else if (mode == 2) {
    Serial.println("Mode: Static Rainbow Fade");
    staticRainbowFade(); // <=== this takes about 4.5 seconds
  }
  // ...
}

void staticRainbowFade() {
  // ...
  for (int brightness = 0; brightness <= 255; brightness++) {
    // ...
    delay(7);
  }
 
  delay(1000);
 
  for (int brightness = 255; brightness >= 0; brightness--) {
    // ...
    delay(7);
  }
}

As an immediate "solution" you can leave the button unpressed for about 5 seconds, and then press it for about 5 seconds. This should change the mode.

However, this is just a work-around. Actually you should refactor your sketch to the non-delayed form. As this is some effort, I do not present it here. You might want to look in the Blinky example that does not use delay() to have an idea. Another topic to research is the "finite state machine" that decouples separate logic.

3
  • Or - as another workaround - read the button also in the for loops inside staticRainbowFade(). And at least reducing the 1s delay in between the for loops. Though rewriting the code for no-delay is way cleaner
    – chrisl
    Commented May 16 at 8:14
  • I don't know what to rewrite. I just need it to work as I expect. I'm not programmer (obviously). I'm interested in many things and I can't learn everything even if I want to. That's why I started to play with ChatGPT coding and I'm happy with the results but there are some issues which the AI can't resolve (for now, hopefully). Thank you for the reply. I'll continue to read and try to fix it.
    – Niki
    Commented May 16 at 11:56
  • Well, well. I will not rant repeatedly against AIs, but they have no clue about programming, because they have no understanding. ChatGPT and similar are just good at guessing word sequences that are free from syntax errors. What you need instead is code that is semantically correct. -- What you want is a complete solution probably with explanation, which is far too broad here. Did you look into the suggested example? Did you grasp it? If you have a specific question about this Blinky, feel free to post a separate question here. You might want to link back to this question, though. Commented May 16 at 12:02

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.