Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
Alan Wang
Published © CC BY-NC-SA

Simple MicroPython IoT Smart Home (ESP8266)

Convert a DIY miniature wooden house into a ESP8266 IoT smart home with WiFi sensor data logging.

BeginnerShowcase (no instructions)7,939
Simple MicroPython IoT Smart Home (ESP8266)

Things used in this project

Hardware components

NodeMCU ESP8266 Breakout Board
NodeMCU ESP8266 Breakout Board
×1
I2C 16x2 Arduino LCD Display Module
DFRobot I2C 16x2 Arduino LCD Display Module
×1
BH1750 (GY-30 or GY-302)
×1
Ultrasonic Sensor - HC-SR04 (Generic)
Ultrasonic Sensor - HC-SR04 (Generic)
×1
6 DOF Sensor - MPU6050
DFRobot 6 DOF Sensor - MPU6050
×1
DHT22 Temperature Sensor
DHT22 Temperature Sensor
×1
Gravity: Analog Gas Sensor (MQ2) For Arduino
DFRobot Gravity: Analog Gas Sensor (MQ2) For Arduino
×1
Gravity: Digital 5A Relay Module
DFRobot Gravity: Digital 5A Relay Module
×1
5 mm LED: Red
5 mm LED: Red
×1
Resistor 220 ohm
Resistor 220 ohm
×4
Jumper wires (generic)
Jumper wires (generic)
×1
Breadboard (generic)
Breadboard (generic)
×1

Software apps and online services

MicroPython
MicroPython

Story

Read more

Code

Simple MicroPython IoT smart home

MicroPython
# MicroPython Smart Home on ESP8266 (NodeMCU V3)
# LCD1602: https://github.com/dhylands/python_lcd
# MPU6050: https://github.com/adamjezek98/MPU6050-ESP8266-MicroPython
# BH1750: https://github.com/catdog2/mpy_bh1750fvi_esp8266
# HC-SR04: https://github.com/rsc1975/micropython-hcsr04
import network, urequests, machine, math, utime, dht, bh1750fvi, mpu6050
from machine import Pin, I2C, ADC
from esp8266_i2c_lcd import I2cLcd
from hcsr04 import HCSR04


# user data
ssid = "your_wifi_ssid" # input your wifi SSID
pw = "wour_wifi_pw" # input your wifi password
ifttt_event = "your_ifttt_event_name" # input your IFTTT webhook event
ifttt_api_key = "your_ifttt_api_key" # input your IFTTT webhook API key
ifttt_enabled = True
update_delay = 10000
display_delay = 2000
lcd_lightup_distance = 100
alarm_angle = 3.0


# I2C (D1=Pin5=SCL, D2=Pin4=SDA): LCD1602, BH1750, MPU6050
# D3=Pin0: active piezo buzzer (triggered with LOW voltage)
# D4=Pin2: LED
# D5=Pin14: DHT22
# D6=Pin13: relay (to power up the DHT22 properly)
# D7=Pin13/D8=Pin15: HCSR04
# A0=ADC0: MQ2
i2c = I2C(scl=Pin(5), sda=Pin(4))
lcd1602 = I2cLcd(i2c, 0x27, 2, 16)
mpu6050 = mpu6050.accel(i2c)
buzzer = Pin(0, Pin.OUT)
buzzer.value(1)
led = Pin(2, Pin.OUT)
dht22 = dht.DHT22(Pin(14))
dht22_power = Pin(12, Pin.OUT)
dht22_power.value(1)
sonar = HCSR04(trigger_pin=13, echo_pin=15)
mq2 = ADC(0)


def lcd_clear():
    lcd1602.move_to(0, 0)
    lcd1602.putstr(" " * 32)

def lcd_show(text, line):
    lcd1602.move_to(0, line)
    lcd1602.putstr(text)

def mpu6050_read(target):
    return mpu6050.get_values()[target]

def mpu6050_pitch():
    return 57.3 * math.atan2(mpu6050_read('AcY') / 16384.0,
                             math.sqrt(math.pow(mpu6050_read('AcX') / 16384.0, 2) + math.pow(mpu6050_read('AcZ') / 16384.0, 2)))

def mpu6050_row():
    return 57.3 * math.atan2(mpu6050_read('AcX') / 16384.0,
                             math.sqrt(math.pow(mpu6050_read('AcY') / 16384.0, 2) + math.pow(mpu6050_read('AcZ') / 16384.0, 2)))

def bh1750_read():
    return bh1750fvi.sample(i2c)

def buzzer_on():
    buzzer.value(0)
    led.on()

def buzzer_off():
    buzzer.value(1)
    led.off()


# wait a bit and power up the DHT22
utime.sleep_ms(100)
dht22_power.value(0)


# connect to wifi
wifi = network.WLAN(network.STA_IF)
wifi.active(True)
wifi.connect(ssid, pw)

lcd_clear()
lcd_show("Connecting to", 0)
lcd_show(" WiFi...", 1)
print("Connecting to WiFi...")

while not wifi.isconnected():
    pass

lcd_clear()
lcd_show("WiFi Connected.", 0)
lcd_show(" Initializing...", 1)
print("WiFi Connected.")


# setup timestamps
sensor_read_time = utime.ticks_ms() - update_delay
display_time = utime.ticks_ms() - display_delay
temperature = 0.0
humidity = 0.0
    
    
# main loop
while True:
    
    distance = sonar.distance_cm()
    pitch = mpu6050_pitch()
    roll = mpu6050_row()
    mq2_value = mq2.read()
    alarm = False
    
    
    if 2 <= distance <= lcd_lightup_distance:
        lcd1602.backlight_on()
    else:
        lcd1602.backlight_off()
    
    if abs(pitch) >= alarm_angle or abs(roll) >= alarm_angle:
        alarm = True
        print("Alarm triggered! Pitch: " + str(round(pitch, 2)) + "* / roll: " + str(round(roll, 2)) + "*")
        buzzer_on()
    
    if mq2_value >= alarm_smoke:
        alarm = True
        print("Alarm triggered! Smoke reading over " + str(alarm_smoke))
        buzzer_on()
        
    if not alarm:
        buzzer_off()
    
    
    if utime.ticks_ms() - display_time >= display_delay:
        
        light = bh1750_read()
        mq2_value = mq2.read()
        
        try:
            
            dht22.measure()
            temperature = dht22.temperature()
            humidity = dht22.humidity()
            
        except:
            
            temperature = 0.0
            humidity = 0.0
            print("DHT22 read error!")
        
        if not (temperature == 0.0 and humidity == 0.0):
            
            lcd_clear()
            lcd_show("{:^16}".format("T: {:3.1f}".format(temperature) + " H: {:3.1f}".format(humidity)), 0)
            lcd_show("{:^16}".format("L: " + str(light) + " Q: " + str(mq2_value)), 1)
            print("Sensor output: Temp: {0}*C, Humid: {1}%, Light: {2} lux, MQ2: {3}/1023".format(temperature, humidity, light, mq2_value))
            
            if ifttt_enabled and (utime.ticks_ms() - sensor_read_time >= update_delay):
                
                if wifi.isconnected():
                    
                    url = "http://maker.ifttt.com/trigger/" + ifttt_event + "/with/key/" + ifttt_api_key
                    url += "?value1=" + str(temperature)
                    url += "&value2=" + str(humidity)
                    url += "&value3=" + str(mq2_value)
                    
                    led.on()
                    response = urequests.get(url)
                    
                    if not alarm:
                        led.off()
                    if response.status_code == 200:
                        print("-- IFTTT updated successfully")
                    else:
                        print("-- IFTTT update failed:")
                        print(response.text)
                    
                else:
                    lcd_clear()
                    lcd_show("WiFi lost.", 0)
                    lcd_show(" Rebooting...", 1)
                    print("WiFi connection lost. Rebooting...")
                    utime.sleep(1)
                    machine.reset()
                    
                sensor_read_time = utime.ticks_ms()
            display_time = utime.ticks_ms()
    
    
    utime.sleep_ms(250)

Credits

Alan Wang

Alan Wang

32 projects • 102 followers
Please do not ask me for free help for school or company projects. My time is not open sourced and you cannot buy it with free compliments.

Comments