2663|10

1万

帖子

25

TA的资源

版主

楼主
 

【DIY创意LED】主程序 [复制链接]

为了方便扩展,这次将程序设计为主程序和效果程序,上电时,ESP8266搜索磁盘,查找磁盘中所有的效果文件,并载入默认效果文件进行演示。

 

下面是主程序:

 

from machine import Pin, lightsleep, Timer, UART, reset
from time import sleep_ms

KEY_CNT_MAX = const(10)

print('\r\nLED start...')
Power = Pin(13, Pin.OPEN_DRAIN, value = 0)
Pin(2, Pin.IN)

import os, gc

from common import *

def init():
    clear(np, (18, 0, 0))
    sleep_ms(100)
    clear(np, (0, 18, 0))
    sleep_ms(100)
    clear(np, (0, 0, 18))
    sleep_ms(100)
    clear(np, (5, 0, 0))

init()

fun_list = []
d = os.listdir('')
for i in range(len(d)):
    if d[i].find('ef_') == 0:
        fun_list.append(d[i].replace('.py', ''))

print(fun_list)

def poweroff():
    print('power off!')
    for i in range(8, 0, -1):
        clear(np, i*30)
        sleep_ms(20)

    Power = Pin(13, Pin.OPEN_DRAIN, value = 1)

def rand(N = 128):
    r = os.urandom(2)
    return (r[0]*256 + r[1])%N

KEY1 = Pin(14, Pin.IN)
KEY2 = Pin(12, Pin.IN)

'''
KEY1_cnt KEY2_cnt  return
    0        0       0
    0        1       1
    0        2       2
    1        0       16
    1        1       17
    2        0       32
    2        2       34
'''
KEY_NONE = const(0)
KEY_PREV = const(1)
KEY_SAV1 = const(2)
KEY_NEXT = const(16)
KEY_RAND = const(17)
KEY_SAV2 = const(32)
KEY_POWEROFF = const(34)

KEY = 0
KEY_cnt = 0
KEY1_cnt = 0
KEY2_cnt = 0

KEYCODE = (KEY_PREV, KEY_NEXT, KEY_RAND, KEY_SAV1, KEY_SAV2, KEY_POWEROFF)

def tm_irq(t):
    global KEY, KEY_cnt, KEY1_cnt, KEY2_cnt

    if KEY_cnt > 0 and KEY_cnt <= KEY_CNT_MAX:
        KEY_cnt += 1
        if KEY_cnt > KEY_CNT_MAX:
            KEY = KEY1_cnt * 16 + KEY2_cnt
            KEY_cnt = 0
            KEY1_cnt = 0
            KEY2_cnt = 0
            if KEY in KEYCODE:
                UART(1).write(b'\x03')

tm = Timer(-1)
tm.init(period=100, mode=Timer.PERIODIC, callback=tm_irq)

def KEY1_irq(t):
    global KEY_cnt, KEY1_cnt

    if KEY_cnt == 0:
        KEY_cnt = 1

    if KEY_cnt <= KEY_CNT_MAX:
        if KEY1_cnt < 3:
            KEY1_cnt += 1

def KEY2_irq(t):
    global KEY_cnt, KEY2_cnt

    if KEY_cnt == 0:
        KEY_cnt = 1

    if KEY_cnt <= KEY_CNT_MAX:
        if KEY2_cnt < 3:
            KEY2_cnt += 1

KEY1.irq(trigger = Pin.IRQ_FALLING, handler = KEY1_irq)
KEY2.irq(trigger = Pin.IRQ_FALLING, handler = KEY2_irq)



def main():
    global KEY, KEY_cnt

    KEY_cnt = 0
    n = 0
    try:
        f = open('last.fun', 'rb')
        n = f.read(1)[0]
        f.close()
        print('load last saved function', n)
    except:
        n = 0
        print('load defaut function')

    while 1:

        try:

            if KEY == KEY_POWEROFF:
                poweroff()
            elif KEY == KEY_PREV:
                n = (n + len(fun_list) - 1)%len(fun_list)
            elif KEY == KEY_NEXT:
                n = (n + 1)%len(fun_list)
            elif KEY == KEY_RAND:
                while 1:
                    nn = rand(len(fun_list))
                    if nn != n:
                        n = nn
                        break
            elif KEY == KEY_SAV1 or KEY == KEY_SAV2:
                print('save function', n)
                f = open('last.fun', 'wb')
                f.write(bytes([n]))
                f.close()
            
            print('run <'+fun_list[n]+'>')
            exec('import '+fun_list[n])
            exec(fun_list[n]+'.run()')

        except KeyboardInterrupt:
            try:
                Pin(2, Pin.IN)
                exec('del '+fun_list[n])
                gc.collect()
                sleep_ms(500)
                print('continue')

            except KeyboardInterrupt:
                print('KeyboardInterrupt')
                KEY_cnt = KEY_CNT_MAX + 1
                Pin(2, Pin.IN)
                break

        except MemoryError:
            clear((32, 0, 0))
            print('memory error, free memory {}'.format(gc.mem_free()))
            reset()

        except Exception as e:
            print('except {}'.format(e))

main()

 

此帖出自单片机论坛

最新回复

那你们连接路由器这块怎么处理的呀?     详情 回复 发表于 2020-12-25 09:17
点赞 关注
 

回复
举报

1万

帖子

25

TA的资源

版主

沙发
 
本帖最后由 dcexpert 于 2020-10-6 18:55 编辑

程序分析

 

上电后,首先设置IO13为低电平,接管电源控制。

 

然后调用init()函数,闪烁WS2812,代表正常启动。

 

然后读取磁盘文件列表,并将以 “ef_”开头的文件保存到列表fun_list中,这是各种效果文件。注意文件名是区分大小写的。

 

后面是关机子程序,在关机前有一个小的动画,从亮变暗,代表关机动作。

 

接下来是按键处理部分。按键通过GPIO的中断触发,因为平时是高电平,触发后变低电平,因此使用下降沿方式触发。每个按键使用一个中断程序,中断后先设置标志位,然后判断计数,最大计数为3。然后在定时器中判断标志位,每100ms判断一次,从触发按键中断开始,判断1秒内按键的次数。然后将两个按键的技术合并为一个按键值(每个按键占用4bit),如果按键值在预设的按键列表中就通过串口1发送16进制数3。

 

最后是main()函数部分。首先打开文件 last.fun,它记录了默认的效果文件序号。如果这个文件不存在或者读取错误,就将默认序号设置为0。在主循环中,先判断按键状态,根据按键值进行不同处理,然后import对应的效果文件,并执行其中run()函数。

此帖出自单片机论坛
 
 

回复

1万

帖子

25

TA的资源

版主

板凳
 

从上面程序中可以看到,主循环是通过异常进行打断的,当出现按键中断,也就是在repl中的ctrl-c,或者是16进制数3。如果按一次ctrl-c,停止运行当前效果,并根据触摸按键的组合,执行后续动作。如果按下多次ctrl-c,则会退出主循环,方便系统调试。

 

ESP8266虽然有两个串口,但是串口0用于REPL了,不能使用,串口1只能发送,接收引脚被内部flash占用也不能使用。而串口1的TXD引脚就是IO2,因此我们还需要将IO2连接到ESP8266的RXD引脚上。不过这个连接需要等到主程序复制到ESP8266后才能进行,因为默认情况下IO2是输出高电平,会影响RXD的接收,造成无法进行后续操作,所以需要先将它设置为接收模式。等主程序运行起来后,在将IO2和RXD引脚短连起来。

 

此帖出自单片机论坛
 
 
 

回复

7608

帖子

2

TA的资源

五彩晶圆(高级)

4
 

谢谢分享,期待集中整理的大作.

此帖出自单片机论坛
 
个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 

回复

189

帖子

0

TA的资源

一粒金砂(中级)

5
 

from machine import Pin, lightsleep, Timer, UART, reset 这句话的这些资料在哪儿看呀,我怎么没有找到呀

此帖出自单片机论坛

点评

可以在中文教程或者《micropython入门指南》中查找,或者直接看官方的英文文档。  详情 回复 发表于 2020-12-17 09:53
 
个人签名单片机软件/硬件交流群:127034610
 
 

回复

1万

帖子

25

TA的资源

版主

6
 
liushiming82 发表于 2020-12-17 09:23 from machine import Pin, lightsleep, Timer, UART, reset 这句话的这些资料在哪儿看呀,我怎么没有找到呀 ...

可以在中文教程或者《micropython入门指南》中查找,或者直接看官方的英文文档。

此帖出自单片机论坛
 
 
 

回复

189

帖子

0

TA的资源

一粒金砂(中级)

7
 

这些文件在哪用找呀 

 

此帖出自单片机论坛
 
个人签名单片机软件/硬件交流群:127034610
 
 

回复

189

帖子

0

TA的资源

一粒金砂(中级)

8
 

ptyhon基于8266的用什么方式可以完成一键配网功能呀?谢谢

此帖出自单片机论坛

点评

好像有个ESPNow的功能,没有试过  详情 回复 发表于 2020-12-24 17:31
 
个人签名单片机软件/硬件交流群:127034610
 
 

回复

1万

帖子

25

TA的资源

版主

9
 
liushiming82 发表于 2020-12-24 16:40 ptyhon基于8266的用什么方式可以完成一键配网功能呀?谢谢

好像有个ESPNow的功能,没有试过

此帖出自单片机论坛
 
 
 

回复

189

帖子

0

TA的资源

一粒金砂(中级)

10
 

那你们连接路由器这块怎么处理的呀?

 

此帖出自单片机论坛

点评

这个版本的LED灯没有使用wifi或蓝牙功能  详情 回复 发表于 2020-12-25 09:45
 
个人签名单片机软件/硬件交流群:127034610
 
 

回复

1万

帖子

25

TA的资源

版主

11
 
liushiming82 发表于 2020-12-25 09:17 那你们连接路由器这块怎么处理的呀?  

这个版本的LED灯没有使用wifi或蓝牙功能

此帖出自单片机论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表