from machine import Pin, I2C,Timer
import time
from hcsr04 import HCSR04
from lcd_api import LcdApi
from i2c_lcd import I2cLcd
from oled import I2C as oled_driver
button = Pin(23,Pin.IN,Pin.PULL_UP)
button2 = Pin(19,Pin.IN,Pin.PULL_UP)
debounce_delay = 50
button_presses = 0
second_button_presses = 0
MAX_BUTTON_PRESS = 5
# I2C Pin setup for ESP32
i2c_freq = 400000
i2c = I2C(0,scl=Pin(22), sda=Pin(21), freq=i2c_freq)
# LCD setup for ESP32
I2C_ADDR = i2c.scan()[0]
totalRows = 2
totalColumns = 16
lcd = I2cLcd(i2c, I2C_ADDR, totalRows, totalColumns)
oled = oled_driver(128,64,i2c,i2c.scan()[1])
# Ultrasonic Sensor setup
ultra = HCSR04(25,26)
#Button Setup
def handle_button_press_tmr(tmr):
global button_presses
tmr.deinit()
if button.value() == 0:
button_presses = (button_presses + 1)
if button_presses == MAX_BUTTON_PRESS:
button_presses = 1
def handle_second_button_press_tmr(tmr):
global second_button_presses
tmr.deinit()
if button2.value() == 0:
second_button_presses = (second_button_presses + 1)
if second_button_presses == 3:
second_button_presses = 1
def handle_button_press_intr(pin):
tmr = Timer(-1)
tmr.init(mode=Timer.ONE_SHOT, period=debounce_delay, callback=handle_button_press_tmr)
def handle_second_button_press(pin):
tmr = Timer(-1)
tmr.init(mode=Timer.ONE_SHOT, period=debounce_delay, callback=handle_second_button_press_tmr)
def measure_distance():
# Return the distance in cm
return ultra.distance_cm()
def display_distance(distance):
# Display distance on LCD
lcd.clear()
lcd.putstr("Distance:{_distance:.3f}".format(_distance=distance))
def display_oled(distance):
oled.clear()
if distance < 70:
oled.text('Warning',10,3)
else:
oled.text('Safe',10,3)
oled.show()
displayed_string = ''
def display_string(to_display):
global displayed_string
if to_display == displayed_string:
return
lcd.clear()
lcd.putstr(to_display)
displayed_string = to_display
def set_i2c_freq(freq):
global i2c_freq,i2c,lcd,oled
if i2c_freq != freq:
i2c_freq = freq
address = i2c.scan()
i2c = I2C(0,scl=Pin(22), sda=Pin(21), freq=i2c_freq)
lcd = I2cLcd(i2c, address[0], totalRows, totalColumns)
oled = oled_driver(128,64,i2c,address[1])
def main():
button.irq(handler = handle_button_press_intr,trigger = Pin.IRQ_FALLING | Pin.IRQ_RISING)
button2.irq(handler = handle_second_button_press,trigger = Pin.IRQ_FALLING | Pin.IRQ_RISING)
global button_presses,second_button_presses
while True:
# Keep the main functionality running
if button_presses == 0:
display_string('Press Button to Start')
elif button_presses == 1:
display_distance(measure_distance())
elif button_presses == 2:
display_string('DECI Students')
time.sleep(1)
display_string('Embedded Systems')
elif button_presses == 3:
distance = measure_distance()
if distance < 50:
display_string('Too Close')
elif 50 < distance < 100 :
display_string('Keep Distance')
elif distance > 100:
display_string('Safe')
elif button_presses == 4:
display_string(f'LCD Address {I2C_ADDR}')
if second_button_presses == 1:
set_i2c_freq(40000)
elif second_button_presses == 2:
set_i2c_freq(4000)
elif second_button_presses == 3:
set_i2c_freq(1000)
elif second_button_presses == 0:
set_i2c_freq(400000)
print(second_button_presses)
display_oled(measure_distance())
time.sleep(1)
if __name__ == "__main__":
main()