如何通过 pySerial 从 Python 发送 int 或 string 并在 C 中转换为 int 或 String

Posted

技术标签:

【中文标题】如何通过 pySerial 从 Python 发送 int 或 string 并在 C 中转换为 int 或 String【英文标题】:How to send int or string from Python over pySerial and turn in to int or String in C 【发布时间】:2019-11-07 15:36:18 【问题描述】:

我正在通过串口从 Python 向我的 Arduino UNO 上的 C 程序发送一个用 ASCII 编码的字符串 1 和一个字符串 0。

我能够接收 C 中的编码数据,即 1 为 0x31,2 为 0x30,这是我所期望的,因为它是 ASCII 十六进制的字符 1 和字符 2。

我可以在 ASCII 状态下读取/使用它。但是现在我希望将这些数据:0x31 转换为 int 1 或 char 1,并将 0x30 转换为 C 中的 int 0 或 char 0。我尝试过 atoi(receivedData)(字面意思是:ASCII 到 int)但这不是工作,我已经发回了atoi(receivedData) 结果,我在 Python 中得到了 0x00。

我该怎么做?

这是我的 C 代码:

uint8_t receivedData;

void uart_init()

    // set the baud rate
    UBRR0H = 0;
    UBRR0L = UBBRVAL;
    // disable U2X mode
    UCSR0A = 0;
    // enable receiver & transmitter
    UCSR0B = (1<<RXEN0) | (1<<TXEN0); // Turn on the transmission and reception circuitry
    // set frame format : asynchronous, 8 data bits, 1 stop bit, no parity
    UCSR0C = _BV(UCSZ01) | _BV(UCSZ00);


void receive(void)

    loop_until_bit_is_set(UCSR0A, RXC0);
    receivedData = UDR0;


void transmit(uint8_t dataa)

    loop_until_bit_is_set(UCSR0A, UDRE0);
    UDR0 = dataa


void processData() 
    cleanUDR0();

    // 0x31 is ascii code for 1, 0x30 is 0
    // led turns on if input == 1 (0x31) and turns off if led == 0 (0x30)
    receive();

    transmit(receivedData);

    int temporary = atoi(receivedData);

    if (temoraray == 1)
        PORTD = 0xff; // Turning LEDs on
    
    else if (temporary == 0)
        PORTD = 0x00; // Turning LEDs off
    


void cleanUDR0(void) 
    unsigned char y;
    while (UCSR0A & (1<<RXC0)) y=UDR0;


int main(void)

   DDRD = 0xFF;
   uart_init();

   While(1) 
      processData();
   

这是我的 Python 代码:

import time
import threading
import serial


class SerialT(threading.Thread):
    connected = False

    serialC = serial.Serial("COM4", 19200)

    while not connected:
        serin = serialC.read()
        connected = True

    while True:
        myStr1 = '1'
        myStr0 = "0"

        serialC.write(myStr1.encode('ascii'))
        print(int(chr(ord(serialC.read()))))

        time.sleep(2)

        serialC.write(myStr0.encode('ascii'))
        print(int(chr(ord(serialC.read()))))

        time.sleep(2)

【问题讨论】:

您确定atoi() 将使用十六进制字符串作为输入吗? 假设您使用的是 Python 3,您可以跳过编码并将字符串创建为 bytes 对象,然后发送这些:myStr1 = b'1', myStr0 = b'0'。此外,serial.Serial.read 返回bytes 对象,因此您可以在结果上调用decode,然后在其上调用int。或者,直接在字节对象上调用int,只要它代表一个以10为底的数字:int(b'1') -&gt; 1 关于 c-half,看起来您存储为 uint8_t。要将其解析为其表示的 int,转换为 char 然后跟随 this answer 应该可以。 @b_c 谢谢,这让我的代码更干净,现在可以使用了!卡了一段时间哈哈 【参考方案1】:

检查 cmets 以获得答案。

C

receivedDataTemp = receivedData - '0';

Python

myStr1 = b'1'
myStr0 = b'0'

serialC.write(myStr1)
print(int(serialC.read().decode()))

【讨论】:

以上是关于如何通过 pySerial 从 Python 发送 int 或 string 并在 C 中转换为 int 或 String的主要内容,如果未能解决你的问题,请参考以下文章

如何使用python(pyserial)向华为E3272 Hilink发送AT命令?

pyserial 2.7,python 3.3,发送回车

如何使用 PySerial 从 COM 端口读写?

如何使用 PySerial 与 micro:bit 建立串行通信?

PySerial 丢失数据

使用pyserial发送二进制数据