Monday, January 30, 2017

Update from Farm-Team: Rethinking node controller boards


As we have been researching and searching for projects that are similar to our complete setup we found many tutorials that used the esp8266 chip as the main controller. This caught our attention as we had written before about communication errors between the Arduino and ESP8266 boards. We bought a nodeMCU devkit board (1.0) to test and play around. The board is basically a ESP8266 (12 E or F) with an integrated USB interface, two capacitors, voltage regulator and IO configurations.

We built another prototype with the NodeMCU board and ordered ESP8266 (ESP-12F) chips to built a prototype with a standalone device.




After receiving the ESP-12 chip I soldered it to a adapter to make it more breadbroad friendly. The ESP-12 needs a regulated 3.3 V source. We used a breadboard power supply at the beginning.


To write to the chip GPIO 15 and GPIO 0 have to be connected to GND.

The tricky part was connecting the analog output hygrometer to the analog input of the ESP-12 board. The analog out provides a 0 to 3.3v current (when getting 100 to 0 % moisture respectively). The analog input of the ESP8266 can read between 0 - 1V so we need a voltage divider to get the analog output to give out a current with this range..





Links:
https://learn.sparkfun.com/tutorials/voltage-dividers
https://raw.githubusercontent.com/nodemcu/nodemcu-devkit/master/Documents/NODEMCU_DEVKIT_SCH.png
https://cdn.sparkfun.com/r/600-600/assets/4/0/3/a/e/511948ffce395f7f47000000.png

Friday, January 20, 2017

Update from Farm-Team: Prototyping Update #3: Building an independent solar battery circuit

Power system shopping

Bought:

  • AMS117 LDOs(step down 3.3V converters)
  • 5 V step up voltage booster
  • TP-4056 Lithium Ion charge controller
  • 6V 200mA solar module
  • 5V 81 mA solar module
  • 3.6V 800 mAh NiMh battery
  • 3.7V 186500 LiIon battery
  • Z-Diodes, resistors, capacitors and LEDs

Basic power consumption (estimates built on data sheets of modules):

Sensor node:
Arduino Pro Mini 3.3V  1~5mA
ESP8266 0.01~170mA
Hygrometer 8mA


NiMh battery tests:


Connected 5 V solar panel to battery with Z-Diode to battery and the battery than directly into the RAW input of the Arduino board. I used 3.6V (3x1.2V) NiMh battery.



In the picture is a nodeMCU connected to the hygrometer instead of the Arduino Pro Mini. More in the next article.




LiIon battery tests:


Connected LiIon charge controller (TP-4056). to solar panel then to battery and charge regulator (AMS117 or other step down regulator, hasn't arrived yet). The charge controller keeps a steady 4.2V (full LiIon.


In this picture, yes again, cheating with a nodeMCU. The above drawing is very similar nodeMCU development board.


Soon to follow: results from tests.

Links:
http://www.home-automation-community.com/arduino-low-power-how-to-run-atmega328p-for-a-year-on-coin-cell-battery/
http://bbs.espressif.com/viewtopic.php?t=133





Friday, January 13, 2017

Update from Farm-Team: Power regulation of the sensor nodes

Thinking about power

Our aim is to produce an independent power solar battery system for our nodes and our main hub. Further goals are longevity, durability and reliability of core system functionality and low and simple maintenance requirements. Furthermore, ease in pairing nodes to main hub via RFID and firmware updates over the air are subjects that we are also researching.

Starting with the sensor node:
Sensor nodes should be very cheap as they should allow farmers in 3rd world countries to scale up if the farm area is bigger than a hector. In that case a repeater node will be required.

We decided to go with the Arduino Pro Mini (3,3V 8MHz version as main) controller due to its low power consumption. On the transceiver side, we decided to first test the modules available on the market and to choose later. The sensor node in operational mode be powered only 4 times a day an sleep most of the time if not instructed otherwise (update/pairing mode).


Global sunlight


What we know:
-        Worst case 4 Hours of bad sunlight a day.
-        Battery may not overcharge or -discharge

Power consumers to 3:
1.      Tx/Rx module with about 20mA in sleep up to 300mA on sending
2.      Hygrometer, not a lot but constant about 8mA
3.      Board, could sleep
And if the board is sleeping we eliminate 1. and 2.  

After some research into similar projects (links below) we learned that rechargeable batteries differ in many ways. We decided to try two battery types. NiMh and LIon. From further research, we were able to determine the sort of solar panel we need (5~6V with 100mA).


Comparison of rechargeable battery types 


Links:
http://www.instructables.com/id/SOLAR-POWERED-ARDUINO-WEATHER-STATION/
http://www.instructables.com/id/ESP8266-Wifi-Temperature-Logger/
http://www.instructables.com/id/ARDUINO-SOLAR-CHARGE-CONTROLLER-Version-20/
http://www.instructables.com/id/Self-Sufficient-Arduino-Board/

http://blog.whatgeek.com.pt/2014/08/arduino-hygrometer-or-humidity-sensor/
http://earth.rice.edu/MTPE/geo/geosphere/hot/energyfuture/Sunlight.jpg

Saturday, January 7, 2017

Update from Farm-Team: Prototyping Update #2 with Arduino Pro Mini board


 Testing ordered components

Update sensor node shopping
  • Bought Arduino Pro Mini 3,3v (Altmega 328 16Mhz) boards
  • Bought FTDI-Adapter
  • Bought ESP8266-1 boards 
  • Bought BMP180, BH1750, temperature sensors 
Testing Arduino board clones. They can operate with up to 5 V. I used the FTDI as power supply. This will give enough power for the Arduino. But as soon as the ESP8266 is in operational mode the power supplied by the FTDI is not enough.


I used the Arduino IDE to upload a sketch that reads the analog input A0.

Testing the ESP8266 board

First I wanted to check the ESP8266-Firmware:

I connected the ESP8266 directly to the FTDI-Adapter. My ESP8266 hat a default baud rate of 115200.
Update: After I bought a breadboard power supply
 and sent "AT+GMR" to the chip.

ESP8266 -> FTDI-Programmer (has to be common GND)
CH_PD -> GND
VCC -> VCC
TX0 -> RX0
RX0 -> TX0


Output:

AT version:1.1.0.0(May 11 2016 18:09:56)
SDK version:1.5.4(baaeaebb)
Ai-Thinker Technology Co. Ltd.
Jun 13 2016 11:29:20
OK

More: AT+Commands: Cheat sheet

Then I connected the Arduino with the ESP8266
Wiring Arduino/ESP8266/FTDI-Programmer
Issues and Problems:
  1. Used nRLF24+ radio chips as ESP8266 modules had not arrived
  2. Connected first FTDI and ESP8266 to hardware serial due to communication problems on software serial, thats why you will see me use different pins
  3. Programmed Arduino board with FTDI adapter, then disconnected and attached ESP. Worked but really bad when debugging.

Code to communicate between Arduino and ESP

Here we simply just just have a bridge between both serial (Programmer to Arduino to ESP) connections:
 #include <SoftwareSerial.h>  
 SoftwareSerial wifiSerial(2, 3); // TX-Blau-Weiss-2-RX, RX-Violett-1K&1,5K-Grün-3-TX Spannungsteiler</pre>  
 void setup()  
 {  
  Serial.begin(9600); // Seriel Port auf 9600 Baud starten für FTDI Anschluß an PC  
  Serial.println("Bitte Befehl Eingeben");  
  wifiSerial.begin(115200); // Software Seriel Port auf 9600 Baud starten für ESP8266  
 }  
 void loop() // Endloss Programschleife  
 {  
  //Wenn vom ESP Informationen kommen zum FTDI weiterleiten  
  while (wifiSerial.available()>0 ){  
  Serial.write(wifiSerial.read());  
  }  
  // Wenn vom PC Befehle kommen an ESP weiter senden  
  while (Serial.available()>0 ){  
  wifiSerial.write(Serial.read());  
  delay(100);  
  }  
 }  


Code to read A0 from Arduino and send it over UDP (via ESP8266 board)

Using my sketch from before just with minor changes. NanoESP to Ardunio + ESP8266
 /*  
 UDP Button Send.  
 No change necessary.  
 */  
 #define DEBUG true  
 #include <SoftwareSerial.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);  
  }  
 }  

Wednesday, January 4, 2017

Update from Cloud-Team: Setting up IBM IoT to execute OpenWhisk actions

IBM Watson IoT Platform 

One main component in our project is the communication between the hardware components (sensors and gateways) and the back-end in the cloud. For this purpose, we have different options such as Eclipse Kapua, but due to the lack of integration between Kapua and OpenWhisk (Our serverless engine), another option such as Watson IoT Platform fits well in such situation. Watson IoT Platform is used to manage devices and transfer the events through MQTT protocol. IBM Watson IOT platform provides a toolkit to build scalable IoT applications, the toolkit includes gateway devices and devices management, and also it allows users to process events in real-time.

Setting up Watson IoT Platform service instance

Watson IoT Platform is available within Bluemix catalog.





After having the instance initialized, the dashboard then will be available.




To access the dashboard, click on the button Lunch Dashboard, and then:



 
Adding Device Types and Devices

Devices in the platform are organized as groups of devices under their types, each device is associated to a device type. To add devices, at least a device type must be created. Device type in the platform is nothing but some basic information such as name and description. It is used only to keep the stuff organized.

To add a device type, from the service dashboard, select devices tab and then follow the photos:













After that go back to Browse tab, and select:



The next steps are similar to the steps followed in creating the device type. When you reach the step of specifying the authentication token, make sure you either provide your own token or save the auto generated token in a safe place since you can not retrieve it once the device is added.



Rules and Actions

Watson IoT Platform provides a powerful tools to filter and interact with events, it provides what is called rules and actions. The rules are some condition based on events attributes that are triggered whenever such conditions are met to execute what is called actions such as sending emails or doing an HTTP request.

Executing Actions in OpenWhisk as Response to Events in the platform

As it is already mentioned in the project architecture, the back-end is serverless based. In other words, it is serverless microservices. A set of microservices that run in response to incoming events from Watson IoT Platform. To fire an OpenWhisk Trigger, an action in the platform is configured to call an HTTP request that fires the OpenWhisk trigger using the event payload as input parameters for the OpenWhisk trigger.


Update from Cloud-Team: Deploying MongoDB Image as a Container in Bluemix

Introduction to MongoDB

MongoDB is an open source document-based database that is built on an architecture of documents and collections. All the data is stored as documents that comprise sets of key-value pairs. Documents are grouped inside separate collections equivalent to the tables in relational databases. The documents are stored using a json-similar rich format called BSON. MongoDB provides high performance, availability and scalability. It uses the document data model which is more flexible than the relational model since it allows for more flexible representation of complex hierarchical relationships using embedded documents. MongoDB is also designed to scale out by supporting automatic scaling using sharding and replication. MongoDB is designed to be a general database offering many nice features such as generic secondary indexes, aggregation pipeline, and automatic failover. Therefore, we are using MongoDB as our operational data store to store everything related to the user, devices, rules, actions, etc. 




In this blog, I plan to give a quick tutorial in how to run mongoDB as a container in IBM cloud platform "Bluemix". 

Deploy mongodb as a docker container in Bluemix:


Below are the steps to deploy mongodb as a docker container in Bluemix:
  • If it hasn't been done already, you need to sign up for Bluemix account and create an organization/space. There are plenty of tutorials in the internet to do so. It should be an easy straight-forward step.
  • Login and select your organization/space that was created in the first step using the below terminal command:
cf login
  • Install the bluemix container "cf ic" terminal plugin using the below terminal command:
cf install-plugin https://static-ice.ng.bluemix.net/ibm-containers-mac
  • Create a namespace:
cf ic namespace set <namespace_name>
  • Prepare the container plugins "cf ic":
cf ic init
  • Copy the mongodb official docker image to bluemix:
cf ic cpi mongo:latest registry.ng.bluemix.net/<namespace_name>/mongo:latest
  • Confirm that the image copied:
cf ic images
  • Run the mongodb docker container in bluemix:
cf ic run --name mongo -p 27017:27017 -d registry.ng.bluemix.net/<namespace_name>/mongo:latest
  • Confirm that the container is running:
cf ic ps 
  • Request a public IP address from Bluemix:
cf ic ip request
  • Bind the created IP address to the running mongodb container:
cf ic ip bind <IP_Address> mongo
  • Confirm that mongodb container is up and running and test it with some queries using mongo shell:
cf ic exec -it mongo bash
mongo
  • After executing all the above steps, you should be able to see the container running in bluemix as shown below:





Update from Cloud-Team: Deploying Cassandra Image as a Container in Bluemix




Introduction to Cassandra


Apache Cassandra is an open source distributed database that is built above the amazon Dynamo data distribution design and the bigtable data model. It is built to manage and handle very large amount of data that can be deployed across many servers and still provide high availability and performance. Cassandra's ring architecture is designed to be a peer-to-peer decentralised system where there is no single point of failure. The architecture is masterless and all the nodes are equally important. This distributed nature of its architecture allows for better scalability , high availability and operations simplicity. Additionally, Cassandra supports a SQL-like query language called CQL that can be used easily during the modelling and retrieving of the stored data.
One of the most common use cases for using Cassandra is to deal with time-series data.This makes Cassandra the best candidate for our use which is to have a historian service that logs all type of events (raw sensor events, processed events, and watering command events) to a persistence store. The historical data stored in Cassandra can be used later to provide analytics and insights into the farm watering process.
In this blog, I plan to give a quick tutorial in how to run cassandra as a container in IBM cloud platform "Bluemix". 

Deploy Cassandra as a docker container in Bluemix:


Below are the steps to deploy cassandra as a docker container in Bluemix:


  • If it hasn't been done already, you need to sign up for Bluemix account and create an organization/space. There are plenty of tutorials in the internet to do so. It should be an easy straight-forward step.
  • Login and select your organization/space that was created in the first step using the below terminal command:
 cf login
  • Install the bluemix container "cf ic" terminal plugin using the below terminal command:
cf install-plugin https://static-ice.ng.bluemix.net/ibm-containers-mac
  • Create a namespace:
cf ic namespace set <namespace_name>
  • Prepare the container plugins "cf ic":
cf ic init
  • Copy the cassandra official docker image to bluemix:
cf ic cpi cassandra:latest registry.ng.bluemix.net/<namespace_name>/cassandra:latest
  • Confirm that the image copied:
cf ic images
  • Run the cassandra docker container in bluemix:
cf ic run --name cassandra -p 9042:9042 -d registry.ng.bluemix.net/<namespace_name>/cassandra:latest
  • Confirm that the container is running:
cf ic ps 
  • Request a public IP address from Bluemix:
cf ic ip request
  • Bind the created IP address to the running cassandra container:
cf ic ip bind <IP_Address> cassandra
  • Confirm that cassandra container is up and running and test it with some queries using cqlsh:
cf ic exec -it cassandra bash
cqlsh
  • After executing all the above steps, you should be able to see the container running in bluemix as shown below: