The Perfect Fusion of Embedded Systems and IoT
In the wave of digital transformation, the combination of embedded systems and Internet of Things (IoT) technologies is redefining how we interact with the world around us. From smart homes to Industry 4.0, these technologies are creating a more intelligent, interconnected future.
Embedded Systems Fundamentals
Hardware Platform Selection
Choosing the right hardware platform is the first step toward a successful project:
ESP32 Series
ESP32 is one of our most recommended IoT development platforms:
#include "WiFi.h"
#include "PubSubClient.h"
const char* ssid = "your_wifi_ssid";
const char* password = "your_wifi_password";
const char* mqtt_server = "your_mqtt_broker";
WiFiClient espClient;
PubSubClient client(espClient);
void setup() {
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
void setup_wifi() {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected");
}
Arduino Series
For entry-level projects, Arduino provides a beginner-friendly development environment:
#include <SoftwareSerial.h>
#include <ArduinoJson.h>
SoftwareSerial bluetooth(2, 3);
void setup() {
Serial.begin(9600);
bluetooth.begin(9600);
// Initialize sensors
pinMode(A0, INPUT); // Temperature sensor
pinMode(13, OUTPUT); // LED indicator
}
void loop() {
int temperature = analogRead(A0);
float celsius = (temperature * 5.0 / 1024.0 - 0.5) * 100;
// Build JSON-formatted data
StaticJsonDocument<200> doc;
doc["temperature"] = celsius;
doc["timestamp"] = millis();
String output;
serializeJson(doc, output);
bluetooth.println(output);
delay(1000);
}
Sensor Integration
Digital Sensors
The DHT22 temperature and humidity sensor is a commonly used digital sensor:
#include "DHT.h"
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
void setup() {
Serial.begin(9600);
dht.begin();
}
void loop() {
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
if (isnan(humidity) || isnan(temperature)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
Serial.print("Humidity: ");
Serial.print(humidity);
Serial.print("% Temperature: ");
Serial.print(temperature);
Serial.println("°C");
delay(2000);
}
Analog Sensors
Example usage of a photoresistor:
const int photocellPin = A0;
const int ledPin = 9;
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
}
void loop() {
int photocellReading = analogRead(photocellPin);
// Map sensor value to LED brightness
int ledBrightness = map(photocellReading, 0, 1023, 255, 0);
analogWrite(ledPin, ledBrightness);
Serial.print("Analog reading = ");
Serial.print(photocellReading);
Serial.print(" - LED brightness = ");
Serial.println(ledBrightness);
delay(100);
}
IoT Architecture Design
Communication Protocol Selection
MQTT Protocol
MQTT is the most commonly used lightweight messaging protocol in IoT applications:
import paho.mqtt.client as mqtt
import json
import time
def on_connect(client, userdata, flags, rc):
print(f"Connected with result code {rc}")
client.subscribe("sensors/temperature")
def on_message(client, userdata, msg):
try:
data = json.loads(msg.payload.decode())
temperature = data['temperature']
timestamp = data['timestamp']
print(f"Received: {temperature}°C at {timestamp}")
# Data processing logic
if temperature > 30:
client.publish("alerts/high_temperature",
json.dumps({"alert": "High temperature detected"}))
except Exception as e:
print(f"Error processing message: {e}")
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect("localhost", 1883, 60)
client.loop_forever()
HTTP REST API
For applications requiring a request-response model:
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
void sendSensorData(float temperature, float humidity) {
if(WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin("http://your-api-server.com/api/sensors");
http.addHeader("Content-Type", "application/json");
StaticJsonDocument<200> doc;
doc["device_id"] = "ESP32_001";
doc["temperature"] = temperature;
doc["humidity"] = humidity;
doc["timestamp"] = millis();
String jsonString;
serializeJson(doc, jsonString);
int httpResponseCode = http.POST(jsonString);
if(httpResponseCode > 0) {
String response = http.getString();
Serial.println(response);
}
http.end();
}
}
Data Processing and Analysis
Edge Computing
Performing preliminary data processing on the device side:
#include <math.h>
class SensorFilter {
private:
float readings[10];
int index;
bool filled;
public:
SensorFilter() : index(0), filled(false) {}
float addReading(float value) {
readings[index] = value;
index = (index + 1) % 10;
if (index == 0) filled = true;
return getAverage();
}
float getAverage() {
float sum = 0;
int count = filled ? 10 : index;
for (int i = 0; i < count; i++) {
sum += readings[i];
}
return sum / count;
}
bool isAnomalous(float value) {
float avg = getAverage();
float variance = 0;
int count = filled ? 10 : index;
for (int i = 0; i < count; i++) {
variance += pow(readings[i] - avg, 2);
}
float stdDev = sqrt(variance / count);
return abs(value - avg) > (2 * stdDev);
}
};
SensorFilter tempFilter;
void loop() {
float rawTemp = readTemperature();
float filteredTemp = tempFilter.addReading(rawTemp);
if (tempFilter.isAnomalous(rawTemp)) {
Serial.println("Anomalous reading detected!");
// Trigger alert or additional processing
}
// Only send filtered data
sendSensorData(filteredTemp);
delay(1000);
}
Power Management
Low-Power Design
For battery-powered IoT devices, power consumption control is critical:
#include "esp_sleep.h"
#define uS_TO_S_FACTOR 1000000 // Microseconds to seconds conversion factor
#define TIME_TO_SLEEP 30 // Sleep duration (seconds)
void setup() {
Serial.begin(115200);
// Read sensor data
float temperature = readTemperature();
float humidity = readHumidity();
// Send data
sendDataToServer(temperature, humidity);
// Configure wake-up source
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
Serial.println("Going to sleep now");
Serial.flush();
// Enter deep sleep
esp_deep_sleep_start();
}
void loop() {
// This will never execute, as the device enters sleep after setup
}
Battery Monitoring
#define BATTERY_PIN A0
#define VOLTAGE_DIVIDER_RATIO 2.0
float getBatteryVoltage() {
int rawValue = analogRead(BATTERY_PIN);
float voltage = (rawValue / 1024.0) * 3.3 * VOLTAGE_DIVIDER_RATIO;
return voltage;
}
int getBatteryPercentage() {
float voltage = getBatteryVoltage();
// Assuming lithium battery voltage range: 3.0V - 4.2V
if (voltage >= 4.2) return 100;
if (voltage <= 3.0) return 0;
return (int)((voltage - 3.0) / 1.2 * 100);
}
void checkBatteryStatus() {
int batteryLevel = getBatteryPercentage();
if (batteryLevel < 20) {
// Send low battery warning
sendLowBatteryAlert();
// Enable power saving mode
enablePowerSaveMode();
}
}
Security Considerations
Data Encryption
#include "mbedtls/aes.h"
void encryptData(uint8_t* input, uint8_t* output, uint8_t* key) {
mbedtls_aes_context aes;
mbedtls_aes_init(&aes);
mbedtls_aes_setkey_enc(&aes, key, 256);
mbedtls_aes_crypt_ecb(&aes, MBEDTLS_AES_ENCRYPT, input, output);
mbedtls_aes_free(&aes);
}
void secureDataTransmission(String data) {
uint8_t key[32] = {/* your encryption key */};
uint8_t input[16];
uint8_t encrypted[16];
// Prepare data for encryption
data.getBytes(input, 16);
// Encrypt data
encryptData(input, encrypted, key);
// Send encrypted data
sendEncryptedData(encrypted, 16);
}
Device Authentication
#include <WiFiClientSecure.h>
WiFiClientSecure client;
void setupSecureConnection() {
// Load CA certificate
client.setCACert(ca_cert);
// Load client certificate and private key
client.setCertificate(client_cert);
client.setPrivateKey(client_key);
}
bool authenticateDevice() {
if (client.connect("secure.server.com", 443)) {
String authRequest = "GET /api/authenticate HTTP/1.1\r\n";
authRequest += "Host: secure.server.com\r\n";
authRequest += "Device-ID: " + String(ESP.getEfuseMac()) + "\r\n";
authRequest += "Connection: close\r\n\r\n";
client.print(authRequest);
// Read response
String response = client.readString();
return response.indexOf("200 OK") != -1;
}
return false;
}
Real-World Project Example
Smart Agriculture Monitoring System
#include <WiFi.h>
#include <PubSubClient.h>
#include "DHT.h"
#define SOIL_MOISTURE_PIN A0
#define DHT_PIN 2
#define PUMP_PIN 8
DHT dht(DHT_PIN, DHT22);
WiFiClient espClient;
PubSubClient mqtt(espClient);
struct SensorData {
float temperature;
float humidity;
int soilMoisture;
bool pumpStatus;
float batteryLevel;
};
void setup() {
Serial.begin(115200);
dht.begin();
pinMode(PUMP_PIN, OUTPUT);
connectWiFi();
mqtt.setServer("mqtt.broker.com", 1883);
mqtt.setCallback(mqttCallback);
}
void loop() {
SensorData data = readSensors();
// Automatic irrigation logic
if (data.soilMoisture < 30 && !data.pumpStatus) {
activatePump();
data.pumpStatus = true;
} else if (data.soilMoisture > 70 && data.pumpStatus) {
deactivatePump();
data.pumpStatus = false;
}
// Send data to cloud
publishSensorData(data);
// Check battery status
if (data.batteryLevel < 20) {
enterPowerSaveMode();
}
delay(30000); // 30-second interval
}
SensorData readSensors() {
SensorData data;
data.temperature = dht.readTemperature();
data.humidity = dht.readHumidity();
data.soilMoisture = map(analogRead(SOIL_MOISTURE_PIN), 0, 1023, 0, 100);
data.pumpStatus = digitalRead(PUMP_PIN);
data.batteryLevel = getBatteryLevel();
return data;
}
Troubleshooting and Maintenance
Remote Diagnostics
void performDiagnostics() {
DiagnosticReport report;
// Check WiFi connection
report.wifiStatus = WiFi.status() == WL_CONNECTED;
report.signalStrength = WiFi.RSSI();
// Check sensor status
report.sensorStatus = testSensors();
// Check memory usage
report.freeHeap = ESP.getFreeHeap();
report.heapFragmentation = ESP.getHeapFragmentation();
// Check power status
report.batteryVoltage = getBatteryVoltage();
// Send diagnostic report
sendDiagnosticReport(report);
}
Over-the-Air Updates
#include <HTTPUpdate.h>
void checkForUpdates() {
String currentVersion = "1.0.0";
String updateURL = "http://update.server.com/firmware.bin";
HTTPClient http;
http.begin(updateURL + "?version=" + currentVersion);
int httpCode = http.GET();
if (httpCode == 200) {
Serial.println("Update available, starting download...");
t_httpUpdate_return ret = httpUpdate.update(updateURL);
switch (ret) {
case HTTP_UPDATE_FAILED:
Serial.printf("Update failed. Error: %s\n",
httpUpdate.getLastErrorString().c_str());
break;
case HTTP_UPDATE_NO_UPDATES:
Serial.println("No updates available");
break;
case HTTP_UPDATE_OK:
Serial.println("Update successful, rebooting...");
ESP.restart();
break;
}
}
http.end();
}
Future Trends
Edge AI Integration
#include "tensorflow/lite/micro/all_ops_resolver.h"
#include "tensorflow/lite/micro/micro_error_reporter.h"
#include "tensorflow/lite/micro/micro_interpreter.h"
// AI model inference on edge devices
class EdgeAI {
private:
tflite::MicroInterpreter* interpreter;
public:
bool initModel(const unsigned char* model_data) {
static tflite::MicroErrorReporter micro_error_reporter;
static tflite::AllOpsResolver resolver;
// Load the model
model = tflite::GetModel(model_data);
// Create the interpreter
static uint8_t tensor_arena[10000];
interpreter = new tflite::MicroInterpreter(
model, resolver, tensor_arena, 10000, µ_error_reporter);
return interpreter->AllocateTensors() == kTfLiteOk;
}
float predict(float* input_data) {
// Set input data
TfLiteTensor* input = interpreter->input(0);
for (int i = 0; i < input->bytes / sizeof(float); i++) {
input->data.f[i] = input_data[i];
}
// Execute inference
if (interpreter->Invoke() != kTfLiteOk) {
return -1;
}
// Get prediction result
TfLiteTensor* output = interpreter->output(0);
return output->data.f[0];
}
};
Conclusion
The combination of embedded systems and IoT technologies opens the door to limitless possibilities. From smart homes to industrial automation, these technologies are reshaping our world. A successful IoT project requires:
- Appropriate hardware platform selection
- Reliable communication architecture
- Effective power management
- Robust security mechanisms
- Intelligent data processing
At BASHCAT, we have extensive experience in embedded systems and IoT development, providing clients with complete solutions from concept to product. If you have related project needs, feel free to contact us.