Atmega328 controlling led with usart and pyserial

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

Hello together,

I want to control a simple led via pyserial.

If pyserial sends a 0, the led should go off, if a 1 is sent the led should go on again.

 

So I start with setting the pin to high, so the led is on.

As soon as I sent a 1 via pyserial the led goes off for about 1-2 second but then turns on again. It does not stay off.

 

Here are my files:

 

main.c


#include <avr/io.h>
#include <util/setbaud.h>

#define BAUD 9600
#define F_CPU 16000000UL

volatile uint8_t loopVar = 1;

void setup() {
    UBRR0H = UBRRH_VALUE;
	UBRR0L = UBRRL_VALUE;

	UCSR0B = (1<<RXEN0)|(1<<TXEN0); //enable uart
    UCSR0C = (1<<UCSZ01)|(1<<UCSZ00); // 8bit dataframe
};

int main(){
    setup();
    
    DDRD |= (1 << PIND4); // set pin4 as output
    PORTD |= (1<<4); // set high
    
    while(loopVar) {
        
        if (UCSR0A & (1<<RXC0)){
           if (UDR0 >0){
              PORTD |= (1<<4); 
           }else{
              PORTD &= ~(1<<4);
           };
        }
    }
}

 

Pyython file:

import serial
import struct
import binascii 

ser = serial.Serial()
ser.baudrate = 9600
ser.port = 'COM4'
ser.open()

print(ser.name)

value = 0
s = struct.pack('B', value)
ser.write(s) 
ser.close()

So again the problem is, that when I execute the python script, the led goes off but after 1-2 second goes on again. 

Can anyone detect an error or is there something wrong of my understanding with USART?

 

Thanks for any help:)

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

michac1995 wrote:
If pyserial sends a 0, the led should go off, if a 1 is sent the led should go on again.

You need to clarify, do you want to send 0 as in 0x00 (NUL) or "0" as in 0x30(ascii 0 char), and 1 as in 0x01(SOH) or "1" as in 0x31(ascii 1 char) ???

 

What other characters are in your data stream, cr? lf? cr & lf?

 

Jim

 

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

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

Atually it doesn't matter for me.
But let's say I want to sent integer values 0 and 1.

Sorry, what do you mean with cr? lf ? cr & lf?

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

michac1995 wrote:

Atually it doesn't matter for me.
But let's say I want to sent integer values 0 and 1.

Sorry, what do you mean with cr? lf ? cr & lf?

cr is carrage return

lf is line feed

 

I'm not familiar with pyserial, so I don't know what is sent when it is called. 

Does it convert the value passed into a single character, or as string of characters or what???

 

run a terminal emulator and connect it to your pyserial device and see what comes out when you run your program, or use a logic analyzer to see what is on the wire.

When working with two unknowns, your pyserial device, and your AVR device, you don't know which one is the problem.

so we need to know what the pyserial device actually sends on the wire when you run the program above, once you know that, then you can troubleshoot the avr end if needed.

 

Jim

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

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

As far as i know:
To send a single, unsigned byte the format character should be 'B' (in which case endianism does not apply) so struct.pack("B", value) should be enough:/

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

michac1995 wrote:

As soon as I sent a 1 via pyserial the led goes off for about 1-2 second but then turns on again. It does not stay off.

Don't know if it is, but turning back on could be explained by

1) the ser.close does something which appears to AVR as another received (and non zero) character, or

2) the AVR is resetting

 

 

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

MrKendo wrote:
1) the ser.close does something which appears to AVR as another received (and non zero) character, or

A logic analyzer or DSO would help show what is actually on the line.

 

Your code only tests for zero to turn LED on, all other characters ( >0) will turn the LED off.  So not real robust test, it may be better to use a switch case with 0, and 1, all else (default) are ignored. 

 

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

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

michac1995 wrote:

s = struct.pack('B', value)

Is indeed sending an unsigned byte, you might want to try this:

 

michac1995 wrote:

ser.flushOutput()
ser.flushOutput()
value = 0
s = struct.pack('B', value)
ser.write(s) 
ser.flushOutput()
ser.close()

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

Your test run is horrible.... pyserial should send a "1" then wait, then send a "0" then wait & repeat everything, say 5 times....do you then see your led blinking on & off? 

 

That will tell you a lot about whether things are proper between the systems...your test run tells basically nothing.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Tue. Dec 3, 2019 - 11:50 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Absolutely.

I'm not very familiar with python but even I can do somethihg like

while 1:
    s = raw_input('enter ')
    if s == 'q':
        break
    elif s == '0':
        print 'sent 0'
        # ser.write
    elif s == '1':
        print 'sent 1'
        # ser.write
    else:
        print 'ignored'

Probably all different now with python 3.

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

Rather than try to debug 2 bits of software at once, wouldn't it be simpler to just start by using a terminal on the PC to get the AVR working?

 

Then, once you know the AVR is working, move on to automating the PC end in Python.

 

Alternatively, get the Python working first by connecting to a terminal.

 

Using printable ASCII would make this a whole lot easier ...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...