Meeting rooms are designed for productivity, but they rarely respond to the changing needs of the people using them. Poor indoor air quality can reduce comfort and concentration, while the same workspace often lacks the flexibility to transition into a more relaxed social environment after working hours. To address this challenge, our project, Key Balance, explores how physical computing and architecture can create healthier and adaptive meeting spaces.

Meeting room on work mode
Meeting room on party mode

The project combines environmental sensing and automated responses through two independent systems: an air-quality lane and a light lane. The goal is simple: improve workplace wellbeing during the day and support social interaction after hours.

Meeting room with window open

The Problem

In enclosed meeting rooms, carbon dioxide and other pollutants can accumulate as people talk and breathe. At the same time, most of workspaces don’t adapt to a social environment that helps to balance work-leisure time.

Our Solution

Key Balance uses an MQ-135 air quality sensor and a light sensor connected to Arduino UNO. When air quality readings rise above 500, a servo motor automatically tilts the window open, allowing fresh air to enter the room. Once the air quality improves and readings reaches 250, the window closes again.

The second system monitors ambient daylight. During the day, the room remains in Work Mode, displaying a calm atmosphere through the OLED screen and subtle lighting. When light levels outise, the room automatically switches to Party Mode, activating a colorful NeoPixel LED strip and updating the OLED display to signal the transition from work to social interaction.

Sun path that activates the party mode
LED light strip on party mode

Design and Technical Process

The project was developed using an Arduino Uno, MQ-135 air sensor, light sensor (LDR), servo motor, NeoPixel LED strip and OLED display. The physical prototype was built as a meeting room using cardboard walls and a transparent membrane window.

Meeting room prototype
Air sensor activating the window tilt

The programming logic relied on sensor thresholds and conditional statements. Air-quality values controlled the opening and closing of the window, while light sensor readings determined whether the room entered Work Mode or Party Mode.

Light sensor activating LED strip

The final prototype successfully demonstrated how responsive architecture can support both health and social life. By automatically improving ventilation and creating a clear transition between work and leisure, Key Balance shows how simple physical computing systems can make shared spaces more intelligent, comfortable and human-centered.

Source Code

#include <MQ135.h> //<- Air Sensor

#include <Servo.h> //<- Motor

#include <Adafruit_NeoPixel.h> //<- LED Strip

#include <U8x8lib.h> //<- OLED Screen

#include <Arduino.h>

U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/U8X8_PIN_NONE);

Servo myservo;

int airSensor = 3;

int airQValue;

int lightSensor = A6;

int lightValue;

#define NeoPixel 2

#define numbPixels 8

Adafruit_NeoPixel pixels(numbPixels, NeoPixel, NEO_GRB + NEO_KHZ800);

void setup() {

  // put your setup code here, to run once:

  myservo.attach(6);

  pixels.begin();

  pixels.setBrightness(50);

  pixels.clear();

  pixels.show();

  u8x8.begin();

    u8x8.setPowerSave(0);

    u8x8.setFlipMode(1);

  Serial.begin(9600);

}

void loop() {

  // put your main code here, to run repeatedly:

  airQValue = analogRead(airSensor);

  if (airQValue > 500) {

    Serial.print(“Air Quality: POOR – “);

    Serial.println(airQValue);

    myservo.write(90);

    delay(500);

  }else if (airQValue < 250){

    Serial.print(“Air Quality: GOOD – “);

    Serial.println(airQValue);

    myservo.write(0);

    delay(500);

  }else{

    Serial.print(“Air Quality Control – “);

    Serial.println(airQValue);

  }

  lightValue = analogRead(lightSensor);

  if (lightValue < 100) {

    Serial.print(“PARTY TIME – “);

    Serial.println(lightValue);

    u8x8.setFont(u8x8_font_courB18_2x3_r);

    u8x8.setCursor(0, 2);

    u8x8.print(” PARTY”);

    rainbow(1);

    delay(500);

  } else {

    Serial.print(“WORK MODE – “);

    Serial.println(lightValue);

    pixels.clear();

    pixels.show();

    u8x8.setFont(u8x8_font_courB18_2x3_r);

    u8x8.setCursor(0, 2);

    u8x8.print(”  WORK “);

    delay(500);

  }

}

void rainbow(int wait) {

  for (long firstPixelHue = 0; firstPixelHue < 5 * 65536; firstPixelHue += 256) {

    for (int i = 0; i < pixels.numPixels(); i++) {

      int pixelHue = firstPixelHue + (i * 65536L / pixels.numPixels());

      pixels.setPixelColor(i, pixels.gamma32(pixels.ColorHSV(pixelHue)));

    }

    pixels.show();

    delay(wait);

  }

}

Video