通过串行向arduino发送8位整数

2024-05-29 00:13:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我创建了一个音乐可视化工具,我想使用python的pyserial库通过串行方式将38位整数(0-255)发送到Arduino。我的计算机上有一个名为rgb.txt的文本文件,其中包含以下数据:8,255,255。我使用以下代码通过串行方式发送数据:

import serial, time
arduino = serial.Serial('COM3', 9600, timeout=.1)
time.sleep(2) #give the connection a second to settle

while True:
    with open("rgb.txt") as f:
        rgb = f.read().strip("\n")
    arduino.write(rgb.encode("ASCII"))

    data = arduino.readline()
    if data:
        try:
            print(data.decode('ASCII').strip("\r").strip("\n")) # (better to do .read() in the long run for this reason
        except UnicodeDecodeError:
            pass
    time.sleep(0.1)

我收到它的代码是:

#include <stdio.h>
int r = A0;
int g = A1;
int b = A2;
void setup() {
  Serial.begin(9600);
  analogWrite(r, 255); delay(333); analogWrite(r, 0);
  analogWrite(g, 255); delay(333); analogWrite(g, 0);
  analogWrite(b, 255); delay(334); analogWrite(b, 0);
}
void loop() {
  if(Serial.available() > 0) {
    char data = Serial.read();
    char str[2];
    str[0] = data;
    str[1] = '\0';
      Serial.println(str);
    }
  }

我得到的结果是

8
,
2
5
5
,
2
5
5

我如何解析它以便接收:

8
255
255

最好是3个不同的变量(r{}{}),谢谢


Tags: 代码txtreaddatatime方式serialrgb
3条回答

如果始终有一个“,”字符,则可以将其转换为int

uint8_t rgb[3] = {0,0,0};
uint8_t rgbIndex = 0;

void loop() {
  if(Serial.available() > 0) {
    char data = Serial.read();
    if(data < '0' || data > '9')
      rgbIndex++;
    else
      rgb[rgbIndex] = rgb[rgbIndex] * 10 + (data - '0');
  }
}

Arduino代码:

#include <stdio.h>
int r = A0;
int g = A1;
int b = A2;
void setup() {
  Serial.begin(115200);
  analogWrite(r, 255); delay(333); analogWrite(r, 0);
  analogWrite(g, 255); delay(333); analogWrite(g, 0);
  analogWrite(b, 255); delay(334); analogWrite(b, 0);
}
void loop() {
  static char buffer[12];
  static uint8_t rgb[3];

  if (Serial.available() > 0) {
    Serial.readBytesUntil('\n', buffer, 12);
    int i = 0;
    char *p = strtok(buffer, ",");
    while (p) {
      rgb[i++] = (uint8_t)atoi(p);
      p = strtok(NULL, ",");
    }
    // You now have uint8s in rgb[]
    analogWrite(A0, rgb[0]);
    analogWrite(A1, rgb[1]);
    analogWrite(A2, rgb[2]); 
    Serial.println(rgb[0]);
    Serial.println(rgb[1]);
    Serial.println(rgb[2]);
  }
}

Python代码:

import serial, time
def run():
    arduino = serial.Serial('COM3', 115200, timeout=.1)
    time.sleep(2) #give the connection a second to settle

    while True:
        with open("rgb.txt") as f:
            rgb = f.read()
            rgb += "\n"
        arduino.write(rgb.encode("ASCII"))

        data = arduino.readline()
        if data:
            try:
                print(data.decode('ASCII').strip("\r").strip("\n")) # (better to do .read() in the long run for this reason
            except UnicodeDecodeError:
                pass
        time.sleep(0.1)
while True:
    try:
        run()
    except serial.serialutil.SerialTimeoutException:
        print("Is your com port correct?")

现在要做的是读取一个char,将其转换为一个CString str,然后在继续下一个char之前println()读取它

您可能可以按照所需的方式将字节粘在一起,但将接收到的字节读入缓冲区并拆分结果更容易:

从Python中发送RGB值,用逗号分隔,末尾用'\n'分隔,然后在Arduino上执行类似的操作(未测试,但您明白了):

void loop() {
  static char buffer[12];
  static uint8_t rgb[3];

  if (Serial.available() > 0) {
    Serial.readBytesUntil('\n', buffer, 12);
    int i = 0;
    char *p = strtok(buffer, ",");
    while (p) {
      rgb[i++] = (uint8_t)atoi(p);
      p = strtok(NULL, ",");
    }
    // You now have uint8s in rgb[]
    Serial.println(rgb[0]);
    Serial.println(rgb[1]);
    Serial.println(rgb[2]); 
  }
}

注意:此代码中没有检查和错误处理

毫无疑问,有更漂亮的方式,但我首先想到了这一点,我认为它会起作用。也可以使用字符串对象来完成,但我尽量不这样做

为了使this other answer中的代码正常工作,需要添加一些东西(但我还没有测试这些添加是否足够):

void loop() {
  if (Serial.available() > 0) {
    char data = Serial.read();
    if (data < '0' || data > '9')
      rgbIndex++;
    else
      rgb[rgbIndex] = rgb[rgbIndex] * 10 + (data - 48);
    if (rgbIndex == 3) {
      // You now have uint_8s in rgb[]
      Serial.println(rgb[0]);
      Serial.println(rgb[1]);
      Serial.println(rgb[2]);
      rgbIndex = 0;
      for (int i=0; i<3; i++)
        rgb[i] = 0;
    }
  }
}

请注意,在Python端,将从文件读取的内容转换为字符或整数,然后只发送三个字节,这将大大简化Arduino端的工作

相关问题 更多 >

    热门问题