import time
import network
import ssd1306
from machine import Pin, I2C
from umqtt.simple import MQTTClient
# Modify wherever the values contain <>
MQTT_BROKER = "broker.hivemq.com"
MQTT_CLIENT_ID = "keypad-<class>-<number in class>-<name>"
MQTT_TOPIC = "elsys/<class>/<number in class>/<name>"
# Keypad constants
ROW_PINS = [12, 14, 27, 26]
COL_PINS = [25, 33, 32]
KEY_MAP = [
['1', '2', '3'],\
['4', '5', '6'],\
['7', '8', '9'],\
['*', '0', '#']
]
# Display Constants
DISPLAY_SCL_PIN = 21
DISPLAY_SDA_PIN = 22
DISPLAY_WIDTH = 128
DISPLAY_HEIGHT = 64
# Connect to Wi-Fi
def connect_to_wifi():
print("Connecting to Wi-Fi", end="")
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect('Wokwi-GUEST', '')
while not sta_if.isconnected():
print(".", end="")
time.sleep(0.1)
print(" Connected!")
# Connect to MQTT Broker
def connect_to_mqtt_broker():
connect_to_wifi()
print("Connecting to MQTT server... ", end="")
client.connect()
print("Connected!")
# Read single key press
def read_key(rows, columns):
for index, row in enumerate(rows):
row.value(1)
result = [columns[i].value() for i in range(len(columns))]
row.value(0)
if max(result) == 1:
key = KEY_MAP[int(index)][int(result.index(1))]
return key
return None
# Read full code
def read_code():
key, code = '', ""
while key != '#':
key = read_key(ROW_PINS, COL_PINS)
if key != None:
time.sleep(0.3)
code += key
fill_display(code)
return code
# Publish access code
def publish_code(code):
client.publish(MQTT_TOPIC, code)
fill_display("Published: " + code)
# Fill display
def fill_display(text):
display.fill(0)
display.text(text, 0, 5)
display.show()
# Clear display
def clear_display():
display.fill(0)
display.show()
# Init MQTT client
client = MQTTClient(MQTT_CLIENT_ID, MQTT_BROKER)
connect_to_mqtt_broker()
# Init keypad
for x in range(0, 4):
ROW_PINS[x] = Pin(ROW_PINS[x], Pin.OUT)
ROW_PINS[x].value(0)
for x in range(0, 3):
COL_PINS[x] = Pin(COL_PINS[x], Pin.IN, Pin.PULL_DOWN)
# Init OLED Display
i2c = I2C(0, scl=Pin(DISPLAY_SCL_PIN), sda=Pin(DISPLAY_SDA_PIN))
display = ssd1306.SSD1306_I2C(DISPLAY_WIDTH, DISPLAY_HEIGHT, i2c)
# Loop
try:
while True:
publish_code(read_code())
time.sleep(5)
clear_display()
finally:
client.disconnect()