IoT-zonnesturing: Slimme energiemanagement met Arduino
Onderdelen en benodigdheden
| Arduino Mega 2560 | × | 1 |
| Ethernet Shield (Wiznet W5100) voor Arduino | × | 1 |
| SG90 Micro-servomotor | × | 2 |
| LDR (lichtgevoelige weerstand), 5 MΩ | × | 4 |
| DHT22 Temperatuur- en vochtigheidssensor | × | 1 |
| Mini zonnepaneel (ca. 115×85 mm, 1,6 W, max 6 V) | × | 1 |
| Weerstanden: 4× 330 Ω, 2× 10 Ω, 1× 220 Ω | × | 7 |
| 5 mm Rode LED (modusindicator) | × | 1 |
Apps en online services
- myDevices Cayenne – IoT-dashboardplatform (MQTT)
- Arduino IDE
Over dit project
Dit project presenteert een goedkope IoT-oplossing om een tweezijdige zonnesturing te monitoren en te besturen voor prestatie-evaluatie. Het systeem volgt de zon automatisch via LDR-sensoren of handmatig via het Cayenne-dashboard.
Systeemarchitectuur
Hardware-opstelling (zie schema's):
- Het zonnepaneel wordt vastgehouden door twee servomotoren:
- L-R servo (MG996R) op PWM-pin 5 – draait om de verticale as (Oost/West).
- U-D servo (SG90) op PWM-pin 6 – draait om de horizontale as (Zuid/Noord).
- Vier LDR-sensoren (GL5528) in de hoeken van het paneel, aangesloten op analoge pinnen A0–A3 via spanningsdelercircuits met 330 Ω seriesweerstanden.
- DHT22 sensor op digitale pin 2 voor temperatuur (−40 tot 80 °C, ±0,5 °C) en vochtigheid (0–100 %, ±2 %).
- PV-spanning en -stroom worden gemeten via een spanningsdeler met twee 10 Ω weerstanden in serie, uitgelezen op A4.
- Een rode LED op pin 3 toont de modus: uit = handmatig, aan = automatisch.
- De Arduino Mega communiceert via de Ethernet Shield (W5100) over MQTT met de Cayenne-cloud.
Software-ontwerp
a. Arduino IDE
De code wordt geschreven in C/C++ en geüpload via USB. De Mega voert alle embedded logica uit.
b. myDevices Cayenne (MQTT)
Cayenne gebruikt het MQTT-protocol (publish/subscribe over TCP/IP). Na registratie krijg je MQTT-credentials (username, password, client ID) die in de sketch worden ingevuld. Widgets op het dashboard koppelen aan virtuele kanalen (0–31) voor sensoren (CAYENNE_OUT) en actuatoren (CAYENNE_IN).
c. Embedded software-logica
Twee bedrijsmodi:
- Handmatig: De gebruiker stuurt de servohoeken via slider-widgets op het dashboard. De Arduino roept
Cayenne.loop()aan om zowel actuator-commando's op te halen als sensordata te verzenden. - Automatisch: De Arduino leest de vier LDR-waarden, berekent gemiddelden voor links/rechts en boven/onder, en stuurt de servomotoren aan tot het verschil binnen een drempel (±10) valt. Ook hier loopt
Cayenne.loop()voor data-uitlezing.
Algoritme (automatische modus):
- Horizontale as (L-R): vergelijk gemiddelde van linker LDR's met rechter LDR's. Links meer licht → draai kloksgewijs (CW); rechts meer licht → tegen de klok in (CCW). Stop bij verschil ≤ 10.
- Verticale as (U-D): vergelijk gemiddelde van bovenste LDR's met onderste. Boven meer licht → CW; onder meer licht → CCW. Stop bij verschil ≤ 10.
d. IoT-monitoringapplicatie opbouwen in Cayenne
- Account aanmaken op cayenne.mydevices.com.
- "Bring Your Own Things" selecteren → MQTT-credentials kopiëren naar de sketch.
- Code compileren, uploaden, Serial Monitor openen voor connectielog.
- Widgets toevoegen per sensor/actuator:
- Value-widget voor LDR's, spanning, stroom, vermogen, temperatuur, vochtigheid.
- Button-widget (kanaal 8) voor moduswissel.
- Slider-widget (kanalen 6 & 7) voor servohoeken in handmatige modus.
- Grafieken bekijken via het grafiek-icoon per widget.
e. Waarschuwingen (Alerts)
In Cayenne kun je triggers instellen: bijv. "als temperatuur > 50 °C → stuur e-mail/SMS". Dit werkt voor elke sensordata die naar het dashboard wordt gestuurd.
Prototype
De prototype bestaat uit het zonnepaneel gemonteerd op de U-D servo (één kant) en een lager (andere kant) voor vrije rotatie. De LDR's zitten in holle cylinders in de hoeken: als het paneel niet loodrecht op de zon staat, valt er schaduw op minimaal één LDR, wat het verschil in lichtintensiteit creëert dat het besturingsalgoritme corrigeert.
Resultaten en gedetailleerde analyse: Springer-paper
Code: Embedded software voor Arduino Mega
/***************************************************************
* PROJECT: IoT based solar tracker system / the embedded software
* Aboubakr El Hammoumi / aboubakr.elhammoumi@usmba.ac.ma
***************************************************************/
#define CAYENNE_PRINT Serial
#include <CayenneMQTTEthernet.h>
#include <Servo.h>
#include <DHT.h>
#define DHTTYPE DHT22
#define DHTPIN 2
DHT dht(DHTPIN, DHTTYPE);
// MQTT credentials (vervang door eigen waarden uit Cayenne Dashboard)
char username[] = "498d2d00-afe2-11ea-883c-638d8ce4c23d";
char password[] = "ab4a8f92d94033c01f6e18ce1d8a84d8c304c9c4";
char clientID[] = "17798a40-b968-11ea-93bf-d33a96695544";
Servo servo_x; // up-down (pin 5)
int servoh = 0, servohLimitHigh = 170, servohLimitLow = 10;
Servo servo_z; // left-right (pin 6)
int servov = 0, servovLimitHigh = 170, servovLimitLow = 10;
int topl, topr, botl, botr;
int threshold_value = 10;
float Vout;
void setup() {
Serial.begin(9600);
Cayenne.begin(username, password, clientID);
servo_x.attach(5);
servo_z.attach(6);
dht.begin();
pinMode(3, OUTPUT);
digitalWrite(3, LOW); // start in handmatige modus
}
void loop() {
// Lees LDR's (let op: pin A4/A5 worden hier voor botl/botr gebruikt)
topr = analogRead(A2);
topl = analogRead(A3);
botl = analogRead(A4);
botr = analogRead(A5);
// PV-spanning meetpunt op A1
Vout = (analogRead(A1) * 5.0) / 1023.0;
Serial.println("Manual-mode");
Cayenne.loop(); // altijd data versturen/ontvangen
if (digitalRead(3) == HIGH) { // Automatische modus
Serial.println("Automatic-mode");
servoh = servo_x.read();
servov = servo_z.read();
int avgtop = (topr + topl) / 2;
int avgbot = (botr + botl) / 2;
int avgright = (topr + botr) / 2;
int avgleft = (topl + botl) / 2;
int diffhori = avgtop - avgbot; // verticale as (U-D servo)
int diffverti = avgleft - avgright; // horizontale as (L-R servo)
// --- Horizontale tracking (servo_x, pin 5) ---
if (abs(diffhori) <= threshold_value) {
servo_x.write(servoh); // stop
} else {
if (diffhori > threshold_value) { // boven meer licht → CW
servo_x.write(servoh - 2);
if (servoh > servohLimitHigh) servoh = servohLimitHigh;
delay(10);
} else { // onder meer licht → CCW
servo_x.write(servoh + 2);
if (servoh < servohLimitLow) servoh = servohLimitLow;
delay(10);
}
}
// --- Verticale tracking (servo_z, pin 6) ---
if (abs(diffverti) <= threshold_value) {
servo_z.write(servov); // stop
} else {
if (diffverti > threshold_value) { // links meer licht → CW
servo_z.write(servov - 2);
if (servov > servovLimitHigh) servov = servovLimitHigh;
delay(10);
} else { // rechts meer licht → CCW
servo_z.write(servov + 2);
if (servov < servovLimitLow) servov = servovLimitLow;
delay(10);
}
}
}
}
// ====== CAYENNE CALLBACKS ======
// Kanaal 8: Modusknop (Button widget) → LED pin 3
CAYENNE_IN(8) {
int value = getValue.asInt();
CAYENNE_LOG("Channel %d, pin %d, value %d", 8, 3, value);
digitalWrite(3, value);
}
// Kanaal 7: U-D servo (slider) – alleen in handmatige modus
CAYENNE_IN(7) {
if (digitalRead(3) == HIGH) { /* Auto: negeren */ }
else {
servo_x.write(getValue.asDouble() * 180.0);
}
}
// Kanaal 6: L-R servo (slider) – alleen in handmatige modus
CAYENNE_IN(6) {
if (digitalRead(3) == HIGH) { /* Auto: negeren */ }
else {
servo_z.write(getValue.asDouble() * 180.0);
}
}
// Sensor-uitlezing naar Cayenne (virtualWrite)
CAYENNE_OUT(0) { // Stroom (A)
float current = Vout / 10.0;
Cayenne.virtualWrite(0, current);
Serial.print("Current: "); Serial.println(current);
}
CAYENNE_OUT(1) { // Spanning (V)
float voltage = Vout * 2.0;
Cayenne.virtualWrite(1, voltage);
Serial.print("Voltage: "); Serial.println(voltage);
}
CAYENNE_OUT(2) { Cayenne.virtualWrite(2, topr); } // LDR Top-Right
CAYENNE_OUT(3) { Cayenne.virtualWrite(3, topl); } // LDR Top-Left
CAYENNE_OUT(4) { Cayenne.virtualWrite(4, botl); } // LDR Bot-Left
CAYENNE_OUT(5) { Cayenne.virtualWrite(5, botr); } // LDR Bot-Right
CAYENNE_OUT(10) { // Vermogen (W)
float power = (Vout * 2.0 * Vout) / 10.0;
Cayenne.virtualWrite(10, power);
Serial.print("Power: "); Serial.println(power);
}
CAYENNE_OUT(11) { // Temperatuur (°C)
float t = dht.readTemperature();
Cayenne.virtualWrite(11, t, TYPE_TEMPERATURE, UNIT_CELSIUS);
Serial.print("Temperature: "); Serial.println(t);
}
CAYENNE_OUT(12) { // Vochtigheid (%)
float h = dht.readHumidity();
Cayenne.virtualWrite(12, h);
Serial.print("Humidity: "); Serial.println(h);
}
Schema's
De Fritzing-schema's tonen de complete bedrading van LDR-spanningsdelers, servo-aansluitingen, DHT22, PV-meetcircuit en Ethernet Shield op de Arduino Mega.
Belangrijke opmerkingen
- Zorg dat de Ethernet Shield via RJ45 met internet verbonden is (router of direct met PC).
- De MQTT-credentials in de code zijn voorbeelden – genereer eigen credentials in Cayenne.
- De LDR-pin-toewijzing in de code (A2–A5) moet overeenkomen met de hardware.
- De drempelwaarde (±10) en servostappen (2°) zijn instelbaar voor stabiliteit/snelheid.
- Voor productiegebruik: voeg watchdog-timer, foutafhandeling en veilige stroomvoorziening toe.
Productieproces
- Zonnetracker V2.0 – Geavanceerd DIY Zonnepaneel Volgsysteem
- Industriële IoT Benutten voor Groei: Verbeyond Kostenbesparing
- Wat Drijft IoT-praktijkers? Inzichten van Industriële Leiders
- 10 miljoen apparaten verbinden: Bosch IoT Suite's mijlpaal-groei
- Blockchain voor het Internet of Things: Veilige, gedecentraliseerde data-uitwisseling ontgrendelen
- De IoT-landschap Beveiligen: Belangrijkste Bedreigingen en Strategische Oplossingen – Deel 2
- IoT-beveiliging Toekomstbestendig Maken: Expert Strategieën voor een Veiligere Verbonden Wereld
- Investeren in het Internet of Things: Groei en Waarde Ontgrendelen
- De Ware Evolutie van het Internet of Things Traceren
- IoT: De Datagolf Meesteren voor Zakelijke Transformatie
- 5 kernuitdagingen voor het Internet of Things vandaag