Arduino code help with fade_functions

Hello Community,

I'm building a code that takes input from several sensors and the result to display on my sign that has about 100 WS2812 LEDs. I have problems with the code. So here is the situation so far.

I have a DHT11 sensor and a LDR. humidity and HeatIndex values are taken and mapped to a certain color so that its reflected on my sign. And brightness is changed according to the values from the LDR. For these changes in color and brightness I used the map() function but, for a smooth fade used the idea from "Hans Jørgen" (Natural-Nerd/sound_reactive.ino at master · hansjny/Natural-Nerd · GitHub) and managed to play around with the values. the code is 270+ lines. so here is my code:


#include "DHT.h"
#include "FastLED.h"
#include <math.h>

#define DHTPIN 8
#define DHTTYPE DHT11   // DHT 11

#define NUM_LEDS_1 60
#define LED_PIN 10
#define NUM_LEDS_2 21
#define LED_PIN_2 11
#define UPDATES_PER_SECOND 100

int old_temp_color = 0;
int old_humd_color = 0;
int old_brightness = 200;

DHT dht(DHTPIN, DHTTYPE);
CRGB leds_1[NUM_LEDS_1];
CRGB leds_2[NUM_LEDS_2];

/*for sound sensor*/
const int sampleWindow = 50; //sample window width in ms(50ms =20Hz)
unsigned int sample;



/*values for temperature and fade*/
int i;
void fade_between_temp(int a, int b, CRGB leds_1[NUM_LEDS_1], int del, int bright);
void set_definite_temp(int a, CRGB leds_1[NUM_LEDS_1], int bright);

/*values for humidity fade*/
int k;
void fade_between_humd(int e, int f, CRGB leds_2[NUM_LEDS_2], int del, int bright);
void set_definite_humd(int e, CRGB leds_2[NUM_LEDS_2], int bright);

/*values and functions for brightness fade*/
int j;
void fade_between_brightness(int c, int d, CRGB leds_1[NUM_LEDS_1], CRGB leds_2[NUM_LEDS_2], int del, int color1, int color2);
void set_definite_brightness(int c, CRGB leds_1[NUM_LEDS_1], CRGB leds_2[NUM_LEDS_2], int color1, int color2);


/*for LDR*/
int ldr = A0;//Set A0(Analog Input) for LDR.
int ldr_raw = 0;

/*for motion sensor*/
int PIR = 2;
unsigned long myTime;
unsigned long finish;



void setup() {
  Serial.begin(9600);
  Serial.println("starting the system");
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds_1, NUM_LEDS_1);
  FastLED.addLeds<WS2812, LED_PIN_2, GRB>(leds_2, NUM_LEDS_2);

  for (int x = 0, y = 0; (x < NUM_LEDS_1) && (y < NUM_LEDS_2); x++, y++) {
    leds_1[x] = CHSV(255, 0, old_brightness);
    leds_2[y] = CHSV(255, 0, old_brightness);
  }
  FastLED.show();
  delay(2000);
  /*temperature and humidity sensor*/
  dht.begin();

  //  /*PIR sensor*/
  //  pinMode(PIR, INPUT);    // initialize sensor as an input
  //
}

void loop() {
  // Wait a few seconds between measurements.
  delay(2000);
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  float f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  }
  // Compute heat index in Celsius (isFahreheit = false)
  float hic = dht.computeHeatIndex(t, h, false);

  Serial.print(F("Humidity: "));
  Serial.println(h);
  Serial.print(F("%  Temperature: "));
  Serial.println(t);
  Serial.println(F("°C "));
  Serial.println(f);
  Serial.print(F("°F  Heat index: "));
  Serial.println(hic);
  Serial.println(F("°C "));

  if (hic < 18) {
    hic = 18;
  }
  if (hic > 35) {
    hic = 35;
  }
  int new_temp_color = map(hic, 18, 35, 95, 0);
  Serial.print(" new_temp_color = ");
  Serial.println(new_temp_color);
  Serial.print(" old_temp_color = ");
  Serial.println(old_temp_color);

  if (new_temp_color < 0) {
    new_temp_color = 0;
  }
  if (new_temp_color > 95) {
    new_temp_color = 95;
  }
  fade_between_temp(old_temp_color, new_temp_color, leds_1, 100, old_brightness );
  delay(1000);
  old_temp_color = new_temp_color;


  if (h < 10) {
    hic = 1;
  }
  if (h > 85) {
    hic = 85;
  }
  int new_humd_color = map(h, 10, 85, 135, 165);
  Serial.print(" new_humd_color = ");
  Serial.println(new_humd_color);
  Serial.print(" old_humd_color = ");
  Serial.println(old_humd_color);

  if (new_humd_color < 135) {
    new_humd_color = 135;
  }
  if (new_humd_color > 165) {
    new_humd_color = 165;
  }
  fade_between_humd(old_humd_color, new_humd_color, leds_2, 100, old_brightness );
  delay(1000);
  old_humd_color = new_humd_color;

  /*LDR sensor*/
  // Wait a few seconds between measurements.
  delay(1000);
  ldr_raw = analogRead(ldr);//Reads the Value of LDR(light).
  int new_brightness = map(ldr_raw, 0, 1000, 255, 50);
  Serial.print(" new brightness = ");
  Serial.println(new_brightness);
  Serial.print(" old brightness = ");
  Serial.println(old_brightness);

  fade_between_brightness(old_brightness, new_brightness, leds_1, leds_2, 100, new_temp_color, new_humd_color);
  delay(1000);
  old_brightness = new_brightness;

  //  /*pir sensor*/
  //  delay(500);
  //   Serial.println("HIHI");
  //  //Wait a few seconds between measurements
  //  int val = digitalRead(PIR);   // read sensor value
  //  if (val == HIGH) {           // check if the sensor is HIGH
  //
  //    Serial.println("motion detected");
  //    myTime = millis();
  //    finish = myTime + 10000;
  //
  //    rainbow();
  //
  //    while (millis() != finish) /* spin your wheels */ ;



}



/*for temp color fade*/
void fade_between_temp(int a, int b, CRGB leds_1[NUM_LEDS_1], int del, int bright) {
  int i, j, steps = 100;
  double dsteps = 100.0;
  double s1, tmp1;
  s1 = double((b - a)) / dsteps;
  tmp1 = a;

  for (i = 0; i < steps; i++) {
    tmp1 += s1;
    for (j = 0; j < NUM_LEDS_1; j++)
      leds_1[j] = CHSV((int)round(tmp1), 255, bright);
    FastLED.show();
    delay(del);
  }
  set_definite_temp(b, leds_1, bright);
}

void set_definite_temp(int a, CRGB leds_1[NUM_LEDS_1], int bright) {
  int i;
  for (i = 0; i < NUM_LEDS_1; i++)
    leds_1[i] = CHSV(a, 255, bright);

  FastLED.show();
}

/*for humd color fade*/
void fade_between_humd(int e, int f, CRGB leds_2[NUM_LEDS_2], int del, int bright) {
  int i, j, steps = 100;
  double dsteps = 100.0;
  double s1, humd1;
  s1 = double((f - e)) / dsteps;
  humd1 = e;

  for (i = 0; i < steps; i++) {
    humd1 += s1;
    for (j = 0; j < NUM_LEDS_2; j++)
      leds_2[j] = CHSV((int)round(humd1), 255, bright);
    FastLED.show();
    delay(del);
  }
  set_definite_humd(f, leds_2, bright);
}

void set_definite_humd(int e, CRGB leds_2[NUM_LEDS_2], int bright) {
  int i;
  for (i = 0; i < NUM_LEDS_2; i++)
    leds_2[i] = CHSV(e, 255, bright);

  FastLED.show();
}


/*for brightness fade*/
void fade_between_brightness(int c, int d, CRGB leds_1[NUM_LEDS_1], CRGB leds_2[NUM_LEDS_2], int del, int color1, int color2) {
  int j, k, l, steps = 100;
  double dsteps = 100.0;
  double s1, bright1;
  s1 = double((d - c)) / dsteps;
  bright1 = c;

  for (j = 0; j < steps; j++) {
    bright1 += s1;
    for (k = 0, l = 0; (k < NUM_LEDS_1) && (l < NUM_LEDS_2); k++, l++)
      leds_1[k] = CHSV(color1, 255, (int)round(bright1));
    leds_2[l] = CHSV(color2, 255, (int)round(bright1));
    FastLED.show();
    delay(del);
  }
  set_definite_brightness(d, leds_1, leds_2, color1, color2);
}

void set_definite_brightness(int c, CRGB leds_1[NUM_LEDS_1], CRGB leds_2[NUM_LEDS_2], int color1, int color2) {
  int j, k;
  for (j = 0, k = 0; (j < NUM_LEDS_1) && (k < NUM_LEDS_2); j++, k++)
    leds_1[j] = CHSV(color1, 255, c);
  leds_2[k] = CHSV(color2, 255, c);

  FastLED.show();
}


/*patterns if motion is detected*/
void rainbow() {
  for (int i = 0; i < NUM_LEDS_1; i++) {
    fill_rainbow(leds_1, i, 0, 255 / NUM_LEDS_1);
    FastLED.show();
    delay(50);
  }
  FastLED.clear();
}

The problem now: Everything works fine except the humidity_fade function, where the old_humidity value keeps changing abruptly which disturb the colour fading function that's related to humidity. I don't know where these values are coming from. If you see my code, the error is somewhere between 132-146 lines.
Could somebody please help me solve this issue?

Why not load it here following the advice in How to get the best out of this forum about using code tags

and please don't post pictures of Serial monitor output. Select the text using the mouse, copy it to the clipboard using Ctrl+c then paste it here in code tags

Im sorry about the previous format of my post. I edited it to fit in the code, but unfortunately, I cannot copy any text from my serial monitor. I have tried many suggestions, but this doesn't work

I don't know if this your problem, but it looks odd, perhaps a copy & paste issue:

  if (h < 10)
  {
    hic = 1;
  }
  if (h > 85)
  {
    hic = 85;
  }

It looks like you're trying to constrain h, but changing hic instead.

What happens when you try ?

Select the text using the mouse
Copy the selected text to the clipboard using Ctrl+C if on a PC or Command+C if on a Mac
Paste the copied text here in code tags

this is my bad. its actually not the issue. i tried to limit 'h' to see if it will solve these abrupt values. but it did not solve my problem. i feel like the problem is in this part of the code

old_humd_color = new_humd_color;

What do your serial prints show is happening with the new and old readings?

it only paste my first time stamp

from the second loop cycle onwards, the new_humd_value is calculated and prints correct (around 150 on average) . But the old value is some abrupt value around (2500+) and this value keeps changing in every cycle

Which version of the IDE and which Operating System are you using ?

IDE 1.8.13 and im using a windows10

Are you sure that you selected the whole of the text ?

yeah. i did. scrolling down and also by ctrl+A

What do you see if you select and copy the text into Notepad?

its the same thing. only the first time stamp copies to the notepad

I know that I said not to post screenshots, but can you please post a screenshot of what it looks like when you have selected the text ? What is copied if you turn off the timestamps ?

It actually pastes nothing when I turn off the time stamps.

This doesn't look good:

    for (k = 0, l = 0; (k < NUM_LEDS_1) && (l < NUM_LEDS_2); k++, l++)
      leds_1[k] = CHSV(color1, 255, (int)round(bright1));
    leds_2[l] = CHSV(color2, 255, (int)round(bright1));

Shouldn't there be some braces there? As you have it you're writing off the end of your array.
Same thing later on too.

Also, why pass leds_1 and leds_2 - they're globals anyway and you're just burning stack.

1 Like

This was the issue. now its working again :slight_smile: Thank you!

I didn't understand this. If I don't pass these two arrays, how can I inform this fade function, which array the function for.?

How exactly are you doing the copy after selecting the text ?