Introduction
The Internet of Things (IoT) is everywhere—from smart home thermostats to industrial sensors. Yet, getting started with embedded development can be overwhelming: choosing between Arduino, ESP32, or Raspberry Pi, understanding protocols like MQTT, and writing low-level code. What if you could accelerate your workflow with a set of carefully crafted prompts? A prompt, in this context, is a precise instruction or task description you can give to an AI assistant or use as a template to generate code, debug issues, or learn a new concept.
This article curates 10 practical prompts, organized by experience level: Basic, Advanced, and Expert. Each prompt is complete with a clear task, the exact prompt text to copy, and a concrete example result (code + explanation). I’ve also included links to official documentation so you can verify every detail. Whether you’re a hobbyist or a seasoned embedded engineer, these prompts will save you hours of searching and trial-and-error.
Basic Prompts
These prompts assume you are new to embedded and IoT. They focus on reading sensors, controlling LEDs, and understanding fundamental GPIO operations.
Prompt 1: Read a TMP36 Temperature Sensor on Arduino
Task: Write Arduino code to read an analog temperature sensor (TMP36) and print the value in both Celsius and Fahrenheit.
Prompt:
"Write an Arduino sketch that reads the analog voltage from a TMP36 temperature sensor connected to pin A0. Convert the voltage to temperature in Celsius and Fahrenheit, and print both values to the Serial Monitor every 1 second. Also add a comment explaining the conversion formula."
Example Result:
// TMP36 Temperature Sensor Reader
// VCC to 5V, GND to GND, Vout to A0
const int sensorPin = A0;
void setup() {
Serial.begin(9600);
}
void loop() {
int sensorValue = analogRead(sensorPin);
float voltage = sensorValue * (5.0 / 1023.0); // 5V reference, 10-bit ADC
float temperatureC = (voltage - 0.5) * 100.0; // TMP36: 10mV per °C, offset 0.5V
float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;
Serial.print("Temperature: ");
Serial.print(temperatureC);
Serial.print(" °C, ");
Serial.print(temperatureF);
Serial.println(" °F");
delay(1000);
}
The TMP36 datasheet from Analog Devices specifies an output scale factor of 10 mV/°C and a 500 mV offset at 0°C—that’s where the conversion formula comes from. This example also demonstrates how to read an analog sensor using the Arduino ADCs.
Prompt 2: Blink an LED on ESP32 Using the Arduino Framework
Task: Get an ESP32 to blink an LED on GPIO 2 with a 1-second period.
Prompt:
"Create an ESP32 Arduino code that blinks an LED connected to GPIO 2 every 500 milliseconds (ON for 500ms, OFF for 500ms). Use the built-in LED if available. Explain the pin mode and the role of delay()."
Example Result:
// ESP32 Blink Example
const int ledPin = 2; // On many ESP32 dev boards, GPIO2 has an onboard LED
void setup() {
pinMode(ledPin, OUTPUT); // Set the pin as output
}
void loop() {
digitalWrite(ledPin, HIGH); // Turn the LED on
delay(500); // Wait for 500ms
digitalWrite(ledPin, LOW); // Turn the LED off
delay(500);
}
This is the classic "Hello World" of embedded. The ESP32 is a dual-core microcontroller with integrated Wi-Fi/Bluetooth, and the Arduino framework makes it easy to write cross-platform code. You can verify the GPIO mapping in the ESP32 DevKitC Pinout.
Prompt 3: Read a Button on Raspberry Pi with gpiozero
Task: Write a Python script for a Raspberry Pi to detect a button press and print a message.
Prompt:
"Write a Python script using the gpiozero library to read a button connected to GPIO 17 and GND. When the button is pressed, print 'Button pressed' to the console. Use a PullUp resistor and debouncing. Show both the 'wait_for_press' method and an event-driven version."
Example Result:
from gpiozero import Button
from signal import pause
# Button on GPIO 17 with pull-up resistor (external or internal)
button = Button(17, pull_up=True)
# Event-driven approach
button.when_pressed = lambda: print("Button pressed")
# Alternative blocking approach
# while True:
# button.wait_for_press()
# print("Button pressed")
pause() # Keep the script running
The gpiozero library is the official Python library recommended by the Raspberry Pi Foundation. It abstracts GPIO complexities and provides built-in debouncing (the bouncetime parameter can be set explicitly if needed).
Advanced Prompts
Now we move to connecting devices to the internet, using MQTT, and building simple services.
Prompt 4: Publish Sensor Data to an MQTT Broker with ESP32
Task: Connect an ESP32 to a public MQTT broker and publish temperature/humidity readings every 10 seconds.
Prompt:
"Write ESP32 (Arduino) code to connect to the public MQTT broker at broker.hivemq.com, port 1883, using the PubSubClient library. Read a DHT22 sensor on GPIO 4, publish the temperature to 'sensor/temperature' and humidity to 'sensor/humidity' every 10 seconds. Include Wi-Fi credentials as constants."
Example Result:
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
const char* ssid = "YOUR_WIFI";
const char* password = "YOUR_PASSWORD";
const char* mqttServer = "broker.hivemq.com";
const int mqttPort = 1883;
WiFiClient espClient;
PubSubClient client(espClient);
DHT dht(4, DHT22);
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
client.setServer(mqttServer, mqttPort);
dht.begin();
}
void loop() {
if (!client.connected()) {
while (!client.connected()) {
if (client.connect("ESP32Client")) {
Serial.println("Connected to MQTT");
} else {
delay(2000);
}
}
}
client.loop();
float h = dht.readHumidity();
float t = dht.readTemperature();
if (!isnan(h) && !isnan(t)) {
char tempStr[8];
char humStr[8];
dtostrf(t, 6, 2, tempStr);
dtostrf(h, 6, 2, humStr);
client.publish("sensor/temperature", tempStr);
client.publish("sensor/humidity", humStr);
}
delay(10000);
}
The MQTT protocol is a lightweight pub/sub model widely used in IoT. The HiveMQ public broker allows testing without local setup. PubSubClient is documented in its GitHub repository.
Prompt 5: MQTT Subscriber with Raspberry Pi Logging to CSV
Task: Create a Python script for Raspberry Pi to subscribe to an MQTT topic and append incoming data to a CSV file.
Prompt:
"Write a Python script for Raspberry Pi using paho-mqtt. Subscribe to the topic 'sensor/temperatureQoS=1. On every message, append a timestamp and the payload to 'sensor_log.csv' with a header if the file is new. Use the broker broker.hivemq.com."
Example Result:
import paho.mqtt.client as mqtt
import csv
import time
from datetime import datetime
BROKER = "broker.hivemq.com"
TOPIC = "sensor/temperature"
CSV_FILE = "sensor_log.csv"
def on_connect(client, userdata, flags, rc):
print("Connected with result code " + str(rc))
client.subscribe(TOPIC, qos=1)
def on_message(client, userdata, msg):
# Create file and header if needed
try:
with open(CSV_FILE, 'r') as f:
pass
except FileNotFoundError:
with open(CSV_FILE, 'w') as f:
f.write("timestamp,value\n")
timestamp = datetime.now().isoformat()
value = msg.payload.decode()
with open(CSV_FILE, 'a') as f:
writer = csv.writer(f)
writer.writerow([timestamp, value])
print(f"{timestamp}: {value}")
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect(BROKER, 1883, 60)
client.loop_forever()
This is a typical edge-sensor logger. You can extend it to multiple topics. The paho-mqtt library is the de facto Python MQTT client documented in Eclipse Paho.
Prompt 6: Build a REST API to Control Raspberry Pi GPIO
Task: Create a simple Flask API to turn an LED on and off via HTTP requests.
Prompt:
"Write a Flask application for Raspberry Pi with two endpoints: POST /led/on and POST /led/off. Use gpiozero to control an LED on GPIO 18. Add a simple JSON response, e.g., {'status': 'on'}. Include CORS headers and run on port 5000."
Example Result:
from flask import Flask, jsonify
from gpiozero import LED
from flask_cors import CORS
app = Flask(__name__)
CORS(app) # Enable CORS for external requests
led = LED(18) # GPIO18 is a common free pin
@app.route('/led/on', methods=['POST'])
def led_on():
led.on()
return jsonify({'status': 'on'})
@app.route('/led/off', methods=['POST'])
def led_off():
led.off()
return jsonify({'status': 'off'})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
This turns your Raspberry Pi into a web-controllable device—the foundation for many home automation projects. Flask is documented in the official Flask docs.
Expert Prompts
These prompts tackle advanced topics: RTOS, low-power design, OTA updates, and machine learning at the edge.
Prompt 7: Over-the-Air (OTA) Updates for ESP32
Task: Implement a secure OTA update mechanism for an ESP32.
Prompt:
"Explain and provide code for ESP32 OTA updates using the Arduino framework. How to use the ArduinoOTA library, how to set a password, and what partition scheme is required? Also show how to roll back if a new firmware fails."
Example Result:
#include <WiFi.h>
#include <ArduinoOTA.h>
const char* ssid = "YOUR_WIFI";
const char* password = "YOUR_PASSWORD";
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("Connection Failed! Rebooting...");
delay(5000);
ESP.restart();
}
ArduinoOTA.setHostname("esp32-ota");
ArduinoOTA.setPassword("admin"); // Set your password
ArduinoOTA.onStart([]() {
String type = (ArduinoOTA.getCommand() == U_FLASH) ? "sketch" : "filesystem";
Serial.println("Start updating " + type);
});
ArduinoOTA.onEnd([]() { Serial.println("\nEnd"); });
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
else if (error == OTA_END_ERROR) Serial.println("End Failed");
});
ArduinoOTA.begin();
}
void loop() {
ArduinoOTA.handle();
}
OTA is a modern necessity for deployed devices. The ArduinoOTA library is part of the ESP32 Arduino package. To use OTA, your board must have a partition scheme with at least two OTA partitions (e.g., "Huge APP (3MB NO OTA)" should be avoided; use "Default 4MB with spiffs" or similar). The Espressif OTA docs offer more details.
Prompt 8: FreeRTOS Multitasking on ESP32
Task: Write a FreeRTOS program that runs two tasks concurrently, sharing a resource safely.
Prompt:
"Write an ESP32 Arduino sketch that uses FreeRTOS to run two tasks: Task 1 reads a DHT22 sensor every 2 seconds and stores the temperature in a global variable; Task 2 reads the global and prints it to Serial every 5 seconds. Use a mutex to protect the shared variable. Also show how to create tasks with different priorities."
Example Result:
#include <Arduino.h>
#include <DHT.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/semphr.h>
DHT dht(4, DHT22);
SemaphoreHandle_t xMutex;
float sharedTemp = 0;
void Task1(void *pvParameters) {
while (1) {
float t = dht.readTemperature();
if (!isnan(t)) {
xSemaphoreTake(xMutex, portMAX_DELAY);
sharedTemp = t;
xSemaphoreGive(xMutex);
}
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
}
void Task2(void *pvParameters) {
while (1) {
xSemaphoreTake(xMutex, portMAX_DELAY);
float localTemp = sharedTemp;
xSemaphoreGive(xMutex);
if (localTemp != 0) {
Serial.printf("Temperature: %.2f\n", localTemp);
}
vTaskDelay(5000 / portTICK_PERIOD_MS);
}
}
void setup() {
Serial.begin(115200);
dht.begin();
xMutex = xSemaphoreCreateMutex();
if (xMutex == NULL) {
Serial.println("Mutex creation failed");
return;
}
xTaskCreatePinnedToCore(Task1, "Task1", 4096, NULL, 1, NULL, 1);
xTaskCreatePinnedToCore(Task2, "Task2", 4096, NULL, 1, NULL, 1);
}
void loop() {
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
FreeRTOS is the default RTOS kernel for the ESP32. The official FreeRTOS documentation explains task scheduling, mutexes, and memory management. This pattern is essential for complex IoT applications.
Prompt 9: Low-Power IoT Node with ESP32 Deep Sleep
Task: Create an ultra-low-power sensor node that wakes periodically, reads data, publishes via MQTT, then sleeps.
Prompt:
"Write ESP32 Arduino code that puts the device into deep sleep for 30 minutes. On wake, connect to Wi-Fi, publish a simple integer counter to MQTT topic 'node/counter', then go back to sleep. Use the sleep timer and also measure the battery voltage on ADC1 pin 35. Include how to configure the ESP32 to wake from a timer."
Example Result:
#include <WiFi.h>
#include <PubSubClient.h>
const char* ssid = "YOUR_WIFI";
const char* password = "YOUR_PASSWORD";
const char* mqttServer = "broker.hivemq.com";
const uint64_t SLEEP_DURATION_MS = 30 * 60 * 1000ULL; // 30 minutes
WiFiClient espClient;
PubSubClient client(espClient);
void setup() {
Serial.begin(115200);
// Read battery voltage (ADC1 pin 35) before connecting to Wi-Fi
float batteryVoltage = analogRead(35) * (3.3 / 4095.0) * 2; // Divider? Adjust for your circuit
Serial.printf("Battery: %.2f V\n", batteryVoltage);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) { delay(100); }
client.setServer(mqttServer, 1883);
if (client.connect("ESP32Node")) {
client.publish("node/counter", "1"); // Static for demo
}
client.disconnect();
WiFi.disconnect();
esp_sleep_enable_timer_wakeup(SLEEP_DURATION_MS * 1000ULL); // microseconds
esp_deep_sleep_start();
}
void loop() {}
Deep sleep is critical for battery-powered sensors. According to the ESP32 datasheet, deep sleep current can be as low as ~10 µA (with RTC timer). The esp_sleep_enable_timer_wakeup() function accepts microseconds, so we multiply milliseconds by 1000.
Prompt 10: Edge Machine Learning for Anomaly Detection on Raspberry Pi
Task: Implement a simple anomaly detection model for IoT sensor data running locally on a Raspberry Pi.
Prompt:
"Create a Python script using scikit-learn's Isolation Forest to detect anomalies in a stream of temperature values. Train the model on an initial normal dataset sent to a list. Then read incoming data from a CSV file and print 'ANOMALY' when the model predicts -1. Include the necessary imports and code."
Example Result:
import numpy as np
from sklearn.ensemble import IsolationForest
import csv
# Simulate normal training data (e.g., temperatures between 20-25°C)
normal_data = np.array([22.1, 22.5, 23.0, 21.8, 24.1, 23.5, 22.9, 24.8]).reshape(-1, 1)
model = IsolationForest(contamination=0.1)
model.fit(normal_data)
with open('sensor_log.csv', 'r') as f:
reader = csv.reader(f)
next(reader, None) # Skip header
for row in reader:
value = float(row[1])
prediction = model.predict([[value]])
if prediction[0] == -1:
print(f"ANOMALY: {value}")
The Isolation Forest algorithm is effective for unsupervised anomaly detection. This is an edge-ML example, perfect for a Raspberry Pi with the scikit-learn library installed. For deeper details, see the scikit-learn documentation.
Conclusion
These 10 prompts cover a full journey: from blinking an LED to building low-power, cloud-connected, ML-enabled IoT devices. By using them, you not only get code, but also learn the underlying concepts—GPIO, analog reading, MQTT, RTOS, power management, and machine learning.
I encourage you to run these examples on your own hardware, modify them, and combine them. For instance, take Prompt 4 and merge it with Prompt 9 to create a solar-powered environmental sensor. The best way to learn IoT is by doing—and these prompts give you a structured starting point.
If you want more guides like this, follow the Asibiont Blog for practical tutorials on embedded systems and IoT. Happy hacking!
Comments