James Bachini

How To Connect An Arduino To A Soroban Smart Contract

Arduino Soroban

This tutorial will guide you through the process of connecting an Arduino to a Soroban smart contract on the Stellar blockchain. We’ll create a system where blockchain events can trigger physical actions through an Arduino.

James On YouTube

All the code for this project is open source at: https://github.com/jamesbachini/Arduino-Soroban-Controller

Connect your Arduino Nano to your computer via USB Note the COM port (Windows) or device path (Mac/Linux) for your Arduino Install the Arduino IDE and upload Firmata Plus:

  • Open Arduino IDE
  • Go to File > Examples > Firmata > StandardFirmataPlus
  • Upload to your Arduino
Arduino IDE

Smart Contract

Now let’s create the Soroban smart contract that will emit events:

#![no_std]
use soroban_sdk::{contract, contractimpl, Env, symbol_short};

#[contract]
pub struct ArduinoSoroban;

#[contractimpl]
impl ArduinoSoroban {
    pub fn launch(env: &Env) {
        env.events().publish(
            (symbol_short!("launch"),),
            1 // Can be used to reference different IO ports
        );
    }
}

mod test;

Let’s deploy this contract. You’ll need Rust installed, there’s more info here on how to setup an IDE for Soroban development.

rustup target add wasm32-unknown-unknown

cargo install --locked stellar-cli --features opt

cargo build --target wasm32-unknown-unknown --release

stellar contract deploy --wasm target/wasm32-unknown-unknown/release/arduino-soroban.wasm --source james --network testnet

stellar contract invoke --id --source-account james --network testnet -- launch

Controller

Create a new Node.js project and install the required dependencies for stellar-sdk and johnny-five. Then create a controller.js file and use this code, remember to replace the ContractID you just deployed on line 5.

const { Board, Led } = require("johnny-five");
const StellarSdk = require('stellar-sdk');

const rpc = new StellarSdk.SorobanRpc.Server('https://soroban-testnet.stellar.org');
const contractId = 'YOUR_CONTRACT_ID_HERE';
const eventsProcessed = [];
let firstRun = true;
let power = false;

// Initialize the board connection
const board = new Board({
    port: "COM3"  // Change this to match your Arduino port
});

board.on("ready", async () => {
    console.log('Board ready...');
    runLoop();
});

// Main loop function to check events and toggle LED based on conditions
const runLoop = async () => {
    while (!power) {
        await checkEvents();
        await new Promise(resolve => setTimeout(resolve, 3000));
    }

    // If power is true, turn LED on and off with delay
    const led = new Led(3);
    console.log('Turning On...');
    led.on();
    await new Promise(resolve => setTimeout(resolve, 5000));
    console.log('Turning Off...');
    led.off();
    power = false;

    // Restart loop after LED toggle
    runLoop();
};

// Function to check and fetch the latest events from the blockchain
const checkEvents = async () => {
    console.log('Checking Events...');
    const latestLedger = await rpc.getLatestLedger();

    const eventsResponse = await rpc.getEvents({
        startLedger: latestLedger.sequence - 8000,
        filters: [
            { type: "contract", contractIds: [contractId] },
            { type: "system", contractIds: [contractId] },
            { type: "diagnostic", contractIds: [contractId] },
        ],
    });

    processEvents(eventsResponse);
};

// Process each event and update power state based on specific conditions
const processEvents = async (eventsResponse) => {
    for (const event of eventsResponse.events) {
        if (!event.topic[0]) return;

        const topicString = event.topic[0]._value.toString();
        const alreadySeen = eventsProcessed.includes(event.id);

        eventsProcessed.push(event.id);

        if (!alreadySeen && topicString === 'launch' && !firstRun) {
            console.log('######### LAUNCH ##########');
            power = true;
        }

        firstRun = false;
    }
};

When the contract is invoked, the controller will:

  • Detect the launch event
  • Turn on the LED connected to pin 3
  • Keep it on for 5 seconds
  • Turn it off and resume listening for new events

This tutorial demonstrates the basic principles of connecting physical hardware to blockchain smart contracts. The possibilities for IoT and Web3 integration are vast, from automated systems to decentralized device networks.

Remember to adapt the code to your specific needs and always prioritize security when dealing with hardware automation.

All the code for this project is open source at: https://github.com/jamesbachini/Arduino-Soroban-Controller

This video is for informational purposes only. Fireworks are dangerous and should only be handled by professionals in controlled environments. Do not attempt to replicate any actions shown. Always follow local laws and safety guidelines when handling fireworks and associated electronics. Please note that I am compensated as a developer in residence to produce content around building on Soroban and the Stellar network. All Code is experimental, has not been security audited by 3rd parties and is provided for educational purposes only.


Get The Blockchain Sector Newsletter, binge the YouTube channel and connect with me on Twitter

The Blockchain Sector newsletter goes out a few times a month when there is breaking news or interesting developments to discuss. All the content I produce is free, if you’d like to help please share this content on social media.

Thank you.

James Bachini

Disclaimer: Not a financial advisor, not financial advice. The content I create is to document my journey and for educational and entertainment purposes only. It is not under any circumstances investment advice. I am not an investment or trading professional and am learning myself while still making plenty of mistakes along the way. Any code published is experimental and not production ready to be used for financial transactions. Do your own research and do not play with funds you do not want to lose.


Posted

in

, , , , , ,

by