Skip to content
Free public beta until December 4, 2026: every course is open, no card needed. After that, the first chapter of each course stays free and full access is a one-time $39 ($19 for up to 100 founding members chosen for helpful feedback). Your progress is kept. How the beta works

Software on your computer

~40 min

Half of every connected system runs on an ordinary computer: the program that receives the devices' messages, the code that stores and checks them, the page that shows them. In this course that computer is yours. This section installs the software once, so later chapters can say "start Mosquitto" or "run the tests" and mean something you can do in a minute. All of it is free and runs locally. Nothing here signs you up for an online service.

Five tools and what each is for

A toolchain is the set of programs that turn the code you write into something that runs. For the board, you already have one: the Arduino tools. This section sets up a second toolchain, on your own computer. Five programs, each with one job.

Mosquitto is a small message server. Your boards will send their readings to it, and other programs will pick them up from it. Chapter 9 explains it properly.

Python is the main language for everything that isn't on the board: little test programs, the service that saves readings, checks on the data. You'll add one extra piece to it, called paho-mqtt, which lets Python talk to Mosquitto.

Node.js runs JavaScript and TypeScript outside a browser. .NET runs C#. Rust is a language some later chapters use for the board itself. These three are only for comparisons and later chapters, so they can wait.

All five are free and run on your own machine. Docker, a tool that packages programs in sealed boxes, is never required.

After installing anything, ask it for its version number. That one line tells you it worked. It's also the first thing a helper will ask for.

The software on your computer that the labs need is this course's toolchain: the programs that run outside the board. A toolchain in general is the set of compilers, interpreters and command-line tools that turn source code into something that runs. Five pieces make up this course's, each with one job:

Tool Version used here Its job in this course
Mosquitto 2.x (the build checks against 2.1.2) A message server that devices send readings to and receive commands from; introduced fully in Chapter 9
Python 3.14, with paho-mqtt 2.1.0 The reference language for everything off the board: test clients, the main service that stores readings, data checks
Node.js a current LTS release (the build was checked with 22 in October 2026; check https://nodejs.org/ for the current LTS) TypeScript versions of the main service and the browser dashboard
.NET SDK 10 C# gateways and services, Chapter 16
Rust (rustup) stable, plus the riscv32imac-unknown-none-elf target Rust firmware for the ESP32-C6, Chapters 17–18

Only Mosquitto and Python are needed before Chapter 14. Install the others when a chapter first uses them, or now if you prefer.

LTS (long-term support) marks a release that gets fixes for years, not months. Docker is optional everywhere. Some projects include a Compose file as a convenience, but every lab runs without it, and the course's own build never needs it.

Each tool prints its version with one command. That command is the first thing to run after an install, and the first thing to paste when asking for help.

Installing them

Pick your operating system once; every block like this on every page follows your choice.

Mosquitto: download the 64-bit installer from https://mosquitto.org/download/. It installs to C:\Program Files\mosquitto.

Python 3.14: the installer from https://www.python.org/downloads/, or winget install Python.Python.3.14. Windows starts Python with the py launcher.

Node.js: the LTS installer from https://nodejs.org/.

.NET 10 SDK: winget install Microsoft.DotNet.SDK.10, or the installer from https://dotnet.microsoft.com/download.

Rust: run rustup-init.exe from https://rustup.rs/, then add the ESP32-C6 target.

Check each one in a new terminal:

& "C:\Program Files\mosquitto\mosquitto.exe" -h
py -3.14 --version
node --version
dotnet --version
rustup target add riscv32imac-unknown-none-elf
rustc --version

With Homebrew (https://brew.sh/):

brew install mosquitto python@3.14

Node.js: the LTS installer from https://nodejs.org/, or a version manager such as nvm.

.NET 10 SDK: the installer from https://dotnet.microsoft.com/download.

Rust: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh, then add the ESP32-C6 target.

Check each one:

$(brew --prefix)/sbin/mosquitto -h
python3.14 --version
node --version
dotnet --version
rustup target add riscv32imac-unknown-none-elf
rustc --version

On Debian or Ubuntu:

sudo apt install mosquitto mosquitto-clients

Python 3.14: if python3 --version shows an older release, install 3.14 with a tool such as uv (uv python install 3.14) or from https://www.python.org/downloads/.

Node.js: an LTS release from https://nodejs.org/, or a version manager such as nvm.

.NET 10 SDK: follow https://learn.microsoft.com/dotnet/core/install/linux for your distribution.

Rust: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh, then add the ESP32-C6 target.

Check each one:

mosquitto -h
python3.14 --version
node --version
dotnet --version
rustup target add riscv32imac-unknown-none-elf
rustc --version

mosquitto -h prints its version on the first line, such as mosquitto version 2.1.2, then its options. dotnet --version should start with 10..

Which tool does the job?

Sort each job under the tool this course uses for it. Decide before you drag, then check.

Loading interactive…

Correct! 🎉 Not quite.

Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.

What this task checks

Structure checked automatically. Whether your ideas are convincing isn't graded, so reread with the checklist.

The compiler says

A model answer

Correct answer

Also accepted:

Why

Why

Mosquitto passes messages; Python is the reference language for test clients and the main service; C# is for gateways; TypeScript (on Node) is for the browser dashboard comparison; Rust is for C6 firmware.

A virtual environment for each project

Python programs borrow ready-made pieces, called packages. paho-mqtt is one. If every project put its packages in one shared place, two projects needing different versions would fight.

A virtual environment solves that. It's a folder inside your project with its own private shelf of packages. While it is switched on, which is called activated, anything you install lands on that shelf only. Delete the folder and those packages are gone. Nothing else is touched.

The four commands above make that folder, switch it on, install paho-mqtt, and print its version.

Notice the ==2.1.0. That asks for exactly version 2.1.0. Version 2 of paho-mqtt changed how programs must use it, so code written for version 1 breaks on version 2. Asking for an exact version means your machine has the same release these pages were tested with. Then, if something fails, you know it's your code and not a version mismatch.

A virtual environment (venv) is a folder holding its own copy of the Python interpreter's package directory. Packages installed while it is active go into that folder only, so two projects can pin different versions of the same library without conflict, and deleting the folder removes them all.

python3.14 -m venv .venv          # Windows: py -3.14 -m venv .venv
source .venv/bin/activate         # Windows: .venv\Scripts\activate
python -m pip install "paho-mqtt==2.1.0"
python -c "import paho.mqtt; print(paho.mqtt.__version__)"

Each lab project in this course carries its own pyproject.toml that pins every dependency exactly, and its README repeats these steps.

Why pin ==2.1.0. paho-mqtt 2.0 changed how a client is created and how its callbacks are called; code written for 1.x fails on 2.x and the reverse. A pin means the code on the page and the library on your machine are the same release, so an error is yours to fix, not a version mismatch. Use python -m pip, not a bare pip: it installs into whichever Python python is, which inside an active venv is the venv's.

Worked example

pip installed it, but Python can't find it

  1. 1

    A learner activates a venv, types pip install paho-mqtt==2.1.0, then runs python client.py and gets ModuleNotFoundError: No module named 'paho'. What happened?

  2. 2

    Two Pythons. On this machine, the pip command on the path belongs to a different Python than the python inside the venv, a common result of several installs.

  3. 3

    Check which is which. python -m pip --version prints the folder pip will install into. If it isn't inside .venv, the venv isn't the one in use.

  4. 4

    Fix. Always install with python -m pip install .... That runs pip as part of the exact interpreter that will run the program.

Worked example

Port 1883 is already taken

  1. 1

    On Ubuntu, sudo apt install mosquitto succeeds, but mosquitto -v in a terminal stops with an error that the address is already in use. Why?

  2. 2

    The package started a service. The Debian package runs Mosquitto in the background as soon as it is installed, and that copy is listening on port 1883, Mosquitto's standard port.

  3. 3

    Only one program can listen on a port. The second copy can't start.

  4. 4

    Fix. sudo systemctl stop mosquitto, then run it in the terminal where you can watch its log. Chapter 9 §2 does exactly this.

Do I need Docker for this?

A project's folder contains a docker-compose.yml next to its README. The learner has Python 3.14 and Mosquitto installed but no Docker. Answer each question to land on what to do.

Loading interactive…

Correct! 🎉 Not quite.

Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.

What this task checks

Structure checked automatically. Whether your ideas are convincing isn't graded, so reread with the checklist.

The compiler says

A model answer

Correct answer

Also accepted:

Why

Check your understanding (counts toward your progress)

Which rustup command prepares Rust to build firmware for the ESP32-C6?

Correct! 🎉 Not quite.

Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.

That's the S3's Xtensa target, which stock rustup doesn't provide.

Boards aren't installed by name; Rust adds compilation targets.

The C6 uses stable Rust, not nightly.

Why

The C6 is a RISC-V chip with no operating system, so its target is riscv32imac-unknown-none-elf, available in stock stable Rust.

The C6's cores are RISC-V.

On Ubuntu, mosquitto -v fails right after sudo apt install mosquitto with "address already in use". What is the most likely cause?

Correct! 🎉 Not quite.

Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.

The install worked: that's why a copy is already running.

Your provider can't see a port on your own computer's loopback address.

Docker is never required.

Why

The Debian package starts a service immediately. Stop it with sudo systemctl stop mosquitto, then run your own copy where you can see its log.

Only one program can listen on a port at a time.

What is a Python virtual environment for?

Correct! 🎉 Not quite.

Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.

It changes where packages go, not how fast code runs.

It lives on your computer. Nothing here runs Python on a board.

It has nothing to do with network access.

Why

A venv is a folder with its own package directory, so each project's pinned versions don't collide with another's.

Think of two projects that need different versions of one package.

A learner runs pip install paho-mqtt==2.1.0, then python client.py, and gets ModuleNotFoundError: No module named 'paho'. Which command tells them the most about why?

Correct! 🎉 Not quite.

Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.

Installing again into the same wrong place changes nothing.

Mosquitto isn't involved in a Python import error.

Node is a different tool entirely.

Why

python -m pip --version prints the folder pip installs into. If it isn't the venv the program runs in, that's the mismatch.

The package went somewhere. Where?

Practice: Installing and checking the tools (5 problems · doesn’t affect your progress)

What is the first thing to run after installing any of the course's tools?

Correct! 🎉 Not quite.

Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.

A lab mixes several tools; check each one alone first.

A reboot is rarely needed and tells you nothing.

Docker is optional, and unrelated to checking an install.

Why

One version line proves the tool is installed and on the path, and it's what a helper will ask for.

Its version command, such as dotnet --version

Sort each job under the tool this course uses for it.

Correct! 🎉 Not quite.

Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.

What this task checks

Structure checked automatically. Whether your ideas are convincing isn't graded, so reread with the checklist.

The compiler says

A model answer

Why

C# runs on .NET, quick test clients are Python, TypeScript is checked with Node's tools, and C6 firmware outside Arduino is the Rust track.

Correct answer

Also accepted:

Why

“A fleet of simulated devices written in C#” → .NET SDK; “A test that publishes a fake reading” → Python; “Type-checking browser dashboard code” → Node.js; “Building ESP32-C6 firmware without the Arduino core” → Rust

Two projects need paho-mqtt 1.6 and 2.1.0. How can both work on one computer?

Correct! 🎉 Not quite.

Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.

A global install holds one version at a time.

It would work, but a venv is the simpler, standard answer, and Docker is never required.

Separate venvs solve exactly this.

Why

Each venv has its own package directory, so each project keeps its own pinned version.

Give each project its own virtual environment

mosquitto -h prints mosquitto version 2.1.2 and then a list of options. What has that shown?

Correct! 🎉 Not quite.

Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.

-h prints help and exits. It starts nothing.

Nothing about the network was tested.

It never opened a port, so it can't tell.

Why

The help text proves the program is installed and names its version. Running it is Chapter 9 §2's job.

Mosquitto is installed and which version it is

A learner on Windows activates .venv and runs python -m pip install "paho-mqtt==2.1.0". Later, in a new terminal, python client.py can't import paho. What did they forget?

Correct! 🎉 Not quite.

Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.

Mosquitto isn't involved in a Python import.

The pin was fine; the package is in the venv.

Activation is per terminal; a restart doesn't activate anything.

Why

Activation lasts for one terminal session. Each new terminal needs .venv\Scripts\activate again.

To activate the venv in the new terminal

Where this goes next

Mosquitto starts in Chapter 9 §2 and stays running through most of the course. Python with paho-mqtt drives the presence lab in Chapter 9 §6 and becomes the reference service in Chapter 14. Node.js and .NET appear side by side with Python in Chapter 14 §3, and .NET again for gateways in Chapter 16. The Rust target added above is what Chapters 17 and 18 compile for.

Feeling good about this section?

Take the section quiz

Every answer gets a full explanation at the end.

Sign in to save highlights

Insert an equation

  • No matches.