Newbie Help with Automotive project

I am totally new to programming and have been spinning my wheels for some time now with no luck.
My project is a grill light setup for my truck. I have some things working but cannot get the Engine On feature part to work right.
I am working with: WS2812B let strip (100) lights. and an Uno.
I want the center 8 lights to come on and hold for 8 seconds. (I have that part).
From there I want to split those 8 lights and sweep 4 in a comet fashion left at the same time the other 4 lights are sweeping right. I want them to then go back the same way to the center 8 lights and hold for 3 seconds again and then stop. I then am going to light 3 separate areas on the strip to simulate Raptor lights. (I also have the 3 lights worked out). My problem is the sweeping from the center out then in and stopping. Here is the code I have so far for the sweep part.

#include <FastLED.h>

using namespace fl;

// How many leds in your strip?
#define NUM_LEDS 100 
#define DATA_PIN 13


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

void setup() { 
	Serial.begin(57600);
	Serial.println("resetting");
	FastLED.addLeds<WS2812,DATA_PIN,RGB>(leds,NUM_LEDS);
	FastLED.setBrightness(100);
}

void fadeall() { for(int i = 0; i < NUM_LEDS; i++) { leds[i].nscale8(120); } }

void loop() { 
	  
  	// First slide the led in one direction
	for(int i = 0; i < NUM_LEDS/2; i++) {
		// Set the i'th led to orange 
		leds[i] = CRGB(90, 254, 0);
		// Show the leds
		FastLED.show(); 
		// now that we've shown the leds, reset the i'th led to black
		// leds[i] = CRGB::Black;
		fadeall();
		// Wait a little bit before we loop around and do it again
		delay(30);
	}

	// Now go in the other direction.  
	for(int i = (NUM_LEDS/2)-1; i >= 0; i--) {
		// Set the i'th led to orange 
		leds[i] = CRGB(90, 254, 0);
		// Show the leds
		FastLED.show();
		// now that we've shown the leds, reset the i'th led to black
		// leds[i] = CRGB::Black;
		fadeall();
    // Wait a little bit before we loop around and do it again
		delay(30);
   
  }

    // Turn off all LEDs
  for (int i = 0; i < NUM_LEDS; i++) {
    leds[i] = CRGB(0, 0, 0);
  }
  FastLED.show();

}

Can someone please explain to me why I can only get the sweep to run on the one side of the strip but not the other?
And how do I get the sweep to start at the center, not at the end?

You can use simple maths to do many tricks like this.

As an example, here's a loop that sends two pixels from the middle to the ends:

int halfWay = (NUM_LEDS / 2) - 1;  /; the middle of the strip

for (int i = 0; i < halfWay; i++) {
		// light up two LEDs at increasing distance from the middle
                leds[halfWay + i] = CRGB(90, 254, 0);
                leds[halfWay - i] = CRGB(90, 254, 0);

		// Show the leds
		FastLED.show();

		// now that we've shown the leds, reset them led to black
                leds[halfWay + i] = CRGB::black;
                leds[halfWay - i] = CRGB::black;

		fadeall();
    // Wait a little bit before we loop around and do it again
	      delay(30);
  }

I'm sorry I cannot test that code just now. But the basic idea is when dealing with N things, write a loop that goes from 0 to N - 1, and use transformations like I did in adding to and subtracting from that changing number to get at the LEDs of interest.

It's way easier than trying to wrangle for loops that run backwards or over different limits.

a7

1 Like

As you progress I expect you to have problems when you put it in the truck. Check the following you will know where I am coming from.

Valuable Resources for Automotive Electronics:

  1. STMicroelectronics Application Note AN2689:
    This application note provides guidelines on protecting automotive electronics from electrical hazards, focusing on design and component selection. Reading this will greatly enhance your understanding of automotive circuit protection.
    Read AN2689
  2. Analog Devices: Automotive Electronics Design:
    This article distills key insights into designing automotive electronics, offering practical advice for engineers.
    Read the article
  3. Diodes Incorporated: Transient Voltage Suppression in Automotive:
    Learn about techniques to protect automotive circuits from transient voltage, which is critical for ensuring reliable operation in harsh conditions.
    Read the article
  4. AEC-100 Standards Webinar:
    This webinar from Monolithic Power Systems provides a detailed overview of AEC standards, essential for understanding automotive electronics requirements.
    Watch the webinar
  5. Understanding Automotive Electronics, An Engineering Perspective by William B. Ribbens:
    This comprehensive book offers an in-depth look into automotive electronics from an engineering perspective, making it an invaluable resource.
    Access the book

These resources should provide a strong foundation for anyone involved in automotive electronics design. If you need further help or more resources, feel free to ask!

1 Like

OK I was close. I did cheat a little to make everything work out, but the idea is the same.

You can see it run here

The code in context:

// https://wokwi.com/projects/422627222463888385

# include <FastLED.h>

#define NUM_LEDS 31
#define DATA_PIN 7

CRGB leds[NUM_LEDS];

void setup() { 
	Serial.begin(115200);
	Serial.println("resetting");

	FastLED.addLeds<WS2812,DATA_PIN,RGB>(leds,NUM_LEDS);

}

void loop() {
  int halfWay = NUM_LEDS / 2;  // the middle of the strip

  for (int i = 0; i <= halfWay; i++) {
    leds[halfWay + i] = CRGB(190, 0, 254);
    leds[halfWay - i] = CRGB(190, 0, 254);

    FastLED.show();

    leds[halfWay + i] = CRGB(0, 0, 0);
    leds[halfWay - i] = CRGB(0, 0, 0);

    delay(100);
  }
}

HTH

a7

Thanks. That does work. I think I was trying to be too complicated when I didnt need to be.
My next question is how do I get it to go back the opposite direction back to the center and then stop there?

Also thanks for the Wokwi link. I didnt know that existed. That will be a huge help.

Russ

OK, I'll give you one more fish. Please read the code and try to see how it works. Most things like this can be reduced to a pattern that moves or changes with each step. Speed and direction can both be controlled in various ways. Longer trains of pixels are much the same - decide where the train is and write a train's worth of pixels starting at that point.

Be aware that some calculations might lead to trying to use pixels that aren't there - either addressing negavite numbers or numbers beyond N - 1 real pixels. Insert logic to assure you aren't, or weird stuff can happen.

I had no such guardrails as I could see I was not doing anything like that.

Here's the loop written so the effect runs in reverse

  for (int i = 0; i <= halfWay; i++) {
    leds[i] = CRGB(190, 0, 254);
    leds[NUM_LEDS - 1 - i] = CRGB(190, 0, 254);

    FastLED.show();

    leds[i] = CRGB(0, 0, 0);
    leds[NUM_LEDS - 1 - i] = CRGB(0, 0, 0);

    delay(100);
  }

It's just N number of steps, each lighting up two LEDs calculated to be coming in from the extremes.

I asked chatGPT for a detailed explanation which I am too lazy to write:

Srsly, read that and read the code and ask questions about code you don't exactly understand if you find any. Put your finger right on the code and watch as you "execute" it by hand and see how that indexing works to make the effect.

FWIW chatGPT pointed out an small error in the first code I showed it. Score one for AI. :expressionless:

a7

You seem to have just tested the code without really understanding it.
You seem to have not yet understood the basic concept how it works

all leds are have a number
starting with number 0
first led No: 0
second led No: 1
third led No: 2
fourth led No: 3
etc. etc. etc. etc. etc. etc. etc. etc. etc. etc. etc.
running one led from begin to end
switch on led 0
next iteration switch off led 0 switch on led 1
next iteration switch off led 1 switch on led 2
next iteration switch off led 2 switch on led 3
etc. etc. etc. etc. etc. etc. etc. etc. etc. etc. etc.

which means counting up

running a single led from the end
switch on led 99
next iteration switch off led 99 switch on led 98
next iteration switch off led 98 switch on led 97
next iteration switch off led 97 switch on led 96
etc. etc. etc. etc. etc. etc. etc. etc. etc. etc. etc.

which means counting down.

if you want any different kind of pattern it is again
switching on/off certain led numbers

start from the middle
switch on led 48,49
switch off led 48,49 switch on 47, 50
switch off led 47,50 switch on 46, 51

which means running towards end middle-position + i
which means running towards start middle-position - i

where variable i counts up 0,1,2,3,4,5,6.....

To make it easier to undrstand what is hapenig write down the numbers of each iteration
on a sheet of paper to see the pattern.

You have two choices:

  1. learning enough math (for months) to imagine it in all in your head
  2. taking some hours to write it down on a sheet of paper and then do extract the math formula

Thank you all for the push in the right direction. I did figure it out. Had to modify my original plan on how I wanted to do things but in the end I am happy with what I did. So now that I have the "easy" one done. I am moving on to make my own below the Tailgate Turn signals, brake lights, running lights and reverse lights in one long LED strip. Should be fun. I'll post my (for now) final code. I'm sure I'll keep tweaking it.

#include <FastLED.h>

#define NUM_LEDS 112
#define DATA_PIN 13
const int buttonPin = 2;
int buttonState = 0;      // Current state of the button
bool lastButtonState = false;  // Previous state of the button
bool loopStarted = false;      // Whether the loop has started

CRGB leds[NUM_LEDS];

void setup() {
  FastLED.setBrightness(200);
  FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS);
  pinMode(buttonPin, INPUT);  // Set the button pin as input with internal pull-up
}
void fadeall() {
  for (int i = 0; i < NUM_LEDS; i++) { leds[i].nscale8(175); }
}

void loop() {

  // Turn all LEDs off
  FastLED.clear();
  FastLED.show();

  // Read the current state of the button -------------------------------------
  buttonState = digitalRead(buttonPin);  // Button pressed when HIGH

  // Check if the button was just pressed (edge detection)
  if (buttonState && !lastButtonState) {
    loopStarted = !loopStarted;  // Toggle the state of the loop
        delay(50);  // Debounce delay to avoid multiple triggers
  }
  // Store the current button state for the next loop iteration
  lastButtonState = buttonState;

  // If the loop is started, do something (like blink an LED)
  if (loopStarted) {

    // Set color (90, 254, 0)
    CRGB color = CRGB(90, 254, 0);

    // Set LED 44 through 68 on for 2 seconds at max brightness of 250
    for (int i = 44; i <= 68; i++) {
      leds[i] = color;
    }
    FastLED.setBrightness(250);
    FastLED.show();
    delay(2000);


    // Starts Comet sweep Out from center
    int halfWay = NUM_LEDS / 2;  // the middle of the strip
    // First loop: LED pattern spreads out
    for (int i = 0; i <= halfWay; i++) {


      leds[halfWay + i] = CRGB(90, 254, 0);
      leds[halfWay - i] = CRGB(90, 254, 0);

      FastLED.setBrightness(250);
      FastLED.show();
      fadeall();

      delay(50);
    }

    // Second loop: LEDs return to the center
    for (int i = halfWay - 1; i >= 0; i--) {

      leds[halfWay + i] = CRGB(90, 254, 0);
      leds[halfWay - i] = CRGB(90, 254, 0);

      FastLED.show();
      fadeall();

      delay(50);
    }
    // Turn off all LEDs
    for (int i = 0; i < NUM_LEDS; i++) {
      leds[i] = CRGB(0, 0, 0);
    }
    FastLED.show();
    delay(50);

    // Set LED 44 through 68 on for 2 seconds at max brightness of 250
    for (int i = 44; i <= 68; i++) {
      leds[i] = color;
    }

    FastLED.setBrightness(200);
    FastLED.show();
    delay(2000);

    // Turn all LEDs off
    FastLED.clear();
    FastLED.show();

    // Set LED 10 through 13, 55 through 58, 100 through 103 at brightness 100
    for (int i = 10; i <= 13; i++) {
      leds[i] = CRGB(90, 254, 0);
    }
    for (int i = 55; i <= 58; i++) {
      leds[i] = CRGB(90, 254, 0);
    }
    for (int i = 100; i <= 103; i++) {
      leds[i] = CRGB(90, 254, 0);
    }
    FastLED.setBrightness(150);
    FastLED.show();
    delay(1000);

    // Hold until power removed
    while (true) {
      // do nothing

    }
  }
}

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