Cultivate Curiosity, Inspire Imagination.

Arduino Tutorial: Floorboard Smart Light System

Introduction

In the "Red Light Green Light" episode in Squid Game, players are required to keep walking without getting spotted. At a specific moment when the giant doll starts hunting, anyone found to be moving will be eliminated.

This tutorial explains how a "Red Light Green Light" game can be built with an Arduino, some LED lights and a thin-film pressure sensor. In this game, players are required to walk on floorboards that have one or more pressure sensors placed underneath them. At a specific moment, the pressure sensors are activated and players who happen to be standing on a pressure sensor that has been activated will trigger an alarm and be eliminated from the game.

 

 

 

Hardware Required

You may purchase the individual components here:

  1. Arduino Uno R3
  2. LCD 16x02
  3. Solderless Breadboard 400 Tie Point
  4. Jumper Wire Male-Male 40x
  5. RP-S40-ST Thin Film Pressure Sensor
  6. Rainbow LED 1x5 Module WS2812
  7. 10k Variable Resistor
  8. 10k Resistor

 

Connecting the Hardware

Connect the 10k variable resistor to the LCD display as follows.

  • VSS (LCD) to GND (10k resistor)
  • VDD (LCD) to 5V (10k resistor)
  • V0 (LCD) to Output (10k resistor)

This connection allows the 10k variable resistor to control the brightness of the LCD screen. Adjusting the 10k variable register will control the LCD contrast.

Connect the LCD display to the Arduino Uno as follows.

  • RS (LCD) to Pin 2 (Arduino Uno)
  • RW (LCD) to Pin 3 (Arduino Uno)
  • E (LCD) to GND (Arduino Uno)
  • D4 (LCD) to Pin 4 (Arduino Uno)
  • D5 (LCD) to Pin 5 (Arduino Uno)
  • D6 (LCD) to Pin 6 (Arduino Uno)
  • D7 (LCD) to Pin 7 (Arduino Uno)
  • A (LCD) to 5V (Arduino Uno)
  • K (LCD) to GND (Arduino Uno)

The RS pin on the LCD allows selection between its command register and data register. This lets us send commands to the LCD (such as a command to clear the LCD screen or to send data to be displayed on the LCD). The RW pins on the LCD toggle between 0 (for reading from the LCD) and 1 (for writing to the LCD). We will be setting these configurations through the Arduino Uno's pin 2 and 3 in our program later.

D4 to D7 are connected to the respective Pins 4 to 7 on the Arduino to display alphabets or numbers to the respective internal registers on the LCD. Pins E and K are connected to the Grounding Pins (GND) on the Arduino.

Pin A powers on the LCD backlight and is connected to the 5V pin on the Arduino.

Connect the RP-S40-ST Thin Film Pressure Sensor to the Arduino as follows:

This allows the Arduino to detect data sent from the pressure sensor.

Connect the Rainbow LED module to the Arduino as follows:

  • DIN (Rainbow LED) to Pin 8 (Arduino Uno)
  • +5V (Rainbow LED) to 5V (Arduino Uno)
  • GND (Rainbow LED) to GND (Arduino Uno)

The DIN pin on the Rainbow LED receives instruction through pin 8 from the Arduino Uno to light up. The 5V pin on the Rainbow LED receives powers from the Arduino. We will be writing instructions for the Arduino Uno to instruct the Rainbow LED to light up.

 

Install the NeoPixel Library for Arduino

The NeoPixel library from AdaFruit will allow us to write codes on the Arduino Uno to communicate with the Rainbow LED. To install the NeoPixel library, start up the Arduino IDE. Go to Tools > Manage Libraries and search for NeoPixel. Scroll down to look for "AdaFruit NeoPixel" and install the latest version of this library.

 

Programming the Arduino

The codes for this project can be found in Kuriosity's Github Repository here. Here are some important code snippets and what they do.

The codes below include the required library.

// include libraries
#include <LiquidCrystal.h>
#include <Adafruit_NeoPixel.h>

The threshold definition determines how hard to press the sensor before triggering the Rainbow LED lights. LED_COUNT is the total number of LEDs on the Rainbow LED strip. In our case, our LED strip has 5 LED lights. We will set the brightness of the LED lights to 150 so that the device does not draw too much power while still maintaining high brightness.

// declare user variables
#define THRESHOLD 500
#define LED_COUNT 5
#define BRIGHTNESS 150 // NeoPixel brightness

Declare the pins for the pressure sensor and the Rainbow LED to receive instructions from the Arduino Uno.

// declare pins
const int forceSensorPin = A0;
const int ledPin = 8;

In the setup() routine, we initialize the LCD and NeoPixel so that it is ready for use. We also initialize the countdown variable to 10 seconds.

void setup() {
// initialize LCD
lcd.begin(16, 2);

// initialize NeoPixel
strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
strip.show(); // Turn OFF all pixels ASAP
strip.setBrightness(BRIGHTNESS);

// initialize variables
countdown = 10000;
}

Code a updateLCD() function. We will call this function later to refresh the LCD. During a countdown, the LCD will display the text "Countdown:" on the first line and "10.00s" in the second line of the LCD panel.

void updateLCD() {
lcd.clear();
lcd.print("Countdown:");
lcd.setCursor(0, 1);
lcd.print(countdown / 1000.0);
lcd.print("s");
}

Code a checkSensor() function that returns a Boolean true or false based on whether the reading exceeds the threshold that we have set. To smoothen the noise and get a more accurate reading, we will take an average of 25 readings from the pressure sensor.

// get an average reading from sensor for stability
bool checkSensor() {
float average = 0;
for (int i = 0; i < 25; i++) {
average += analogRead(forceSensorPin);
}
average = average / 25.0;

if (average > THRESHOLD) return true;
return false;
}

In the main loop, we will reduce the countdown variable by 10 every 10 milliseconds.

void loop() {
// reduce count by 10ms every 10ms
if (millis() - lastCountdownTime > 10) {
if (countdown > 0) countdown -= 10;
lastCountdownTime = millis();
}

The LCD panel will be updated every 25 milliseconds with the new value of the countdown variable. We are updating the LCD panel only every 25 milliseconds because if the text on the LCD panel refreshes too fast, our eyes will not be able to see the text displayed.

// update the LCD every 25ms
// if you refresh too fast our eyes cannot see the text displayed
if (millis() - lastUpdateTime > 25) {
updateLCD();
lastUpdateTime = millis();
}

Add a logic to determine if the countdown has reached 0. Once the countdown timer reaches 0, the program checks if the pressure sensor has been triggered. If it is, the trigger variable is set to true and the LED strip flashes. This is similar to how the doll blinks her eyes and turns her head in the Squid Game. At this moment, anyone who has triggered the pressure sensor 'loses' because they have been standing or moving on it.

// check if timer is still running and sensor is triggered
if (countdown == 0 && checkSensor()) {
trigger = true;
}

if (trigger) {
// toggle the blink state every 100ms
if (millis() - lastBlinkTime > 100) {
blinkState = !blinkState;
lastBlinkTime = millis();
}

if (blinkState) {
// show red colour
strip.fill(strip.Color(255, 0, 0, strip.gamma8(255)));
} else {
// show blank
strip.fill(strip.Color(0, 0, 0, strip.gamma8(255)));
}
strip.show();

 

Running the Game

Let's try to run the game. Download the program to the Arduino Uno, then power it up.

The countdown timer starts counting down to 0.

When it has reaches 0, the pressure sensor starts sensing if it has been activated. Let's touch the pressure sensor to activate it.

This lights up the LED strip. In the game, whoever activates the LED strips will "lose" the game.

Well done! We have replicated the Squid Game mechanics and now you can go further and build a stage with the actual doll. To further improve this setup, we can add a clock module to re-design it as an alarm clock.

Check out our next tutorial to learn how to build it!

 

Resources