Microcontroller Communication
Exploring MCU, MPU, SoC semantics, Nextion displays, Arduino Cloud, eWeLink and your own MQTT / Home Assistant server.
Open in the interactive Digital Garden
Remember the disclaimer? Should you decide to act upon any information on this website, you do so at your own risk. Some parts below (the Sonoff Basic in Example 4 in particular) switch mains voltage, which can cause serious injury or death. Most countries restrict such work to qualified persons, so check the regulations in your country and consult a professional.
CPU (Central Processing Unit), MPU (Microprocessor Unit), MCU (Microcontroller Unit), and SoC (System on Chip) semantics differentiate integrated circuits based on their design or components. The boundaries are blurry, and in practice the terms overlap:
| Term | What it is | Typical example |
|---|---|---|
| CPU | The processing core itself, the part that executes instructions | The core inside every chip below |
| MPU | A processor that needs external RAM, storage and peripherals, usually runs a full operating system such as Linux | Raspberry Pi (Linux board) |
| MCU | CPU, RAM, flash and peripherals (GPIO, ADC, UART) in one chip, runs a single program without an operating system | Raspberry Pi Pico (RP2040), ATmega328 in the Arduino Uno |
| SoC | Everything on one chip, often including radio; the term is used for MCUs with Wi-Fi as well as for complete application processors | ESP8285 (ESP8266 with 1 MB flash inside) |
For a few euros you can buy what Itead calls a Wi-Fi Switch module. It features an ESP8285 chip, which is an ESP8266 with the flash memory built into the package. According to Espressif Systems, with their development boards, you are able to develop your own IoT applications. These parts are so small that you need special tools to integrate them into a custom-designed system.
Raspberry Pi Pico, Arduino Nano 33 IoT, and many other variations make it easy to read sensors, drive displays and talk to the network from a few lines of code. The Nano 33 IoT combines a 3.3 V SAMD21 microcontroller with a separate Wi-Fi/Bluetooth module. Its pins are not 5 V tolerant, which matters as soon as you connect parts that were designed for the 5 V Arduino Uno. Communication with the Nextion Touch Display from Itead, who offers the Nextion Editor designed specifically for graphical user interfaces, takes the drawing of screens off the microcontroller: the display has its own processor, and the microcontroller only exchanges short messages with it over a serial line, instead of pushing binary pixel data. You place components visually and control them with ASCII text-based instructions, which is somewhat reminiscent of Microsoft Visual Basic.
You can pair a Nextion display with an Arduino Nano 33 IoT to display and manage various elements on the screen, a computer, or another smart device with network capabilities. The Arduino Cloud enables you to manage these elements over the internet without running your own server. That server does not disappear, however: it runs at Arduino, and the free plan is limited (at the time of writing two "Things", and the phone app counts as one of them, see the plans page for current limits). Thanks to the active Arduino community, numerous resources are available online.
Why would you need a server of your own? Temperature sensors and similar devices are often part of a larger collection. In terms of resource management, storing and processing data on each individual device separately makes little sense. A server collects the readings in one place, keeps the history, draws graphs, sends alerts and lets one device react to another. Whether that server belongs to someone else or to you decides who owns the data, whether the system keeps working without Internet access, and what happens when a vendor changes its plans:
| eWeLink (Example 3) | Arduino Cloud (Example 4) | Own server (Example 5) | |
|---|---|---|---|
| Who runs the server | Itead | Arduino | You (Raspberry Pi, mini PC, VM) |
| Works without Internet | Partly (LAN mode) | No | Yes |
| Limits | Supported devices only | Free plan: few Things and variables | Your hardware |
| Effort | Lowest | Low | Highest (updates, backups, security are yours) |
The own-server route (Mosquitto and Home Assistant) is described in more detail in the Network Door Opener note, Examples 4 and 5; here it is applied to a sensor.
| Development & Design Resources |
|---|
| Designing a Microcontroller Development Board |
| KiCad EDA |
Examples & Guides
Overview
| # | Hardware | Link | Server | User interface |
|---|---|---|---|---|
| 1 | Nano 33 IoT (or Uno) + LM60 + Nextion | UART | none | Nextion touch display |
| 2 | Arduino + temperature sensor | USB serial | none | Serial Monitor / Plotter |
| 3 | Sonoff switch | Wi-Fi | eWeLink cloud | eWeLink app |
| 4 | Nano 33 IoT + Sonoff Basic | Wi-Fi | Arduino Cloud | Dashboard + IoT Remote app |
| 5 | ESP8266 board + DS18B20 | Wi-Fi, MQTT | Own (Mosquitto + Home Assistant) | Home Assistant dashboard |
Example 1 – Temperature on a Nextion display
- Nextion Display, Arduino, and a Temperature Sensor (the original tutorial, written for a 5 V Arduino)
- Arduino Nano 33 IoT (3.3 V) or an Arduino Uno (5 V)
- LM60 temperature sensor (analog output)
- Nextion display, powered from 5 V
How it works:
- Wiring: display 5 V and GND to a supply that can deliver the display's current (see its datasheet, do not draw it from a weak pin), display TX to the microcontroller RX, display RX to the microcontroller TX, and all grounds together. Check in the datasheet of your Nextion model that its TX level is acceptable for a 3.3 V board.
- The LM60 outputs 424 mV at 0 °C plus 6.25 mV per °C, so the temperature is (V − 0.424) / 0.00625. Supply it with 3.3 V (it needs at least 2.7 V) and put a 100 nF capacitor close to the sensor.
- In the Nextion Editor add a text box named
t0on page 0. Its default speed is 9600 baud. - Every Nextion command is ASCII text followed by three bytes of 0xFF, for example
t0.txt="21.5 C". This is whatnextionSend()below does.
// Arduino Nano 33 IoT: LM60 on A0, Nextion on Serial1 (D0 = RX, D1 = TX), 9600 baud
const int SENSOR_PIN = A0;
void nextionSend(const String &cmd) {
Serial1.print(cmd);
Serial1.write(0xFF); // every Nextion command ends with three 0xFF bytes
Serial1.write(0xFF);
Serial1.write(0xFF);
}
float readTemperatureC() {
long sum = 0;
for (int i = 0; i < 16; i++) { // average to reduce ADC noise
sum += analogRead(SENSOR_PIN);
delay(2);
}
float volts = (sum / 16.0f) * 3.3f / 4095.0f; // 12-bit ADC, 3.3 V reference
return (volts - 0.424f) / 0.00625f; // LM60: 424 mV at 0 C, 6.25 mV per C
}
void setup() {
Serial1.begin(9600);
analogReadResolution(12);
delay(500); // give the display time to start
nextionSend("page 0");
}
void loop() {
float t = readTemperatureC();
nextionSend("t0.txt=\"" + String(t, 1) + " C\""); // text box t0 on page 0
delay(1000);
}
On an Uno use SoftwareSerial instead of Serial1 as in the tutorial, a 5.0 V reference and 1023 steps instead of 3.3 V and 4095.
The averaging of 16 readings matters: a single reading of the analog pin jumps by a few tenths of a degree.
The sensor tolerance (about ±2 °C according to the datasheet) is larger than the noise, so compare it with a reference thermometer before you trust it.
Example 2 – Temperature sensor without a display
The simplest setup: sensor on an analog pin, readings over USB to the Serial Monitor. This is the best way to test a sensor before you add a display or a network. Open Tools → Serial Plotter in the Arduino IDE to see a graph; it expects one number per line. The conversion depends on the sensor: an LM60 as in Example 1 has an offset of 424 mV, a sensor of the LM35 type gives 10 mV per °C without offset, so check the formula for the part you actually have.
const int SENSOR_PIN = A0;
void setup() {
Serial.begin(115200);
analogReadResolution(12); // Nano 33 IoT; on an Uno use 1023 and 5.0 V below
}
void loop() {
long sum = 0;
for (int i = 0; i < 16; i++) {
sum += analogRead(SENSOR_PIN);
delay(2);
}
float volts = (sum / 16.0f) * 3.3f / 4095.0f;
float tempC = (volts - 0.424f) / 0.00625f; // LM60; an LM35 would be volts * 100.0f
Serial.println(tempC, 1); // one number per line: works with Serial Plotter
delay(1000);
}
Example 3 – Sonoff switch with eWeLink
The module itself is the whole system: an ESP8285 that connects to your Wi-Fi, a relay, and firmware that talks to the eWeLink cloud. You need no programming and no server of your own.
- Power the RE5V1C with 5 V DC (it is a low-voltage module, specified for 0–40 °C) and connect only the load you want to switch to its dry-contact output.
- Your phone must be on a 2.4 GHz Wi-Fi network; the ESP8285 does not support 5 GHz. Put the module into pairing mode as described in the pairing guide and add it in the eWeLink app.
- Set the mode (toggle, inching with automatic switch-off, or self-locking) and optionally timers and scenes.
- Test it once with the Internet connection of your router unplugged. The module also supports LAN control without Internet access; if you want to control it only locally, the Sonoff DIY mode (offered by models sold as "DIY switch") and ESPHome (Example 5) are the alternatives.
Consequences of this convenience: the account and the data live at the vendor, the app only works as long as the service exists, and anyone who gets into your account can switch the relay. Use a long, unique password.
Example 4 – Arduino Nano 33 IoT, Arduino Cloud and a Sonoff Basic
- Arduino Nano 33 IoT, Arduino Cloud, and Sonoff Basic Switch
- Arduino Nano 33 IoT with the LM60 from Example 1
- Sonoff Basic (an ESP8266 switch for mains voltage), see the project above for flashing
- An Arduino account (the free plan allows two Things)
The idea: the Nano reads the temperature and publishes it as a Cloud variable, the Cloud shows it in a dashboard on the web and in the IoT Remote app, and a switch on the dashboard controls the Sonoff Basic, which is registered as a second Thing.
Create a Thing for the Nano, add the variable temperature (type Temperature Sensor, read only), connect the device, and let the Cloud generate thingProperties.h. The sketch is then short:
// Sketch tab of the Arduino Cloud Thing. thingProperties.h is generated by the Cloud
// and contains: CloudTemperatureSensor temperature; (variable "temperature", read only)
#include "thingProperties.h"
const int SENSOR_PIN = A0;
float readTemperatureC() { // same function as in Example 1
long sum = 0;
for (int i = 0; i < 16; i++) {
sum += analogRead(SENSOR_PIN);
delay(2);
}
float volts = (sum / 16.0f) * 3.3f / 4095.0f;
return (volts - 0.424f) / 0.00625f;
}
void setup() {
Serial.begin(9600);
delay(1500);
analogReadResolution(12);
initProperties();
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
setDebugMessageLevel(2);
ArduinoCloud.printDebugInfo();
}
void loop() {
ArduinoCloud.update(); // keeps the connection alive, must run often
static unsigned long last = 0;
if (millis() - last >= 10000) { // one reading every 10 s
last = millis();
temperature = readTemperatureC();
}
}
Warning: the Sonoff Basic has no galvanic isolation between its circuit board and the mains. Never connect a serial adapter to it while it is connected to mains. Flash it on the bench, powered only by the 3.3 V of the adapter, and install it in a closed housing only when it is finished and by someone qualified. With two Things, the free plan is already used up; the IoT Remote app on a phone counts as a third one, so check the plan page before you rely on this.
Example 5 – Your own server: ESPHome, MQTT and Home Assistant
- Server: Raspberry Pi, mini PC or virtual machine running Home Assistant with the Mosquitto broker (Home Assistant has it as an add-on)
- ESP8266 board, for example a D1 mini (or the ESP32 of your choice)
- DS18B20 temperature sensor (digital, 1-Wire) and a 4.7 kΩ resistor
- ESPHome for the firmware
Here the roles from Example 4 are taken over by software that you control. A digital sensor replaces the analog LM60: it needs no ADC, is not disturbed by supply noise, and its reading is the same on a 3.3 V or a 5 V board. The device publishes its readings by MQTT, the broker passes them on, and Home Assistant stores them, draws the graphs and can send a message to your phone when a limit is crossed.
1. Broker (inside the home network, so plain port 1883 with a password is acceptable; never forward this port to the Internet):
# /etc/mosquitto/conf.d/lan.conf (broker reachable only inside the home network)
listener 1883
allow_anonymous false
password_file /etc/mosquitto/passwd
# sudo mosquitto_passwd -c /etc/mosquitto/passwd sensor_user
# sudo systemctl restart mosquitto
# test: mosquitto_sub -h 192.168.1.10 -u sensor_user -P PASSWORD -t 'sensors/#' -v
2. Sensor firmware (ESPHome MQTT component). Check the sensor syntax for your ESPHome version, because the 1-Wire configuration has changed between releases:
# temp-sensor.yaml (ESPHome, ESP8266 board such as a D1 mini, DS18B20 on D2 = GPIO4)
esphome:
name: temp-livingroom
esp8266:
board: d1_mini
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ota:
- platform: esphome
password: !secret ota_password
mqtt:
broker: 192.168.1.10
username: !secret mqtt_user
password: !secret mqtt_pass
topic_prefix: sensors/livingroom
discovery: true # Home Assistant finds the sensor by itself
# 1-Wire bus; a 4.7 kOhm resistor between data and 3.3 V is required
one_wire:
- platform: gpio
pin: GPIO4
sensor:
- platform: dallas_temp # older ESPHome versions: "dallas:" hub + "platform: dallas"
name: "Temperature"
update_interval: 30s
3. Home Assistant: add the MQTT integration with the address and the account of the broker. The sensor appears by itself because of discovery: true. Put it on a dashboard and enable the history graph.
If the device is only used with Home Assistant, you can use the ESPHome native API instead of MQTT: remove the mqtt: block and add api: with an encryption key. MQTT is the better choice when other programs than Home Assistant should receive the data, or when you want to follow the same pattern as in the Network Door Opener note, including TLS and per-device accounts.
For all examples
- Check the logic level before you connect anything: the Nano 33 IoT, ESP8266 and ESP32 are 3.3 V devices; 5 V on a pin can destroy them.
- Ground of all parts must be common, and a sensor wire longer than a metre needs shielding or a digital sensor.
- Use unique, long passwords for every cloud account, broker user and Wi-Fi network; one account per device lets you revoke a single device.
- Keep the firmware and the server updated, and keep a backup of the server configuration.
- Do not expose a broker or Home Assistant to the Internet without TLS and authentication. A VPN is the simplest way to reach them from outside.
- Mains voltage belongs to qualified persons; use modules with low-voltage inputs wherever possible.
Some resources: