再次升级:增加农历和天气预报

海鲜市场入手拟辉光管时钟,就是这货:

效果还是蛮炫的。

用了一年多,突然抽风,具体表现为自动切换为日期和星期显示,需要按键才能切回来,过一会儿又变成日期/星期。

原来是运行一个lixie_clock.exe程序,连接电脑进行各种设置和对时。但现在却死活再也连不上电脑。虽加了卖家微信,但不管微信或者海鲜市场联系,均无回应,估计卖家已随黄鹤去。

偶然看到ESP8266开发板才十块钱,遂动了给TA换心的念头。

买来8266 D1 mini开发板,lm386音频DAC(用于增加随音量闪烁功能)。花几个小时,动手焊了几根线,写了若干python程序。调试修Bug,搞定!

至此,将原来的STM32F103芯片主板替换掉,功能如下:

  • 连接wifi每小时自动对时(直接使用板上RTC,每小时可以误差30秒之多)
  • 三种模式随小时数轮换
  • 模式一、随音量大小闪烁(调节亮度),颜色为小时数对7取模
  • 模式二、时分秒6个灯按七彩颜色流转
  • 模式三、时分秒6个灯同色呼吸,按七彩颜色切换

三个python文件,传到8266板上:

;获得端口号,假定为COM4
esptool.py read_mac;刷入micropython固件
esptool.py -p COM4 erase_flash
esptool.py --port COM4 --baud 460800 write_flash --flash_size=detect 0 esp8266-20220618-v1.19.1.bin;上传文件
ampy -p COM4 put main.py
ampy -p COM4 put lx_clock.py
ampy -p COM4 put rainbow.py

micropython与python有些微差异,发现了就改之。

main.py就两行:

from lx_clock import lx_clocklx_clock()

rainbow.py:

import timeBRIGHT_STEPS = 32# micropython无deepcopy
def color_deepcopy(color_class):return Color(color_class.name, color_class.rgb, color_class.step)class Color:def __init__(self, name, rgb_tuple, step_tuple = (-1, -1, -1)):self.__name = nameself.r = rgb_tuple[0]self.g = rgb_tuple[1]self.b = rgb_tuple[2]self.__r_max = self.rself.__g_max = self.gself.__b_max = self.bself.__r_step = (step_tuple[0] == -1) and (self.__r_max / BRIGHT_STEPS) or step_tuple[0]self.__g_step = (step_tuple[1] == -1) and (self.__g_max / BRIGHT_STEPS) or step_tuple[1]self.__b_step = (step_tuple[2] == -1) and (self.__b_max / BRIGHT_STEPS) or step_tuple[2]# 亮度调节(百分比)def brightness(self, percent):if percent < 0 or percent > 1:return self.rgbself.r = self.__r_max * percentself.g = self.__g_max * percentself.b = self.__b_max * percentreturn self.rgb@property   def rgb(self):    return (int(self.r), int(self.g), int(self.b))@property   def name(self):    return self.__name@propertydef step(self):    return (self.__r_step, self.__g_step, self.__b_step)def grade(self, direct = 'down'):if direct == 'down':self.r = self.__grade_rgb(self.r, 0 - self.__r_step)self.g = self.__grade_rgb(self.g, 0 - self.__g_step)self.b = self.__grade_rgb(self.b, 0 - self.__b_step)else:self.r = self.__grade_rgb(self.r, self.__r_step)self.g = self.__grade_rgb(self.g, self.__g_step)self.b = self.__grade_rgb(self.b, self.__b_step)return self.rgbdef __grade_rgb(self, current_value, value):if current_value + value > 255:current_value = 255elif current_value + value < 0:current_value = 0else:current_value += valuereturn current_valueclass RainBow:def __init__(self, mode = 1):# step为默认,全亮 -> 全暗self.__color_def1 = [Color('red', (255, 0, 0)),Color('orange', (255, 125, 0)),Color('yellow', (255, 255, 0)),Color('green', (0, 255, 0)),Color('cyan', (0, 255, 255)),Color('blue', (0, 0, 255)),Color('violet', (255, 0, 255)),]# step为变化到下一个颜色self.__color_def2 = [Color('red', (255, 0, 0), (0, 165 / BRIGHT_STEPS, 0)),Color('orange', (255, 125, 0), (0, (255 - 125) / BRIGHT_STEPS, 0)),Color('yellow', (255, 255, 0), (0 - 255 / BRIGHT_STEPS, 0, 0)),Color('green', (0, 255, 0), (0, 0, 255 / BRIGHT_STEPS)),Color('cyan', (0, 255, 255), (0, 0 - 255 / BRIGHT_STEPS, 0)),Color('blue', (0, 0, 255), (255 / BRIGHT_STEPS, 0, 0)),Color('violet', (255, 0, 255), (0, 0, 0 - 255 / BRIGHT_STEPS)),]self.__colors = []self.__mode = modeif self.__mode == 1:for i in range(len(self.__color_def1)):self.__colors.append({'index': i, 'color': color_deepcopy(self.__color_def1[i])})else:self.__colors.append({'index': 0, 'color': color_deepcopy(self.__color_def2[0])})self.__colors.append({'index': 6, 'color': color_deepcopy(self.__color_def2[6])})self.__colors.append({'index': 5, 'color': color_deepcopy(self.__color_def2[5])})self.__colors.append({'index': 4, 'color': color_deepcopy(self.__color_def2[4])})self.__colors.append({'index': 3, 'color': color_deepcopy(self.__color_def2[3])})self.__colors.append({'index': 2, 'color': color_deepcopy(self.__color_def2[2])})self.__colors.append({'index': 1, 'color': color_deepcopy(self.__color_def2[1])})self.__current_step = 0self.__loop_times = 0def color_with_index(self, index = 0):for color in self.__colors:if color['index'] == index:return color['color']return self.__colors[0]['color']@property            def rgbs(self):rgbs = []for color in self.__colors:rgbs.append(color['color'].rgb)return rgbsdef magic(self):if self.__mode == 1:return self.__magic1()else:return self.__magic2()# 模式一:单色呼吸灯,全暗后切换下一颜色到全亮def __magic1(self):self.__current_step += 1if self.__current_step == BRIGHT_STEPS:self.__current_step = 0self.__loop_times += 1if self.__loop_times % 2 != 0:for color in self.__colors: # 颜色移位color['index'] += 1if color['index'] == len(self.__colors):color['index'] = 0for color in self.__colors: # 重新初始化color_class,全暗idx = color['index']color['color'] = color_deepcopy(self.__color_def1[idx])color['color'].brightness(0)else:for color in self.__colors: # 重新初始化color_class,全亮color['color'].brightness(1)else:if self.__loop_times % 2 == 0:for color in self.__colors:color['color'].grade('down')else:for color in self.__colors:color['color'].grade('up')return self.rgbs# 模式二:七彩色,直接切换到下一颜色def __magic2(self):self.__current_step += 1if self.__current_step == BRIGHT_STEPS:self.__current_step = 0for color in self.__colors: # 颜色移位color['index'] += 1if color['index'] == len(self.__colors):color['index'] = 0for color in self.__colors: # 重新初始化color_classidx = color['index']color['color'] = color_deepcopy(self.__color_def2[idx])else:for color in self.__colors:color['color'].grade('up')return self.rgbs

lx_clock.py,请修改83行wifi的SSID和密码:

from machine import Pin, ADC, Timer, RTC
from neopixel import NeoPixel
import network, time, ntptimeHOLD_TIME_MS = 30   # 保持时间(毫秒)
MAX_VOLUME_VAL = 64 # 最大音量ADC值# 时间转换为led位置
def time2pos(now_time):led_sn = (9, 4, 8, 3, 7, 2, 6, 1, 5, 0)return (led_sn[int(now_time[4] / 10)],led_sn[int(now_time[4] / 10)] + 10,led_sn[now_time[4] % 10] + 20,led_sn[now_time[4] % 10] + 30,led_sn[int(now_time[5] / 10)] + 40,led_sn[int(now_time[5] / 10)] + 50,led_sn[now_time[5] % 10] + 60,led_sn[now_time[5] % 10] + 70,led_sn[int(now_time[6] / 10)] + 80,led_sn[int(now_time[6] / 10)] + 90,led_sn[now_time[6] % 10] + 100,led_sn[now_time[6] % 10] + 110,)def magic1(np, now_time, rainbow):light_sn = time2pos(now_time)rgbs = rainbow.magic()for i in range(np.n):if i in light_sn:np[i] = rgbs[0]else:np[i] = (0, 0, 0)np.write()def magic2(np, now_time, rainbow):light_sn = time2pos(now_time)rgbs = rainbow.magic()for i in range(np.n):if i in light_sn:np[i] = rgbs[int(i / 20 % 7)]else:np[i] = (0, 0, 0)np.write()def bright_volume(np, now_time, pot, sound_rainbow):light_sn = time2pos(now_time)rainbox_index = now_time[4] / 3 % 7volume = pot.read()if volume > MAX_VOLUME_VAL:volume = MAX_VOLUME_VALglobal last_volumeif last_volume == volume:returnlast_volume = volumefor i in range(np.n):if i in light_sn:np[i] = sound_rainbow.color_with_index(rainbox_index).brightness(volume / MAX_VOLUME_VAL)else:np[i] = (0, 0, 0)np.write()def minute_work(t_minute):sync_ntp()def do_connect():sta_if = network.WLAN(network.STA_IF)if not sta_if.isconnected():print('connecting to network...')sta_if.active(True)sta_if.connect('SSID', 'wifi密码') # 需修改SSID和密码while not sta_if.isconnected():passprint('network config:', sta_if.ifconfig())def sync_ntp():now_time = RTC().datetime() # 年、月、日、星期、小时、分钟、秒、亚秒global last_ntp_sync_hourif last_ntp_sync_hour == now_time[4] and now_time[6] > 30: # 一小时同步一次returndo_connect() # 连接网络,如已连接则自动忽略ntptime.NTP_DELTA = 3155644800    # 可选UTC+8偏移时间(秒),不设置就是UTC0ntptime.host = 'ntp1.aliyun.com'  # 可选,ntp服务器,默认是pool.ntp.orgntptime.settime()                 # 修改设备时间synced_time = RTC().datetime() # 年、月、日、星期、小时、分钟、秒、亚秒last_ntp_sync_hour = synced_time[4]def lx_clock(loop_times = -1, mode = -1):global last_ntp_sync_hourlast_ntp_sync_hour = -1pin = Pin(15, Pin.OUT)    # set GPIO15 to output to drive NeoPixelsnp = NeoPixel(pin, 120)   # create NeoPixel driver on GPIO0 for 120 pixelsfrom rainbow import RainBow    sound_rainbow = RainBow()magic_rainbow1 = RainBow(1)magic_rainbow2 = RainBow(2)# period最大0xCCCCCCCC=5540小时或221天t_minute = Timer(-1)t_minute.init(period = 1000 * 10, mode = Timer.PERIODIC, callback = minute_work)global last_volumelast_volume = 0pot = ADC(0)while loop_times != 0:now_time = RTC().datetime() # 年、月、日、星期、小时、分钟、秒、亚秒hour = now_time[4]if mode == 0:bright_volume(np, now_time, pot, sound_rainbow)elif mode == 1:magic1(np, now_time, magic_rainbow1)elif mode == 2:magic2(np, now_time, magic_rainbow2)else:if hour % 3 == 0:bright_volume(np, now_time, pot, sound_rainbow)elif hour % 3 == 1:magic1(np, now_time, magic_rainbow1)elif hour % 3 == 2:magic2(np, now_time, magic_rainbow2)time.sleep_ms(HOLD_TIME_MS)if loop_times > 0:loop_times -= 1t_minute.deinit()

ESP8266 D1 mini开发板:

几点说明:

  1. ws2812b灯板连接到15、GND、VBUS;
  2. lm386连接到A0、3.3V,GND与灯板共用;
  3. 灯板共有120个LED,排列方式不同厂家出品可能不同,可调整time2pos函数中的对应灯号;
  4. 无lm386,则需要去掉对应代码,并屏蔽模式一;
  5. 请修改83行WiFi的SSID和密码。

这种时钟原理很巧妙,程序代码相对简单。这里有网站。

顺手多买了一个0.96寸oled显示屏,准备尝试放上农历天气啥的,弄完继续分享源码。

拟辉光管时钟“重生”记(源码)相关推荐

  1. 【开源】纯手工低成本打造拟辉光管时钟,也可以很酷炫

    不想错过我的推送,记得右上角-查看公众号-设为星标,摘下星星送给我 <命运石之门>里 "世界线变动率探测仪",各种辉光管的作品,让热爱DIY的小伙伴欢喜,但是辉光管的价 ...

  2. ESP32制作一个拟辉光管时钟

    拟辉光管时钟 60 多年过去了,尽管辉光管已经停产,有很多工程师仍然对它情有独钟.我用 8 块液晶显示屏制作了一个拟辉光管时钟,感受复古元素的美感,表达对过去经典的敬意. 项目起源 看过<命运石 ...

  3. #教你从零制作拟辉光管时钟#

    #制作电路板 #设计制作 方案确定后,即可展开制作,制作之前先来看一下制作拟辉光管时钟所需的物料 物料清单: Esp8266控制器 *1 PCB灯板 *6 ws2812灯带 1条 50*30mm透明亚 ...

  4. 自己制作“EleksTubeIPS创意复古RGB拟辉光管时钟”分享《一》---(持续更新2021-12-17)

    1.先来一张正儿八经的产品图 相当的帅气!可惜腰包不给力就只能自己动手丰衣足食了!!! 2.材料分析(因为贫穷只能看图说话了!) 外壳:外壳看成色有种金属质感(磨砂带颗粒的)但是我上网查了半天并没有找 ...

  5. 自己制作“EleksTubeIPS创意复古RGB拟辉光管时钟”分享《四》-(持续更新2022-2-28)

    很抱歉好久没有更新了! 因为改动比较大所以更新慢了点,之前总想着使用stm32单片机做但是为了控制成本一直提高不了刷新效率,后来在热心网友的帮助下选择了ESP32来做,今天刚刚有点成绩,就迫不及待的想 ...

  6. 自己制作“EleksTubeIPS创意复古RGB拟辉光管时钟”分享《二》---(持续更新2021-12-22)

    一.前期的准备工作 1.经过漫长的等待pcb等一系列物料都一一到齐了,下图为本次的物料 二.测试版的制作 1.首先焊接两个屏幕小板和一个底板,如下图所示, 2.接下来就是写代码了.代码直接放到最后的下 ...

  7. 自己制作“EleksTubeIPS创意复古RGB拟辉光管时钟”分享《三》---(持续更新2021-12-27,2021-12-28新增修改)

    一,如何解决屏幕刷新速率的问题 1.目前能达到的刷新速率,因为没有办法连续刷新,只能按复位来看图片的刷新速率,显然速度还是很慢. STM32F103驱动屏幕显示图片目前能达到的速度 2.理论上可以达到 ...

  8. 【单片机】辉光管时钟系列<一>--单片机最小系统

    已经有两个多月没有写文章了,这两个多月都忙着毕业的事.在业务时间也重拾了大学期间的单片机知识,准备做个辉光管时钟.现在程序和电路都已经完成了,就等着PCB板回来了.下面我将以一系列的文章来介绍辉光管时 ...

  9. 【单片机】辉光管时钟系列<四>温度芯片DS18B20显示

    在辉光管时钟里,我们还加入了温度显示功能.这里,我们采用简单易用的温度芯片DS18B20来测量环境温度.DS18B20是常用的数字温度传感器,具有体积小,硬件开销低,抗干扰能力强,精度高的特点. 本文 ...

最新文章

  1. 诺基亚塞班系列最强回顾(搬运整理)
  2. qt designer python显示_请问在python怎么使用qtdesigner设计的ui?
  3. sas table将缺失值计入百分比_医药SAS编程及应用之爱情草全部发芽啦
  4. PopupWindow 使用详解(二) Popwindow 制作常见花哨效果
  5. 相邻数字+(正月点灯笼的动态规划2)(递归+DP)---JAVA
  6. codeforces 69A-C语言解题报告
  7. mac电脑如何与手机同步复制粘贴_如何将电脑里的文件同步到手机里?
  8. I am BACKKKKKK
  9. Golang Http Server源码阅读
  10. 蓝桥杯2019年第十届C/C++省赛第六题-旋转
  11. 网页设计心得HTML心得体会3000,网页制作的心得体会
  12. git 小乌龟 配置_git 小乌龟安装教程
  13. 苹果11蓝牙配对不成功怎么办_【苹果手机蓝牙不能配对】苹果手机蓝牙无法配对_苹果手机蓝牙怎么配对...
  14. 《第一行代码第三版》总结篇
  15. 电脑的wifi天线原理_详解无线路由器天线的原理
  16. 1.操作系统的基本特性和主要功能
  17. 聚币网API[Python3版]
  18. 用 UrlSchemes 实现调用应用并传参
  19. 【LeetCode/力扣】1723. 完成所有工作的最短时间
  20. Elasticsearch7.17 一: 快速入门

热门文章

  1. 3、Modbus通讯协议详解
  2. Web Wiz Forums 12.03 ASP论坛程序源码
  3. linux---设置环境变量
  4. 人工智能之数学基础----连续性和可导性
  5. 姓名 艺名Dean Wang
  6. Linux构建高效FTP服务器
  7. 低供电电压CMOS偏置电路分析(有些类似于三支路电流源)
  8. 西班牙SAPEC测试UHD 8K视频压缩技术
  9. 全网最全的鸿蒙源码结构分析(附自制4张架构图)
  10. PPU时代来临——AGEIA物理加速卡全面解析(zz