Micropython学习交流群 学习QQ群:786510434 提供多种固件下载和学习交流。
Micropython-扇贝物联 QQ群:31324057 扇贝物联是一个让你与智能设备沟通更方便的物联网云平台
Micropython学习交流群 学习QQ群:468985481 学习交流ESP8266、ESP32、ESP8285、wifi模块开发交流、物联网。
Micropython老哥俩的IT农场分享QQ群:929132891 为喜欢科创制作的小白们分享一些自制的计算机软硬件免费公益课程,由两位多年从事IT研发的中年大叔发起。
micropython esp32休眠假死 唤醒 rtc nvs btree数据保持
首先本次记录时MICROPYTHON 在ESP32环境下的记录,这里需要声明你使用的micropython 的版本固件不应该太古老,根据我的经验,有些早期固件不支持以下测试,或者不具备相应功能,固件嘛一般都是新的好,新的功能以及更少的BUG, 不像语言,太新的版本反而会出现兼容问题。我本次的固件版本为2021年9月版本的固件,已经证实的是2018年的固件不能支持下面的内容。
本次记录是一些关于低功耗方面的偏向于底层控制,大量的使用了machine模块,以及如何唤醒与数据保持的零散记录。
命令重启指令,这个是遇到异常的补救手段,因主动性强放在首位
machine.reset_cause() #复位原因:返回数字1-5 ,1-5意思见如下说明 复位原因 说明 1 machine.PWRON_RESET 电源复位 2 machine.HARD_RESET 硬重置(断电) 3 machine.WDT_RESET 看门狗复位 4 machine.DEEPSLEEP_RESET 深度睡眠 5 machine.SOFT_RESET 软复位
改变频率运行,在节省功耗的部分情况下可以调整CPU运行频率,但是也可能因为对频率调整后影响某些时序封装后的指令,所以可以尝试使用,有异常优先调整回默认频率~
machine.freq() #查询运行频率 #默认为160MHZ machine.freq(160000000) #设置运行频率 可设定参数为 20MHz, 40MHz, 80Mhz, 160MHz ,240MHz
硬件休眠 ,分为假死状态和全死状态~~里面的参数是保持死状态的毫秒时间 ,5000就是5秒,不带参数就是死下去,等待设定好条件状态唤醒。
machine.sleep(5000) 停止CPU并禁用除了WLAN(如果存在)之外的全部外设。(不推荐) machine.lightsleep (5000) 假死状态,随时唤醒,功耗大幅度降低(据说降低到百分之一不到),优点是保持了系统一定活性,不丢失运行数据也可以从睡眠点继续执行程序,类似假死 machine.deepsleep(5000) 停止 CPU 和所有外设 (包括网络)。全死状态(据说功耗和关机差不多),唤醒时类似复位一样从头运行,可以 reset_cause() 了解复位原因是不是深度睡眠
复活术:中断复活,可以复活两种低功耗的死状态,采用的是中断触发的方式,这个引脚可不是随便用的,不支持会报错的大约可用的引脚是 14 ,12 ,13,25啥的,自己测试,记得报错了就换引脚,程序肯定没问题
import esp32 , machine ,time wake1 = machine.Pin(25, mode = machine.Pin.IN) esp32.wake_on_ext0(pin = wake1, level = esp32.WAKEUP_ALL_LOW) #esp32.wake_on_ext0 中断唤醒 ,这个比较常用 #esp32.wake_on_ext1 据说是WLAN唤醒。。。。没测试觉得没啥大用 #pin = 传入一个PIN输入对象 #level = esp32.WAKEUP_ALL_LOW 低电平唤醒 #level = esp32.WAKEUP_ANY_HIGH 高电平唤醒 print('10秒后失眠~') time.sleep(10) #主函数没有这个睡眠小心一睡不起只能刷固件~~~ machine.deepsleep() # machine.ligthsleep()
RTC存储器,这是一个不断电就能持续保持数据的存储器,
尤其是其可以在deepsleep状态下保持数据,只要不断电就能保持,但是板子的RST复位按钮引起的复位数据会丢失,它的用法如下,注意:只能接受字符串类型,我们可以用JSON把数据包装好给他,也很方便
import machine import json rtc = machine.RTC() data=json.dumps([1,2,3,4,5]) rtc.memory(data) # 写入存储器 #rtc.memory('12345') rec_data=rtc.memory() #从存储器读出数据
NVS非易失存储
首先,这个是非易失存储也就是断电不掉的存储方式,这个方式可以长期保持数据,理论上可以存储数字和字符串但是~
import esp32 a=esp32.NVS('abc') # abc是命名空间,也就是实例化的开辟了一个叫abc的世界 a.set_i32('a1',1) # 在实例化的命名空间中存入一个键值对,值必须为32位有正负的整数 {'a1':1} a.set_blob('a2','sdf') #存入一个字符串型的键值对 a.commit() #### 把存好的数据刷入实例化的命名空间,必须有这个否则不存 a.get_i32('a1') #在实例化的空间中取出'a1'的值 a.erase_key('a1') #删除这个键值
下面这部分是关于取出.set_blob()这部分的,这部分资料比较少官方文档也说得不清不楚的,我就单独写一下取出字符串部分的具体流程,重点有俩,1、存的时候COMMIT()别忘记2、取字符串内容先建立缓冲区再去取,返回值是长度,内容在缓冲区里边,解码即可获取。
from esp32 import NVS nvs = NVS("abc") blob1 = "wo shi yi ge xiao niao " #要写入NVS的字符串 nvs.set_blob("blob1", blob1) #写入方式 nvs.commit() #刷入NVS buf1 = bytearray(50) #准备缓冲区,大小为50 len1 = nvs.get_blob("blob1", buf1) #取出blob1的内容,写入缓冲区buf1中,返回长度给len1 print(len1,buf1.decode()) #打印下长度和内容,注意必须解码
然后,我平时断电保持一般会采用btree简单数据库的形式,下面这个是一次开发的读写封装的类,用它代替NVS就可以,如果要好好使用可以自行仔细改一改,这个数据库支持
import btreeclass btree_r_w(object): def write_btree(self,b_id,b_name): #传入参数必须是二进制字符串例如 b'1',b'gao' try: f = open("mydb", "r+b") except OSError: f = open("mydb", "w+b") db = btree.open(f) db[b_id] =b_name db.flush() db.close() f.close() def read_btree(self,b_id): #传入参数必须是二进制字符串例如 b'1',有返回值 try: f = open("mydb", "r+b") except OSError: f = open("mydb", "w+b") db = btree.open(f) name = db.get(b_id) db.close() f.close() return nameif __name__=='__main__': a=btree_r_w()#实例化 a.write_btree(b'1',b'gk')#写 data= a.read_btree(b'1')#读 print(data)
下面是官方的btree例程文档粘贴在下面便于查询
import btree # First, we need to open a stream which holds a database # This is usually a file, but can be in-memory database # using io.BytesIO, a raw flash partition, etc. # Oftentimes, you want to create a database file if it doesn't # exist and open if it exists. Idiom below takes care of this. # DO NOT open database with "a+b" access mode. try: f = open("mydb", "r+b") except OSError: f = open("mydb", "w+b") # Now open a database itself db = btree.open(f) # The keys you add will be sorted internally in the database db[b"3"] = b"three" db[b"1"] = b"one" db[b"2"] = b"two" # Assume that any changes are cached in memory unless # explicitly flushed (or database closed). Flush database # at the end of each "transaction". db.flush() # Prints b'two' print(db[b"2"]) # Iterate over sorted keys in the database, starting from b"2" # until the end of the database, returning only values. # Mind that arguments passed to values() method are *key* values. # Prints: # b'two' # b'three' for word in db.values(b"2"): print(word) del db[b"2"] # No longer true, prints False print(b"2" in db) # Prints: # b"1" # b"3" for key in db: print(key) db.close() # Don't forget to close the underlying stream! f.close()
来源:
https://blog.csdn.net/gaoke11240/article/details/121507235
Copyright © 2014 ESP56.com All Rights Reserved
执行时间: 0.0099911689758301 seconds