Wednesday, February 8, 2017

Update from Farm-Team: Ideas for the main hub our gateway to the cloud

For our main hub we early on defined the following requirements/specifications:

The main hub operates as:
  • Central sensors (temperature, humidity, light intensity, pressure etc.). Sensors:
    • DHT22
    • BH1750
    • BMP180
    • Analog precipitation sensor
  • Wifi access point for the sensor nodes
  • MQTT broker also for the sensor nodes
  • MQTT/IBMIoT client to the cloud
  • Database/dataspool for measurement values
  • Remote administration console
Lets us first start with the main hub controller:
The general idea is connection the controller directly to the Raspberry Pi (Model B+)  via UART (serial).

We will be using the nanoESP board we used before. Again, this only a dev board built on the basis of a Arduino Nano board plus an ESP8266 board, which is sold by Conrad Electronics, an electronics retailer in Germany. On our board drawings and schematics you will see a Arduino Nano board connected to an ESP8266 board. Also instead of a analog precipitation sensor we are using a soil moisture sensor and the light intensity sensor on the drawing is not the identical one we are using.

Connecting BH1750 and BMP180 to the board: As we will be using two sensors that require I2C communication via the A4 and A5 pins on the Arduino we will be using a I2C multiplexer from Ardafruit (SCL/SDA). I found this tutorial to be very helpful. 
Example from tutorial (with two identical sensors)


Connecting the DHT22 sensor: This can be directly connected to a digital GPIO on the Arduino. Pretty straight forward: A lot of tutorials on the web for this step:

Example from tutorial (Arduino Nano & DHT22 sensor)

After connecting the precipitation sensor to A0 (see next illustration), we can now focus on connecting nanoESP board to our Raspberry Pi. For this step I recommend a look at this tutorial.
The tutorial explains how to connect via level shift converter or a voltage divider as the Raspberry Pi GPIO operate at a lower voltage. The easiest way though is to connect the Raspberry Pi to the Arduino Nano via USB cable as this saves you from needing further current regulation but also supplies the board with a regulated power source.

After the final step:

Final setup

Main hub controller schematics



The code

The code loops through all sensors and builds a json-String. This is the printed to serial.

 #include <Wire.h>  
 //Libraries  
 #include <DHT.h>  
 #include <BH1750.h>  
 #include <Adafruit_BMP085.h>  
 #define TCAADDR 0x70  
 //Constants  
 #define DHTPIN 2   // what pin we're connected to  
 #define DHTTYPE DHT22  // DHT 22 (AM2302)  
 DHT dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor for normal 16mhz Arduino  
 int sensorValue = 0;  
 int humidity;  
 int sensorPin = A0;  
 BH1750 lightMeter;  
 Adafruit_BMP085 bmp;  
 void tcaselect(uint8_t i) {  //function to switch I2C multiplexer
  if (i > 7) return;  
  Wire.beginTransmission(TCAADDR);  
  Wire.write(1 << i);  
  Wire.endTransmission();   
 }  
 void setup(void)   
 {  
  Serial.begin(19200);  
  //Serial.println("Sensor Test"); Serial.println("");  
  /* Initialise the 1st sensor */  
  tcaselect(2);  //switch to and start BH1750
  lightMeter.begin();  
 // if(!lightMeter.begin())  
 // {  
   /* There was a problem detecting the HMC5883 ... check your connections */  
 //  Serial.println("Ooops, no Lightmeter detected ... Check your wiring!");  
  //  while(1);  
 // }  
  delay(500);  
  /* Initialise the 2nd sensor */  
  tcaselect(6);  //switch to and start BMP180
  if(!bmp.begin())  
  {  
   /* There was a problem detecting the HMC5883 ... check your connections */  
   Serial.println("Ooops, no BMP detected ... Check your wiring!");  
   while(1);  
   dht.begin();  
  }  
 }  
 void loop(void)   
 {  
  tcaselect(2);  
  displaySensorDetails();  
  delay(500);  
  tcaselect(6);  
  displaySensorDetailsBMP();  
  delay(500);  
  displaySensorDetailsDHT();  
  delay(500);  
  displaySensorDetailsRain();  
  delay(1000);  
 }  
 void displaySensorDetails() {  
  uint16_t lux = lightMeter.readLightLevel();  
  Serial.print("{\"d\":{");  
  Serial.print("\"");  
  Serial.print("light");  
  Serial.print("\" : ");  
  Serial.print(lux);  
  Serial.print("}}");  
  Serial.println();  
  delay(1000);  
  }  
 void displaySensorDetailsBMP() {  
  Serial.print("{\"d\":{");  
  Serial.print("\"");  
  Serial.print("temperature1");  
  Serial.print("\" : ");  
  Serial.print(bmp.readTemperature());  
  Serial.print(", \"");  
  Serial.print("pressure");  
  Serial.print("\" : ");  
  Serial.print(bmp.readPressure());  
  Serial.print(", \"");  
  // Calculate altitude assuming 'standard' barometric  
  // pressure of 1013.25 millibar = 101325 Pascal  
  Serial.print("altitude");  
  Serial.print("\" : ");  
  Serial.print(bmp.readAltitude());  
  Serial.print(", \"");  
  Serial.print("calculatedpressureatsealevel");  
  Serial.print("\" : ");  
  Serial.print(bmp.readSealevelPressure());  
 // you can get a more precise measurement of altitude  
 // if you know the current sea level pressure which will  
 // vary with weather and such. If it is 1015 millibars  
 // that is equal to 101500 Pascals.  
  Serial.print(", \"");  
  Serial.print("realaltitude");  
  Serial.print("\" : ");  
  Serial.print(bmp.readAltitude(101500));  
  Serial.print("}}");  
  Serial.println();  
  //Serial.println();  
  delay(1000);  
 }  
 void displaySensorDetailsDHT() {  
   float h = dht.readHumidity(); //Luftfeuchte auslesen  
   float t = dht.readTemperature(); //Temperatur auslesen  
   // Prüfen ob eine gültige Zahl zurückgegeben wird. Wenn NaN (not a number) zurückgegeben wird, dann Fehler ausgeben.  
   if (isnan(t) || isnan(h))   
   {  
   Serial.println("DHT22 konnte nicht ausgelesen werden");  
   }   
   else  
   {  
   Serial.print("{\"d\":{");  
   Serial.print("\"");  
   Serial.print("humidity");  
   Serial.print("\" : ");  
   Serial.print(h);  
   Serial.print(", ");  
   Serial.print("\"");  
   Serial.print("temperature2");  
   Serial.print("\" : ");  
   Serial.print(t);  
   Serial.print("}}");  
   Serial.println();  
  }  
  }  
 void displaySensorDetailsRain() {  
  sensorValue = analogRead(sensorPin);  
  humidity = map (sensorValue, 250, 1024, 100, 0);  
  Serial.print("{\"d\":{");  
  Serial.print("\"");  
  Serial.print("rain");  
  Serial.print("\" : ");  
  Serial.print(humidity);  
  Serial.print("}}");  
  Serial.println();  
  }  

In our next blog entry we will describe how our Raspberry Pi is reading and handling the data it is getting from the Arduino board. 

Links:
https://learn.adafruit.com/adafruit-tca9548a-1-to-8-i2c-multiplexer-breakout/wiring-and-test
http://www.instructables.com/id/Raspberry-Pi-Arduino-Serial-Communication/
https://oscarliang.com/raspberry-pi-and-arduino-connected-serial-gpio/


No comments:

Post a Comment