Create Publication

We are looking for publications that demonstrate building dApps or smart contracts!
See the full list of Gitcoin bounties that are eligible for rewards.

Solution Thumbnail



Smart sensor demo unit with Algorand data notarization: leveraging AlgoIoT library by GT50



In some scenarios, smart sensor data may require some sort of authentication; an excellent way to do this is to register the data in blockchain.

In order for data notarization to be trusted, blockchain cryptographic operations should be performed on the sensor node itself (“end node”); that is, the IoT device should host the wallet internally and directly submit the transaction to the blockchain.

This is easily accomplished if the sensor node is of Single-Board-Computer class (full-blown CPU, standard OS etc.); but many sensors are of microcontroller-level class (MCU), thus having access to far lower resources in terms of processing power, memory, firmware size, energy.

The team was composed of (in alphabetical order):
Marco Angelucci ([email protected])
Fernando Carello ([email protected])
Sandro Fontana ([email protected])
Enrico Speranza ([email protected])

Architectural requirements

Why we chose Algorand

The project builds on the concept of “blockchain notarization”: data written to a blockchain are secure, distributed, decentralized, inalterable, accessible.
Among the available blockchains.

Our IoT project is focused on the implementation of an inexpensive (a few hundred €) air quality sensor that can be installed in hundreds of units in the metropolitan area.

In order for this solution to be practicable, we needed a blockchain that was quick to net the data so that the multitude of stations could operate without significant delays. The cost per transaction had to be low because the number of transactions is potentially very high. And finally, the transaction had to be able to record enough data to contain the air quality information.

We selected Algorand because of its specific qualities.
The Algorand blockchain is fast: the average wait time for a transaction to complete is under 3.0s. This means we can work directly with Algorand Mainnet, without recurring to a sidechain.

Algorand is also feature-rich: for example, a payment transaction allows a Note field up to 1000 bytes long, which was crucial for us to store sensors data without having to design complex custom structures.

Last but not least, fees are low; so even registering each sensor reading session as a separate transaction (with the associated benefits) is still affordable.

These features make the Algorand blockchain particularly suitable for notarising IoT sensor data.

The availability of comprehensive documentation and the presence of SDKs for different languages helped us greatly in the realisation of our solution.

We had to write all the methods from scratch because we had to optimise the code as much as possible for use with ESP32.
The availability of SDKs for different languages made it easier for us to debug our implementation because it gave us the opportunity to verify our work with the official software.

Projected transactions volume

When analysing air pollution levels, data are commonly sampled at 30-minute intervals.

With this update interval, each Smart Sensor Node would perform 17520 transactions per year.

Taking Rome, IT as an example (which has an extension of about 1300 square kilometers), about 1000 smart sensors would provide an acceptable coverage for air quality monitoring.
This would mean 17.5+ million blockchain transactions per year (for Rome only).

It is possible to follow all transactions relating to the version currently in operation:


Smart sensors market is growing with double-digit yearly figures; the estimated Compound Annual Growth Rate is between 14% and 19% up to 2027, according to various sources.

“Smart sensors” is a broad term; we will focus on relatively small MCU-controlled, battery-operated units (possibly with energy harvesting capabilities) with wireless network access and the ability to connect to the cloud via a TCP/IP stack.

Our goal was to add blockchain-based (Algorand-based, specifically) sensors data “notarization” to existing smart sensors infrastructures.

EditorImages/2024/03/14 09:46/Aspose.Words.d1f0e903-1503-4144-96c3-cd770602e184.001.jpg

EditorImages/2024/03/14 09:46/Aspose.Words.d1f0e903-1503-4144-96c3-cd770602e184.002.jpg

Since we are targeting lightweight devices (microcontroller-class), it is of paramount importance to keep the inevitable overhead, in terms of wakeup time, computing resources, memory footprint, firmware size, to a minimum. At the same time, in order to obtain the required level of trust, we wanted the Algorand transaction to originate within the IoT End Node itself, without resorting to an intermediate service gateway.

This means the Microcontroller Unit has to manage the Algorand account (keys) itself; it also means the Ed25519 signature has to be processed on board and that the smart sensor node has to communicate with the Algorand “algod” service directly, via its REST API.

In 2023, GT50 published an open-source Arduino library for the ESP32 microcontroller, “AlgoIoT”, which allows writing data to the Algorand blockchain in a very simple, straightforward way.

Now, GT50 presents an actual smart sensor node based upon the AlgoIoT library, as a Proof of Concept.

The “AlgoIoT” library for the Arduino software ecosystem

In 2023, GT50 developed the AlgoIoT library to streamline and simplify the process of writing data in the Algorand blockchain:

Following the Arduino Library standard, “AlgoIoT” is targeted towards the ESP32 family of WiFi-enabled microcontrollers (via the Arduino-ESP32 core package); still, it is easy to be ported to other platforms.

It uses the “Note” field of a Algorand payment transaction to store data in JSON format, following the ARC-2 convention as recommended.

The library comes with appropriate documentation and integrates an example (“AlgoIoT_sendData”) which allows the user to “notarize” data quickly and easily.

Proof of concept: our Smart Sensor node for air quality monitoring

As both a case study and a practical demo for our AlgoIoT library, we designed a prototype Smart Sensor wireless end node which monitors the air quality near our office in Rome, IT.

Key points of the project were:

  • Self-powered via small solar panel (thus, low power draw was a must)
  • Compact size
  • Off-the-shelf components, as much as possible
  • Low cost: Bill of Materials < 300 EUR, casings not included
  • Open-Source development tools for board firmware



For our Proof of Concept, we selected the ubiquitous Expressif ESP32 microcontroller family.

It is the world’s most common WiFi-enabled MCU, first in worldwide market share since its introduction according to TSR reports[1]. While the exact number of units sold is not publicly available, the combined sales figures of ESP32 MCUs and the predecessor ESP8266 exceed 1 billion units since 2014[2].

Being the best seller in its class would be a compelling argument in itself; additionally, the ESP32 microcontroller boasts very good specifications.

In particular, we used the ESP32-PICO-D4 via UnexpectedMaker TinyPICO[ [3] development board:

EditorImages/2024/03/14 09:31/Aspose.Words.d1f0e903-1503-4144-96c3-cd770602e184.003.jpeg

  • Dual-core 32-bit RISC CPU at 240 MHz (Xtensa LX6)
  • 520 KB total RAM
  • 4 MB flash memory
  • 2.4 GHz WiFi 802.11 b/g/n

Despite having selected the ESP32 as our target device, our code should be easy to adapt to different MCU platforms, especially those compatible with the Arduino development environment; the RAM footprint is about 58 KB, including the Arduino-ESP32 overhead.


We decided to monitor Particulate Matter (PM) concentration, because of its primary role in city air pollution [13].

We selected Plantower PMSA003I [14] for the task, since it is readily available, sports an industry standard I2C interface, has a low power draw and monitors concentrations of PM 1.0, PM 2.5, PM 10 separately. The sensor is available as a convenient breakout board by Adafruit Industries.

EditorImages/2024/03/14 09:31/Aspose.Words.d1f0e903-1503-4144-96c3-cd770602e184.004.jpeg

For completeness, we also monitor air temperature, relative humidity and pressure; for this task, we selected the renowned Bosch BME280 sensor[[15]. Again, we have I2C interface and reduced power draw. Having the same interface of the Plantower PMSA003I allowed us to share a single bus for the two sensors, reducing complexity and size.

EditorImages/2024/03/14 09:33/Aspose.Words.d1f0e903-1503-4144-96c3-cd770602e184.005.jpeg

Hardware design considerations

Being a Proof of Concept, at this stage the sensor board is essentially hand-made, with a custom prototype board (2.54mm pitch) and socketed components for easy replacement.

Sensors are connected to JST-XH sockets via 180mm cables. Both sensors share the same I2C bus, being set at different addresses. Cable length is short enough not to cause issues with I2C.

We use a 12V 1.5W (peak) solar panel, connected to a MP1584EN regulator (as a breakout board socketed on the proto board).

The regulator outputs 5.2V to the PM sensor and the TinyPICO ESP32 board, which in turns directly manages a 3.7V 1700mAh LiPo battery, used as power backup for 24/7/365 operation. TinyPICO also provides the needed 3.3V regulated power for the Bosch BME280 sensor.

We preferred a 12V panel because “5V” panels voltage output actually varies in the 4.0V-6.2V range depending on the illumination, while the TinyPICO board needs a 4.8V-5.5V power source.

In order to save power, we need to put both sensors in a sleep mode of sort, since we follow a sleep/wakeup cycle for our board.

This is accomplished via software for the BME280 sensor, but the PM sensor requires its SET pin to be pulled low.

Problem is, the PM sensor integrates a pullup resistor which keeps the SET pin high when not actively pulled low. When the ESP32 microcontroller is in deep sleep mode, it cannot pull down a pin; so, the sensor would be active all the time, draining the backup battery since it draws up to 100mA.

To solve the issue, we added a pulldown resistor onboard. We needed to keep the SET pin at the logical low, which according to the sensor datasheet means < 0.8V.

We measured the integrated pullup resistor, which turned out to be a 96 Kohm part. Adding a 10 Kohm pulldown resistor, we managed to get the SET pin at the appropriate low level. When the ESP32 wakes up from deep sleep, it pulls the pin high, putting the sensor in active mode.

EditorImages/2024/03/14 09:43/Aspose.Words.d1f0e903-1503-4144-96c3-cd770602e184.006.jpg

Resulting schematics:

EditorImages/2024/03/14 09:37/Aspose.Words.d1f0e903-1503-4144-96c3-cd770602e184.007.jpg

To simplify board assembly, we designed a dual-layer custom PCB:

EditorImages/2024/03/29 11:12/Aspose.Words.9759e07a-ae8f-400d-97a8-c582904cbd32.008.jpeg

EditorImages/2024/03/29 11:13/Aspose.Words.9759e07a-ae8f-400d-97a8-c582904cbd32.009.jpeg

Power usage considerations

We need our sensor to operate 24/7/365 on solar power, with a rechargeable 3.7V LiPo battery providing power when sunlight is over.

The TinyPICO has onboard circuitry to manage the battery as an UPS: it recharges the battery when enough power is available to its VIN pin and drains from the battery when not, without interruptions.

We did not want a large solar panel, nor a large battery, because of cost and size constraints (see the key points for the project in the first chapters); so, we opted for a sleep/wakeup cycle, with the unit operating every 30 minutes (which is plenty for air quality monitoring).

When operating from the backup battery, the average power consumption in active mode (WiFi connected, sensors operating etc.) is about 880 mW.

The active cycle lasts 41 seconds on average.

The power consumption in sleep mode is about 8 mW; in a cycle, we have approx. 1759 seconds of sleep time.

Mode Seconds per hour Power draw (mW)
Active 82 880
Sleep 3518 8

This leads to the following estimation for energy consumption:

(3518 x 8 + 82 x 880) / 3600 ≈ 28 mWh

Using 80% of battery capacity as a safe figure and accounting for 70% efficiency by the TinyPICO power circuitry, we can count on

3.7 x 1700 x 0.8 x 0.7 = 3500 mWh

of backup energy, so we can tolerate about 5 days without useful solar irradiation.

It is interesting to note that sleep energy consumption accounts for roughly 28% of total consumption, with the aforementioned settings. A large part of this power draw is due to the PM sensor board having a power LED directly connected to the power source: it is not turned off even with the sensor in Standby mode.

Techniques to reduce sleep power draw are discussed in “Possible Future Enhancements”.


Software design considerations

As said, the software is based upon the “AlgoIoT_sendData.ino” example sketch which comes with GT50 AlgoIoT library.

Main additions are a timed sleep/wakeup cycle, actual sensor data collecting and a variable color status LED to help troubleshooting (LED is integrated in the TinyPICO board, so not visible externally).

Sleep/wakeup cycle

The timed sleep/wakeup cycle leverages ESP32 “deep sleep” power mode, which turns off basically everything but the RTC (Real Time Clock) peripheral. It is the lowest-consumption mode and, in theory (ESP32 main chip only), achieves a current draw as low as 10 microampere.

The ESP32 can be set to sleep for a given amount of time, with high precision. Time interval is set by esp_sleep_enable_timer_wakeup(microseconds) and deep sleep is entered with a call to esp_deep_sleep_start().

To achieve such low a power consumption, however, the internal RAM is not powered.

This means no variable value is retained, not even the instruction pointer: every time the ESP32 wakes up from deep sleep, it actually “resets” and starts from the beginning of the program (setup() method) without any existing variable value.

While it is possible to write data to the non-volatile flash memory before entering sleep and retrieving those data in setup(), there is the issue of flash memory cells wearing. With about 20’000 write cycles a year (based upon a 30 mins sleep/wakeup period), we would risk appreciably shortening the life of the ESP32 internal flash memory in a few years of projected activity.

So, we wrote the main sketch without saving any data between cycles.

Power saving

In order to save as much energy as possible without overcomplicating the project, we resorted to various techniques.

Since WiFi scanning/connecting is very power intensive, we limited the number of retries to 5: then, if the WiFi connection is not established, the node “gives up” and returns to sleep.

PM sensor: it has relatively high power draw at approx. 1W, because of the small fan and laser source. Since it requires approx. 30s of settling time for concentrations data to be reliable, we start the sensor early in the wakeup cycle, so it can stabilize while we attempt WiFi connection, which may take 10-15s.

Temperature/Humidity/Pressure sensor: we use it in Forced mode, which briefly wakes up the sensor, reads data (with multisampling to improve accuracy) and promptly returns to sleep.

Enable Switch: in some cases, we may have to momentarily take the node offline, for maintenance etc. Since we have a twin power source at different voltages (12V solar panel + 3.7V LiPo battery) with the battery directly connected to the ESP32 board, it was difficult to design a “main power switch” to turn off the IoT node for good, within the given project constraints. Instead, we opted for an external “Enable Switch”: a specific pin of the ESP32 MCU, which is normally pulled up, can be grounded by a 2-way switch.

First thing we do in setup() is checking if the pin is Low: in this case, we immediately enter sleep, without even enabling sensors or WiFi.

In order to write data to a blockchain, a wallet has to be stored on the device; WiFi credentials are needed as well.

Ideally, the MCU should offer some kind of safe storage space for keys, credentials etc. Unfortunately, this is not the case with the ESP32-PICO-D4 we worked with.

Thus, credentials had to be hard-coded in the firmware. Firmware is written in the flash memory, which can be read if one can physically access the TinyPICO board.

A tamper-proof enclosure may be designed for use cases where physical access has to avoided, but that would raise the costs significantly.

Alternative protection technique may be researched and are discussed in “Possible Future Enhancements”.

As for the software (firmware) itself, we adopted the usual secure programming techniques; debug code is not even compiled when not in debug mode (switched via #ifdef). The TinyPICO board does not expose a JTAG physical debug interface.

Status LED

Since the sensor unit misses a display, troubleshooting is usually done by plugging its USB cable and uploading a debug firmware.

That said, for a quick assessment of the board status we took advantage of the RGB LED integrated in the TinyPICO.

We assigned the following colors:

Onboard LED color Status
Red Critical error
Magenta Board just woke up, not connected to WiFi yet
Yellow Connected to WiFi; collecting and preparing sensor data
Green Transaction OK: data written to the blockchain

Since the enclosure is not transparent, the status LED is only visible when the board is exposed (discussed in “Possible Future Enhancements”).

Resources (SDKs etc.)

Software applications (firmware) for the ESP32 family of microcontrollers may be developed with the well-known Arduino IDE, thanks to the official open-source Arduino-ESP32 “core” (tools + hardware abstraction layer)[4].

This means we were able to leverage a large number of libraries available for the Arduino platform.

In particular:

  • WiFi[5] and HTTPClient [6] libraries to connect to Algorand services via the “Algonode” provider [7]
  • ArduinoJson library[8]
  • Arduino Cryptographic library[9] to sign transaction data with Ed25519 EdDSA
  • Base64 library[10] to decode Algorand network hash and for debug purposes
  • Adafruit PM25AQI library for the Plantower PM sensor
  • A library by Eduard Malokhvii [16], for the Bosch BME280 Temperature/Humidity/Pressure sensor

Given our goal to minimize memory footprint and to keep firmware size and overhead to a minimum, we wrote all Algorand-specific code in C++ from scratch, keeping everything as bare-bone as possible; therefore, we did not use existing Algorand SDKs.

The basis for Algorand-based “notarization” is the Algorand Payment Transaction; we exploit the “node” field to write sensors data. Further details may be gained from the AlgoIoT library source code and documents.


Firmware for the Smart Sensor PoC is based upon the “AlgoIoT_sendData” example sketch included in our “AlgoIoT” library, available here:

Basically, we added a sleep/wakeup cycle, support for the PMSA003I PM sensor, board status via a colored LED (TinyPICO-specific) and an “enable” switch which allows us to bypass normal operations (the board immediately enters sleep without doing any work).

It has the following structure, which conforms to the standard Arduino “setup + loop” sketch format:


Checks for Enable Switch position: if OFF, enters sleep immediately.

Initializations, in particular for WiFi and sensors.


Once the WiFi connection is established, we read sensors data via readSensors().

Then we build the “note” Algorand transaction field in ARC-2 format, calling various methods according to the data type; for example:

g_algoIoT.dataAddFloatField(T_LABEL, tempC);

After all data fields have been added to the structure, we simply submit the transaction:


Then we enter sleep mode, until next wakeup.

As shown, GT50 AlgoIoT library allows for a very simple way to write data to the Algorand blockchain: all the intricacies are carried on by the library.


For smart sensors data to be trusted, blockchain-based notarization, especially leveraging Algorand flexibility and speed, is particularly interesting.

For this solution to be effective, data have to be processed as soon as possible, ideally at the sensing stage, to avoid integrity pitfalls.

GT50 already published the “AlgoIoT” library for the Arduino development platform; now we present a case study with a fully working “smart sensor” wireless unit for air quality monitoring.

Possible future enhancements

By somewhat loosening costs and complexity constraints, various improvements may be implemented in possible future versions of the sensor unit.

Sensor coordinates

At the moment, sensor position (Latitude, Longitude, Altitude) is hardcoded; a GPS receiver could be added to the unit. The downside is energy consumption: a GPS receiver needs time (up to a few minutes, depending on sky visibility) to properly collect reliable position data and we have a short wakeup time. Moreover, GPS receivers are quite power hungry, especially if previous data cannot be stored (and the ESP32 looses RAM content in deep sleep mode). Still, some GPS receivers store previously read data within an embedded memory.

Tamper prevention/detection

If someone physically accesses the electronic board, data integrity may be compromised.

Tamper-proof enclosures exist in various grades, but they are expensive and design is complicated for a sensor unit which needs access to the environment and thus cannot be sealed.

On the other side, tamper detection may suffice depending on the application. In this case, various strategies could be implemented to detect board enclosure tampering; the information could then be written in the blockchain along with sensors data.

External error LED

At the moment, we use TinyPICO onboard RGB LED to help troubleshooting issues; but it is only visible when the board is exposed.

An external high visibility LED could be added to the enclosure, to signal critical errors.

External display

It may be interesting/useful if sensor data (and maybe error messages) are showed on a display on the unit itself, for visual inspection. By leveraging paper-like e-ink displays, impact on energy consumption would be negligible.

Further power saving

At the moment, we rely on ESP32 “deep sleep” mode and sensors standby modes to save power. Still, the unit draws as much as 8 mW in sleep mode; this accounts for 28% of energy consumption with current sleep/wakeup timings.

A Power Control Unit may be added to completely cut off power to the board or at least to sensors, which are responsible for more than half the power draw in sleep mode.

Webservice-based data collection

At the moment, the unit submits data to the Algorand blockchain only.

This means we need to query the blockchain to gather sensors data.

While this is mandatory to ensure data integrity, it complicates matters if data plotting, analysis etc. is required.

An external webservice may be added, with the ability to store timestamped sensors data and blockchain transaction IDs. This way we would have all the flexibility needed to analyze and show data, while retaining the ability to quickly verify data integrity via the Algorand blockchain.

Arduino platform library submission

At the moment, GT50 “AlgoIoT” library follows Arduino Library v1 format.

This is a simple package format which allows the downloaded library .zip package to be installed straight from the Arduino IDE.

It would be handy to have the library directly accessible/searchable/installable from the “Manage Library” menu entry of the Arduino IDE.

In order for this goal to be accomplished, the library file structure has to be compliant to the v1.5 Arduino Library specifications, proper metadata should be added, library dependencies have to be specified, hardware platform has to be indicated.

Then, the package must pass various checks before being submitted for publication.