Scroll Down
BONFIRE
STORIES
The installation symbolically reconstructs the bonfire environment found in nature, where information and stories were traditionally shared orally, allowing for knowledge of the past and imagination of the future. The conveyed information is presented interactively, akin to precious testimonies, providing a personal and educational experience without being overly rhetorical. It aims to create an immersive and collective-based encounter that emotionally engages visitors for a flexible duration of time.
TECNICAL
SPECIFICATIONS
Hardware
Trotec Laser Cutter
Prusa MK2 3D Printer
9 x 32 x 32 pixel LED Matrices
9 x Ribbon Cables
2 x Teensy Microprocessors
1 x Teensy Smart Matrix Shield
1 x Teensy Audio Shield
3 x Grove Ultrasonic Distance Sensor
3 x 100 Farrad capacitors
3 x 104 0.1 Farrad ceramic capacitors
3 x 330 resistors
Software
Arduino IDE
Fusion 360
Prusa Slicer
Trotec Ruby
Physical Material
8 mm plywood
Screws
L-braces
Wood for legs
Speaker and AUX cable
#include <MatrixHardware_Teensy4_ShieldV5.h>
#include <SmartMatrix.h>
//SMART MATRIX LIBRARY DEFS
#define COLOR_DEPTH 24
const uint16_t WIDTH = 32 * 9;
const uint16_t HEIGHT = 32 * 1;
const uint8_t kRefreshDepth = 24;
const uint8_t kDmaBufferRows = 4;
const uint8_t kPanelType = SM_PANELTYPE_HUB75_16ROW_MOD8SCAN;
const uint32_t kMatrixOptions = (SM_HUB75_OPTIONS_NONE);
const uint8_t kBackgroundLayerOptions = (SM_HUB75_OPTIONS_MATRIXCALC_LOWPRIORITY);
SMARTMATRIX_ALLOCATE_BUFFERS(matrix, WIDTH, HEIGHT, kRefreshDepth, kDmaBufferRows, kPanelType, kMatrixOptions);
SMARTMATRIX_ALLOCATE_BACKGROUND_LAYER(bg, WIDTH, HEIGHT, COLOR_DEPTH, kBackgroundLayerOptions);
// values
int val_sensor1 = 0;
int val_sensor2 = 0;
int val_sensor3 = 0;
byte pin_analog_1 = A17;
byte pin_analog_2 = A16;
byte pin_analog_3 = A15;
//Added May 14
byte pin_audio_in = A10;
int audio_playing_t1 = 0;
//JTE Variables
int threshold = (4, 4);
void setup() {
Serial.begin(115200);
// pixels.begin();
//TO LINK TEENSYS (this is #2)
pinMode(pin_analog_1, INPUT);
pinMode(pin_analog_2, INPUT);
pinMode(pin_analog_3, INPUT);
//Added May 14
pinMode(pin_audio_in, INPUT);
//LED Matrix
matrix.addLayer(&bg);
matrix.begin();
matrix.setBrightness(100);
bg.enableColorCorrection(true);
}
//FOR NEW FIRE PIXELS fade in and out
uint frame = 0;
float x = 0;
float y = 10;
float vx = 0.2;
float vy = 0.5;
void loop() {
val_sensor1 = analogRead(pin_analog_1);
val_sensor2 = analogRead(pin_analog_2);
val_sensor3 = analogRead(pin_analog_3);
// /*
Serial.print("Sensor 1: ");
Serial.print(val_sensor1);
// Serial.print(" cm\t");
Serial.print("\t\t Sensor 2: ");
Serial.print(val_sensor2);
// Serial.print(" cm\t");
Serial.print("\t\t Sensor 3: ");
Serial.println(val_sensor3);
// Serial.println(" cm");
// */
// delay(100);
/*
* STARTING POINTS OF THE LINES
*/
int _x1 = 0;
int _y1 = 0;
int _x2 = 0;
int _y2 = 0;
int _x3 = 0;
int _y3 = 0;
/*
* ENDING POINTS OF THE LINES 1 matrix
*/
//Commented Out for the additive color maps to shine
// int x1 = map(val_sensor1, 1024, 0, _x1, 16);
// int y1 = map(val_sensor1, 1024, 0, _y1, 16);
// int x2 = map(val_sensor2, 1024, 0, _x2, 16);
// int y2 = map(val_sensor2, 1024, 0, _y2, 16);
// int x3 = map(val_sensor3, 1024, 0, _x3, 16);
// int y3 = map(val_sensor3, 1024, 0, _y3, 16);
int brightness1 = map(val_sensor1, 1023, 0, 0, 100);
int brightness2 = map(val_sensor2, 1023, 0, 0, 100);
int brightness3 = map(val_sensor3, 1023, 0, 0, 100);
// Serial.print("x1: ");
// Serial.print(x1);
// Serial.print("\t, y1: ");
// Serial.println(y1);
// Serial.print("x2: ");
// Serial.print(x2);
// Serial.print("\t, y2: ");
// Serial.println(y2);
// Serial.print("x3: ");
// Serial.print(x3);
// Serial.print("\t, y3: ");
// Serial.println(y3);
// !!! use drawPixel() and not bg.drawPixel() !!!
// OG DOTS
// drawPixel(x1, y1, {7, 60, 0});
// drawPixel(x2, y2, {121, 79, 98});
// drawPixel(x3, y3, {22, 70, 117});
delay(50);
//Firey Background
x = x + vx;
y = y + vy;
if (x >= WIDTH - 1 || x <= 0) {
vx = -vx;
}
if (y >= HEIGHT - 1 || y <= 0) {
vy = -vy;
}
int r = int((sin(frame * 0.011) + 1.0) * 20) + 30;
int g = 0;
int b = 0;
bg.fillScreen({ r, g, b });
for (int i = 0; i < 400; i++) {
bg.drawPixel(random(WIDTH), random(HEIGHT), { random(200, 255), random(100, 150), 0 });
// bg.fillScreen({ 0, 0, 0 }); // Clear to a color {r,g,b}
}
//BACKGROUND PURPLE //PINK //GREEN
if (val_sensor1 <= 150 || val_sensor2 <= 150 || val_sensor3 <= 150) {
int r = 0;
int g = 0;
int b = int((sin(frame * 0.011) + 1.0) * 20) + 30;
bg.fillScreen({brightness1, brightness2, brightness3});
for (int i = 0; i < 400; i++) {
bg.drawPixel(random(WIDTH), random(HEIGHT), {random(200, 255), 0, random(200, 255) }); //GREEN
}
}
bg.swapBuffers(); // The library offers double buffering
frame++;
}
//______________________________________
void drawPixel(int x, int y, const rgb24& color) {
static uint8_t y_map[] = {
0, 1, 2, 3, 4, 5, 6, 7, // first 8 rows are ok
16, 17, 18, 19, 20, 21, 22, 23, // swap these rows
8, 9, 10, 11, 12, 13, 14, 15, // ... with these
24, 25, 26, 27, 28, 29, 30, 31 // last 8 rows are ok
};
bg.drawPixel(x, y_map[y], color);
}
//AUDIO
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
// GUItool: begin automatically generated code
AudioPlaySdWav playSdWav; //xy=269,139
AudioOutputI2S i2s1; //xy=579,194
AudioConnection patchCord1(playSdWav, 0, i2s1, 0);
AudioConnection patchCord2(playSdWav, 1, i2s1, 1);
AudioControlSGTL5000 sgtl5000_1; //xy=385,277
// GUItool: end automatically generated code
// Use these with the Teensy Audio Shield
#define SDCARD_CS_PIN 10
#define SDCARD_MOSI_PIN 7 // Teensy 4 ignores this, uses pin 11
#define SDCARD_SCK_PIN 14 // Teensy 4 ignores this, uses pin 13
//DISTANCE SENSOR
#include "Ultrasonic.h"
byte pin_sig_1 = 39;
byte pin_sig_2 = 38;
byte pin_sig_3 = 29;
// Values variables
long dist_1 = 0; // distance measured by the first sensor
long dist_2 = 0; // distance measured by the second sensor
long dist_3 = 0; // distance measured by the third sensor
Ultrasonic sensor1(pin_sig_1);
Ultrasonic sensor2(pin_sig_2);
Ultrasonic sensor3(pin_sig_3);
int distance_PWM_1 = 0;
int distance_PWM_2 = 0;
int distance_PWM_3 = 0;
byte pin_pwm_1 = 33;
byte pin_pwm_2 = 24;
byte pin_pwm_3 = 25;
//Audio add pins—May 14
byte pin_audio_out = 28;
int audio_output = LOW;
//threshold maximum
int threshold_distance_max = 150; // cm
//threshold minimum—-where the audio should start
int threshold_distance_min = 40; //cm
//AUDIO TRACKS
const char *audio_tracks[] = { "BO_01.WAV", "BO_02.WAV", "BO_03.WAV", "BO_04.WAV", "BO_05.WAV", "BO_06.WAV", "BO_07.WAV", "BO_08.WAV" }; // Make sure names are correct
const int num_tracks = sizeof(audio_tracks) / sizeof(audio_tracks[0]);
//CURRENT TRACK
int current_track = 0; // start at the first track
//PLAYED TRACKS
bool played_tracks[num_tracks] = { false };
//TRIGGER
bool audio_triggered = false;
//FLAG for playing
bool audio_playing = false;
//TIMER
unsigned long time_since_last_trigger = 0;
void setup() {
Serial.begin(115200);
//TO LINK TEENSYS (this is #1)
pinMode(pin_pwm_1, OUTPUT);
pinMode(pin_pwm_2, OUTPUT);
pinMode(pin_pwm_3, OUTPUT);
//Added May 14
pinMode(pin_audio_out, OUTPUT);
AudioMemory(10);
sgtl5000_1.enable();
sgtl5000_1.volume(.9);
SPI.setMOSI(SDCARD_MOSI_PIN);
SPI.setSCK(SDCARD_SCK_PIN);
if (!SD.begin(SDCARD_CS_PIN)) {
while (1) {
Serial.println("Unable to access the SD card");
delay(500);
}
}
}
void loop() {
static unsigned long last_time_below_threshold_1 = 0;
unsigned long current_time = millis();
dist_1 = sensor1.MeasureInCentimeters();
dist_2 = sensor2.MeasureInCentimeters();
dist_3 = sensor3.MeasureInCentimeters();
if (dist_1 > threshold_distance_max) dist_1 = threshold_distance_max;
if (dist_2 > threshold_distance_max) dist_2 = threshold_distance_max;
if (dist_3 > threshold_distance_max) dist_3 = threshold_distance_max;
distance_PWM_1 = map(dist_1, 0, threshold_distance_max, 0, 255);
distance_PWM_2 = map(dist_2, 0, threshold_distance_max, 0, 255);
distance_PWM_3 = map(dist_3, 0, threshold_distance_max, 0, 255);
analogWrite(pin_pwm_1, distance_PWM_1);
analogWrite(pin_pwm_2, distance_PWM_2);
analogWrite(pin_pwm_3, distance_PWM_3);
// Print the distance measured by each sensor to the serial monitor
Serial.print("Sensor 1: ");
Serial.print(dist_1);
Serial.print(" cm\t\t");
Serial.print("Sensor 2: ");
Serial.print(dist_2);
Serial.print(" cm\t\t");
Serial.print("Sensor 3: ");
Serial.print(dist_3);
Serial.println(" cm");
Serial.println(current_track);
Serial.println(audio_playing);
Serial.println(audio_output);
if (audio_playing) {
audio_output = true;
digitalWrite(pin_audio_out, HIGH);
} else {
audio_output = false;
digitalWrite(pin_audio_out, LOW);
}
// Check if any of the sensors triggered
if (dist_1 < threshold_distance_min || dist_2 < threshold_distance_min || dist_3 < threshold_distance_min) {
// If audio is not already playing
if (!audio_playing) {
// if (audio_playing == false) {
// Play the current track
digitalWrite(pin_audio_out, HIGH);
playSdWav.play(audio_tracks[current_track]);
audio_triggered = true;
audio_playing = true;
played_tracks[current_track] = true;
// Move to the next track
current_track++;
if (current_track >= num_tracks) {
// If we have played all tracks, start again from the beginning
current_track = 0;
}
}
// Reset the timer if any of the sensors are triggered
last_time_below_threshold_1 = current_time;
} else {
// If no sensors have triggered for 3 seconds and audio is playing
if (audio_playing && current_time - last_time_below_threshold_1 > 3000) {
// Stop the audio and reset the flags
playSdWav.stop();
audio_triggered = false;
audio_playing = false;
digitalWrite(pin_audio_out, LOW);
}
}
// NEW ADD May 11
if (playSdWav.isPlaying() == false && audio_triggered == true) {
// Reset the audio triggered flag and set the audio_playing flag to false
audio_triggered = false;
audio_playing = false;
}
// Check if all tracks have been played
bool all_played = true;
for (int i = 0; i < num_tracks; i++) {
if (played_tracks[i] == false) {
all_played = false;
break;
}
}
// If all tracks have been played, reset the played_tracks array
if (all_played == true) {
//added one line below
// current_track = 0;
for (int i = 0; i < num_tracks; i++) {
played_tracks[i] = false;
}
}
}