• MACHINE DRIVER: Getting Started


This blog uses a simplified example that utilizes the Machine Driver feature on neqto:, focusing on its technical aspects to help you get started.

With the Machine Driver feature on neqto:, users can deploy firmware updates to their neqto: integrated devices remotely.


To explain how Machine Driver works, this simple example uses an Nvidia Jetson Nano as a component device connected to a neqto: Bridge. The data is transferred using UART over USB. The setup is as follows:

  • The Nvidia Jetson Nano is connected to the neqto: Bridge via its I/O board USB port (the UART interface of the neqto: Bridge module is connected to the USB terminal of the neqto: Bridge I/O board via a USB serial conversion IC).
Note: Other common interfaces like (UART, RS232, RS485, SPI, and I2C) can also be used
  • A camera is connected to the Nvidia Jetson Nano which is configured to take pictures with a frequency defined as one picture per second in a 'firmware' file.
  • The objective is to increase the frequency of this operation to two pictures per second.


The user can upload the new firmware files on the cloud conveniently using the neqto: Console or the neqto: API along with a configured JavaScript script, fup.js.

When the user gives the Machine Driver command from the console, the main script (run.js) is halted and the fup.js script is downloaded from the cloud. Then, the fup.js script initiates the download of the new firmware, and writes it to the device (component).


The following scripts are required to execute Machine Driver on Nvidia Jetson Nano.

Files on the Bridge

firmware.py - The new firmware
  • This is the new firmware that the user wants to flash onto their device.
fup.js - The file that handles FOTA
  • This file does the following in sequential order:

  • reads the binary contents of the firmware file

  • converts the contents to string format

  • sends the converted data to the connected device via the communication protocol

  • returns the result to the cloud

// ----------------------------------------------------------------
// ----------------------------------------------------------------
var uart = new UART(2);
var BAUDRATE = 921600; //device baudrate.
uart.open(BAUDRATE, false, 0);

// Sending function - send converted data to the connected device via the UART communication protocol
var uart_sendData = function (data) {
  uart.send(data + '\n', false);
  // print(new Date().toString() + ': UART Sent | ' + data);

// FOTA Object - only one file per object
var fota = new nqFOTA('firmware.py');

// Conversion function - converts the contents to string format
bin2string = function(ab) {
  var ret_str = '';
  uint8_a = new Uint8Array(ab);
  for (var i = 0; i < uint8_a.length; i++) {
      ret_str += (String.fromCharCode(uint8_a[i]));
  return ret_str;

// Update function - reads and calls the conversion and sending functions
var updateReading = function (custom_func) {
  uart_sendData("--FOTA START--");
  var buff = fota.binRead(); // reads the contents of the firmware file
  while (buff != null) {
    buff = fota.binRead();
  uart_sendData("--FOTA END--");
  return 1;

// Main
var dl_data_len = fota.fileDownload(); // download the firmware file from the cloud
if (dl_data_len > 0) {
  var result = updateReading(send_string); // the result
  if (result != 1) { // send result to cloud
    fota.reportResult('UPDATE FAILED ', TARGET_VER);
  } else {  //success
    fota.reportResult('UPDATE SUCCESSFUL ', TARGET_VER);

// Termination

3. Files on Jetson Nano

firmware.py - The old firmware
  • This is the old firmware that needs to be upgraded.¥
program.py - A file dependent on the firmware settings
  • This is an example file that is dependent on the firmware settings.
import firmware
fota_daemon.py - A file that receives data from the neqto: Bridge on Machine Driver
  • On the component side, a daemon is required that can recognize that the neqto: Bridge is initiating FOTA (and the settings of the FOTA request), and then proceed to decode and write the contents received over UART to the specified location.

  • Additionally, the handler should be able to know when the FOTA request has ended. On completion, the main program is resumed.

import serial
ser = serial.Serial('/dev/ttyUSB0', 921600)
fota = False
data = ser.readline()[:-1].decode()
if data == "--FOTA START--":
  fota = True
  firmware = open("firmware.py", 'w+')
if data == "--FOTA END--":
  fota = False
if fota and data != "--FOTA START--":


This simple example shows the simplicity of Machine Driver to update the firmware remotely with the click of a button. With neqto:, debugging and repair during system failures can be monitored and resolved with minimal effort, saving precious time and money. Also, with advancement in technology, devices need firmware upgrades to keep up in terms of security, features, etc.; neqto: can enable the user to deliver these updates using Machine Driver. A number of sectors will benefit from this feature. For instance, in the automobile industry, modern cars are built around the idea of automatic/remote control and come with some important features like over-the-air (OTA) updates. This allows manufacturers to update the car firmware to deploy security updates and new software features remotely. However, for already-existing designs and entry-level automobiles these features can be difficult and expensive to develop and integrate. For such cases, with its ability to integrate on top of existing systems, neqto: easily enables OTA firmware updates using its Machine Driver feature. In future blogs we will talk in detail about more use cases and how neqto: raises the bar for IoT by closely integrating with these devices.