Traceback (most recent call last): File "<stdin>", line 8, in <module> File "/lib/ssd1306.py", line 119, in __init__ File "/lib/ssd1306.py", line 38, in __init__ File "/lib/ssd1306.py", line 75, in init_display File "/lib/ssd1306.py", line 124, in write_cmd OSError: [Errno 116] ETIMEDOUT
时间: 2025-09-04 21:03:14 AIGC 浏览: 13
### 解决 OSError [Errno 116] ETIMEDOUT 初始化 SSD1306 模块问题
当初始化 SSD1306 模块时遇到 `OSError [Errno 116] ETIMEDOUT` 错误,通常是由于 I2C 总线未能成功与显示屏建立通信引起的。这种错误可能是由多种原因造成的,包括硬件连接不良、I2C 地址设置不正确或者软件配置不当等问题[^3]。
---
#### 1. 硬件连接检查
确保 OLED 显示屏的 SDA 和 SCL 引脚已经正确连接到 ESP32 的对应 GPIO 引脚上。常见的默认引脚分配如下:
- **SDA**: GPIO 21
- **SCL**: GPIO 22
如果使用不同的引脚组合,请务必在代码中相应修改 I2C 初始化部分。另外还需确认电源供电正常(VCC 和 GND),以及是否有拉电阻存在来稳定信号传输质量[^4]。
---
#### 2. 验证 I2C 设备地址
SSD1306 默认的 I2C 地址为 `0x3C` 或者 `0x3D` ,具体取决于硬件设计。可以编写一小段扫描程序检测实际存在的设备地址:
```python
from machine import Pin, SoftI2C
# 定义 I2C 接口参数
i2c = SoftI2C(scl=Pin(22), sda=Pin(21))
print("Scanning I2C bus...")
devices = i2c.scan()
if devices:
print(f"I2C devices found at addresses: {devices}")
else:
print("No I2C device detected.")
```
运行此脚本后观察输出结果,若未发现任何设备,则表明物理连线存在问题;反之则记录下正确的设备地址以便后续调用[^5]。
---
#### 3. 调整超时时间
尽管 MicroPython 中并没有直接暴露用于设定 I2C 操作全局超时期限的功能接口,但是可以通过增加重试逻辑间接缓解因短暂干扰引发的失败情况。例如:
```python
def retry_ssd1306_initialization(attempts=5):
from machine import Pin, SoftI2C
import ssd1306
scl_pin = Pin(22)
sda_pin = Pin(21)
while attempts > 0:
try:
i2c = SoftI2C(scl=scl_pin, sda=sda_pin)
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
return oled
except OSError as e:
if str(e).find("[Errno 116]") != -1 and attempts > 1:
print(f"Attempt failed due to timeout ({attempts} remaining)")
attempts -= 1
else:
raise
retry_ssd1306_initialization()
```
上述函数会在初次尝试失败之后最多再重复四次直到耗尽所有机会为止[^6]。
---
#### 4. 减少数据速率
有时候降低 I2C 数据率也可以帮助改善通讯可靠性特别是对于较长距离布线场景而言。可通过调整频率参数实现这一点:
```python
i2c = SoftI2C(scl=Pin(22), sda=Pin(21), freq=100_000) # 将速度设为100kHz而非默认值400kHz
```
---
#### 5. 替代方案 – 使用 SPI 协议
假如经过以上努力仍然无法排除故障,那么不妨考虑改用 SPI 接口代替 I2C 。虽然SPI需要更多GPIO资源但它往往表现出更高的鲁棒性和更快的数据吞吐能力[^7]:
```python
from machine import Pin, SPI
import ssd1306
spi = SPI(-1, baudrate=8000000, polarity=0, phase=0,
sck=Pin(18), mosi=Pin(23))
dc = Pin(16, Pin.OUT)
res = Pin(4, Pin.OUT)
cs = Pin(5, Pin.OUT)
oled_spi = ssd1306.SSD1306_SPI(128, 64, spi, dc, res, cs)
```
---
### 总结
针对 `OSError [Errno 116] ETIMEDOUT` 初步建议从基础层面着手排查诸如接线准确性、目标器件在线状态等方面入手逐步深入分析根本成因所在直至最终妥善处置完毕。
阅读全文
相关推荐




















