Embedded สัปดาห์ที่ 3 Arduino IoTs – ThingSpeak Interface
Arduino IoTs – ThingSpeak Interface
Thingspeak
เป็นเว็ปที่ให้การบริการในการเก็บข้อมูล และสามารถแสดงข้อมูลแบบ real-time
ได้ ซึ้งเราสามารถ update ข้อมูล
หรือจะเรียกดูข้อมูลได้ตลอดเวลา ที่ไหนก็ได้ เพราะทำงานบน cloud ซึ่ง thingspeak สร้างมาเพื่อต้องการให้ตอบโจทย์ของ IoT
อยู่แล้ว ส่วนข้อมูลที่เก็บอยู่บน cloud นั้นก็ขึ้นอยู่กับเราว่าจะใช้ยังไง
รูปแบบไหน ในการที่จะส่งข้อมูล data ไปไว้บน cloud นั้น ทาง thingspeak ได้มี api ในการติดต่อไว้เรียบร้อยแล้ว
1 การเปิดใช้งาน Thinkspeak
· อันดับแรกเลย ให้ทำการสมัครสมาชิกให้เรียบร้อย
· จากนั้นก็สร้าง channel ขึ้นมา โดยให้เรากดไปที่ My
channel แล้วก็ new channel ขึ้นมา
· หลังจากที่ new channel ขึ้นมาแล้ว ไปที่ channel
setting ก็ป้อนข้อมูลเข้าไป
· อย่าลืมเลือก Make Public
· เสร็จแล้วก็กด save channel
· เมื่อสร้างเสร็จแล้ว ก็จะแสดงหน้าต่าง
ในหน้าต่างนี้จะแสดงข้อมูลเป็นแบบเส้นกราฟ ซึ่งตอนนี้ยังไม่มีข้อมูลใด ๆ
ส่งมาจึงไม่เกิดอะไรขึ้น
2 การ update ข้อมูลไปยัง cloud ผ่าน
api ของ thingspeak
· อันดับแรกให้ดูที่ API KEY ของเราว่ามันคืออะไร โดยกดที่ API Key จะมี Write API Key สำหรับเขียนข้อมูล และ Read API Key สำหรับอ่านข้อมูล ในที่นี้เราจะใช้เฉพาะ Write เท่านั้น
· จากนั้น Add Library Thingspeak ที่นี่ แล้วไปที่ File > Example > Thingspeak > WriteVoltage แล้วกรอกดังต่อไปนี้ แล้ว Upload ไปยัง esp8266
ssid = ชื่อ Wifi , pass = รหัส Wifi
myChannelNumber = Channel ID
myWriteAPIKey = Write API Key
Code :
#include "ThingSpeak.h"
#if defined(ARDUINO_AVR_YUN)
#include "YunClient.h"
YunClient client;
#else
#if defined(USE_WIFI101_SHIELD) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_ARCH_ESP8266)
// Use WiFi
#ifdef ARDUINO_ARCH_ESP8266
#include <ESP8266WiFi.h>
#else
#include <SPI.h>
#include <WiFi101.h>
#endif
char ssid[] = "<YOURNETWORK>"; // your network SSID (name)
char pass[] = "<YOURPASSWORD>"; // your network password
int status = WL_IDLE_STATUS;
WiFiClient client;
#elif defined(USE_ETHERNET_SHIELD)
// Use wired ethernet shield
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
EthernetClient client;
#endif
#endif
#ifdef ARDUINO_ARCH_AVR
// On Arduino: 0 - 1023 maps to 0 - 5 volts
#define VOLTAGE_MAX 5.0
#define VOLTAGE_MAXCOUNTS 1023.0
#elif ARDUINO_SAMD_MKR1000
// On MKR1000: 0 - 1023 maps to 0 - 3.3 volts
#define VOLTAGE_MAX 3.3
#define VOLTAGE_MAXCOUNTS 1023.0
#elif ARDUINO_SAM_DUE
// On Due: 0 - 1023 maps to 0 - 3.3 volts
#define VOLTAGE_MAX 3.3
#define VOLTAGE_MAXCOUNTS 1023.0
#elif ARDUINO_ARCH_ESP8266
// On ESP8266: 0 - 1023 maps to 0 - 1 volts
#define VOLTAGE_MAX 1.0
#define VOLTAGE_MAXCOUNTS 1023.0
#endif
unsigned long myChannelNumber = 31461;
const char * myWriteAPIKey = "LD79EOAAWRVYF04Y";
void setup() {
#ifdef ARDUINO_AVR_YUN
Bridge.begin();
#else
#if defined(ARDUINO_ARCH_ESP8266) || defined(USE_WIFI101_SHIELD) || defined(ARDUINO_SAMD_MKR1000)
WiFi.begin(ssid, pass);
#else
Ethernet.begin(mac);
#endif
#endif
ThingSpeak.begin(client);
}
void loop() {
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// Convert the analog reading
// On Uno,Mega,YunArduino: 0 - 1023 maps to 0 - 5 volts
// On ESP8266: 0 - 1023 maps to 0 - 1 volts
// On MKR1000,Due: 0 - 4095 maps to 0 - 3.3 volts
float voltage = sensorValue * (VOLTAGE_MAX / VOLTAGE_MAXCOUNTS);
// Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different
// pieces of information in a channel. Here, we write to field 1.
ThingSpeak.writeField(myChannelNumber, 1, voltage, myWriteAPIKey);
delay(20000); // ThingSpeak will only accept updates every 15 seconds.
}
*********TEST***********
1. ทดสอบสอบอ่านค่าจาก HDC1080 แล้วส่งค่าอุณหภูมิและความชื้นไปแสดงผลที่ Thingspeak ทุกๆ 30 วินาที
- Add Library HDC1080 จาก here
- เชื่อมต่อ HDC1080 กับ NodeMCU ดังนี้
- HDC1080Data (SDA) = D2
- Clock (SCL) = D1
Code :
#include <ESP8266WiFi.h>
#include <Wire.h>
#include "ClosedCube_HDC1080.h"
ClosedCube_HDC1080 hdc1080;
const char* ssid = "***your wifi*****"; // Wifi name
const char* password = "***your pass*****"; // Wifi Password
String apiKey = "W982GV5NOIVYZX4J"; // Write API Key
const char* server = "api.thingspeak.com";
WiFiClient client;
void setup()
{ Serial.begin(115200);
delay(1000);
Serial.println(); Serial.println();
Serial.print("Connecting to "); Serial.println(ssid);
WiFi.begin(ssid, password);
hdc1080.begin(0x40);
while (WiFi.status() != WL_CONNECTED)
{ delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void loop()
{ Serial.println("-------------------------");
Serial.print("Requesting temperatures...");
float cTemp = hdc1080.readTemperature();
float Humid = hdc1080.readHumidity();
Serial.print("Temperature is: ");
Serial.println(cTemp, 4); // Display Temperature
if (client.connect(server, 80)) // "184.106.153.149" or api.thingspeak.com
{ String postStr = apiKey;
postStr += "&field1=";
postStr += String(cTemp);
postStr += "\r\n\r\n";
client.print("POST /update HTTP/1.1\n");
client.print("Host: api.thingspeak.com\n");
client.print("Connection: close\n");
client.print("X-THINGSPEAKAPIKEY: " + apiKey + "\n");
client.print("Content-Type: application/x-www-form-urlencoded\n");
client.print("Content-Length: ");
client.print(postStr.length());
client.print("\n\n");
client.print(postStr);
Serial.print("Temperature('C)= ");
Serial.println(cTemp, 4);
}
client.stop();
Serial.println("Waiting...");
delay(30000); // thingspeak needs minimum 15 sec delay between updates
}
ผลลัพธ์
2. ออกแบบวงจรให้มีอปุกรณ์เชื่อมต่อ NodeMCU ดังต่อไปน ี้และให้สามารถเรียกดูและควบคุมได้ผ่าน Thingspeak
- HDC1080Data (SDA) = D2
- Clock (SCL) = D1
- LED_1 D3 - LED_2 D4
- LED_3 D5
- Sw_Input_1 D6
แก้ไขเพิ่มเติมจากข้อที่แล้ว
url = "/channels/Channel ID/fields/Field Number /last"
Code :
#include <ESP8266WiFi.h>
#include "ThingSpeak.h"
#include <Wire.h>
#include "ClosedCube_HDC1080.h"
ClosedCube_HDC1080 hdc1080;
WiFiClient client;
const char* host = "api.thingspeak.com";
const char* url = "/channels/261532/fields/3/last";
String line = "";
const int PORT = 80;
WiFiServer server(80);
#define SW1 D6
#define LED1 D3
#define LED2 D4
#define LED3 D5
unsigned long myChannelNumber = 261532;
const char * myWriteAPIKey = "W982GV5N**********";
char ssid[] = "yourNetwork"; // your network SSID (name)
char pass[] = "password"; // your network password
void setup()
{ Serial.begin(115200);
delay(10);
Serial.print("Connecting to ");
pinMode(SW1, INPUT_PULLUP);
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
Serial.println(ssid);
WiFi.begin(ssid, pass);
hdc1080.begin(0x40);
while (WiFi.status() != WL_CONNECTED)
{ delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
ThingSpeak.begin(client);
}
void loop()
{
Serial.println("Wait... ");
float temp = hdc1080.readTemperature();
ThingSpeak.setField(1,temp);
float humi = hdc1080.readHumidity();
ThingSpeak.setField(2,humi);
int sw = digitalRead(SW1);
ThingSpeak.setField(3,sw);
ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
Serial.print("Send Data to Thinkspeak = ");
Serial.print(temp); Serial.print(" "); Serial.print(humi); Serial.print(" ");
Serial.println(sw);
Serial.print("\n");
delay(22000);
WiFiClient client = server.available();
Serial.print("Connecting to "); Serial.println(host);
Serial.print("Requesting URL : "); Serial.println(url);
if (!client.connect(host, PORT))
{ Serial.print(".");
return;
}
else
{ client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n");
delay(50);
Serial.println("SEND !!");
}
while (!client.available())
{}
while (client.available())
{ line += (char)client.read();
}
Serial.println();
Serial.println("GET SUCCESSFULLY !!");
Serial.print("###### rawData >> "); Serial.println(line);
int lengthData = line.length();
char data = line[lengthData - 1];
String s = (String)"Position " + lengthData + (String)", Data " + data;
Serial.print("###### splitted >> "); Serial.println(s);
switch (data) {
case '1':
digitalWrite(LED1, LOW);
Serial.print("LED-1 = ON");
break;
case '0':
digitalWrite(LED1, HIGH);
Serial.print("LED-1 = OFF");
break;
}
line = "";
Serial.println();
delay(3000);
}
ผลลัพธ์#include "ThingSpeak.h"
#include <Wire.h>
#include "ClosedCube_HDC1080.h"
ClosedCube_HDC1080 hdc1080;
WiFiClient client;
const char* host = "api.thingspeak.com";
const char* url = "/channels/261532/fields/3/last";
String line = "";
const int PORT = 80;
WiFiServer server(80);
#define SW1 D6
#define LED1 D3
#define LED2 D4
#define LED3 D5
unsigned long myChannelNumber = 261532;
const char * myWriteAPIKey = "W982GV5N**********";
char ssid[] = "yourNetwork"; // your network SSID (name)
char pass[] = "password"; // your network password
void setup()
{ Serial.begin(115200);
delay(10);
Serial.print("Connecting to ");
pinMode(SW1, INPUT_PULLUP);
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
Serial.println(ssid);
WiFi.begin(ssid, pass);
hdc1080.begin(0x40);
while (WiFi.status() != WL_CONNECTED)
{ delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
ThingSpeak.begin(client);
}
void loop()
{
Serial.println("Wait... ");
float temp = hdc1080.readTemperature();
ThingSpeak.setField(1,temp);
float humi = hdc1080.readHumidity();
ThingSpeak.setField(2,humi);
int sw = digitalRead(SW1);
ThingSpeak.setField(3,sw);
ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
Serial.print("Send Data to Thinkspeak = ");
Serial.print(temp); Serial.print(" "); Serial.print(humi); Serial.print(" ");
Serial.println(sw);
Serial.print("\n");
delay(22000);
WiFiClient client = server.available();
Serial.print("Connecting to "); Serial.println(host);
Serial.print("Requesting URL : "); Serial.println(url);
if (!client.connect(host, PORT))
{ Serial.print(".");
return;
}
else
{ client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n");
delay(50);
Serial.println("SEND !!");
}
while (!client.available())
{}
while (client.available())
{ line += (char)client.read();
}
Serial.println();
Serial.println("GET SUCCESSFULLY !!");
Serial.print("###### rawData >> "); Serial.println(line);
int lengthData = line.length();
char data = line[lengthData - 1];
String s = (String)"Position " + lengthData + (String)", Data " + data;
Serial.print("###### splitted >> "); Serial.println(s);
switch (data) {
case '1':
digitalWrite(LED1, LOW);
Serial.print("LED-1 = ON");
break;
case '0':
digitalWrite(LED1, HIGH);
Serial.print("LED-1 = OFF");
break;
}
line = "";
Serial.println();
delay(3000);
}
หลังจาก Upload ไปยัง esp8266 และต่อวงจรตามที่กำหนดได้ถูกต้อง จากสามารถส่งค่าปุ่มกดไปยัง Thingspeak และอ่านค่ากลับมายัง esp8266 จากนั้นจะสามารถควบคุม LED ได้ โดยในตัวอย่างได้นำเสนอแค่ 1 ปุ่มกด แสดง 1 LED
Comments
Post a Comment