提示:仅供学习使用,请勿用作商业用途


ESP32用MicroPython的查理复用

  • 什么是查理复用
  • 一、什么是查理复用
  • 二、原理图释义
  • 三、代码实现
  • 1.引入库
  • 2.变量定义和管脚初始化
  • 3.定义流水模式,共三种(顺序,逆序,两两闪烁)
  • 4.按键控制
  • 总结



什么是查理复用

因为在网上没找到自己想要的查理复用源码,自己琢磨了一下做出来了一个逻辑很简单但蛮好用的查理复用桥的使用办法,第一次发文章,如果有疏漏请指出。


一、什么是查理复用

查理复用是一种嵌入式算法,基于这种算法可以让IO口能点亮更多灯,通过芯片内置管脚模式置换输出高阻两种模式,让IO口改变电流流向,实现能然n个管脚点亮n*(n+1)个灯的效果。

二、原理图释义

两个管脚的查理复用原理图如下图,只要改变两个管脚输入输出模式就可以实现两个灯轮流亮灯

esp32 在启动过程中 管脚默认电平_python


三个管脚的查理复用原理图如下,我这里的代码也将用三个管脚来演示,在其中两个管脚实现输出0和1的时候,还需要一个管脚实现高阻模式,高祖模式相当于断路了,几乎没有电流流过。

esp32 在启动过程中 管脚默认电平_开发语言_02

三、代码实现

1.引入库

代码如下(示例):

import machine
import time
import threading

2.变量定义和管脚初始化

代码如下(示例):

led1 = machine.Pin(32, machine.Pin.OUT)
led2 = machine.Pin(22, machine.Pin.OUT)
led3 = machine.Pin(16, machine.Pin.OUT)
KEY= machine.Pin(0, machine.Pin.IN, machine.Pin.PULL_UP) #构建KEY对象 
state=0 #LED引脚状态
i=0#更换流水灯模式
delay=0#非阻塞性延时

3.定义流水模式,共三种(顺序,逆序,两两闪烁)

代码如下(示例):

#逆序流水灯
def switch3(num):
    if num==5:
        led1.value(1)
        led2.value(0)
        led3.init(mode=machine.Pin.IN, pull=None)
    elif num==4:
        led2.init(mode=machine.Pin.OUT)
        led1.value(0)
        led2.value(1)
        led3.init(mode=machine.Pin.IN, pull=None)
    elif num==3:
        led1.value(0)
        led3.value(1)
        led2.init(mode=machine.Pin.IN, pull=None)
    elif num==2:
        led1.init(mode=machine.Pin.OUT)
        led1.value(1)
        led3.value(0)
        led2.init(mode=machine.Pin.IN, pull=None)
    elif num==1:
        led2.value(1)
        led3.value(0)
        led1.init(mode=machine.Pin.IN, pull=None)
    elif num==0:
        led3.init(mode=machine.Pin.OUT)
        led2.value(0)
        led3.value(1)
        led1.init(mode=machine.Pin.IN, pull=None)
        
        
#顺序流水灯
def switch1(num):
    if num==0:
        led1.init(mode=machine.Pin.OUT)
        led1.value(1)
        led2.value(0)
        led3.init(mode=machine.Pin.IN, pull=None)
    elif num==1:
        led1.value(0)
        led2.value(1)
        led3.init(mode=machine.Pin.IN, pull=None)
    elif num==2:
        led3.init(mode=machine.Pin.OUT)
        led1.value(0)
        led3.value(1)
        led2.init(mode=machine.Pin.IN, pull=None)
    elif num==3:
        led1.value(1)
        led3.value(0)
        led2.init(mode=machine.Pin.IN, pull=None)
    elif num==4:
        led2.init(mode=machine.Pin.OUT)
        led2.value(1)
        led3.value(0)
        led1.init(mode=machine.Pin.IN, pull=None)
    elif num==5:
        led2.value(0)
        led3.value(1)
        led1.init(mode=machine.Pin.IN, pull=None)
        
        
#两个一起闪的流水灯
def switch2(num):
    if num==0:
        led1.value(1)
        led2.value(0)
        led3.value(0)
    elif num==1:
        led1.value(0)
        led2.value(1)
        led3.value(0)
    elif num==2:
        led1.value(0)
        led2.value(0)
        led3.value(1)

        

#流水灯切换模式
def switch():
        global state
        global i
        
        if state==0:
            print("switch0 i is ",str(i))
            switch1(i)
            i+=1
            i%=6
        elif state==2:
            print("switch2 i is ",str(i))
            switch2(i)
            i+=1
            i%=3
        elif state==1:
            print("switch1 i is ",str(i))
            switch3(i)
            i+=1
            i%=6

4.按键控制

while True:
    if KEY.value()==0:   #按键被按下 
        time.sleep_ms(10) #消除抖动 
        if KEY.value()==0: #确认按键被按下
            state+=1
            state%=4
            print("state is "+str(state))
            led2.init(mode=machine.Pin.OUT)
            time.sleep_ms(10)
            led1.init(mode=machine.Pin.OUT)
            time.sleep_ms(10)
            led3.init(mode=machine.Pin.OUT)
            led1.value(0)
        	led2.value(0)
        	led3.value(0)
            i=0
            time.sleep_ms(10)
            while not KEY.value(): #检测按键是否松开 
                pass
    if(delay==100):#判断非阻塞延时,时间到了就执行一次,换下一个流水模式
        switch()
        delay=0
    else:
        delay+=1
        time.sleep_ms(10)

总结

比较麻烦的地方在从switch1切换到switch2中,看起来是从一个灯亮切换成两个灯亮,但实际上也是从有高阻模式切换成全输出模式,需要在按键切换的时候对当下num模式进行判断并将管脚改回输出并置0操作。