一、硬件需要用到的材料

首先需要一块树莓派的板子哈,这里我们用到的是Raspberry Pi Zero 2 W。

Raspberry Pi Zero 2 W 的核心是 RP3A0,这是一款由英国 Raspberry Pi 设计的定制系统级封装。Zero 64 配备主频为 53GHz 的四核 1 位 ARM Cortex-A512 处理器和 2MB 的 SDRAM,速度是原始 Raspberry Pi Zero 的五倍。

无线局域网内置于屏蔽外壳中,具有改进的射频合规性,在使用 Raspberry Pi Zero 2 W 进行设计时为您提供更大的灵活性。

所有这些都采用相同的 65 毫米× 30 毫米的微型外形尺寸。

1、通过LM35温度传感器

2、电容式湿度传感器

3、LDR模块来获取土壤的温度、湿度、光敏强度

4、ADS1115模数转换器:

详细请看ADS1115的介绍:



https://blog.csdn.net/2202_75379338/article/details/134357187?spm=1001.2014.3001.5502

5、LCD显示屏(2寸 8引脚)

二、硬件电路连接

1RaspberryPI zero 2W与LCD显示屏

RaspberryPI zero 2W与LCD显示屏接线表

RaspberryPI zero 2W

LCD显示屏

GND

GDN

3.3V

BCM 10(MOSI)

BCM 11(SCLK)

VCC

DIN

CLK

BCM 8(CE0)

CS

BCM 25

DC

BCM 27(PCM_D)

RST

BCM 15(RXD)

BL

2连接RaspberryPI zero 2W与ADS1115

 RaspberryPI zero 2W与ADS1115接线表

RaspberryPI zero 2W

ADS1115

GND

GND

5V

BCM 3(SCL)

BCM 2(SDA)

VCC

SCL

SDA

3连接ADS1115与各传感器

ADS1115与各个传感器接线表

ADS1115

LM35温度传感器

电容式湿度传感器

LDR模块

GND

GND

GDN

GDN

VCC

A1

VCC

Vout

VCC

   

VCC

A2

AUOT

A3

AO

三、代码部分

对RaspberryPI zero 2W和LCD显示屏进行配置的关键部分代码如下:

class RaspberryPi:  
    def __init__(self,spi=spidev.SpiDev(0,0),spi_freq=40000000,rst = 27,dc = 25,bl = 18,bl_freq=1000,i2c=None,i2c_freq=100000):
        import RPi.GPIO
        self.np=np
        self.RST_PIN= rst
        self.DC_PIN = dc
        self.BL_PIN = bl
        self.SPEED  =spi_freq
        self.BL_freq=bl_freq
        self.GPIO = RPi.GPIO
        #self.GPIO.cleanup()  
        self.GPIO.setmode(self.GPIO.BCM)
        self.GPIO.setwarnings(False) 
        self.GPIO.setup(self.RST_PIN,   self.GPIO.OUT)
        self.GPIO.setup(self.DC_PIN,    self.GPIO.OUT)
        self.GPIO.setup(self.BL_PIN,    self.GPIO.OUT)
        self.GPIO.output(self.BL_PIN,   self.GPIO.HIGH)
        #Initialize SPI
        self.SPI = spi
        if self.SPI!=None :
            self.SPI.max_speed_hz = spi_freq
            self.SPI.mode = 0b00

这是一个RaspberryPi类,它用于控制RaspberryPI zero 2W上的SPI和I2C接口,以及控制LCD显示屏的背光、复位和数据/命令选择引脚。在初始化时,它将引脚设置为输出模式,并将SPI和I2C接口初始化。

class LCD_2inch(lcdconfig.RaspberryPi):
    width = 240
    height = 320                                # 设置LCD屏幕的宽度和高度
    def command(self, cmd):
        self.digital_write(self.DC_PIN, self.GPIO.LOW)    # 设置DC引脚为低电平
        self.spi_writebyte([cmd])                       # 通过SPI总线发送命令

这是一个LCD屏幕的驱动程序,用于连接RaspberryPI zero 2W和LCD显示屏。它定义了屏幕的宽度和高度,并实现了一个命令函数,用于向屏幕发送指令。该函数将命令发送给SPI总线,并使用GPIO控制数据/命令引脚。

对RaspberryPI zero 2W和ADS1115进行配置的关键部分代码如下:

import board
import busio
import time
i2c = busio.I2C(board.SCL, board.SDA)
import adafruit_ads1x15.ads1115 as ADS
from adafruit_ads1x15.analog_in import AnalogIn
ads = ADS.ADS1115(i2c)
chan = AnalogIn(ads, ADS.P2)
while True:
    print(chan.value)
time.sleep(0.1)

对ADS1115与各传感器进行配置的关键部分代码如下:

i2c = busio.I2C(board.SCL, board.SDA)
ads = ADS.ADS1115(i2c)
Moisture_channel = AnalogIn(ads, ADS.P2)
LDR_channel = AnalogIn(ads, ADS.P3)
LM35_channel = AnalogIn(ads, ADS.P1)
ADC_16BIT_MAX = 65536
lm35_constant = 10.0/1000
ads_InputRange = 4.096  #For Gain = 1; Otherwise change accordingly
ads_bit_Voltage = (ads_InputRange * 2) / (ADC_16BIT_MAX - 1)

 显示表情相关代码:

while True:
    # Read the specified ADC channels using the previously set gain value.
    LDR_Value = LDR_channel.value
    LDR_Percent = _map(LDR_Value, 22500, 50, 0, 100)
    Moisture_Value = Moisture_channel.value
    Moisture_Percent = _map(Moisture_Value, 31000, 15500, 0, 100)
    ads_ch0 = LM35_channel.value
    ads_Voltage_ch0 = ads_ch0 * ads_bit_Voltage
    Temperature = int(ads_Voltage_ch0 / lm35_constant)
    print("Temperature = ", Temperature)
    print("Light Intensity = ", LDR_Percent)
    print("Moisture % = ", Moisture_Percent)
    if (LDR_Percent < 20):
        if(LowIn_DataSent == 0):
            client.send(bytes('sleep','utf-8'))
            HighIn_DataSent = 0
            LowIn_DataSent = 1
    elif (LDR_Percent > 20):
        if(HighIn_DataSent == 0):
            client.send(bytes('happy','utf-8'))
            HighIn_DataSent = 1
            LowIn_DataSent = 0
    if (Moisture_Percent < 90):
        Moisture_Recent = Moisture_Percent
        if(Thirsty_DataSent == 0):
            client.send(bytes('thirsty','utf-8'))
            Thirsty_DataSent = 1
            Savory_DataSent = 0
            Happy_DataSent = 0
    elif (Moisture_Percent > 100):
        Moisture_Recent = Moisture_Percent
        if(Happy_DataSent == 0):
            client.send(bytes('savory','utf-8'))
            Happy_DataSent = 1
            Savory_DataSent = 0
            Thirsty_DataSent = 0
    if(Temperature>30):
        if(TemperatureDataSent == 0):
            client.send(bytes('hotty','utf-8'))
            TemperatureDataSent = 1
    elif(Temperature<22):
        if(TemperatureDataSent == 0):
            client.send(bytes('freez','utf-8'))
            TemperatureDataSent = 1
    else:
            TemperatureDataSent = 0

当光照强度百分比小于20时,显示屏表现出土壤“sleep”的状态,需要一些光照;当光照强度百分比大于20时,显示屏表现出土壤“happy”的状态,表示植物很健康;当土壤湿度小于90时,显示屏表现出土壤“thirsty”的状态,需要一些水分;当土壤湿度大于100时,显示屏表现出土壤“savory”的状态;当土壤温度高于30摄氏度时,显示屏表现出土壤“hotty”的状态,需要降温;当土壤温度低于22摄氏度时,显示屏表现出土壤“freez”的状态,需要一些温暖。

最终实现代码: 

最终实现程序代码
import os
import sys
import logging
import spidev as SPI
sys.path.append("..")
from lib import LCD_2inch
from PIL import Image,ImageDraw,ImageFont
import socket
# Raspberry Pi pin configuration:
RST = 27
DC = 25
BL = 18
bus = 0
device = 0
logging.basicConfig(level=logging.DEBUG)
directory = os.getcwd()
#Server For Data Reception
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)   #绑定自己的电脑IP地址
server.bind(('192.168.43.137', 8080))   #开启监听
server.listen(5)
doInterrupt = 0
showOn = 0
def show(emotion):
    global doInterrupt, showOn, disp
    try:
        disp = LCD_2inch.LCD_2inch(spi=SPI.SpiDev(bus, device),spi_freq=90000000,rst=RST,dc=DC,bl=BL)
        disp.Init() # Initialize library.
        #disp.clear() # Clear display.
        bg = Image.new("RGB", (disp.width, disp.height), "BLACK")
        draw = ImageDraw.Draw(bg)
        # display with hardware SPI:
        for i in range(180):
            if (doInterrupt==1):
                doInterrupt = 0
                break
            else:
                image = Image.open(directory+'/emotion/'+emotion+'/frame'+str(i)+'.png')	
                image = image.rotate(180)
                disp.ShowImage(image)
        showOn = 0
        disp.module_exit()
        logging.info("quit:")
    except IOError as e:
        logging.info(e)
    except KeyboardInterrupt:
        disp.module_exit()
        logging.info("quit:")
        exit()
def main():
    global doInterrupt, showOn
    previousData = 'happy'
    show('happy')
    conn, addr = server.accept()
    conn.settimeout(1000)
    while True:
        try:
            data = conn.recv(1024).decode()
            #print(data)
            if (previousData != data):
                print(data)
                doInterrupt = 1
                previousData = data
                show(data)
        except socket.timeout:
            if showOn!=1:
                show(previousData)
if __name__=='__main__':
    try:
        main()
    except KeyboardInterrupt:
        exit()

更多推荐