IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 继续树莓派4B+OLED:开机自动显示IP地址 -> 正文阅读

[网络协议]继续树莓派4B+OLED:开机自动显示IP地址

因为有了之前(树莓派:Adafruit的I2C SSD1306 OLED驱动)那篇的基础,想干脆让它开机自动显示IP地址。

首先当然找获取IP的代码。记得前几年抄过一段,所以又找了出来:

def get_ip_address(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    return socket.inet_ntoa(fcntl.ioctl(
        s.fileno(),
        0x8915,
        struct.pack('256s', ifname[:15]))[20:24])

当时调用很简单,因为我是用无线的,所以历史代码调用用了这一句:
ip = get_ip_address('wlan0')

然而今天再拿出来试居然报错了。解决起来倒是非常简单,加个“b”类型前缀即可:

ip = get_ip_address(b'wlan0')

结合示例中的代码,另存了一份代码,命名为s.py,完整代码如下:

import time

import Adafruit_GPIO.SPI as SPI
import Adafruit_SSD1306

from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont

#import subprocess
import socket
import fcntl
import struct
#import commands

def get_ip_address(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    return socket.inet_ntoa(fcntl.ioctl(
        s.fileno(),
        0x8915,
        struct.pack('256s', ifname[:15]))[20:24])

ip = get_ip_address(b'wlan0')


RST = None     # on the PiOLED this pin isnt used
DC = 23
SPI_PORT = 0
SPI_DEVICE = 0

disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST)


disp.begin()
disp.clear()
disp.display()

width = disp.width
height = disp.height
image = Image.new('1', (width, height))

draw = ImageDraw.Draw(image)

draw.rectangle((0,0,width,height), outline=0, fill=0)

padding = -2
top = padding
bottom = height-padding
x = 0


font = ImageFont.truetype('/usr/share/fonts/truetype/noto/NotoMono-Regular.ttf', 14)

draw.rectangle((0,0,width,height), outline=0, fill=0)

#cmd = "hostname -I"
#IP = subprocess.check_output(cmd, shell = True )

draw.text((x, top), ip,  font=font, fill=255)
disp.image(image)
disp.display()

然后就是设置开机自动执行了。意外的,并没有想象中顺利,无论是使用/etc/rc.local还是crontab -e。没有深究,感觉是要么python相关的库调取不到,要么bash环境有问题。

最终使用systemd解决。

在/usr/lib/systemd/system下新建一个后缀为.service的文件(我用了showip-oled.service),内容如下:

[Unit]
Description=Show IP on OLED
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/bin/python3 -u /home/pi/Adafruit_Python_SSD1306/examples/s.py
Restart=on-failure
RestartSec=6
User=pi

[Install]
WantedBy=multi-user.target

具体含义可以参考:Systemd的使用指南 - 简书 (jianshu.com)https://www.jianshu.com/p/7fd8b6ea336e

?因为获取IP并展示在OLED屏幕上只需要在开机时执行,因此Type用了oneshot。一开始没有加Restart和RestartSec,结果测试时发现脚本运行到获取ip相关的地方会报错,因此最终还是加上了这两项。

Service文件保存(含新建、修改等)后可以执行sudo systemctl daemon-reload让系统重刷一下。然后尝试?sudo systemctl start showip-oled.service 看看是否能正常运行,并用sudo systemctl status showip-oled.service 确认。最后运行下?sudo systemctl enable showip-oled.service 使能自动运行。

最后就可以正式测试了。由于我发现树莓派关机后只要不撤电源线,OLED仍可继续显示,因此建议关机后先把电源也断开,确保OLED无任何显示,之后再给树莓派通电。正常情况下应该能显示IP地址了。如果还是不行,可以再用?sudo systemctl status showip-oled.service 看看还有啥错。

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-04-22 19:15:05  更:2022-04-22 19:16:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 3:27:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码