Prof_Klyzlr

Dear MRHers,

Am barrelling thru a layout speed-build right now, (details irrelevant to this post),
and need a pair of fire fx. Perfect opportunity to try a quick Arduino deployment.

Anyway, the Arduino is in and flickering away, and honestly, I'm disappointed...

The concept is cool, and the price is decent compared to commercial options,
but compared to the Audio-fire circuits I'm used to using, this looks more like lightening than fire....

The key problem is that the Arduino explicitly on/off flashes the LEDs, it doesn’t fade /dim them
(IE constantly vary the intensity),...

And equally, with a paired Red/amber set, it is rare for both to be On at the same time....

So, before I grab my trusty MP3 player and revert to "audio fire",
does anyone know a way to make an Arduino Fire flicker and glow/pulse like a smouldering fire does?

Happy Modelling,
Aim to Improve,
Prof Klyzlr

Reply 0
fernpoint

Arduino LED fading

Hi Prof

I'm no expert on this stuff, so I'm sure that someone else will chime in with a more complete answer, but ......

You can fade LEDs in and out using pulse wave modulation though an analogwrite() which.is on a scale of 0 - 255, such that analogWrite(255) requests a 100% duty cycle (always on), and analogWrite(127) is a 50% duty cycle.

I have used it to do a slow fade of a red LED on a welding simulator sketch :

for (int i = 50; i> 0; i--)                             { //decrease i with 1
          analogWrite(ledPin_red_glow, i);
          delay(40);

Obviously you can speed up and alter this effect by changing the range and increment/decrement of "i" and also the delay factor.

Bit busy right now, but if I get a some time I'll have a go at a sketch for a fade/flicker (rather than just flickering) fire simulator because I do need one in the near future. However I am pretty sure someone will beat me to it .

Rob Clark

Reply 0
fernpoint

Try this

Hi Prof

Not knowing the "light quality" of what you are comparing the Arduino to' try this 3 led sketch (I used 1 * red and 2 * yellow).


int LED_Pin7 = 7;
int LED_Pin8 = 8;
int LED_Pin9 = 9;

int Intensity_7;   // Intensity of the LED: [0 = Off], [255 = Brightly Lit]
int Intensity_8;
int Intensity_9;

void setup()
{
 }
void loop()
{
  Intensity_7 = random(1, 255);    
  Intensity_8 = random(1, 240);
  Intensity_9 = random(1, 255);

  analogWrite(LED_Pin7, Intensity_7);
  delay(random(1, 36));          
  analogWrite(LED_Pin8, Intensity_8);
  delay(random(1, 36));          
  analogWrite(LED_Pin9, Intensity_9);
  delay(random(1, 25));         
}

Values will need some tweaking I'm sure.

Is this vaguely close to what you want?

Rob

Reply 0
Pelsea

Drunkard's walk

Prof--

Rob's code is a good framework for this, but you might get something closer to what you want with a drunkard's walk algorithm. 

int LED_Pin7 = 7;
int LED_Pin8 = 8;
int LED_Pin9 = 9;

long Intensity_7 = 100;   // Intensity of the LED: [0 = Off], [255 = Brightly Lit]
long Intensity_8 = 100;
long Intensity_9 = 100;
void setup() {
  // put your setup code here, to run once:
}

void loop() {
  Intensity_7 = drunk(Intensity_7, 32, 7);    
  Intensity_8 = drunk(Intensity_8, 64, 4);
  Intensity_9 = drunk(Intensity_9, 0, 4);

  analogWrite(LED_Pin7, Intensity_7);
  analogWrite(LED_Pin8, Intensity_8);
  analogWrite(LED_Pin9, Intensity_9); 

}

long drunk(long seed,long bottom, long maxstep){
  long change = random(1, maxstep + 1) ;
  if (random (0,2)== 0){
    change *= -1;
  }
  long result = seed + change;
  // keep in range
  if(result> 255

    return seed - change;
  }
  return result;
}

Instead of the random calls, I substituted a function that adds or subtracts a random step from the existing value. This version of the drunk function takes three arguments- starting value, the lowest value to ever return, and the largest step to take. The function:

  • uses random to get an amount to step
  • uses random(0,2) to decide which direction to change
  • checks the result-- if it is out of range (bottom to 255) reverses the step

Originally bottom and maxstep were globals, but I found that there's quite a bit of differenct in the way LEDs (and even Arduino outputs) react to this code, so I designed the function to take these as arguments. That way you can tweak each color. Note that the smaller the maxstep, the slower the changes.

pqe

Reply 0
Prof_Klyzlr

Dear Rob, PQ, Thanks for the

Dear Rob, PQ,
 
Thanks for the thoughts, greatly appreciated! The Speed-Build has to get done, so the existing Arduino deployment will have to stay for now,
(I tried adding capacitors to slow the transition times of the output lines, but no joy...) but I'll definitely breadboard both of these up and Eval asap...
 
I would ask, give the Ard pins can both Sink and Source, what would you expect the results to be for a back-to-back pair of LEDS to be if connected between (say) pins 7 and 8? (IE such that the "output" is bi-polar?) I get that the difference slew would be slower, and the potential difference (compared to a normal Pin<>GND connection) would be less, But both conditions could be adjusted-for within the code...???
 
Happy Modelling,
Aim to Improve,
Prof Klyzlr
Reply 0
Pelsea

Sink source...

You could connect the leads of a two wire bicolor LED to Arduino pins, and flip/fade the colors by raising one pin while lowering the other. (Don't forget a resistor.) For anything heavier, you need a driver, like an L293. 

pqe

Reply 0
J. Kluth

Why are you using long instead of int?

Does the algorithm require the precision of a 32 bit variable? It seems like a 16 bit would be sufficient, as the max value is going to be 255, or even a byte as it is an unsigned number between 0 and 255, or am I mistaken?

Always looking to learn,

Jay K.

Reply 0
Pelsea

Long vs int

I used longs just because the random() function returns a long. Ints will work fine, and save a few bytes of memory. (Don't try that with time functions though.) Signs are required, so you can't convert to bytes. I've recently been working in another language that is really fussy about type matching so my habits have changed.

pqe

Reply 0
fernpoint

Flicker

I just tried pqe's version of the flicker sketch - much better than mine

Rob

Reply 0
J. Kluth

It works better if you use different pins

Unless you are using a Mega or a Due, it works better if you use pins 5, 6, and 9 for the pwm outputs.  The analogWrite command only functions on pins 3,5,6,9,10,&11 on the Uno, Micro, or  Nano.  This is a function of the AVR chip features.  If you use it as written, the LED's on pins 7 and 8 flicker on and off, without dimming.  If you change the pin assignments, all 3 LED's vary continuously.

Always looking to learn,

Jay K.

Reply 0
Pelsea

Haste makes waste

A bit of a hurry + misreading the pin labels led to a big goof. Here is corrected code:

int LED_Pin5 = 5;
int LED_Pin6 = 6;
int LED_Pin9 = 9;

long Intensity_5 = 100;   // Intensity of the LED: [0 = Off], [255 = Brightly Lit]
long Intensity_6 = 100;
long Intensity_9 = 100;
void setup() {
  // put your setup code here, to run once:
}

void loop() {
  Intensity_5 = drunk(Intensity_5, 32, 25);    
  Intensity_6 = drunk(Intensity_6, 32, 12);
  Intensity_9 = drunk(Intensity_9, 32, 25);

  analogWrite(LED_Pin5, Intensity_5);
  analogWrite(LED_Pin6, Intensity_6);
  analogWrite(LED_Pin9, Intensity_9); 

}

long drunk(long seed,long bottom, long maxstep){
  long change = random(1, maxstep+1) ;
  if (random (0,2)== 0){
    change *= -1;
  }
  long result = seed + change;
  // keep in range
  if(result> 255

    return seed - change;
  }
  return result;
}

pqe

Reply 0
Reply