A lightweight command line serial monitor for communicating with microcontrollers
This project was inspired by the Arduino IDE's serial monitor which is useful while developing and debugging code on an external device like an Arduino or Teensy board.
The project is built with Python 3, it uses the pySerial library to identify and communicate with serial ports, the python Curses library to render a simple text based user interface in a terminal window and Click to provide a command line interface.
This script has been tested using Mac OS and Linux but it may work for Windows as well.
Python 3 and the pip package manager are required, if you don't have them, learn how to install them here.
Before using micro_monitor, use pip to install dependencies:
pip3 install -r requirements.txt
If you like the tool, you may want to make it executable and save an alias for it in your system.
Navigate to the repository in your terminal and run the script. Note that on a Linux machine serial ports may be reserved for administrators, you may need to run the script with sudo
.
cd micro_monitor/
python3 micro_monitor.py
micro_monitor first checks for available serial ports. Because printers and other devices often appear in this list, it only searches for devices which include "usb" in their name. If one port exists, it is selected by default, if multiple ports exist you may select the desired one.
Connections are opened at a baudrate of 9600 by default.
One usb port available:
-> Port selection: /dev/cu.usbmodem4091371 Teensyduino
-> Serial port connection opened at 9600 baud
Once a connection is available, press return
to enter the serial monitor window. You may press the escape
key to exit at any time.
The window is divided in half into send and receive sections.
A prompt in the send section allows you to compose a string to send to the serial port. This prompt is very basic, only ascii characters are allowed but it is possible to type a simple command, use the backspace
key and press return
to send the command.
The receive section displays the most recently received messages from the serial port.
The monitor window may be resized while the script runs. The most recently sent and recieved messages are always displayed.
Note that the Curses temporarily changes the way the terminal reacts. If micro_monitor doesn't exit gracefully you may find a mess of characters left on the screen and that text is not wrapping properly. To fix this, just type the terminal command reset
.
You may also find that if you attempt to scroll in your terminal window, you no longer see the most recently rendered text output. In that case, press any key to get back into the terminal user interface.
Because micro_monitor.py requires something to communicate with, a good example program for a microcontroller will send data to its serial port and then accept, process and return messages. As an example I've been using a program that translates incoming strings to uppercase. If you have an Arduino compatible microcontroller, you can use the following code, which is also included in the repository under example_arduino_sketch/
:
int inByte = 0; // incoming serial byte
int i = 0;
void setup() {
// start serial port at 9600 bps and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
establishContact(); // send a byte to establish contact until receiver responds
}
void loop() {
if (Serial.available() > 0) {
// get incoming byte:
inByte = Serial.read();
if (inByte == 10) {
Serial.println();
}
else {
// Check if inByte is in the lowercase range
if (inByte >= 97 && inByte <= 122) {
inByte = inByte - 32;
}
Serial.write(inByte);
i++;
}
}
}
void establishContact() {
while (Serial.available() <= 0) {
Serial.println("Waiting for a byte.."); // send an initial string
delay(300);
}
}
Several command line options are provided. For example, to open a connection with the baud rate of 19200 :
python3 micromonitor.py --baud_rate=19200
To see a full list of command line options, use the option --help
Options:
--baud_rate INTEGER Baud rate, default is 9600bps.
--line_ending TEXT Line ending for serial messages, options are: 'n': for
\n, 'r': for \r, 'both': for \r\n. The default is 'n'.
--all_ports Show all availble serial ports. By default only serial
ports with "usb" in their path are shown.
--port TEXT Select specific port number.
--monochrome Black and white mode.
--help Show this message and exit.
- pySerial - Great documentation - pySerial Docs
- Python Curses Tutorial - A big picture introduction to Curses - Tutorial Videos
- Click - A tool for creating python command line interfaces - Click Docs
- Basics of communicating with serial ports in unix
- Handling special characters in Curses - A very helpful function - The Developer's Cry Blog
- Detecting the backspace key in Curses