Arduino
Arduino Modules
Voor de sturing maak ik gebruik van Arduino modules, omdat deze overal verkrijgbaar zijn, goedkoop, en universeel inzetbaar.
Mijn standaard module bestaat uit:
- Arduino Mega: de 'grote' versie, met meer geheugen, meer aansluitingen, en meer rekenkracht. Dit is nodig omdat de ethernet module al wat in- en uitgangen inpikt, en ik wat ruimte nodig heb voor flexibiliteit. Qua prijs maakt het eigenlijk niet zoveel uit...
- W5100 ethernetshield, de 'oude' versie, deze wordt het best ondersteund door de bestaande libraries, en is qua mogelijkheden ruim voldoende voor mijn toepassingen.
- PoE (Power Over Ethernet) adapter, hiermee zorg ik ervoor dat de voeding over de ethernet kabel wordt aangevoerd.
- DC-DC converter: deze module zorgt ervoor dat de 12 volt voeding teruggebracht wordt naar 5 volt voor de arduino. Dit is efficiƫnter dan de eigen voeding van de Arduino te gebruiken.
Libraries
#include <Ethernet.h>// Ethernet.h library
#include "PubSubClient.h" //PubSubClient.h Library from Knolleary
#include <Adafruit_Sensor.h>
#include <DHT.h>
Dit zijn dus achtereenvolgens:
- de standaard ethernet library voor het Ethernetshield
- De PuBSubClient library voor MQTT
- De AdaFruit sensor library voor de sensors
- De DHT library voor de DHT temperatuur/vochtigheid sensor
MQTT
Voor de communicatie tussen modules en besturing gebruik ik het MQTT protocol. Dit is een 'Message Broker', kort gezegd een soort telefooncentrale voor digitale berichten. Je zet je berichten op een kanaal, en iedereen kan zich 'abonneren' op dit kanaal om deze berichten te zien. In de arduino code ziet dat er als volgt uit:
EthernetClient ethClient;
PubSubClient mqttClient;
mqttClient.setClient(ethClient);
mqttClient.setServer( "192.168.178.37", 1883); // or local broker
mqttClient.setCallback(callback);
Hiermee geef je dus aan dat je een client van het MQTT systeem wordt (de MQTT server is de 'broker'), en je geeft aan wat de afhandeling wordt van de binnenkomende berichten (callback); deze routine moet bestaan, en heet hier dus 'callback'.
Afhandeling MQTT berichten
Mijn callback routine ziet er als volgt uit:
void callback(char* topic, byte * payload, unsigned int length) {
char msgBuffer[20];
// I am only using one ascii character as command, so do not need to take an entire word as payload
// However, if you want to send full word commands, uncomment the next line and use for string comparison
payload[length] = '\0'; // terminate string with 0
String strPayload = String((char*)payload); // convert to string
int RelayPort;
int RelayValue;
if (strPayload[0] == 'R') {
// Relais commando
RelayPort = strPayload[1] - 48;
if (RelayPort > 16) RelayPort -= 3;
RelayValue = strPayload[2] - 48;
if (RelayValue == 40) {
digitalWrite(RelayPins[RelayPort], !digitalRead(RelayPins[RelayPort]));
} else {
digitalWrite(RelayPins[RelayPort], RelayValue);
}
report_state(RelayPort);
} else if (strPayload == "IP") {
// 'Show IP' commando
mqttClient.publish(topic_out, ip.c_str());// publish IP nr
}
else if (strPayload == "AON") {
// Alle relais aan
for (int i = 0 ; i < NumberOfRelays; i++) {
digitalWrite(RelayPins[i], 1);
report_state(i);
}
}
else if (strPayload == "AOF") {
// Alle relais uit
for (int i = 0 ; i < NumberOfRelays; i++) {
digitalWrite(RelayPins[i], 0);
report_state(i);
}
}
else if (strPayload == "STAT") {
// Status van alle relais
for (int thisPin = 0; thisPin < NumberOfRelays; thisPin++) {
report_state(thisPin);
}
}
else if (strPayload[0] == 'P') {
int PulseRelayPort = strPayload[1] - 48;
// Pulserelais aan
digitalWrite(PulseRelayPins[PulseRelayPort], !PulseRelayInitialStates[PulseRelayPort]);
String messageString = "P" + String(PulseRelayPort) + "1";
messageString.toCharArray(messageBuffer, messageString.length() + 1);
mqttClient.publish(topic_out_door, messageBuffer);
PulseActivityTimes[PulseRelayPort] = millis();
}
else if (strPayload[0] == 'L') {
analogWrite(PWMoutput, strPayload.substring(1).toInt());
}
else {
// Onbekend commando
mqttClient.publish(topic_out, "Unknown command");
}
} // callback
De volgende berichten worden dus afgehandeld:
- R<relaisnummer><status>, waarbij Relaisnummer het nummer van het relais is, beginnende bij 1, en status de waardes 0 (uit), 1 (aan) en X (omzetten) kan hebben.
- IP: geef het ip-adres terug
- AON: zet alle relais aan
- AOF: zet alle relais uit
- STAT: geef de status van alle relais
- P<relaisnummer>1: activeer pulsrelais
- L<waarde>: zet de pwm output naar de pwm waarde gegeven door <waarde>
Reacties
Een reactie posten