10 Prompts for IoT and Embedded Development: Arduino, ESP32, and Raspberry Pi

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!

← All posts

Comments