【得捷电子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")
-
-
- wifi.radio.connect('xxxxxxxxxxxxxxxxxx', 'xxxxxxxxxxxxxxxxxxxxxx')
- print(f"My IP address: {wifi.radio.ipv4_address}")
-
- 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
-
-
-
- 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
-
-
-
- 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")
-
-
-
- Button0 = digitalio.DigitalInOut(board.BUTTON)
- Button0.direction = digitalio.Direction.INPUT
- Button0.pull = digitalio.Pull.UP
- print("Button0 Init Success\n")
-
-
-
- font_file = "opposans_m_12.pcf"
- font_Chinese = bitmap_font.load_font(font_file)
- print("fonts Init Success\n")
-
-
- text_Wifi = "WiFi状态:{}\n{}:1080/client".format(Wifi_Mode,Wifi_ip)
- 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)
-
-
- RGBr, RGBg, RGBb = 255,255,255
- text_RGB = "RGB灯颜色:{:03}:{:03}:{:03}\n按键次数:{:02}".format(RGBr, RGBg, RGBb, i)
- 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)
-
-
-
- pool = socketpool.SocketPool(wifi.radio)
- 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>
- """
-
- @server.route("/client", GET)
- def client(request: Request):
- return Response(request, HTML_TEMPLATE, content_type="text/html")
-
- @server.route("/connect-websocket", GET)
- def connect_client(request: Request):
- global websocket
- if websocket is not None:
- print("websocket.close")
- websocket.close()
- websocket = Websocket(request)
- return websocket
-
-
- display.show(my_display_group)
- print("display show Success\n")
-
-
-
- if(wificonnect_State == True):
- server.start(str(wifi.radio.ipv4_address), port = 1080)
- else:
- server.start(str(wifi.radio.ipv4_address_ap), port = 1080)
-
- time.sleep(2)
- while True:
-
- server.poll()
-
- 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))
-
-
- 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
-
-
-
- text_RGB_title.color = (RGBr, RGBg, RGBb)
- text_RGB_title.text = "RGB灯颜色:{:03}:{:03}:{:03}\n按键次数:{:02}".format(RGBr, RGBg, RGBb, i)
- Button0_Work()
实际效果如下视频。
播放器加载失败: 未检测到Flash Player,请到 安装
004
还有一个问题,我的板子每次启动都先花屏一下,如下图,然后再正常显示,不知道是不是被修过的原因,已经收到板子的同学们,你们的板子有这个情况吗?
|