2554 views|10 replies

1w

Posts

25

Resources
The OP
 

【DIY Creative LED】Main Program [Copy link]

In order to facilitate expansion, this time the program is designed as a main program and an effect program. When powered on, ESP8266 searches the disk, finds all the effect files on the disk, and loads the default effect file for demonstration.

Here is the main program:

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()

This post is from MCU

Latest reply

How do you handle the connection to the router?   Details Published on 2020-12-25 09:17
 

1w

Posts

25

Resources
2
 
This post was last edited by dcexpert on 2020-10-6 18:55

Program Analysis

After power-on, first set IO13 to low level to take over power control.

Then the init() function is called to flash the WS2812, indicating a normal startup.

Then read the disk file list and save the files starting with "ef_" into the list fun_list, which are various effect files. Note that the file name is case sensitive.

The next part is the shutdown subroutine. Before the shutdown, there is a small animation that changes from bright to dark, representing the shutdown action.

Next is the key processing part. The key is triggered by the GPIO interrupt. Because it is usually high level, it becomes low level after being triggered, so it is triggered by the falling edge. Each key uses an interrupt program. After the interrupt, the flag is set first, and then the count is judged. The maximum count is 3. Then the flag is judged in the timer, once every 100ms, starting from the triggering of the key interrupt, and the number of key presses within 1 second is judged. Then the two key technologies are merged into one key value (each key occupies 4 bits). If the key value is in the preset key list, the hexadecimal number 3 is sent through serial port 1.

Finally, the main() function is opened. First, the file last.fun is opened, which records the default effect file number. If the file does not exist or there is a read error, the default number is set to 0. In the main loop, the key state is first determined, and different processing is performed according to the key value. Then, the corresponding effect file is imported and the run() function is executed.

This post is from MCU
 
 

1w

Posts

25

Resources
3
 

As can be seen from the above program, the main loop is interrupted by an exception, when a key interrupt occurs, that is, ctrl-c in repl, or the hexadecimal number 3. If ctrl-c is pressed once, the current effect is stopped and subsequent actions are performed according to the combination of touch keys. If ctrl-c is pressed multiple times, the main loop will be exited, which is convenient for system debugging.

Although ESP8266 has two serial ports, serial port 0 is used for REPL and cannot be used. Serial port 1 can only send, and the receiving pin is occupied by the internal flash and cannot be used. The TXD pin of serial port 1 is IO2, so we also need to connect IO2 to the RXD pin of ESP8266. However, this connection can only be made after the main program is copied to ESP8266, because by default IO2 outputs a high level, which will affect the reception of RXD and make subsequent operations impossible, so it needs to be set to receive mode first. After the main program is running, short the IO2 and RXD pins.

This post is from MCU
 
 
 

7422

Posts

2

Resources
4
 

Thank you for sharing, I look forward to your collection of masterpieces.

This post is from MCU
 
Personal signature

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

 
 

189

Posts

0

Resources
5
 

Where can I find the information about from machine import Pin, lightsleep, Timer, UART, reset? I can't find it.

This post is from MCU

Comments

You can look it up in the Chinese tutorial or the MicroPython Getting Started Guide, or read the official English documentation directly.  Details Published on 2020-12-17 09:53
 
Personal signature单片机软件/硬件交流群:127034610
 
 

1w

Posts

25

Resources
6
 
liushiming82 posted on 2020-12-17 09:23 from machine import Pin, lightsleep, Timer, UART, reset Where can I find the information in this sentence? I can't find it...

You can look it up in the Chinese tutorial or the MicroPython Getting Started Guide, or read the official English documentation directly.

This post is from MCU
 
 
 

189

Posts

0

Resources
7
 

Where can I find these files?

This post is from MCU
 
Personal signature单片机软件/硬件交流群:127034610
 
 

189

Posts

0

Resources
8
 

How can ptyhon based on 8266 complete the one-key network configuration function? Thank you

This post is from MCU

Comments

There seems to be an ESPNow feature, but I haven't tried it.  Details Published on 2020-12-24 17:31
 
Personal signature单片机软件/硬件交流群:127034610
 
 

1w

Posts

25

Resources
9
 
liushiming82 posted on 2020-12-24 16:40 How can ptyhon based on 8266 complete the one-key network configuration function? Thank you

There seems to be an ESPNow feature, but I haven't tried it.

This post is from MCU
 
 
 

189

Posts

0

Resources
10
 

How do you handle the connection to the router?

This post is from MCU

Comments

This version of the LED light does not use wifi or bluetooth capabilities  Details Published on 2020-12-25 09:45
 
Personal signature单片机软件/硬件交流群:127034610
 
 

1w

Posts

25

Resources
11
 
liushiming82 posted on 2020-12-25 09:17 How do you handle the connection to the router?

This version of the LED light does not use wifi or bluetooth capabilities

This post is from MCU
 
 
 

Guess Your Favourite
Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list