Final Project: Learning Lighthouse¶
This page presents the process, designs, and steps taken to create my final project for FAB Academy 2023.
Guiding the Way: The Inspiration Behind Learning Lighthouse¶
As a teacher, I often found myself struggling with classroom management. I would spend a lot of time trying to get my students to focus, which left little time for actual teaching. That’s when I had an idea: a light that would signal to my students when they were on task and when they needed to refocus. And so, the Learning Lighthouse was born!
The Learning Lighthouse project isn’t just about improving classroom management, it’s also about promoting positive behavior and accountability among students. How does it work? Each time the light is switched to green or red, the screens count the number of times it changes. At the end of each class, the class receives either a green or red point on the monthly count board.
And here’s where it gets interesting: at the end of the month, the total number of green and red points is tallied up. If the green count is higher, the class receives a reward, such as extra recess or a pizza party. But if the red count is higher, there are consequences, such as losing a privilege or doing extra homework. This system encourages students to stay on task and behave well in the classroom, while also teaching them about accountability and consequences.
A Sneak Peek into Learning Lighthouse¶
From Blueprint to Reality: The Development Journey of Learning Lighthouse¶
The successful completion of this project involves a series of interconnected processes, including electronics, coding, and design and fabrication, all of which are critical components of the development cycle.
Planning for Progress¶
The initial planning phase involved creating a detailed sketch, complete with precise measurements, to capture the design that had taken shape in my mind.
I meticulously identified the required materials and their respective quantities, which include 4 RGB addressable light strips, 2 OLED display screens, an IR sensor, IR remote, and black and frosted acrylic, all carefully selected to ensure that they complement the project’s design and functionality.
Design and Fabrication in Action¶
Design in Fusion360¶
To initiate the design process, I commenced by creating a basic layout comprising of two rectangles. The larger rectangle was designed as the black acrylic frame while the smaller rectangle was intended as the frosted acrylic display area, providing room for light to radiate through. I then duplicated this design to create two sides of the final product, each possessing its own frame and display area.
During the second phase of the design process, I devoted my attention to creating finger-joints that would enable the two sides of the product to fit together with precision. Following this, I replicated the sides, resulting in four sides that could be assembled.
Subsequently, I incorporated additional elements into the design, including two openings for the OLED display screens, a dedicated aperture for the IR sensor, and another for the USB wire to pass through.
As part of my product design, I have included a specialized component that effectively isolates the electronic components from the upper portion of the product. This component features four precisely placed apertures located at the corners, which serve as passageways for the RGB light strips. The component is secured in place using long joints that I have carefully machined on each side, ensuring a precise and robust fit.
At last, I have created a component that reliably encloses the upper and lower sections of the product. This component has been intricately designed by combining two simple shapes - a square and a square frame.
The image below displays the ultimate visual representation of the design.
Click here to download the design
Prototype¶
Prior to the final production of the design, a 3mm medium-density fiberboard prototype was created to verify the precision of the measurements and the compatibility of the joints. The prototype stage is crucial in ensuring that the final product is of high quality and meets the desired specifications. It allows for any design flaws or inaccuracies to be identified and corrected prior to mass production, ultimately saving time and resources while improving the overall product outcome.
It should be noted that the design was cut using a laser cutter machine.
Final Fabrication¶
In the final stage of production, I opted for the use of black acrylic and frosted acrylic as the primary materials. Black acrylic was utilized for the frame, while frosted acrylic was reserved for the central area to facilitate the passage of light. The accompanying image showcases the finished fabrication, which is yet to have all electronic components fastened and arranged in their respective locations.
Note that the acrylic was cut using a laser cutter machine during the fabrication process.
The Synergy of Electronics and Coding¶
This project involves the use of several electronic components, including:
- Arduino MKR WiFi 1010
- 4 Addressable RGB lighting strips that can be illuminated in either red or green
- 2 OLED displays that will indicate the number of times the lights have changed to either color
- IR sensor that detects signals and changes the lighting color accordingly
- IR remote used to send signals to the IR sensor to adjust the lighting color or turn off the lights
- USB wire for connecting to a power source
Electronic Components: Pre-Integration Testing¶
Prior to integrating all of the electronic components together, I conducted individual testing on each of them utilizing basic programming codes. This enabled me to ensure that each component was functioning properly and to identify and address any issues before incorporating them into the larger project. By performing these preliminary tests, I was able to increase the likelihood of a successful integration and minimize the risk of encountering unforeseen difficulties during the project’s implementation.
Merging Electronic Components into a Unified System¶
Once I had completed extensive testing and confirmed the proper functioning of all electronic components, I proceeded to connect them to the Arduino MKR WIFI 1010 board.
Following that, I programmed the board with the provided code.
#include <IRremote.h>
#include <Adafruit_NeoPixel.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SPI.h>
#define STRIP_PIN 4 // Define the pin for the OLED light strip
#define NUM_LEDS 108 // Define the number of LEDs in the OLED light strip
Adafruit_NeoPixel strip(NUM_LEDS, STRIP_PIN, NEO_GRB + NEO_KHZ800); // Create an instance of the OLED light strip
int RECV_PIN = 3; // Define the pin for the IR receiver sensor
IRrecv irrecv(RECV_PIN); // Create an instance of the IR receiver sensor
decode_results results; // Create a variable to store the results of the IR receiver sensor
// #include <WiFiNINA.h>
#define SCREEN_WIDTH 128 // OLED display width
#define SCREEN_HEIGHT 64 // OLED display height
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_SSD1306 display1(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int count = 0;
int redcount = 0;
void setup() {
strip.begin(); // Initialize the OLED light strip
strip.show(); // Initialize all LEDs to 'off'
Wire.begin(); // Initialize the OLED light strip
Serial.begin(9600); // Initialize serial communication
irrecv.enableIRIn(); // Enable the IR receiver sensor
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3D)) { // Address 0x3C for 128x64
// if the OLED init failed, loop forever:
Serial.print("hello");
for(;;); // Don't proceed, loop forever
}
if (!display1.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x64
// if the OLED init failed, loop forever:
for(;;); // Don't proceed, loop forever
}
// // Clear the buffer
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.println("Setup");
display.display();
delay(1000);
display.clearDisplay();
display.setCursor(0, 0);
// // Clear the buffer
display1.clearDisplay();
display1.setTextSize(2); // Normal 1:1 pixel scale
display1.setTextColor(WHITE); // Draw white text
display1.setCursor(0, 0); // Start at top-left corner
display1.println("Setup");
display1.display();
delay(1000);
display1.clearDisplay();
display1.setCursor(0, 0);
}
void loop() {
display.clearDisplay();
display.setTextSize(7); // Increase text size
display.setTextColor(WHITE); // Draw white text
display1.clearDisplay();
display1.setTextSize(7); // Increase text size
display1.setTextColor(WHITE); // Draw white text
String countString = String(count); // Convert the count to a String to get its length
// Calculate center position of the text. Each character is 6 pixels wide at text size 1.
// It grows with the text size.
int textWidth = countString.length() * 6 * 7; // In pixels
int centerPosition = (SCREEN_WIDTH - textWidth) / 2;
display.setCursor(centerPosition, 0); // Position the text at the center
display.println(count);
display.display();
display1.setCursor(centerPosition, 0); // Position the text at the center
display1.println(redcount);
display1.display();
if (irrecv.decode(&results)) { // Check if the IR receiver sensor has received a signal
Serial.println(results.value, HEX); // Print the value of the signal in hexadecimal to the serial monitor
Serial.println(results.value); // Print the value of the signal in hexadecimal to the serial monitor
irrecv.resume(); // Resume the IR receiver sensor to receive the next signal
if (results.value==16724175)
{
Serial.println("green");
for (int i = 0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, 0, 255, 0); // Set each LED to yellow color
}
strip.show(); // Display the yellow color on the OLED light strip
count++;
}
else if (results.value==16718055)
{
Serial.println("blue");
for (int i = 0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, 0, 0, 255); // Set each LED to yellow color
}
strip.show(); // Display the yellow color on the OLED light strip
}
else if (results.value==16743045)
{
redcount++;
Serial.println("red");
Serial.println(redcount);
for (int i = 0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, 255, 0, 0); // Set each LED to red color
}
strip.show(); // Display the red color on the OLED light strip
}
else if (results.value==16769055)
{
redcount=0;
count=0;
Serial.println("clear");
for (int i = 0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, 0, 0, 0); // Set each LED to red color
}
strip.show(); // Display the red color on the OLED light strip
}
else if (results.value==16716015)
{
Serial.println("result");
for(int i=0; i<10; i++){
for (int i = 0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, 0, 255, 0); // Set each LED to red color
}
strip.show(); // Display the red color on the OLED light strip
delay(200);
for (int i = 0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, 255, 0, 0); // Set each LED to red color
}
strip.show(); // Display the red color on the OLED light strip
delay(200);
}
if (count>redcount){
for (int i = 0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, 0, 255, 0); // Set each LED to green color
}
strip.show(); // Display the red color on the OLED light strip
}
else{
for (int i = 0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, 255, 0, 0); // Set each LED to green color
}
strip.show(); // Display the red color on the OLED light strip
}
}
}
}
Before permanently securing the electronic components in their designated positions, I conducted a thorough assessment to ensure the code was working flawlessly.
Unveiling the End Result: The Final Product of the Project¶
Here is the completed final product, showcasing all the added details.