IoT & Embedded Systeme Grundlagen: Sensoren, Mikrocontroller, Raspberry Pi, Arduino & Edge Computing
Dieser Beitrag ist eine umfassende Einführung in die IoT & Embedded Systeme Grundlagen – inklusive Sensoren, Mikrocontroller, Raspberry Pi, Arduino und Edge Computing mit praktischen Beispielen.
In a Nutshell
IoT und Embedded Systeme sind vernetzte, spezialisierte Computer, die physikalische Geräte mit dem Internet verbinden und Daten in Echtzeit verarbeiten.
Kompakte Fachbeschreibung
IoT (Internet of Things) ist ein Netzwerk vernetzter physischer Geräte, die über Sensoren Daten sammeln, verarbeiten und über das Internet austauschen.
Kernkomponenten:
Embedded Systeme
- Mikrocontroller: ARM Cortex-M, AVR, PIC
- Mikroprozessoren: ARM Cortex-A, x86, RISC-V
- Betriebssysteme: Embedded Linux, RTOS, FreeRTOS
- Speicher: Flash, EEPROM, RAM, SD-Karten
Sensoren und Aktoren
- Umweltsensoren: Temperatur, Luftfeuchtigkeit, Druck
- Bewegungssensoren: Beschleunigung, Gyroskop, Magnetometer
- Optische Sensoren: Kamera, Infrarot, Ultraschall
- Aktorik: Motoren, Servos, Relais, LEDs
Kommunikationsprotokolle
- Wireless: WiFi, Bluetooth, LoRaWAN, Zigbee
- Wired: I2C, SPI, UART, CAN, Ethernet
- IoT-Protokolle: MQTT, CoAP, HTTP/REST, WebSocket
- Edge-Protokolle: gRPC, Protocol Buffers
Edge Computing
- Datenverarbeitung: Lokale Verarbeitung statt Cloud
- Latenzoptimierung: Echtzeit-Verarbeitung
- Bandbreiteneffizienz: Reduzierte Datenübertragung
- Offline-Fähigkeit: Betrieb ohne Internetverbindung
Prüfungsrelevante Stichpunkte
- IoT: Internet of Things, vernetzte physische Geräte
- Embedded Systeme: Spezialisierte Computersysteme
- Sensoren: Temperatur, Bewegung, optische Sensoren
- Mikrocontroller: ARM Cortex-M, AVR, PIC
- Raspberry Pi: Einplatinencomputer mit Linux
- Arduino: Open-Source Mikrocontroller-Plattform
- Edge Computing: Lokale Datenverarbeitung
- RTOS: Real-Time Operating System
- MQTT: Message Queuing Telemetry Transport
- IHK-relevant: Moderne Embedded-Systementwicklung und IoT
Kernkomponenten
- Hardware: Mikrocontroller, Prozessoren, Sensoren
- Firmware: Low-Level-Software, Treiber, Bootloader
- Betriebssysteme: Embedded Linux, RTOS, FreeRTOS
- Kommunikation: Protokolle, Netzwerke, Sicherheit
- Edge Computing: Lokale Verarbeitung, Analytics
- Cloud Integration: Datenübertragung, Speicherung
- Power Management: Energieeffizienz, Batteriemanagement
- Security: Verschlüsselung, Authentifizierung, Updates
Praxisbeispiele
1. Arduino IoT Sensor Node mit MQTT
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
#include <ArduinoJson.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
// WiFi configuration
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
// MQTT configuration
const char* mqtt_server = "mqtt.example.com";
const int mqtt_port = 1883;
const char* mqtt_username = "your_username";
const char* mqtt_password = "your_password";
const char* client_id = "arduino_sensor_01";
// Sensor configuration
#define DHT_PIN 4
#define DHT_TYPE DHT22
#define LIGHT_PIN A0
#define MOTION_PIN 2
#define BUZZER_PIN 5
#define LED_PIN 13
// Topics
const char* temp_topic = "iot/sensors/temperature";
const char* humidity_topic = "iot/sensors/humidity";
const char* light_topic = "iot/sensors/light";
const char* motion_topic = "iot/sensors/motion";
const char* status_topic = "iot/sensors/status";
const char* control_topic = "iot/sensors/control";
// Timing
unsigned long lastSensorRead = 0;
const long sensorInterval = 5000; // 5 seconds
unsigned long lastStatusUpdate = 0;
const long statusInterval = 60000; // 1 minute
// Global objects
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
DHT dht(DHT_PIN, DHT_TYPE);
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org");
// Sensor data structure
struct SensorData {
float temperature;
float humidity;
int lightLevel;
bool motionDetected;
unsigned long timestamp;
};
// Device status
struct DeviceStatus {
bool wifiConnected;
bool mqttConnected;
float batteryLevel;
int uptime;
String firmwareVersion;
};
void setup() {
Serial.begin(115200);
while (!Serial) delay(10);
Serial.println("IoT Sensor Node starting...");
// Initialize pins
pinMode(LED_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(MOTION_PIN, INPUT_PULLUP);
// Initialize sensors
dht.begin();
// Initialize NTP client
timeClient.begin();
timeClient.setTimeOffset(3600); // UTC+1
// Connect to WiFi
connectWiFi();
// Connect to MQTT
connectMQTT();
// Initialize time
timeClient.update();
Serial.println("IoT Sensor Node ready!");
blinkLED(3, 200);
}
void loop() {
// Handle WiFi connection
if (WiFi.status() != WL_CONNECTED) {
connectWiFi();
}
// Handle MQTT connection
if (!mqttClient.connected()) {
connectMQTT();
}
// Update NTP time
timeClient.update();
// Read sensors periodically
if (millis() - lastSensorRead >= sensorInterval) {
readAndPublishSensors();
lastSensorRead = millis();
}
// Update status periodically
if (millis() - lastStatusUpdate >= statusInterval) {
publishStatus();
lastStatusUpdate = millis();
}
// Handle MQTT messages
mqttClient.loop();
// Check for motion interrupt
checkMotion();
delay(100);
}
void connectWiFi() {
Serial.println("Connecting to WiFi...");
WiFi.begin(ssid, password);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 30) {
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nWiFi connected!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
digitalWrite(LED_PIN, HIGH);
} else {
Serial.println("\nFailed to connect to WiFi");
digitalWrite(LED_PIN, LOW);
}
}
void connectMQTT() {
Serial.println("Connecting to MQTT...");
mqttClient.setServer(mqtt_server, mqtt_port);
mqttClient.setCallback(mqttCallback);
int attempts = 0;
while (!mqttClient.connected() && attempts < 10) {
Serial.print("Attempting MQTT connection...");
if (mqttClient.connect(client_id, mqtt_username, mqtt_password)) {
Serial.println("connected!");
// Subscribe to control topic
mqttClient.subscribe(control_topic);
// Publish connection message
publishConnectionStatus(true);
} else {
Serial.print("failed, rc=");
Serial.print(mqttClient.state());
Serial.println(" try again in 5 seconds");
delay(5000);
attempts++;
}
}
if (!mqttClient.connected()) {
Serial.println("Failed to connect to MQTT");
}
}
void mqttCallback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
String message = "";
for (int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.println(message);
// Parse JSON message
DynamicJsonDocument doc(1024);
DeserializationError error = deserializeJson(doc, message);
if (error) {
Serial.println("Failed to parse JSON");
return;
}
// Handle control commands
if (String(topic) == control_topic) {
handleControlCommand(doc);
}
}
void handleControlCommand(JsonDocument& command) {
String cmd = command["command"];
if (cmd == "buzz") {
int duration = command["duration"] | 1000;
buzz(duration);
} else if (cmd == "led") {
bool state = command["state"];
digitalWrite(LED_PIN, state ? HIGH : LOW);
} else if (cmd == "restart") {
Serial.println("Restarting device...");
ESP.restart();
} else if (cmd == "sleep") {
int duration = command["duration"] | 10;
Serial.println("Going to sleep for " + String(duration) + " seconds");
ESP.deepSleep(duration * 1000000);
}
}
void readAndPublishSensors() {
SensorData data;
// Read temperature and humidity
data.temperature = dht.readTemperature();
data.humidity = dht.readHumidity();
// Read light level
data.lightLevel = analogRead(LIGHT_PIN);
// Read motion sensor
data.motionDetected = digitalRead(MOTION_PIN) == HIGH;
// Get timestamp
data.timestamp = timeClient.getEpochTime();
// Check for valid readings
if (isnan(data.temperature) || isnan(data.humidity)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
// Publish sensor data
publishSensorData(data);
// Print sensor data
Serial.println("Sensor Data:");
Serial.print("Temperature: ");
Serial.print(data.temperature);
Serial.println("°C");
Serial.print("Humidity: ");
Serial.print(data.humidity);
Serial.println("%");
Serial.print("Light: ");
Serial.println(data.lightLevel);
Serial.print("Motion: ");
Serial.println(data.motionDetected ? "Yes" : "No");
Serial.print("Timestamp: ");
Serial.println(data.timestamp);
}
void publishSensorData(SensorData& data) {
// Create JSON document
DynamicJsonDocument doc(1024);
doc["device_id"] = client_id;
doc["timestamp"] = data.timestamp;
doc["temperature"] = data.temperature;
doc["humidity"] = data.humidity;
doc["light_level"] = data.lightLevel;
doc["motion_detected"] = data.motionDetected;
// Serialize JSON
String jsonStr;
serializeJson(doc, jsonStr);
// Publish to topics
mqttClient.publish(temp_topic, String(data.temperature).c_str());
mqttClient.publish(humidity_topic, String(data.humidity).c_str());
mqttClient.publish(light_topic, String(data.lightLevel).c_str());
mqttClient.publish(motion_topic, String(data.motionDetected).c_str());
// Publish combined data
mqttClient.publish("iot/sensors/combined", jsonStr.c_str());
}
void publishStatus() {
DeviceStatus status;
status.wifiConnected = (WiFi.status() == WL_CONNECTED);
status.mqttConnected = mqttClient.connected();
status.batteryLevel = getBatteryLevel();
status.uptime = millis() / 1000;
status.firmwareVersion = "1.0.0";
// Create JSON document
DynamicJsonDocument doc(1024);
doc["device_id"] = client_id;
doc["timestamp"] = timeClient.getEpochTime();
doc["wifi_connected"] = status.wifiConnected;
doc["mqtt_connected"] = status.mqttConnected;
doc["battery_level"] = status.batteryLevel;
doc["uptime"] = status.uptime;
doc["firmware_version"] = status.firmwareVersion;
doc["free_heap"] = ESP.getFreeHeap();
doc["cpu_freq"] = ESP.getCpuFreqMHz();
// Serialize JSON
String jsonStr;
serializeJson(doc, jsonStr);
// Publish status
mqttClient.publish(status_topic, jsonStr.c_str());
}
void publishConnectionStatus(bool connected) {
DynamicJsonDocument doc(512);
doc["device_id"] = client_id;
doc["timestamp"] = timeClient.getEpochTime();
doc["connected"] = connected;
doc["ip_address"] = WiFi.localIP().toString();
doc["mac_address"] = WiFi.macAddress();
String jsonStr;
serializeJson(doc, jsonStr);
mqttClient.publish("iot/sensors/connection", jsonStr.c_str());
}
void checkMotion() {
static bool lastMotionState = false;
bool currentMotionState = digitalRead(MOTION_PIN) == HIGH;
if (currentMotionState && !lastMotionState) {
// Motion detected
Serial.println("Motion detected!");
// Immediate motion notification
DynamicJsonDocument doc(256);
doc["device_id"] = client_id;
doc["timestamp"] = timeClient.getEpochTime();
doc["motion_detected"] = true;
doc["alert_type"] = "motion";
String jsonStr;
serializeJson(doc, jsonStr);
mqttClient.publish("iot/sensors/alert", jsonStr.c_str());
// Alert buzzer
buzz(200);
}
lastMotionState = currentMotionState;
}
float getBatteryLevel() {
// Read battery voltage (assuming voltage divider)
int rawValue = analogRead(A0);
float voltage = rawValue * (3.3 / 4096.0) * 2.0; // Voltage divider factor
// Convert to percentage (assuming 3.0V to 4.2V range)
float percentage = ((voltage - 3.0) / 1.2) * 100.0;
percentage = constrain(percentage, 0.0, 100.0);
return percentage;
}
void buzz(int duration) {
tone(BUZZER_PIN, 1000, duration);
}
void blinkLED(int times, int delayMs) {
for (int i = 0; i < times; i++) {
digitalWrite(LED_PIN, HIGH);
delay(delayMs);
digitalWrite(LED_PIN, LOW);
delay(delayMs);
}
}
// OTA Update functionality
void checkForOTAUpdate() {
// This would implement OTA update checking
// For simplicity, just print status
Serial.println("Checking for OTA updates...");
}
// Power management
void enterDeepSleep(int seconds) {
Serial.println("Entering deep sleep...");
ESP.deepSleep(seconds * 1000000);
}
void wakeFromDeepSleep() {
Serial.println("Waking from deep sleep...");
// Reinitialize peripherals after wake
}
2. Raspberry Pi Edge Computing mit Python
import time
import json
import threading
import queue
import subprocess
import os
import signal
import sys
from datetime import datetime
import logging
import sqlite3
import paho.mqtt.client as mqtt
import picamera
import RPi.GPIO as GPIO
import Adafruit_DHT
import board
import busio
import adafruit_ads1x15.ads1115 as ADS
from adafruit_ads1x15.analog_in import AnalogIn
import numpy as np
import cv2
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing import image
import tensorflow as tf
class IoTEdgeGateway:
def __init__(self, config_file='config.json'):
"""Initialize IoT Edge Gateway"""
self.config = self.load_config(config_file)
self.setup_logging()
self.setup_gpio()
self.setup_sensors()
self.setup_camera()
self.setup_mqtt()
self.setup_database()
self.setup_ml_models()
# Data queues
self.sensor_queue = queue.Queue()
self.image_queue = queue.Queue()
self.control_queue = queue.Queue()
# Runtime state
self.running = True
self.threads = []
# Register signal handlers
signal.signal(signal.SIGINT, self.signal_handler)
signal.signal(signal.SIGTERM, self.signal_handler)
self.logger.info("IoT Edge Gateway initialized")
def load_config(self, config_file):
"""Load configuration from JSON file"""
try:
with open(config_file, 'r') as f:
return json.load(f)
except FileNotFoundError:
self.logger.error(f"Config file {config_file} not found")
return self.get_default_config()
def get_default_config(self):
"""Get default configuration"""
return {
"mqtt": {
"broker": "localhost",
"port": 1883,
"username": "",
"password": "",
"client_id": "edge_gateway_01"
},
"sensors": {
"dht_pin": 4,
"light_pin": 18,
"motion_pin": 24,
"ads1115_address": 0x48
},
"camera": {
"resolution": (640, 480),
"framerate": 30,
"rotation": 0
},
"database": {
"path": "iot_data.db"
},
"ml_models": {
"object_detection": "models/object_detection.h5",
"anomaly_detection": "models/anomaly_detection.h5"
},
"processing": {
"sensor_interval": 5,
"image_interval": 10,
"batch_size": 32
}
}
def setup_logging(self):
"""Setup logging configuration"""
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('edge_gateway.log'),
logging.StreamHandler(sys.stdout)
]
)
self.logger = logging.getLogger(__name__)
def setup_gpio(self):
"""Setup GPIO pins"""
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
# Setup pins
self.dht_pin = self.config['sensors']['dht_pin']
self.light_pin = self.config['sensors']['light_pin']
self.motion_pin = self.config['sensors']['motion_pin']
# Setup motion pin as input with pull-up
GPIO.setup(self.motion_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# Add interrupt for motion detection
GPIO.add_event_detect(self.motion_pin, GPIO.RISING,
callback=self.motion_detected, bouncetime=300)
self.logger.info("GPIO setup completed")
def setup_sensors(self):
"""Setup sensor interfaces"""
# DHT22 sensor
self.dht_sensor = Adafruit_DHT.DHT22
# ADS1115 ADC for analog sensors
i2c = busio.I2C(board.SCL, board.SDA)
self.ads = ADS.ADS1115(i2c)
self.ads.gain = 1 # +/- 4.096V
# Analog channels
self.light_channel = AnalogIn(self.ads, ADS.P0)
self.temp_channel = AnalogIn(self.ads, ADS.P1)
self.humidity_channel = AnalogIn(self.ads, ADS.P2)
self.logger.info("Sensors setup completed")
def setup_camera(self):
"""Setup camera interface"""
try:
self.camera = picamera.PiCamera()
self.camera.resolution = tuple(self.config['camera']['resolution'])
self.camera.framerate = self.config['camera']['framerate']
self.camera.rotation = self.config['camera']['rotation']
# Camera warm-up
time.sleep(2)
self.logger.info("Camera setup completed")
except Exception as e:
self.logger.error(f"Camera setup failed: {e}")
self.camera = None
def setup_mqtt(self):
"""Setup MQTT client"""
self.mqtt_client = mqtt.Client(self.config['mqtt']['client_id'])
# Set callbacks
self.mqtt_client.on_connect = self.mqtt_on_connect
self.mqtt_client.on_message = self.mqtt_on_message
self.mqtt_client.on_disconnect = self.mqtt_on_disconnect
# Set credentials if provided
if self.config['mqtt']['username']:
self.mqtt_client.username_pw_set(
self.config['mqtt']['username'],
self.config['mqtt']['password']
)
# Connect to broker
try:
self.mqtt_client.connect(
self.config['mqtt']['broker'],
self.config['mqtt']['port'],
60
)
self.mqtt_client.loop_start()
self.logger.info("MQTT client connected")
except Exception as e:
self.logger.error(f"MQTT connection failed: {e}")
def setup_database(self):
"""Setup SQLite database"""
self.db_path = self.config['database']['path']
self.init_database()
self.logger.info("Database setup completed")
def init_database(self):
"""Initialize database tables"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
# Sensor data table
cursor.execute('''
CREATE TABLE IF NOT EXISTS sensor_data (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
sensor_type TEXT,
sensor_id TEXT,
value REAL,
unit TEXT,
processed BOOLEAN DEFAULT FALSE
)
''')
# Image data table
cursor.execute('''
CREATE TABLE IF NOT EXISTS image_data (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
filename TEXT,
objects_detected TEXT,
confidence REAL,
processed BOOLEAN DEFAULT FALSE
)
''')
# System status table
cursor.execute('''
CREATE TABLE IF NOT EXISTS system_status (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
cpu_usage REAL,
memory_usage REAL,
disk_usage REAL,
temperature REAL,
uptime INTEGER
)
''')
conn.commit()
conn.close()
def setup_ml_models(self):
"""Setup machine learning models"""
self.models = {}
try:
# Load object detection model
if os.path.exists(self.config['ml_models']['object_detection']):
self.models['object_detection'] = load_model(
self.config['ml_models']['object_detection']
)
self.logger.info("Object detection model loaded")
# Load anomaly detection model
if os.path.exists(self.config['ml_models']['anomaly_detection']):
self.models['anomaly_detection'] = load_model(
self.config['ml_models']['anomaly_detection']
)
self.logger.info("Anomaly detection model loaded")
except Exception as e:
self.logger.error(f"ML model loading failed: {e}")
def mqtt_on_connect(self, client, userdata, flags, rc):
"""MQTT connection callback"""
if rc == 0:
self.logger.info("Connected to MQTT broker")
# Subscribe to control topics
client.subscribe("edge/gateway/control")
client.subscribe("edge/sensors/+/control")
else:
self.logger.error(f"MQTT connection failed with code {rc}")
def mqtt_on_message(self, client, userdata, msg):
"""MQTT message callback"""
try:
topic = msg.topic
payload = json.loads(msg.payload.decode())
self.logger.info(f"Received message on {topic}: {payload}")
# Handle control messages
if "control" in topic:
self.control_queue.put((topic, payload))
except Exception as e:
self.logger.error(f"MQTT message processing failed: {e}")
def mqtt_on_disconnect(self, client, userdata, rc):
"""MQTT disconnection callback"""
self.logger.warning(f"MQTT disconnected with code {rc}")
def motion_detected(self, channel):
"""Motion detection interrupt handler"""
timestamp = datetime.now().isoformat()
# Publish motion alert
alert = {
"device_id": self.config['mqtt']['client_id'],
"timestamp": timestamp,
"alert_type": "motion",
"location": "entrance"
}
self.mqtt_client.publish("edge/alerts/motion", json.dumps(alert))
# Trigger image capture
if self.camera:
self.image_queue.put(("motion", timestamp))
self.logger.info("Motion detected and alert published")
def read_dht_sensor(self):
"""Read DHT22 sensor data"""
humidity, temperature = Adafruit_DHT.read_retry(
self.dht_sensor, self.dht_pin
)
if humidity is not None and temperature is not None:
return {
"temperature": temperature,
"humidity": humidity,
"timestamp": datetime.now().isoformat()
}
else:
self.logger.error("Failed to read DHT sensor")
return None
def read_analog_sensors(self):
"""Read analog sensor data"""
try:
# Read light sensor
light_voltage = self.light_channel.voltage
light_level = (light_voltage / 3.3) * 100 # Convert to percentage
# Read temperature sensor (if using analog temp sensor)
temp_voltage = self.temp_channel.voltage
# Convert voltage to temperature (example conversion)
analog_temp = (temp_voltage - 0.5) * 100 # LM35 conversion
# Read humidity sensor (if using analog humidity sensor)
humidity_voltage = self.humidity_channel.voltage
analog_humidity = (humidity_voltage / 3.3) * 100
return {
"light_level": light_level,
"analog_temperature": analog_temp,
"analog_humidity": analog_humidity,
"timestamp": datetime.now().isoformat()
}
except Exception as e:
self.logger.error(f"Analog sensor reading failed: {e}")
return None
def capture_image(self, trigger="scheduled"):
"""Capture image from camera"""
if not self.camera:
return None
try:
timestamp = datetime.now().isoformat()
filename = f"images/capture_{timestamp.replace(':', '-')}.jpg"
# Capture image
self.camera.capture(filename)
# Process image with ML models
processed_image = self.process_image(filename)
return {
"filename": filename,
"timestamp": timestamp,
"trigger": trigger,
"processed": processed_image
}
except Exception as e:
self.logger.error(f"Image capture failed: {e}")
return None
def process_image(self, image_path):
"""Process image with ML models"""
try:
# Load and preprocess image
img = image.load_img(image_path, target_size=(224, 224))
img_array = image.img_to_array(img)
img_array = np.expand_dims(img_array, axis=0)
img_array = img_array / 255.0
result = {}
# Object detection
if 'object_detection' in self.models:
predictions = self.models['object_detection'].predict(img_array)
result['objects'] = self.decode_predictions(predictions)
# Anomaly detection
if 'anomaly_detection' in self.models:
anomaly_score = self.models['anomaly_detection'].predict(img_array)[0][0]
result['anomaly_score'] = float(anomaly_score)
result['is_anomaly'] = anomaly_score > 0.5
return result
except Exception as e:
self.logger.error(f"Image processing failed: {e}")
return None
def decode_predictions(self, predictions):
"""Decode ML model predictions"""
# This would depend on the specific model
# Example implementation
class_names = ['person', 'car', 'bicycle', 'dog', 'cat']
# Get top predictions
top_indices = np.argsort(predictions[0])[-5:][::-1]
results = []
for i, index in enumerate(top_indices):
results.append({
"class": class_names[index],
"confidence": float(predictions[0][index]),
"rank": i + 1
})
return results
def store_sensor_data(self, sensor_data):
"""Store sensor data in database"""
try:
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
for sensor_type, value in sensor_data.items():
if sensor_type == "timestamp":
continue
cursor.execute('''
INSERT INTO sensor_data (sensor_type, sensor_id, value, unit)
VALUES (?, ?, ?, ?)
''', (sensor_type, "gateway_01", value, self.get_unit(sensor_type)))
conn.commit()
conn.close()
except Exception as e:
self.logger.error(f"Database storage failed: {e}")
def get_unit(self, sensor_type):
"""Get unit for sensor type"""
units = {
"temperature": "°C",
"humidity": "%",
"light_level": "%",
"analog_temperature": "°C",
"analog_humidity": "%"
}
return units.get(sensor_type, "")
def get_system_status(self):
"""Get system status information"""
try:
# CPU usage
cpu_usage = psutil.cpu_percent()
# Memory usage
memory = psutil.virtual_memory()
memory_usage = memory.percent
# Disk usage
disk = psutil.disk_usage('/')
disk_usage = disk.percent
# CPU temperature
try:
temp = subprocess.check_output(['vcgencmd', 'measure_temp'])
cpu_temp = float(temp.decode().split('=')[1].split("'")[0])
except:
cpu_temp = 0.0
# Uptime
uptime = time.time() - psutil.boot_time()
return {
"cpu_usage": cpu_usage,
"memory_usage": memory_usage,
"disk_usage": disk_usage,
"temperature": cpu_temp,
"uptime": uptime,
"timestamp": datetime.now().isoformat()
}
except Exception as e:
self.logger.error(f"System status check failed: {e}")
return None
def sensor_worker(self):
"""Worker thread for sensor data collection"""
self.logger.info("Sensor worker started")
while self.running:
try:
# Read DHT sensor
dht_data = self.read_dht_sensor()
if dht_data:
self.sensor_queue.put(("dht", dht_data))
# Read analog sensors
analog_data = self.read_analog_sensors()
if analog_data:
self.sensor_queue.put(("analog", analog_data))
# Get system status
system_status = self.get_system_status()
if system_status:
self.sensor_queue.put(("system", system_status))
# Sleep for interval
time.sleep(self.config['processing']['sensor_interval'])
except Exception as e:
self.logger.error(f"Sensor worker error: {e}")
time.sleep(1)
def image_worker(self):
"""Worker thread for image processing"""
self.logger.info("Image worker started")
while self.running:
try:
# Get image capture request
if not self.image_queue.empty():
trigger, timestamp = self.image_queue.get(timeout=1)
# Capture image
image_data = self.capture_image(trigger)
if image_data:
# Publish image data
self.mqtt_client.publish(
"edge/gateway/images",
json.dumps(image_data)
)
# Store in database
self.store_image_data(image_data)
# Periodic image capture
else:
image_data = self.capture_image("scheduled")
if image_data:
self.mqtt_client.publish(
"edge/gateway/images",
json.dumps(image_data)
)
self.store_image_data(image_data)
# Sleep for interval
time.sleep(self.config['processing']['image_interval'])
except queue.Empty:
continue
except Exception as e:
self.logger.error(f"Image worker error: {e}")
time.sleep(1)
def control_worker(self):
"""Worker thread for control commands"""
self.logger.info("Control worker started")
while self.running:
try:
# Get control command
topic, command = self.control_queue.get(timeout=1)
self.logger.info(f"Processing control command: {command}")
# Handle commands
if command.get("command") == "restart":
self.restart_system()
elif command.get("command") == "shutdown":
self.shutdown_system()
elif command.get("command") == "capture_image":
self.image_queue.put(("manual", datetime.now().isoformat()))
elif command.get("command") == "update_config":
self.update_config(command.get("config", {}))
except queue.Empty:
continue
except Exception as e:
self.logger.error(f"Control worker error: {e}")
time.sleep(1)
def data_processor(self):
"""Worker thread for data processing and publishing"""
self.logger.info("Data processor started")
while self.running:
try:
# Process sensor data
if not self.sensor_queue.empty():
sensor_type, data = self.sensor_queue.get(timeout=1)
# Store in database
self.store_sensor_data(data)
# Publish to MQTT
topic = f"edge/sensors/{sensor_type}"
self.mqtt_client.publish(topic, json.dumps(data))
# Check for anomalies
if sensor_type == "system":
self.check_system_anomalies(data)
time.sleep(0.1)
except queue.Empty:
continue
except Exception as e:
self.logger.error(f"Data processor error: {e}")
time.sleep(1)
def check_system_anomalies(self, system_data):
"""Check for system anomalies"""
anomalies = []
# Check CPU usage
if system_data.get("cpu_usage", 0) > 80:
anomalies.append("high_cpu_usage")
# Check memory usage
if system_data.get("memory_usage", 0) > 85:
anomalies.append("high_memory_usage")
# Check disk usage
if system_data.get("disk_usage", 0) > 90:
anomalies.append("high_disk_usage")
# Check temperature
if system_data.get("temperature", 0) > 70:
anomalies.append("high_temperature")
# Publish anomalies if any
if anomalies:
alert = {
"device_id": self.config['mqtt']['client_id'],
"timestamp": datetime.now().isoformat(),
"alert_type": "system_anomaly",
"anomalies": anomalies,
"system_data": system_data
}
self.mqtt_client.publish("edge/alerts/system", json.dumps(alert))
self.logger.warning(f"System anomalies detected: {anomalies}")
def store_image_data(self, image_data):
"""Store image data in database"""
try:
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute('''
INSERT INTO image_data (filename, objects_detected, confidence, processed)
VALUES (?, ?, ?, ?)
''', (
image_data["filename"],
json.dumps(image_data.get("processed", {})),
0.0, # Default confidence
image_data.get("processed") is not None
))
conn.commit()
conn.close()
except Exception as e:
self.logger.error(f"Image data storage failed: {e}")
def restart_system(self):
"""Restart the system"""
self.logger.info("System restart requested")
self.running = False
# Restart after cleanup
subprocess.run(['sudo', 'reboot'])
def shutdown_system(self):
"""Shutdown the system"""
self.logger.info("System shutdown requested")
self.running = False
# Shutdown after cleanup
subprocess.run(['sudo', 'shutdown', '-h', 'now'])
def update_config(self, new_config):
"""Update configuration"""
self.config.update(new_config)
# Save new config
with open('config.json', 'w') as f:
json.dump(self.config, f, indent=2)
self.logger.info("Configuration updated")
def start(self):
"""Start the edge gateway"""
self.logger.info("Starting IoT Edge Gateway")
# Start worker threads
self.threads = [
threading.Thread(target=self.sensor_worker, daemon=True),
threading.Thread(target=self.image_worker, daemon=True),
threading.Thread(target=self.control_worker, daemon=True),
threading.Thread(target=self.data_processor, daemon=True)
]
for thread in self.threads:
thread.start()
self.logger.info("All worker threads started")
def stop(self):
"""Stop the edge gateway"""
self.logger.info("Stopping IoT Edge Gateway")
self.running = False
# Stop MQTT client
self.mqtt_client.loop_stop()
self.mqtt_client.disconnect()
# Cleanup GPIO
GPIO.cleanup()
# Wait for threads to finish
for thread in self.threads:
thread.join(timeout=5)
self.logger.info("IoT Edge Gateway stopped")
def signal_handler(self, signum, frame):
"""Handle system signals"""
self.logger.info(f"Received signal {signum}")
self.stop()
sys.exit(0)
def run(self):
"""Main run loop"""
try:
self.start()
# Keep main thread alive
while self.running:
time.sleep(1)
except KeyboardInterrupt:
self.logger.info("Keyboard interrupt received")
except Exception as e:
self.logger.error(f"Unexpected error: {e}")
finally:
self.stop()
if __name__ == "__main__":
# Import psutil for system monitoring
import psutil
# Create and run edge gateway
gateway = IoTEdgeGateway()
gateway.run()
3. Embedded C++ für Mikrocontroller
#include <Arduino.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <RTClib.h>
#include <DHT.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <EEPROM.h>
#include <FreeRTOS.h>
#include <task.h>
// Configuration constants
#define WIFI_SSID "YOUR_WIFI_SSID"
#define WIFI_PASSWORD "YOUR_WIFI_PASSWORD"
#define MQTT_SERVER "mqtt.example.com"
#define MQTT_PORT 1883
#define MQTT_CLIENT_ID "embedded_device_01"
#define MQTT_USERNAME "your_username"
#define MQTT_PASSWORD "your_password"
// Pin definitions
#define DHT_PIN 4
#define BMP_SDA_PIN 21
#define BMP_SCL_PIN 22
#define SD_CS_PIN 5
#define LED_PIN 2
#define BUZZER_PIN 12
#define RELAY_PIN 13
#define BUTTON_PIN 0
// Sensor types
#define DHT_TYPE DHT22
// Task priorities
#define SENSOR_TASK_PRIORITY 2
#define COMM_TASK_PRIORITY 3
#define CONTROL_TASK_PRIORITY 1
#define DATA_LOGGER_TASK_PRIORITY 1
// Task stack sizes
#define SENSOR_TASK_STACK_SIZE 2048
#define COMM_TASK_STACK_SIZE 4096
#define CONTROL_TASK_STACK_SIZE 2048
#define DATA_LOGGER_TASK_STACK_SIZE 2048
// Data structures
struct SensorData {
float temperature;
float humidity;
float pressure;
float altitude;
unsigned long timestamp;
bool valid;
};
struct SystemStatus {
bool wifiConnected;
bool mqttConnected;
bool sdCardPresent;
float batteryLevel;
int uptime;
int freeHeap;
float cpuTemperature;
unsigned long lastSensorRead;
unsigned long lastMQTTMessage;
};
struct ControlCommand {
String command;
String parameters;
unsigned long timestamp;
bool processed;
};
// Global objects
DHT dhtSensor(DHT_PIN, DHT_TYPE);
Adafruit_BMP280 bmp280;
RTC_DS3231 rtc;
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
// Data queues
QueueHandle_t sensorDataQueue;
QueueHandle_t controlCommandQueue;
QueueHandle_t logDataQueue;
// Semaphores
SemaphoreHandle_t wifiMutex;
SemaphoreHandle_t mqttMutex;
SemaphoreHandle_t sensorMutex;
SemaphoreHandle_t sdMutex;
// Global variables
SystemStatus systemStatus;
TaskHandle_t sensorTaskHandle;
TaskHandle_t commTaskHandle;
TaskHandle_t controlTaskHandle;
TaskHandle_t dataLoggerTaskHandle;
// Function prototypes
void sensorTask(void *pvParameters);
void communicationTask(void *pvParameters);
void controlTask(void *pvParameters);
void dataLoggerTask(void *pvParameters);
void connectWiFi();
void connectMQTT();
void mqttCallback(char* topic, byte* payload, unsigned int length);
void publishSensorData(SensorData& data);
void publishSystemStatus();
void handleControlCommand(ControlCommand& command);
void logData(String message);
void setupSensors();
void setupSDCard();
void setupRTC();
void buttonISR();
void alertUser(int beeps, int duration);
void enterDeepSleep(int seconds);
void wakeFromDeepSleep();
void setup() {
Serial.begin(115200);
Serial.println("Embedded IoT Device starting...");
// Initialize GPIO
pinMode(LED_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(RELAY_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
// Setup interrupts
attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), buttonISR, FALLING);
// Initialize semaphores
wifiMutex = xSemaphoreCreateMutex();
mqttMutex = xSemaphoreCreateMutex();
sensorMutex = xSemaphoreCreateMutex();
sdMutex = xSemaphoreCreateMutex();
// Initialize queues
sensorDataQueue = xQueueCreate(10, sizeof(SensorData));
controlCommandQueue = xQueueCreate(5, sizeof(ControlCommand));
logDataQueue = xQueueCreate(20, sizeof(String[50]));
// Setup hardware
setupSensors();
setupSDCard();
setupRTC();
// Initialize system status
systemStatus = {
.wifiConnected = false,
.mqttConnected = false,
.sdCardPresent = false,
.batteryLevel = 0.0,
.uptime = 0,
.freeHeap = ESP.getFreeHeap(),
.cpuTemperature = 0.0,
.lastSensorRead = 0,
.lastMQTTMessage = 0
};
// Create FreeRTOS tasks
xTaskCreate(
sensorTask,
"SensorTask",
SENSOR_TASK_STACK_SIZE,
NULL,
SENSOR_TASK_PRIORITY,
&sensorTaskHandle
);
xTaskCreate(
communicationTask,
"CommTask",
COMM_TASK_STACK_SIZE,
NULL,
COMM_TASK_PRIORITY,
&commTaskHandle
);
xTaskCreate(
controlTask,
"ControlTask",
CONTROL_TASK_STACK_SIZE,
NULL,
CONTROL_TASK_PRIORITY,
&controlTaskHandle
);
xTaskCreate(
dataLoggerTask,
"DataLoggerTask",
DATA_LOGGER_TASK_STACK_SIZE,
NULL,
DATA_LOGGER_TASK_PRIORITY,
&dataLoggerTaskHandle
);
// Alert user that system is ready
alertUser(3, 200);
Serial.println("Embedded IoT Device ready!");
}
void loop() {
// Main loop is handled by FreeRTOS tasks
vTaskDelay(pdMS_TO_TICKS(1000));
}
void sensorTask(void *pvParameters) {
Serial.println("Sensor task started");
SensorData sensorData;
const TickType_t xDelay = pdMS_TO_TICKS(5000); // 5 seconds
while (1) {
// Take sensor mutex
if (xSemaphoreTake(sensorMutex, pdMS_TO_TICKS(100)) == pdTRUE) {
// Read DHT sensor
float humidity = dhtSensor.readHumidity();
float temperature = dhtSensor.readTemperature();
// Read BMP280 sensor
float pressure = bmp280.readPressure();
float altitude = bmp280.readAltitude(1013.25); // Sea level pressure
// Check if readings are valid
if (!isnan(humidity) && !isnan(temperature) && pressure > 0) {
sensorData.temperature = temperature;
sensorData.humidity = humidity;
sensorData.pressure = pressure / 100.0; // Convert to hPa
sensorData.altitude = altitude;
sensorData.timestamp = millis();
sensorData.valid = true;
// Update system status
systemStatus.lastSensorRead = millis();
systemStatus.freeHeap = ESP.getFreeHeap();
// Send data to queue
if (xQueueSend(sensorDataQueue, &sensorData, pdMS_TO_TICKS(100)) != pdTRUE) {
Serial.println("Failed to send sensor data to queue");
}
// Log sensor data
String logMessage = "Sensor: T=" + String(temperature) +
"C, H=" + String(humidity) +
"%, P=" + String(sensorData.pressure) + "hPa";
logData(logMessage);
} else {
Serial.println("Invalid sensor readings");
sensorData.valid = false;
// Log error
logData("ERROR: Invalid sensor readings");
}
xSemaphoreGive(sensorMutex);
} else {
Serial.println("Failed to take sensor mutex");
}
vTaskDelay(xDelay);
}
}
void communicationTask(void *pvParameters) {
Serial.println("Communication task started");
const TickType_t xDelay = pdMS_TO_TICKS(1000); // 1 second
while (1) {
// Handle WiFi connection
if (xSemaphoreTake(wifiMutex, pdMS_TO_TICKS(100)) == pdTRUE) {
if (WiFi.status() != WL_CONNECTED) {
connectWiFi();
}
systemStatus.wifiConnected = (WiFi.status() == WL_CONNECTED);
xSemaphoreGive(wifiMutex);
}
// Handle MQTT connection
if (systemStatus.wifiConnected) {
if (xSemaphoreTake(mqttMutex, pdMS_TO_TICKS(100)) == pdTRUE) {
if (!mqttClient.connected()) {
connectMQTT();
}
systemStatus.mqttConnected = mqttClient.connected();
// Process MQTT messages
mqttClient.loop();
xSemaphoreGive(mqttMutex);
}
}
// Publish sensor data
SensorData sensorData;
if (xQueueReceive(sensorDataQueue, &sensorData, pdMS_TO_TICKS(100)) == pdTRUE) {
if (sensorData.valid && systemStatus.mqttConnected) {
publishSensorData(sensorData);
systemStatus.lastMQTTMessage = millis();
}
}
// Publish system status periodically
static unsigned long lastStatusPublish = 0;
if (millis() - lastStatusPublish > 60000) { // Every minute
if (systemStatus.mqttConnected) {
publishSystemStatus();
lastStatusPublish = millis();
}
}
vTaskDelay(xDelay);
}
}
void controlTask(void *pvParameters) {
Serial.println("Control task started");
ControlCommand command;
const TickType_t xDelay = pdMS_TO_TICKS(500); // 0.5 seconds
while (1) {
// Process control commands
if (xQueueReceive(controlCommandQueue, &command, pdMS_TO_TICKS(100)) == pdTRUE) {
handleControlCommand(command);
}
// Monitor system health
static unsigned long lastHealthCheck = 0;
if (millis() - lastHealthCheck > 30000) { // Every 30 seconds
// Check free heap
if (ESP.getFreeHeap() < 1000) {
logData("WARNING: Low memory");
alertUser(2, 100);
}
// Check uptime
systemStatus.uptime = millis() / 1000;
// Check battery level (if implemented)
systemStatus.batteryLevel = getBatteryLevel();
lastHealthCheck = millis();
}
vTaskDelay(xDelay);
}
}
void dataLoggerTask(void *pvParameters) {
Serial.println("Data logger task started");
String logMessage;
const TickType_t xDelay = pdMS_TO_TICKS(1000); // 1 second
while (1) {
// Process log messages
if (xQueueReceive(logDataQueue, &logMessage, pdMS_TO_TICKS(100)) == pdTRUE) {
// Print to serial
Serial.println(logMessage);
// Write to SD card if available
if (systemStatus.sdCardPresent) {
if (xSemaphoreTake(sdMutex, pdMS_TO_TICKS(100)) == pdTRUE) {
writeLogToSD(logMessage);
xSemaphoreGive(sdMutex);
}
}
}
vTaskDelay(xDelay);
}
}
void connectWiFi() {
Serial.println("Connecting to WiFi...");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 30) {
vTaskDelay(pdMS_TO_TICKS(500));
Serial.print(".");
attempts++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nWiFi connected!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
digitalWrite(LED_PIN, HIGH);
logData("WiFi connected: " + WiFi.localIP().toString());
} else {
Serial.println("\nFailed to connect to WiFi");
digitalWrite(LED_PIN, LOW);
logData("ERROR: WiFi connection failed");
}
}
void connectMQTT() {
Serial.println("Connecting to MQTT...");
mqttClient.setServer(MQTT_SERVER, MQTT_PORT);
mqttClient.setCallback(mqttCallback);
int attempts = 0;
while (!mqttClient.connected() && attempts < 10) {
Serial.print("Attempting MQTT connection...");
if (mqttClient.connect(MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD)) {
Serial.println("connected!");
// Subscribe to control topics
mqttClient.subscribe("embedded/control");
mqttClient.subscribe("embedded/" + String(MQTT_CLIENT_ID) + "/control");
logData("MQTT connected");
} else {
Serial.print("failed, rc=");
Serial.print(mqttClient.state());
Serial.println(" try again in 5 seconds");
vTaskDelay(pdMS_TO_TICKS(5000));
attempts++;
}
}
if (!mqttClient.connected()) {
Serial.println("Failed to connect to MQTT");
logData("ERROR: MQTT connection failed");
}
}
void mqttCallback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
String message = "";
for (int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.println(message);
// Parse JSON message
DynamicJsonDocument doc(1024);
DeserializationError error = deserializeJson(doc, message);
if (error) {
Serial.println("Failed to parse JSON");
logData("ERROR: Failed to parse MQTT message");
return;
}
// Create control command
ControlCommand command;
command.command = doc["command"] | "";
command.parameters = doc["parameters"] | "";
command.timestamp = millis();
command.processed = false;
// Send command to control task
if (xQueueSend(controlCommandQueue, &command, pdMS_TO_TICKS(100)) != pdTRUE) {
Serial.println("Failed to send control command to queue");
}
}
void publishSensorData(SensorData& data) {
if (xSemaphoreTake(mqttMutex, pdMS_TO_TICKS(100)) == pdTRUE) {
// Create JSON document
DynamicJsonDocument doc(1024);
doc["device_id"] = MQTT_CLIENT_ID;
doc["timestamp"] = data.timestamp;
doc["temperature"] = data.temperature;
doc["humidity"] = data.humidity;
doc["pressure"] = data.pressure;
doc["altitude"] = data.altitude;
// Serialize JSON
String jsonStr;
serializeJson(doc, jsonStr);
// Publish to topics
mqttClient.publish("embedded/sensors/temperature", String(data.temperature).c_str());
mqttClient.publish("embedded/sensors/humidity", String(data.humidity).c_str());
mqttClient.publish("embedded/sensors/pressure", String(data.pressure).c_str());
mqttClient.publish("embedded/sensors/combined", jsonStr.c_str());
xSemaphoreGive(mqttMutex);
}
}
void publishSystemStatus() {
if (xSemaphoreTake(mqttMutex, pdMS_TO_TICKS(100)) == pdTRUE) {
// Create JSON document
DynamicJsonDocument doc(1024);
doc["device_id"] = MQTT_CLIENT_ID;
doc["timestamp"] = millis();
doc["wifi_connected"] = systemStatus.wifiConnected;
doc["mqtt_connected"] = systemStatus.mqttConnected;
doc["sd_card_present"] = systemStatus.sdCardPresent;
doc["battery_level"] = systemStatus.batteryLevel;
doc["uptime"] = systemStatus.uptime;
doc["free_heap"] = systemStatus.freeHeap;
doc["cpu_temperature"] = systemStatus.cpuTemperature;
doc["last_sensor_read"] = systemStatus.lastSensorRead;
doc["last_mqtt_message"] = systemStatus.lastMQTTMessage;
// Serialize JSON
String jsonStr;
serializeJson(doc, jsonStr);
// Publish status
mqttClient.publish("embedded/status", jsonStr.c_str());
xSemaphoreGive(mqttMutex);
}
}
void handleControlCommand(ControlCommand& command) {
Serial.println("Processing control command: " + command.command);
if (command.command == "buzz") {
int duration = command.parameters.toInt();
if (duration == 0) duration = 1000;
alertUser(1, duration);
} else if (command.command == "led") {
bool state = (command.parameters == "on");
digitalWrite(LED_PIN, state ? HIGH : LOW);
} else if (command.command == "relay") {
bool state = (command.parameters == "on");
digitalWrite(RELAY_PIN, state ? HIGH : LOW);
} else if (command.command == "restart") {
Serial.println("Restarting device...");
logData("System restart requested");
vTaskDelay(pdMS_TO_TICKS(1000));
ESP.restart();
} else if (command.command == "sleep") {
int seconds = command.parameters.toInt();
if (seconds == 0) seconds = 10;
Serial.println("Going to sleep for " + String(seconds) + " seconds");
logData("Entering deep sleep for " + String(seconds) + " seconds");
enterDeepSleep(seconds);
} else if (command.command == "get_status") {
publishSystemStatus();
} else {
Serial.println("Unknown command: " + command.command);
logData("WARNING: Unknown control command: " + command.command);
}
command.processed = true;
}
void logData(String message) {
String logEntry = String(millis()) + ": " + message;
// Send to logger queue
if (xQueueSend(logDataQueue, &logEntry, pdMS_TO_TICKS(100)) != pdTRUE) {
Serial.println("Failed to send log message to queue");
}
}
void setupSensors() {
Serial.println("Setting up sensors...");
// Initialize DHT sensor
dhtSensor.begin();
// Initialize BMP280
if (!bmp280.begin(BMP280_ADDRESS_ALT)) {
Serial.println("Could not find BMP280 sensor!");
logData("ERROR: BMP280 sensor not found");
} else {
Serial.println("BMP280 sensor initialized");
logData("BMP280 sensor initialized");
}
Serial.println("Sensors setup completed");
}
void setupSDCard() {
Serial.println("Setting up SD card...");
if (SD.begin(SD_CS_PIN)) {
Serial.println("SD card initialized");
systemStatus.sdCardPresent = true;
logData("SD card initialized");
// Create log file if it doesn't exist
File logFile = SD.open("/log.txt", FILE_WRITE);
if (logFile) {
logFile.println("\n=== System Restart ===");
logFile.close();
}
} else {
Serial.println("SD card initialization failed");
systemStatus.sdCardPresent = false;
logData("ERROR: SD card initialization failed");
}
}
void setupRTC() {
Serial.println("Setting up RTC...");
if (rtc.begin()) {
if (rtc.lostPower()) {
Serial.println("RTC lost power, setting to compile time");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
Serial.println("RTC initialized");
logData("RTC initialized");
} else {
Serial.println("Couldn't find RTC");
logData("ERROR: RTC not found");
}
}
void writeLogToSD(String message) {
File logFile = SD.open("/log.txt", FILE_WRITE);
if (logFile) {
DateTime now = rtc.now();
logFile.print(now.timestamp(DateTime::TIMESTAMP_FULL));
logFile.print(": ");
logFile.println(message);
logFile.close();
}
}
void buttonISR() {
// Button press interrupt
static unsigned long lastInterrupt = 0;
unsigned long interruptTime = millis();
if (interruptTime - lastInterrupt > 200) { // Debounce
// Create manual capture command
ControlCommand command;
command.command = "capture";
command.parameters = "manual";
command.timestamp = interruptTime;
command.processed = false;
// Send to control task
xQueueSendFromISR(controlCommandQueue, &command, NULL);
// Alert user
alertUser(1, 100);
}
lastInterrupt = interruptTime;
}
void alertUser(int beeps, int duration) {
for (int i = 0; i < beeps; i++) {
tone(BUZZER_PIN, 1000, duration);
vTaskDelay(pdMS_TO_TICKS(duration * 2));
}
}
float getBatteryLevel() {
// Read battery voltage (assuming voltage divider)
int rawValue = analogRead(A0);
float voltage = rawValue * (3.3 / 4096.0) * 2.0; // Voltage divider factor
// Convert to percentage (assuming 3.0V to 4.2V range)
float percentage = ((voltage - 3.0) / 1.2) * 100.0;
percentage = constrain(percentage, 0.0, 100.0);
return percentage;
}
void enterDeepSleep(int seconds) {
// Configure wake-up sources
esp_sleep_enable_timer_wakeup(seconds * 1000000); // Convert to microseconds
esp_sleep_enable_ext0_wakeup(GPIO_NUM_0, 0); // Wake on button press
// Enter deep sleep
esp_deep_sleep_start();
}
void wakeFromDeepSleep() {
// This function is called after waking from deep sleep
Serial.println("Waking from deep sleep...");
// Reinitialize peripherals
setupSensors();
setupSDCard();
// Check wake-up reason
esp_sleep_wakeup_cause_t wakeup_reason = esp_sleep_get_wakeup_cause();
switch (wakeup_reason) {
case ESP_SLEEP_WAKEUP_TIMER:
Serial.println("Wakeup caused by timer");
break;
case ESP_SLEEP_WAKEUP_EXT0:
Serial.println("Wakeup caused by external signal (RTC GPIO)");
break;
default:
Serial.println("Wakeup was not caused by deep sleep");
break;
}
}
IoT Architektur
Schichtenmodell
graph TD
A[Physical Layer] --> B[Sensor/Actuator Layer]
B --> C[Edge Computing Layer]
C --> D[Network Layer]
D --> E[Cloud Layer]
E --> F[Application Layer]
A1[Sensors, Actuators] --> A
B1[Microcontrollers, Gateways] --> B
C1[Edge Processing, Analytics] --> C
D1[WiFi, LoRaWAN, 5G] --> D
E1[Cloud Services, Storage] --> E
F1[Web Apps, Mobile Apps] --> F
Embedded Systeme Vergleich
Mikrocontroller vs. Mikroprozessoren
| Eigenschaft | Mikrocontroller | Mikroprozessor |
|---|---|---|
| Integration | High (CPU + Peripherie) | Low (nur CPU) |
| Kosten | Niedrig | Mittel bis Hoch |
| Stromverbrauch | Sehr Niedrig | Mittel bis Hoch |
| Leistung | Begrenzt | Hoch |
| Speicher | Intern, begrenzt | Extern, flexibel |
| Anwendung | Embedded, IoT | General Purpose |
IoT Plattformen
| Plattform | Protokolle | Edge Computing | Cloud Integration | Lizenz |
|---|---|---|---|---|
| Arduino | WiFi, Ethernet | Begrenzt | Cloud Services | Open Source |
| Raspberry Pi | WiFi, Ethernet | Ja | Volle Integration | Open Source |
| ESP32 | WiFi, Bluetooth | Ja | MQTT, HTTP | Open Source |
| NVIDIA Jetson | WiFi, Ethernet | Ja | NVIDIA Cloud | Kommerziell |
Kommunikationsprotokolle
Wireless Protokolle
| Protokoll | Reichweite | Datenrate | Stromverbrauch | Anwendung |
|---|---|---|---|---|
| WiFi | 50-100m | 150-600 Mbps | Hoch | Indoor, High-Speed |
| Bluetooth | 10-100m | 1-3 Mbps | Mittel | Personal Area |
| LoRaWAN | 2-15km | 0.3-50 kbps | Sehr Niedrig | Long Range |
| Zigbee | 10-100m | 250 kbps | Niedrig | Mesh Networks |
IoT-Protokolle
| Protokoll | Typ | Overhead | QoS | Anwendung |
|---|---|---|---|---|
| MQTT | Publish/Subscribe | Niedrig | 3 Stufen | Echtzeit |
| CoAP | Request/Response | Sehr Niedrig | Kein | Constrained |
| HTTP/REST | Request/Response | Hoch | TCP | Web Integration |
| WebSocket | Full-Duplex | Mittel | TCP | Echtzeit |
Edge Computing Konzepte
Edge vs. Cloud Processing
| Aspekt | Edge Computing | Cloud Computing |
|---|---|---|
| Latenz | Millisekunden | Sekunden |
| Bandbreite | Reduziert | Hoch |
| Offline | Möglich | Nicht möglich |
| Skalierbarkeit | Begrenzt | Unbegrenzt |
| Kosten | Variabel | Predictable |
Edge Computing Anwendungen
- Prädiktive Wartung: Lokale Analyse von Sensordaten
- Video Analytics: Echtzeit-Objekterkennung
- Industrial IoT: Steuerung von Produktionsanlagen
- Smart Cities: Verkehrsanalyse und Steuerung
Vorteile und Nachteile
Vorteile von IoT & Embedded Systemen
- Automatisierung: Reduzierung manueller Arbeit
- Echtzeit-Überwachung: Sofortige Statusinformationen
- Effizienz: Optimierung von Prozessen
- Skalierbarkeit: Flexible Anpassung an Bedarf
- Kosteneinsparung: Reduzierung Betriebskosten
Nachteile
- Sicherheitsrisiken: Angriffsfläche für Hacker
- Komplexität: Integration und Wartung
- Abhängigkeit: Ausfall bei Netzwerkproblemen
- Datenschutz: Sammlung persönlicher Daten
- Kompatibilität: Unterschiedliche Standards
Häufige Prüfungsfragen
-
Was ist der Unterschied zwischen Mikrocontroller und Mikroprozessor? Mikrocontroller integrieren CPU, Speicher und Peripherie auf einem Chip, während Mikroprozessoren nur die CPU enthalten und externe Komponenten benötigen.
-
Erklären Sie Edge Computing! Edge Computing verarbeitet Daten lokal auf Geräten nahe der Datenquelle statt in der Cloud, um Latenz zu reduzieren und Bandbreite zu sparen.
-
Wann verwendet man welches IoT-Protokoll? MQTT für Echtzeit-Kommunikation, CoAP für ressourcenbeschränkte Geräte, HTTP/REST für Web-Integration, WebSocket für bidirektionale Kommunikation.
-
Was sind die Hauptanforderungen an Embedded Systeme? Zuverlässigkeit, Echtzeitfähigkeit, geringer Stromverbrauch, kostengünstige Produktion, lange Lebensdauer und Wartungsfreiheit.
Wichtigste Quellen
- https://www.arduino.cc/
- https://www.raspberrypi.org/
- https://mqtt.org/
- https://www.espressif.com/en/products/socs/esp32