我有一块(未)吃灰多年的树莓派2和很多块(真)吃灰多年的 Nokia 5110 屏幕,最近收拾了一下,翻出了这块屏幕,然后找出了以前为它写的代码,基本就是网上摘抄的代码。心想不能真的就让它永远吃灰下去,于是今天就重新为它写了代码。
为什么叫高级版呢,因为是以前代码的升级啊。
具体效果如图
前期准备:
树莓派: 理论上从一到四代均可。
Nokia 5110:淘宝几块到十几块不等。
Linux 基础:基础的不能再基础的基础。
Python 能力:会打空格就行。如果需要自己定制,那还需要一点基础
要求:
python 3:2.7已经死了,早点抛弃吧。树莓派自带有python3。
知晓如何科学的提问:我不是神,问题不讲清楚怎么帮你解决。
缺陷:
不能显示中文:因为我使用的包没有中文字库而且其他能显示中文的字太大了,信息量太少,排版也不好看,就放弃了。
因为是好几年(也就一两年)前的代码。今天去看一个库的时候发现已经停止维护了。也就是不能用 pip 直接安装了(好像一直都不能直接用 pip 安装)。
代码会在最后打包提供下载。
硬件连接
连接方式我直接使用的 https://www.algissalys.com/how-to/nokia-5110-lcd-on-raspberry-pi 的连接方式。一般库用的也是这种连接方式。注意LIGHT口图上是没有标注的,可以连接到3.3V或者5V(但是有些屏幕LIGHT需要接地,具体看淘宝上的描述把)
测试 连接好以后需要测试一下屏幕是否能用或者是否连对了。
在树莓派shell下执行
1 2 3 4 5 6 7 git clone https://github.com/adafruit/Adafruit_Nokia_LCD cd Adafruit_Nokia_LCDsudo python3 setup.py installcd examplespython3 shapes.py
如果执行成功会出现
这个图形,这里我偷懒用的网上的图片。
这时候就可以开始下一步了。
添加代码 我的屏幕主要显示如下几项信息:
时间
天气(使用的和风天气的api)
CPU信息
ram信息
磁盘信息
理论上可以定制无限多的信息,只要你觉得自己看得过来。
主代码(显示代码) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 import timeimport Adafruit_GPIO.SPI as SPIimport Adafruit_Nokia_LCD as LCDimport piimport my_weatherimport requestsfrom PIL import Imagefrom PIL import ImageDrawfrom PIL import ImageFontfrom bs4 import BeautifulSoupget_ip_url = 'http://icanhazip.com/' get_ip_time: str = str () ip: str = str () get_weather_time: str = str () weather: list = list () max_height = 5 sleep_time = 5 DC = 23 RST = 24 SPI_PORT = 0 SPI_DEVICE = 0 def get_my_ip () -> str : """ 每天更新一次公网IP地址 :return: """ global get_ip_time, ip today_date = time.strftime("%y-%m-%d" , time.localtime()) if today_date == get_ip_time or get_ip_time != "" : return str (ip) else : get_ip_time = today_date ip = BeautifulSoup(requests.get(get_ip_url).content, "html.parser" , from_encoding='gbk' ) return str (ip) def get_weather () -> list : """ 每小时更新一次天气情况 :return: """ global get_weather_time, weather now_hour: str = time.strftime("%y-%m-%d %H" , time.localtime()) if now_hour == get_weather_time or get_weather_time != "" : return weather else : tmp, pm25, pm10 = my_weather.main() text = 'TEMP:%s' % tmp pm25_text = 'PM2.5:%s' % pm25 pm10_text = 'PM10:%s' % pm10 current_weather = list ([str (text), str (pm25_text), str (pm10_text)]) get_weather_time = now_hour weather = current_weather return weather def split_content (content ) -> list : """ 5110只能显示五行数据,如果超过六行,做分割 :param content: :return: """ temp_list = list () if len (content) > max_height: i = 1 while i < len (content): temp: list = list ([content[0 ]]) while len (temp) < max_height and i < len (content): temp.append(content[i]) i = i + 1 temp_list.append(temp) else : temp_list.append(content) return temp_list def draw_text (wait_to_draw_content ): disp = LCD.PCD8544(DC, RST, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=4000000 )) disp.begin(contrast=60 ) disp.clear() disp.display() image = Image.new('1' , (LCD.LCDWIDTH, LCD.LCDHEIGHT)) draw = ImageDraw.Draw(image) draw.rectangle((0 , 0 , LCD.LCDWIDTH, LCD.LCDHEIGHT), outline=255 , fill=255 ) font = ImageFont.load_default() for each in wait_to_draw_content: text = each x_pos = 42 - (len (text) * 6 / 2 ) if x_pos < 0 : x_pos = 0 y_base = int ((6 - len (wait_to_draw_content)) / 2 ) y_pos = 8 * (y_base + wait_to_draw_content.index(each)) draw.text((x_pos, y_pos), text, font=font) disp.image(image) disp.display() if __name__ == '__main__' : try : while True : now_time = time.strftime("%y-%m-%d %H:%M" , time.localtime()) draw_content = [now_time, str (get_my_ip())] now_weather = get_weather() draw_content.extend(now_weather) pi_info: list = pi.main(all =True ) draw_content.extend(pi_info) draw_content = split_content(draw_content) for each in draw_content: draw_text(each) time.sleep(sleep_time) except KeyboardInterrupt as e: print ("exit..." )
这是经过我简化的代码,但是所有的必要功能都在。
获取树莓派状态信息 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 import osdef getCPUtemperature (): res = os.popen('/usr/bin/vcgencmd measure_temp' ).readline() return res.replace("temp=" , "" ).replace("'C\n" , "" ) def getCPUuse (): return str (os.popen(r"/usr/bin/top -n 1 -b| /usr/bin/awk '/Cpu\(s\):/ {print $2}'" ).readline().strip()) def getRAMinfo (): p = os.popen('free' ) i = 0 while 1 : i = i + 1 line = p.readline() if i == 2 : return line.split()[1 :4 ] def getDiskSpace (): p = os.popen("df -h /" ) i = 0 while 1 : i = i + 1 line = p.readline() if i == 2 : return line.split()[1 :5 ] def main (all =False , cpu=True , ram=False , disk=False ) -> list : pi = list () if all : cpu = True ram = True disk = True if cpu: CPU_temp = getCPUtemperature() CPU_usage = getCPUuse() cpu_tmp = 'CPU TMP:%s' % CPU_temp cpu_usg = 'CPU USE:%s' % CPU_usage pi.append(str (cpu_tmp)) pi.append(str (cpu_usg)) if ram: RAM_stats = getRAMinfo() RAM_total = round (int (RAM_stats[0 ]) / 1000 , 1 ) RAM_used = round (int (RAM_stats[1 ]) / 1000 , 1 ) RAM_free = round (int (RAM_stats[2 ]) / 1000 , 1 ) RAM_total = 'RAM|All:' + str (RAM_total) RAM_used = 'RAM|Used:' + str (RAM_used) RAM_free = 'RAM|Free:' + str (RAM_free) pi.append(RAM_total) pi.append(RAM_used) pi.append(RAM_free) if disk: DISK_stats = getDiskSpace() DISK_total = DISK_stats[0 ] DISK_used = DISK_stats[1 ] DISK_perc = DISK_stats[3 ] DISK_total = 'DISK|Size:' + str (DISK_total) DISK_used = 'DISK|Used:' + str (DISK_used) DISK_perc = 'DISK|Used:' + str (DISK_perc) pi.append(DISK_total) pi.append(DISK_used) pi.append(DISK_perc) return pi
这个文件主要获取树莓派的CPU、RAM、磁盘的信息。
天气获取 注意:这个文件需要你的 api key,具体可以在 https://console.heweather.com/my/service 申请,同时需要你填入自己的所在地。需要填的项目都用星号表示了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 import jsonimport requestsfrom bs4 import BeautifulSoupkey = "key=**************" locate = "location=****" Regular_weather_data = 'https://free-api.heweather.com/s6/weather?' def weather_url (weather_api ): url = weather_api + locate + "&" + key return url def get_raw_data (url ): data = requests.get(url) soup = BeautifulSoup(data.content, "html.parser" , from_encoding='utf-8' ) soup = str (soup) json_data = json.loads(soup) return json_data def LiveWeather (data ): now_cond = data['HeWeather6' ][0 ]['now' ]['cond_txt' ] Sensible_temperature = data['HeWeather6' ][0 ]['now' ]['fl' ] tmp = data['HeWeather6' ][0 ]['now' ]['tmp' ] vis = data['HeWeather6' ][0 ]['now' ]['vis' ] update_time = data['HeWeather6' ][0 ]['update' ]['loc' ] dress_suggestion_brf = data['HeWeather6' ][0 ]['lifestyle' ][1 ]['brf' ] dress_suggestion_description = data['HeWeather6' ][0 ]['lifestyle' ][1 ]['txt' ] return tmp def air_quality (data ): aqi = data['HeWeather6' ][0 ]['air_now_station' ][0 ]['aqi' ] qlty = data['HeWeather6' ][0 ]['air_now_station' ][0 ]['qlty' ] co = data['HeWeather6' ][0 ]['air_now_station' ][0 ]['co' ] pm25 = data['HeWeather6' ][0 ]['air_now_station' ][0 ]['pm25' ] pm10 = data['HeWeather6' ][0 ]['air_now_station' ][0 ]['pm10' ] main = data['HeWeather6' ][0 ]['air_now_station' ][0 ]['main' ] air_sta = data['HeWeather6' ][0 ]['air_now_station' ][0 ]['air_sta' ] pub_time = data['HeWeather6' ][0 ]['air_now_station' ][0 ]['pub_time' ] return pm25, pm10 def main (): url = weather_url(Regular_weather_data) data = get_raw_data(url) ac_url = 'https://free-api.heweather.com/s6/air/now?location=beijing&' + key ac_data = get_raw_data(ac_url) tmp = LiveWeather(data) pm25, pm10 = air_quality(ac_data) return tmp, pm25, pm10
可以看到返回了很多数据,但是我只使用了tmp(温度),PM2.5,PM10三项数据,如果你有一定的python基础,可以自己修改。如果需要我帮忙修改的,可以在下面留言。
其他设置 主要的代码就是以上三个。
还需要安装依赖
1 sudo python3 -m pip install requests bs4 Adafruit_GPIO Pillow
以及一个第一步就手动安装的包。
在所有的依赖都安装完成后,可以测试一下代码了。
成功了就是如下图的效果。
systemctl 服务 如果测试没有问题,我们就可以把它作为服务,以后就可以开启启动了
在 display.py 文件的目录下执行
获得当前目录,可以看到我的是 /home/pi/Nokia5110 复制下来
继续输入
1 sudo nano /etc/systemd/system/Nokia5110.service
添加如下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [Unit] Description=Nokia 5110 Display After=network.target [Service] User=pi Group=pi Type=simple WorkingDirectory=/home/pi/Nokia5110 ExecStart=/usr/bin/python3 /home/pi/Nokia5110/display.py Restart=on-failure [Install] WantedBy=multi-user.target
如果不放心配置是否正确,可以在shell中执行
1 /usr/bin/python3 /home/pi/Nokia5110/display.py
看看是否显示成功。
如果提示 -bash: /usr/bin/python3: 没有那个文件或目录 有可能是你没有安装python3或者python3的执行文件不在/usr/bin/python3。
如果是第二种情况(输入python3可以执行,/usr/bin/python3却不能执行的情况)可以输入
然后将 /usr/bin/python3 替换为 输出的结果即可。
输入 ctrl + o 保存 ctrl + x 退出。
依次执行:
1 2 3 4 sudo systemctl daemon-reloadsudo systemctl enable Nokia5110.servicesudo systemctl start Nokia5110sudo systemctl status Nokia5110
如果是如上结果,并且屏幕正常显示,说明没有问题了。
到此,所有的设置结束。
代码下载 点击下载