Introduction: Build a Weather Station by MediaTek Linkit ONE

Hello, I built a weather station by linkitONE, which is similar to arduino UNO with high performance on wireless conmunication. My weather station would automatically upload data to internet and recorded on the cloud. Let me intirduce how to make it work.

Step 1: Introduction

MediaTek Linkit ONE is developed for wearables and Internet

of Things (IoT) devices, which using hardware and API similar to those offered for Arduino boards. So you can code on it by Arduino IDE just like on Arduino (but note that the Linkit ONE SDK only support IDE version below 1.5.7).

There is the website with a detail introduction of Linkit ONE and its SDK, HDK.

Step 2: LinkitONE Wireless Communication

A standard Linkit ONE package contains a Linkit ONE board, a chargeable battery, and three useful wireless modules (GPS, GSM, and Wifi/Bluetooth antennas).

Step 3: LinkitONE and Mediatek Cloud Sandbox(MCS)

Linkit ONE is not only good at dealing with wireless communication but also user-friendly at data analysis and presentation on cloud. (MediaTek Cloud Sandbox )

Such as the above GPS tracker example.

For more information about LinkitONE and GPS tracker, please see our another instrucable (GPS tracker).

Step 4: Let's DIY a Weather Station

Today I built a weather station to measuring the atmosphere data and then upload to my cloud sandbox. The architecture of this small station is pretty simple. The computer supply power to linkit ONE and communicate with is by micro USB cable. For measuring data, I use Grove Barometer Sensor to obtain the values of the temperature and pressure of the atmosphere, and then calculating the ideal altitude of my station. Also, I measure the humidity in my room by DHT11 sensor, which is commonly used for Arduino sample. Finally, I wrote a program to upload the data to the cloud every few seconds with WiFi module, and I can just observe the variation of data through internet although I’m far away from my room.

Step 5:

Note:

Since Linkit ONE uses most of the efficiency on dealing with internet communication, it usually takes some time to obtain the correct value of humidity by DHT11 sensor. And it sometimes have some disturbance while measuring data, it’s normally, just be patient and wait some time. For another solution to this problem, you can improve my code by filtering those strange values and averages those sensible samples to obtain better observation. I didn’t do that because I want to observe those abnormal data.

Step 6: Preparation for Coding

You must include the SDK of Linkit ONE and the following three libraries to make this program works first.

1. Linkit ONE SDK

2. Arduino HTTP library

3. Grove Barometer Sensor library

4. DHT11 sensor library(see the attached file)

Step 7: My Weather Station Code

#include <LTask.h>
#include <LWifi.h>
#include <LWiFiClient.h>
#include <HttpClient.h>
#include <LDateTime.h>

#define WIFI_AP "12345" //my wifi ap
#define WIFI_PASSWORD "2222222222" //my wifi ap password
#define WIFI_AUTH LWIFI_WPA //the kind of authority of my wifi which is WPA2
#define per 50
#define per1 3
#define DEVICEID "DVViF3eK" //the device id given by cloud sandbox
#define DEVICEKEY "yWHbtj3nxy0T4OFQ" //the device key given by cloud sandbox
#define SITE_URL "api.mediatek.com" //the site of the API


LWiFiClient c; //wifi client
LWiFiClient c2;
HttpClient http(c2); //http client
unsigned int rtc; //real-time clock
unsigned int lrtc;
unsigned int rtc1;
unsigned int lrtc1;
char port[4]="   ";
char connection_info[21]="                    ";
char ip[21]="              ";             
int portnum;
int val = 0;
String tcpdata = String(DEVICEID) + "," + String(DEVICEKEY) + ",0";

String TCPCMD_LED_ON = "LED_controller,1"; //tcp command to controll LED ON/OFF
String TCPCMD_LED_OFF = "LED_controller,0";



#include <dht11.h> //include library of DHT11 sensor
dht11 DHT11;
#define DHT11PIN 2


#include <Wire.h> //include wire library to enable Grove
#include <Barometer.h> //include library of Barometer sensor
Barometer myBarometer;


float humidity;
float temperature;
float pressure;
float atm;
float altitude;



void setup() {
  //initialize
  Serial.begin(9600);
  LTask.begin();
  LWiFi.begin();
  myBarometer.init();
  pinMode(13, OUTPUT);
  while(!Serial);
  
  Serial.println("Connecting to AP");
  while (0 == LWiFi.connect(WIFI_AP, LWiFiLoginInfo(WIFI_AUTH, WIFI_PASSWORD)))
    delay(1000);
  Serial.println("WiFi succeed");
  
  Serial.println("calling connection");
  while (!c2.connect(SITE_URL, 80))
    delay(1000);
  Serial.println("Connection to site succeed");
  
  getconnectInfo();
  Serial.println("getConnectionInfo succeed"); 
  
  connectTCP();
  Serial.println("connectTCP() succeed");
  
}

void loop() {
  
 
  int chk = DHT11.read(DHT11PIN); //check DHT11 and read values
  humidity = DHT11.humidity;
  temperature = myBarometer.bmp085GetTemperature(myBarometer.bmp085ReadUT()); //read values from Barometer sensor
  pressure = myBarometer.bmp085GetPressure(myBarometer.bmp085ReadUP());
  altitude = myBarometer.calcAltitude(pressure);  //calculate the ideal altitude
//  atm = pressure / 101325;
//  Serial.print("Read sensor: ");
//  switch(chk)
//  {
//    case 0: Serial.println("OK"); break;
//    case -1: Serial.println("Checksum error"); break;
//    case -2: Serial.println("Time out error"); break;
//    default: Serial.println("Unknown error"); break;a
//  }

  //print some information on serial monitor
  Serial.println("===================================");
  Serial.print("Humidity: ");
  Serial.println(humidity);
  Serial.print("Temperature: ");
  Serial.println(temperature);
  Serial.print("Altitude: ");
  Serial.println(altitude);
  Serial.print("Pressure: ");
  Serial.println(pressure);
  Serial.println("===================================");
  
  delay(3000);
  String tcpcmd="";
  //read tcp command from cloud to determine whether LED is ON or OFF
  while(c.available())
  {
    int v = c.read();
    if(v != -1);
    {
      Serial.print((char)v);
      tcpcmd += (char)v;
      if(tcpcmd.substring(40).equals(TCPCMD_LED_ON))
      {
        digitalWrite(13, HIGH);
        tcpcmd = "";
      }
      else if(tcpcmd.substring(40).equals(TCPCMD_LED_OFF))
      {
        digitalWrite(13, LOW);
        tcpcmd = "";
      }
    }
  }
  
  LDateTime.getRtc(&rtc);
  if ((rtc - lrtc) >= per) {
    heartBeat();
    lrtc = rtc;
  }
  //Check for report datapoint status interval
  LDateTime.getRtc(&rtc1);
  if ((rtc1 - lrtc1) >= per1) {
    uploadstatus();
    lrtc1 = rtc1;
  }
}









void getconnectInfo(){
  //calling RESTful API to get TCP socket connection  
  c2.print("GET /mcs/v2/devices/");
  c2.print(DEVICEID);
  c2.println("/connections.csv HTTP/1.1");
  c2.print("Host: ");
  c2.println(SITE_URL);
  c2.print("deviceKey: ");
  c2.println(DEVICEKEY);
  c2.println("Connection: close");
  c2.println();
  
  delay(500);

  int errorcount = 0;
  while (!c2.available())
  {
    Serial.println("waiting HTTP response: ");
    Serial.println(errorcount);
    errorcount += 1;
    if (errorcount > 10) {
      c2.stop();
      return;
    }
    delay(100);
  }
  int err = http.skipResponseHeaders();

  int bodyLen = http.contentLength();
  Serial.print("Content length is: ");
  Serial.println(bodyLen);
  Serial.println();
  char c;
  int ipcount = 0;
  int count = 0;
  int separater = 0;
  while (c2)
  {
    int v = c2.read();
    if (v != -1)
    {
      c = v;
      Serial.print(c);
      connection_info[ipcount]=c;
      if(c==',')
      separater=ipcount;
      ipcount++;    
    }
    else
    {
      Serial.println("no more content, disconnect");
      c2.stop();

    }
    
  }
  Serial.print("The connection info: ");
  Serial.println(connection_info);
  int i;
  for(i=0;i<separater;i++)
  {  ip[i]=connection_info[i];
  }
  int j=0;
  separater++;
  for(i=separater;i<21 && j<5;i++)
  {  port[j]=connection_info[i];
     j++;
  }
  Serial.println("The TCP Socket connection instructions:");
  Serial.print("IP: ");
  Serial.println(ip);
  Serial.print("Port: ");
  Serial.println(port);
  portnum = atoi (port);
  Serial.println(portnum);

} //getconnectInfo



void connectTCP(){
  //establish TCP connection with TCP Server with designate IP and Port
  c.stop();
  Serial.println("Connecting to TCP");
  Serial.println(ip);
  Serial.println(portnum);
  while (0 == c.connect(ip, portnum))
  {
    Serial.println("Re-Connecting to TCP");    
    delay(1000);
  }  
  Serial.println("send TCP connect");
  c.println(tcpdata);
  c.println();
  Serial.println("waiting TCP response:");
} //connectTCP


void heartBeat(){
  Serial.println("send TCP heartBeat");
  c.println(tcpdata);
  c.println();
} //heartBeat


void uploadstatus(){
  //calling RESTful API to upload datapoint to MCS(Meditek Cloud Sandbox)
  Serial.println("calling connection");
  LWiFiClient c2;  
 
  char bufferH[5];
  char bufferT[5];
  char bufferA[7];
  char bufferP[7];
  
  sprintf(bufferH, "%.2f", humidity);
  sprintf(bufferT, "%.2f", temperature);
  sprintf(bufferA, "%.2f", altitude);
  sprintf(bufferP, "%.0f", pressure);
  
  String uploadLED;
  String uploadHumidity = "humidity_display,," + String(bufferH);
  String uploadTemperature = "temperature_display,," + String(bufferT);
  String uploadAltitude = "altitude_display,," + String(bufferA);
  String uploadPressure = "pressure_display,," + String(bufferP);
  
  
  while (!c2.connect(SITE_URL, 80))
  {
    Serial.println("Re-Connecting to WebSite");
    delay(1000);
  }
  delay(100);
  if(digitalRead(13)==1)
    uploadLED = "LED_display,,1";
  else
    uploadLED = "LED_display,,0";
  
  String uploadData = uploadLED + "\n" +
                      uploadHumidity + "\n" +
                      uploadTemperature + "\n" + 
                      uploadAltitude + "\n" +
                      uploadPressure;
  
  HttpClient http(c2);
  c2.print("POST /mcs/v2/devices/");
  c2.print(DEVICEID);
  c2.println("/datapoints.csv HTTP/1.1");
  c2.print("Host: ");
  c2.println(SITE_URL);
  c2.print("deviceKey: ");
  c2.println(DEVICEKEY);
  c2.print("Content-Length: ");
  c2.println(uploadData.length());
  c2.println("Content-Type: text/csv");
  c2.println("Connection: close");
  c2.println();
  c2.println(uploadData);
  //upload the data
  
  delay(500);

  int errorcount = 0;
  while (!c2.available())
  {
    Serial.print("waiting HTTP response: ");
    Serial.println(errorcount);
    errorcount += 1;
    if (errorcount > 10) {
      c2.stop();
      Serial.println("uploadStatus failed");
      return;
    }
    delay(100);
  }
  int err = http.skipResponseHeaders();

  int bodyLen = http.contentLength();
  Serial.print("Content length is: ");
  Serial.println(bodyLen);
  Serial.println();
  while (c2)
  {
    int v = c2.read();
    if (v != -1)
      Serial.print(char(v));
    else
    {
      Serial.println("no more content, disconnect");
      c2.stop();
    }
  }
}

Step 8: Outcome on Serial Monitor. and If Succeed, It Will Upload Those Data Displayed on the Monitor

Step 9: Data Presentation on MediaTek Cloud Sandbox, There Are LED_controller, LED_display, Temperature_display, Humidity_display, Pressure_display, and Altitude_display

Step 10: View Data Record on Cloud

Finally, the cloud website would automatically record the received data with time, just like the example.

You may analysis your data according different time, or comdined with another data, such as humidity and temperature according to different time, altitude, or pressure.

Thanks for reading!

If you have any question, please leave a message!