-
Notifications
You must be signed in to change notification settings - Fork 2
/
fire.h
executable file
·105 lines (88 loc) · 2.92 KB
/
fire.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*
LICENSE: GPLv2
Source: https://github.com/darrenpmeyer/Arduino-FireBoard/
Author https://github.com/darrenpmeyer/
*/
#include <FastLED.h>
CRGBPalette16 gPal;
void setupFire() {
/* Set a black-body radiation palette
This comes from FastLED */
gPal = HeatColors_p;
}
/* Refresh rate. Higher makes for flickerier
Recommend small values for small displays */
#define FPS 17
#define FPS_DELAY 1000/FPS
/* Rate of cooling. Play with to change fire from
roaring (smaller values) to weak (larger values) */
int cooling = 40;
/* How hot is "hot"? Increase for brighter fire */
int hotness = 100;
void Fireplace () {
static unsigned int spark[MATRIX_WIDTH]; // base heat
CRGB stack[MATRIX_WIDTH][MATRIX_HEIGHT]; // stacks that are cooler
// 1. Generate sparks to re-heat
for (int i = 0; i < MATRIX_WIDTH; i++) {
if (spark[i] < hotness) {
int base = hotness * 2;
spark[i] = random16(base, hotness * MATRIX_HEIGHT);
}
}
// 2. Cool all the sparks
for (int i = 0; i < MATRIX_WIDTH; i++) {
spark[i] = qsub8(spark[i], random8(0, cooling));
}
// 3. Build the stack
/* This works on the idea that pixels are "cooler"
as they get further from the spark at the bottom */
for (int i = 0; i < MATRIX_WIDTH; i++) {
unsigned int heat = constrain(spark[i], hotness / 2, hotness * MATRIX_HEIGHT);
for (int j = MATRIX_HEIGHT - 1; j >= 0; j--) {
/* Calculate the color on the palette from how hot this
pixel is */
byte index = constrain(heat, 0, hotness);
stack[i][j] = ColorFromPalette(gPal, index);
/* The next higher pixel will be "cooler", so calculate
the drop */
unsigned int drop = random8(0, hotness);
if (drop > heat) heat = 0; // avoid wrap-arounds from going "negative"
else heat -= drop;
heat = constrain(heat, 0, hotness * MATRIX_HEIGHT);
}
}
// 4. map stacks to led array
for (int i = 0; i < MATRIX_WIDTH; i++) {
for (int j = 0; j < MATRIX_HEIGHT; j++) {
leds(i, MATRIX_HEIGHT - 1 - j) = stack[i][j];
}
}
}
#define MAX_HOTNESS 180
#define MIN_HOTNESS 40
#define ADJUSTMENT_FACTOR 20
#define MIN_UPDATE_DELAY 150
void checkButtonsFire() {
static unsigned long lastUpdate = millis();
if (!(millis() - lastUpdate > MIN_UPDATE_DELAY)) return; // Just return if it is not yet time to update
if (button_state[LEFT_PIN]) {
hotness = constrain(hotness - ADJUSTMENT_FACTOR, MIN_HOTNESS, MAX_HOTNESS);
}
if (button_state[UP_PIN]) {
cooling = constrain(cooling - ADJUSTMENT_FACTOR, 0, 255);
}
if (button_state[DOWN_PIN]) {
cooling = constrain(cooling + ADJUSTMENT_FACTOR, 0, 255);
}
if (button_state[RIGHT_PIN]) {
hotness = constrain(hotness + ADJUSTMENT_FACTOR, MIN_HOTNESS, MAX_HOTNESS);
}
lastUpdate = millis();
}
void loopFire() {
random16_add_entropy(rand()); // We chew a lot of entropy
checkButtonsFire();
Fireplace();
FastLED.show();
wait(FPS_DELAY);
}