0

I am sending a String 1 and a String 0 encoded with ASCII from Python to a C program on my Arduino UNO over a serial port.

I am able to receive the encoded data in C which is 0x31 for 1 and 0x30 for 2, this is what I expected as it is ASCII hex for char 1 and char 2.

I can read/use this in its ASCII state. But now I want this data: 0x31 to be turned into an int 1 or char 1 and 0x30 into an int 0 or char 0 in C. I have tried atoi(receivedData) (Which is literally: ASCII to int) but this doesn't work, I have sent the atoi(receivedData) result back and I get a 0x00 in Python.

How can I go about doing this?

Here is my C code:

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();
   }
}

Here is my Python code:

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)
4
  • Are you sure atoi() will take hex strings as input? Commented Nov 7, 2019 at 15:43
  • 1
    Assuming you're using Python 3, you can skip the encoding and just create your strings as bytes objects, then send those: myStr1 = b'1', myStr0 = b'0'. Additionally, serial.Serial.read returns bytes objects, so you can just call decode on the result, then int on that. Or, just call int on the bytes object directly, so long as it represents a base-10 number: int(b'1') -> 1 Commented Nov 7, 2019 at 15:51
  • 1
    In regards to the c-half, it looks like you're storing as a uint8_t. To parse it into its represented int, casting to char and then following this answer should work. Commented Nov 7, 2019 at 16:09
  • 1
    @b_c Thank you, this made my code cleaner and it works now! Been stuck for a while haha Commented Nov 7, 2019 at 16:18

1 Answer 1

1

Check comments for the answer.

C

receivedDataTemp = receivedData - '0';

Python

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

serialC.write(myStr1)
print(int(serialC.read().decode()))
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.