NEOPIXEL brightness control

EL Wire/Tape/Panels, LEDs, pixels and strips, LCDs and TFTs, etc products from Adafruit

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: NEOPIXEL brightness control

Post by adafruit_support_rick »

You want to add the function declarations to this list in the .h file:

Code: Select all

  void
    begin(void),
    show(void),
    setPin(uint8_t p),
    setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b),
    setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w),
    setPixelColor(uint16_t n, uint32_t c),
    setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t brightness),  //added
    setPixelColor(uint16_t n, uint32_t c, uint8_t brightness),                           //added
    setBrightness(uint8_t),
    clear(),
    updateLength(uint16_t n),
    updateType(neoPixelType t);
Your functions look OK, except you want to add 1 to brightness. See the the comment on setBrightness() for an explanation of this.
Also, brightness needs to be uint8_t, not uint16_t

Code: Select all

// Set pixel brightness individually using seperate R,G,B components:
void Adafruit_NeoPixel::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t brightness) {
  brightness = brightness + 1;
  setPixelColor(n, (brightness*r/255) , (brightness*g/255), (brightness*b/255));
}

// Set pixel brightness individually using a 'packed' 32-bit RGB color:
void Adafruit_NeoPixel::setPixelColor(uint16_t n, uint32_t c, uint8_t brightness) {
   uint8_t
      r = (uint8_t)(c >> 16),
      g = (uint8_t)(c >>  8),
      b = (uint8_t)c;
  setPixelColor(n, r, g, b, brightness);
}

User avatar
Bazeman
 
Posts: 3
Joined: Tue May 02, 2017 6:18 pm

Re: NEOPIXEL brightness control

Post by Bazeman »

Hi Rick,

Thanks again for the help!

I had added the code to the .H and .CPP file, but as soon I inserted the extra lines only in the .H file, no program using the neopixel library wanted to compile anymore... I finally changed back the uint8_t brightness, back to uint16_t brightness as Chargerdude70 had put in his code, and after that I did not got any errors anymore....

Then I also added the lines to the .cpp file and the chasefade.ino file that you posted on page 4, works...

Can you explain why you said/thought that the uint brightness should be 8 and not 16?? I'm allready happy that the programs run now and I can fiddle with the effect, but I also want to understand why you said what you said, for future reference and understanding ;-)

Thanks!

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: NEOPIXEL brightness control

Post by adafruit_support_rick »

In the rest of the library, brightness is a uint8_t. You don't have any more levels of brightness on a neopixel, since they only support 8 bits/color. The calculations will work with a uint16_t. But you don't need it because it implies more than 8 bit control.

User avatar
xl97
 
Posts: 201
Joined: Mon Jul 27, 2009 12:51 pm

Re: NEOPIXEL brightness control

Post by xl97 »

Sorry to bring up an old thread like this.. but I 'too' am on the look out for a decent (normal) fade function for Dotstars (Neopixels)..

From skimming this thread.. it seems that the approach here is use setBrightness()? (but I though I had read somewhere that using setBrightness() is NOT the correct way to fade an led strip?

Also doesnt brightness only limit you to a certain number of 'steps'? (so maybe clunky at best?)

I am looking for a 'fade' function that does the following:

* fades from off (0,0,0) to orange (255, 155, 0)... when a button is pressed
* when the button is released... I need to fade from orange (255,155,0) to off (0,0,0) again..

the 'catch' here is that,, if I let go of the button (release) before the 'fade-in' is complete.. I want the 'fade-out' to start at the exact point/level the fade-in stopped.

* I do not want to start fade-out at the (255,155,0) value if it never reached that point during fade-in before initiating the fade-out.... (make sense?)

The color shouldnt matter.. as I should be able to set that from a variable or passed in as a parameter to the function.

I need it to be non-blocking.. as the 'function' will be called inside of a millis() statement whenever the 'time' is right..

Is the setBrightness() approach Ive seen outlined here the bets way to achieve this?

I still need to come up with a non-blocking 'fire' pattern/animation.. (because if the button is still being pressed AFTER fade-in has completed.. I need to seamlessly transition to a different led strip animation/pattern).. but I'll hold of on that until I can come to grips on how to properly fade in/out from one color.


@adafruit_support_rick - maybe you have some suggestions or an available function perhaps?

Thanks.

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: NEOPIXEL brightness control

Post by adafruit_support_bill »

The setBrightness function is 'lossy'. Since it operates directly on the pixel data, once you decrease brightness, information about the original brightness is lost, so you can never get back to that level.

Given all your requirements, this is the approach I'd use:

https://learn.adafruit.com/multi-taskin ... 3/overview

User avatar
xl97
 
Posts: 201
Joined: Mon Jul 27, 2009 12:51 pm

Re: NEOPIXEL brightness control

Post by xl97 »

adafruit_support_bill wrote:The setBrightness function is 'lossy'. Since it operates directly on the pixel data, once you decrease brightness, information about the original brightness is lost, so you can never get back to that level.

Given all your requirements, this is the approach I'd use:

https://learn.adafruit.com/multi-taskin ... 3/overview
Thanks for the reply..

I was re-reading that tutorial.. I just keep feeling like it so much 'overkill' just to fade out to off (0,0,0) or off to a single color.

I'm also not sure if the fade() or fadeUpdate() function is what I need? (I 'think' it is.. but the video shows it fading between two colors)..

update: ok.. I see now that you define the colors to use by the Color1 and Color2 variables...

Does it need to be in a class? I already have an 'active pattern' type of set-up sketch going on.. (taken from many of the other Neopixel examples).. which sorta loosely follows this approach.



Lastly.. since I'm working with Dotstars.. can I just change:

class NeoPatterns : public Adafruit_NeoPixel

to
class NeoPatterns : public Adafruit_DotStar



So I'm still a little confused/un-clear on what I need to strip out..... to get it implemented into my current sketch?

Here is my current sketch: (please ignore the currentTrack and doCompletion variables/checks ....those pertain to audio stuff that I ripped out to make it only focus on the led implementation)..

Any advice on what I need to rip form the tutorial is appreciated! :)

Code: Select all



#include <Adafruit_DotStar.h>.
#include <SPI.h>

//neopixels 
/*
#include <Adafruit_NeoPixel.h>
#define PINforControl 6 // pin connected to the small NeoPixels strip
#define NUMPIXELS1 8 // number of LEDs on strip
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS1, PINforControl, NEO_GRB + NEO_KHZ800);
*/

//dotstars
#define NUMPIXELS 144 //temp number
Adafruit_DotStar strip = Adafruit_DotStar(NUMPIXELS, DOTSTAR_BGR); //Royce's strip

const int buttonPin = 2;  //A5 = D19
int buttonState = 0;
int lastButtonState = 1;
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 5;    // the debounce time; increase if the output flickers


unsigned long patternUpdateInterval = 10;
unsigned long powerOnSpeed = 5; //lower = faster
unsigned long powerDownSpeed = 15; //lower = faster
unsigned long thrustSpeed = 10; //lower = faster
unsigned long lastPatternUpdate = 0;
int targetPattern = 0;

uint32_t red = strip.Color(255, 0, 0);
uint32_t green = strip.Color(0, 255, 0);
uint32_t blue = strip.Color(0, 0, 255);
uint32_t nocolor = strip.Color(255,255,255);



#define S_IDLE 1
#define S_POWERON 2
#define S_POWERDOWN 3
static int state = S_IDLE;


void setup() {
  //debug (monitor)
  Serial.begin(115200);
  
  //neopixel strip setup  (doesnt seem work to reset leds to 'off'
  Serial.println(F("turn all leds off")); //read current volume
  strip.begin(); // Initialize pins for output
  strip.show(); //reset all leds to off 
  //clearall();
   
  pinMode(buttonPin, INPUT);
  digitalWrite(buttonPin, HIGH);

}

void loop() { 
	switch (state) {
		case S_IDLE:
			buttonState = digitalRead(buttonPin);
			//if (buttonState != lastButtonState) {
			if ((buttonState != lastButtonState) && (millis() - lastDebounceTime > debounceDelay)) {
				lastDebounceTime = millis(); //update last time pressed/released       
				
				if (buttonState == LOW) { 
					state = S_POWERON;
         
				}else { 
					state = S_POWERDOWN;
         
				}   
			}else{       
				if(buttonState == LOW) {           
					if(currentTrack == 2 && doCompletionCheck == true){
						if (millis() - lastPowerOnCompletionCheck > powerOnCompletionCheckDelay) {
							lastPowerOnCompletionCheck = millis(); //update last time checked for file completion
							targetPattern = 1;
							patternUpdateInterval = thrustSpeed;            
							currentTrack = 3;
							doCompletionCheck = false;                
						}
					}
					//continue updating pattern whether is be poweron pattern or thrust pattern if button still pressed
					if(millis() - lastPatternUpdate > patternUpdateInterval){
						updatePattern(targetPattern);            
					} 
                                     
				}else{                 
					if(currentTrack == 4 && doCompletionCheck == true){
						if (millis() - lastPowerDownCompletionCheck > powerDownCompletionCheckDelay) {
							lastPowerOnCompletionCheck = millis(); //update last time checked for file completion          
							doCompletionCheck = false;    
							clearall();                                     
						}	

						//update led pattern/animation
						if(millis() - lastPatternUpdate > patternUpdateInterval && doCompletionCheck == true){
							updatePattern(targetPattern);              
						}
            
					}
				}       
			}
			lastButtonState = buttonState;
		break;

   

		case S_POWERON:			
			Serial.println(F("[POWER ON]"));
			currentTrack = 2;     
			doCompletionCheck = true;
			
			//update led pattern/animation
			targetPattern = 0;
			patternUpdateInterval = powerOnSpeed;     
			updatePattern(targetPattern);
      
			lastPowerOnCompletionCheck = millis(); //update last time checked for file completion

			//return to button checking (idle state)
			state = S_IDLE;
		break;

   

		case S_POWERDOWN:     
			Serial.println(F("[POWER DOWN]"));
			currentTrack = 4;
			doCompletionCheck = true;
			
			//update led pattern/animation
			targetPattern = 2;
			patternUpdateInterval = powerDownSpeed;
			updatePattern(targetPattern);
			
			lastPowerDownCompletionCheck = millis(); //update last time checked for file completion

			//return to button checking (idle state)
			state = S_IDLE;   
		break;
	}

}

//--[neopixel pattern code]--//
void  updatePattern(int newPattern){
  switch(newPattern) {
    case 0:        
        FadeUpdate(); //new addition from tutorial (function only?)
        //setColor(red);
        break;
    case 1:
        setColor(blue);
        break;
    case 2:
        setColor(green);
        break;
    case 3:
         setColor(red);
         break;     
  } 
}

void clearall(){
	for(int i=0;i<NUMPIXELS;i++){
		strip.setPixelColor(i, strip.Color(0,0,0));
	}
	strip.show();
	//Serial.println(F("--should be all cleared--"));
}

void setColor(uint32_t targetColor){   
   
	for(int i=0;i<NUMPIXELS;i++){
		if(i<12){
			strip.setPixelColor(i, targetColor);
		}else{
			strip.setPixelColor(i, 0, 0, 0); 
		}
	}	   
	strip.show();
	lastPatternUpdate = millis();  //update pattern time stamp
}




User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: NEOPIXEL brightness control

Post by adafruit_support_bill »

I just keep feeling like it so much 'overkill'
You don't have to use all of the patterns. Only the ones that you need.
I'm also not sure if the fade() or fadeUpdate() function is what I need?
Both. fade() sets up the colors and timing. fadeUpdate() is what does the actual work based on the millis() timer.
Does it need to be in a class?
It is not essential if you are only doing one pattern at a time. But the class is already written for you. The simplest approach is to just use it.
Lastly.. since I'm working with Dotstars.. can I just change:

class NeoPatterns : public Adafruit_NeoPixel

to
class NeoPatterns : public Adafruit_DotStar
Yes. The libraries are pretty much identical once you initialize the strip.

User avatar
xl97
 
Posts: 201
Joined: Mon Jul 27, 2009 12:51 pm

Re: NEOPIXEL brightness control

Post by xl97 »

bummer.. I was hoping to easily integrate it into what I have going on already....

I'll guess I take a closer look tonight when I get home from work.

Thanks!

User avatar
xl97
 
Posts: 201
Joined: Mon Jul 27, 2009 12:51 pm

Re: NEOPIXEL brightness control

Post by xl97 »

(Finally!.. the weekend is here.. so I can get back to this!)

So I am (finally) attempting to strip out the lone function, and all supporting vars and dependencies/functions..

On my first attempt to compile/upload..

I am getting the error: "Color" was not declared in this scope

Stemming from this line:
ColorSet(Color(red, green, blue));

Where does the 'Color()' function come from? From some library (that I didnt include?)

I am NOT using any sort of classes here..

My current approach is to rip most things out to global variables.. (updated at various times/events).. and take out the fadeUpdate() function to be used standalone.

I'm sure I'll have many more issues to resolve, but for now this is the first one.

Thanks in advance for any direction on solving this.

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: NEOPIXEL brightness control

Post by adafruit_support_bill »

I am NOT using any sort of classes here..
That is the problem then. If you pull the code out of the class, you lose all of the members and properties of the class.

The NeoPatterns class was derived from the Neopixels class. So i inherited all of the members and properties of the Neopixels class - including the member function "Color".

Since your code is not derived from the Neopixel class anymore, you need to explicitly tell it where to find the color function you want it to use.

User avatar
xl97
 
Posts: 201
Joined: Mon Jul 27, 2009 12:51 pm

Re: NEOPIXEL brightness control

Post by xl97 »

How do I do that? (reference it specifically that is?)


If I am still using the DotStar library.... wouldn't it still 'be there' for use? (sorry.. still not fully up to speed on classes/OOP stuff for C++ yet... trying though!)

I just need to use the name I used to instantiate my led strip then? (Is that what your saying?)

So basically.. strip.Color() instead of just referencing Color().. got it! (thanks)..

So I made some updates... I am not getting any errors.... but the fade is -not- working..

I tried to make a simple state machine sketch that checks for press..

if pressed starts the FADE IN pattern.. if button is still being pressed... continue with fade in pattern.. if button is released.. initiate FADE OUT pattern.. (currentyl commented the fade out portion out as it just automatically triggers after a few seconds..

so for now.. just press button.. start fade in pattern.. if button is STILL being pressed..continue to update FADE IN pattern..

No errors.. but the fade is -not- correct.. it just seems to start/jump to a white'ish color when button is pressed..... and then then sorta 'twinkle' as the button is still being pressed.... when let go.. it ends up a very random shade of white// (sometimes pink-white.. sometimes a lightgreen-white..etc)

Not sure what I'm missing here? am I not updating a var? or setting something?

Code: Select all


//neopixels
/*
  #include <Adafruit_NeoPixel.h>
  #define PINforControl 6 // pin connected to the small NeoPixels strip
  #define NUMPIXELS 8 // number of LEDs on strip
  Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, PINforControl, NEO_GRB + NEO_KHZ800);
*/

//dotstars
#include <Adafruit_DotStar.h>
#include <SPI.h>
#define NUMPIXELS 144 //temp number
Adafruit_DotStar strip = Adafruit_DotStar(NUMPIXELS, DOTSTAR_BGR); //Royce's strip

// Patern directions supported:
enum  direction { FORWARD, REVERSE };
direction Direction = FORWARD;   // direction to run the pattern - no direction needed in this project (kept for posterity for now)
void (*OnComplete)();  // Callback on completion of pattern -// not implemented yet in my current sketch

const int buttonPin = 2;  //A5 = D19
int buttonState = 0;
int lastButtonState = 1;
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 10;    // the debounce time; increase if the output flickers

uint16_t totalPatternSteps;  // total number of steps in the pattern
uint16_t currentPatternStep;
unsigned long patternUpdateInterval = 3000; // milliseconds between updates
unsigned long powerOnSpeed = 3000; //lower = faster
unsigned long powerDownSpeed = 3000; //lower = faster
unsigned long lastPatternUpdate = 0; // timestamp of last update to led pattern
uint32_t Color1; // What colors are in use
uint32_t Color2; // What colors are in use
int targetPattern = 0; // which pattern is running

uint32_t red = strip.Color(255, 0, 0);
uint32_t green = strip.Color(0, 255, 0);
uint32_t blue = strip.Color(0, 0, 255);
uint32_t nocolor = strip.Color(255, 255, 255);

long lastPowerOnCompletionCheck = 0;  // the last time the output pin was toggled
long lastPowerDownCompletionCheck = 0;  // the last time the output pin was toggled

#define S_IDLE 1
#define S_FADEIN 2
#define S_FADEOUT 3
static int state = S_IDLE;


void setup() {
  //debug (monitor)
  Serial.begin(115200);

  //neopixel strip setup  (doesnt seem work to reset leds to 'off'
  Serial.println(F("turn all leds off")); //read current volume
  strip.begin(); // Initialize pins for output
  strip.show(); //reset all leds to off
  clearall();

  pinMode(buttonPin, INPUT);
  digitalWrite(buttonPin, HIGH);

  Color1 = Wheel(random(255)); // What colors are in use
  Color2 = Wheel(random(255)); // What colors are in use

}

void loop() {
  switch (state) {

    case S_IDLE:
      buttonState = digitalRead(buttonPin);
      if ((buttonState != lastButtonState) && (millis() - lastDebounceTime > debounceDelay)) {
        lastDebounceTime = millis(); //update last time pressed/released
              
        if (buttonState == LOW) {
          state = S_FADEIN;
        } else {
          state = S_FADEOUT;
        }

      }else {
        //no button state change, but still being pressed/held low
        if (buttonState == LOW) {
          //continue updating pattern if button is still pressed.
          if (millis() - lastPatternUpdate > patternUpdateInterval) {
            updatePattern(targetPattern);
          }

        } else {
          //update led pattern/animation
          //if (millis() - lastPatternUpdate > patternUpdateInterval) {
            //updatePattern(targetPattern);
          //}
        }
      }
      lastButtonState = buttonState;
      break;



    case S_FADEIN:
      Serial.println(F("[FADE IN]"));

      //set colors for fade in pattern/animation
      Color1 = nocolor; // What colors are in use
      Color2 = red; // What colors are in use

      //update led pattern/animation
      targetPattern = 0;
      patternUpdateInterval = powerOnSpeed;
      totalPatternSteps = 20;
      updatePattern(targetPattern);

      //update timestamp
      lastPowerOnCompletionCheck = millis(); //update last time checked for file completion

      //return to button checking (idle state)
      state = S_IDLE;
      break;



    case S_FADEOUT:
      Serial.println(F("[FADE OUT]"));

      //set colors for fade in pattern/animation
      Color1 = red; // What colors are in use
      Color2 = nocolor; // What colors are in use

      //update led pattern/animation
      targetPattern = 2;
      patternUpdateInterval = powerDownSpeed;
      totalPatternSteps = 30;
      updatePattern(targetPattern);

      //update timestamp
      lastPowerDownCompletionCheck = millis(); //update last time checked for file completion

      //return to button checking (idle state)
      state = S_IDLE;
      break;
  }

}

//--[neopixel pattern code]--//
void  updatePattern(int newPattern) {
  switch (newPattern) {
    case 0:
      FadeUpdate(); //new addition from tutorial (function only?)
      //setColor(red);
      break;
    case 1:
      FadeUpdate();
      //setColor(blue);
      break;
    case 2:
      FadeUpdate();
      //setColor(green);
      break;
    case 3:
      setColor(red);
      break;
  }
}

void clearall() {
  for (int i = 0; i < NUMPIXELS; i++) {
    strip.setPixelColor(i, strip.Color(0, 0, 0));
  }
  strip.show();
  //Serial.println(F("--should be all cleared--"));
}

void setColor(uint32_t targetColor) {

  for (int i = 0; i < NUMPIXELS; i++) {
    if (i < 12) {
      strip.setPixelColor(i, targetColor);
    } else {
      strip.setPixelColor(i, 0, 0, 0);
    }
  }
  strip.show();
  lastPatternUpdate = millis();  //update pattern time stamp
}


// Increment the index and reset at the end
void Increment() {
  if (Direction == FORWARD) {
    currentPatternStep++;
    if (currentPatternStep >= totalPatternSteps) {
      currentPatternStep = 0;
      if (OnComplete != NULL) {
        OnComplete(); // call the comlpetion callback
      }
    }
  } else { // Direction == REVERSE
    --currentPatternStep;
    if (currentPatternStep <= 0) {
      currentPatternStep = totalPatternSteps - 1;
      if (OnComplete != NULL) {
        OnComplete(); // call the comlpetion callback
      }
    }
  }
}



// Update the Fade Pattern - - //the gold of what I need.
void FadeUpdate() {
  //Serial.println(F("Fade pattern update....."));
  uint8_t red = ((Red(Color1) * (totalPatternSteps - currentPatternStep)) + (Red(Color2) * currentPatternStep)) / totalPatternSteps;
  uint8_t green = ((Green(Color1) * (totalPatternSteps - currentPatternStep)) + (Green(Color2) * currentPatternStep)) / totalPatternSteps;
  uint8_t blue = ((Blue(Color1) * (totalPatternSteps - currentPatternStep)) + (Blue(Color2) * currentPatternStep)) / totalPatternSteps;
  ColorSet(strip.Color(red, green, blue));
  strip.show();
  Increment();
}

// Returns the Red component of a 32-bit color
uint8_t Red(uint32_t color) {
  return (color >> 16) & 0xFF;
}

// Returns the Green component of a 32-bit color
uint8_t Green(uint32_t color) {
  return (color >> 8) & 0xFF;
}

// Returns the Blue component of a 32-bit color
uint8_t Blue(uint32_t color) {
  return color & 0xFF;
}

// Set all pixels to a color (synchronously)
void ColorSet(uint32_t color) {
  Serial.println(F("Setting color...."));
  for (int i = 0; i < strip.numPixels(); i++) {
    strip.setPixelColor(i, color);
  }
  strip.show();
}


// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if (WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else if (WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  } else {
    WheelPos -= 170;
    return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  }
}


// Initialize for a Fade -- // Needed?  can be set by poweron/powerdown states?
/*
void Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t patternUpdateInterval, direction dir = FORWARD) {
  targetPattern = 0;
  patternUpdateInterval = powerOnSpeed;
  totalPatternSteps = steps;
  Color1 = color1;
  Color2 = color2;
  currentPatternStep = 0;
  Direction = dir;
}
*/


User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: NEOPIXEL brightness control

Post by adafruit_support_bill »

How do I do that? (reference it specifically that is?)
The Color function is still part of the DotStar class, so you need to reference it via an instance of that class. If you have an instance called "strip", then you can access the Color function using "strip.Color")
No errors.. but the fade is -not- correct.. it just seems to start/jump to a white'ish color when button is pressed..... and then then sorta 'twinkle' as the button is still being pressed.... when let go.. it ends up a very random shade of white// (sometimes pink-white.. sometimes a lightgreen-white..etc)
Both the FadeIn and FadeOut cases in your code perform exactly one update, then return to idle.

User avatar
xl97
 
Posts: 201
Joined: Mon Jul 27, 2009 12:51 pm

Re: NEOPIXEL brightness control

Post by xl97 »

adafruit_support_bill wrote: Both the FadeIn and FadeOut cases in your code perform exactly one update, then return to idle.
That is correct..

but while back in the 'idle' state.. I am checking to see if the button is STILL being pressed...

if it -is- still being pressed.. my intent/approach was to still update the perform the pattern update.. like so:

Code: Select all

if (millis() - lastPatternUpdate > patternUpdateInterval) {
     updatePattern(targetPattern);
}
Which in my mind means..

upon initial button press..
* go to FADEIN state.. set some vars, initiate initial pattern update..
* go back to idle (button checking).. see if button is STILL being held down.. (as the fade in should only continue while button is pressed.. when let go, it should trigger fade out pattern/updates).... keep updating the pattern...etc..

I feel like I'm closer to get it standalone (still some code clean up/updates needed).. but once I have it working standalone.. I can refactor and use it in my current sketch/project)
Last edited by xl97 on Sat Mar 17, 2018 2:58 pm, edited 1 time in total.

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: NEOPIXEL brightness control

Post by adafruit_support_bill »

So your states are not really states then. Just transitions between states.

So how is Fade out supposed to work then? You reverse the fade colors when the button is released, but you don't update them unless the button is pressed.

User avatar
xl97
 
Posts: 201
Joined: Mon Jul 27, 2009 12:51 pm

Re: NEOPIXEL brightness control

Post by xl97 »

adafruit_support_bill wrote:So your states are not really states then. Just transitions between states.
Fair enough. I suppose that is more accurate.

So how is Fade out supposed to work then? You reverse the fade colors when the button is released, but you don't update them unless the button is pressed.
Close... except it updates because its 'still in not-pressed' button state...(button press update fade-in,.... button release updates fade-out)

I havent given too much though to the fadeout function yet.. (as I was still just trying to wrap my head around getting a normal 'fade in' function to work....at all)..

but in theory.. yes. When the button is released.
* reverse colors (although in the end.. I'd like to use getPixelColor() to set the initial color1 (because you cant be sure at what point in the 'fade-in' pattern (color) you are when released..
* set some other vars like what pattern to use, patternIntervalSpeed, totalSteps...etc..etc..
* return back to the button checking (idle) state...

if there has been NO button state change once back in the IDLE state.. then continue to update until pattern is complete/total steps reached..etc..etc..


This latest version is sorta working (for the fade-in portion only)

Except that it keeps fading in over and over (and I need to play with the speed/timing more I suppose)..

However.. the release (fade-out) doesnt work.. and when I press the button again.. it doesn random behavior color, blinks..etc)

Code: Select all







//neopixels
/*
  #include <Adafruit_NeoPixel.h>
  #define PINforControl 6 // pin connected to the small NeoPixels strip
  #define NUMPIXELS 8 // number of LEDs on strip
  Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, PINforControl, NEO_GRB + NEO_KHZ800);
*/

//dotstars
#include <Adafruit_DotStar.h>
#include <SPI.h>
#define NUMPIXELS 144 //temp number
Adafruit_DotStar strip = Adafruit_DotStar(NUMPIXELS, DOTSTAR_BGR); //Royce's strip

// Patern directions supported:
enum  direction { FORWARD, REVERSE };
direction Direction = FORWARD;   // direction to run the pattern - no direction needed in this project (kept for posterity for now)
void (*OnComplete)();  // Callback on completion of pattern -// not implemented yet in my current sketch

const int buttonPin = 2;  //A5 = D19
int buttonState = 0;
int lastButtonState = 1;
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 10;    // the debounce time; increase if the output flickers

unsigned long lastPatternUpdate = 0; // timestamp of last update to led pattern
uint16_t totalPatternSteps;  // total number of steps in the pattern
uint16_t currentPatternStep;
unsigned long patternUpdateInterval = 30; // milliseconds between updates
unsigned long powerOnSpeed = 30; //lower = faster
unsigned long powerDownSpeed = 30; //lower = faster

uint32_t Color1; // What colors are in use
uint32_t Color2; // What colors are in use
int targetPattern = 0; // which pattern is running

uint32_t red = strip.Color(255, 0, 0);
uint32_t green = strip.Color(0, 255, 0);
uint32_t blue = strip.Color(0, 0, 255);
uint32_t nocolor = strip.Color(255, 255, 255);

long lastPowerOnCompletionCheck = 0;  // the last time the output pin was toggled
long lastPowerDownCompletionCheck = 0;  // the last time the output pin was toggled

#define S_IDLE 1
#define S_FADEIN 2
#define S_FADEOUT 3
static int state = S_IDLE;

bool doFadeout = false;
bool doFadeIn = false;

void setup() {
  //debug (monitor)
  Serial.begin(115200);

  //neopixel strip setup  (doesnt seem work to reset leds to 'off'
  Serial.println(F("turn all leds off")); //read current volume
  strip.begin(); // Initialize pins for output
  strip.show(); //reset all leds to off
  clearall();

  pinMode(buttonPin, INPUT);
  digitalWrite(buttonPin, HIGH);

  //Color1 = Wheel(random(255)); // What colors are in use
  //Color2 = Wheel(random(255)); // What colors are in use

}

void loop() {
  switch (state) {

    case S_IDLE:
      buttonState = digitalRead(buttonPin);
      if ((buttonState != lastButtonState) && (millis() - lastDebounceTime > debounceDelay)) {
        lastDebounceTime = millis(); //update last time pressed/released
              
        if (buttonState == LOW) {
          state = S_FADEIN;
        } else {
          //state = S_FADEOUT;
        }

      }else {
        //no button state change, but still being pressed/held low
        if (buttonState == LOW) {
          //continue updating pattern if button is still pressed.
          if (millis() - lastPatternUpdate > patternUpdateInterval && doFadeIn == true) {
            updatePattern(targetPattern);
          }

        } else {
          //update led pattern/animation
          //if (millis() - lastPatternUpdate > patternUpdateInterval && doFadeout == true) {
            //updatePattern(targetPattern);
          //}
        }
      }
      lastButtonState = buttonState;
      break;



    case S_FADEIN:
      Serial.println(F("[FADE IN]"));
      doFadeIn = true;
      
      //set colors for fade in pattern/animation
      Color1 = strip.getPixelColor(0); //nocolor; // What colors are in use
      Color2 = red; // What colors are in use

      //update led pattern/animation
      targetPattern = 0;
      patternUpdateInterval = powerOnSpeed;
      totalPatternSteps = 200;
      updatePattern(targetPattern);

      //update timestamp
      lastPowerOnCompletionCheck = millis(); //update last time checked for file completion

      //return to button checking (idle state)
      state = S_IDLE;
      break;



    case S_FADEOUT:
      Serial.println(F("[FADE OUT]"));

      doFadeout = true;
      
      //set colors for fade in pattern/animation
      //Color1 = red; // What colors are in use
      Color1 = strip.getPixelColor(0);
      Color2 = nocolor; // What colors are in use

      //update led pattern/animation
      targetPattern = 2;
      patternUpdateInterval = powerDownSpeed;
      totalPatternSteps = 300;
      //updatePattern(targetPattern);

      //update timestamp
      lastPowerDownCompletionCheck = millis(); //update last time checked for file completion

      //return to button checking (idle state)
      state = S_IDLE;
      break;
  }

}

//--[neopixel pattern code]--//
void  updatePattern(int newPattern) {
  switch (newPattern) {
    case 0:
      FadeUpdate(); //new addition from tutorial (function only?)
      //setColor(red);
      break;
    case 1:
      FadeUpdate();
      //setColor(blue);
      break;
    case 2:
      FadeUpdate();
      //setColor(green);
      break;
    case 3:
      setColor(red);
      break;
  }
}

void clearall() {
  for (int i = 0; i < NUMPIXELS; i++) {
    strip.setPixelColor(i, strip.Color(0, 0, 0));
  }
  strip.show();
  //Serial.println(F("--should be all cleared--"));
}

void setColor(uint32_t targetColor) {
  for (int i = 0; i < NUMPIXELS; i++) {
    if (i < 12) {
      strip.setPixelColor(i, targetColor);
    } else {
      strip.setPixelColor(i, 0, 0, 0);
    }
  }
  strip.show();
  lastPatternUpdate = millis();  //update pattern time stamp
}


// Increment the index and reset at the end
void Increment() {
  if (Direction == FORWARD) {
    currentPatternStep++;
    if (currentPatternStep >= totalPatternSteps) {
      currentPatternStep = 0;       
      doFadeIn = false;
      if (OnComplete != NULL) {
        OnComplete(); // call the comlpetion callback
      }
    }
  } else { // Direction == REVERSE
    --currentPatternStep;
    if (currentPatternStep <= 0) {
      currentPatternStep = totalPatternSteps - 1;
      if (OnComplete != NULL) {
        OnComplete(); // call the comlpetion callback
      }
    }
  }
}



// Update the Fade Pattern - - //the gold of what I need.
void FadeUpdate() {
  //Serial.println(F("Fade pattern update....."));
  uint8_t red = ((Red(Color1) * (totalPatternSteps - currentPatternStep)) + (Red(Color2) * currentPatternStep)) / totalPatternSteps;
  uint8_t green = ((Green(Color1) * (totalPatternSteps - currentPatternStep)) + (Green(Color2) * currentPatternStep)) / totalPatternSteps;
  uint8_t blue = ((Blue(Color1) * (totalPatternSteps - currentPatternStep)) + (Blue(Color2) * currentPatternStep)) / totalPatternSteps;
  ColorSet(strip.Color(red, green, blue));
  //strip.show();
  Increment();
  lastPatternUpdate = millis();  //update pattern time stamp
}

// Returns the Red component of a 32-bit color
uint8_t Red(uint32_t color) {
  return (color >> 16) & 0xFF;
}

// Returns the Green component of a 32-bit color
uint8_t Green(uint32_t color) {
  return (color >> 8) & 0xFF;
}

// Returns the Blue component of a 32-bit color
uint8_t Blue(uint32_t color) {
  return color & 0xFF;
}

// Set all pixels to a color (synchronously)
void ColorSet(uint32_t color) {
  //Serial.println(F("Setting color...."));
  for (int i = 0; i < strip.numPixels(); i++) {
    strip.setPixelColor(i, color);
  }
  strip.show();
}


// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if (WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else if (WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  } else {
    WheelPos -= 170;
    return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  }
}


// Initialize for a Fade -- // Needed?  can be set by poweron/powerdown states?
/*
void Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t patternUpdateInterval, direction dir = FORWARD) {
  targetPattern = 0;
  patternUpdateInterval = powerOnSpeed;
  totalPatternSteps = steps;
  Color1 = color1;
  Color2 = color2;
  currentPatternStep = 0;
  Direction = dir;
}
*/



I have commented out the call to FADEOUT state.. and also the check when the button is -still- in released mode that updates the fadeout pattern..

So this is no only focusing on the fadeIn behavior..

This works pretty good..

fades in from off (initially set color).. to red... at a decent speed.. however if I keep the button pressed after the fade in starts and finishes.... it starts to blink with some purple/blue hues in it.... when I let go and press the button again.. more blinking and either a red or light purple color when released.

Locked
Please be positive and constructive with your questions and comments.

Return to “Glowy things (LCD, LED, TFT, EL) purchased at Adafruit”