Be reminded to get up by using loud sounds from your Stand-Up Alarm Chair. Stand up to sitting down and improve your health!
Story
Sitting is terrible for our health. However, some of us spend out entire day in our seats, either for work or just out of laziness. According to a study done at the University of Waterloo, “people should be standing for at least 30 minutes per hour to get health benefits.” However, we might not get up for many reasons such as fatigue, too much work, laziness, and other reasons.
But what if we modified our chairs so that they were difficult to sit on for long periods of time? Using two (or more) ESP32s, an IR Obstacle sensor, and a buzzer (or more), you can make an Stand-Up Alarm Chair that only allows you to sit for preset duration before it gets too disruptive to stay seated (or possibly scare you out of your seat).
Design Idea
When something is annoying, eventually you just cannot take it anymore and try to get away from it. That is the underlying idea with this design: if the user sits for too long, a buzzer will blare until they get off. One ESP32, using an IR Obstacle sensor, monitors if the user is sitting on a chair and records the data. The other ESP32 receives that data and determines whether or not to turn on the buzzer alarm.
Where to place the ESP32 with the IR Obstacle sensor is up to you as long as it can monitor when you sit. Mine in the corner between the seat and backrest of my chair. I recommend using a power bank to power this ESP32 since they're smaller and more portable, which makes them easier to position on a chair. The other ESP32 with the buzzer should be close enough to hear it from your chair. We use multiple ESP32s because each one only has one 5.0V supply, which is needed for all the sensors. Besides, with multiples ESP32s, a surround system alarm can be made!
Setting up ESP32s and Sensors
I used Arduino IDE to setup my ESP32s. Simply follow this tutorial on how to install ESP32 into your Arduino IDE.
The ESP32s have a server/client relationship. The server is connected to the IR Obstacle sensor and is attached to the chair. The client is set further away and attached to a buzzer. The sensors are connected according to the schematic below. To make my ESP32s into servers and clients, I followed this tutorial for ESP32 Client-Server Wi-Fi Communication Between Two Boards.
You will need to install the EasyBuzzer library on your Arduino IDE. Press CLTR + SHIFT + I to get to managelibraries and search for EasyBuzzer.
Server Code
This ESP32 acts as a server to the client ESP32, but also acts as a client to an IoT platform (we will discuss this later). To connect to the IoT platform you need to add your router’s SSID and password. The ESP32’s SSID and password are already provided. You also need to add your IoT platform’s GatewayURL to send the ESP32’s data to.
const char* ssid = "MAIN ROUTER SSID";
const char* password = "MAIN ROUTER PASSWORD";
const char* ESP_ssid = "ESP32-Access-Point";
const char* ESP_password = "123456789";
const char* url = "GATEWAY URL";
The ESP32 collects the IR Obstacle sensor data every second for 24 hours (86400 seconds) then resets itself for the next day (this is in the loop function). If the IR Obstacle sensor detects someone on the chair, it updates a counter that tracks the total number of seconds a person has been sitting on that specific seat. A binary switch also gets updated if the movement on the seat changes.
for (int i = 0; i < 86400; i++){
isObstacle = digitalRead(isObstaclePin);
if (isObstacle == LOW)
{
Serial.println("OBSTACLE!!, OBSTACLE!!");
counter = counter + 1;
switcher = 1;
}else{
Serial.println("clear");
switcher = 0;
}
}
The counter and the switch data both get sent to the IoT platform and the ESP32 server.
Client Code
This ESP32 acts as the client to the server ESP32 and will be the main reason you get up from your seat. To connect to the ESP32 server, the same SSID and password must be used. This has already been provided unless you’ve changed them. It will then use the server’s URL to get the counter and switch data.
const char* ESP_ssid = "ESP32-Access-Point";
const char* ESP_password = "123456789";
const char* url_switch = "http://192.168.4.1/On_Off";
Inside the loop function, the server data is requested and converted into a string, with the counter data being converted into an int afterwards. If the counter has surpassed a specified limit and you’re still sitting down, the buzzer will turn on. It will only shut off if the counter has gone down again or if you stand up (unless there is a power outage, the wiring gets unplugged, etc.). This will force you to stay out of that chair for at least your resting time. The default is 30 minutes every hour.
However, if you decide to get up for that resting period without your alarm going off, your sitting counter will reset itself.
for(int i = 0; i < 86400; i++){
EasyBuzzer.update();
if(WiFi.status()== WL_CONNECTED){
switcher = httpGETRequest(url_switch);
}else{
Serial.println("Error in WiFi connection");
}
Serial.println(counter);
if((counter % interval) > period_rest){
if(switcher == "1"){
Serial.println("NOT RESTING");
EasyBuzzer.singleBeep(2000, 1000);
}else{
Serial.println("RESTING");
EasyBuzzer.stopBeep();
counter = counter + 1;
}
}else if(switcher == "1"){
Serial.println("SITTING");
counter = counter + 1;
temp_rest = 0;
}else{
Serial.println("NOT SITTING");
temp_rest = temp_rest + 1;
if(temp_rest > period_rest){
counter = 0;
}
}
delay(1000);
}
Store and Track Data
Congrats! You can now successfully modify any seat to annoy you out of your seat. But what if you want to track your progress on how long you’re sitting down per day, or how long it takes you to be fed up with the alarm? As we mentioned before, you can use an IoT platform to manage this. But why use any IoT platform when you can use a new, simple to use, and powerful IoT platform by the name uBeac.
Using uBeac
All you need to do is create a free uBeac account here and you’re on your way to becoming an IoT genius. Following the tutorial for OS Monitoring of your computer, just create a Gateway, paste it in the ESP32 server, and you’ll start seeing data arrive! Then make your Dashboard to see live data from your sensors. To view past reports, click on the Reports module and see it as raw data or in graph format.
Now that you know everything you need to make this project, get up from your seat and make it happen! If there are any questions or recommendations, leave them in the comments below. Happy connecting!
#include <WiFi.h>
#include <HTTPClient.h>
#include <ESPAsyncWebServer.h>
int isObstaclePin = 15; // This is our input pin
int isObstacle = HIGH; // HIGH MEANS NO OBSTACLE
const char* ssid = "Pokemon"; //Main Router
const char* password = "1945000000"; //Main Router Password
const char* ESP_ssid = "ESP32-Access-Point";
const char* ESP_password = "123456789";
const char* url = "http://myworkspace.hub.ubeac.io/myPC";
String payload_pattern = "[{\"id\": \"MyESP\", \"sensors\": [{\"id\": \"Time Near Sensor\", \"value\": $timer$}, {\"id\": \"Close\", \"value\": $switcher$}]}]";
int dividen = 3600;
int counter = 0;
int switcher = 0;
AsyncWebServer server(80);
void setup() {
//Setup IR Obstacle Sensor
pinMode(isObstaclePin, INPUT);
Serial.begin(115200); // Starts the serial communication
//Connect to Local WiFi
delay(4000); //Delay needed before calling the WiFi.begin
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) { //Check for the connection
delay(1000);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
//Setup ESP32 WiFi
WiFi.softAP(ESP_ssid, ESP_password);
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
server.on("/On_Off", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", String(switcher).c_str());
});
bool status;
server.begin();
}
void loop() {
counter = 0;
switcher = 0;
for (int i = 0; i < 86400; i++){
isObstacle = digitalRead(isObstaclePin);
if (isObstacle == LOW)
{
Serial.println("OBSTACLE!!, OBSTACLE!!");
counter = counter + 1;
switcher = 1;
}
else
{
Serial.println("clear");
switcher = 0;
}
float timer;
timer = (float)counter / (float)dividen;
String payload = payload_pattern;
payload.replace("$timer$",String(timer));
payload.replace("$switcher$",String(switcher));
if(WiFi.status()== WL_CONNECTED){
HTTPClient http;
http.begin(url);
int httpResponseCode = http.POST(payload);
if(httpResponseCode>0){
String response = http.getString();
Serial.println(httpResponseCode);
}
http.end();
}else{
Serial.println("Error in WiFi connection");
}
delay(1000);
}
}
- Seat Server
#include <WiFi.h>
#include <HTTPClient.h>
#include <ESPAsyncWebServer.h>
int isObstaclePin = 15; // This is our input pin
int isObstacle = HIGH; // HIGH MEANS NO OBSTACLE
const char* ssid = "Pokemon"; //Main Router
const char* password = "1945000000"; //Main Router Password
const char* ESP_ssid = "ESP32-Access-Point";
const char* ESP_password = "123456789";
const char* url = "http://myworkspace.hub.ubeac.io/myPC";
String payload_pattern = "[{\"id\": \"MyESP\", \"sensors\": [{\"id\": \"Time Near Sensor\", \"value\": $timer$}, {\"id\": \"Close\", \"value\": $switcher$}]}]";
int dividen = 3600;
int counter = 0;
int switcher = 0;
AsyncWebServer server(80);
void setup() {
//Setup IR Obstacle Sensor
pinMode(isObstaclePin, INPUT);
Serial.begin(115200); // Starts the serial communication
//Connect to Local WiFi
delay(4000); //Delay needed before calling the WiFi.begin
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) { //Check for the connection
delay(1000);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
//Setup ESP32 WiFi
WiFi.softAP(ESP_ssid, ESP_password);
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
server.on("/On_Off", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", String(switcher).c_str());
});
bool status;
server.begin();
}
void loop() {
counter = 0;
switcher = 0;
for (int i = 0; i < 86400; i++){
isObstacle = digitalRead(isObstaclePin);
if (isObstacle == LOW)
{
Serial.println("OBSTACLE!!, OBSTACLE!!");
counter = counter + 1;
switcher = 1;
}
else
{
Serial.println("clear");
switcher = 0;
}
float timer;
timer = (float)counter / (float)dividen;
String payload = payload_pattern;
payload.replace("$timer$",String(timer));
payload.replace("$switcher$",String(switcher));
if(WiFi.status()== WL_CONNECTED){
HTTPClient http;
http.begin(url);
int httpResponseCode = http.POST(payload);
if(httpResponseCode>0){
String response = http.getString();
Serial.println(httpResponseCode);
}
http.end();
}else{
Serial.println("Error in WiFi connection");
}
delay(1000);
}
}
The article was first published in Hackster, March 13, 2020
author: Amir Pournasserian