from machine import Pin, SoftI2C, ADC, PWM
from servo import Servo
import dht
import math
import time
from lcd_api import LcdApi
from i2c_lcd import I2cLcd
import wifi
from umqtt.simple import MQTTClient
import uasyncio as asyncio
################################ Mo ta thiet bi
# relay dieu khien hoat dong may bom nuoc/may bom dung dich phan bon
# phần máy bơm hoạt động luân phiên đang bị auto hoạt động và chưa có biện pháp ngắt nguồn
# servo dieu khien mai che nang
# LRD la cam bien anh sang (cai mau xanh xanh nam tren breadboard)
# LRD -> servo
# cam bien do am dat la chip custom mau xanh luc o duoi
# nut bam thuc hien dieu khien thu cong
################################
#cam bien nhiet do, do am
sensor = dht.DHT22(Pin(14))
h = -1
################################
#man hinh led
I2C_ADDR = 0x27
totalRow = 4
totalColumns = 20
i2c = SoftI2C(scl = Pin(22), sda = Pin(21), freq = 10000) #initializing I2C method for ESP32
lcd = I2cLcd(i2c, I2C_ADDR, totalRow, totalColumns)
lcd.putstr("Hello")
time.sleep(1)
# lcd.clear()
################################
#cam bien anh sang
#muc anh sang khong tot: direct sunlight (>30,000 lux)
led1 = Pin(26, Pin.OUT)
led2 = Pin(25, Pin.OUT)
adc = ADC(Pin(32))
atten_value = ADC.ATTN_11DB
adc.atten(atten_value)
rl10 = 50000 # LDR resistance at 10lux
gamma = 0.7 # log(R) / log(lux)
#tinh quang tro
def calculate_resistance():
value = adc.read()
voltage_ratio = value / (4095 - value)
return 10000 * voltage_ratio
#R = R_10 * (lux / 10) ^ -γ => lux = 10 * (R / R_10) ^ -1/γ
#tinh lux
def calculate_lux(resistance):
return 10 * math.pow(resistance / (rl10), -1 / gamma)
################################
#servo
motor = Servo(pin = 23)
# motor.move(n) # quay n°
servAngle = 0
################################
#relay
#relay led đỏ bơm nước tưới
#relay led vàng bơm dung dịch phân bón
waterRelay = Pin(25, Pin.OUT) # nước
fertilizerRelay = Pin(26, Pin.OUT) # phân bón
# relay.off cổng COM kết nối NC
# relay.on cổng COM kết nối NO
# relay.on()
################################
#soil_sensor_chip
# khoảng giá trị đầu ra 350-1024
# 350 là có nước, 1024 là không có nước
# cách dùng: soilMois.read()
soilMois = ADC(Pin(34))
soilMois.atten(ADC.ATTN_11DB)
#test button
button = Pin(4, Pin.OUT)
################################
# Khai báo biến đo lường
t = -1 #nhiệt độ
h = -1 #độ ẩm
lux = -1 #ánh sáng
soilMoisterValue = -1
countingTime = -1
#Các mảng này để lưu trữ và tính giá trị trung bình trong một khoảng thời gian
t_stack = []
h_stack = []
lux_stack = []
# Hàm khởi động máy bơm tưới nước
def watering(duration):
waterRelay.on();
time.sleep(duration)
waterRelay.off()
#################################
# Setting wifi và liên kết đến mqtt
wifi.connect_ap()
#MQTT
client_id = "720e81de16ff4f6786bbed0c1da73392.s2.eu.hivemq.cloud"
server = "broker.hivemq.com"
client = MQTTClient(client_id, server)
client.connect()
#ThinkSpeak
client_id1 = "CQAfHRwVKCMuDy8FGh8VHDs"
user_name1 = "CQAfHRwVKCMuDy8FGh8VHDs"
password1 = "iTtNunL32EtXNrMKsSudXmAB"
server1 = "mqtt3.thingspeak.com"
client1 = MQTTClient(client_id = client_id1, server =server1, user=user_name1, password=password1)
client1.connect()
publish_topic = b"channels/2384358/publish"
motor.move(0)
while True:
# Nhận tín hiệu nút bấm từ MQTT sau đó GÁN LẠI VÀO CÁC BIẾN DƯỚI ĐÂY
# Code here...........
# Kết nối MQTT api
# Các biến để bắt message
# msgWhite = ......
# msgRed = ......
# msgYellow = ......
# msgGreen = ......
if msgWhite == "white_0":
Manual_Flag = True
if msgRed == "red_0"
red_button_pushed = True
if msgRed == "red_0"
red_button_pushed = True
if msgRed == "red_0"
red_button_pushed = True
# Manual_Flag dùng để chọn chế độ tự động hoặc thủ công
# Nếu nút white được bấm thì gán Manual_Flag = True, ngược lại gán False
# Tương tự với các nút khác
# Manual_Flag = Trues
red_button_pushed = True
yellow_button_pushed = True
green_button_pushed = True
##################################
countingTime = -1
# Bộ đếm giây
countingTime += 1
# print(countingTime)
time.sleep(1)
#Kiểm tra trạng thái tưới tưới
isWatered = False
#reset bộ đếm sau mỗi 24h
if countingTime > 24*60*60:
countingTime = 0
# Đo sau mỗi 5 giây
if countingTime % 5 == 0:
# đo từ cảm biến nhiệt độ, độ ẩm
sensor.measure()
t = sensor.temperature()
h = sensor.humidity()
#Lưu giá trị đo lường vào stack
t_stack.append(t)
h_stack.append(h)
# Đo giá trị ánh sáng, đất
lux = calculate_lux(calculate_resistance()) # đo độ sáng
print(lux)
lux_stack.append(lux) #Lưu vào stack
soilMoisterValue = soilMois.read() #đo độ ẩm đất
#Hiển thị lên led
lcd.clear()
lcd.putstr(f"Temp: {t}\n")
lcd.putstr(f"Humid: {h}\n")
lcd.putstr(f"Lux: {lux}\n")
lcd.putstr(f"SoilMois: {soilMoisterValue}\n")
#gửi dữ liệu và hiển thị biểu đồ lên ThinkSpeak và MQTT
print("Send data to broker")
client.publish("IoT_MQTT_TemperatureA", str(t))
client.publish("IoT_MQTT_HumidityA", str(h))
client.publish("IoT_MQTT_LuxA", str(lux))
client.publish("IoT_MQTT_SoilMoisterA", str(soilMoisterValue))
payload = f"field1={t}&field2={h}&field3={lux}&field4={soilMoisterValue}&status=MQTTPUBLISH"
client1.publish(publish_topic,payload.encode("utf-8"))
if countingTime % (10*60) == 0: # Xử lí dữ liệu nhiệt độ, độ ẩm sau mỗi 10p
tempAverage = sum(t_stack)/len(t_stack)
humidAverage = sum(h_stack)/len(h_stack)
# isWatered = False
# print(tempAverage)
# print(humidAverage)
# Gửi dữ liệu nhiệt độ, độ ẩm trung bình (tempAverage, humidAverage) trong 10p vừa rồi lên mqtt/thingspeak/ifttt
# Code here......................
if Manual_Flag == False:
#Khởi động máy bơm nước để tưới khi nhiệt độ > 40
if (tempAverage > 40 or humidAverage < 15) and isWatered == False:
watering(10) #Hàm định nghĩa ở trên
countingTime += 10
isWatered = True
else:
if red_button_pushed == True:
waterRelay.on()
else:
waterRelay.off()
t_stack.clear()
h_stack.clear()
if countingTime % (60*60) == 0: #Xử lí dữ liệu ánh sáng sau mỗi 1h
luxAverage = sum(lux_stack)/len(lux_stack)
# print(luxAverage)
# Gửi dữ liệu ánh sáng trung bình (luxAverage) trong 1h vừa rồi lên MQTT/ThingSpeak
# Code here.............
if Manual_Flag == False:
# Đóng màn che nắng khi chỉ số ánh sáng vượt 30.000 lux
if (luxAverage > 30000):
motor.move(180)
print("Đóng màn che")
else:
motor.move(0)
print("Mở màn che")
else:
if green_button_pushed == True:
motor.move(0)
print("Đóng màn che")
else:
print("Mở màn che")
motor.move(180)
lux_stack.clear()
if countingTime % (12*60*60) == 0: #Xử lí dữ liệu cảm biến đất sau mỗi 12h
#Gửi dữ liệu đất hiện tại (soilMoisterValue) lên MQTT, ThingSpeak
# Code here........................
#Tưới nước khi độ ẩm đất và không khí quá thấp
if Manual_Flag == False:
if (soilMoisterValue > 1020 and humidity < 15) and isWatered == False:
watering(10)
countingTime += 10
isWatered = True
else:
if red_button_pushed == True:
waterRelay.on()
else:
waterRelay.off()
#Khởi động máy bơm phân bón
if Manual_Flag == True and yellow_button_pushed == True:
fertilizerRelay.on()
else:
fertilizerRelay.off()