Adafruit Trinket Random Number

Potentially an easy issue.

I am working on a small program using an Adafruit trinket which as 5kb of flash storage. WIth the fastLED library, i am very limited in my storage space and i was trying to use the random() function or the rand() function to generator a random brightness to simulate a candle flicker.. however, I am finding that those functions add too much to my sketch size..

Is ther an easy way to simulate a random "Flicker" without using these functions? I've got 6 whole bytes to spare currently.

#include <FastLED.h>

CRGB leds[12];
int MotionRead;
int Motion;
byte ledProgram;
byte oldValue;
unsigned long timer;
unsigned long timer1;
byte y;

void pulsingWhite();
void rainbow();
void solidWhite();
void off();


void setup() {
  //Serial.begin(115200);
  FastLED.addLeds<WS2812B, 1>(leds, 12);
  MotionRead = analogRead(1);
  Motion = map(MotionRead, 0, 1023, 0, 255);
  oldValue = Motion;
}


void loop() {
  
  MotionRead = analogRead(1);
  Motion = map(MotionRead, 0, 1023, 0, 255);
   
  solidWhite();
  if (Motion - oldValue > 15 || oldValue - Motion > 15) {
    oldValue = Motion;
    if (millis() > timer1 + 1000) {
     ledProgram++;
    timer1 = millis();
      if (ledProgram > 4)ledProgram = 0;
    }
  }


  switch (ledProgram) {
    case 0:
      {
        solidWhite();
        break;
      }
    case 1:
      {
        pulsingWhite();
        break;
      }
      case 2:
      {
        candle();
        break; 
     } 
    case 3:
      {
        rainbow();
        break;
      }
    case 4:
      {
        off();
        break;
      }
  }
  FastLED.show();
}


void solidWhite() {
  for (int x = 0; x < 12; x++) {
    leds[x] = CHSV(0, 0 , 255);
   }
}

void pulsingWhite() {
   if (millis() > timer + 100) {
    y++;
    if (y == 255)y = 0;
    timer = millis();
  }
  for (int x = 0; x < 12; x++) {
    leds[x] = CHSV(0, 0, y);
  }
}


void candle() {
   if (millis() > timer + 10) {
   for (int x = 0; x < 12; x++) {
    leds[x] = CHSV(0, 0, 255);
   }
  timer = millis();
  }
}

void rainbow() {
  if (millis() > timer + 100) {
    y++;
    if (y == 255)y = 0;
    timer = millis();
  }
  for (int x = 0; x < 12; x++) {
    leds[x] = CHSV(y, 255, 255);
  }
}


void off() {
  for (int x = 0; x < 12; x++) {
    leds[x] = CHSV(0, 0, 0);
  }
}

The random function adds ~ 300bytes and the rand function adds about 150bytes

With some minor tweaking of your code I was able to trim it down form 4204 to 4,084 bytes but I am compiling it with an UNO so try it out maybe I freed up enough room for your random functions.

Good Luck

#include <FastLED.h>

CRGB leds[12];
int MotionRead;
int Motion;
byte ledProgram;
byte oldValue;
unsigned long timer;
unsigned long timer1;
byte y;

void AllLEDs(byte H, byte S, byte V);
void pulsingWhite();
void rainbow();
void solidWhite();
void off();


void setup() {
  //Serial.begin(115200);
  FastLED.addLeds<WS2812B, 1>(leds, 12);
  MotionRead = analogRead(1);
  Motion = map(MotionRead, 0, 1023, 0, 255);
  oldValue = Motion;
}


void loop() {

  MotionRead = analogRead(1);
  Motion = map(MotionRead, 0, 1023, 0, 255);

  solidWhite();
  if (Motion - oldValue > 15 || oldValue - Motion > 15) {
    oldValue = Motion;
    //   if (millis() > timer1 + 1000) {
    if ((millis() - timer1) >= 1000) { // not that it matters with your sketch but this will not suffer rollover issues after leaving it on for a long time

      ledProgram++;
      timer1 = millis();
      if (ledProgram > 4)ledProgram = 0;
    }
  }


  switch (ledProgram) {
    case 0:
      {
        solidWhite();
        break;
      }
    case 1:
      {
        pulsingWhite();
        break;
      }
    case 2:
      {
        candle();
        break;
      }
    case 3:
      {
        rainbow();
        break;
      }
    case 4:
      {
        off();
        break;
      }
  }
  FastLED.show();
}
void AllLEDs(byte H, byte S, byte V) {
  for (int x = 0; x < 12; x++) {
    leds[x] = CHSV(H, S , V);
  }
}

void solidWhite() {
  AllLEDs(0, 0, 255);
}

void pulsingWhite() {
  // if (millis() > timer + 100) {
  if ((millis() - timer) >= 100) { // not that it matters with your sketch but this will not suffer rollover issues after leaving it on for a long time
    y++;
    //if (y == 255)y = 0;//y is of type byte and will roll over to zero automatically
    timer = millis();
  }
  AllLEDs(0, 0, y);
}


void candle() {
  // if (millis() > timer + 10) {
  if ((millis() - timer) >= 10) { // not that it matters with your sketch but this will not suffer rollover issues after leaving it on for a long time
    AllLEDs(0, 0, 255);
    timer = millis();
  }
}

void rainbow() {
  //if (millis() > timer + 100) {
  if ((millis() - timer) >= 100) { // not that it matters with your sketch but this will not suffer rollover issues after leaving it on for a long time
    y++;
    // if (y == 255)y = 0; //y is of type byte and will roll over to zero automatically
    timer = millis();
  }
  AllLEDs(y, 255, 255);
}


void off() {
  AllLEDs(0, 0, 0);
}

For random behavior in a for loop, you can change something like
x++
to something like
x += random(somenumber)

A thank you for the detailed reply, homslice. I was able to figure out the fact I didn't need to protect the bytes from rollover. Your other notes are worth while though, thanks! It gives me enough room for the rand() function but not the random() function, so I am pretty happy with that!

in case your wondering why I used a trinket instead of something with more firepower.. it's because it came free with an order from Adafruit.

I 3Dprinted the vase, got some ws2812b LEDs, and an adafruit trinket and this is what I came up with. You can see the flicker effect about 10-15 seconds in..

In an empty sketch, compiler says 26 bytes is saved from replacing

int x= map (analogRead(A0), 0,1023, 0,255);

with

int x= analogRead(A0)/4;

Not familiar with what kind of chip you're working with, but do you have different kinds of memory?

I know I had to massage my code to fit FastLed onto an ATTiny85 by moving some global variables/declarations (like CRGB leds[12]; ) into setup/loop.

it is an AtTiny85 breakout board basically... it's got flash and sram whatever the stock chip is and that's it. I'm not sure what fastled version your using, but it also depends on what your using from the fastled library, because the library only includes the parts you need.

Google up "linear congruential random number generator". These produce very good random numbers using a simple equation. You'll have to tailor the output of any specific generator to the range that you want, but that's just simple division.

You can try adapting this code. It produces a 7bit pseudo-random number...

/*
 * getbright()
 *
 * Get a new set of pseudo-random brightnesses for each output
 *
 * generating the random numbers isn't time-critical, but use a macro
 * so that we can easilly change the algorithm for all outputs without
 * changing too much code.  We could use pointers to each brightness
 * or arrays, but that seems a bit gratuitously HLL-like.
 *
 * 127 state pseudo-random numer
 * Shift register with feedback at bits 0,6
 */

#define nextrandom(last)  \
    newbit = last & 0b01000000;  /* bit 6 */  \
    if (last & 1)	         /* bit 0 */ \
      newbit ^=  0b01000000; \
    last = (last>>1) + newbit;

byte brightness;

void getbright( void)
{
   char newbit;
   nextrandom(brightness);
}

I'm glad I could help you squeeze the random feature in and I Enjoyed watching your video Thanks for the update :slight_smile:

I reviewed the code once again for fun and spotted another place you could adjust I've shrunk it down to 4014 bytes that's another 70 bytes off the code

#include <FastLED.h>

CRGB leds[12];
byte ledProgram;
int oldValue;
unsigned long timer;
unsigned long timer1;
byte y;

void AllLEDs(byte H, byte S, byte V);
void pulsingWhite();
void rainbow();
void solidWhite();
void off();


void setup() {
  //Serial.begin(115200);
  FastLED.addLeds<WS2812B, 1>(leds, 12);
  oldValue = analogRead(1);
}

void loop() {
  solidWhite();
  if (abs(analogRead(1) - oldValue) > 60) {
    oldValue = analogRead(1);
    //   if (millis() > timer1 + 1000) {
    if ((millis() - timer1) >= 1000) { // not that it matters with your sketch but this will not suffer rollover issues after leaving it on for a long time

      ledProgram++;
      timer1 = millis();
      if (ledProgram > 4)ledProgram = 0;
    }
  }


  switch (ledProgram) {
    case 0:
      {
        solidWhite();
        break;
      }
    case 1:
      {
        pulsingWhite();
        break;
      }
    case 2:
      {
        candle();
        break;
      }
    case 3:
      {
        rainbow();
        break;
      }
    case 4:
      {
        off();
        break;
      }
  }
  FastLED.show();
}
void AllLEDs(byte H, byte S, byte V) {
  for (int x = 0; x < 12; x++) {
    leds[x] = CHSV(H, S , V);
  }
}

void solidWhite() {
  AllLEDs(0, 0, 255);
}

void pulsingWhite() {
  // if (millis() > timer + 100) {
  if ((millis() - timer) >= 100) { // not that it matters with your sketch but this will not suffer rollover issues after leaving it on for a long time
    y++;
    //if (y == 255)y = 0;//y is of type byte and will roll over to zero automatically
    timer = millis();
  }
  AllLEDs(0, 0, y);
}


void candle() {
  // if (millis() > timer + 10) {
  if ((millis() - timer) >= 10) { // not that it matters with your sketch but this will not suffer rollover issues after leaving it on for a long time
    AllLEDs(0, 0, 255);
    timer = millis();
  }
}

void rainbow() {
  //if (millis() > timer + 100) {
  if ((millis() - timer) >= 100) { // not that it matters with your sketch but this will not suffer rollover issues after leaving it on for a long time
    y++;
    // if (y == 255)y = 0; //y is of type byte and will roll over to zero automatically
    timer = millis();
  }
  AllLEDs(y, 255, 255);
}


void off() {
  AllLEDs(0, 0, 0);
}