You Want Electronic Components for your project. 

For more information, contact us at: 

Apply Programming Libraries to Manage Sensor Data and Actuators


Lesson 3.3 — Apply Programming Libraries to Manage Sensor Data and Actuators

One of the most powerful aspects of the Arduino and MicroPython ecosystems is the availability of pre-written libraries that handle the complex low-level communication with sensors and actuators.

ANALOGY
A library is like a ready-made cooking sauce in a restaurant kitchen. Instead of making it from scratch every time, the chef opens the jar and uses it. Libraries let you use sensors without becoming an expert in their internal communication protocols.

Installing Arduino Libraries

Method How to install When to use
Library Manager (recommended) Arduino IDE: Sketch → Include Library → Manage Libraries. Search by sensor name. Click Install. Best for popular sensors
ZIP file install Download ZIP from GitHub. Sketch → Include Library → Add .ZIP Library. For libraries not in manager
Manual install Extract ZIP to ~/Documents/Arduino/libraries/. Restart Arduino IDE. For troubleshooting installs
PlatformIO Professional alternative IDE: add libraries in platformio.ini with lib_deps. Handles versioning automatically. For production development

DHT11 / DHT22 — Temperature and Humidity Sensor

DHT Pin Connect to Notes
VCC 3.3 V or 5 V (check your module) Power supply
DATA Arduino pin 4 (any digital pin) Single-wire data signal
GND GND Ground
Pull-up 4.7 kΩ between DATA and VCC Required for reliable communication (some modules include on board)
C/C++ — DHT Sensor with Arduino (DHT library by Adafruit)
#include <DHT.h>
#define DHTPIN  4      // Data pin connected to GPIO 4
#define DHTTYPE DHT22  // DHT22 or DHT11

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(9600);
  dht.begin();
  Serial.println("DHT Sensor ready");
}

void loop() {
  delay(2000);  // DHT22 needs minimum 2 seconds between reads
  float humidity    = dht.readHumidity();
  float temperature = dht.readTemperature();  // Celsius by default
  float heatIndex   = dht.computeHeatIndex(temperature, humidity, false);

  // Check for read failures
  if (isnan(humidity) || isnan(temperature)) {
    Serial.println("ERROR: Failed to read from DHT sensor!");
    return;
  }
  Serial.print("Humidity: ");    Serial.print(humidity, 1);    Serial.print(" % ");
  Serial.print("Temperature: "); Serial.print(temperature, 1); Serial.print(" C ");
  Serial.print("Heat Index: ");  Serial.print(heatIndex, 1);   Serial.println(" C");
}

MicroPython — DHT Sensor on ESP32 (built-in dht module)
# MicroPython has a built-in DHT module — no installation needed!
import dht
from machine import Pin
import time

sensor = dht.DHT22(Pin(4))  # Or dht.DHT11(Pin(4))

while True:
    try:
        sensor.measure()
        temp = sensor.temperature()
        hum  = sensor.humidity()
        print(f'Temperature: {temp:.1f} C  Humidity: {hum:.1f} %')
    except Exception as e:
        print('Sensor error:', e)
    time.sleep(2)

Servo Motor Control

Wire colour Connection
Red wire (VCC) 5 V (directly from Arduino 5V pin or external supply — do NOT power from ESP32 3.3V output)
Brown/Black wire GND
Orange/Yellow wire Signal: connect to PWM pin (Arduino pin 9, or any ESP32 GPIO)
C/C++ — Servo Control (Arduino Servo library)
#include <Servo.h>
Servo gateServo;

void setup() {
  gateServo.attach(9);  // Attach servo signal to pin 9
  Serial.begin(9600);
}

void loop() {
  // Sweep 0 to 180 degrees
  for (int angle = 0; angle <= 180; angle += 10) {
    gateServo.write(angle);
    delay(100);
  }
  delay(1000);
  gateServo.write(0);  // Return to 0
  delay(1000);
}

// IoT use case: Open/close a valve based on sensor input
void setValve(bool open) {
  gateServo.write(open ? 90 : 0);  // 90 = open, 0 = closed
  Serial.println(open ? "Valve OPEN" : "Valve CLOSED");
}

MicroPython — Servo Control on ESP32
from machine import Pin, PWM
import time

servo = PWM(Pin(9), freq=50)  # Servo needs 50 Hz PWM signal

def set_angle(degrees):
    """Convert degrees (0-180) to PWM duty cycle."""
    min_duty = int(65535 * 0.5 / 20)   # 0.5ms pulse
    max_duty = int(65535 * 2.5 / 20)   # 2.5ms pulse
    duty = min_duty + int((max_duty - min_duty) * degrees / 180)
    servo.duty_u16(duty)

# Sweep servo
for angle in range(0, 181, 10):
    set_angle(angle)
    time.sleep_ms(100)
set_angle(0)  # Return to start

I2C Sensor — BMP280 Barometric Pressure

BMP Pin Connection
VCC 3.3 V (NOT 5 V — these sensors are 3.3 V only)
GND GND
SDA Arduino A4 or ESP32 GPIO 21 (default I2C SDA)
SCL Arduino A5 or ESP32 GPIO 22 (default I2C SCL)
C/C++ — BMP280 with Adafruit BMP280 Library
#include <Wire.h>
#include <Adafruit_BMP280.h>

Adafruit_BMP280 bmp;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  if (!bmp.begin(0x76)) {  // I2C address: 0x76 or 0x77
    Serial.println("ERROR: BMP280 not found. Check wiring and I2C address.");
    while (1) delay(1000);
  }
  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,
                  Adafruit_BMP280::SAMPLING_X2,   // temperature
                  Adafruit_BMP280::SAMPLING_X16,  // pressure
                  Adafruit_BMP280::FILTER_X16,
                  Adafruit_BMP280::STANDBY_MS_500);
}

void loop() {
  float temp     = bmp.readTemperature();
  float pressure = bmp.readPressure() / 100.0;  // Pa to hPa
  float altitude = bmp.readAltitude(1013.25);

  Serial.print("Temp: ");     Serial.print(temp, 1);     Serial.print(" C ");
  Serial.print("Pressure: "); Serial.print(pressure, 1); Serial.print(" hPa ");
  Serial.print("Altitude: "); Serial.print(altitude, 1); Serial.println(" m");
  delay(2000);
}

OLED Display — Showing Sensor Data Locally

A 0.96-inch SSD1306 OLED display connected via I2C allows your IoT device to show sensor readings without a computer. Essential for standalone deployments.

C/C++ — OLED with Adafruit SSD1306 Library
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
DHT dht(4, DHT22);

void setup() {
  Serial.begin(9600);
  dht.begin();
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println("SSD1306 OLED not found");
    while(1);
  }
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.println("Weather Station");
  display.println("Initialising...");
  display.display();
  delay(2000);
}

void loop() {
  float temp = dht.readTemperature();
  float hum  = dht.readHumidity();

  display.clearDisplay();
  display.setTextSize(2);
  display.setCursor(0, 0);
  display.print(temp, 1);
  display.println(" C");
  display.setTextSize(1);
  display.print("Humidity: ");
  display.print(hum, 0);
  display.println("%");
  display.display();  // Push buffer to screen
  delay(2000);
}

JSON — Formatting Sensor Data for IoT Transmission

JSON (JavaScript Object Notation) is the universal data format for IoT cloud communication. Sensor readings are packed into a JSON object before being sent to a cloud platform, MQTT broker, or REST API.

C/C++ — Building JSON with ArduinoJson Library
#include <ArduinoJson.h>

void sendSensorPayload(float temp, float hum, float pressure) {
  StaticJsonDocument<200> doc;  // stack memory (safer on small MCUs)

  doc["device_id"]    = "weather-station-kigali-01";
  doc["temperature"]  = round(temp * 10) / 10.0;   // 1 decimal place
  doc["humidity"]     = round(hum  * 10) / 10.0;
  doc["pressure_hpa"] = round(pressure * 10) / 10.0;
  doc["timestamp_ms"] = millis();

  char jsonBuffer[200];
  serializeJson(doc, jsonBuffer);
  Serial.println(jsonBuffer);
  // Output: {"device_id":"weather-station-kigali-01","temperature":24.5,...}

  // In Unit 6 you will replace Serial.println with:
  // mqttClient.publish("sensors/weather", jsonBuffer);
}

MicroPython — JSON Encoding with ujson
import ujson, time

def build_payload(temp, hum):
    data = {
        'device_id':   'weather-esp32-01',
        'temperature': round(temp, 1),
        'humidity':    round(hum, 1),
        'uptime_ms':   time.ticks_ms()
    }
    return ujson.dumps(data)

payload = build_payload(24.5, 68.2)
print(payload)
# Output: {"device_id": "weather-esp32-01", "temperature": 24.5, ...}

Library Best Practices for IoT

Practice Explanation
Always check .begin() return value Most sensor libraries return false or 0 if initialisation fails. Handle this with a clear error message, not a silent continue.
Pin the library version Libraries update and sometimes introduce breaking changes. Note the version to ensure consistency across team members.
Minimise includes Each #include adds to compile time and flash usage. Only include libraries you actually use.
Read the examples first Every Arduino library includes working example sketches under File → Examples. Always start from the example and adapt it rather than writing from scratch.
Check for conflicting pin usage Some libraries claim GPIO pins internally (e.g. Servo library uses Timer1 on AVR, interfering with PWM on pins 9 and 10). Read the docs.

Check Your Understanding — Lesson 3.3

?
1. Write the C/C++ code to read temperature and humidity from a DHT22 on pin 4, check if the reading is valid using isnan(), and print a formatted message like ‘T: 24.5C H: 68%’ to the Serial Monitor.

?
2. What is the purpose of calling display.clearDisplay() before each update cycle on an OLED display? What would happen if you omitted this call?

?
3. In ArduinoJson, what is the difference between StaticJsonDocument and DynamicJsonDocument? Which is recommended for IoT devices with limited RAM and why?

I'm an Embedded & AIoT Systems Engineer and the Founder & CEO of Nyereka Tech, a Rwanda-based startup enabling access to STEM tools, training, and innovation. I'm passionate about empowering young innovators through practical technology education and local manufacturing solutions.