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 urequests as requests
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
motor.move(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
#Biến tính giờ
countingTime = -1
#Biến bù giờ bơm nước
additionalTime = 0
#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()
#################################
# Giải thích giá trị nút bấm
# value = 1 là nút chưa được bấm, thiết bị tự động hoạt động bình thường
# value = 0 là nút được bấm, bắt buộc khởi động thiết bị
white = Pin(18, Pin.IN, Pin.PULL_UP) # CHỌN CHẾ ĐỘ ĐIỀU KHIỂN THỦ CÔNG/TỰ ĐỘNG
red = Pin(2, Pin.IN, Pin.PULL_UP) #khởi động máy bơm nước (RELAY CÓ LED ĐỎ)
yellow = Pin(4, Pin.IN, Pin.PULL_UP) #khởi động máy bơm nước (RELAY CÓ LED VÀNG)
green = Pin(5, Pin.IN, Pin.PULL_UP) #khởi động servo mở rèm che
#################################
# Setting wifi và liên kết đến mqtt
wifi.connect_ap()
#MQTT
client_id = "123cdc990fa1480bb6c1abf2ce0a10a0.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"
api_key = "2W0LSN2Q6NMBSSM6"
url1 = "https://api.thingspeak.com/update?api_key={}&field1=".format(api_key)
url2 = "https://api.thingspeak.com/update?api_key={}&field2=".format(api_key)
url3 = "https://api.thingspeak.com/update?api_key={}&field3=".format(api_key)
url4 = "https://api.thingspeak.com/update?api_key={}&field4=".format(api_key)
def send_to_thingspeak(field, data):
try:
# Thực hiện HTTP POST request để gửi dữ liệu lên ThingSpeak
if(field == 'tempAverage'):
response = requests.post(url1 +str(data))
elif(field == 'humidAverage'):
response = requests.post(url2 +str(data))
elif(field == 'luxAverage'):
response = requests.post(url3 +str(data))
elif(field == 'soilMoisterValue'):
response = requests.post(url4 +str(data))
print("Data sent to ThingSpeak. Response:", response.text)
except Exception as e:
print("Error:", e)
while True:
print("white:", white.value())
# print("red:", red.value())
# print("yellow:", yellow.value())
# print("green:", green.value())
# print()
# Nút bật tắt chế độ điều khiển thủ công
if white.value() == 0:
Manual_Flag = True
else:
Manual_Flag = False
# Nút bật máy bơm nước
if red.value() == 0:
red_button_pushed = True
else:
red_button_pushed = False
# Nút bật máy bơm dung dịch phân bón
if yellow.value() == 0:
yellow_button_pushed = True
else:
yellow_button_pushed = False
# Nút bật mở màn che
if green.value() == 0:
green_button_pushed = True
else:
green_button_pushed = False
# 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
##################################
# Bộ đếm giây
countingTime += 1
additionalTime = 0
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)
send_to_thingspeak("tempAverage", tempAverage)
send_to_thingspeak("humidAverage", 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......................
print(countingTime)
print("Send temp and humid data to broker")
client.publish("IoT_MQTT_TemperatureA", str(tempAverage))
client.publish("IoT_MQTT_HumidityA", str(humidAverage))
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:
print(Manual_Flag)
print("Mở máy bơm nước")
watering(10) #Hàm định nghĩa ở trên
additionalTime += 10
isWatered = True
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.............
print("Send lux data to broker")
client.publish("IoT_MQTT_LuxA", str(luxAverage))
send_to_thingspeak("luxAverage", luxAverage)
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")
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 (soilMoisureValue) lên MQTT, ThingSpeak
# Code here........................
print("Send soilMoisterValue data to broker")
client.publish("IoT_MQTT_SoilMoisterA", str(soilMoisterValue))
send_to_thingspeak("soilMoisterValue", soilMoisterValue)
#Tưới nước khi độ ẩm đất và không khí quá thấp
if Manual_Flag == False:
if (soilMoisterValue > 1020 and h < 15): # and isWatered == False:
print("Mở máy bơm nước")
watering(10)
additionalTime += 10
isWatered = True
else:
if red_button_pushed == True:
waterRelay.on()
else:
waterRelay.off()
############################
# Điều khiển thủ công
if Manual_Flag == True:
# Khởi động máy bơm nước
if red_button_pushed == True:
print("Máy bơm nước bật")
waterRelay.on()
else:
print("Máy bơm nước tắt")
waterRelay.off()
#Khởi động máy bơm phân bón
if yellow_button_pushed == True:
print("Máy bơm dung dịch phân bón bật")
fertilizerRelay.on()
else:
print("Máy bơm dung dịch phân bón tắt")
fertilizerRelay.off()
#Đóng mở màn che
if green_button_pushed == True:
motor.move(180)
print("Màn che đóng")
else:
print("Màn che mở")
motor.move(0)
else:
waterRelay.off()
fertilizerRelay.off
motor.move(0)
# Cộng thời gian bù giờ bơm nước
countingTime += additionalTime