In the ZTC a device is a peripheral that can execute Zerynth bytecode. In order to do so a device must be prepared and customized with certain attributes. The main attributes of a device are:

  • alias, a unique name given by the user to the device in order to identify it in ZTC commands
  • uid, a unique id provided by the operative system identifying the device at hardware level
  • target, specifies what kind of virtual machine can be run by the device
  • name, a human readable name describing the device. Automatically set by the ZTC
  • chipid, the unique identifier of the microcontroller present on the device
  • remote_id, the unique identifier of the device in the pool of user registered device
  • classname, a Python class name identifying the class containing commands to configure the device

When a new device is connected, some steps must be taken in order to make it able to run Zerynth code:

  1. The device must be discovered, namely its hardware parameters must be collected (uid).
  2. Once discovered an alias must be assigned. Depending on the type of device target and classname can be assigned in the same step.
  3. The device must be registered in order to create virtual machines for it (chipid and remote_id are obtained in this step)
  4. The device must be :ref:`virtualized <ztc-cmd-device-virtualize>, namely a suited virtual machine must be loaded on the device microcontroller

List of device commands:

The list of supported devices is available here


Device discovery is performed by interrogating the operative system database for USB connected peripherals. Each peripheral returned by the system has at least the following “raw” attributes:

  • vid, the USB vendor id
  • pid, the USB product id
  • sid, the unique identifier assigned by the operative system, used to discriminate between multiple connected devices with the same vid:pid
  • port, the virtual serial port used to communicate with the device, if present
  • disk, the mount point of the device, if present
  • uid, a unique identifier assigned by the ZTC
  • desc, the device description provided by the operative system (can differ between different platforms)

Raw peripheral data can be obtained by running:

ztc device discover


In Linux peripheral data is obtained by calling into libudev functions. In Windows the WMI interface is used. In Mac calls to ioreg are used.

Raw peripheral data are not so useful apart from checking the effective presence of a device. To obtain more useful data the option -- matchdb must be provided. Such option adds another step of device discovery on top of raw peripheral data that is matched against the list of supported devices and the list of already known devices.

A --matchdb discovery returns a different set of more high level information:

  • name, the name of the device taken from the ZTC supported device list
  • alias, the device alias (if set)
  • target, the device target, specifying what kind of microcontroller and pcb routing is to be expected on the device
  • uid, the device uid, same as raw peripheral data
  • chipid, the unique identifier of the device microcontrolloer (if known)
  • remote_id, the unique identifier of the device in the Zerynth backend (if set)
  • classname, the Python class in charge of managing the device

All the above information is needed to make a device usable in the ZTC. The information provided helps in distinguishing different devices with different behaviours. A device without an alias is a device that is not yet usable, therefore an alias must be set. A device without chipid and remote_id is a device that has not been :ref:`registered <ztc-cmd-device-register> yet and can not be virtualized yet.

To complicate the matter, there are additional cases that can be spotted during discovery:

  1. A physical device can match multiple entries in the ZTC supported device list. This happens because often many different devices are built with the same serial USB chip and therefore they all appear as the same hardware to the operative system. Such device are called “ambiguous” because the ZTC can not discriminate their target. For example, both the Mikroelektronika Flip&Click development board and the Arduino Due, share the same microcontroller and the same USB to serial converter and they both appear as a raw peripheral with the same vid:pid. The only way for the ZTC to differentiate between them is to ask the user to set the device target. For ambiguous devices the target can be set while setting the alias. Once the target is set, the device is disambiguated and subsequent discovery will return only one device with the right target.
  2. A physical device can appear in two or more different configurations depending on its status. For example, the Particle Photon board has two different modes: the DFU modes in which the device can be flashed (and therefore virtualized) and a “normal” mode in which the device executes the firmware (and hence the Zerynth bytecode). The device appears as a different raw peripherals in the two modes with different vid:pid. In such cases the two different devices will have the same target and, once registered, the same chipid and remote_id. They will appear to the Zerynth backend as a single device (same remote_id), but the ZTC device list will have two different devices with different alias and different classname. The classname for such devices can be set while setting the alias. In the case of the Particle Photon, the classname will be “PhotonDFU” for DFU mode and “Photon” for normal mode. PhotonDFU is the alter_ego of Photon in ZTC terminology.
  3. Some development boards do not have USB circuitry and can be programmed only through a JTAG or an external usb-to-serial converter. Such devices can not be discovered. To use them, the programmer device (JTAG or usb-to-serial) must be configured by setting alias and target to the ones the development device.

Finally, the discover command can be run in continuous mode by specifying the option --loop. With --loop the command keeps printing the set of discovered devices each time it changes (i.e. a new device is plugged or a connected device is unplugged). In some operative system the continuous discovery is implemented by polling the operative system device database for changes. The polling time can be set with option --looptime milliseconds, by default it is 2000 milliseconds.

Device configuration

Before usage a device must be configured. The configuration consists in linking a physical device identified by its uid to a logical device identified by its alias and target attributes. Additional attributes can be optionally set. The configuration command is:

ztc device alias put uid alias target

where uid is the device hardware identifier (as reported by the discovery algorithm), alias is the user defined device name (no spaces allowed) and target is one of the supported the supported devices target. A target specifies what kind of microcontroller, pin routing and additional perpherals can be found on the device. For example, the target for NodeMCU2 development board id nodemcu2 and informs the ZTC about the fact that the configured device is a NodeMCU2 implying an esp8266 microcontroller, a certain pin routing and an onboard FTDI controller.

There is no need to write the whole uid in the command, just a few initial character suffice, as the list of known uids is scanned and compared to the given partial uid (may fail if the given partial uid matches more than one uid).

Additional options can be given to set other device attributes:

  • --name name set the human readable device name to name (enclose in double quotes if the name contains spaces)
  • --chipid chipid used by external tools to set the device chipid manually
  • --remote_id remote_id used by external tools to set device remote_id manually
  • --classname classname used to set the device classname in case of ambiguity.

Aliases can be also removed from the known device list with the command:

ztc device alias del alias

Device Registration

To obtain a virtual machine a device must be registered first. The registration process consists in flashing a registration firmware on the device, obtaining the microcontroller unique identifier and communicating it to the Zerynth backend. The process is almost completely automated, it may simply require the user to put the device is a mode compatible with burning firmware.

Device registration is performed by issuing the command:

ztc device register alias

where alias is the device alias previously set (or just the initial part of it).

The result of a correct registration is a device with the registration firmware on it, the device chipid and the device remote_id. Such attributes are automatically added to the device entry in the known device list.


Devices with multiple modes can be registered one at a time only!


Device virtualization consists in flashing a Zerynth virtual machine on a registered device. One or more virtual machines for a device can be obtained with specific ZTC commands. Virtualization is started by:

ztc device virtualize alias vmuid

where alias is the device alias and vmuid is the unique identifier of the chosen vm. vmuid can be typed partially, ZTC will try to match it against known identifiers. vmuid is obtained during virtual machine creation.

The virtualization process is automated, no user interaction is required.

Serial Console

Each virtual machine provides a default serial port where the output of the program is printed. Such port can be opened in full duplex mode allowing bidirectional communication between the device and the terminal.

The command:

ztc device open alias

tries to open the default serial port with the correct parameters for the device. Output from the device is printed to stdout while stdin is redirected to the serial port. Adding the option --echo to the command echoes back the characters from stdin to stdout.

Supported Devices

Different versions of the ZTC may have a different set of supported devices. To find the device supported by the current installation type:

ztc device supported

and a table of target names and paths to device support packages will be printed. Supported devices can be filtered by type with the --type type option where type can be one of:

  • board for development boards
  • jtag for JTAG tools
  • usbtoserial for USB to Serial converters