The Blue Box
Top view of the Blue Box, with power off and sticky note on top labeling what the button does
Why did I make this?
Sometimes I get bouts of profound melancholia that are extremely debilitating and greatly affect my ability to be productive and get things done in my day to day life. Though trial and error I've found that moving around and talking to friends generally helps with lessening how badly it affects me or makes it go away entirely. The Blue Box is my attempt at making a physical device that reminds me of these things and help me blunt the worst parts of the melancholic moods.
Each box is 6 in x 6 in x 4 in. The electronic components inside consist of LEDs, an Arduino, a breadboard, a LoRa radio module, and a buzzer.
A picture from a different angle, this time to show the "Go Outside" that's cut onto the front face
On the opposite side of the main body, "You're not alone, go talk to friends" is laser cut on its front face
The green wire sticking out of the top of both boxes' holes serve as the antenna for both modules to communicate with each other
![](https://www.google.com/images/icons/product/drive-32.png)
In this video, I show myself pressing the one button on the main body. This makes the LEDs inside the main body light up, and sends a radio signal to the external module. The external module receives the radio signal and lights up its own LEDs, as well as activating a buzzer.
Process
Testing the circuit for the external module my roommate is meant to carry around
Testing the circuit for the main body, this is a stripped down version of it
Initial stages of prototype the physical design of the blue box, the cardboard model to show dimensions, and the red acrylic to get familiar with the laser cutting process
Before I built anything, I made the schematic for how this project should roughly function in terms of circuits and electric connections. It helped me immensely in the rest of the project for development because I could now test the circuits to make sure they were working as planned.
The biggest part of this project process was getting the radios to work with each other. It wasn't too bad in the end when I put everything together but it did take more time than I wished it to. The fabrication process itself was also about as hard as I expected it to be. I've never built anything before out of acrylic, or laser cut anything before this semester. It took some time to get used to and I'm still not entirely confident in designing to be lasercut even now. Learning Fusion 360 to a sufficient level to CAD something that will slide together is a skill I'll need to practice. Given that this was only the second time ever I had to fabricate something and the first time I had to do it myself, this project turned out better than I expected. Once I actually got going and in the thick of it, none of the skills that had initially seemed daunting to learn seemed hard anymore. They were simply necessary.
Discussion
"Make roommate’s box smaller, current is a hefty thing to carry around". I also want to make the box's design more compact, but with the skillset and time I had to do this project, that really wasn't something I could do feasibly. I suppose that if I were to revisit this project with that idea in mind I would switch over to an Arduino nano so that there wouldn't need to be as much space inside the box to hold all the electronics.
"If you don't use radio, you could use wifi and ping your roommates phone". This is a really interesting idea that I think also has a lot of potential if I want to explore this route instead. It is true that the best part is no part, and getting rid of an external box that my roommate would need to carry around would certainly meet that criteria. Given how essential phones are to our lives now, it's the next best thing to a guarantee that my roommate would see the pings. I don't know how I feel about having another point of contact with my roommate having the same endpoint on his end though.
I have mixed feelings on this project and how it turned out, to be completely honest. I'm happy that I managed to get a form of it working, but it wasn't the form I was hoping for. I was hoping that at the end of the process I would have a thing ready to use just like how my ideation laid it out. It would be something that my roommate could carry around and the thing would just work over long distances and through walls. That unfortunately wasn't what I got, what with the range of the final result being much too short for actual functionality. Ultimately, the Blue Box in its current form does not solve the problem I designed it to solve, so it did not satisfy my own goals. I might come back to this project and redesign it so that it can, but that's not something I'll be doing this semester. The build process was very educational though. Through fabricating the two boxes, I familiarized myself with the Ideate laser printers, Fusion 360, and the Long Range radios for the Arduino. I'm glad to have these tools in my back pocket now because they'll almost certainly be useful for any future projects I intend to do. This project was also good in terms of experience with how much work it took to actually build the boxes and get the electronics up and running. I now have a better sense of scope and how much effort it will take to do or build a particular thing, which I'm very grateful for.
I've already discussed in previous paragraphs what I would do with the second iteration of the project, but I'll lay it out explicitly here. The second iteration will do away with the roommate module entirely, the main box will instead ping my roommate's phone directly. The main box will also be substantially smaller, and I hope to achieve this by using the Arduino Nano instead of the Uno. I'll also redo the main box so that the main form is instead a cylinder, the better to hold it with. The button would also be much bigger and have a cover, so that pressing it isn't risky or uncomfortable.
Technical information
Project Code
/* Allen Zhu
Carnegie Mellon University
Physical Computing (60-223) Spring 2024
Project 2: The Blue Box, a trinket to help me not be sad
Sample/template code taken from Professor Robert Zacharias
LoRa code taken from Adafruit's website found here: https://learn.adafruit.com/adafruit-rfm69hcw-and-rfm96-rfm95-rfm98-lora-packet-padio-breakouts/rfm9x-test
This code is freely available under the CC-by-SA 4.0 DEED license
This Arduino sketch is to help a LoRa transmitter module transmit an on/off signal to its receiver module, see Blue Box External Module for more details.
Structuring this Arduino sketch so that the loop contains four basic elements:
1) read inputs (gather information from the world)
2) compute and make decisions based on those inputs
3) drive outputs (effect different actuators in the world)
4) report information back to the user
Pin mapping:
Arduino pin | role | details
------------------------------------
2 output interrupt pin for LoRa
9~ output radio reset pin
10~ output CS pin, connects to SPI chip select
11~ output MOSI pin, connects to SPI MOSI
12 output MISO pin, connects to SPI MISO
13 output SCLK pin, connects to SPI clock
*/
/*
------------------------------------LoRa Setup------------------------------------
*/
// importing libraries
#include <SPI.h>
#include <RH_RF95.h>
// pinout setup for LoRa
#define RFM95_CS 10 // reset and CS pins can be any pin
#define RFM95_RST 9
#define RFM95_INT 2 // the IRQ pin should be an interrupt pin. On an UNO this is pin #2 or pin #3.
// Setting frequency of the LoRa module
#define RF95_FREQ 915.0 // note: must match RX's freq!
// Singleton instance of the radio driver
RH_RF95 rf95(RFM95_CS, RFM95_INT); // instantiating radio with custom pin numbers
// Blinky on receipt
#define LED 13
void setup() {
// setting up pins
pinMode(LED, OUTPUT);
pinMode(RFM95_RST, OUTPUT);
digitalWrite(RFM95_RST, HIGH);
// startup text
Serial.begin(9600);
delay(100);
Serial.println("Arduino LoRa RX Test!");
// manual reset
digitalWrite(RFM95_RST, LOW);
delay(10);
digitalWrite(RFM95_RST, HIGH);
delay(10);
//checking if radio initialization was successful
while (!rf95.init()) {
Serial.println("LoRa radio init failed"); // it failed
while (1);
}
Serial.println("LoRa radio init OK!"); //it succeeded
// Frequency for this project is 915 MHz
if (!rf95.setFrequency(RF95_FREQ)) {
Serial.println("setFrequency failed");
while (1);
}
Serial.print("Set Freq to: ");
Serial.println(RF95_FREQ);
// Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on
// The default transmitter power is 13dBm, using PA_BOOST.
// setting transmitter power to 23 here, LoRa range is from 5 to 23 dBm:
rf95.setTxPower(23, true);
}
int16_t packetnum = 0; // packet counter, we increment per xmission
void loop() {
// 1) read inputs (gather information from the world) (unnecessary)
// 2) compute and make decisions based on those inputs (unnecessary)
// sending the signal to the receiver
delay(2000); // Wait 2 seconds between transmits, could also 'sleep' here!
Serial.println("Transmitting..."); // Send a message to rf95_server
// 3) drive outputs (effect different actuators in the world)
// the actual message itself to be transmitted
//char radiopacket[20] = "On "; the former message to be sent
int onSignal = 1; // the signal to be sent
packetnum++;
Serial.print("Sending "); Serial.println(onSignal);
//radiopacket[19] = 0;
// 4) report information back to the user
Serial.println("Sending..."); delay(10);
rf95.send(onSignal, 10);
Serial.println("Waiting for packet to complete..."); delay(10);
rf95.waitPacketSent();
}
//EXTERNAL MODULE CODE
/* Allen Zhu
Carnegie Mellon University
Physical Computing (60-223) Spring 2024
Project 2: The Blue Box, a trinket to help me not be sad
Sample/template code taken from Professor Robert Zacharias
LoRa code taken from Adafruit's website found here: https://learn.adafruit.com/adafruit-rfm69hcw-and-rfm96-rfm95-rfm98-lora-packet-padio-breakouts/rfm9x-test
This Arduino sketch is to help a LoRa receiver module receive an on/off signal from the transmitter module, see main body sketch for more details.
Structuring this Arduino sketch so that the loop contains four basic elements:
1) read inputs (gather information from the world)
2) compute and make decisions based on those inputs
3) drive outputs (effect different actuators in the world)
4) report information back to the user
Pin mapping:
Arduino pin | role | details
------------------------------------
4 output LED pin
5 output buzzer pin
2 output interrupt pin for LoRa
9~ output radio reset pin
10~ output CS pin, connects to SPI chip select
11~ output MOSI pin, connects to SPI MOSI
12 output MISO pin, connects to SPI MISO
13 output SCLK pin, connects to SPI cloc
*/
/*
------------------------------------LoRa Setup------------------------------------
*/
// importing libraries
#include <SPI.h>
#include <RH_RF95.h>
// pinout setup for LoRa
#define RFM95_CS 10 // reset and CS pins can be any pin
#define RFM95_RST 9
#define RFM95_INT 2 // the IRQ pin should be an interrupt pin. On an UNO this is pin #2 or pin #3.
//pinout setup for everything else
#define LEDPIN 4
#define BUZZERPIN 5
// Setting frequency of the LoRa module
#define RF95_FREQ 915.0 // note: must match TX's freq!
// Singleton instance of the radio driver
RH_RF95 rf95(RFM95_CS, RFM95_INT); // instantiating radio with custom pin numbers
// Blinky on receipt
#define LED 13
void setup() {
// setting up pins
pinMode(LED, OUTPUT);
pinMode(LEDPIN, OUTPUT);
pinMode(BUZZERPIN, OUTPUT);
pinMode(RFM95_RST, OUTPUT);
digitalWrite(RFM95_RST, HIGH);
// startup text
Serial.begin(9600);
delay(100);
Serial.println("Arduino LoRa RX Test!");
// manual reset
digitalWrite(RFM95_RST, LOW);
delay(10);
digitalWrite(RFM95_RST, HIGH);
delay(10);
//checking if radio initialization was successful
while (!rf95.init()) {
Serial.println("LoRa radio init failed"); // it failed
while (1)
;
}
Serial.println("LoRa radio init OK!"); //it succeeded
// Frequency for this project is 915 MHz
if (!rf95.setFrequency(RF95_FREQ)) {
Serial.println("setFrequency failed");
while (1)
;
}
Serial.print("Set Freq to: ");
Serial.println(RF95_FREQ);
// Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on
// The default transmitter power is 13dBm, using PA_BOOST.
// setting transmitter power to 23 here, LoRa range is from 5 to 23 dBm:
rf95.setTxPower(23, true);
}
int16_t packetnum = 0; // packet counter, we increment per xmission
int radioWorks = 0;
void loop() {
// 1) read inputs (gather information from the world)
if (rf95.available())
{
// Should be a message for us now
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);
// 2) compute and make decisions based on those inputs
if (rf95.recv(buf, &len)) // receiving the transmitted message
{
//declaring variables for ease of data manipulation
radioWorks = 1;
digitalWrite(LED, HIGH);
RH_RF95::printBuffer("Received: ", buf, len);
Serial.print("Got: ");
Serial.println((char*)buf);
Serial.print("RSSI: "); // RSSI is signal strength, -15 is the likely highest you'll see, larger number = stronger signal
Serial.println(rf95.lastRssi(), DEC);
// 3) drive outputs (effect different actuators in the world)
// Send a reply
uint8_t data[] = "And hello back to you";
rf95.send(data, sizeof(data));
rf95.waitPacketSent();
// 4) report information back to the user
Serial.println("Sent a reply");
digitalWrite(LED, LOW);
}
else
{
Serial.println("Receive failed");
}
}
// 2) compute and make decisions based on those inputs
if (radioWorks == 1) {
// 3) drive outputs (effect different actuators in the world)
digitalWrite(LEDPIN, HIGH);
digitalWrite(BUZZERPIN, HIGH);
delay(3000);
digitalWrite(LEDPIN, LOW);
digitalWrite(BUZZERPIN, LOW);
radioWorks = 0;
}
}