了解如何让您的微控制器记住您的设置,这样即使它断电或重新启动,您也可以快速将其恢复到工作状态!
为什么?
假设你有一个正在运行的MicroPython项目,你不小心拔掉了微控制器的电源。当你重新插入它时,它会像一个转世的婴儿一样醒来 - 完全不知道它过去的生活 - 然后浏览你的 boot.py 和 main.py 文件,像你第一次打开它一样执行他们的代码。换句话说,它对过去的执行没有持久的记忆。
对于许多项目来说,这真的很糟糕。例如,您可以使用MicroPython创建一个彩色RGB灯,您可以通过手机进行控制。但是,如果您将其设置为希望微控制器在重新启动之间“记住”的美丽颜色,它将不起作用。如果没有持久内存,当您再次打开灯时,灯将恢复为其默认的硬编码颜色。
但还是有希望的!我们可以将用户的设置保存到微控制器的板载闪存中,而不是“忘记”您的颜色设置。今天,您将在ESP32上学习如何做到这一点,但无论您使用哪种微控制器或编程语言,都适用相同的原理。使用MicroPython实现这项技术(与C相反)最棒的地方是,它预装了一个完整的文件系统和一个易于使用的标准库,用于处理配置文件。
使用JSON保持简单
将配置存储为JSON(jay-sun?jace-on?juss-on?)文件非常棒,因为MicroPython有一个内置的ujson库,可以读取和写入JSON文件。更好的是,它直接将JSON文件读取到一个普通的Python字典中,这使得配置数据易于使用。如果您以前使用过桌面或web软件,那么您应该熟悉这种配置文件的方法。
为了演示这种方法,让我们构建一个简单的ESP32项目,通过单击按钮切换LED,并记住LED的最后状态(打开或关闭),即使它从电源上拔下。在深入研究代码之前,让我们先画出程序流程。它将帮助我们决定程序何时保存用户的设置,以及何时加载以前的设置。
程序流程
通过将 LED 状态存储在配置文件中来记住 LED 状态的程序流程
该程序可以整齐地分为初始化阶段和主循环阶段。在初始化期间,我们检查配置文件中 LED 的最后已知状态,并立即将 LED 设置为此状态。因此,在我们进入主循环之前,我们已经匹配了用户的最后一个设置。
在主循环中,我们检查用户是否按下按钮并切换 LED。每次我们切换 LED 时,它都会更改程序的状态。我们通过将 LED 的新状态保存到配置文件来捕获此状态更改。这可确保微控制器下次启动时,将 LED 设置为与用户所需的设置相匹配。就是这样!
虽然这看起来是一个非常简单的程序,但它展示了状态管理的强大概念。通过在单独的数据结构中存储和跟踪程序的状态,只需修改配置文件即可在程序中重新创建任何方案。像这样单独管理状态是一种很好的做法,用于各种领域,从数据库支持的应用程序到现代前端 Web 开发框架。好的,足够的设计和理论。让我们将其转换为代码!
在MicroPython中编码
我们只需要创建 2 个文件 - 代码和配置。让我们从配置文件开始,在我们的例子中,它只是一行:
Code: Select all
{"is_led_on": 0}
我们默认设置 is_led_on 为 0,这意味着 LED 应该熄灭。请注意,JSON 语法与 Python 字典非常相似。
接下来是MicroPython代码。请注意,这是在 ESP32 开发套件上测试过的 - 如果您有不同的微控制器,则可能需要更改 LED 和按钮的引脚编号以匹配您的特定开发板。首先,让我们加载配置文件并初始化外设:
Code: Select all
import json
from machine import Pin
from time import sleep
# load the config file from flash
with open("config.json") as f:
config = json.load(f)
# init LED and button
led = Pin(2, Pin.OUT)
btn = Pin(0)
我们使用 json.load 将配置文件加载到名为 config 的字典中。接下来,我们需要定义一个函数,该函数可以将配置字典保存回 JSON 文件:
Code: Select all
def save_config():
"""function to save the config dict to the JSON file"""
with open("config.json", "w") as f:
json.dump(config, f)
该函数以“w”(即写入模式)打开配置文件,获取全局配置字典,然后用 json.dump 将其转储到该文件中。MicroPython 让这一切变得如此简单!稍后,每当用户按下按钮时,我们将在主循环中调用此函数。
在进入主循环之前,我们需要根据用户的上次设置将 LED 调到其初始状态(开/关)。这就像将 LED 设置为字典中的值一样简单:
Code: Select all
# load LED state from config file
led.value(config["is_led_on"])
Code: Select all
# use button to toggle LED
while True:
if btn.value() == 0:
led.value(not led.value())
config["is_led_on"] = led.value()
save_config()
sleep(0.5)
差不多就是这样!所有这些逻辑都在大约 30 行代码中。相同的模式 - 在启动时从配置文件加载状态,每次更改时将状态保存到配置文件 - 可以应用于任何MicroPython项目,无论是花哨的彩虹LED灯还是小型四轴飞行器。