Sunday, December 4, 2016

Update from Farm-Team: Prototyping Update #1: sensor with nanoESP

Prototyping Update #1

Added visualisation on iobroker with values supplied over MQTT


Summary

  • I had a NanoESP (aka. Pretzel-) board, which is basically a Arduino Nano board with integrated ESP8266 chip sold in Conrad Electronics (German retailer)
  • Built a prototype of the sensor node using the NanoESP basically to prove our concept at an early stage
  • The board would be reading Analog input of a connected hygrometer
  • We powered the setup with a 5V 5 Ah portable usb powerbank (pink device on the left)
  • The (pink) powerbank powers the board via usb

  • The board connects to an AP and the data is published over UDP
  • Afterwards we started sending the data over MQTT whicht is supported by the nanoESP board. 

Shopping

  • Hygrometers 3.3 - 5 V operartional current
Already available: NanoESP board, powerbank, breadboard, etc.

Testing

  • Measuring  analog (moisture) value every 30 seconds
  • Sending data over udp to connected devices
  • Sending data over MQTT
  • Battery lasts about 16 hours


Sensor testing and calibration


Used free Android UDP Receiver App to get values while connected to the device 

Code with data transmission over UDP


/*
UDP transmission
*/

#define DEBUG true

#include <SoftwareSerial.h>
#include <NanoESP.h>
SoftwareSerial esp8266(11, 12); // RX, TX void setup() { Serial.begin(19200); esp8266.begin(19200); //Long Timeout needed for RST and settings of WLAN-Data esp8266.setTimeout(5000); if (sendCom("AT+RST", "ready")) { debug("RESET OK"); } if (configAP()) { debug("AP ready"); } if (configUDP()) { debug("UDP ready"); } //shorter Timeout for faster wrong UPD-Comands handling esp8266.setTimeout(1000); } void loop() { if (esp8266.available()) { int sensorValue = analogRead(A0); Serial.println(sensorValue); delay(100); /* constraint function will limit the values we get so we can work better with map * since I only need values in the bottom limit of 300, will make it the outer limit and 1023 the other limit */ sensorValue = constrain (sensorValue, 300,1023); // print the values returned by the sensor //Serial.println(sensorValue); // create a map with the values // You can think we have the 100% to 300 and 0 % to 1023 wrong, but no ! // 300 - or 100 % - is the target value for moisture value in the soil // 0% of humidity - or moisture - is when the soil is dry int moisture = map (sensorValue, 300, 1023, 100, 0); String output = String(moisture) + "%"; Serial.println(output); sendUDP(output); } } //-----------------------------------------Config ESP8266------------------------------------ boolean configAP() { boolean succes = true; succes &= (sendCom("AT+CWMODE=2", "OK")); succes &= (sendCom("AT+CWSAP=\"NanoESP\",\"\",5,0", "OK")); return succes; } boolean configUDP() { boolean succes = true; succes &= (sendCom("AT+CIPMODE=0", "OK")); succes &= (sendCom("AT+CIPMUX=0", "OK")); succes &= sendCom("AT+CIPSTART=\"UDP\",\"192.168.4.255\",55005,55006", "OK"); //UDP Bidirectional and Broadcast return succes; } //-----------------------------------------------Controll ESP----------------------------------------------------- boolean sendUDP(String Msg) { boolean succes = true; succes &= sendCom("AT+CIPSEND=" + String(Msg.length() + 2), ">"); //+",\"192.168.4.2\",90", ">"); if (succes) { succes &= sendCom(Msg, "OK"); } return succes; } boolean sendCom(String command, char respond[]) { esp8266.println(command); if (esp8266.findUntil(respond, "ERROR")) { return true; } else { debug("ESP SEND ERROR: " + command); return false; } } String sendCom(String command) { esp8266.println(command); return esp8266.readString(); } //-------------------------------------------------Debug Functions------------------------------------------------------ void serialDebug() { while (true) { if (esp8266.available()) Serial.write(esp8266.read()); if (Serial.available()) esp8266.write(Serial.read()); } } void debug(String Msg) { if (DEBUG) { Serial.println(Msg); }
}


Code #2 with MQTT instead of UDP


#include <NanoESP.h>
#include <NanoESP_MQTT.h>
#include <SoftwareSerial.h>

#define SSID "XXXX"
#define PASSWORD "xxxxxxxxxxxx"
#define LED_WLAN 13
#define DEBUG true
#define mqttBroker "iot.eclipse.org"
#define mqttClientId "NanoESP"
#define mqttPort 1183

NanoESP nanoesp = NanoESP();
NanoESP_MQTT mqtt = NanoESP_MQTT(nanoesp);

void setup() {
  Serial.begin(19200);

  nanoesp.init();
  nanoesp.configWifi(STATION, SSID, PASSWORD);

  if (nanoesp.wifiConnected()) {
    Serial.println ("Wifi connected");
    digitalWrite(LED_WLAN, HIGH);
  }
  else {
    Serial.println ("Wifi not Connected");
  }
  //Print IP in Terminal
  Serial.println (nanoesp.getIp());
  if (mqtt.connect(0, mqttBroker, 1883, "NanoESP")) {
  Serial.println ("MQTT connected");
  if (mqtt.publish(0, "test", "Sensor node initial connection", 1, false)) Serial.println ("Published to test");
  if (mqtt.subscribe(0, "test", 1)) Serial.println ("Subscribed to test"); 
  if (mqtt.subscribe(0, "moisture", 1)) Serial.println ("Subscribed to moisture");
  }
}

void loop() {
  delay(random(10000));
  int id, len;
  int sensorValue = analogRead(A0); 
  sensorValue = constrain (sensorValue, 300,1023);
  int moisture = map (sensorValue, 300, 1023, 100, 0);

  if (mqtt.ping(0)) {
    Serial.println("MQTT ok comencing...");
    } else {
      //connect
      Serial.println("Setting up MQTT connection");
      mqttConnect();
    }
        
  if (nanoesp.recvData(id, len)) {
    String topic, value;
    if (mqtt.recvMQTT(id, len, topic, value)) {
      Serial.println ("New Message:\nTopic=" + topic + " Value=" + value);
    }
  } 
  mqtt.publish(0, "moisture", String(moisture));
  Serial.println(moisture);
  //if (mqtt.disconnect(0)) Serial.println("MQTT disconnected");
}

//-----------------------------------mqtt connection

void mqttConnect() {
  
  if (mqtt.connect(0, mqttBroker, 1883, "NanoESP")) {
    Serial.println ("MQTT connected");
    if (mqtt.publish(0, "test", "Sensor node reconnected", 1, false)) Serial.println ("Published to test");
    if (mqtt.subscribe(0, "test", 1)) Serial.println ("Subscribed to test");
    if (mqtt.subscribe(0, "moisture", 1)) Serial.println ("Subscribed to moisture");

    //if (MQTT_Unsubscribe(0, "test")) debug("Unsubscribed from test");
    //if (MQTT_Ping(0)) debug("Ping send ");
    //if (MQTT_Disconnect(0)) debug("Disconnect");
  }
}