Skip to content



Final Project

My project is an essential prodect that every parent shoud have in their baby’s room. I was inspired to make this project by the fact that me and my wife are expecting our first child by the end of this year 2021. So this product can be hanged on the wall and it monitor the vital enviromental parameters in the baby’s room. The 5 parameters are:

  1. Room temperature.
  2. Air humidity.
  3. unhealthy gases.
  4. Air pressure.
  5. altitude.


Brainstorming and Research

I started First by Brainstorming and sketching how it will look like and what it will do.



then I started reseaching on Projects with similar Ideas to ne inspired from. I foud this project on insttuctables where they use a Sensor called BME680 to measure the 5 parameters I’m interested in:

  1. Room temperature.
  2. Air humidity.
  3. unhealthy gases.
  4. Air pressure.
  5. altitude.

then I also found this project where they are using a speaker with an Arduino and using Text to speeech (TTS) method to make the arduino talk.

also, I found through my research how to use I2C OLED with only 4 oins needed!

Lastly, I though of Adding an RGB light for warning purposes and I found this NEOPIXEL Guide to understand how to program an RGB with only 3 pins which is cool.


Project Requirements.


Materials:

the materials I require for building the device case and its accessories:

  1. PLA filament: for building the major case.
  2. Acrylic Sheet: for buiding the sensor and oled protection covers.
  3. Vynil Stickers: for branding.

Components:

Inputs:

  1. BME 680 MultiSensor.

Outputs:

  1. I2 OLED creen..

  2. rechargeable Speaker.

  3. NEOPIXEL RGB Light.

Controlling & Connection & Powering

  1. Micro controller.
  2. FTDI Cable.
  3. Wires.
  4. Battery.

machine Requirements.

  1. 3D Printer.
  2. CNC Milling Machine.
  3. Laser Cutter.
  4. Vynil Cutter.
  5. Soldering Kit.

ELectronic Design.

I design on Eagle a similar Atmega 328p Board to my previous one but with some changes:




  • I made the board smaller and put the FTDI pins nearer to the edge.

  • 2 pins connected to SCL and 2 Pins connected to SDA.

  • 5 digital pins and 4 analog pins.

  • 6 avaliable VCC pins and 7 GND.

  • 4 3mm holes in the corners to fix the board in the device case.

Then I exported the Gerber and Excellon files to flat cam to prepare the file for CNC milling.



Electronic Production.

I used a Ronald SRM-20 Milling Machine to mill the PCB board.





and the Board looks like this after milling.



then I soldered the SMD components as following:




Coding.

First I connected all the Inputs and outputs to the board as shown in the picture Below:



  • Speaker is connected to Pin 3 and GND.

  • OLED is connected to SCL, SDA, VCC and GND.

  • Sensor is Connected to SCL, SDA, VCC and GND.

  • RGB is connected to Pin 10, VCC and GND.

Then I Downloaded Several Libraries to Arduino IDE from the Libraries searching option to be able to program all like:

  • FastLED.

  • adafruit BME680.

  • Takie.

  • adafruit NEOPIXEL.

After that I started coding and testing till I reach the final code as shown here :


#include <FastLED.h>

#define NUM_LEDS  1
#define LED_PIN   10

CRGB leds[NUM_LEDS];

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#include <Arduino.h>
#include "Talkie.h"
#include "Vocab_US_Large.h"
#include "Vocab_Special.h"

Talkie voice;


#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME680 bme;

const uint8_t spTEMP[] PROGMEM = {0x0A,0x38,0xDE,0x32,0x00,0x2F,0xBB,0x37,0xBF,0x59,0x57,0x76,0x6F,0xB8,0xB2,0x16,0xCA,0xC4,0x75,0xCB,0x4A,0xAB,0x4A,0xF3,0xF6,0xCD,0x2B,0x2D,0x66,0x94,0xD7,0xBA,0xB4,0x34,0x79,0x93,0x52,0x97,0x16,0xB2,0x28,0x5B,0x4D,0x43,0x36,0x10,0x20,0xAB,0xB2,0x52,0xC4,0x26,0x9A,0x26,0x49,0x47,0x9B,0x1B,0xA5,0xA6,0x74,0x5D,0x43,0xF1,0x65,0x14,0x91,0xAD,0xED,0xB5,0x99,0xB1,0x69,0x1A,0x20,0xC0,0x0A,0x84,0x0E,0xD8,0xD3,0x23,0x01,0xA3,0x4C,0x1A,0xA0,0xF5,0xC9,0xD6,0x95,0xE0,0x24,0x1D,0xD9,0x5A,0x9B,0x9C,0x8B,0xAE,0x79,0x2B,0x43,0xAC,0xA6,0xDE,0x9C,0x35,0x9D,0xB1,0xB3,0x47,0x52,0xD7,0x74,0xC6,0x2E,0x52,0xA1,0x5E,0xC2,0x1D,0x3B,0xEB,0xB8,0x65,0x0D,0x5F,0xAA,0x26,0xB6,0xE2,0x35,0x7C,0xA9,0x2A,0xFB,0x6A,0x16,0xF7,0xE7,0x9E,0x4C,0xEB,0xD9,0xFE,0x1F};
const uint8_t spIS[] PROGMEM = {0xA3,0xED,0xC6,0x30,0x3D,0x57,0xAD,0x7E,0xA8,0x42,0xA9,0x5C,0xB5,0xFA,0xA9,0x8A,0xB8,0x62,0xF3,0xEA,0x86,0x48,0xE6,0x8A,0x57,0xAB,0xEB,0x22,0x58,0x23,0x5E,0xAF,0xAE,0xCA,0x64,0xF5,0x7C,0x3C,0xBA,0xCA,0x93,0xD5,0xE3,0x76,0xEB,0x3B,0x4E,0x55,0xB3,0x4D,0x65,0xB8,0x58,0x5D,0xDD,0x72,0x97,0xE9,0x1B,0x55,0x27,0x4D,0xD3,0xE6,0x85,0xD5,0x4D,0x3D,0x6B,0xF9,0x5F,0x50,0x1B,0x26,0x27,0x0A,0xF8,0xAD,0x54,0x01,0xBF,0xBA,0x0B,0xE0,0xA7,0xF4,0xFF,0x07};
const uint8_t spHIGH[] PROGMEM = {0x28,0x5A,0x1C,0x01,0x45,0x7B,0x94,0x32,0x87,0xB0,0x32,0x8E,0xB2,0xF2,0xE4,0xC6,0x33,0x65,0xF6,0xCA,0x53,0x68,0x8F,0xD4,0xC5,0xAB,0x48,0xA9,0x22,0xDD,0x17,0xAD,0x32,0xD5,0xF4,0x74,0x5F,0xBC,0xBA,0x1C,0xCB,0x32,0x74,0xF1,0x1A,0x8A,0x6F,0x8B,0xD4,0xC5,0x6B,0xAD,0xAE,0xCD,0x4B,0x17,0xAF,0xA3,0xBA,0x56,0x2F,0x7D,0x34,0xEE,0xEA,0x5A,0xAC,0x6D,0x51,0x7B,0x9A,0x6D,0xF1,0xD2,0x47,0xFD,0x2D,0x6F,0xD1,0x21,0x33,0xF9,0x30,0x7D,0x2D,0x88,0x74,0xD4,0xE4,0xF4,0x57,0xAF,0x34,0xD5,0x93,0xD2,0xDF,0x82,0x61,0x76,0xCF,0xFE,0x7F};
const uint8_t spPRESSURE[] PROGMEM = {0x06,0x28,0xC1,0x4C,0x03,0x2D,0x49,0x59,0x4A,0x9A,0x3D,0x9F,0xAC,0x04,0x2D,0x2D,0x69,0x73,0xB2,0x56,0x4C,0x43,0x6D,0xF5,0xCD,0x5A,0x3E,0x6A,0x89,0x09,0x65,0x71,0xC0,0xAA,0xDB,0x1E,0x88,0x40,0x04,0x46,0xDF,0x63,0x0A,0x9A,0x65,0x1D,0x43,0xC9,0x49,0x5C,0xE1,0x7D,0xCF,0x7B,0x9F,0x47,0xB9,0xCA,0x12,0xF6,0xD6,0x3C,0xF9,0x8B,0x9F,0xFD,0xFF,0x1F};
const uint8_t spGAS[] PROGMEM = {0x01,0x28,0xD6,0xC4,0x00,0x39,0x08,0x8D,0xAA,0x44,0x97,0xD2,0x98,0xBC,0xBA,0x12,0x43,0x22,0x7D,0xF6,0x9A,0xAA,0x2D,0xD3,0xB6,0xC5,0x6B,0xAD,0xAE,0xCC,0xCA,0x56,0xAF,0xAD,0xDA,0x32,0x2F,0x7B,0xBD,0x8E,0xEA,0xCB,0xAC,0x6C,0xF1,0x38,0xAA,0x2F,0x8D,0xF4,0xC7,0xED,0xAE,0x3E,0xAD,0xD4,0x67,0xF7,0x3B,0xBD,0xB5,0x58,0x99,0x74,0x13,0xF3,0x95,0x6D,0x21,0x92,0xB1,0x19,0x50,0x85,0x0B,0x03,0x9A,0x4F,0x21,0x40,0x2B,0x6D,0x02,0x68,0x3A,0xED,0xFF,0x01};
const uint8_t spLEVEL[] PROGMEM = {0x69,0xAB,0xC4,0xB3,0xD8,0x92,0x86,0x2D,0x83,0xEE,0x60,0xCD,0x12,0xD6,0x0C,0x66,0x45,0x2C,0x73,0x58,0x0B,0xA8,0x53,0xD6,0xAC,0x6D,0xE9,0xC0,0x57,0xC5,0xB2,0xAE,0xA1,0xB0,0x49,0x0D,0x7B,0xBD,0x86,0xA2,0x47,0x35,0xE3,0xF5,0xEA,0xB2,0x4B,0x4B,0xCB,0xC7,0xA3,0xCD,0xDE,0x23,0x59,0x1A,0x9A,0x31,0x8B,0xB0,0x54,0x76,0xE3,0xC6,0x26,0x5C,0x2C,0xCC,0x76,0x6B,0x92,0xBC,0x34,0x95,0xC6,0xA3,0xCE,0x74,0xDB,0x85,0x3B,0x8F,0xBA,0x90,0x9C,0x51,0xCC,0xD6,0xEA,0x4C,0x63,0x56,0x30,0x6D,0xA9,0x23,0xCF,0x59,0xD0,0x34,0xB5,0xF9,0x7F};


void setup() {

 delay (5000);
bme.gas_resistance = 60000;

   FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(200);
   leds[0] = CRGB::Black;
  FastLED.show();

  #if defined(TEENSYDUINO)
    pinMode(3, OUTPUT);
    digitalWrite(3, HIGH); //Enable Amplified PROP shield
#endif

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
   display.display();
  delay(100);
  display.clearDisplay();
  display.display();
  Serial.begin(9600);
    display.setTextSize(2);
  display.setTextColor(WHITE);
  while (!Serial);
  Serial.println(F("BME680 test"));

  if (!bme.begin()) {
    Serial.println("Could not find a valid BME680 sensor, check wiring!");
    while (1);
  }


  bme.setTemperatureOversampling(BME680_OS_8X);
  bme.setHumidityOversampling(BME680_OS_2X);
  bme.setPressureOversampling(BME680_OS_4X);
  bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
  bme.setGasHeater(320, 150); // 320*C for 150 ms
}

void loop() {


  if (bme.temperature >= 27) {

      display.setCursor(0,0);

      display.print("Temp=");
      display.print(bme.temperature);
      display.print("*C");
       display.display();
       delay(100);
       display.clearDisplay();
       voice.say(spTEMP);
       delay (50);
       voice.say(spIS);
       delay (50);
       voice.say(spHIGH);

      leds[0] = CRGB::Green;
      FastLED.show();
      delay(1000);

      leds[0] = CRGB::Black;
      FastLED.show();
      delay(200);


}
else if(0.01*bme.pressure >= 2000) {


      display.setCursor(0,0);

       display.print("Pressure= ");
       display.print(bme.pressure / 100.0);
       display.print("hPa");
       display.display();
       delay(200);

       display.clearDisplay();
        voice.say(spPRESSURE);
       delay (50);
       voice.say(spLEVEL);
       delay (50);  
       voice.say(spIS);
       delay (50);
       voice.say(spHIGH);

       leds[0] = CRGB::Green;
       FastLED.show();
       delay(2000);

       leds[0] = CRGB::Black;
       FastLED.show();
       delay(200);
       delay (50);

}
else if(bme.gas_resistance <= 35000) {


      display.setCursor(0,0);

        display.print("Gas=");
      display.print(bme.gas_resistance /1000.0);
      display.print("KOhms");
       display.display();
       delay(100);
       display.clearDisplay();

        voice.say(spGAS);
        delay (50);
        voice.say(spLEVEL);
        delay (50);  
        voice.say(spIS);
        delay (50);
        voice.say(spHIGH);

        leds[0] = CRGB::Green;
        FastLED.show();
        delay(2000);

       leds[0] = CRGB::Black;
       FastLED.show();
       delay(200);
       delay (50);

}





else if(0.01*bme.pressure < 2000 && bme.gas_resistance > 35000 && bme.temperature < 27){

        leds[0] = CRGB::Red;
        FastLED.show();

        display.setCursor(0,0);

        display.print("Temp=");
        display.print(bme.temperature);
        display.print("*C");
        display.display();
        delay(2000);
        display.clearDisplay();

       display.setCursor(0,0);
       display.print("Pressure= ");
       display.print(bme.pressure / 100.0);
       display.print("hPa");
       display.display();
       delay(2000);
       display.clearDisplay();

       display.setCursor(0,0);
       display.print("Humidity=");
       display.print(bme.humidity);
       display.print("%");
      display.display();
      delay(2000);
      display.clearDisplay();

      display.setCursor(0,0);
      display.print("Gas=");
      display.print(bme.gas_resistance /1000.0);
      display.print("KOhms");
      display.display();
      delay(2000);
      display.clearDisplay();

      display.setCursor(0,0);
      display.print("Approx.Alt=");
      display.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
      display.print(" m");
      display.display();
      delay(2000);
      display.clearDisplay();


  }
}

CAD Designs.

I designed the case for the Device using eagle and looked like this:



and I design the sensor and OLED protection covers and the sticker for branding on CorelDraw and they looked like this:



Farication device body and accessories.

I 3D printed the case using Ultimaker 3D printer and it looked like this.



and I used laser cutter to cut Acrylic for the sensor and OLED protection covers.



and for the sticker I used vynil cuttter



and the final device after adding all the components looked like this:



Final Project Video and Poster.



BOM

Qty Description Price Source
1 PLA filament 30.00 $ Fablab UAE
1 Acrylic Sheet 00.00 $ USED
1 Vynil Stickers 00.00 $ USED
1 BME 680 MultiSensor. 19.00 $ Fablab UAE
1 I2 OLED screen 18.00 $ Fablab UAE
1 rechargeable Speaker. 00.00 $ Old speaker
1 NEOPIXEL RGB Light. 00.00 $ USED
1 FTDI Cable 10.00 $ Fablab UAE
1 Wires. 02.00 $ Fablab UAE
TOTAL 101.00 $
___

Final thoughts

The result of the project was successful and the 5 parameters were measured correctly and the activated alarm message, light, and screen were triggered correctly then go back to normal every time the threshold was achieved.

I think there is an opening for an improvement by adding a way to connect the device to the parent’s mobile phones which i need to look into more.

the


Files:


Board

Schematic

Code

Case

Senor and Oled Cover

Sticker