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

使用Python Turtle显示盖革计数器剂量值时遇类型错误求助

解决TypeError: unsupported operand type(s) for /: 'NoneType' and 'int'问题

这个错误的核心原因很直白:你的read_sev()函数没有返回任何值,当你执行sev=read_sev()时,sev被默认赋值为None——这是Python中函数没有return语句时的默认返回值。之后在draw_gauge里尝试用None和整数40做除法,自然会触发类型错误。

修复步骤

1. 给read_sev()添加返回语句

修改这个函数,让它返回处理后的希沃特数值,同时增加异常处理避免串口数据异常导致程序崩溃:

def read_sev():
    try:
        sev = ser.readline()
        # 优化数据处理:先解码再去除多余字符,避免硬编码截取长度
        sev_clean = sev.decode("utf-8").strip()
        # 转换为浮点型
        sev_value = float(sev_clean)
        return sev_value
    except (UnicodeDecodeError, ValueError, serial.SerialException) as e:
        # 处理可能的异常:比如串口数据乱码、无法转成浮点数、串口断开
        print(f"读取数据出错: {e}")
        ser.flushInput()  # 清空串口缓存里的无效数据
        return 0.0  # 返回一个默认值,保证程序能继续运行

2. 额外优化:修复表盘刻度的逻辑问题

你当前的刻度绘制代码有个小bug:循环40次每次右转50度,总共会转2000度,这会导致刻度重叠混乱。如果你的最大量程是40 Sv,那么360度对应40 Sv,每个刻度应该间隔9度(360/40),修改刻度绘制部分:

pen.penup()
pen.goto(0,0)
pen.setheading(90)
for _ in range(40):
    pen.fd(190)
    pen.pendown()
    pen.fd(20)
    pen.penup()
    pen.goto(0,0)
    pen.rt(9)  # 替换原来的50度,每个刻度间隔9度

完整修改后的代码

#!/usr/bin/python3
import turtle
import serial
import time

wn = turtle.Screen()
wn.bgcolor("black")
wn.setup(width=600, height=600)
wn.title("Geiger Counter")
wn.tracer(0)

# 初始化串口,明确指定波特率(和Arduino程序设置一致,比如9600)
ser = serial.Serial('/dev/ttyACM1', 9600)
ser.flushInput()

# 读取希沃特值的函数,添加返回和异常处理
def read_sev():
    try:
        sev = ser.readline()
        sev_clean = sev.decode("utf-8").strip()
        sev_value = float(sev_clean)
        return sev_value
    except (UnicodeDecodeError, ValueError, serial.SerialException) as e:
        print(f"读取数据出错: {e}")
        ser.flushInput()
        return 0.0

# 初始化绘图笔
pen = turtle.Turtle()
pen.hideturtle()
pen.speed(0)
pen.pensize(3)

# 绘制表盘和指针
def draw_gauge(sev, pen):
    # 绘制外圈
    pen.up()
    pen.goto(0,210)
    pen.setheading(180)
    pen.color("green")
    pen.pendown()
    pen.circle(210)

    # 绘制刻度(修复角度间隔)
    pen.penup()
    pen.goto(0,0)
    pen.setheading(90)
    for _ in range(40):
        pen.fd(190)
        pen.pendown()
        pen.fd(20)
        pen.penup()
        pen.goto(0,0)
        pen.rt(9)

    # 绘制指针
    pen.penup()
    pen.goto(0,0)
    pen.color("white")
    pen.setheading(90)
    # 限制数值在0-40之间,避免指针超出表盘
    clamped_sev = max(0.0, min(sev, 40.0))
    angle = (clamped_sev / 40) * 360
    pen.rt(angle)
    pen.pendown()
    pen.fd(200)

while True:
    sev = read_sev()
    draw_gauge(sev, pen)
    wn.update()
    time.sleep(1)
    pen.clear()

wn.mainloop()

额外说明

  • 串口初始化时必须指定波特率,要和Arduino程序里的设置完全一致,否则会出现数据乱码。
  • 新增的异常处理是为了避免偶尔的串口数据异常导致程序直接崩溃,提升运行稳定性。
  • clamped_sev的作用是防止读取到超过40 Sv的数值时,指针转出表盘范围。

内容的提问来源于stack exchange,提问作者Renato Gallo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 06:57:31