2015년 11월 15일 일요일

JSON Examples for Ardunio platform

2015년 10월 29일 목요일

[WIZwiki_W7500ECO] HTTPClient with JSON parser

[WIZwiki_W7500ECO] HTTPClient with JSON parser

JSON is easy for machines to parse and generate which is based on a subset of the JavaScript Programming Language. Currently many Web Services allow to access data in JSON format. However, JSON parser is too big for low-end device as like a ARMmbed platform which has limited-resource. This post shows how to use HTTPClient parse Json data in ARMmbed platform.
IMG_20151029_165139

Preparation materials

  1. Software
  2. Hardware

Simplest python JSON server on PC

  • Reference : fraka6.blogsopot.kr: The simplest python server example

  • Modify Server IP address & port on ron_handler

    def run(port=8000): #set port
    
      print('http server is starting...')
      #ip and port of server
      #server_address = ('127.0.0.1', port)
      server_address = ('192.168.0.223', port)#set port
      httpd = HTTPServer(server_address, Handler)
      print('http server is running...listening on port %s' %port)
      httpd.serve_forever()
    
  • Modify JSON form in do_GET handler

    #handle GET command
    def do_GET(self):
      if format == 'html':
          self.send_response(200)
          self.send_header("Content-type", "text/plain")
          self.send_header('Content-type','text-html')
          self.end_headers()
          self.wfile.write("body")
      elif format == 'json':
          #self.request.sendall(json.dumps({'path':self.path}))
          #self.request.sendall(json.dumps({'pi':3.14}))
          self.request.sendall(json.dumps({'name':'John snow', 'age': 30, 'gender':'male'}))
      else:
          self.request.sendall("%s\t%s" %('path', self.path))
      return
    
  • Excute json_server
    2015-10-29_16-26-33

  • Test by using curl

      $>curl ip_address:port_number
    

    2015-10-29_16-26-00

Make main.cc

  1. Network Configration for WIZwiki-W7500ECO

     // Enter a MAC address for your controller below.
     uint8_t mac_addr[6] = {0x00, 0x08, 0xDC, 0x00, 0x01, 0x02};
    
     printf("initializing Ethernet\r\n");
     // initializing MAC address
     eth.init(mac_addr, "192.168.0.34", "255.255.255.0", "192.168.0.1");
    
     // Check Ethenret Link
     if(eth.link() == true)   printf("- Ethernet PHY Link-Done \r\n");
     else printf("- Ethernet PHY Link- Fail\r\n");
    
     // Start Ethernet connecting: Trying to get an IP address using DHCP
     if (eth.connect()<0)    printf("Fail - Ethernet Connecing");
    
  2. TCP connect to simple python JSON server

     sock.connect("192.168.0.223", 8000); // "destination IP address", destination port number
    
  3. Make Get form in HTTP format

     snprintf(http_tx_msg, http_tx_msg_sz,  "GET / HTTP/1.1\r\nHost: 192.168.0.223:8000\r\nUser-Agent: WIZwiki-W7500ECO\r\nConection: close\r\n\r\n");
    
  4. TCP Send Get form

     sock.send_all(http_tx_msg, http_tx_msg_sz-1); // tx_buf, tx_buf_size
    
  5. TCP Recv data in JSON format

     while ( (returnCode = sock.receive(http_rx_msg, http_rx_msg_sz-1)) > 0) {
             http_rx_msg[returnCode] = '\0';
             printf("Received %d chars from server:\n\r%s\n", returnCode, http_rx_msg);
         }
    
  6. Do JSON parse
     parse(parser, http_rx_msg);
    
  7. Output the parsed data
     // parsing "string" in string type
     printf("name =%s\r\n" , parser["name"].get<string>().c_str());
     // parsing "age" in integer type
     printf("age =%d\r\n" , parser["age"].get<int>());
     // parsing "gender" in string type
     printf("gender =%s\r\n" , parser["gender"].get<string>().c_str());
    

Demo. HTTPClient with JSON parser

  1. Network config.
  2. Confirm Received JSON data
  3. Print-out the pasing data
    2015-10-29_16-42-55

Packet Capture

  1. TCP-Connection
  2. Target board sends GET Form to simple python JSON server
  3. simple python JSON server sends JSON data to Target board
    2015-10-29_16-22-56

2015년 10월 28일 수요일

Fraka6 Blog - No Free Lunch: The simplest python server example ;)

Fraka6 Blog - No Free Lunch: The simplest python server example ;)



2015년 9월 22일 화요일

How to collect and analyze sensing data of IoT platform

How to collect and analyze sensing data of IoT platform

This post shows how to connect IoT platform to Cloud service and how to display sensing data for graphical analysis.

data.sparkfun.com

  • What is Phant?

    • Phant is a open source cloud server platform by powered Sparkfun Electronics.
    • Sparkfun created data.spartfun.com ,which is a free cloud service running phant. -
    • To collect data from your device to cloud service, you just need to register a new stream.
    • After register, you get two keys for accessing the data; one is q private key is required to update that stream, other is a public key grants access to any other stream on the service.
    • All communication with Phant is carried out over HTTP. So, your device should be acted as HTTP Client.
    • http://data.sparkfun.com/input/[publicKey]?private_key=[privateKey]&[field1]=[value]&[field2]=[value]
      
  • Phant : Phant.io

    Phant is a modular node.js based data logging tool for collecting data from the Internet of Things. It is the open source software that powers data.sparkfun.com, and is actively maintained by SparkFun Electronics. Phant is short for elephant. Elephants are known for their remarkable recall ability, so it seemed appropriate to name a data logging project in honor of an animal that never forgets.

analog.io

  • 3rd party of data.sparkfun.com
  • Graphing front end

    analog.io is a full stack IoT web service and hardware platforms where people can create connected devices and share them with the world. It is designed to solve all kinds of world problems from air pollution, improving farm output or studying the bee population. It is really only limited by the users imagination. (for more detail)
    2015-09-22_19-36-25

Prepare materials

  • Hardware
    IMG_20150922_195307

    • mbed platform : WIZwiki-W7500

      • ARM® Cortex™-M0 Core 48MHz
      • 128KB Flash memory
      • 16KB to 48 KB SRAM (Min 16KB available if 32KB socket buffer is used, Max 48KB available if no socket buffer is used)
      • Hardwired TCP/IP Core (8 Sockets, MII: Medium-Independent Interface)
      • 12-bit, 8ch ADC
      • 53 I/Os
      • 1ch Watchdog, 4ch Timers and 8ch PWM
      • 3ch UART
      • 2ch SPI
      • 2ch I2C
    • Sensors (ywrobot easy module shield v1): DHT11
      ywrobot

  • Registrations

    • data.sparkfun.com
      To create a data stream, head over to data.sparkfun.com, and click “CREATE”.

      • Create a Data Stream

        2015-09-22_20-06-54

          * Fields - This comma-separated list of words defines data stream to post a list of unique values.
          * Stream Alias - This testbox defines domain name for you Data Stream
        
      • New Stream example: After creating a data Stream, you will confirm URL, Keys for accessing for your data stream.
        E_New Stream1

Software

2015-09-22_20-28-32

  • Used Lib
    • WIZnetInterface Lib. : for Ethernet connectivity of W7500
    • DHT Lib. : for DHT11 sensor

Codes flow

  • mbed.org repositories : https://developer.mbed.org/users/embeddist/code/Data_Sparkfun_io/

  • Configuration Arduino’s I/O pins

    /*
    *Input Pins, Misc
    * D4 - Temp. and Hum. Sensor
    * D3 - Push buttom
    */
    DHT sensor(D4, DHT11);
    DigitalIn  triggerPin(D3);
    
  • Configuration Phat Stuff

    /*
    * Phant Stuffs
    * Insert your publicKey
    * Insert your privateKey
    * Generat Fileds; 'Files name shoud be same "field name" in Create Stream form'
    */
    char publicKey[] = "insert_your_publicKey";
    char privateKey[] = "insert_your_privateKey";
    uint8_t NUM_FIELDS = 2;
    char fieldNames1[] = "hum";
    char fieldNames2[] = "temp";
    
  • Network Configuration : DHCP Client

     // Enter a MAC address for your controller below.
      uint8_t mac_addr[6] = {0x00, 0x08, 0xDC, 0x00, 0x01, 0x02};     
    
      printf("initializing Ethernet\r\n");
      // initializing MAC address
      eth.init(mac_addr);
    
      // Check Ethenret Link
      if(eth.link() == true)   printf("- Ethernet PHY Link-Done \r\n");
      else printf("- Ethernet PHY Link- Fail\r\n");
    
      // Start Ethernet connecting: Trying to get an IP address using DHCP
      if (eth.connect()<0)    printf("Fail - Ethernet Connecing");
    
      // Print your local IP address:
      printf("IP=%s\n\r",eth.getIPAddress());
      printf("MASK=%s\n\r",eth.getNetworkMask());
      printf("GW=%s\n\r",eth.getGateway());
    
  • HTTP Client

    /*
    *    - If the trigger pin (3) goes low, send the data.
    *        - Get sensing datas by using analogread()
    *        - Call postData
    *            - Open socket as TCP Client
    *            - Try to connet TCP server (data.sparkfun.com); if needs, do DNS clinet for getting IP address of server
    *            - Make query string based on Phant frame
    *            - Send query
    *            - Check for a response from the server, and route it out the serial port.
    */
    
      while(1)
      {
          if(triggerPin ==0)
          {
              sensor.readData();
              c   = sensor.ReadTemperature(CELCIUS);
              h   = sensor.ReadHumidity();
             printf("Temperature in Celcius: %4.2f", c);
             printf("Humidity is %4.2f\n", h, dp, dpf);
    
            sock.connect("data.sparkfun.com", 80);
    
            snprintf(http_cmd, http_cmd_sz,  "GET /input/%s?private_key=%s&%s=%2.2f&%s=%3.3f HTTP/1.1\r\nHost: data.sparkfun.com\r\nConection: close\r\n\r\n", 
                                              publicKey, privateKey, fieldNames1, h, fieldNames2, c);
            sock.send_all(http_cmd, http_cmd_sz-1);
    
            while ( (returnCode = sock.receive(buffer, buffer_sz-1)) > 0)
            {
                buffer[returnCode] = '\0';
                printf("Received %d chars from server:\n\r%s\n", returnCode, buffer);
            }
    
            sock.close();         
          }
    
          wait(2);
      }
    
  • Make Query string over HTTP

      http://data.sparkfun.com/input/[publicKey]?private_key=[privateKey]&hum=[value]&temp=[value]
    
      snprintf(http_cmd, http_cmd_sz,  "GET /input/%s?private_key=%s&%s=%2.2f&%s=%3.3f HTTP/1.1\r\nHost: data.sparkfun.com\r\nConection: close\r\n\r\n", publicKey, privateKey, fieldNames1, h, fieldNames2, c);
      sock.send_all(http_cmd, http_cmd_sz-1);
    

Demo

Serial Monitor

  1. DHCP Clinet message
  2. Press the button to send query to server.
  3. Confirm the response message on serial terminal and data.spark.com/your_stream

     initializing Ethernet
     - Ethernet PHY Link-Done
     IP=192.168.11.224
     MASK=255.255.255.0
     GW=192.168.11.1
     Temperature in Celcius: 27.00Humidity is 55.00
     Received 299 chars from server:
     HTTP/1.1 200 OK
     Access-Control-Allow-Origin: *
     Access-Control-Allow-Methods: GET,POST,DELETE
     Access-Control-Allow-Headers: X-Requested-With, Phant-Private-Key
     Content-Type: text/plain
     X-Rate-Limit-Limit: 300
     X-Rate-Limit-Remaining: 298
     X-Rate-Limit-Reset: 1441353380.898
     Date: Fri, 04 Sep 20
     Received 299 chars from server:
     15 07:46:03 GMT
     Transfer-Encoding: chunked
     Set-Cookie: SERVERID=phantworker2; path=/
     Cache-control: private
    

https://data.sparkfun.com/office_monitoring

2015-09-04_16-39-51

analog.io: import stream from data.sparkfun.com/your_stream

  • How to Import Stream

    1. Click ‘+Import Stream’ button on menu
      2015-09-04_16-38-19

    2. Select ‘Sparkfun’ on Host drop box and input Public key of data.sparkfun.com
      2015-09-04_16-38-36

    3. Confirm your Stream
      2015-09-04_16-36-04

2015년 8월 26일 수요일

How to push data to data.sparkfun.com for Internet of Things

How to push data to data.sparkfun.com for Internet of Things

This post shows how to connect Arduino platform to data.sparkfun.com for Internet of Things.

  • Scope of post
    • Internet Connectivity : W5500 Ethernet Shield
    • Cloud Service : data.sparkfun.com
    • Arduino IDE 1.7.6 (arduino.org); surpports Ethernet libraries for W5500
    • HTTP Query

data.sparkfun.com

  • What is Phant?

    • Phant is a open source cloud server platform by powered Sparkfun Electronics.
    • Sparkfun created data.spartfun.com ,which is a free cloud service running phant. -
    • To collect data from your device to cloud service, you just need to register a new stream.
    • After register, you get two keys for accessing the data; one is q private key is required to update that stream, other is a public key grants access to any other stream on the service.
    • All communication with Phant is carried out over HTTP. So, your device should be acted as HTTP Client.
    • http://data.sparkfun.com/input/[publicKey]?private_key=[privateKey]&[field1]=[value]&[field2]=[value]
      
  • Phant : Phant.io

    Phant is a modular node.js based data logging tool for collecting data from the Internet of Things. It is the open source software that powers data.sparkfun.com, and is actively maintained by SparkFun Electronics. Phant is short for elephant. Elephants are known for their remarkable recall ability, so it seemed appropriate to name a data logging project in honor of an animal that never forgets.

Prepare materials

  • Hardware
    hardware
  • Tool : Arduino IDE

  • Registration on data.sparkfun.com
    To create a data stream, head over to data.sparkfun.com, and click “CREATE”.

    • Create a Data Stream

      • New Stream example
        E_New Stream

        • Fields - This comma-separated list of words defines data stream to post a list of unique values.
        • Stream Alias - This testbox defines domain name for you Data Stream
      • Create Data Steam: After creating a data Stream, you will confirm URL, Keys for accessing for your data stream.
        E_New Stream1

Software

Codes flow

  • Configuration Arduino’s I/O pins

    • D3 - Active-low momentary button (pulled high internally)
    • A1 - Photoresistor (which is combined with a 10k resistor to form a voltage divider output to the Arduino).
    • A2 - Temporature Sensor (LM35)
  • Configuration Phat Stuff

    • Insert your publicKey
    • Insert your privateKey
    • Generat Fileds; ‘Files name shoud be same “field name” in Create Stream form’
  • setup()

    • Call Serial.begin(115200);
    • Setting Input pins
    • Call setupEthernet(): do DHCP Client and writing MAC Addrerss
  • loop()

    • If the trigger pin (3) goes low, send the data.
      • Get sensing datas by using analogread()
      • Call postData
        • Open socket as TCP Client
        • Try to connet TCP server (data.sparkfun.com); if needs, do DNS clinet for getting IP address of server
        • Make query string based on Phant frame
        • Send query
        • Check for a response from the server, and route it out the serial port.

Arduino’s I/O pins:

const int triggerPin = 3;
const int lightPin = A1;
const int tempPin = A2; 

void setup()
{
...

  // Setup Input Pins:
  pinMode(triggerPin, INPUT_PULLUP);
  pinMode(lightPin, INPUT_PULLUP);
  pinMode(tempPin, INPUT_PULLUP);
...
}

Phant Stuff

const String publicKey = "insert_your_publicKey"; 
const String privateKey = "insert_your_privateKey";

const byte NUM_FIELDS = 2;
const String fieldNames[NUM_FIELDS] = {"lux", "temp"}; // Fileds shoud be same "field names" in Create Stream.
int fieldData[NUM_FIELDS];

Make Query string over HTTP

  • Format
      http://data.sparkfun.com/input/[publicKey]?private_key=[privateKey]&lux=[value]&temp=[value]
    
client.print("GET /input/");
client.print(publicKey);
client.print("?private_key=");
client.print(privateKey);
for (int i=0; i<NUM_FIELDS; i++)
{
  client.print("&");
  client.print(fieldNames[i]);
  client.print("=");
  client.print(fieldData[i]);
}
client.println(" HTTP/1.1");
client.print("Host: ");
client.println(server);
client.println("Connection: close");
client.println();

Phant_Ethernet.ino

/*****************************************************************
Phant_Ethernet.ino
Post data to SparkFun's data stream server system (phant) using
an Arduino and an Ethernet Shield.
Jim Lindblom @ SparkFun Electronics
Original Creation Date: July 3, 2014
Roy Kim(Soohwan Kim) embeddist@gmail.com
Modified DateL August 26, 2015
S

This sketch uses an Arduino Uno to POST sensor readings to 
SparkFun's data logging streams (http://data.sparkfun.com). A post
will be initiated whenever pin 3 is connected to ground.

Before uploading this sketch, there are a number of global vars
that need adjusting:
1. Ethernet Stuff: Fill in your desired MAC and a static IP, even
   if you're planning on having DCHP fill your IP in for you.
   The static IP is only used as a fallback, if DHCP doesn't work.
2. Phant Stuff: Fill in your data stream's public, private, and 
data keys before uploading!

Hardware Hookup:
  * These components are connected to the Arduino's I/O pins:
    <Original>
    * D3 - Active-low momentary button (pulled high internally)
    * A0 - Photoresistor (which is combined with a 10k resistor
           to form a voltage divider output to the Arduino).
    * D5 - SPDT switch to select either 5V or 0V to this pin.
    <Modified>
    * D3 - Active-low momentary button (pulled high internally)
    * A1 - Photoresistor (which is combined with a 10k resistor
           to form a voltage divider output to the Arduino).
    * A2 - Temporature Sensor (LM35)

  * A CC3000 Shield sitting comfortable on top of your Arduino.

Development environment specifics:
    <Original>
    IDE: Arduino 1.0.5 
    Hardware Platform: RedBoard & PoEthernet Shield
    <Modified>
    IDE: Arduino 1.7.6 
    Hardware Platform: Arduino DUE & W5500 Ethernet Shield

This code is beerware; if you see me (or any other SparkFun 
employee) at the local, and you've found our code helpful, please 
buy us a round!

Much of this code is largely based on David Mellis' WebClient
example in the Ethernet library.

Distributed as-is; no warranty is given.
*****************************************************************/
#include <SPI.h> // Required to use Ethernet
//#include <Ethernet.h> // The Ethernet library includes the client for W5100
#include <Ethernet2.h> // The Ethernet library includes the client for W5500
//#include <Progmem.h> // Allows us to sacrifice flash for DRAM //@Modified: Don't use

///////////////////////
// Ethernet Settings //
///////////////////////
// Enter a MAC address for your controller below.
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
//IPAddress server(54,86,132,254);  // numeric IP for data.sparkfun.com
char server[] = "data.sparkfun.com";    // name address for data.sparkFun (using DNS)
// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192,168,0,177);

// Initialize the Ethernet client library
// with the IP address and port of the server 
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;

/////////////////
// Phant Stuff //
/////////////////
const String publicKey = "6JZbNolApzF4om2l9yYK";
const String privateKey = "Ww0vPW1yrkUNDqWPV9jE";

const byte NUM_FIELDS = 2;
const String fieldNames[NUM_FIELDS] = {"lux", "temp"};
int fieldData[NUM_FIELDS];

//////////////////////
// Input Pins, Misc //
//////////////////////
const int triggerPin = 3;
const int lightPin = A1;
const int tempPin = A2; 

float tempC;
int reading;
//String name = "Ether-anon";
String name = "Roy";
boolean newName = true;

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

  // Setup Input Pins:
  pinMode(triggerPin, INPUT_PULLUP);
  pinMode(lightPin, INPUT_PULLUP);
  pinMode(tempPin, INPUT_PULLUP);

  // Set Up Ethernet:
  setupEthernet();

  Serial.println(F("=========== Ready to Stream ==========="));
  Serial.println(F("Press the button (D3) to send an update"));
#if 0 // don't use
  Serial.println(F("Type your name (no spaces!), followed by '!' to update name"));
#endif
}

void loop()
{
  // If the trigger pin (3) goes low, send the data.
  if (!digitalRead(triggerPin))
  {
    // Gather data:
        fieldData[0] = analogRead(lightPin);
        fieldData[1] = analogRead(tempPin);
    //fieldData[2] = name;

    Serial.println("Posting!");
    postData(); // the postData() function does all the work, 
                // check it out below.

    delay(1000);
  }
#if 0 // don't use
  // Check for a new name input:
  if (Serial.available())
  {
    char c = Serial.read();
    if (c == '!')
    {
      newName = true;
      Serial.print("Your name is ");
      Serial.println(name);
    }
    else if (newName)
    {
      newName = false;
      name = "";
      name += c;
    }
    else
    {
      name += c;
    }
  }
#endif
}

void postData()
{
  // Make a TCP connection to remote host
  if (client.connect(server, 80))
  {
    // Post the data! Request should look a little something like:
    // GET /input/publicKey?private_key=privateKey&light=1024&switch=0&name=Jim HTTP/1.1\n
    // Host: data.sparkfun.com\n
    // Connection: close\n
    // \n
    client.print("GET /input/");
    client.print(publicKey);
    client.print("?private_key=");
    client.print(privateKey);
    for (int i=0; i<NUM_FIELDS; i++)
    {
      client.print("&");
      client.print(fieldNames[i]);
      client.print("=");
      client.print(fieldData[i]);
    }
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Connection: close");
    client.println();
  }
  else
  {
    Serial.println(F("Connection failed"));
  } 

  // Check for a response from the server, and route it
  // out the serial port.
  while (client.connected())
  {
    if ( client.available() )
    {
      char c = client.read();
      Serial.print(c);
    }      
  }
  Serial.println();
  client.stop();
}

void setupEthernet()
{
  Serial.println("Setting up Ethernet...");
  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println(F("Failed to configure Ethernet using DHCP"));
    // no point in carrying on, so do nothing forevermore:
    // try to congifure using IP address instead of DHCP:
    Ethernet.begin(mac, ip);
  }
  Serial.print("My IP address: ");
  Serial.println(Ethernet.localIP());
  // give the Ethernet shield a second to initialize:
  delay(1000);
}

Demo:

Serial Monitor

  1. DHCP Clinet message
  2. Press the button to send query to server, then postData() is called.
  3. Confirm the response message
    E_2015-08-26_17-15-57

https://data.sparkfun.com/office_monitoring

  • Before sending query
    E_page2

  • After sending query : lux and temp are filed names.
    E_page3