baldaquin.arduino_
— Arduino interface#
This module provides minimal support for interacting with the Arduino ecosystem, the basic idea is that we start with Arduino UNO and we add on more boards as we need them.
See also
In order to fully utilize the facilities in this module you will need at least some additional third-paryt software. The following links are relevant for operating with Arduino boards.
Since nowadays the Arduino CLI seems to be the preferred way to interact
programmatically with the Arduino ecosystem, we will assume that is the
default choice. If you have arduino-cli
installed you should be good to
go—see the installation instructions.
(This will literally run a script and copy the executable on your machine,
which is handy because you will not need administrator priviledges to
run the thing. The same thing holds for all the additional modules, e.g.,
arduino:avr you might need.)
The ArduinoBoard
class provides a small
container encapsulating all the information we need to interact with a board, most
notably the list of DeviceId
for the latter
(that can be used to auto-detect boards attached to a COM port), as well as the
relevant parameters to upload sketches on it.
A small database internal to the class contains a list of boards that we support, and which can be retrieved either by DeviceId or by designator:
>>> board = ArduinoBoard.by_device_id(DeviceId(0x2341, 0x43))
>>> print(board)
ArduinoBoard(designator='uno', name='Arduino UNO', vendor='arduino',
architecture='avr', upload_protocol='arduino', upload_speed=115200,
build_mcu='atmega328p', device_ids=((vid=0x2341, pid=0x43),
(vid=0x2341, pid=0x1), (vid=0x2a03, pid=0x43), (vid=0x2341, pid=0x243),
(vid=0x2341, pid=0x6a)))
>>>
>>> board = ArduinoBoard.by_designator('uno')
>>> print(board)
ArduinoBoard(designator='uno', name='Arduino UNO', vendor='arduino',
architecture='avr', upload_protocol='arduino', upload_speed=115200,
build_mcu='atmega328p', device_ids=((vid=0x2341, pid=0x43),
(vid=0x2341, pid=0x1), (vid=0x2a03, pid=0x43), (vid=0x2341, pid=0x243),
(vid=0x2341, pid=0x6a)))
Auto-detecting boards#
The module comes with a couple of utilities to help auto-detecting boards.
autodetect_arduino_boards()
will look over all the COM ports and identify all the supported Arduino boards
connected. An arbitrary number of board objects can be passed to the function, and
they will act as a filter for the boards that are actually returned. If, e.g.,
you are interested in all the Arduino UNOs connected, you can do something along
the lines of:
>>> ports = arduino_.autodetect_arduino_boards(arduino_.UNO)
>>> [INFO] Autodetecting Arduino boards ['Arduino UNO']...
>>> [INFO] Scanning serial devices...
>>> [DEBUG] Port(name='/dev/ttyS0', device_id=(vid=None, pid=None), manufacturer=None)
>>> [DEBUG] Port(name='/dev/ttyACM0', device_id=(vid=0x2341, pid=0x43), manufacturer='Arduino (www.arduino.cc)')
>>> [INFO] Done, 2 device(s) found.
>>> [INFO] Filtering port list for specific devices: [(vid=0x2341, pid=0x43), (vid=0x2341, pid=0x1), (vid=0x2a03, pid=0x43), (vid=0x2341, pid=0x243), (vid=0x2341, pid=0x6a)]...
>>> [INFO] Done, 1 device(s) remaining.
>>> [DEBUG] Port(name='/dev/ttyACM0', device_id=(vid=0x2341, pid=0x43), manufacturer='Arduino (www.arduino.cc)')
>>> [DEBUG] /dev/ttyACM0 -> uno (Arduino UNO)
>>>
>>> print(ports)
>>> [Port(name='/dev/ttyACM0', device_id=(vid=0x2341, pid=0x43), manufacturer='Arduino (www.arduino.cc)')]
The function returns a list of Port
objects,
that are ready to use.
In many cases you might be interested in a single board, in which case you can use
the autodetect_arduino_board()
,
variant. This will return the first board that is found, and log a warning if
more than one is connected.
These two functions can be integrated in complex workflows as needed.
Uploading sketches#
This module implements two diffent interfaces to programmatically upload sketches onto a connected Arduino board:
ArduinoCli
, wrapping the Arduino command-line interface;AvrDude
, wrapping avrdude.
As alerady said earlier on, we shall assume that arduino-cli
is the preferred
way to do business. In most cases you can simply use the top-level interface
upload_sketch()
to upload a sketch onto
an Arduino board connected to the computer.
Compiling sketches#
The module also provides a way to compile sketches, using the simple, top-level
interface compile_sketch()
.
Module documentation#
Arduino common resources.
- class baldaquin.arduino_.ArduinoBoard(designator: str, name: str, vendor: str, architecture: str, upload_protocol: str, upload_speed: int, build_mcu: str, device_ids: tuple[DeviceId])[source]#
Small container class representing a specific Arduino board.
This is not supposed as a mean to replicate all the functionalities of the Arduino CLI—on the contrary, we want to include here the bare minimum that is necessary in order to do simple things, e.g., auto-recognize Arduino boards attached to the serial port and programmatically upload a sketch.
The ultimate reference for all this information is embedded into the (platform-specific) boards.txt file, e.g., arduino/ArduinoCore-avr Rather than parsing the entire file and come up with a parallel Python structure supporting all the boards on the face of the Earth, we decided to manually add the necessary data for specific boards only when (and if) we need them, starting from the Arduino UNO, being used in plasduino.
The typical entry in the file for a board is something like this:
uno.name=Arduino UNO uno.vid.0=0x2341 uno.pid.0=0x0043 uno.vid.1=0x2341 uno.pid.1=0x0001 uno.vid.2=0x2A03 uno.pid.2=0x0043 uno.vid.3=0x2341 uno.pid.3=0x0243 uno.vid.4=0x2341 uno.pid.4=0x006A uno.upload_port.0.vid=0x2341 uno.upload_port.0.pid=0x0043 uno.upload_port.1.vid=0x2341 uno.upload_port.1.pid=0x0001 uno.upload_port.2.vid=0x2A03 uno.upload_port.2.pid=0x0043 uno.upload_port.3.vid=0x2341 uno.upload_port.3.pid=0x0243 uno.upload_port.4.vid=0x2341 uno.upload_port.4.pid=0x006A uno.upload_port.5.board=uno uno.upload.tool=avrdude uno.upload.tool.default=avrdude uno.upload.tool.network=arduino_ota uno.upload.protocol=arduino uno.upload.maximum_size=32256 uno.upload.maximum_data_size=2048 uno.upload.speed=115200 uno.bootloader.tool=avrdude uno.bootloader.tool.default=avrdude uno.bootloader.low_fuses=0xFF uno.bootloader.high_fuses=0xDE uno.bootloader.extended_fuses=0xFD uno.bootloader.unlock_bits=0x3F uno.bootloader.lock_bits=0x0F uno.bootloader.file=optiboot/optiboot_atmega328.hex uno.build.mcu=atmega328p uno.build.f_cpu=16000000L uno.build.board=AVR_UNO uno.build.core=arduino uno.build.variant=standard
Note that we refer to the qualifier for the board (“uno” in this case) as the board designator, and we parse the bare minimum of the information from the file.
- designator: str#
- name: str#
- vendor: str#
- architecture: str#
- upload_protocol: str#
- upload_speed: int#
- build_mcu: str#
- fqbn() str [source]#
Return the fully qualified board name (FQBN), as defined in https://arduino.github.io/arduino-cli/1.1/platform-specification/
- static concatenate_device_ids(*boards: ArduinoBoard) tuple[DeviceId] [source]#
Return a tuple with all the possible DeviceId objects corresponding to a subset of the supported arduino boards.
- Parameters:
*boards (ArduinoBoard) – The ArduinoBoard object(s) we are interested into.
- Returns:
A tuple of DeviceId objects.
- Return type:
tuple
- static by_device_id(device_id: DeviceId) ArduinoBoard [source]#
Return the ArduinoBoard object corresponding to a given DeviceId.
Note this only involves a dictionary lookup, and nothing is created on the spot.
- Parameters:
vid (int) – The vendor ID for the given device.
pid (int) – The prodict ID for the given device.
- Returns:
The ArduinoBoard object corresponding to the DeviceId.
- Return type:
- static by_designator(designator: str) ArduinoBoard [source]#
Return the ArduinoBoard object corresponding to a given (vid, pid) tuple.
Note this only involves a dictionary lookup, and nothing is created on the spot.
- Parameters:
designator (str) – The board designator (e.g., “uno”).
- Returns:
The ArduinoBoard object corresponding to the designator.
- Return type:
- baldaquin.arduino_.autodetect_arduino_boards(*boards: ArduinoBoard) list[Port] [source]#
Autodetect all supported arduino boards of one or more specific types attached to the COM ports.
- Parameters:
*boards (ArduinoBoard) – The ArduinoBoard object(s) we are interested into.
- Returns:
The list of Port object with relevant boards attached to them.
- Return type:
list of Port objects
- baldaquin.arduino_.autodetect_arduino_board(*boards: ArduinoBoard) Port [source]#
Autodetect the first supported arduino board within a list of board types.
Note this returns None if no supported arduino board is found, and the first board found in case there are more than one.
- Parameters:
*boards (ArduinoBoard) – The ArduinoBoard object(s) we are interested into.
- Returns:
The Port object our target board is attached to.
- Return type:
- class baldaquin.arduino_.ArduinoProgrammingInterfaceBase[source]#
Basic class for concrete interfaces for programming Arduino devices.
- PROGRAM_NAME = None#
- PROGRAM_URL = None#
- static upload(file_path: str, port: str, board: ArduinoBoard, **kwargs) CompletedProcess [source]#
Do nothing method, to be reimplented in derived classes.
- classmethod _execute(args) CompletedProcess [source]#
Execute a shell command.
This is wrapping the basic subprocess functionality, adding some simple diagnostics. Note a
CalledProcessError
exception is raised if the underlying program returns an error code different from zero.- Parameters:
args (any) – All the arguments passed to subprocess.run().
- Returns:
The CompletedProcess object.
- Return type:
subprocess.CompletedProcess
- class baldaquin.arduino_.ArduinoCli[source]#
Poor-man Python interface to the Arduino-CLI.
The installation instructions for the arduino command-line interface are at https://arduino.github.io/arduino-cli/1.1/installation/
(At least on GNU/Linux) this points to a single file that you can just place wherever your $PATH will reach it. For the records: when I run the thing for the first time (uploading a sketch to an Arduino UNO) it immediately prompted me to install more stuff
>>> arduino-cli core install arduino:avr
(which I guess is fine, but it is weighing in as to what we should suggest users to install).
- PROGRAM_NAME = 'arduino-cli'#
- PROGRAM_URL = 'https://github.com/arduino/arduino-cli'#
- static upload(file_path: str, port: str, board: ArduinoBoard, verbose: bool = False) CompletedProcess [source]#
Upload a sketch to a board.
Note this is using avrdude under the hood.
Usage: arduino-cli upload [flags] Examples: arduino-cli upload /home/user/Arduino/MySketch -p /dev/ttyACM0 -b arduino:avr:uno arduino-cli upload -p 192.168.10.1 -b arduino:avr:uno --upload-field password=abc Flags: --board-options strings List of board options separated by commas. Or can be used multiple times for multiple options. --build-path string Directory containing binaries to upload. --discovery-timeout duration Max time to wait for port discovery, e.g.: 30s, 1m (default 1s) -b, --fqbn string Fully Qualified Board Name, e.g.: arduino:avr:uno -h, --help help for upload --input-dir string Directory containing binaries to upload. -i, --input-file string Binary file to upload. -p, --port string Upload port address, e.g.: COM3 or /dev/ttyACM2 -m, --profile string Sketch profile to use -P, --programmer string Programmer to use, e.g: atmel_ice -l, --protocol string Upload port protocol, e.g: serial -F, --upload-field key=value Set a value for a field required to upload. --upload-property stringArray Override an upload property with a custom value. Can be used multiple times for multiple properties. -v, --verbose Optional, turns on verbose mode. -t, --verify Verify uploaded binary after the upload. Global Flags: --additional-urls strings Comma-separated list of additional URLs for the Boards Manager. --config-dir string Sets the default data directory (Arduino CLI will look for configuration file in this directory). --config-file string The custom config file (if not specified the default will be used). --json Print the output in JSON format. --log Print the logs on the standard output. --log-file string Path to the file where logs will be written. --log-format string The output format for the logs, can be: text, json (default "text") --log-level string Messages with this level and above will be logged. Valid levels are: trace, debug, info, warn, error, fatal, panic (default "info") --no-color Disable colored output.
- static compile(file_path: str, output_dir: str, board: ArduinoBoard, verbose: bool = False) CompletedProcess [source]#
Compile a sketch.
Usage: arduino-cli compile [flags] Examples: arduino-cli compile -b arduino:avr:uno /home/user/Arduino/MySketch arduino-cli compile -b arduino:avr:uno --build-property "build.extra_flags="-DMY_DEFINE="hello world""" /home/user/Arduino/MySketch arduino-cli compile -b arduino:avr:uno --build-property "build.extra_flags=-DPIN=2 "-DMY_DEFINE="hello world""" /home/user/Arduino/MySketch arduino-cli compile -b arduino:avr:uno --build-property build.extra_flags=-DPIN=2 --build-property "compiler.cpp.extra_flags="-DSSID="hello world""" /home/user/Arduino/MySketch Flags: --board-options strings List of board options separated by commas. Or can be used multiple times for multiple options. --build-path string Path where to save compiled files. If omitted, a directory will be created in the default temporary path of your OS. --build-property stringArray Override a build property with a custom value. Can be used multiple times for multiple properties. --clean Optional, cleanup the build folder and do not use any cached build. --discovery-timeout duration Max time to wait for port discovery, e.g.: 30s, 1m (default 1s) --dump-profile Create and print a profile configuration from the build. --encrypt-key string The name of the custom encryption key to use to encrypt a binary during the compile process. Used only by the platforms that support it. -e, --export-binaries If set built binaries will be exported to the sketch folder. -b, --fqbn string Fully Qualified Board Name, e.g.: arduino:avr:uno -h, --help help for compile -j, --jobs int32 Max number of parallel compiles. If set to 0 the number of available CPUs cores will be used. --keys-keychain string The path of the dir to search for the custom keys to sign and encrypt a binary. Used only by the platforms that support it. --libraries strings Path to a collection of libraries. Can be used multiple times or entries can be comma separated. --library strings Path to a single library’s root folder. Can be used multiple times or entries can be comma separated. --only-compilation-database Just produce the compilation database, without actually compiling. All build commands are skipped except pre* hooks. --optimize-for-debug Optional, optimize compile output for debugging, rather than for release. --output-dir string Save build artifacts in this directory. -p, --port string Upload port address, e.g.: COM3 or /dev/ttyACM2 --preprocess Print preprocessed code to stdout instead of compiling. -m, --profile string Sketch profile to use -P, --programmer string Programmer to use, e.g: atmel_ice -l, --protocol string Upload port protocol, e.g: serial --quiet Optional, suppresses almost every output. --show-properties string[="expanded"] Show build properties. The properties are expanded, use "--show-properties=unexpanded" if you want them exactly as they are defined. (default "disabled") --sign-key string The name of the custom signing key to use to sign a binary during the compile process. Used only by the platforms that support it. -u, --upload Upload the binary after the compilation. -v, --verbose Optional, turns on verbose mode. -t, --verify Verify uploaded binary after the upload. --warnings string Optional, can be: none, default, more, all. Used to tell gcc which warning level to use (-W flag). (default "none") Global Flags: --additional-urls strings Comma-separated list of additional URLs for the Boards Manager. --config-dir string Sets the default data directory (Arduino CLI will look for configuration file in this directory). --config-file string The custom config file (if not specified the default will be used). --json Print the output in JSON format. --log Print the logs on the standard output. --log-file string Path to the file where logs will be written. --log-format string The output format for the logs, can be: text, json (default "text") --log-level string Messages with this level and above will be logged. Valid levels are: trace, debug, info, warn, error, fatal, panic (default "info") --no-color Disable colored output.
- class baldaquin.arduino_.AvrDude[source]#
Poor-man Python interface to the avrdude.
Usage: avrdude [options] Options: -p <partno> Required. Specify AVR device. -b <baudrate> Override RS-232 baud rate. -B <bitclock> Specify JTAG/STK500v2 bit clock period (us). -C <config-file> Specify location of configuration file. -c <programmer> Specify programmer type. -D Disable auto erase for flash memory -i <delay> ISP Clock Delay [in microseconds] -P <port> Specify connection port. -F Override invalid signature check. -e Perform a chip erase. -O Perform RC oscillator calibration (see AVR053). -U <memtype>:r|w|v:<filename>[:format] Memory operation specification. Multiple -U options are allowed, each request is performed in the order specified. -n Do not write anything to the device. -V Do not verify. -u Disable safemode, default when running from a script. -s Silent safemode operation, will not ask you if fuses should be changed back. -t Enter terminal mode. -E <exitspec>[,<exitspec>] List programmer exit specifications. -x <extended_param> Pass <extended_param> to programmer. -v Verbose output. -v -v for more. -q Quell progress output. -q -q for less. -l logfile Use logfile rather than stderr for diagnostics. -? Display this usage. avrdude version 6.4, URL: <http://savannah.nongnu.org/projects/avrdude/>
- PROGRAM_NAME = 'avrdude'#
- PROGRAM_URL = 'https://github.com/avrdudes/avrdude'#
- static upload(file_path: str, port: str, board: ArduinoBoard, verbose: bool = False) CompletedProcess [source]#
Upload a sketch to a board.
- baldaquin.arduino_.upload_sketch(file_path: str, board_designator: str, port_name: str | None = None, verbose: bool = False) CompletedProcess [source]#
High-level interface to upload a compiled sketch to an arduino board.
- Parameters:
file_path (str) – The path to the binary file containing the sketch compiled for the given board.
board_designator (str) – The board designator (e.g., “uno”).
port_name (str, optional) – The port name the board is attached to (e.g., “/dev/ttyACM0”). If this is None, we use the autodetection features implemented in the module.
verbose (bool) – If True, the program will run in verbose mode.
- baldaquin.arduino_.compile_sketch(file_path: str, board_designator: str, output_dir: str, verbose: bool = False) CompletedProcess [source]#
High-level interface to compile a sketch for a given arduino board.
- Parameters:
file_path (str) – The path to the binary file containing the sketch compiled for the given board. Note that, in virtue of some interesting decision by the Arduino team, it appears that the main source file for the sketch should be embedded in a folder with the same name (without extension)—I guess that vaguely makes sense for sketches with multiple files. The directory name is also gladly accepted for the compilation.
board_designator (str) – The board designator (e.g., “uno”).
otuput_dir (str) – Path to the folder where the compilation artifacts should be placed.
verbose (bool) – If True, the program will run in verbose mode.