Hi there! It was a long time since the last XOD visual programming language release but finally, the new 0.31.0 version is here. It brings a few vectors of improvement.

UPD is now ACT

Skilled xoders know the standard pattern when nodes actually communicate to hardware on an UPD pin pulse. The UPD pin is by default set to “Loop” so that a piece of hardware continuously reflects the data coming on other value pins.

It works fine until you get a module that updates sloooowly. Take an I²C LCD as an example: the full update takes up to 50 ms. Updating such display over an over again even when the text stays intact (most of the time) comes to be entirely pointless. Moreover, that means the program has no chance to react to other things faster than once per 50 ms. Put several slow nodes in a single program, and it quickly becomes unresponsive.

To address the problem, if a node represents an actuator which reflects input data 1-to-1 on its own state, it now exposes a boolean ACT pin instead of the old pulse UPD pin. As long as ACT is true the hardware follows input value changes and updates precisely at the moments when it is necessary.

Old UPD vs new ACT

The new pattern also honors partial updates. For example, if only the text for line #2 has changed, only it will be redrawn. Line #1 will stay intact, saving the precious milliseconds for other good things.

The new pattern is based on a new node, which is unsurprisingly called act . Its usage is straightforward and you can apply the same principle to own hardware nodes

`act ` usage example to convert the `ACT` boolean to `UPD` pulse on data change

xod/common-hardware cleanup

Do you have a simple LED? A button? Sure, yes. Do you have a LIS331DH accelerometer? Probably no. But such things co-existed in a single library xod/common-hardware which seamlessly became a pile of random hardware nodes.

We found some common groups of nodes and moved them to various dedicated libs under xod-dev :

HC-SR04 ultrasonic sensor nodes now live in xod-dev/hc-sr04

IMU and MEMS STMicroelectronic chip drivers live in xod-dev/st-mems

DHT11, DHT21, and other DHTs are now read with nodes under xod-dev/dht

The original xod/common-hardware became much leaner. We fixed it by adding a bunch of general-purpose hardware nodes :)

relay — drive a mechanical relay

— drive a mechanical relay pwm-load — drive a dimmable load or a PWM-compatible solid state relay, MOSFET transistor, or similar

— drive a dimmable load or a PWM-compatible solid state relay, MOSFET transistor, or similar binary-sensor — read a sensor which outputs a stable 0 or 1

— read a sensor which outputs a stable 0 or 1 mechanical-switch — read something like a reed switch or a float

JSON

JSON is arguably the most widespread format for communication with HTTP APIs. Previously the possibilities of parsing a JSON response to extract the necessary data were quite limited in XOD.

Our brave developers accepted the challenge and since now XOD offers a full-fledged xod/json library.

JSON parsing in XOD

The most interesting aspect of the library is that it is very memory-efficient. The whole JSON data never stored in RAM completely: the necessary portions are extracted on fly, as raw characters go in.

To get a quick idea of how to parse a JSON-formatted string, see the new guide article:

Throttle node

Making some real-world applications XOD devs come to a necessity of additional nodes in the standard library.

For example, the throttle node. Throttling is a mechanism often found in programming to limit the number of changes or requests. Now, a xoder can easily limit the frequency of sensor readings regardless of the incoming request rate by placing such node in-between.

Throttle node limits the rate of a capricious DHT sensor reading

Errors

After testing the new error mechanism introduced in 0.30.0 against more real-world cases, it became apparent that it contains some flaws. For example, the decision to remove all errors on pulse links at the end of a transaction was too premature.

Now, the behavior is more consistent. Pulses lose errors only when the nodes which raised them are re-evaluated. Also, we have fixed a few edge-cases and adjusted defer ’s behavior when dealing with errors.

Memory optimization

With yet one pass of generated code re-organization, moving, and data packing, we get another RAM consumption saving. It highly depends on the program being compiled but in some cases gives 2.5× improvement when compared to the previous version.