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

Qua software gebruik ik de volgende 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

Populaire posts van deze blog

Meer over Sonoff Schakelaars

Zonneschermen

Smart meter