用esp8266做一个网络时钟

一、产品简介

​ TM1638是深圳市天微电子有限公司设计的一款带键盘扫描接口的LED(发光二极管显示器)驱动控制专用芯片,内部集成有MCU数字接口、数据锁存器、LED高压驱动、键盘扫描等电路。主要应用于冰箱、空调 、家庭影院等产品的高段位显示屏驱动。

​ TM1638按键数码管LED显示模块是用TM1638芯片驱动,集合了单片机常用外围电路,最大特点是只需要占用单片机三个IO口即可驱动,扫描显示和按键扫描不需要单片机干预,只需要读写相关寄存器送显示数据或检测按键,节省MCU资源。

用esp8266做一个网络时钟_第1张图片

引脚定义(采用SPI通信协议):

  • VCC:DC-5V
  • GND:GND
  • STB:MOSI
  • CLK:SCLK
  • DIO:MISO

二、技术参数

  • 采用功率CMOS 工艺
  • 显示模式 10 段×8 位
  • 键扫描(8×3bit)
  • 8级辉度可调
  • 串行接口(CLK,STB,DIO)
  • 振荡方式:RC 振荡(450KHz+5%)
  • 内置上电复位电路
  • 采用SOP28封装

三、软件接口

驱动下载地址https://github.com/mcauser/micropython-tm1638

Methods

Power up, power down or check status.

power(val=None)

Get or set brightness.

brightness(val=None)

Write zeros to each address.

clear()

Write to all 16 addresses from a given position. Order is left to right, 1st segment, 1st LED, 2nd segment, 2nd LED etc.

write(data, pos=0)

Set the value of a single LED.

led(pos, val)

Set all LEDs at once. LSB is left most LED. Only writes to the LED positions (every 2nd starting from 1).

leds(val)

Set one or more segments at a relative position. Only writes to the segment positions (every 2nd starting from 0).

segments(segments, pos=0)

Return a byte representing which keys are pressed. LSB is SW1.

keys()

Convert a single hex digit (0x00-0x0f) to a segment.

encode_digit(digit)

Convert a string to a list of segments. Dots are merged with the previous character.

encode_string(string)

Convert a single character to a segment.

encode_char(char)

Display a number in hexadecimal format 00000000 through FFFFFFFF, right aligned, leading zeros.

hex(val)

Display a numeric value -9999999 through 99999999, right aligned.

number(num)

Display a temperature -9 through 99 followed by degrees C.

temperature(num, pos=0)

Displays a relative humidity -9 through 99 followed by RH.

humidity(num, pos=4)

Displays as much of a string as will fit.

show(string, pos=0)

Display a string, scrolling from the right to left, speed adjustable. String starts off-screen right and scrolls until off-screen left at 4 FPS by default.

scroll(string, delay=250)

四、接口案例

利用esp8266显示时钟

接线:

ESP8266 LED&KEY TM1638 Module
3V3 (or 5V) VCC
G GND
D7 (GPIO13) STB
D5 (GPIO14) CLK
D6 (GPIO12) DIO

模块导入:

from package import tm1368 as tm1638
from package import alarm as am
from machine import Pin,RTC
import time
from package import WiFi
import ntptime
import network
import uasyncio as asyncio
#import upip #用于安装asyncio库
#upip.install("_thread")

引脚定义:

rtc = RTC()
'''
D7 (GPIO13)	STB
D5 (GPIO14)	CLK
D6 (GPIO12) DIO
'''
tm=tm1638.TM1638(stb=Pin(13),clk=Pin(14),dio=Pin(12)) ##标号一致 板子有标记

全局变量:

alarm_hour = 12
alarm_minute = 0
alarm_flag = True #闹钟开关
alarm_status = False #闹钟状态

hour = 13
minute = 14
second = 0
year = 2022
month = 5
day = 20

'''
mode = 0 显示时间
mode = 1 显示日期
mode = 2 显示闹钟
'''
mode = 0

联网同步时间:

#联网并同步时间
WiFi.WIFI_Connect()
WiFi.sync_ntp()
last_sync_time = 0
print(rtc.datetime())
print("同步后本地时间:%s" %str(time.localtime()))

显示时间:

def display_time():#时间显示画面
    #tm.clear()
    global hour
    global minute
    global second
    now_time = "{:0>2d}-{:0>2d}-{:0>2d}".format(hour,minute,second)
    # print(now_time)
    tm.show(now_time)

显示日历:

def display_calendar():#日历显示画面
    global month
    global day
    global year
    now_calendar = "{}.{:0>2d}.{:0>2d}".format(year,month,day)
    tm.show(now_calendar)

显示闹钟:

def display_alarm():#闹钟显示画面
    global alarm_hour
    global alarm_minute
    global alarm_flag
    if alarm_flag == 1 :
        status = '-11-'
    else:
        status = 'off-'
        #print(status)
    alarm = "{}{:0>2d}.{:0>2d}".format(status,alarm_hour,alarm_minute)
    tm.show(alarm)

闹钟设置(只设置了led流水灯,没用蜂鸣器):

async def mode1():
    b = 0x80
    t = 0
    for i in range(8):
        b = 0x80
        for j in range(8-i):
            st = b | t
            tm.leds(st)
            time.sleep(0.3)
            await asyncio.sleep(0.3)
            b = cror(b,1)
        b = crol(b,1)
        t = b | t

按键设置:

def set_model():#设置模式,选择显示内容
    k = [0] *9
    k = key_num(k)
    
    n = button(k)
    global alarm_hour
    global alarm_minute
    global mode
    global alarm_flag
    if n == 1:#闹钟小时增加
        if flag[n] == 0:
            alarm_hour +=1
            if alarm_hour > 23:
                alarm_hour = 0
            flag[n] = 1
    elif n == 2:#闹钟小时减少
        if flag[n] == 0:
            flag[n] = 1
            alarm_hour -=1
            if alarm_hour < 0:
                alarm_hour = 23
    elif n == 3:#闹钟分钟增加
        if flag[n] == 0:
            flag[n] = 1
            alarm_minute += 1
            if alarm_minute > 59:
                alarm_minute = 0
    
    elif n == 4:#闹钟分钟减少
        if flag[n] == 0:
            flag[n] = 1
            alarm_minute -= 1
            if alarm_minute < 0:
                alarm_minute = 59
    elif n ==5:#显示输出模式:时间、日历、闹钟
        if flag[n] == 0:
            flag[n] = 1
            mode = (mode+1)%3
    elif n == 6:#设置闹钟开关
        if flag[n] == 0:
            flag[n] = 1
            alarm_flag = ~ alarm_flag
            #print(alarm_flag)
    for i in range(1,len(k)):#按钮标志复位,防止连续按下
        if k[i] == 0 :
            flag[i] = 0

显示模块:

async def display():
  global year
  global month
  global day
  global hour
  global minute
  global second
  global alarm_flag
  global alarm_status
  while 1:
    t = time.localtime(time.time())
    year = t[0]
    month = t[1]
    day = t[2]
    hour = t[3]
    Synchronize_network_time(hour)
    minute = t[4]
    second = t[5]
    tm.brightness(0)
    if mode == 0:
        display_time()
    elif mode == 1:
        display_calendar()
    elif mode == 2:
        display_alarm()
    alarm_status = alarm_hour == hour and alarm_minute == minute
    set_model()
    await asyncio.sleep(0.05)

五、详细代码:

alarm.py

from package import tm1368 as tm1638
from machine import Pin
import time
import uasyncio as asyncio
tm=tm1638.TM1638(stb=Pin(13),clk=Pin(14),dio=Pin(12)) ##标号一致 板子有标记
def crol(d,k):#循环左移
    a = 1
    for i in range(0,k-1):
        a = (a << 1) + 1
    a = a<<(8-k)
    h = (d & a ) >> (8-k)
    d = ((d | a ) << k)%256 + h
    #print("d = {:0>8b},h = {:0>8b},a = {:0>8b}".format(d,h,a))
    return d
def cror(d,k):#循环右移
    a = 1
    for i in range(0,k-1):
        a = (a << 1) + 1
    h = (d & a ) << (8-k)
    d = (d >> k) + h
    print("d = {:0>8b},h = {:0>8b},a = {:0>8b}".format(d,h,a))
    return d
async def mode1():
    b = 0x80
    t = 0
    for i in range(8):
        b = 0x80
        for j in range(8-i):
            st = b | t
            tm.leds(st)
            time.sleep(0.3)
            await asyncio.sleep(0.3)
            b = cror(b,1)
        b = crol(b,1)
        t = b | t
def off():
    b = 0x00
    tm.leds(b)
def led():
    st = 0xaa
    status = []
    mode1()
if __name__ == '__main__':
    while True:
        led()

WIFI.py

import ntptime
import network,time
from machine import RTC,Pin
rtc = RTC()

print("同步前本地时间:%s" %str(time.localtime()))

# 联WIFI
def WIFI_Connect():

    wlan = network.WLAN(network.STA_IF) #STA模式
    wlan.active(True)                   #激活接口
    start_time=time.time()              #记录时间做超时判断
    if not wlan.isconnected():
        print('connecting to network...')
        wlan.connect('ssid', 'password') #输入WIFI账号密码
        while not wlan.isconnected():
            if time.time()-start_time > 15 :
                print('WIFI Connected Timeout!')
                break
    if wlan.isconnected():
        print('connected!')
        print('network information:', wlan.ifconfig())

# 同步时间
def sync_ntp():
     ntptime.NTP_DELTA = 3155644800   # 可选 UTC+8偏移时间(秒),不设置就是UTC0
     ntptime.host = 'ntp1.aliyun.com'  # 可选,ntp服务器,默认是"pool.ntp.org"
     try:
         ntptime.settime()   # 修改设备时间,到这就已经设置好了
     except:
         #for i in range(6):
         #   led.value(1)              #turn off 0是亮
          #  time.sleep(0.1)
          #  led.value(0)             
           # time.sleep(0.1)
         print('同步失败')

if __name__ == '__main__':
    WIFI_Connect()
    sync_ntp()
    print(rtc.datetime())
    print("同步后本地时间:%s" %str(time.localtime()))



main.py

from package import tm1368 as tm1638
from package import alarm as am
from machine import Pin,RTC
import time
from package import WiFi
import ntptime
import network
import uasyncio as asyncio
rtc = RTC()
'''
D7 (GPIO13)	STB
D5 (GPIO14)	CLK
D6 (GPIO12) DIO
'''
tm=tm1638.TM1638(stb=Pin(13),clk=Pin(14),dio=Pin(12)) ##标号一致 板子有标记

alarm_hour = 12
alarm_minute = 0
alarm_flag = True #闹钟开关
alarm_status = False #闹钟状态

hour = 13
minute = 14
second = 0
year = 2022
month = 5
day = 20

#k = [0]*9
'''
mode = 0 显示时间
mode = 1 显示日期
mode = 2 显示闹钟
'''
mode = 0
#联网并同步时间
WiFi.WIFI_Connect()
WiFi.sync_ntp()
last_sync_time = 0
print(rtc.datetime())
print("同步后本地时间:%s" %str(time.localtime()))

def key_num(k):#这个类是按钮用的,凑合用用
  if tm.keys()==1:
    k[1]=1
  elif tm.keys()==2:
    k[2]=1
  elif tm.keys()==4:
    k[3]=1
  elif tm.keys()==8:
    k[4]=1
  elif tm.keys()==16:
    k[5]=1
  elif tm.keys()==32:
    k[6]=1
  elif tm.keys()==64:
    k[7]=1
  elif tm.keys()==128:
    k[8]=1
  return k
        
def display_time():#时间显示画面
    #tm.clear()
    global hour
    global minute
    global second
    now_time = "{:0>2d}-{:0>2d}-{:0>2d}".format(hour,minute,second)
    # print(now_time)
    tm.show(now_time)
    
def display_calendar():#日历显示画面
    global month
    global day
    global year
    now_calendar = "{}.{:0>2d}.{:0>2d}".format(year,month,day)
    tm.show(now_calendar)

def display_alarm():#闹钟显示画面
    global alarm_hour
    global alarm_minute
    global alarm_flag
    if alarm_flag == 1 :
        status = '-11-'
    else:
        status = 'off-'
        #print(status)
    alarm = "{}{:0>2d}.{:0>2d}".format(status,alarm_hour,alarm_minute)
    tm.show(alarm)
    
flag = [0]*9 #按键标志
def button(k):
    for i in range(len(k)):
        if k[i]==1:
            return i
    return 0

def set_model():#设置模式,选择显示内容
    k = [0] *9
    k = key_num(k)
    
    n = button(k)
    global alarm_hour
    global alarm_minute
    global mode
    global alarm_flag
    if n == 1:#闹钟小时增加
        #print(n,flag[n],flag[2])
        if flag[n] == 0:
            alarm_hour +=1
            if alarm_hour > 23:
                alarm_hour = 0
            flag[n] = 1
    elif n == 2:#闹钟小时减少
        #print(n,flag[n],flag[1])
        if flag[n] == 0:
            flag[n] = 1
            alarm_hour -=1
            if alarm_hour < 0:
                alarm_hour = 23
    elif n == 3:#闹钟分钟增加
        if flag[n] == 0:
            flag[n] = 1
            alarm_minute += 1
            if alarm_minute > 59:
                alarm_minute = 0
    
    elif n == 4:#闹钟分钟减少
        if flag[n] == 0:
            flag[n] = 1
            alarm_minute -= 1
            if alarm_minute < 0:
                alarm_minute = 59
    elif n ==5:#显示输出模式:时间、日历、闹钟
        if flag[n] == 0:
            flag[n] = 1
            mode = (mode+1)%3
    elif n == 6:#设置闹钟开关
        if flag[n] == 0:
            flag[n] = 1
            alarm_flag = ~ alarm_flag
            #print(alarm_flag)
    for i in range(1,len(k)):#按钮标志复位,防止连续按下
        if k[i] == 0 :
            flag[i] = 0
            
def Synchronize_network_time(hour):#每六个小时同步时间
    global last_sync_time
    if hour %6 == 0 and hour!= last_sync_time:
        wlan = network.WLAN(network.STA_IF) #STA模式
        if not wlan.isconnected():
            #print("正在连接网络")
            WiFi.WIFI_Connect()
        WiFi.sync_ntp()
        print('{hour}同步成功')
        last_sync_time == hour
''' 按下第 n 个按钮 k[n] = 1'''
async def alarm():
    global alarm_flag
    global alarm_status
    if alarm_flag == 1 and alarm_status == 1:
        
        await am.mode1()
    else:
        am.off()
        
async def alarm_test():
    while True:
        await alarm()
        
        await asyncio.sleep(1)
        
        
async def display():
  global year
  global month
  global day
  global hour
  global minute
  global second
  global alarm_flag
  global alarm_status
  while 1:
    t = time.localtime(time.time())
    year = t[0]
    month = t[1]
    day = t[2]
    hour = t[3]
    Synchronize_network_time(hour)
    minute = t[4]
    second = t[5]
    tm.brightness(0)
    if mode == 0:
        display_time()
    elif mode == 1:
        display_calendar()
    elif mode == 2:
        display_alarm()
    alarm_status = alarm_hour == hour and alarm_minute == minute
    set_model()
    await asyncio.sleep(0.05)
        
loop = asyncio.get_event_loop()
loop.create_task(alarm_test())
loop.create_task(display())
loop.run_forever()

你可能感兴趣的:(esp8266,microPython,网络,单片机,嵌入式硬件)