10679|7

53

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

microPython + esp8266 +tm1650= 网络时钟 [复制链接]

本帖最后由 是最帅的啊 于 2021-11-6 13:32 编辑

        大家好呀好久没有露面啦,问其原因肯定不是打游戏和陪女朋友啦。

        这次我给大家带来的是网络时钟,原理是这样的8266联网之后可以获取网络时间,ws2812可以测量环境温度,光敏电阻可以获取当前的光照强度,把他们组合在一起就可以做一个网络时钟啦。

        先不说了上视频

        原理其实很简单,多一点的是PCB布局和外壳制作,我想要的是一面全部都是数码管,因为数码管面积的限制和需要和外壳连接所以布局可用面积很小了。

        下面是我的原理图和PCB,需要的话也可以查看附件进行下载。

具体的实物效果图就如下所示

在正面有4个并排的数码管,我把第三个倒置过来了,用来模仿时间中的  : 符号,所以我对tm1650的原版进行了一定的修改。后面在代码段我会具体和大家讲解的。

在这一面中我画了4个定位孔,目的是让板子和外壳能连接起来,便于固定。孔径是M3的,支撑的螺柱是12mm的,板与板之间相互固定的螺丝是m2的,相关的资料请查看附件。

这是部分图纸

接下来是代码部分:下面是改的tm1650代码

 

'''
此函数只适用于李先生所画的错版TM1650,ET V1.0版本的灯,请勿对号入座
'''

from machine import I2C
from micropython import const

COMMAND_I2C_ADDRESS = const(0x24)
DISPLAY_I2C_ADDRESS = const(0x34)

buf = (0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71)
buf2 = (0x3f,0x30,0x5b,0x79,0x74,0x6d,0x6f,0x38,0x7f,0x7d)

class TM1650():
    def __init__(self,i2c):
        self.i2c = i2c
        self._intensity = 3
        self.dbuf = [0, 0, 0, 0]
        self.tbuf = bytearray(1)
        self.on()

#调节亮度,亮度范围为0-8,        
    def intensity(self, dat = -1):
        if dat < 0 or dat > 8:
            return self._intensity
        if dat == 0:
            self.off()
        else:
            self._intensity = dat
            self.cmd((dat<<4)|0x01)
#此行为写命令函数,地址位为0x24
    def cmd(self, c):
        self.tbuf[0] = c
        self.i2c.writeto(COMMAND_I2C_ADDRESS, self.tbuf)
#此行打开数码管        
    def on(self):
        self.cmd((self._intensity<<4)|0x01)    
#关闭数码管
    def off(self):
        self._intensity = 0
        self.cmd(0)

#此行为写数据函数,地址位为0x34        
    def dat(self, d, bit):
        self.tbuf[0] = d
        self.i2c.writeto(DISPLAY_I2C_ADDRESS + bit%4, self.tbuf)
#清除数码管的值
    def clear(self):
        self.dat(0, 0)
        self.dat(1, 0)
        self.dat(2, 0)
        self.dat(3, 0)
        self.dbuf = [0, 0, 0, 0]
#显示单个字的函数
    def showbit(self, num, bit = 0):
        if bit == 1:
            self.dbuf[1] = buf2[num]
            self.dat(buf2[num%10],bit)
        else:
            self.dbuf[bit] = buf[num%16]
            self.dat(buf[num%16],bit)
#显示数字的函数            
    def shownum(self,num):
        if num < 0 :
            self.dat(0x40,3)
            num = -num
        else :
            self.showbit(num//1000,3)
        self.showbit((num//100)%10,2)
        self.showbit((num//10)%10,1)
        self.showbit(num%10,0)
            
#打开点
    def showdp(self,show = True,bit=1):
        if show:
            self.dat(self.dbuf[bit] | 0x80,bit)
        else:
            self.dat(self.dbuf[bit] & 0x7F,bit)
#显示时间的函数
    def rtc_time(self,hour=0,minute=0):
        self.dat(buf[hour//10],3)
        self.dat(buf[hour%10]|0x80,2)
        self.dat(buf2[minute//10]|0x80,1)
        self.dat(buf[minute%10],0)
#显示温度的函数
    def temperature(self,num=10.1):
        if num >= 10 :
            num = num * 10
            
            self.dat(buf[int(num/100)],3)
            self.dat(buf[int(num/10%10)]|0x80,2)
            self.dat(buf2[int(num%10)],1)
            self.dat(buf[12],0)
        if 0 <= num < 10 :
            num = num * 100
            
            self.dat(buf[int(num/100)]|0x80,3)
            self.dat(buf[int(num/10%10)],2)
            self.dat(buf2[int(num%10)],1)
            self.dat(buf[12],0)
        if -10 < num < 0 :
            num = - num * 10
           
            self.dat(0x40,3)
            self.dat(buf[int(num/10)]|0x80,2)
            self.dat(buf2[int(num%10)],1)
            self.dat(buf[12],0)
        if num < -10 :
            num = - num           
            self.dat(0x40,3)
            self.dat(buf[int(num/10)],2)
            self.dat(buf2[int(num%10)],1)
            self.dat(buf[12],0)
            
            
            
        

接下来就是主程序了,在这里我选择使用的是网络时钟,但是经常刷新时间会报系统错误,暂时我也不知道是啥原因,所以我在这里恳请大家能给我解惑,谢谢啦。

from machine import I2C,Pin,RTC
import time,ntptime1
import tm1650
i2c = I2C(scl=Pin(4),sda=Pin(5),freq=100000)
tm = tm1650.TM1650(i2c)


#联网
def do_connect():
    import network
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    if not wlan.isconnected():
        print('没有连上网络')
        wlan.connect('你家的WiFi账号','你家的WiFi密码')
        while not wlan.isconnected():
            tm.dat(0x40,3)
            tm.dat(0x40,2)
            tm.dat(0x40,1)
            tm.dat(0x40,0)

#时间顺序排序                        
def wtime(h=0,m=0):
    tm.showbit(h//10,3)
    tm.showbit(h%10,2)
    tm.showbit(m//10,1)
    tm.showbit(m%10,0)
    tm.showdp(1,1)
    tm.showdp(1,2)

def main():
    i = 0
    do_connect()
    rtc=RTC()
    ntptime1.settime() # set the rtc datetime from the remote server
    while 1:
        if i > 5*60 : #每隔5分钟获取一次网络时间
            i = 0
            ntptime1.settime()
        etime=rtc.datetime()
        tm.rtc_time(etime[4]+8,etime[5])
        time.sleep(1)
        i = i + 1
        
main()        

最开始的时候,我以为是这个授时的服务器被我经常访问崩掉了,所以我把ntptime.py里面的网址改成国内的阿里云

try:
    import usocket as socket
except:
    import socket
try:
    import ustruct as struct
except:
    import struct

# (date(2000, 1, 1) - date(1900, 1, 1)).days * 24*60*60
NTP_DELTA = 3155673600

# The NTP host can be configured at runtime by doing: ntptime.host = 'myhost.org'
host = "ntp1.aliyun.com" #修改为国内的阿里云


def time():
    NTP_QUERY = bytearray(48)
    NTP_QUERY[0] = 0x1B
    addr = socket.getaddrinfo(host, 123)[0][-1]
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        s.settimeout(1)
        res = s.sendto(NTP_QUERY, addr)
        msg = s.recv(48)
    finally:
        s.close()
    val = struct.unpack("!I", msg[40:44])[0]
    return val - NTP_DELTA


# There's currently no timezone support in MicroPython, so
# utime.localtime() will return UTC time (as if it was .gmtime())
def settime():
    t = time()
    import machine
    import utime

    tm = utime.localtime(t)
    machine.RTC().datetime((tm[0], tm[1], tm[2], tm[6] + 1, tm[3], tm[4], tm[5], 0))

把更新的时间放缓了一点点,但是时间长了还是会有更新错误出现

对应的为ntptime1.py  中   msg = s.recv(48)这段代码,请求大家帮我看一下具体的原因,谢谢。

def time():
    NTP_QUERY = bytearray(48)
    NTP_QUERY[0] = 0x1B
    addr = socket.getaddrinfo(host, 123)[0][-1]
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        s.settimeout(1)
        res = s.sendto(NTP_QUERY, addr)
        msg = s.recv(48) #错误的点
    finally:
        s.close()
    val = struct.unpack("!I", msg[40:44])[0]
    return val - NTP_DELTA

        

8266时钟.pcbdoc

803.67 KB, 下载次数: 2

esp8266时钟.schdoc

228.07 KB, 下载次数: 3

最新回复

写的不错,帖子如其名,挺帅的。   详情 回复 发表于 2022-5-1 07:48
点赞(1) 关注(1)
 

回复
举报

1411

帖子

3

TA的资源

版主

沙发
 

问其原因肯定不是打游戏和陪女朋友啦,你这是不打自招吗?

 

不过感谢分享经验,很厉害!

个人签名

没有什么不可以,我就是我,不一样的烟火! 

 
 

回复

2万

帖子

71

TA的资源

管理员

板凳
 

嚯 看来是个爱动手的孩子。期待后续作品。

加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
个人签名

加油!在电子行业默默贡献自己的力量!:)

 
 
 

回复

1274

帖子

2

TA的资源

版主

4
 

WS2812是个灯,这玩意可不好获取温度

点评

什么意思啊,我不太明白  详情 回复 发表于 2021-11-17 14:45
 
 
 

回复

53

帖子

0

TA的资源

一粒金砂(中级)

5
 
通宵敲代码 发表于 2021-11-12 16:50 WS2812是个灯,这玩意可不好获取温度

什么意思啊,我不太明白

点评

[attachimg]573351[/attachimg]  详情 回复 发表于 2021-11-17 14:58
 
 
 

回复

1274

帖子

2

TA的资源

版主

6
 
是最帅的啊 发表于 2021-11-17 14:45 什么意思啊,我不太明白

 
 
 

回复

1632

帖子

4

TA的资源

纯净的硅(高级)

7
 

介绍里说的是WS2812,这个是LED驱动芯片。但是你实际用的是DS18b20

个人签名科技改变生活
 
 
 

回复

18

帖子

0

TA的资源

一粒金砂(中级)

8
 

写的不错,帖子如其名,挺帅的。

 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
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
快速回复 返回顶部 返回列表