树莓派交通灯模拟设备

作为一名电子爱好者,经常在工作台上摆弄各种电子元件。四岁的儿子偶尔会来到工作台,玩弄那些插在面包板上的红色、黄色和绿色LED灯,他称它们为“交通灯”。这启发了,为什么不为他制作一个可以在圣诞节使用的设备呢?

决定为这个设备添加以下功能:

  • 一个可以通过移动应用控制的交通灯,可以模拟交通灯/行人灯的序列,并且可以手动开关。
  • 一些实用的功能,比如一个20字符x4行的屏幕,可以显示:
    • 日期和时间
    • 温度和湿度
    • 由应用控制的消息(2行x20字符)

本教程旨在涵盖以下技术:

  • 使用Python和Flask创建简单的Pi HTTP服务器
  • 在Pi上运行的轻量级SQLite数据库
  • 使用DHT22传感器读取树莓派的温度和湿度
  • 使用带有I2C接口的廉价20x4 LCD显示屏
  • 使用Xamarin创建简单的移动应用,向Pi HTTP服务器发送命令。将使用Xamarin Forms,这是一个非常方便的跨平台(iOS/Android/Windows Mobile)框架。

以下是最终产品,用乐高积木包装,并附有应用。

电路图

由于20x04 LCD需要5V,而树莓派接受3.3V作为数字输入,因此需要一个3.3V/5V逻辑转换器。

使用以下代码:

sudo apt-get install python-dev python-rpi.gpio Adafruit_DHT - 用于读取温度和湿度的库。在树莓派上运行以下命令以安装库。 sudo apt-get update sudo apt-get install build-essential python-dev sudo python setup.py install Install sqlite3 - sqlite是一个非常轻量级的基于文件的SQL数据库。 sudo apt-get install sqlite3

创建数据库文件和表。

sqlite3 weather.db 在sqlite提示符下,创建表: sqlite> CREATE TABLE weather (timestamp DATETIME, temperature REAL, humidity REAL);

安装I2C 2004显示屏所需的工具(或按照此处的详细说明进行操作):

Enable i2C: sudo raspi-config Select “Advanced Options”. Select “I2C”. Select "Yes". Install Utilities: sudo apt-get update sudo apt-get install -y python-smbus i2c-tools Reboot: sudo reboot

按照电路图连接I2C 2004显示屏。运行以下命令找到它的地址。在案例中,得到了0x27。

sudo i2cdetect -y 1

编辑lcd_i2c.py以反映得到的地址:

#for 2004 I2C_ADDR = 0x27

在这个阶段,运行weather.py的所有先决条件现在应该已经准备好了。尝试运行以下命令(需要sudo访问gpio):

sudo python weather.py

如果一切顺利,应该在2004 LCD上看到类似于以下内容,显示日期时间、温度、湿度和IP地址(第3行将显示eth0,第4行将显示wlan0)。

运行weatherwww.py

weatherwww.py是一个Flask Web应用程序。Flask是一个Python框架,允许轻松快速地编写Web服务/动态网页。

要安装Flask,最快的方法是运行以下命令。也可以在virtualenv下运行它:

sudo pip install Flask

要在内置的Flask Web服务器下运行weatherwww.py Web应用程序,请运行以下命令:

cd /home/pi/weather export FLASK_APP=weatherwww.py flask run --host=0.0.0.0

运行上述命令后,它应该显示类似于以下内容:

使用浏览器测试Flask Web应用程序是否正常工作(将192.168.11.115替换为Pi的IP地址)。

如果它返回"OK",则意味着Web应用程序正在运行。如果所有电子设备都连接好了,红色LED也应该亮起。

设置的最后一步是通过添加到rc.local来自动启动这两个进程,通过调用运行脚本(在zip文件中包含了RunWeather和RunWeatherWWW)。

sudo nano /etc/rc.local

快速解释代码 - weather.py

当启动时,它会获取温度和湿度并插入到数据库中:

humidity, temperature = Adafruit_DHT.read_retry(sensor, 4) InsertWeather(temperature,humidity)

然后尝试在屏幕上获取并显示IP(因为希望这个设备可以无头运行):

lanip = GetLANIP().strip() wanip = GetWLANIP().strip() retry=0 while((not lanip) and (not wanip)) and retry<5: time.sleep(2) lanip = GetLANIP().strip() wanip = GetWLANIP().strip() retry = retry + 1 lcd_i2c.lcd_string(lanip,LCD_LINE_3) lcd_i2c.lcd_string(wanip,LCD_LINE_4)

然后它将进入一个无限循环,不断地获取天气(每10分钟一次)并刷新显示上的时间(大约每30秒一次,取决于获取天气所需的时间)。

快速解释代码 - weatherwww.py

在Flask中,每个URL都映射到一个方法。例如:

@app.route('/redon') def redon(): GPIO.output(GPIO_RED,True) return 'OK'

还有一些稍微长一点的运行方法,比如这个。由于使用的是内置的单线程Flask Web容器,当上一个请求仍在运行时,它将接受任何新请求。为了改进这一点,可以考虑将其更改为异步启动一个新线程并立即返回响应。然而,这有点棘手,因为新请求需要取消之前运行的请求。

@app.route('/blinkyellow') def blinkyellow(): allledoff() GPIO.output(GPIO_YELLOW,True) time.sleep(1) GPIO.output(GPIO_YELLOW,False) time.sleep(1) GPIO.output(GPIO_YELLOW,True) time.sleep(1) GPIO.output(GPIO_YELLOW,False) time.sleep(1) GPIO.output(GPIO_YELLOW,True) time.sleep(1) GPIO.output(GPIO_YELLOW,False) return 'OK' http://192.168.11.115:5000/display?line3=hello&line4=how are you?
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485