引子单纯觉得我的ESP32吃灰太浪费了。纯纯伪需求。那么，问题就来到了我的树莓派，What can I do with it?功能本次的小项目实现了这么几个功能：通过ESP32连接Wi-Fi。通过爬虫，检测博客是否宕机。通过计时功能，每隔一个小时检测。能够计算每天的宕机次数，并显示在一个八段数码管上。ESP32首先我们来简单介绍一下ESP32究竟是什么，通俗来讲，ESP32就是一个「带有Wi-Fi、蓝牙功能的微型电脑」，可以通过「一些管脚控制其它的电子外设工作」。长这个样子：如您所见，在电路板的两侧有两排引脚，可以输出数字信号，接收信号，并对信号进行处理。在下面，是一个Micro USB接口，可以连接电脑下载程序，也可以连接充电器作为供电接口。MicroPython嵌入式通常使用C语言进行开发，但是最近几年也出现了能够用Python语言进行开发的方法——MicroPython。MicroPython就是为嵌入式设备专门设计的一种Python语言，是常用Python语言的精简版，也增加了一些嵌入式设备独有的库。利用MicroPython开发，相比于C语言效率非常高，牺牲的是一部分性能和存储空间。环境配置安装Thonny，随后右下角-「配置解释器」，选择MicroPython（ESP32），选择好端口，然后点击「安装或更新MicroPython（esptool）」，然后根据自己板子的实际情况，填好相关内容，下载即可。当写好Python文件时，只需要在Thonny中点击「视图-文件」，然后在写好的文件上右键，点选「上传到/」即可。在ESP32中，只有main.py才会在上电后直接运行。接线这边本来想用FritZing画一个面包板连线图的，但是没有找到板子的资料，姑且口述吧，这里也不是特别重要。面包板上有这么几个东西：一个红色LED、一个绿色LED、一个八段数码管、三个适当阻值的电阻、一个按钮、一块ESP32和若干杜邦线。连接LED：随便找两个引脚，分别引出两根线，分别接到红绿LED的正极引脚，两个LED的负极引脚分别接到电阻上，然后接地。连接数码管：我所使用的是5011AS共阴八段数码管，通过查询引脚图，则将3号和8号引脚接地，其余引脚连接到适当引脚即可。在ESP32中，大于34的引脚为纯输入引脚，所以需要选择34以内的引脚连接。连接按键：我所使用的是四脚按键，这种按键长边的两个引脚是默认导通的，短边的两个引脚是不导通的，所以，可以在一个引脚上接一个电阻，随后接到ESP32的引脚上，另一个短边引脚则接地。LED是为了显示「网络连接错误」和「正在验证博客状态」的，数码管是为了显示一天之内的宕机次数，而按键则是为了开启数码管，只有按下才开启数码管显示。代码逻辑代码逻辑其实很简单，可以分为以下几个部分：初始化引脚。连接Wi-Fi网络。第一次检测网站是否宕机。主循环：检测按钮是否被按下。检测时间是否满足要求。初始化引脚这里的操作很简单：if __name__ == "__main__": # Init GPIOs error_light_pin = 23 working_light_pin = 22 eight_a = 25 eight_b = 26 eight_c = 19 eight_d = 18 eight_e = 17 eight_f = 32 eight_g = 33 eight_dot = 16 button_monitor = 13 eight_a_led = Pin(eight_a, Pin.OUT) eight_b_led = Pin(eight_b, Pin.OUT) eight_c_led = Pin(eight_c, Pin.OUT) eight_d_led = Pin(eight_d, Pin.OUT) eight_e_led = Pin(eight_e, Pin.OUT) eight_f_led = Pin(eight_f, Pin.OUT) eight_g_led = Pin(eight_g, Pin.OUT) eight_dot_led = Pin(eight_dot, Pin.OUT) error_led = Pin(error_light_pin, Pin.OUT) working_led = Pin(working_light_pin, Pin.OUT) button = Pin(button_monitor, Pin.IN, Pin.PULL_UP)连接Wi-Fi # Init Networks SSID = "<YOUR WIFI SSID>" PSWD = "<YOUR WIFI PSWD>" wlan = network.WLAN(network.STA_IF) wlan.active(True) # Connection print("Connecting to {SSID}") wlan.connect(SSID, PSWD) while not wlan.isconnected(): error_led.value(1) time.sleep(1) error_led.value(0) print("Done.")WIFI通常有AP和STA模式，AP相当于热点，STA相当于客户端。检测网站是否宕机这里就使用HTTP状态码进行检测，逻辑如下：def get_status_code(): headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36', ... } url = "https://www.coderlock.site" rqg = requests.get(url, headers=headers) return int(rqg.status_code) def work(working_led): fail_time = 0 working_led.value(1) status_code = get_status_code() if status_code != 200: fail_time = 1 working_led.value(0) return fail_time在主函数中： fail_time = 0 print("Start Working!") fail_time += work(working_led)检测按键是否被按下我们的按键接地，所以在引脚内部要使用上拉输入，检测逻辑如下： while True: if button.value() == 0: print("Button Pressed!") num_list = show_num_list(fail_time % 10) num_list.append(1 if fail_time > 10 else 0) show_num(num_list, eight_a_led, eight_b_led, eight_c_led, eight_d_led, eight_e_led, eight_f_led, eight_g_led, eight_dot_led) time.sleep(3) show_num([0,0,0,0,0,0,0,0], eight_a_led, eight_b_led, eight_c_led, eight_d_led, eight_e_led, eight_f_led, eight_g_led, eight_dot_led)这里其实最好加一个防抖处理。我将dot位用作十位。显示数字显示数字没什么好说的，就是根据想要的数字，分别控制不同引脚的高电平，我们的是共阴数码管，所以给高电平是亮：def show_num_list(num: int): res = [0 for i in range(7)] if num == 0: res = [1,1,1,1,1,1,0] elif num == 1: res = [0,1,1,0,0,0,0] elif num == 2: res = [1,1,0,1,1,0,1] elif num == 3: res = [1,1,1,1,0,0,1] elif num == 4: res = [0,1,1,0,0,1,1] elif num == 5: res = [1,0,1,1,0,1,1] elif num == 6: res = [1,0,1,1,1,1,1] elif num == 7: res = [1,1,1,0,0,0,0] elif num == 8: res = [1,1,1,1,1,1,1] elif num == 9: res = [1,1,1,1,0,1,1] else: pass return res def show_num(num_list, eight_a_led, eight_b_led, eight_c_led, eight_d_led, eight_e_led, eight_f_led, eight_g_led, eight_dot_led): eight_a_led.value(num_list[0]) eight_b_led.value(num_list[1]) eight_c_led.value(num_list[2]) eight_d_led.value(num_list[3]) eight_e_led.value(num_list[4]) eight_f_led.value(num_list[5]) eight_g_led.value(num_list[6]) eight_dot_led.value(num_list[7])检测时间我设定的是一个小时检测一次： curr_hour, curr_min, curr_sec = time.localtime()[3:6] if curr_hour == 23: fail_time = 0 if curr_min == 0 and curr_sec == 0: print("Scanning...") fail_time += work(working_led)完整代码import network from machine import Pin import time import requests error_light_pin = 23 def led_on(led): while True: led.value(1) time.sleep(1) def show_num_list(num: int): res = [0 for i in range(7)] if num == 0: res = [1,1,1,1,1,1,0] elif num == 1: res = [0,1,1,0,0,0,0] elif num == 2: res = [1,1,0,1,1,0,1] elif num == 3: res = [1,1,1,1,0,0,1] elif num == 4: res = [0,1,1,0,0,1,1] elif num == 5: res = [1,0,1,1,0,1,1] elif num == 6: res = [1,0,1,1,1,1,1] elif num == 7: res = [1,1,1,0,0,0,0] elif num == 8: res = [1,1,1,1,1,1,1] elif num == 9: res = [1,1,1,1,0,1,1] else: pass return res def show_num(num_list, eight_a_led, eight_b_led, eight_c_led, eight_d_led, eight_e_led, eight_f_led, eight_g_led, eight_dot_led): eight_a_led.value(num_list[0]) eight_b_led.value(num_list[1]) eight_c_led.value(num_list[2]) eight_d_led.value(num_list[3]) eight_e_led.value(num_list[4]) eight_f_led.value(num_list[5]) eight_g_led.value(num_list[6]) eight_dot_led.value(num_list[7]) def get_status_code(): headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36', ... } url = "https://www.coderlock.site" rqg = requests.get(url, headers=headers) return int(rqg.status_code) def work(working_led): fail_time = 0 working_led.value(1) status_code = get_status_code() if status_code != 200: fail_time = 1 working_led.value(0) return fail_time if __name__ == "__main__": # Init LEDs error_light_pin = 23 working_light_pin = 22 eight_a = 25 eight_b = 26 eight_c = 19 eight_d = 18 eight_e = 17 eight_f = 32 eight_g = 33 eight_dot = 16 button_monitor = 13 eight_a_led = Pin(eight_a, Pin.OUT) eight_b_led = Pin(eight_b, Pin.OUT) eight_c_led = Pin(eight_c, Pin.OUT) eight_d_led = Pin(eight_d, Pin.OUT) eight_e_led = Pin(eight_e, Pin.OUT) eight_f_led = Pin(eight_f, Pin.OUT) eight_g_led = Pin(eight_g, Pin.OUT) eight_dot_led = Pin(eight_dot, Pin.OUT) error_led = Pin(error_light_pin, Pin.OUT) working_led = Pin(working_light_pin, Pin.OUT) button = Pin(button_monitor, Pin.IN, Pin.PULL_UP) # Init Networks SSID = "<YOUR SSID HERE>" PSWD = "<YOUR PSWD HERE>" wlan = network.WLAN(network.STA_IF) wlan.active(True) # Connection print("Connecting to {SSID}") wlan.connect(SSID, PSWD) while not wlan.isconnected(): error_led.value(1) time.sleep(1) error_led.value(0) print("Done.") # Init Time fail_time = 0 print("Start Working!") fail_time += work(working_led) # Main Function print("Looping!") while True: if button.value() == 0: print("Button Pressed!") num_list = show_num_list(fail_time % 10) num_list.append(1 if fail_time > 10 else 0) show_num(num_list, eight_a_led, eight_b_led, eight_c_led, eight_d_led, eight_e_led, eight_f_led, eight_g_led, eight_dot_led) time.sleep(3) show_num([0,0,0,0,0,0,0,0], eight_a_led, eight_b_led, eight_c_led, eight_d_led, eight_e_led, eight_f_led, eight_g_led, eight_dot_led) curr_hour, curr_min, curr_sec = time.localtime()[3:6] if curr_hour == 23: fail_time = 0 if curr_min == 0 and curr_sec == 0: print("Scanning...") fail_time += work(working_led)