2021-11-09 micropython esp32刷固件 adc 多线程的记录 线程守护 外部中断 睡眠唤醒 定时器 喂狗 信号反转 综合记录贴

本文详细介绍了如何使用esptool.py工具烧录ESP32固件,包括清除芯片数据、不同固件的耗电特性。此外,还探讨了ESP32的ADC和DAC功能,以及在microPython环境下实现多线程的方法,包括线程启动、关闭以及线程锁的概念。最后,提到了外部中断和定时器的使用,以及利用定时器进行看门狗喂狗操作。
摘要由CSDN通过智能技术生成

首先刷固件 esptool.py --port com43 erase_flash COM43 是需要的口,按需更改,这个步骤可以先刷掉芯片数据,防止烧写后残余数据干扰。

有的板子都不用按钮啥的就能直接自己下载 ,但是有的不行,所以要尝试

带电池座这个ESP32 烧写的时候要按下BOOT 腱子

后来买的国云的也得按住BOOT

  1. esptool.py --chip esp32 --port com7 --baud 460800 write_flash -z 0x1000 G:\python\pymini\esp32\esp32_softsrial_ble.bin(这里是输入固件地址,也可以直接把固件拉到里边就出地址了,最好别有中文,谨慎点好)这个大老鼠的耗电高有WIFI 有软串口
  2. esptool.py --chip esp32 --port com43 --baud 460800 write_flash -z 0x1000 G:\python\pymini\esp32\esp32-idf3-20200516-unstable-v1.12-462-gcd9a8c174.bin 这个官方的耗电小
  3. 没问题就应该可以了

补一个esp32 ADC 2个DAC 我验证了一个25引脚,另一个是26 也验证了但是没上表测试

from machine import ADC
import machine,time
pin = machine.Pin(13,machine.Pin.IN)
adc = ADC(pin,atten=ADC.ATTN_11DB)        # 创建ADC引脚并指定衰减值, atten=  这个衰减值可以增大ADC监测电压范围当然同时会降低精度
#################
#ADC.ATTN_0DB: 无衰减 (100mV - 950mV)
#ADC.ATTN_2_5DB: 2.5dB 衰减 (100mV - 1250mV)
#ADC.ATTN_6DB: 6dB 衰减 (150mV - 1750mV)
#ADC.ATTN_11DB: 11dB 衰减 (150mV - 2450mV)
#11DB的衰减基本可以检测0-3.3V电压,但是两头不怎么准,中间线性度还可以
#################

val = adc.read_u16()  # 读数值 0-65535
val = adc.read_uv()   # 读数值比较大 精度很高
val = adc.adc.read()  # 读数值0-4095
while 1:
    print(adc.read())
    time.sleep(1)
from machine import DAC,Pin
dac = DAC(Pin(25))
dac.write(0)        #值(0-255)

2019.11.3日记录

多线程,esp32的microPython多线程没有写完,或者说官方想做但是没做好,甚至可能都已经放弃了,但是这个多线程还是有一些实际意义的,因为他确实很需要,那么我们偶尔在一些实验项目上使用它也是可以的。

1.引用

import _thread

2.构建线程函数

def threadRun1(a,b):
  while 1:
  	print(a,b)  #a,b是我传进来的参数,证明线程可以接收数据
  	time.sleep(5) # 睡眠函数是防止线程把CPU堵死,单片机CPU很宝贵没事多睡觉,无害身体好
  1. 启动线程
_thread.start_new_thread(threadRun1,(1,5))
  1. 合在一起,下面是一个线程查询苏宁时间API的程序
    给线程数据可以传参,也可以用全局变量,取线程数据也是全局变量
import network
import urequests as requests
import time
import _thread
data=''  ## 构建一个变量,用它来把线程里边的数据取出来
def threadRun1(a,b):
  while 1:
    if wl.isconnected():#判断联网
      print('连接成功')
      global data #全局变量
      cc=requests.get("http://quan.suning.com/getSysTime.do").text ##get方法传数据
      data=cc
      print(cc)
    else:
      print('失败重连')
      time.sleep(10)
      wl.connect('300king','13704677369')
wl=network.WLAN(network.STA_IF)#wifi模式设定
wl.active(True)#网络可用设定
if wl.isconnected(): #2021年的固件版本不让附着网络后重新执行附着所以要多验证网络是否附着,以前的固件随便附着不报错。
  pass
else:
  wl.connect('300king','13704677369')
#以上是联网部分,下面是与服务器通信部分
print('启动')
_thread.start_new_thread(threadRun1,(1,5))# a=1,b=5  这里非必须但是重要

  1. 如果想关闭线程则在线程内部执行 `_thread.exit()
def threadRun1(a,b):
  while 1:
    b=b+1
    if wl.isconnected():
      print('连接成功')
      global data
      cc=requests.get("http://quan.suning.com/getSysTime.do").text #get方法传数据
      data=cc
      print(cc)
      if b >20:
        _thread.exit() # 遇到这个线程就静默退出了

最后还有一个线程锁的概念,可惜没太搞懂。单片机本来资源就不丰富,多任务这种还是测试开发范围,这个线程锁是多任务调度使用的,所以资料也少。那我就先把资料沾着里留着以后再说,。

资料锁线程锁索锁锁

补充:一个线程守护的写法:

今天忽然有灵感尝试着写了一下
逻辑:开启一个线程,在线程中声明一个全局变量flag =1,主函数循环中每2秒赋值flag =1一次,而线程中每5秒flag=0一次,如此,在线程中如果主函数不死则判断flag一定是1这个值打印OK,主函数挂掉线程会标志位为0,

import _thread
import random
import time
flag=1
cishu =10
def threadRun1(a,b):
  global flag
  while 1:
    time.sleep(5)
    if flag==0 :
      print('死了')
    else :
      print('ok')
    flag=0
_thread.start_new_thread(threadRun1,(1,5))
while 1 :
  flag = 1
  time.sleep(2)
  cishu=cishu-1
  if cishu==0 :
    break

如果更改两个循环的对抗时间,则主函数可以监控线程是否正常工作

import _thread
import random
import time
flag=1 #工作标识
def threadRun1():
  global flag
  cishu =10
  while 1:
    time.sleep(2) #2秒FLAG变0
    flag=0
    cishu=cishu-1
    if cishu<0:
      _thread.exit() #线程退出,模拟线程崩溃。使用时,不需要这个判断,线程最好别崩溃^_^
_thread.start_new_thread(threadRun1,())
while 1 :
  flag = 1  
  time.sleep(5) #5miao flag =1
  if flag==0:
    print('threadRun  ok')  #线程正常走这里
  else :
    print('err')   #线程挂了走这里

中断~中断 ,外部中断的写法

import machine,esp32
a = 0#与主程序通信
def callback(pin):#定义回调函数
  global a#声明为全局变量
  a = a+1
  print(a)
p25 = machine.Pin(25, machine.Pin.IN, machine.Pin.PULL_UP)
#参数:  引脚编号   引脚模式为输入模式  引脚上拉确保无输入是高电平的已知状态
#machine.Pin.PULL_UP    上拉
#machine.Pin.PULL_DOWN  下拉
#None 无上下拉

#machine.Pin.PULL_HOLD  保持,大部分IO口可设置这个状态,在深度睡眠时保持其状态
#注意:一旦设置这个参数,其实这个脚是被锁死的  也就是指令无法改变其状态,一般用法为单独执行一次保持功能
#p25 = machine.Pin(25, machine.Pin.OUT, machine.Pin.PULL_UP)
#p25.value(1)
#p25 = machine.Pin(25, machine.Pin.IN, machine.Pin.PULL_HOLD)  #锁死ON状态,深睡也不会变
#解开再执行一次
#p25 = machine.Pin(25, machine.Pin.OUT, machine.Pin.PULL_UP) #此时就可以修改引脚值了


p25.irq(trigger=machine.Pin.IRQ_FALLING, handler=callback)
#触发中断回调设置:           #trigger= 触犯模式设置        handler= 回调函数名  
#machine.Pin.IRQ_FALLING  #下降沿模式
#machine.Pin.IRQ_RISING   #上升沿模式
#trigger=(machine.Pin.IRQ_FALLING | machine.Pin.IRQ_RISING)  # 上下沿一起来吧

state=machine.disable_irq()
()#禁用中断

machine.enable_irq(state)
#重新启动中断




睡眠唤醒

import esp32 , machine ,time
wake1 = machine.Pin(25, mode = machine.Pin.IN) 
#注意引脚,如果用了不支持的脚会报错,记得换脚测试
esp32.wake_on_ext0(pin = wake1, level = esp32.WAKEUP_ALL_LOW)
print('10秒后失眠~')
time.sleep(10)
machine.deepsleep() # machine.ligthsleep()


#以下引脚是接着协处理的,可配置唤醒,但还是要避开影响启动的脚

RTC_GPIO0 (GPIO36)
RTC_GPIO3 (GPIO39)
RTC_GPIO4 (GPIO34)
RTC_GPIO5 (GPIO35)
RTC_GPIO6 (GPIO25)
RTC_GPIO7 (GPIO26)
RTC_GPIO8 (GPIO33)
RTC_GPIO9 (GPIO32)
RTC_GPIO10 (GPIO4)
RTC_GPIO11 (GPIO0)
RTC_GPIO12 (GPIO2)
RTC_GPIO13 (GPIO15)
RTC_GPIO14 (GPIO13)
RTC_GPIO15 (GPIO12)
RTC_GPIO16 (GPIO14)
RTC_GPIO17 (GPIO27)

定时器内容~ 也都放这里吧

import machine
###############构造一个回调函数,在这里执行中断动作注意里边不要执行内存分配动作,
###############定时器的回调函数需要一个参数否则出错
flag=0 标志位
def xx(t): #定时器回调这里必须有一个参数
    global flag #全局变量
    print(1)
###############

t1 = machine.Timer(0)#实例化一个定时器通道,可选0-3一共四个定时器
t1.init( period=1000, mode=machine.Timer.PERIODIC, callback=xx)#1秒循环定时 参数为:间隔时间(毫秒)定时模式:循环还是一次  回调函数:指定\


t2 = machine.Timer(1)
t2.init( period=5000, mode=machine.Timer.ONE_SHOT, callback=xx)#mode=machine.Timer.ONE_SHOT #5秒后只执行一次的定时

# Timer.deinit()  # 停止定时器
# 例如:t1.deinit() 
扩充:定时器喂狗,定时器里是可以喂狗的,但是一般用标志位来喂狗,主要用途是8266中喂狗周期不到2秒就会超时,则采用定时器喂狗,并在主程序中刷新标志位的值即可实现长周期喂狗。下面程序采用一个定时器就可以30秒喂一次狗。
from machine import WDT
wdt = WDT()
wdt_flag=0
def Time_wdt(t_id):
    global wdt_flag
    wdt_flag=wdt_flag+1
    if wdt_flag<200:
        wdt.feed()
    print(wdt_flag,t_id)
t1 = machine.Timer(0)#实例化一个定时器通道
t1.init( period=1000, mode=machine.Timer.PERIODIC, callback=Time_wdt)#1秒循环定时 参数为:间隔时间(毫秒)定时模式:循环还是一次  回调函数:指定\

while 1:
	wdt_flag=0
	time.sleep(30)

补充一个冷门知识~输出引脚信号反转 Signal

用处是可以使引脚逻辑统一,比如有的继电器高电平触发,有的低电平触发。。。在一个程序里就会显得很头大,有的是1有的是0 ,那就用这个反转信号对引脚处理下统一触发逻辑,其实还是很必要的。

from machine import Pin, Signal
led2 = Pin(27, Pin.OUT,Pin.PULL_DOWN) #实例化27引脚
led2.value(1) #此时 引脚电压3.3V ,如果 led2.value(0)  则引脚电压为 0v

led1 = Signal(led2, invert=True)  
#两级反转,也就是通过Signal包装,并指定invert为真时则反转信号,为假则不反转
led1.value(1) #此时 引脚电压0V ,如果 led1.value(0)  则引脚电压为3.3V

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值