Internet of Things/ESP8266 node: verschil tussen versies

Uit Lab
Naar navigatie springen Naar zoeken springen
(Nieuwe pagina aangemaakt met '== Software == Voor de meest actuele versie van deze software, zie: https://github.com/eelcodijkstra/iot2016/blob/master/esp8266node.ino <syntaxhighlight lang="cp...')
 
 
(6 tussenliggende versies door dezelfde gebruiker niet weergegeven)
Regel 1: Regel 1:
== ESP8266 als IoT-node: WiFi ==
De ESP8266-module bevat een microcontroller met een WiFi-radio. Er zijn verschillende bordjes met deze module, met verschillende configuraties. Enkele voorbeelden van dergelijke bordjes:
* NodeMCU (bij voorkeur: V1)
* WeMOS D1 Mini (R2; of Mini PRO)
* Adafruit Feather Huzzah (https://www.adafruit.com/product/2821)
De bordjes verschillen onder andere door het USB-serie-IC dat gebruikt wordt (CP2104 (beter), CH340 (bruikbaar)), en door de hoeveelheid Flash-geheugen die beschikbaar is. Dit Flash-geheugen kan gebruikt worden als programma-geheugen en als lokaal filesysteem.
De meeste van deze bordjes gebruik je door deze op een breadboard te plaatsen, waarop je ook andere onderdelen (sensoren, actuatoren als LEDs) kunt plaatsen.
De ESP8266 werkt op 3.3V, in plaats van de 5V van de Arduino UNO. Bij de keuze van de onderdelen die je aansluit moet je hiermee rekening houden.
* veel van de recentere hardware werkt ook op 3.3V, zoals de Raspberry Pi en de micro:bit.
Je kunt de ESP8266 op verschillende manieren programmeren. Hieronder gebruiken we de Arduino-IDE.
* hiervoor moet het ESP8266-board geïnstalleerd zijn, in de Voorkeuren (preferences) moet je volgende URL toevoegen:
** <code>http://arduino.esp8266.com/versions/2.3.0/package_esp8266com_index.json</code>
* selecteren van het juiste bord: Hulpmiddelen->Board
* selecteren van de juiste USB-serie-poort: Hulpmiddelen->Poort
Voor sommige van deze ESP8266-borden heb je een speciale USB-driver nodig.
=== Naamgeving van de pinnen ===
Je hebt te maken met twee soorten aansluitingen en de bijbehorende namen:
* de aansluitingen van de ESP8266-module (GPIO pins);
* de aansluitingen van het bordje (NodeMCU, D1 Mini, Feather Huzzah, enz.)
De namen van de pinnen in de Arduino-software zijn gebaseerd op de aansluitingen van de ESP8266-module. je moet dan zelf nagaan hoe deze aansluitingen verbonden zijn met de aansluitingen van je bordje.
* zie: https://github.com/esp8266/Arduino/blob/master/doc/reference.md
* voorbeeld: (Feather Huzzah ESP8266): https://learn.adafruit.com/adafruit-feather-huzzah-esp8266/pinouts
De ESP8266 heeft maar één analoge ingang: deze geef je aan met <code>A0</code>.
Naast de genoemde pinnen kun je gebruik maken van de ingebouwde LED: <code>BUILTIN_LED</code>.
== Software ==
== Software ==


Voor de meest actuele versie van deze software, zie: https://github.com/eelcodijkstra/iot2016/blob/master/esp8266node.ino
Voor de meest actuele versie van deze software, zie: https://github.com/eelcodijkstra/iot2016/blob/master/esp8266node.ino
Deze versie heeft voorzieningen voor:
* 1 LED
* 1 buttonschakelaar
* 1 analoge input
Een volgende versie heeft voorzieningen voor een extra LED en een extra button-schakelaar.


<syntaxhighlight lang="cpp>
<syntaxhighlight lang="cpp>

Huidige versie van 8 jan 2017 om 21:24

ESP8266 als IoT-node: WiFi

De ESP8266-module bevat een microcontroller met een WiFi-radio. Er zijn verschillende bordjes met deze module, met verschillende configuraties. Enkele voorbeelden van dergelijke bordjes:

De bordjes verschillen onder andere door het USB-serie-IC dat gebruikt wordt (CP2104 (beter), CH340 (bruikbaar)), en door de hoeveelheid Flash-geheugen die beschikbaar is. Dit Flash-geheugen kan gebruikt worden als programma-geheugen en als lokaal filesysteem.

De meeste van deze bordjes gebruik je door deze op een breadboard te plaatsen, waarop je ook andere onderdelen (sensoren, actuatoren als LEDs) kunt plaatsen.

De ESP8266 werkt op 3.3V, in plaats van de 5V van de Arduino UNO. Bij de keuze van de onderdelen die je aansluit moet je hiermee rekening houden.

  • veel van de recentere hardware werkt ook op 3.3V, zoals de Raspberry Pi en de micro:bit.

Je kunt de ESP8266 op verschillende manieren programmeren. Hieronder gebruiken we de Arduino-IDE.

Voor sommige van deze ESP8266-borden heb je een speciale USB-driver nodig.

Naamgeving van de pinnen

Je hebt te maken met twee soorten aansluitingen en de bijbehorende namen:

  • de aansluitingen van de ESP8266-module (GPIO pins);
  • de aansluitingen van het bordje (NodeMCU, D1 Mini, Feather Huzzah, enz.)

De namen van de pinnen in de Arduino-software zijn gebaseerd op de aansluitingen van de ESP8266-module. je moet dan zelf nagaan hoe deze aansluitingen verbonden zijn met de aansluitingen van je bordje.

De ESP8266 heeft maar één analoge ingang: deze geef je aan met A0.

Naast de genoemde pinnen kun je gebruik maken van de ingebouwde LED: BUILTIN_LED.

Software

Voor de meest actuele versie van deze software, zie: https://github.com/eelcodijkstra/iot2016/blob/master/esp8266node.ino

Deze versie heeft voorzieningen voor:

  • 1 LED
  • 1 buttonschakelaar
  • 1 analoge input

Een volgende versie heeft voorzieningen voor een extra LED en een extra button-schakelaar.

/*
 * test a combination of JSON, MQTT over ESP8266-WiFi
 * simple sensor: button
 * simple actuator: LED
 */

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>

// i/o pin map
const int led0 = D5;
const int button0 = D4;

// WiFi
const char* ssid     = "networkname";
const char* password = "password";
unsigned char mac[6];
WiFiClient espClient;

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

PubSubClient client(espClient);

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["sensor0"] = digitalRead(button0);
  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["sensor1"] = analogRead(A0);
  root["localtime"] = millis();
  root.printTo(msg);
  Serial.println(msg);
  client.publish(sensorTopic.c_str(), msg.c_str());
}

void networkSetup() {
  digitalWrite(BUILTIN_LED, LOW); // active low: LED ON
  delay(100);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.print(ssid);

  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
 
  Serial.println();
  Serial.print("WiFi connected, IP address: ");  
  Serial.println(WiFi.localIP());
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  for (int i = 0; i < 6; i++) {
    Serial.print(mac[i], HEX);
  }
  Serial.println();

  digitalWrite(BUILTIN_LED, HIGH); // LED off
}

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(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  pinMode(led0, OUTPUT);
  pinMode(button0, INPUT);
  Serial.begin(115200);
  
  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;
  }
}