Problems with Decode and Arduino

Asked

Viewed 71 times

0

Hello, People

I have the following code on Arduino

if((digitalRead(4) != 1)||(digitalRead(5) != 1))
  {
      Serial.print("\t");
      Serial.print(analogRead(A0));
      Serial.print(",");
      Serial.print(millis());
      Serial.print("\n");
  }

And with it, I read in Python with the following code:

def leituraSerial():
    tempo_leitura = time.time() + (TIMER + 1.6) # Contador de TIMER segundos
    k = 0

    while(time.time() <= tempo_leitura):  

        print("\n Leitura Iniciada!")

        aux = entrada.readline()
        str(aux)
        print(aux.decode('ascii'))

I tried several encodings of cp1252, windows-1250, utf-8, latin_1 and so on. some return x00 with the value I wanted, others give error, the way the code is above, it runs, but if I add, for example:

ts, tp = aux.split(",")

Already returns me the following error:

'ascii' codec can't decode byte 0xfe in position 8: ordinal not in range(128) 

If you use utf-8:

'utf-8' codec can't decode byte 0xfd in position 6: invalid start byte

So what the hell is going on???

  • The str(aux) is doing nothing; str() returns the value of a string, and does not modify it. What happens if you do print(str(aux)) without the decode?

  • If I remember correctly, comes a byte-Object, b' t0,4998 n', for example.

1 answer

3

The problem is not on Python’s side -

Your C functions should not be returning strings, but numbers - which means that the number that is going to the reported string is garbage (the integer number returned by its functions is interpreted as a memory address - print goes there and reads the contents of that address until it finds a value of 0x00 and puts what it found in the string.

If instead of Arduino, at the other end, you had run your program under an operating system with memory access management per process, your program would stop with a Segmentation fault. But on an 8-bit machine, any C program has equivalent powers to the system kernel.

To solve this, if you want to send your data as text, use the function itoa on the C-side should look something like:

<include stdlib.h>
...
   char tmp[20];
...
if((digitalRead(4) != 1)||(digitalRead(5) != 1))
  {

      Serial.print("\t");
      Serial.print(itoa(analogRead(A0), tmp, 10));
      Serial.print(",");
      Serial.print(itoa(millis(), tmp, 10));
      Serial.print("\n");
  }

So that’s your answer.

To complete the coding information: you don’t have to worry about coding unless you’re using accented characters in your Arduino program. If it is - let’s assume that you were sending a complete table and the first row of the header was "analog reading, milliseconds n" - in this case it would just use the same encoding used in the C file in which you wrote this string, before compiling. The C language does not "know" text, only "bytes" - so if its original C file was in utf-8, the analog "ó" would be in the object program, within Arduíno as the sequence `" xc3 xb3" - which is received in Python, and treated with ". Decode('utf-8')", would turn back the letter "ó".

  • Thanks for the light, but the problem still persists.

  • 1

    you have to explore the data you are effectively getting from the Python side - simply print the byte sequence on the screen, and you will see what comes in, without doing any Code. You can also use the "latin1" codec: it never gives "Decode" error, since it has characters set to all possible values from 0 to 255 (it does not mean that the text will be correct). The method hex() of the bytes object, instead of "Decode" will give you a string with two hexa digits for each byte too - easy to view the data.

  • So, using Latin-1, the code started to work, but at first reading it always returns an unexpected random character, such as ü 0.1 , for example, the expected would only be 0.1, which in fact happens with the remaining readings, This hinders the conversion I do to float

  • Voce changed the C code on the device as in the question? an unexpected "ü" character is a strong indication that Voce is expecting data as text on the computer, but is not sending the data as text from there.

  • Yes, I used itoa to secure strings, this happens only the first line, so I just ignored the first line, but it’s a trick...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.