Why does python print multiple multi-digit numbers on multiple lines?

I wrote a python program that receives a binary number from an Atmega32 (microcontroller) via the USART and outputs it.

on the other hand, My Atmega32 reads its PINA when the interrupt is triggered and sends its value to the computer using the USART.

this is my python program:

>>> import serial
>>> ser=serial.Serial ('COM3')
>>> ser.open()
>>> while(1):
    ser.read()

      

when I connect the PINA pins in such a way as to make 00000111

(equal to 7 ) I see the output below in python:

'7'
'7'
'7'
'7'
'7'
'7'
.
.
.

      

But when I connect PINA pins in such a way as to make 10000111

(equal to 135 ) I see the following output in python:

'1'
'3'
'5'
'1'
'3'
'5'
'1'
'3'
'5'
'1'
'3'
'5'
'1'
'3'
'5'
'1'
'3'
'5'
.
.
.

      

As you can see above, it prints 135 on three lines! Why?


FYI: This is the program I wrote for Atmega32 at CodeVision:

interrupt [EXT_INT0] void ext_int0_isr(void)
{
printf("%d",PINA);
}

      


Update: I am changing the ATMEGA and Python-Side programs as suggested in the answers:

My AVR interrupt routine:

interrupt [EXT_INT0] void ext_int0_isr(void)
{
printf("%d",PINA);
printf("%d\n",0);
}

      

And this is my output in python:

>>> while(1):
    ser.readline()


'35\n'
'135\n'
'135\n'
'135\n'
'135\n'
'135\n'
'135\n'
'agi\x16agi\x16\xff135255\n'
'1350\n'
'1350\n'
'1350\n'
'1350\n'
'1350\n'
'1350\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'1350\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'1350\n'
'1350\n'
'1350\n'
'1350\n'
'1350\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'1350\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'1350\n'
'1350\n'
'1350\n'
'1350\n'
'1350\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'1350\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'

      

As you can see, the output is not what we expected from AVR code and Python code!

+3


source to share


2 answers


I'll try to explain what's going on:

On the μC side, you transmit the value over the serial line. You have to decide in what format this happens and force the recipient to use the same format.

You have decided to use ASCII. Thus, the device converts each value to its digits and sends them down the line. The problem with the fist is that you don't have a separator. If you have 5 times the value of 77, it sends 7777777777

. But how do you know that this is not 10 times the value of 7? Thus, you must add a line separator.



Other options could be sending binary data data (as it is) or as hex data with all 2 bytes (s printf("%02x", PINA)

). Then you don't need a separator.

Whichever way you choose, you will need to make the receiver compatible with the sender.

  • If you keep it as is (but with \n

    ), you can work with .readline()

    .
  • If you ship it as binary, you can keep it as is.
  • If you want to use hexadecimal format, you also need to read 2 bytes and convert them as you wish.
+2


source


ser.read()

will only return 1 byte at a time. Specify a counter to read multiple bytes.

>>> x = ser.read()          # reads one byte
>>> x = ser.read(10)        # reads up to ten bytes 

      

You can try instead ser.readline()

.

Edit:

Can you try inserting a newline character into the program you wrote for the Atmega32:



interrupt [EXT_INT0] void ext_int0_isr(void)
{
printf("%d\n",PINA);
}

      

and then find the newline character before printing:

mylist=[]
while True:
    char = ser.read()
    if char == '\n':
        print(mylist)
        mylist = []
        continue
    mylist.append(char)

      

or use ser.readline()

as suggested by @hyades in the comments.

+4


source







All Articles