
如何使用 Deepseek帮忙查找MicroPython 开发的ESP32S3控制ws2812灯带的程序中的bug
如何使用 Deepseek帮忙查找MicroPython 开发的ESP32S3控制ws2812灯带的程序中的bug
最近最火的一定就是DeepSeek了,没有之一!确实DeepSeek给我们的工作生活带了巨大的帮助,虽然豆包之类的工具也能给我们提供类似的服务,甚至由于推出的时间更长,在某些方面表现更好一些,但毕竟DeepSeek是国产的东西,需要我们更多的支持。
这里,我们不提DeepSeek如何帮助我们解决现实工作、学习、生活方面的诸多问题,只是简单记录一次编程过程中,利用DeepSeek查找程序中的bug的经历。
最近因为项目需要使用ESP32S3,ESP32S3很多人应该都非常熟悉,我也很多年前就听说过ESP芯片,也有在项目中使用过,但都是使用现成的模块,所以,这次的项目对我是一个挑战,好在这个项目相对比较简单。
经过了解分析后,决定使用MicroPython来做这个项目,不过遗憾的是,Python我之前也没有接触过,只是听说比较简单,不过自己毕竟有较丰富的C/C++的开发经验,相信MicroPython应该是小菜一碟。
在一番准备后,打脸来的真快。该项目需要控制ws2812灯带,这个项目前几天用stm32及CH592F都开发过,按说应该真的是小菜一碟,很快就写好控制程序:
from machine import Pin
from neopixel import NeoPixel
import time
WS2812_NUM = 60
WS2812_LED_LEVEL = 0x10
g = 0xff
r = 0
b = 0
pin = Pin(36, Pin.OUT)
np = NeoPixel(pin, WS2812_NUM)
def ws2812_LED_Cycle(phase):
for i in range(WS2812_NUM - 1):
np[WS2812_NUM - 1 - i] = np[WS2812_NUM -2 - i]
if phase < WS2812_LED_LEVEL:
g -= (0xff / WS2812_LED_LEVEL)
r += (0xff / WS2812_LED_LEVEL)
phase = phase + 1
if phase == WS2812_LED_LEVEL:
g = 0
r = 0xff
elif phase < (WS2812_LED_LEVEL * 2):
r -= (0xff / WS2812_LED_LEVEL)
b += (0xff / WS2812_LED_LEVEL)
phase = phase + 1
if phase == (WS2812_LED_LEVEL * 2):
r = 0
b = 0xff
elif phase < (WS2812_LED_LEVEL * 3):
b -= (0xff / WS2812_LED_LEVEL)
g += (0xff / WS2812_LED_LEVEL)
phase = phase + 1
if phase == (WS2812_LED_LEVEL * 3):
b = 0
g = 0xff
np[0] = (r,g,b)
offset = 0
while True:
offset = ws2812_LED_Cycle(offset)
np.write()
time.sleep_ms(100)
程序一直报错,而且是语法错,但因为之前没有用过Python,手头上也没有Python的书,在网上查找了一番,还是云里雾里的。
突发奇想,能不能使用DeepSeek帮忙诊断上述代码中的bug?想到就试,将这段代码复制,在DeepSeek APP中输入:
帮忙分析一下下面代码的问题
接下来是上面的代码
DeepSeek用了大概1分钟时间,判断出该代码是用来控制ws2812灯带的,诊断了代码中的问题,并给出了正确代码,不能不给一个大大的赞!
下述文字全是DeepSeek给出的诊断并给出了修改方式:
你提供的代码存在多个问题,以下是详细分析及修复建议:
1. 索引越界错误
在 `for` 循环中,`np[WS2812_NUM - i]` 会导致索引越界(最大索引应为 `WS2812_NUM - 1`)。
错误代码:
```python
for i in range(WS2812_NUM - 1):
np[WS2812_NUM - i] = np[WS2812_NUM - i - 1] # 当 i=0 时,索引为 60,越界
```
修复方法:
将索引调整为 `WS2812_NUM - 1 - i`:
```python
for i in range(WS2812_NUM - 1):
np[WS2812_NUM - 1 - i] = np[WS2812_NUM - 2 - i] # 正确索引范围 0~59
```
---
2. 未声明全局变量
在函数内修改全局变量 `g`, `r`, `b` 时,未使用 `global` 关键字,会导致 `UnboundLocalError`。
错误代码:
```python
def ws2812_LED_Cycle(phase):
# 直接修改全局变量 g, r, b
g -= (0xff / WS2812_LED_LEVEL)
```
修复方法:
在函数内声明全局变量:
```python
def ws2812_LED_Cycle(phase):
global g, r, b # 添加声明
# 后续代码
```
---
3. 颜色值为浮点数
NeoPixel 需要 RGB 值为整数(0~255),但代码中计算出的颜色值是浮点数。
错误代码:
```python
g -= (0xff / WS2812_LED_LEVEL) # 结果为浮点数(如 15.9375)
```
修复方法:
强制转换为整数:
```python
g = int(g - (0xff / WS2812_LED_LEVEL))
r = int(r + (0xff / WS2812_LED_LEVEL))
# 或使用整数除法(需调整逻辑)
```
4. 缺少 np.write()
修改 NeoPixel 数据后,需调用 `np.write()` 才能更新到硬件,否则 LED 不会变化。
缺失代码:
```python
np[0] = (r, g, b)
# 缺少 np.write()
```
修复方法:
在修改数据后调用写入:
```python
np[0] = (int(r), int(g), int(b)) # 确保为整数
np.write() # 关键!将数据发送到 LED
```
---
5. 条件分支缩进错误
代码中 `elif` 的缩进不正确,导致逻辑错误。`elif` 应与外层的 `if` 对齐,而非嵌套在内层 `if` 中。
错误缩进:
```python
if phase < WS2812_LED_LEVEL:
# ...
if phase == WS2812_LED_LEVEL:
# ...
elif phase < (WS2812_LED_LEVEL * 2): # 缩进错误,导致归属外层 if
```
**修复方法:**
调整缩进,确保 `elif` 与外层 `if` 对齐:
```python
if phase < WS2812_LED_LEVEL:
# ...
elif phase < (WS2812_LED_LEVEL * 2):
# ...
elif phase < (WS2812_LED_LEVEL * 3):
# ...
```
---
6. 未处理 `phase` 超出范围
当 `phase >= WS2812_LED_LEVEL * 3` 时,代码不执行任何操作,可能导致颜色停止更新。需重置 `phase` 实现循环。
修复方法:
在函数末尾或外部循环中重置 `phase`:
```python
if phase >= WS2812_LED_LEVEL * 3:
phase = 0 # 重置循环
return phase # 返回更新后的 phase 供下次调用
```
完整修复后的代码
```python
from machine import Pin
from neopixel import NeoPixel
import time
WS2812_NUM = 60
WS2812_LED_LEVEL = 0x10 # 16
g = 0xff
r = 0
b = 0
pin = Pin(36, Pin.OUT)
np = NeoPixel(pin, WS2812_NUM)
def ws2812_LED_Cycle(phase):
global g, r, b # 声明全局变量
# 移位操作(修复索引越界)
for i in range(WS2812_NUM - 1):
np[WS2812_NUM - 1 - i] = np[WS2812_NUM - 2 - i]
# 颜色渐变逻辑
if phase < WS2812_LED_LEVEL:
g = int(g - (0xff / WS2812_LED_LEVEL))
r = int(r + (0xff / WS2812_LED_LEVEL))
phase += 1
if phase == WS2812_LED_LEVEL:
g = 0
r = 0xff
elif phase < (WS2812_LED_LEVEL * 2):
r = int(r - (0xff / WS2812_LED_LEVEL))
b = int(b + (0xff / WS2812_LED_LEVEL))
phase += 1
if phase == (WS2812_LED_LEVEL * 2):
r = 0
b = 0xff
elif phase < (WS2812_LED_LEVEL * 3):
b = int(b - (0xff / WS2812_LED_LEVEL))
g = int(g + (0xff / WS2812_LED_LEVEL))
phase += 1
if phase == (WS2812_LED_LEVEL * 3):
b = 0
g = 0xff
phase = 0 # 重置 phase 以循环
# 更新第一个 LED 颜色并写入硬件
np[0] = (r, g, b)
np.write()
return phase # 返回更新后的 phase
# 示例调用
phase = 0
while True:
phase = ws2812_LED_Cycle(phase)
time.sleep(0.1)
```
---
其他注意事项
1. **颜色顺序**:确认 NeoPixel 的 RGB 顺序是否为 `(r, g, b)`,某些灯带可能使用 `(g, r, b)`。
2. **性能优化**:频繁调用 `np.write()` 可能影响性能,可适当调整延时(如 `time.sleep(0.1)`)。
3. **相位重置逻辑**:根据需求决定 `phase` 是否在函数内重置,或由外部控制。
根据DeepSeek的诊断及给出的代码,最后修改代码如下:
from machine import Pin
from neopixel import NeoPixel
import time
WS2812_NUM = 60
WS2812_LED_LEVEL = 0x10
g = 0xff
r = 0
b = 0
pin = Pin(36, Pin.OUT)
np = NeoPixel(pin, WS2812_NUM)
def ws2812_LED_Cycle(phase):
global g,r,b
for i in range(WS2812_NUM - 1):
np[WS2812_NUM -1 - i] = np[WS2812_NUM - 2 - i]
if phase < WS2812_LED_LEVEL:
g = int(g - (0xff / WS2812_LED_LEVEL))
r = int(r + (0xff / WS2812_LED_LEVEL))
phase += 1
if phase == WS2812_LED_LEVEL:
g = 0
r = 0xff
elif phase < (WS2812_LED_LEVEL * 2):
r = int(r - (0xff / WS2812_LED_LEVEL))
b = int(b + (0xff / WS2812_LED_LEVEL))
phase += 1
if phase == (WS2812_LED_LEVEL * 2):
r = 0
b = 0xff
elif phase < (WS2812_LED_LEVEL * 3):
b = int(b - (0xff / WS2812_LED_LEVEL))
g = int(g + (0xff / WS2812_LED_LEVEL))
phase += 1
if phase == (WS2812_LED_LEVEL * 3):
phase = 0
b = 0
g = 0xff
np[0] = (g,r,b)
return phase
offset = 0
while True:
offset = ws2812_LED_Cycle(offset)
np.write()
time.sleep_ms(100)
这里需要提到的是,通过DeepSeek还帮我快速掌握了Python的语句块的划分,Python对语句格式的要求非常严格,而这些作为新手,如果是自学的话,是极有可能忽略的问题。
更多推荐
所有评论(0)