625|2

283

帖子

7

TA的资源

一粒金砂(高级)

楼主
 

【得捷电子Follow me第2期】任务5:通过网络控制WS2812B [复制链接]

 

 

本次任务是结合123,在手机上通过网络控制板载Neopixel LED的显示和颜色切换,屏幕同步显示状态。

本来我原计划采用APP Inventor配合板子进行TCP通讯实现任务要求的功能,但是这个只适合安卓手机,普适性差。后来看见坛友大佬ttxiaotaoge的帖子《【得捷电子Follow me第2期】CircuitPython入门到完成任务1-5详细教程》后,感觉这个网页的方法非常棒,只需浏览器就能操作,不挑系统,索性可耻的抄作业了。大佬帖子链接:

https://bbs.eeworld.com.cn/thread-1253916-1-1.html

抄作业第一步,就是学习分析代码。由于大佬用的板子不是这次官方要求的Adafruit ESP32-S3 TFT Feather,需要适配硬件参数。

第一步修改屏幕,这个改起来很简单,原来的屏蔽掉,直接用系统原配即可。如下代码。

然后添加WiFi连接,我猜测大佬的板子是支持WiFi记忆的,所以上电不需要再做连接设置。

接下来修改按键和RGB灯的配置信息,其中按键不要忘了设置上拉哦,如下图红框所示。

最后就是调整显示文字的格式,不然会显示不全。

代码改好后直接运行就OK了,效果如下图所示。

然后用电脑浏览器打开网址:

http://192.168.31.110:1080/client

就可在网页中改变RGB灯颜色了,如下图。

当然也可以在手机浏览器中打开这个网页,如下图。

最后的最后,我对代码进行小幅修改,删掉了天气和时间显示,只显示RGB灯的状态,录了一段视频,放在下面了。

感谢得捷电子和EEWORLD提供的这次机会,也希望在接下来的活动中,提供更多好玩的板子和题目,让大家一起快乐搞机。

具体代码如下。

  • import board
  • import digitalio
  • import terminalio
  • import busio
  • import neopixel
  • import rtc
  • import time
  • #网络相关库
  • import wifi
  • import socketpool
  • import ssl
  • import adafruit_requests
  • from adafruit_httpserver import Server, Request, Response, Websocket, GET
  • #显示相关库
  • import displayio
  • from adafruit_bitmap_font import bitmap_font
  • from adafruit_display_text.label import Label
  • display = board.DISPLAY
  • board.DISPLAY.brightness = 0.5
  • board.DISPLAY.rotation = 0
  • my_display_group = displayio.Group()
  • print("Display Init Success\n")
  • # displayDriver_End
  • wifi.radio.connect('xxxxxxxxxxxxxxxxxx', 'xxxxxxxxxxxxxxxxxxxxxx')
  • print(f"My IP address: {wifi.radio.ipv4_address}")
  • # WiFi状态查询,未连接WIFI则不联网更新数据,开启AP模式
  • wificonnect_State = wifi.radio.connected
  • print("wificonnect_State",wificonnect_State)
  • if(wificonnect_State == False):
  • wifi.radio.start_ap(ssid = 'Esp32', password = '')
  • Wifi_Mode = 'STA' if(wificonnect_State == True) else 'AP'
  • Wifi_ip = wifi.radio.ipv4_address if(wificonnect_State == True) else wifi.radio.ipv4_address_ap
  • #构造函数——按键控制RGB
  • i = 0
  • Enter_flag = False
  • def Button0_Work():
  • global i
  • global Enter_flag
  • global RGBr, RGBg, RGBb
  • if(Button0.value == False and Enter_flag == False):
  • time.sleep(0.05)#延时消抖
  • if(Button0.value == False and Enter_flag == False):
  • i+=1
  • RGBr, RGBg, RGBb = 8*i, 8*i, 8*i
  • pixels.fill((RGBr, RGBg, RGBb))
  • Enter_flag = True
  • print("pixels change\n",i)
  • if(i>20):
  • i = 0
  • elif(Button0.value == True and Enter_flag == True):
  • time.sleep(0.05)#延时消抖
  • if(Button0.value == True and Enter_flag == True):
  • Enter_flag = False
  • # RGBDriver_Begin
  • pixel_pin = board.NEOPIXEL
  • num_pixels = 1
  • pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.2, auto_write=True)
  • pixels.fill((8, 8, 8))
  • print("RGBDriver Init Success\n")
  • # RGBDriver_End
  • # ButtonDriver_Begin
  • Button0 = digitalio.DigitalInOut(board.BUTTON)
  • Button0.direction = digitalio.Direction.INPUT
  • Button0.pull = digitalio.Pull.UP
  • print("Button0 Init Success\n")
  • # ButtonDriver_End
  • # 添加中文字体
  • font_file = "opposans_m_12.pcf"
  • font_Chinese = bitmap_font.load_font(font_file)
  • print("fonts Init Success\n")
  • # 显示WiFi IP 和 Mode
  • text_Wifi = "WiFi状态:{}\n{}:1080/client".format(Wifi_Mode,Wifi_ip)#更新RGB状态
  • text_Wifi_title = Label(font_Chinese, text=text_Wifi, color = 0xffffff)
  • text_Wifi_title.x = 5
  • text_Wifi_title.y = 10
  • my_display_group.append(text_Wifi_title)
  • # 显示RGB状态,和按键状态,RGB文字同RGB灯颜色
  • RGBr, RGBg, RGBb = 255,255,255
  • text_RGB = "RGB灯颜色:{:03}:{:03}:{:03}\n按键次数:{:02}".format(RGBr, RGBg, RGBb, i)#更新RGB状态
  • text_RGB_title = Label(font_Chinese, text=text_RGB, color = (RGBr, RGBg, RGBb))
  • text_RGB_title.x = 5
  • text_RGB_title.y = 70
  • my_display_group.append(text_RGB_title)
  • # ShowChinese_End
  • # GetandSetHttp_Begin
  • pool = socketpool.SocketPool(wifi.radio) # 网络管理,触发http操作
  • server = Server(pool, debug=True)
  • websocket: Websocket = None
  • next_message_time = time.monotonic()#数据更新时钟,以秒为单位变化
  • HTML_TEMPLATE = """
  • <html lang="en">
  • <head>
  • <!--注释:强制html使用utf-8编码-->
  • <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
  • <title>Web控制中心</title>
  • </head>
  • <body>
  • <p>按键状态: <strong>-</strong></p>
  • <p>RGB 颜色: <input type="color"></p>
  • <script>
  • const Button_count = document.querySelector('strong');
  • const colorPicker = document.querySelector('input[type="color"]');
  • let ws = new WebSocket('ws://' + location.host + '/connect-websocket');
  • ws.onopen = () => console.log('WebSocket connection opened');
  • ws.onclose = () => console.log('WebSocket connection closed');
  • ws.onmessage = event => Button_count.textContent = event.data;
  • ws.onerror = error => Button_count.textContent = error;
  • colorPicker.oninput = debounce(() => ws.send(colorPicker.value), 200);
  • <!--注释:创建一个延时函数,消除RGB调整抖动-->
  • function debounce(callback, delay = 1000) {
  • let timeout
  • return (...args) => {
  • clearTimeout(timeout)
  • timeout = setTimeout(() => {
  • callback(...args)
  • }, delay)
  • }
  • }
  • </script>
  • </body>
  • </html>
  • """
  • #创建Http服务器
  • @server.route("/client", GET)
  • def client(request: Request):
  • return Response(request, HTML_TEMPLATE, content_type="text/html")
  • #创建websocket服务
  • @server.route("/connect-websocket", GET)
  • def connect_client(request: Request):
  • global websocket # pylint: disable=global-statement
  • if websocket is not None:
  • print("websocket.close")
  • websocket.close() # Close any existing connection
  • websocket = Websocket(request)
  • return websocket
  • #UI show Begin
  • display.show(my_display_group)
  • print("display show Success\n")
  • #UI show End
  • #判断网络模式,设定location.host
  • if(wificonnect_State == True):
  • server.start(str(wifi.radio.ipv4_address), port = 1080)
  • else:
  • server.start(str(wifi.radio.ipv4_address_ap), port = 1080)
  • # GetandSetHttp_Begin
  • time.sleep(2)#等待2秒进入循环
  • while True:
  • #httpSeverLoop_Begin
  • server.poll()
  • # Check for incoming messages from client
  • if websocket is not None:
  • if (data := websocket.receive(True)) is not None:
  • RGBr, RGBg, RGBb = int(data[1:3], 16), int(data[3:5], 16), int(data[5:7], 16)
  • pixels.fill((RGBr, RGBg, RGBb))
  • # Send a message every second
  • if websocket is not None and next_message_time < time.monotonic():
  • time.sleep(0.2)
  • if websocket is not None:
  • Button_count = i
  • websocket.send_message(str(Button_count))
  • next_message_time = time.monotonic() + 1
  • #httpSeverLoop_End
  • #Other_Loop
  • text_RGB_title.color = (RGBr, RGBg, RGBb)
  • text_RGB_title.text = "RGB灯颜色:{:03}:{:03}:{:03}\n按键次数:{:02}".format(RGBr, RGBg, RGBb, i)#更新RGB状态
  • Button0_Work()

实际效果如下视频。

播放器加载失败: 未检测到Flash Player,请到安装
004

 

还有一个问题,我的板子每次启动都先花屏一下,如下图,然后再正常显示,不知道是不是被修过的原因,已经收到板子的同学们,你们的板子有这个情况吗?

最新回复

666大佬,牛逼   详情 回复 发表于 2023-9-8 09:43
点赞 关注
 
 

回复
举报

7145

帖子

11

TA的资源

版主

沙发
 

进入系统后,先清一下屏,可能就不会出现花屏的现象了。

 
 
 

回复

22

帖子

0

TA的资源

一粒金砂(中级)

板凳
 

666大佬,牛逼

 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
艾睿电子& Silicon Labs 有奖直播 | 全新蓝牙信道探测:从技术创新到实际应用
直播时间:3月12日(周三)上午10:00
直播奖励:多功能榨汁机、蓝牙音箱、手机支架

查看 »

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