Stand-Up Alarm Chair with ESP32 + Arduino IDE

0 252 Medium

Be reminded to get up by using loud sounds from your Stand-Up Alarm Chair. Stand up to sitting down and improve your health!

 

 

HARDWARE LIST
2 DFRobot FireBeetle ESP32 IOT Microcontroller (Supports Wi-Fi & Bluetooth)
1 Digilent IR Proximity Sensor
1 Buzzer

Software apps and online services

 - uBeac IoT Platform Free Subscription

 - Arduino IDE

 

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.

 

ESP32 with buzzer (left, blue) and ESP32 with IR Obstacle sensor (right, orange)
ESP32 with buzzer (left, blue) and ESP32 with IR Obstacle sensor (right, orange)

 

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!

 

My high tech setup of IR Obstacle sensor on chair with ESP32 and power bank taped together below chair
My high tech setup of IR Obstacle sensor on chair with ESP32 and power bank taped together below chair

 

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.

CODE
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.

CODE
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.

CODE
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.

CODE
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.

 

Sample dashboard
Sample dashboard

 

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!

 

Schematics

 - ESP32 Setup

 

 

Code

 - Seat Client

CODE
#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

CODE
#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);
  }
}
License
All Rights
Reserved
licensBg
0