USART communication between Atmega32 and Python2.7

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I wrote a program in python2.7 that receive a binary number from Atmega32 via USART and prints it in output.

in the other hand, My Atmega32 read its PINA on the interrupt firing and sends its value to the computer using USART.

 

this is my python program :

 

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

 

when I connect PINA pins in a way that make00000111 (equal to 7), I see the below output in python:

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

But when I connect PINA pins in a way that make 10000111 (equal to 135), I see the below output in python :

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

As you see above, it prints 135 in three line! Why?

 

FYI : This is the program that I wrote for Atmega32 in CodeVision :

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

 

As I can't distinguish a multi-digit number from some singl-digit numbers (for example, I can't distiguish 135 from 1, 3 and 5 in a row), I change my Codevision program as below :

 

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

I expect an output like below (for PINA='00000111') :

 

7
$
$
$
$
7
$
$
$
$
7
$
$
$
$
7

and for PINA='10000111' I expect the below output :

 

1
3
5
$
$
$
$
1
3
5
$
$
$
$
1
3
5
$
$
$
$

But, what I received is like below :

 

7
$
$
$
$
7
$
$
$
$
7
$
$
$
$
7
7
7
$
$
$
$
7
$
$
$
$
7
7
7
$
$
$
$
7
$
$
$
$
7
7
7
$
$
$
$

and

 

 

1
3
5
$
$
$
$
1
3
5
$
$
$
$
1
3
5
$
$
$
$
1
3
5
$
$
$
$
1
3
5
1
3
5
1
3
5
$
$
$
$
1
3
5
1
3
5
1
3
5
$
$
$
$
1
3
5
1
3
5
1
3
5
$
$
$
$
1
3
5

 

As you see in the real outputs above, sometimes 7 repeated unexpectedly before printing dollar signs! 

 

So, I have two questions: 

 

1- Why python prints a single multi-digit number in multiple lines? (while 135 is one byte and we expect it to print each byte in a singe line)!

2- Why in the second form of interrupt routine, PINA value repeats unexpectedly for 3 times between printing $ sings? (Can it be related to the speed of interrupt firing rate?)

This topic has a solution.
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

1. Python did what you asked. Read the doc.
2. You are sending three bytes - the characters 1 3 and 5. That's what printf and %d do.

You probably want to use readline in python and add a line end in your printf. Ie printf("%d\n",PINA);

Last Edited: Sat. Dec 27, 2014 - 10:12 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ebrahim.rcii wrote:
As you see above, it prints 135 in three line! Why?

 

FYI : This is the program that I wrote for Atmega32 in CodeVision :

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

 

1- Why python prints a single multi-digit number in multiple lines? (while 135 is one byte and we expect it to print each byte in a singe line)!

 

printf 'prints with format'.

%d means that you want to send a number.

135 consists of three characters, so you're sending a '1', a '3' and a '5'.

 

Your python on the other hand, has no print statement, so it's just formatting what receives (each byte is displayed as an ascii letter on screen).

 

To send one byte, you should use "printf("%c", number);"

To display it in python, maybe you should use a print statement : while true: print "{:d}".format(ser.read())"

 

ebrahim.rcii wrote:

2- Why in the second form of interrupt routine, PINA value repeats unexpectedly for 3 times between printing $ sings? (Can it be related to the speed of interrupt firing rate?)

No idea.

What speeds are you using on the serial port?

Maybe your µc isn't at the same exact speed?

maybe your python is missing some values?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

send and receive your numeric information in ASCII text chars, not binary. That's essential to avoid byte-order issues and other factors.

 

I have mega328, mega1284 and ARM with UART at 115,200 baud working with Python 2.7 and the serial module.

There are issues reported when using the serial module with Python 3.

 

On AVR (0r any) never print or call library functions from an interrupt service routine.

 

 

 

Last Edited: Tue. Dec 30, 2014 - 09:17 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As noted, the primary cause of you confusion is that by default serial.Serial.read returns a one-character string.

In python's interactive mode, an expression causes python to print its value as a string and follow it by a newline.

Your python will show only one character per line.

 

The repetitions are a mystery to me.

From the continuous interrupts, I infer that INT0 is configured to be level-based.

If your ISR code runs in the order specified, I see no possible mechanism for repetition.

If it runs out of order, that suggests that interrupts are being re-enabled somehow.

Perhaps printf sometimes does that.

If it did that all the time, you would blow the stack with nested interrupts.

 

Why do this in an interrupt?

If it's going to happen all the time anyway, why not just make it part of the main loop?

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Quote:
If it's going to happen all the time anyway, why not just make it part of the main loop?
From another thread by the OP, the capture points will likely come faster than they can be pushed out the USART.  He needs to capture into a ring buffer, and dump that buffer to the USART in the main loop.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear friends ,thank you for your time and your considerations.

These two problem have been solved as follow :

 

The first problem solution : 

1-I replace ser.read() with ser.readline() in python program.

2-I changed print("%d",PINA) with printf("%02x",PINA) in Codevision program.

 

 

The second problem solution :

1-Moving printf("%02x",PINA) out of ISR

2-Using Ring Buffer

 

Last Edited: Wed. Dec 31, 2014 - 08:32 PM