You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用writerow将Arduino传入PsychoPy的带时间戳整数流写入CSV?

解决Arduino整数流无法写入PsychoPy CSV的问题

嘿,我来帮你搞定这个困扰!你说print(port.readline())能正常收到Arduino的整数,但CSV里只有时间戳,大概率是数据读取后的处理环节或者CSV写入逻辑出了小疏漏,咱们一步步拆解解决:

核心问题分析

port.readline()返回的是bytes类型的数据(比如b'123\r\n'),如果直接转整数或者写入CSV,要么会报错,要么写入的是无法识别的字节内容,最终导致整数没被正确记录。另外,Arduino输出的内容通常会带换行符(\r\n),需要先清理掉才能转成有效的整数。

分步解决方案

1. 正确处理Arduino的输入数据

首先要把读取到的字节数据解码成字符串,去掉多余的换行/空格,再转成整数,还要处理可能的异常(比如Arduino输出了调试信息而非整数):

raw_data = port.readline()
if raw_data:  # 确保不是空数据
    # 解码字节为字符串,清理首尾空白(包括换行符)
    clean_data = raw_data.decode('utf-8').strip()
    try:
        arduino_num = int(clean_data)  # 转成整数
    except ValueError:
        # 处理非整数数据,比如Arduino的串口调试信息
        print(f"收到无效数据: {clean_data}")
        arduino_num = "无效数据"  # 或者跳过写入

2. 确保CSV写入包含时间戳和整数

要保证每次写入CSV时,同时传入时间戳处理后的整数,并且文件操作要规范(比如用csv.writerwriterow方法传入列表):

import csv
from psychopy import clock

# 初始化CSV文件(建议在实验开始前打开)
with open('arduino_record.csv', 'w', newline='') as csv_file:
    writer = csv.writer(csv_file)
    # 先写入表头
    writer.writerow(['timestamp', 'arduino_integer'])
    
    # 实验循环中持续读取和写入
    while True:
        # 获取PsychoPy同步的时间戳(比系统时间更准确)
        current_time = clock.getTime()
        
        # 读取并处理Arduino数据(用上面的代码)
        raw_data = port.readline()
        arduino_num = None
        if raw_data:
            clean_data = raw_data.decode('utf-8').strip()
            try:
                arduino_num = int(clean_data)
            except ValueError:
                arduino_num = f"无效: {clean_data}"
        
        # 写入CSV:同时传入时间戳和整数
        if arduino_num is not None:
            writer.writerow([current_time, arduino_num])
        
        # 实验退出条件(比如按ESC键)
        # if event.getKeys(keyList=['escape']):
        #     break

3. 串口初始化的关键细节

  • 一定要加timeout参数:serial.Serial('COMx', 9600, timeout=1),避免readline()阻塞整个实验流程
  • 给Arduino留启动时间:初始化串口后加core.wait(2),让Arduino完成重启后的初始化

完整示例代码

把上面的逻辑整合到PsychoPy的实验框架里,完整代码如下:

import serial
import csv
from psychopy import core, clock, event

# 配置串口(替换成你的串口名称和波特率)
port = serial.Serial('COM3', 9600, timeout=1)
core.wait(2)  # 等待Arduino启动

# 创建并打开CSV文件
with open('arduino_data.csv', 'w', newline='', encoding='utf-8') as f:
    csv_writer = csv.writer(f)
    csv_writer.writerow(['timestamp', 'arduino_integer'])  # 写入表头
    
    print("开始记录数据,按ESC退出...")
    while True:
        # 获取时间戳
        timestamp = clock.getTime()
        
        # 读取Arduino数据
        raw_input = port.readline()
        if raw_input:
            try:
                # 解码、清理、转整数
                arduino_value = int(raw_input.decode('utf-8').strip())
                # 写入CSV
                csv_writer.writerow([timestamp, arduino_value])
                print(f"已记录: 时间戳={round(timestamp, 3)}, 整数={arduino_value}")
            except ValueError:
                # 记录无效数据
                invalid_data = raw_input.decode('utf-8').strip()
                csv_writer.writerow([timestamp, f"无效数据: {invalid_data}"])
                print(f"无效数据: {invalid_data}")
        
        # 检查退出按键
        if event.getKeys(keyList=['escape']):
            print("停止记录,关闭串口...")
            break

# 关闭串口
port.close()
core.quit()

额外排查点

  • 检查Arduino代码:确保用Serial.println()输出整数(带换行符,让readline()能正确读取),而不是Serial.print()
  • 验证数据转换:在写入CSV前,用print(type(arduino_num))确认是整数类型,而不是bytes或字符串
  • 查看CSV文件:如果用Excel打开显示异常,试试用记事本打开,确认是否有隐藏的字节内容

内容的提问来源于stack exchange,提问作者Shravan Thaploo

火山引擎 最新活动