What messages did Will Byers send via Christmas lights?

fade

Staff member
I'm having difficulty finding a list of the actual messages he sent through the Christmas lights. Does anybody know what they were? I rigged up a quick interactive set of 26 LEDs to put in a Stranger Things Jack o' lantern but I don't know what his actual messages were.
 

GasBandit

Staff member
I'm having difficulty finding a list of the actual messages he sent through the Christmas lights. Does anybody know what they were? I rigged up a quick interactive set of 26 LEDs to put in a Stranger Things Jack o' lantern but I don't know what his actual messages were.
I know the first one was "Right here" in response to "where are you?"
Then, in response to "what should I do," a very ominous "R-U-N" right before the demigorgon attacks.

At some point somebody asks if he is safe, I think, and the answer is "N-O"

If I was setting it up, I'd set "R-U-N" on repeat with 5 seconds or so between repetitions.
 

fade

Staff member
Yeah I saw that one. NeoPixels is cheating though. I'm kidding of course, but I'm just using some shift registers and multiplexing.
 

fade

Staff member
This is the basic code setup so far. Really simple. The messages will be on a loop, and yes/no/maybe will be on a button randomized like a magic 8 ball, programmed on an ISR:

Code:
// Multiplexing 3 rows X 9 cols of LEDS:
// 1 2 3 4 5 6 7 8 9 |
// ------------------|
// A B C D E F G H | A
// I J K L M N O P Q | B
// R S T U V W X Y Z | C
// rowcol
// ABC12345 6789xxxx
byte A[2] = {0b10001111, 0b11110000};
byte B[2] = {0b10010111, 0b11110000};
byte C[2] = {0b10011011, 0b11110000};
byte D[2] = {0b10011101, 0b11110000};
byte E[2] = {0b10011110, 0b11110000};
byte F[2] = {0b10011111, 0b01110000};
byte G[2] = {0b10011111, 0b10110000};
byte H[2] = {0b10011111, 0b11010000};
byte I[2] = {0b01001111, 0b11110000};
byte J[2] = {0b01010111, 0b11110000};
byte K[2] = {0b01011011, 0b11110000};
byte L[2] = {0b01011101, 0b11110000};
byte M[2] = {0b01011110, 0b11110000};
byte N[2] = {0b01011111, 0b01110000};
byte O[2] = {0b01011111, 0b10110000};
byte P[2] = {0b01011111, 0b11010000};
byte Q[2] = {0b01011111, 0b11100000};
byte R[2] = {0b00101111, 0b11110000};
byte S[2] = {0b00110111, 0b11110000};
byte T[2] = {0b00111011, 0b11110000};
byte U[2] = {0b00111101, 0b11110000};
byte V[2] = {0b00111110, 0b11110000};
byte W[2] = {0b00111111, 0b01110000};
byte X[2] = {0b00111111, 0b10110000};
byte Y[2] = {0b00111111, 0b11010000};
byte Z[2] = {0b00111111, 0b11100000};
byte* alphabet[26] = {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V};
byte* runMsg[3] = {R, U, N};
byte* noMsg[3] = {N, O};
byte* yesMsg[3] = {Y, E, S};
byte* maybeMsg[5] = {M, A, Y, B, E};
byte* helpMsg[4] = {H,E,L,P};
byte* rightHereMsg[9] = {R, I, G, H, T, H, E, R, E};
byte* willByersMsg[9] = {W, I, L, L, B, Y, E, R, S};
byte* demogorgonMsg[19] = {D, E, M, O, G, O, R, G, O, N};
Yeah, yeah, I could've used hex numbers, or made this more efficient, etc. (Pasting borked my nice formatting, too.)
 

fade

Staff member
Here's my completed code, if anyone is interested in replicating. I'm going make an Instructable and enter it into the Halloween prop contest.

Code:
// Stranger things with magic 8 ball style question answering
//
// 2016, Jack Stalnaker
// Shift Register definitions
// -------------------------------------
// Pin connected to ST_CP of 74HC595
int latchPin = 8;
// Pin connected to SH_CP of 74HC595
int clockPin = 12;
// Pin connected to DS of 74HC595
int dataPin = 11;
// Pin connected to button
int buttonPin = 2;
// Multiplexing 3 rows X 9 cols of LEDS:
// 1 2 3 4 5 6 7 8 9 |
// ------------------|
// A B C D E F G H | A
// I J K L M N O P Q | B
// R S T U V W X Y Z | C
// rowcol
// ABC12345 6789xxxx
const byte A[2] = {0b10001111, 0b11110000};
const byte B[2] = {0b10010111, 0b11110000};
const byte C[2] = {0b10011011, 0b11110000};
const byte D[2] = {0b10011101, 0b11110000};
const byte E[2] = {0b10011110, 0b11110000};
const byte F[2] = {0b10011111, 0b01110000};
const byte G[2] = {0b10011111, 0b10110000};
const byte H[2] = {0b10011111, 0b11010000};
const byte I[2] = {0b01001111, 0b11110000};
const byte J[2] = {0b01010111, 0b11110000};
const byte K[2] = {0b01011011, 0b11110000};
const byte L[2] = {0b01011101, 0b11110000};
const byte M[2] = {0b01011110, 0b11110000};
const byte N[2] = {0b01011111, 0b01110000};
const byte O[2] = {0b01011111, 0b10110000};
const byte P[2] = {0b01011111, 0b11010000};
const byte Q[2] = {0b01011111, 0b11100000};
const byte R[2] = {0b00101111, 0b11110000};
const byte S[2] = {0b00110111, 0b11110000};
const byte T[2] = {0b00111011, 0b11110000};
const byte U[2] = {0b00111101, 0b11110000};
const byte V[2] = {0b00111110, 0b11110000};
const byte W[2] = {0b00111111, 0b01110000};
const byte X[2] = {0b00111111, 0b10110000};
const byte Y[2] = {0b00111111, 0b11010000};
const byte Z[2] = {0b00111111, 0b11100000};
const byte blank[2] = {0b00000000, 0b00000000};
const byte* alphabet[26] = {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z};
const byte* runMsg[3] = {R, U, N};
const byte* noMsg[3] = {N, O};
const byte* yesMsg[3] = {Y, E, S};
const byte* maybeMsg[5] = {M, A, Y, B, E};
const byte* helpMsg[4] = {H, E, L, P};
const byte* rightHereMsg[9] = {R, I, G, H, T, H, E, R, E};
const byte* willByersMsg[9] = {W, I, L, L, B, Y, E, R, S};
const byte* demogorgonMsg[10] = {D, E, M, O, G, O, R, G, O, N};
const byte* randomMsg[25];
// Timing
unsigned long currentMillis;
int currentMsgIdx = 0;
// Magic 8 ball variables
volatile bool needMagic8BallAnswer = false;
// Send the message out to the shift registers
void send_letter(const byte* letter, int delayTime = 0) {
// take the latchPin low so
// the LEDs don't change while you're sending in bits:
digitalWrite(latchPin, LOW);
// shift out the bits:
shiftOut(dataPin, clockPin, MSBFIRST, letter[0]);
shiftOut(dataPin, clockPin, MSBFIRST, letter[1]);
//take the latch pin high so the LEDs will light up:
digitalWrite(latchPin, HIGH);
// delay if needed
delay(delayTime);
}
// Message script
class ScriptedMessage {
public:
ScriptedMessage(const byte** messageIn, int lenIn, int timeAfterMsgIn, int ltrDurationIn = 1000)
: message(messageIn), len(lenIn), timeAfterMsg(timeAfterMsgIn), ltrDuration(ltrDurationIn), currentLtrIdx(0), previousLtrMillis(millis()), msgDone(false)
{}
// Send the next letter in the message out
void send_next_letter() {
if (currentMillis - previousLtrMillis >= ltrDuration) {
if (!msgDone) {
if (currentLtrIdx == len - 1) {
msgDone = true;
doneMillis = currentMillis;
}
send_letter(message[currentLtrIdx]);
currentLtrIdx = (currentLtrIdx + 1) % len;
previousLtrMillis = currentMillis;
} else {
send_letter(blank);
}
}
}
// is this message done?
bool is_done() const {
if (msgDone && (currentMillis - doneMillis > timeAfterMsg)) {
return true;
}
else return false;
}
// reset the message
void reset() {
msgDone = false;
currentLtrIdx = 0;
}
private:
const byte** message;
int len;
unsigned long doneMillis;
unsigned long timeAfterMsg;
unsigned long ltrDuration;
unsigned long previousLtrMillis;
int currentLtrIdx;
bool msgDone;
};
const int scriptLength = 8;
ScriptedMessage msgScript[scriptLength] = {ScriptedMessage(willByersMsg, 9, 2500), ScriptedMessage(rightHereMsg, 9, 2500),
ScriptedMessage(helpMsg, 4, 2500),
ScriptedMessage(runMsg, 3, 2100), ScriptedMessage(runMsg, 3, 2100), ScriptedMessage(runMsg, 3, 2100),
ScriptedMessage(demogorgonMsg, 10, 2000), ScriptedMessage(randomMsg, 25, 2200, 50)
};
 
// Generate a random message
void generate_random_message() {
for (int iltr = 0; iltr < 25; ++iltr) {
int letterIdx = random(0, 26);
randomMsg[iltr] = alphabet[letterIdx];
}
}
// Handle presses to the magic 8 ball button
void magic_8_ball_button_pushed() {
send_letter(blank);
needMagic8BallAnswer = true;
}
// Answer magic 8 ball questions
void magic_8_ball_answer() {
if (needMagic8BallAnswer) {
send_letter(blank, 500);
int answer = random(0, 3);
// yes, we're using delay() here because I DO want to lock up the Arduino
switch (answer) {
case (0):
// yes
for (int iltr = 0; iltr < 3; ++iltr) send_letter(yesMsg[iltr], 500);
break;
case (1):
// maybe
for (int iltr = 0; iltr < 5; ++iltr) send_letter(maybeMsg[iltr], 500);
break;
case (2):
// no
for (int iltr = 0; iltr < 2; ++iltr) send_letter(noMsg[iltr], 500);
break;
}
send_letter(blank, 2000);
needMagic8BallAnswer = false;
}
}
// Set the current message in the script if we're done with the last one, and we're past
// the post-message delay
void set_current_message() {
if (msgScript[currentMsgIdx].is_done()) {
msgScript[currentMsgIdx].reset();
currentMsgIdx = (currentMsgIdx + 1) % scriptLength;
}
}
void setup() {
// set pins to output to control the shift register
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
// fill random message (can move this to loop to randomize during run)
generate_random_message();
// set pin for button and attach an interrupt
pinMode(buttonPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(2), magic_8_ball_button_pushed, LOW);
}
void loop() {
// Avoiding delay() keeps the Arduino responsive
currentMillis = millis(); // capture the latest value of millis()
magic_8_ball_answer();
msgScript[currentMsgIdx].send_next_letter();
set_current_message();
}
Again, apologies, but the board screws up my formatting when I paste.

EDIT: attaching file.
 

Attachments

Last edited:

fade

Staff member
Well, I guess I didn't, since it ended up being 12 outputs and 1 input (with 14 available). I started with grander ambitions, and wanted more pins free. Plus it was fun.[DOUBLEPOST=1477713151,1477712898][/DOUBLEPOST]
IMG_4121.JPG
IMG_4123.JPG


It actually worked on the first try. That's fairly unprecedented...
 
Top