Python Forum

Full Version: User serial/pyserial to send messages to an arudino via terminal manually
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Is there a way to send a byte/char to the arudino using serial/pyserial without tying up the serial port continuously so I can send control commands to the arduino via the command line/keyboard inputs when needed and be able to read for events from the arudino?

We plan on using command line to interact with the arudino such as start/stop on command but we have a sensor that we want to constantly listen to for events?

Is this possible through pyserial/serial?
Do you mean open the port, write data (some bytes), receive data, close connection?
Example:

import sys
import time
from argparse import ArgumentParser
from binascii import hexlify, unhexlify
from pathlib import Path

from serial import Serial, SerialException


def send_receive(port, baudrate, command, delay, timeout):
    port = Path("/dev", port)
    if not port.exists():
        raise ValueError(f"{port} does not exist.")
    raw_data = unhexlify(command)  # str as hex representation -> bytes
    with Serial(port=str(port), baudrate=baudrate, timeout=timeout / 1000) as ser:
        ser.write(raw_data)
        time.sleep(delay / 1000)
        return hexlify(ser.read()).decode()


def get_args():
    parser = ArgumentParser()
    parser.add_argument("port", help="Name of serial port without /dev/")
    parser.add_argument(
        "baudrate", default=9600, type=int, help="Baudrate of serial connection"
    )
    parser.add_argument("command", help="hexadecimal string literal to send.")
    parser.add_argument(
        "delay", default=1000, type=int, help="Delay in ms to wait after sending data"
    )
    parser.add_argument(
        "timeout", default=5000, type=int, help="Timeout in ms for receiving data"
    )
    return parser.parse_args()


def main():
    args = get_args()
    received_data = send_receive(
        args.port, args.baudrate, args.command, args.delay, args.timeout
    )
    if not received_data:
        print("No data received...")
    else:
        print(received_data)


if __name__ == "__main__":
    try:
        main()
    except SerialException as e:
        print(" ".join(e.args[1:]), file=sys.stderr)
Not plug and play, but a very robust solution:

You could use something like https://www.adafruit.com/product/4471 which uses a Microchip MCP2221A
https://www.microchip.com/wwwproducts/en/MCP2221A uSB to I2C bridge

It can be wired to an Arduino's I2C connectors as follows: https://howtomechatronics.com/tutorials/...h-arduino/

It will take a bit of work to get everything in sync, but software is provided by adafruit.

If you use this approach, you will have the ability to hook multiple devices to the same I2C port.

Here are a couple of I2C tutorials if you are interested in this form of communications (most use python):

These specifically for the arduino:
Video: https://www.youtube.com/watch?v=6IAkYpmA1DQ
https://howtomechatronics.com/tutorials/...h-arduino/

https://learn.sparkfun.com/tutorials/i2c/all

https://www.circuitbasics.com/basics-of-...-protocol/

more video:
https://www.youtube.com/watch?v=DsSBTYbXAKg
https://www.youtube.com/watch?v=HGX457RA4IU