You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用OLED、ESP32及SH1106 MicroPython库绘制图表?求助

在ESP32的SH1106 OLED上绘制图表与数据计算方案

一、数据预处理:映射原始数据到OLED坐标

SH1106 OLED通常为128×64分辨率,原始数据的数值范围(比如传感器读数)和屏幕像素范围不匹配,需要先做归一化映射,把数据转换为屏幕可识别的坐标。核心公式如下:
y = 屏幕Y轴上限 - ((当前数据 - 数据最小值) / (数据最大值 - 数据最小值)) * (屏幕Y轴范围)
注:OLED坐标原点在左上角,所以Y值越大越靠近屏幕底部,需反向映射。

实现映射函数:

def map_data(data, data_min, data_max, screen_y_min, screen_y_max):
    # 处理数据全部相同的边界情况
    if data_max == data_min:
        return (screen_y_min + screen_y_max) // 2
    return screen_y_max - int(((data - data_min) / (data_max - data_min)) * (screen_y_max - screen_y_min))

二、基础图表绘制示例

1. 折线图

通过连接预处理后的坐标点实现,适合展示数据趋势:

from machine import I2C, Pin
from sh1106 import SH1106_I2C

# 初始化OLED
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)
oled = SH1106_I2C(128, 64, i2c, addr=0x3c, rotate=0)

# 模拟传感器数据
sensor_data = [12, 15, 18, 14, 20, 17, 19, 13]

def draw_line_chart(data, x_start=5, y_start=5, width=118, height=54):
    data_min = min(data)
    data_max = max(data)
    points = []
    
    # 计算每个数据点的屏幕坐标
    for idx, val in enumerate(data):
        x = x_start + int((idx / (len(data)-1)) * width)
        y = map_data(val, data_min, data_max, y_start, y_start + height)
        points.append((x, y))
    
    # 绘制连线
    for i in range(len(points)-1):
        oled.line(points[i][0], points[i][1], points[i+1][0], points[i+1][1], 1)
    # 绘制数据点(增强可读性)
    for (x, y) in points:
        oled.fill_rect(x-1, y-1, 3, 3, 1)
    
    oled.show()

# 执行绘图
oled.fill(0)
draw_line_chart(sensor_data)

2. 柱状图

用矩形块展示单组数据的分布:

def draw_bar_chart(data, x_start=5, y_start=5, width=118, height=54):
    data_min = min(data)
    data_max = max(data)
    bar_width = width // len(data) - 2  # 柱子间留空隙
    
    for idx, val in enumerate(data):
        bar_height = int(((val - data_min) / (data_max - data_min)) * height)
        x = x_start + idx * (bar_width + 2)
        y = y_start + height - bar_height
        oled.fill_rect(x, y, bar_width, bar_height, 1)
    
    oled.show()

# 执行绘图
oled.fill(0)
draw_bar_chart(sensor_data)

三、常用数据计算示例

结合Python基础语法实现统计计算,可将结果与图表同屏显示:

# 计算平均值
def calc_average(data):
    return sum(data) / len(data)

# 计算方差
def calc_variance(data):
    avg = calc_average(data)
    return sum((x - avg)**2 for x in data) / len(data)

# 示例:显示计算结果+折线图
avg_val = calc_average(sensor_data)
var_val = calc_variance(sensor_data)

oled.fill(0)
oled.text(f"Avg: {avg_val:.1f}", 0, 0)
oled.text(f"Var: {var_val:.1f}", 0, 10)
draw_line_chart(sensor_data, y_start=20)
oled.show()

四、优化技巧

  • 减少全屏刷新:仅更新图表区域而非整个屏幕,降低资源消耗;
  • 控制刷新频率:数据采集频率过高时,间隔1-2秒刷新一次即可;
  • 缓存计算结果:周期性采集的数据可缓存坐标映射结果,避免重复计算;
  • 异常处理:提前判断数据为空、数值溢出等情况,避免程序崩溃。

内容的提问来源于stack exchange,提问作者Mr.Programmer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 21:05:02