Garden Monitoring using Intel Edison and Carriots

Garden Monitoring using Intel Edison and Carriots

Edison01

ลืมรดน้ำต้นไม้!!! เหตุการณ์นี้คงเกิดขึ้นบ่อยสำหรับหลายคนที่ชื่นชอบปลูกต้นไม้กระถางไว้ริมหน้าต่าง บนโต๊ะทำงาน หรือนอกระเบียงห้องพัก… วันนี้ขอเสนอ เครื่องตรวจสอบความชุ่มชื้นของดินด้วย Edison และ Sensor จากนั้นส่งข้อมูลผ่านอินเตอร์เน็ตไปเก็บไว้บน Carriots เป็น Cloud สำหรับ Internet of Things (IoT) ที่สามารถเก็บข้อมูล แล้วนำมาแสดงผลในรูปแบบกราฟผ่านทางหน้าเว็บผ่าน JavaScripts หรือจะนำข้อมูลออกไปใช้งานต่อไปที่อื่นก็ได้เช่นกัน นอกจากนี้ยังสามารถแจ้งเตือนผ่านอีเมลหรือข้อความสั้นได้อีกด้วย.. โอ้ว…จอร์จ… มันยอดมาก

          บทความ IoT ในตอนก่อนหน้านี้ได้แนะนำถึง Edison จาก Intel (ย้อนอ่านบทความ ที่นี่) ซึ่งมี Atom รันระบบปฏิบัติการ Linux และ Quark เป็นไมโครคอนโทรลเลอร์ในตัวเดียวกัน เพียบพร้อมด้วยโมดูลสื่อสารไร้สายทั้ง Wireless LAN และ Bluetooth เหมาะสำหรับการนำไปพัฒนาอุปกรณ์ IoT ที่แม้มีขนาดเล็กประมาณ USB Flash Drive แต่มีการทำงานที่ทรงพลัง และมีอุปกรณ์เชื่อมต่อเครือข่ายครบถ้วนไม่ต้องเชื่อมต่อให้วุ่นวาย

02

EFDV355 Intel® Edison and Mini Breakout Kit

03

EFDV373 Intel® Edison and Arduino Breakout Kit

Edison03 1

ESEN175 Grove – Moisture Sensor

          ในการวัดความชื้นของดินใช้ Soil Moisture Sensor ซึ่งจะเปลี่ยนแปลงแรงดันเอาต์พุตเมื่อความชื้นเปลี่ยนแปลง โดยเสียบตัววัดไว้ในดินที่ต้องการ และต่อสัญญาณจากโมดูลเข้าที่ขา Analog Input เพื่ออ่านค่าแรงดันที่เปลี่ยนไป ค่าอนาล็อก (ความละเอียด 10 บิต) ที่อ่านได้ในช่วง 0 ถึง 300 คือ อยู่ในที่แห้งหรือดินที่มีความชื้นน้อยมาก ช่วง 300 ถึง 700 คือ ดินที่มีความชื้นน้อยถึงปานกลาง ค่าช่วง 700 ขึ้นไป คือ ดินที่มีความชื้นสูงหรือดินเปียกหรือมีน้ำอยู่มาก

          การเชื่อมต่อ Sensor เข้ากับ Edison หากใช้บอร์ดแบบ Arduino Breakout ให้เชื่อมต่อขา SIG ของ Sensor เข้าที่ขา A0 หากใช้บอร์ด Mini Breakout ให้เชื่อมต่อเข้าที่ขา J19 ขา 4 อย่าลืมต่อไฟเลี้ยง 5V กับ GND ให้กับโมดูลด้วย

Edison04

  Carriots เป็นบริการ Cloud สำหรับ IoT ซึ่งช่วยให้เราสามารถเชื่อมต่ออุปกรณ์ (Devices) ต่างๆ เข้ากับระบบเพื่อเก็บข้อมูล (Data Logging) ตามที่เราต้องการ โดยเราสามารถบริการจัดการ (Manage) ทั้งอุปกรณ์และข้อมูลของเรา นอกจากนี้ยังสามารถนำข้อมูลที่ได้ไปใช้งานต่อได้ในหลากหลายรูปแบบ ทั้งแสดงผลเป็นกราฟบนเว็บไซต์ของ Carriots เอง หรือดึงไปแสดงบนเว็บไซต์ต่างๆ หรือเขียนแอพพลิเคชั่นของเราเชื่อมต่อข้อมูลไปใช้งานภายนอกผ่าน API และระบบรักษาความปลอดภัยที่ดี นอกจากนี้ยังสามารถนำข้อมูลออก (Export) ไปใช้งานอื่นได้เช่นกัน ซึ่ง Carriots ให้บริการในเชิงธุรกิจมีการคิดค่าบริการที่ไม่สูงนักหากจะนำไปใช้งานจริง สามารถเข้าไปดู              รายละเอียดได้ที่เว็บไซต์ www.carriots.com/pricing แต่เดี๋ยวก่อน ถ้าคุณทำตามบทความวันนี้เราจะพาไปใช้งานแบบฟรี (จริงๆ เขามีให้ฟรีอยู่แล้ว สมัครได้เลย) โดยแบบฟรีนี้

  • ไม่เสียค่าใช้จ่าย
  • ใช้งานได้ 10 อุปกรณ์
  • มี API Key ในการใช้งานให้ 2 คีย์ ตรงนี้เปรียบเสมือนกุญแจเข้าระบบเพื่อใช้งาน API ของ Carriots ในการ Stream ข้อมูลขึ้นมาเก็บไว้ และการอ่านเอาข้อมูลออกไปใช้
  • จำกัดจำนวนการใช้งานที่ 15,000 ข้อมูลต่อวัน แต่ไม่เกินนาทีละ 500 ข้อมูล
  • เก็บข้อมูลออนไลน์ไว้ได้ 1 ปี แต่ออฟไลน์ไม่จำกัด
  • สามารถส่ง SMS ได้ 5 ข้อความต่อวัน แต่ไม่เกินนาทีละ 1 ข้อความ
  • ส่งอีเมลได้วันละ 100 ฉบับ แต่ไม่เกินนาทีละ 10 ฉบับ
  • ดึงข้อมูลด้วย HTTP Request ออกไปภายนอกได้ 15000 ครั้งต่อวัน

          แค่นี้ก็ถือว่าเยอะแล้วสำหรับของฟรีนะว่ามั๊ย สมัครใช้บริการกันก่อนโดยเข้าไปที่ www.carriots.com แล้วเลือก Free Account ปุ่มสีส้มเด่นชัดทางมุมขวาบน

Edison05

กรอกข้อมูลเพื่อสมัครขอใช้บริการ ไม่ต้องกังวลนะ ฟรีจริง ไม่มีการกรอกรหัสบัตรเครดิตหรือเพย์พาลอะไรทั้งนั้น ในส่วนของ Region กับ Timezone กำหนดให้ตรงเพื่อให้ข้อมูลที่เก็บมี Timestamp ถูกต้อง สุดท้ายด้านล่างต้องยอมรับ Term of Service และ Privacy policy ด้วย ส่วนจะรับข้อมูลด้านเทคนิคหรือด้านสินค้าเพิ่มเติมทางอีเมลหรือไม่ก็ตามสะดวก กรอกเรียบร้อยให้กดปุ่ม Submit รอสักพักจะมีอีเมลเข้ามา ให้ยืนยันตัวตนจึงจะสามารถล็อกอินเข้าใช้งานได้

Edison06

  จากนั้นให้ล็อกอินเข้าระบบตรงมุมขวาบนเหนือปุ่ม Free Account

Edison07

 เข้ามาจะเป็นหน้า Control Panel ด้านซ้ายมีเมนูในการจัดการ Project Device  Data และ Rules ตรงกลางจะแสดงรายละเอียดและแนะนำการใช้งาน ด้านขวาเป็นข้อมูลสรุปเรื่อง Alarm กับ Device

Edison08

 เข้าที่เมนู Device Management > Devices เพื่อสร้างตัวอุปกรณ์ในระบบสำหรับรองรับการส่งข้อมูล (Stream) เข้ามา จากนั้นกดปุ่ม New จะเข้าสู่หน้า Device creation กรอกข้อมูลต่างๆ ลงไป ในส่วนของ Type เนื่องจากไม่มีจึงเลือกเป็น Other (เลือก Arduino ก็น่าจะได้) ในส่วนของ Sensor ไม่มีเหมือนกัน เลือกเป็นนน Others (เลือก Humidity ก็น่าจะได้) อย่าลืมในส่วนท้ายให้เลือก Id group เป็น defaultGroup@<your username> แล้วกดปุ่ม Create

Edison09

ระบบจะสร้าง Device ขึ้นมา ให้สามารถกดเข้าไปดูและแก้ไขรายละเอียดได้ ในส่วนที่แสดงสถานะ หากมีการเชื่อมต่อแล้วจะเปลี่ยนจากสีส้มเป็นสีเขียว

Edison10

 ด้านบนสุดของหน้าเว็บไซต์ เลือกเมนู My Settings > My Account จะเข้าหน้า User Edit แสดงข้อมูลผู้ใช้ของเรา ที่เราต้องสนใจคือส่วนของ Apikey ต่างๆ โดยในการส่งข้อมูลเข้ามา (Stream) เราสามารถใช้ Full Privileges Apikey หรือ Automatic Apikey Stream Only ก็ได้

Edison11

การพัฒนาโปรแกรมบน Edison ใช้ Arduino IDE หากยังไม่เคยเริ่มต้นเลย สามารถดูได้จาก Review Intel Edison – What will you make?

ให้สร้างโปรเจคขึ้นมาใหม่ แล้วเขียนโค้ดลงไปดังนี้

/*  Moisture to Carriots - developed 20 Jan 2015 by ThaiEasyElec.com  */
#include <SPI.h>
#include <String.h>
#include <WiFi.h>
// Carriots configuration
#define WEBSITE  "api.carriots.com"
#define API_KEY  "  Your API Key  "  // Private or Stream API Key here!
#define DEVICE   " Your Device  "    // ID such as moisture@thaieasyelec
// Wi-Fi configuration
char ssid[] = "  Your Wi-Fi SSID  "; // SSID of Access Point 
char pass[] = "  Your Password  ";   // Password / Passkey 
int keyIndex = 0;                    // Key Index number (only for WEP)
int status = WL_IDLE_STATUS;
WiFiClient client;                   // create client 
 
void setup() {
  Serial.begin(9600);                // init serial for monitor
  // Connect Wi-Fi network (see Wi-Fi Client Example)
  while ( status != WL_CONNECTED) { 
    Serial.print(F("Attempting to connect to Network named: "));
    Serial.println(ssid);              // print the network name (SSID);
    status = WiFi.begin(ssid, pass);   // connect to Wi-Fi with SSID and Pass
    delay(10000);                      // wait for connection
  } 
  printWifiStatus();                   // print out the status
}
void loop() {
  int moisture = analogRead(A0);           // Read analog from moisture sensor
  String moistureLvl = String(moisture);   // Change to string
  // create data for Carriots
  int length = 0;
  String data = "{\"protocol\":\"v2\",\"device\":\""+String(DEVICE)+"\",\"at\":\"now\",\"data\":{\"MoistureLevel\":\""+String(moistureLvl)+"\"},\"checksum\":\"\"}";
  length = data.length();
  Serial.print(F("Data length: "));
  Serial.println(length);
 
  // Send request
  if (client.connect(WEBSITE,80)) {        // connect to api.carriots.com port 80
    Serial.println(F("Connected!"));
    client.println(F("POST /streams HTTP/1.1"));          // HTTP Post Header
    client.println(F("Host: api.carriots.com"));
    client.println(F("Accept: application/json"));
    client.println(F("User-Agent: Arduino-Carriots"));
    client.println(F("Content-Type: application/json"));
    client.println("carriots.apikey: "+String(API_KEY));  // sent API Key
    client.println("Content-Length: "+String(length));    // sent length
    client.println(F("Connection: close"));
    client.println();
    client.println(data);                                 // sent data
  } else {
    Serial.println(F("Connection failed"));    
    return;
  }
  Serial.println(F("-------------------------------------")); 
    while (client.available()) {
      char c = client.read();                             // read HTTP response
      Serial.print(c);
  }
  Serial.println(F("-------------------------------------"));
  Serial.println(F("\n\nDisconnecting"));
  client.stop();                                          // close connection
  // Wait 10 seconds until next update
  delay(298000);                                          // delay 4 min 58 sec
}
 
void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print(F("SSID: "));
  Serial.println(F(WiFi.SSID()));
  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print(F("IP Address: "));
  Serial.println(ip);
}

          ในส่วนของ Carriots configuration ให้นำ API Key และ Device ที่สมัครและสร้างไว้มาใส่ลงไป

          ในส่วนของ Wi-Fi configuration ให้ใส่ SSID และ Passkey ของ Wireless LAN ที่ใช้งาน

          ในฟังก์ชั่น setup() จะเป็นการตั้งค่า Serial เพื่อแสดงข้อมูล การเชื่อมต่อ Wi-Fi ด้วยฟังก์ชั่น WiFi.begin และแสดงข้อมูลการเชื่อมต่อด้วยฟังก์ชั่น printWifiStatus()

          ในฟังก์ชั่น loop() จะอ่านค่าความชื้นจากเซ็นเซอร์ด้วยฟังก์ชั่น analogRead() แล้วนำค่ามาแปลงแล้วเก็บเป็นสตริงไว้ที่ตัวแปร moistureLvl

          ตัวแปร data เป็นข้อมูล (Payloads) ตามรูปแบบที่ทาง Carriots กำหนดให้ส่ง (Stream) เข้าไปและหาความยาว โดยข้อมูลจัดให้มีรูปแบบดังนี้ (https://www.carriots.com/tutorials/send_stream/arduino_yun)?

{
    "protocol":"v2",
    "device": "devicename@username",
    "at":"now",
    "data":{
        "MoistureLevel":"number"
},
    "checksum":""
}

          ในส่วน Send Request เรียกใช้ฟังก์ชั่น client.connect() ไปที่ api.carriots.com พอร์ต 80 แล้วส่ง HTTP Post แบบ REST https://www.carriots.com/documentation/api/rest_api_headers#request ตามด้วย Payload จากนั้นอ่านค่า HTTP Response ที่ตอบกลับมาแสดงผลออกทาง Serial แล้วหน่วงเวลาก่อนอ่านค่าแล้วส่งไปใหม่

          *** ตอนคอมไพล์หากติด Error ไฟล์ WString.h ให้ตามไปแก้ไขโดยเพิ่ม #define PSTR(s) (s) ลงในส่วนต้นไฟล์ C:\arduino-1.5.3-Intel.1.0.4\hardware\arduino\edison\cores\arduino\WString.h

          รันโปรแกรมแล้วเปิด Serial Monitor เพื่อดูสถานะการทำงาน หากโปรแกรมทำงานถูกต้องจะแสดงข้อมูลดังภาพ โดยในรอบแรกจะเชื่อมต่อ Wi-Fi แล้วแสดง IP Address ที่เชื่อมต่อได้ โดยหลังจากส่งไปแล้ว หากมี response OK กลับมาแปลว่า Carriots ได้รับข้อมูลที่เราส่งไปแล้ว

Edison12

 กลับไปที่เว็บไซต์แล้วในเมนูด้านซ้ายเลือก Data Management > Data streams จะเห็นข้อมูลที่เราส่งมาเข้ามาเก็บ ปล่อยให้ส่งข้อมูลสักพัก หรือจะปรับเวลาดีเลย์ให้ส่งเร็วขึ้นเผื่อให้เห็นผลการทำงานก็ได้

Edison13

  เลือกเมนู Data Management > Publish data > Wizard Widget Graphs จะเข้าสู่หน้า Graphs Wizard ทำตามขั้นตอนบนหน้าจอ 7 ขั้นตอนก็จะสามารถแสดงกราฟของข้อมูลแบบง่ายๆ ได้

Edison14

 แค่เลือกแล้วกด Next ไปเรื่อยๆ เริ่มจากเลือกรูปแบบกราฟ เลือกอุปกรณ์ที่ต้องการ เลือกช่วงวันเวลาของข้อมูล เลือกจำนวนข้อมูลที่ต้องการให้แสดง เลือกข้อมูลหากมีเก็บมากกว่าหนึ่งข้อมูล เลือกแกนแสดงผล และเลือกการจัดเรียงเหตุการณ์ตามเวลาก่อนหลังจากนั้นกดปุ่ม Refresh Values กราฟจะแสดงออกมาให้เห็น นอกจากนี้ยังสามารถนำโค้ดด้านล่างเป็น JavaScript ไปแปะบนเว็บไซต์ที่ต้องการเพื่อดึงกราฟที่ทำไว้ขึ้นมาแสดงง่ายๆ ได้ทันที แจ่มอ่ะ!!!

Edison15

  สุดท้ายเลือกเมนู Rules Management > Wizard Create Listeners > Send Email จะเข้าสู่หน้า Wizard Create Listener Send Email ให้เรากำหนดค่าแค่ 3 ขั้นตอนก็สามารถส่งอีเมลแจ้งเตือนเหตุการณ์ได้แล้ว…ง่ายเกิ๊น O_o

Edison16

 ตรง Entity type ให้เราเลือกได้หลายระดับ ถ้าสร้างเป็นระบบของไว้หลายตัวสามารถเลือกเป็นโปรเจคได้ไล่ไปจนถึงระดับอุปกรณ์แต่ละตัวเลยก็ได้เช่นกัน และสามารถเลือก Id ที่ต้องการได้ ขั้นตอนถัดไปใส่อีเมลปลายทางที่ต้องการให้ส่งไป สุดท้ายกำหนดเงื่อนไขที่จะให้อีเมลถูกส่งออกไปและรายละเอียดข้อความที่ต้องการส่งออกไป ยกตัวอย่างเช่น กำหนดเงื่อนไขว่าถ้าระดับ Moisture Level น้อยกว่า 400 ให้ส่งอีเมล์แจ้ง ในช่อง If expression ระบุลงไปว่า Context.Data.MoistureLvl<400 แล้วกดปุ่ม Create Listener เป็นอันเรียบร้อย

Edison17

จากนั้นลองดึง Moisture Sensor ออกจากดินแล้วดูข้อมูลที่เข้ามาว่ามีค่าเท่าไร มีอีเมลเข้ามาหรือไม่ จะได้รู้ว่ามันจะแจ้งเตือนให้เราไปรดน้ำได้จริงไหม ถ้าใช้ได้หลังจากนี้เราคงไม่ลืมรดน้ำกันอีกต่อไป ^___^