Python Forum
How to Properly Open a Serial Port in a Function
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to Properly Open a Serial Port in a Function
#1
Being a new guy to Python, I’m trying to figure out how to properly pass information between functions so I can keep redundant code to a minimum. However, I must have figured something wrong regarding my function that opens a serial port. I want to be able to open the serial port in one function and write to and read from the serial port in other functions. I think I’m returning serial port information wrong.

What am I missing that causes this code to not work?

"""Sends a  message via serial & receives back information via serial."""
 
import serial
import time
port = ' '
PLAYING_DONE = bytearray([170, 1, 1, 0, 172])

def request(port, track_info):
    """Start playing track.  Track is??"""
    print("def request ", port, track_info)  #For debugging
    write_command(port, [7] + track_info)

def write_command(port, command):
    """Write command to serial port"""
    print("def write_command ", port, command)  #For debugging
    command = [170] + command           # Command packet starts with 0xAA
    command.append(sum(command) % 256)  # Append checksum
    print('Command = ', command)        # For debugging purposes
    port_open(port)                     # Open Serial Port
    port.write(bytearray(command))     #<--- seems the error is here
    port.close()

def port_open(port):
    """Open serial port"""
    print("def port_open ", port)       #For debugging
    ser = serial.Serial('/dev/ttyS0',   # Serial port on my computer
        baudrate=9600, parity=serial.PARITY_NONE,
        stopbits=serial.STOPBITS_ONE,
        bytesize=serial.EIGHTBITS, timeout=30)     #  timeout for read
    return port

def read_status(port, info_length):
    """Read status?  Returns  bytearray"""
    print("def read_status ", port, info_length)
    write_command(port, [1, 0])
    time.sleep(0.5)
    port_open(port)                     # Open Serial Port
    if port.inWaiting() == info_length:
         return port.read(info_length)
    port.close()

request(port, [2, 0, 9])                # Track info?
while reading != PLAYING_DONE:
    reading = read_status(port, 4)
    print(f'Return = {reading}')        # For debugging purposes

request(port, [12, 0])                  # query_MP3_count
while reading[0] != PLAYING_DONE[0]:
    reading = read_status(port, 5)
    print(f'Return = {reading}')        # For debugging purposes
print("Total MP3s ", reading[3] + reading[4])
time.sleep(2)

print("Done and closed")
Error:
pi@raspberrypi:~ $ sudo python3 QueryTest.py def request [2, 0, 9] def write_command [7, 2, 0, 9] Command = [170, 7, 2, 0, 9, 188] def port_open Traceback (most recent call last): File "QueryTest.py", line 42, in <module> request(port, [2, 0, 9]) # Track info? File "QueryTest.py", line 11, in request write_command(port, [7] + track_info) File "QueryTest.py", line 20, in write_command port.write(bytearray(command)) AttributeError: 'str' object has no attribute 'write'
Reply
#2
On line 5 port = ' ' so port is an empty string
The error on line 20 port.write(bytearray(command)) #<--- seems the error is here is because the code is trying to call a write method on that string of which does not have that method.

def port_open(port):
    """Open serial port"""
    print("def port_open ", port)       #For debugging
    ser = serial.Serial('/dev/ttyS0',   # Serial port on my computer
        baudrate=9600, parity=serial.PARITY_NONE,
        stopbits=serial.STOPBITS_ONE,
        bytesize=serial.EIGHTBITS, timeout=30)     #  timeout for read
    return port
this function has a port parameter but is it really needed as it's aim is to open a port.
it is returned the port that is passed into it which is an empty string.
Should it be returning the opened port ser

If port_open(port) was actually returning an open port, in the two places that it's used at the moment its is not using a variable to point to that open port.
port = port_open(port)
Reply
#3
Thanks guys.

You showed me the problem in my program. Actually 2 problems.

1st, the statement ser = serial.Serial('/dev/ttyS0', should be port = serial.Serial('/dev/ttyS0'.
2nd, I added the statement port = port_open(port) where appropriate.

I have some more fine tuning but that made all of the difference.

Thanks again.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Waiting for input from serial port, then move on KenHorse 3 1,051 Apr-17-2024, 07:21 AM
Last Post: DeaD_EyE
  MCU reboots after opening Serial port when ran from Raspberry PI zazas321 3 436 Mar-19-2024, 09:02 AM
Last Post: zazas321
  pyserial/serial "has no attribute 'Serial' " gowb0w 9 4,004 Aug-24-2023, 07:56 AM
Last Post: gowb0w
  with open context inside of a recursive function billykid999 1 579 May-23-2023, 02:37 AM
Last Post: deanhystad
  Serial Port As Global Prasanjith 2 1,501 Mar-23-2023, 08:54 PM
Last Post: deanhystad
  python serial port barryjo 2 1,656 Dec-27-2021, 11:09 PM
Last Post: barryjo
  is there a way to mention port range or search for port dynamically with qConnection Creepy 0 1,486 Sep-09-2021, 03:15 PM
Last Post: Creepy
Question Python3 - serial port reload parovelb 4 5,871 Apr-08-2021, 09:18 AM
Last Post: parovelb
  Unable to read from serial port br0kenpixel 1 2,477 Aug-08-2020, 10:03 PM
Last Post: Larz60+
  Read Data from Serial Port PA3040 3 3,189 Feb-16-2020, 04:54 AM
Last Post: PA3040

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020