Internet of Things/Arduino node

Uit Lab
Naar navigatie springen Naar zoeken springen

Breadboard schakeling

Arduino breadboard

NB: door op een tekening te klikken krijg je een grotere versie.

Als je twijfelt over een aansluiting, raadpleeg dan het schema eronder.

Op het breadboard zijn de volgende deelschakelingen geplaatst:

  • een drukknopschakeling met output naar D2
    • deze bestaat uit een drukknop, aan de ene kant verbonden aan 5V, aan de andere kant via een "pull down weerstand" van 10 kOhm aan 0V.
  • een drukknopschakeling met outout naar P3
  • een LDR-schakeling met outut naar A0
    • de LDR is onderdeel van een spanningsdeler, om de variabele weerstand om te zetten in een variabele spanning
  • een LED-schakeling aangestuurd door output D5
    • de LED staat in serie met een weerstand van 220 Ohm, om de stroom door de LED (en door de Arduino-output) te beperken.
  • een LED-schakeling aangestuurd door output D6
  • een temperatuursensor met output naar A1

Schema

Arduino schema

Software: test van de hardware

De hardware en software voor een IoT-node vormen een complexe keten. Voor een goede werking moet elke schakel van de keten goed functioneren. Het is dan handig om de verschillende onderdelen van de keten afzonderlijk te kunnen controleren.

  • testen van de hardware-schakeling
  • testen van de internet-verbinding
  • testen van de MQTT-server
  • testen van de MQTT-server-verbinding

Voor het testen is het nodig om de tekst-uitvoer van de Arduino zichtbaar te maken via de Seriële Monitor. De Arduino stuurt deze uitvoer via de USB-verbinding naar de host-computer (waarmee je de software voor de Arduino ontwikkelt). De Seriële Monitor start je op via Hulpmiddelen->Seriële Monitor. Het opstarten van de Seriële Monitor resulteert in een reset van de Arduino.

Met de onderstaande software kun je de hardware testen:

Deze software verbindt de schakelaars met de LEDs en met de sensoren:

  • indrukken van button 0 resulteert in het branden van LED 0, en de weergave van de sensor op A0 via

Software

De meet recente versie van de software is te vinden op GitHub: https://github.com/eelcodijkstra/iot2016/blob/master/arduinonode.ino

De software moet op de volgende punten aangepast worden aan de eigen situatie:

  • het MAC-adres van de Ethernet-shield moet juist ingevuld worden; deze gegevens staan meestal op het Ethernet shield;
  • het adres van de MQTT-broker moet aangepast worden aan de eigen broker.
/*
 * test a combination of JSON, MQTT over Arduino-Ethernet
 * simple sensor: button
 * simple actuator: LED
 */

#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>

// i/o pin map
const int led0 = 5;
const int button0 = 2;
const int button1 = 3;
// analog sensor on A0

// Ethernet: define MAC address of Ethernet shield
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {0x90, 0xA2, 0xDA, 0x00, 0x4D, 0x61};
EthernetClient ethClient;

// PubSub (MQTT)
const char* mqttServer = "mqttbroker";
// alternative: IPAddress mqttServer(172, 16, 0, 2);
const int mqttPort = 1883;

PubSubClient client(ethClient);

String nodeID;
String sensorTopic;
String actuatorTopic;

long sensor1Timer = 0;
long sensor1Period = 50000; // in millisecs

// JSON

void sensor0Publish() {
  StaticJsonBuffer<200> jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  String msg;
  root["id"] = nodeID;
  root["button0"] = digitalRead(button0);
  root["button1"] = digitalRead(button1);
  root["localtime"] = millis();
  root.printTo(msg);
  Serial.println(msg);
  client.publish(sensorTopic.c_str(), msg.c_str());
}

void sensor1Publish() {
  StaticJsonBuffer<200> jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  String msg;
  root["id"] = nodeID;
  root["sensor0"] = analogRead(A0);
  delay(1);
  root["sensor1"] = analogRead(A1);
  root["localtime"] = millis();
  root.printTo(msg);
  Serial.println(msg);
  client.publish(sensorTopic.c_str(), msg.c_str());
}

void networkSetup() {
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    for (;;)
      ;
  }
  // print your local IP address:
  Serial.print("My IP address: ");
  Serial.println(Ethernet.localIP());
}

void mqttCallback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  if (strcmp(topic, actuatorTopic.c_str())==0) {
    Serial.println("actuator message received");
    StaticJsonBuffer<200> jsonBuffer;
    JsonObject& root = jsonBuffer.parseObject((char*) payload);
    if (root.success()) {
      if (root.containsKey("led0")) {
        digitalWrite(led0, root["led0"]);
      }
    }
  }
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    String clientID = "IoTClient-" + nodeID;
    if (client.connect(clientID.c_str())) {
      Serial.println("connected");

      client.subscribe(actuatorTopic.c_str());
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  pinMode(led0, OUTPUT);
  pinMode(button0, INPUT);
  //analogReference(INTERNAL); //1.1V
  Serial.begin(9600);

  networkSetup();
  nodeID = String(mac[4] * 256 + mac[5], HEX);
  // MQTT init:
  sensorTopic = "node/" + nodeID + "/sensors";
  actuatorTopic = "node/" + nodeID + "/actuators";
  client.setServer(mqttServer, mqttPort);
  client.setCallback(mqttCallback);
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  if (digitalRead(button0)) {
    sensor0Publish();
    delay(200); // limit button repetition rate
  }

  if (millis() >= sensor1Timer) {
    sensor1Publish();
    sensor1Timer = sensor1Timer + sensor1Period;
  }
}