Go Down

Topic: JavaScript-Arduino serial port communication library with API and desktop GUI (Read 138 times) previous topic - next topic


Hello, this is my JavaScript-Arduino/ChipKIT serial port communication library with API and desktop GUI. I had some similar code migrating from one project to another, so at some point I have decided to put common parts into reusable library. It works both on ChipKIT and classical Arduino.

Desktop application demo (Node.js+Electron) works like this:

Serial monitor-based console version:

screenshot for desktop GUI:

screencast for console version:

Generally, this is question-answer library: external user (desktop) sends command via serial port (manually via serial monitor or programatically from JS desktop app), board (Arduino/ChipKIT) executes command and sends back reply.

Source code and examples

Arduino/ChipKIT core library and examples

JavaScript/Node.js part:
https://github.com/1i7/babbler-js - core library
https://github.com/1i7/babbler-js-material-ui - ReactJS Material-UI widgets library
https://github.com/1i7/babbler-js-demo - examples

Aurduino/ChipKIT library: Babbler_h

To install, make git clone https://github.com/1i7/babbler_h.git repository and move/link babbler_h, babbler_serial and babbler_json directories from repository to $HOME/Arduino/libraries, so you will have:


Then restart Arduino IDE and see examples in File/Examples/babbler_h/ menu


Flash _1_babbler_hello example

Code: [Select]
#include "babbler.h"
#include "babbler_simple.h"
#include "babbler_cmd_core.h"
#include "babbler_serial.h"

// Размеры буферов для чтения команд и записи ответов
// Read and write buffer size for communication modules

// Буферы для обмена данными с компьютером через последовательный порт.
// +1 байт в конце для завершающего нуля
// Data exchange buffers to communicate with computer via serial port.
// +1 extra byte at the end for terminating zero
char serial_read_buffer[SERIAL_READ_BUFFER_SIZE+1];
char serial_write_buffer[SERIAL_WRITE_BUFFER_SIZE];

/** Зарегистрированные команды */
/** Registered commands */
extern const babbler_cmd_t BABBLER_COMMANDS[] = {
    // команды из babbler_cmd_core.h
    // commands from babbler_cmd.core.h

/** Количество зарегистрированных команд */
/** Number of registered commands*/
extern const int BABBLER_COMMANDS_COUNT = sizeof(BABBLER_COMMANDS)/sizeof(babbler_cmd_t);

/** Руководства для зарегистрированных команд */
/** Manuals for registered commands */
extern const babbler_man_t BABBLER_MANUALS[] = {
    // команды из babbler_cmd_core.h
    // commands from babbler_cmd.core.h

/** Количество руководств для зарегистрированных команд */
/** Number of manuals for registered commands */
extern const int BABBLER_MANUALS_COUNT = sizeof(BABBLER_MANUALS)/sizeof(babbler_man_t);

void setup() {
    Serial.println("Starting babbler-powered device, type help for list of commands");
    //    serial_read_buffer, SERIAL_READ_BUFFER_SIZE,
    //    serial_write_buffer, SERIAL_WRITE_BUFFER_SIZE,
    //    9600);
        serial_read_buffer, SERIAL_READ_BUFFER_SIZE,
        serial_write_buffer, SERIAL_WRITE_BUFFER_SIZE,

void loop() {
    // постоянно следим за последовательным портом, ждем входные данные
    // monitor serial port for input data

Then open Serial Monitor and try to type some commands:

help --list
help ping
help help

you will get reply on each of them.

This will look like a kind of command-line terminal with 2 built-in commands: ping and help.

Other examples show, how to add new custom commands (this is what babbler_h API was done for):

Custom commands to blink leds:

Custom commands with params (pin_mode and digital_write transport):

Library is divided into 3 layers:
- transport layer: read input, detect packets, call input packet handler, write output
- cmd api layer: add functions with own code and easily register them as commands by name
- i/o protocol layer: take care of protocol details without impacting user code (receive input and send reply as plain text or wrap to some kind of JSON or XML)

They are mostly independent

For example, you can use babbler_serial (babbler_serial.h) module alone without cmd api layer (babbler.h) for raw input-reply:

Or add new communication transport modules in addition to babbler_serial (wifi and bluetooth are in mid-time plans).

JavaScript/Node.js library: babbler-js

Babbler-js library allows to communicate with Babbler-based Arduino/ChipKIT boards from Node.js environment. It would work only with JSON-based i/o protocol firmware with at least "ping" command available on board.

The device is considered connected when:
1. Serial communication port is opened
2. "ping" command (wrapped to JSON) is sent to device and device sends back reply with "ok" status (also wrapped to JSON).

To install/run

For JS desktop application first flash babbler_json_io example with JSON-based io-protocol to Arduino/ChipKIT (Arduino Mega would be required)

For JS part, install node, then git clone https://github.com/1i7/babbler-js-demo.git repo.

For basic API example go to babbler-basic dir, run:
npm install
node babbler-basic.js

Code: [Select]
var BabblerDevice = require('babbler-js');

var babblerDevice = new BabblerDevice();

babblerDevice.on('connected', function() {
    console.log("send cmd: ping");
    babblerDevice.sendCmd("ping", [],
        // onReply
        function(cmd, params, reply) {
            console.log("got reply on '" + cmd + " " + params + "': " + reply);
        // onError
        function(cmd, params, err) {
            console.log("fail with '" + cmd + " " + params + "': " + err);
    console.log("send cmd: help --list");
    babblerDevice.sendCmd("help", ["--list"],
        // onReply
        function(cmd, params, reply) {
            console.log("got reply on '" + cmd + " " + params + "': " + reply);
        // onError
        function(cmd, params, err) {
            console.log("fail with '" + cmd + " " + params + "': " + err);

babblerDevice.on('disconnected', function(error) {
    console.log("disconnected" + (error != undefined ? ": " + error : ""));

//babblerDevice.connect("/dev/ttyUSB0", {baudRate: 9600});

replace "/dev/ttyUSB0" with the correct device name. This code would connect to device and would send "ping" and "help --list" commands on success.

To run GUI desktop app (Electron+ReactJS+MaterialUI) like on video, go to babbler-serial-react dir and run:
npm install

Most custom code of this app is here:

Notes for JS and custom commands:
- Each command on device should be executed and return reply not later than in 5 seconds after being called, it would be considered failed on the JS side elsewhere.

More detailed tutorials (in Russian):
Console inside Arduino robot with babbler_h: https://habrahabr.ru/post/315084/
Babbler-js: Babbler_h+NodeJS: https://habrahabr.ru/post/315480/
Desktop GUI with ReactJS to control Arduino with Babbler_h: https://habrahabr.ru/post/316194/

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131