- 2024-12-16
-
加入了学习《FollowMe 第二季: 1 Adafruit Circuit Playground Express及任务讲解》,观看 Adafruit Circuit Playground Express 及任务讲解
- 2024-11-17
-
加入了学习《电网自动化设备模拟前端设计要点以及 TI 方案》,观看 1.1 电网基础设施及交流模拟信号输入模块
- 2024-10-15
-
加入了学习《随身信息牌DIY》,观看 随身信息牌测试视频
-
加入了学习《随身信息牌DIY》,观看 随身信息牌测试视频
- 2024-09-30
-
加入了学习《直播回放: FollowMe 4 W5500-EVB-Pico 使用入门》,观看 W5500-EVB-Pico 使用入门
- 2024-06-28
-
加入了学习《Digi-Key: Follow Me 系列(2) 直播回放》,观看 Adafruit ESP32-S3 TFT Feather开发板使用入门
- 2024-05-13
-
回复了主题帖:
【2023 DigiKey大赛参与奖】RaspberryPI 3B+ 开箱帖
Jacktang 发表于 2024-5-12 22:03
拆箱的小刀真不赖,瑞士小军刀?
哈哈 ,不是瑞士小军刀, 不太好买的“玩具小刀”
- 2024-05-12
-
发表了主题帖:
【2023 DigiKey大赛参与奖】RaspberryPI 3B+ 开箱帖
感谢得捷和EEWORLD,这次活动获得了参与奖。我用参与奖购买了一个Raspberry Pi 3B+ 和一片MP3429
PS:为什么是3B+?因为奖金只能够买一个3B+
- 2024-01-28
-
发表了主题帖:
【Luckfox RV1103 测评】开箱贴
Luckfox开发板官方提供了很多上手教程:Luckfox WIKI
引用一段官方的简介:
LuckFox Pico、Luckfox Pico Mini A/B 与 LuckFox Pico Plus 是基于瑞芯微 RV1103 芯片的低成本微型 linux 开发板,而 LuckFox Pico Pro 与 LuckFox Pico Max 是基于瑞芯微 RV1106 芯片的低成本微型 linux 开发板。RV1103/RV1106 是一款专门用于人工智能相关应用的高度集成 IPC 视觉处理器 SoC。它基于单核 ARM Cortex-A7 32 位内核,集成了 NEON 和 FPU,并内置 NPU 支持 INT4 / INT8 / INT16 混合运算,计算能力高达 0.5TOPs。
此外,它采用了全新的基于硬件的 ISP,支持多种算法加速器,如 HDR、3A、LSC、3DNR、2DNR、锐化、去雾、伽马校正等。同时,它还具有内置的16位DRAM DDR2,可维持要求苛刻的内存带宽,以及内置的 POR,音频编解码器和 MAC PHY。总之,RV1103/RV1106 是一款功能强大的处理器,适用于各种人工智能应用场景。
我收到的是Luckfox Pico Mini B款开发板,搭载的RV1103
板子整体非常小巧,在上周我自己刚好也买了Luckfox的 LuckFox Pico Plus 版本,后面整体对比测评看看。
- 2024-01-20
-
回复了主题帖:
这个基于车载UWB雷达的车内检测方案看着有点厉害呀~~
不需要别的,uwb技术可以测心跳 你敢信
- 2024-01-18
-
回复了主题帖:
测评入围名单: Luckfox幸狐 RV1103 Linux 开发板
个人信息无误,确认可以完成评测计划
- 2024-01-15
-
加入了学习《基于RP2040的智能信息显示屏》,观看 基于RP2040的智能信息显示屏
-
发表了主题帖:
【DigiKey“智造万物,快乐不停”创意大赛】基于RP2040的智能信息显示屏
基于RP2040的智能信息显示屏
作者:JustD0
一、作品简介
智能信息显示屏使用树莓派的MCU-RP2040作为主控,以RGB LED点阵作为显示屏,用来显示智能生活提醒信息。最初设想是使用显示屏的方式来提醒居家的一些信息,比如时间、天气情况、根据天气情况给出一些出行建议,上班通勤路线拥堵提醒、b站粉丝量等等信息,还有根据心情、时间计划安排智能的提醒一些小动画,下面两张图是创意设想的草图:
二、系统框图
功能定义图:
硬件设计:
由于时间紧张,在选型阶段就选用整体硬件上采用RP2040的LED点阵屏开发板来实现功能:
软件设计:
软件系统整体分为两个部分:服务器端和从机端,服务器端主要实现对天气信息分析产生穿搭建议、通过路况信息分析拥堵情况,并通过文字转语音工具将整理好的建议文本朗读出来,并保存为音频文件,同时服务器端还搭建了mqtt server,可以提供mqtt通讯,传输以上信息。从机端主要是通过网络获取时间,通过mqtt协议获取天气、路况、穿搭以及建议的音频,进行适时播放显示。
由于RP2040能够很好的支持micropython开发,micropython对于快速功能验证简直不要太好用,所以整体采用micropython作为从机端的开发,而服务器端也采用python的方式实现。
三、各部分功能说明
开机过程,会显示digikey的logo和eeworld的logo,在此过程中,智能信息牌会去连接家里的路由器,初始化显示屏、网络、时间以及mptt客户端等。
disp = Display()
disp.draw_image(digikey_logo)
disp.brightness_ramp(1)
time.sleep(1)
# 连接网络
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.config(pm=0xa11140) # Turn WiFi power saving off for some slow APs
wlan.connect(param['SSID'], param['PSK'])
# Wait for connect success or failure
max_wait = 100
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break
max_wait -= 1
print('waiting for connection...')
time.sleep(0.2)
if max_wait > 0:
print("Connected")
clock = Clock()
bili = Bilibili()
# 显示eeword图案
disp.brightness_ramp(-1)
disp.draw_color(disp.BLACK)
disp.draw_image(eeworld_logo)
disp.brightness_ramp(1)
time.sleep(1)
disp.draw_color(disp.BLACK)
weather_dict = {'skycon':b'sun','comfort': b'short','equip':b'none'}
sound_file = None
def mqtt_recv(topic, msg):
global weather_dict,sound_file
if topic == b'info_skycon':
weather_dict['skycon'] = msg
if topic == b'info_comfort':
weather_dict['comfort'] = msg
if topic == b'info_equip':
weather_dict['equip'] = msg
if topic == b'sound_status':
if msg == b'start':
sound_file = open('sound.pdm','w')
elif msg == b'stop':
sound_file.close()
if topic == b'sound_stream':
sound=bytearray(msg)
sound_file.write(sound)
print('sound write')
CLIENT_ID = ubinascii.hexlify(machine.unique_id())
mq = MQTTClient(CLIENT_ID, param['MQTT_SERVER'],param['MQTT_PORT'])
mq.set_callback(mqtt_recv)
mq.connect()
print(f"Pico {CLIENT_ID} Connect to Mqtt Broker {param['MQTT_SERVER']}:{param['MQTT_PORT']}")
mq.subscribe("info_skycon")
mq.subscribe("info_comfort")
mq.subscribe("info_equip")
mq.subscribe("sound_status")
mq.subscribe("sound_stream")
对于显示问题,由于像素数据相对还是比较大的,所以我对图像像素数据进行了抽象,通过json的格式来描述,相对的减少了纯色图片的空间占用情况,在服务器端的编码函数如下:
def convert_png_to_json(image_path):
# 提取文件名
file_name = os.path.basename(image_path)
image_name, extension = os.path.splitext(file_name)
if image_name[0].isdigit():
image_name = 'pic' + image_name
image_name= image_name.replace('-','_')
# 加载图片
image = Image.open(image_path).convert('RGB')
# 获取图片长宽
width,height = image.size
color_index = ord('a')
color_list = {}
image_data = ''
# 遍历图像的每个像素点,统计颜色
for y in range(height):
for x in range(width):
pixel = image.getpixel((x, y))
exists = False
if pixel != (0, 0, 0): #有颜色的像素
if len(color_list) == 0:
color_list[chr(color_index)] = pixel
color_index += 1
else:
for key,value in color_list.items():
if pixel == value:
exists = True
if not exists:
color_list[chr(color_index)] = pixel
color_index += 1
# 遍历图像编码存储字符串
for y in range(height):
for x in range(width):
pixel = image.getpixel((x, y))
exists = False
color = ''
for key, value in color_list.items():
if value == pixel:
exists = True
color = key
if exists:
image_data += str(color)
else:
image_data += ' '
#保存颜色列表
out = {
'w': width,
'h': height,
'd': image_data,
'c': color_list
}
out_json = json.dumps(out)
return out_json
对应的在显示屏上也有解析图片的处理:
@micropython.native # noqa: F821
def draw_image(self, image, update = True, offset_x = 0, offset_y = 0):
# print(image_json)
# image_json = json.loads(image_json)
# 遍历像素点
img_h = image['h']
img_w = image['w']
for y in range(img_h):
for x in range(img_w):
pixel = image['d'][y * img_w + x]
# draw the prompt text
if pixel != ' ':
r = image['c'][pixel][0]
g = image['c'][pixel][1]
b = image['c'][pixel][2]
# print(f"({x},{y}) {pixel} pen({r},{g},{b})")
self.graphics.set_pen(self.graphics.create_pen(r, g, b))
self.graphics.pixel(x + offset_x, y + offset_y)
if update:
self.gu.update(self.graphics)
接下来 是时间模块,通过ntp对时,来显示当前时钟,这部分封装了一个class,并设定了天、小时、秒更新的回调功能,可以动态定义更新函数来显示不同内容
class Clock():
def __init__(self):
# constants for controlling the background colour throughout the day
self.MIDDAY_HUE = 1.1
self.MIDNIGHT_HUE = 0.8
self.MIDDAY_SATURATION = 1.0
self.MIDNIGHT_SATURATION = 1.0
self.MIDDAY_VALUE = 0.8
self.MIDNIGHT_VALUE = 0.3
self.localtime = {'year':0,'month':0,'day':0,'wd':0,'hour':0,'minute':0,'second':0}
self.last_second = 0
self.last_day = 0
self.last_hour = 0
self.utc_offset = 8
# create the rtc object
self.rtc = machine.RTC()
self.day_update_handler = None
self.hour_update_handler = None
self.secend_update_handler = None
# 同步时间
def sync(self):
try:
ntptime.settime()
except OSError:
pass
def adjust_utc_offset(self,offset):
self.utc_offset = self.utc_offset + offset
def set_day_update_handler(self,handler):
self.day_update_handler = handler
def set_hour_update_handler(self,handler):
self.hour_update_handler = handler
def set_secend_update_handler(self,handler):
self.secend_update_handler = handler
def update(self):
year, month, day, wd, hour, minute, second, _ = self.rtc.datetime()
hour = (hour + self.utc_offset) % 24
self.localtime = {'year': year, 'month': month, 'day': day, 'wd': wd, 'hour': hour, 'minute': minute, 'second': second}
# 一天更新一次时间
if day != self.last_day:
self.sync()
if self.day_update_handler is not None:
self.day_update_handler()
self.last_day = day
if hour != self.last_hour:
if self.hour_update_handler is not None:
self.hour_update_handler()
self.last_hour = hour
if second != self.last_second:
if self.secend_update_handler is not None:
self.secend_update_handler()
self.last_second = second
def update_immediately(self):
self.last_second = None
self.update()
def get_clock_str(self):
return "{:02}:{:02}:{:02}".format(self.localtime['hour'], self.localtime['minute'], self.localtime['second'])
def get_clock_hsv(self):
time_through_day = (((self.localtime['hour'] * 60) + self.localtime['minute']) * 60) + self.localtime['second']
percent_through_day = time_through_day / 86400
percent_to_midday = 1.0 - ((math.cos(percent_through_day * math.pi * 2) + 1) / 2)
hue = ((self.MIDDAY_HUE - self.MIDNIGHT_HUE) * percent_to_midday) + self.MIDNIGHT_HUE
sat = ((self.MIDDAY_SATURATION - self.MIDNIGHT_SATURATION) * percent_to_midday) + self.MIDNIGHT_SATURATION
val = ((self.MIDDAY_VALUE - self.MIDNIGHT_VALUE) * percent_to_midday) + self.MIDNIGHT_VALUE
return hue,sat,val
对于天气解析,穿搭建议以及交通信息分析都在服务器端,也分别封装成了class,由于代码篇幅较长,所以都放在了第四章节的作品源码中。
四、作品源码
https://download.eeworld.com.cn/detail/justd0/630789
五、作品功能演示视频
晴天,穿长袖长裤
下雨天,短袖短裤,带雨伞
下雪天有雾霾,长袖长裤,戴口罩
六、项目总结
这次项目的时间有些紧张,从收到物料到提交作品不到两个月的时间,主要这段时间工作上十分繁忙,导致空余时间有限的可怜,最开始物料选型的时候,也没想到53*11像素是那么的少,导致有好多有趣的图案动画都没办法显示上去,也就让智能信息牌的功能受限了不少,不过万幸是目前设想的功能倒是都做出来了。
还是感谢digikay和eeworld举办这次比赛,让我能有机会把玩下rp2040这颗mcu,总体上来说树莓派的东西确实没有不好上手的,在叠加上micropython这个利器,确实让开发效率能够提升不少。
这次制作的为了制作智能信息牌的外壳,我还特意买了台3d打印机,打印了好多版本的外壳,才让显示效果比较柔和、且像素串扰小,只是不完美的是打印机尺寸比板子的还是小了不少,导致最后只能分开两半来打印,出来的效果中间会有条缝隙,不过远看还是不太清楚的,还好。
最后再次感谢digikey和eeworld。
-
上传了资料:
基于rp2040的智能信息牌源码
- 2024-01-12
-
加入了学习《【DigiKey创意大赛】多通道微型气相色谱采集单元》,观看 多通道微型气相色谱采集单元