Back to the basic: connect ESP8266 and web page through cloud MQTT เชื่อมต่อ และควบคุม ESP8266 กับเว็บเพจ ผ่านคลาวน์ MQTT

Back to the basic: connect ESP8266 and web page through cloudMQTT
เชื่อมต่อ และควบคุม ESP8266 กับเว็บเพจ ผ่านคลาวน์ MQTT

คราวนี้เรากลับมาทำโปรเจคพื้นฐานโดยควบคุมไฟกระพริบ เช็คค่าอุณหภูมิ จากบอร์ด ESP8266 ด้วยเว็บเพจ โดยเว็บเพจจะแสดงค่าอุณหภูมิทุกครั้งที่เรากดปุ่มที่บอร์ด และมีปุ่มให้เรากดควบคุมไฟLEDจากเว็บเพจ

ก่อนอื่นต้องทำการสมัครสมาชิกและสร้าง CloudMQTT Instance ขึ้นมาก่อน หลังจากนั้นให้เข้าไปดูข้อมูลต่างๆเพื่อนำไปใช้ยืนยันความปลอดภัย และการเข้าถึงระบบคลาวน์

Setup cloudMQTT account and get your user, password, port and Websockets Port which we aim to use them in Arduino script.09-11-2016-20-58-22

Click on WebSocket UI to open WebSocket window terminal where we will see all activities between ESP8266 and web page.09-11-2016-21-03-26

โปรเจคนี้ผมใช้บอร์ดของ SparkFun ซื้อมาเล่นนานแล้วไม่ค่อยใช้งาน เลยปัดฝุ่นนำกลับมาอีกครั้งบอร์ดนี้มีเซนเซอร์อยู่ในตัวเองครับ ส่วนท่านมีบอร์ดอื่นที่เป็น ESP8266 ก็ใช้ได้เช่นเดียวกัน แต่ท่านอาจจะต้องต่อ LED และต่อเซนเซอร์อุณหภูมิ ความชื้นเอง ซึ่งสามารถหาข้อมูลได้ง่ายมีอยู่ทั่วไปครับ

In this project, I use ESP8266 on the SparkFun Blynk Board which it already has onboard temperature/humidity sensor and NeoPixel.13794-04a

ใช้โปรแกรม Arduino IDE เพื่อเขียนโปรแกรม โดยนำโค้ดด้านล่างไปปรับแต่งดูครับ

Apply the following source code in your Arduino IDE to fit with your ESP8266 module.

/*
MQTT publish/subscriber example https://www.cloudmqtt.com/

- connects to an MQTT server
- publishes to the topic "showTemp"
- subscribes to the topic "showTemp"

Modified by SpidyHero
*/

#include <ESP8266WiFi.h>
#include <PubSubClient.h> //using CloudMQTT lib
#include <BlynkSimpleEsp8266.h> //using Blynkboard lib
#include <Adafruit_Si7021.h> //using temperature&Humidity sensor on board
#include <Adafruit_NeoPixel.h> //using Adafruit_NeoPixel on board
#include <Wire.h>

#define WS2812_PIN 4 // Pin connected to WS2812 LED
Adafruit_Si7021 tempSensor = Adafruit_Si7021(); //using Si7021 (temperature&Humidity sensor on board)
Adafruit_NeoPixel rgb = Adafruit_NeoPixel(1, WS2812_PIN, NEO_GRB + NEO_KHZ800); //using Adafruit_NeoPixel on board

// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 0; // NodeMCU pushbutton pin
const int ledPin = 5; // LED pin on NodeMCU

// variables will change:
int buttonState = 0; // variable for reading the pushbutton status

//-------------------------------//

const char *ssid = "xxxxxxx"; // your WiFi network name
const char *pass = "xxxxxxx"; //your WiFi network password

// Update these with values suitable for your network.
IPAddress server(54,75,121,168); // CloudMQTT Server IP, ping m20.cloudmqtt.com to get this IP

WiFiClient wclient;
PubSubClient client(wclient,"m20.cloudmqtt.com", 15346); //your MQTT Port number

// use this function to receive message from CloundMQTT subscribes topic (showTemp)
void callback(const MQTT::Publish& pub) {
Serial.print(pub.topic());
Serial.print(" => ");
Serial.println(pub.payload_string());

//check if there is message "555" is sent to this topic, then blink LED
if (pub.payload_string()== "555"){//check if there is message "555" is sent to this topic, then blink LED
Serial.println("Blinking LED");
blink(10);
}
}

// setup
void setup()
{
tempSensor.begin(); //setup temp&humid sensor
rgb.begin(); // setup Neo Pixel LED
rgb.show(); //// Initialize all pixels to 'off'

// Setup console
Serial.begin(115200);
delay(10);
Serial.println();
Serial.println();

// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);

client.set_callback(callback);

//----setup WiFi connection----//
WiFi.begin(ssid, pass);

int retries = 0;
while ((WiFi.status() != WL_CONNECTED) && (retries < 10)) {
retries++;
delay(500);
Serial.print(".");
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("");
Serial.println("WiFi connected");
}

//----MQTT validate connection ----//
//char* user = "afdwjnnv"; // your MQTT user
//char* pass = "wY1CUsaq5jn2"; // your MQTT password

if (client.connect(MQTT::Connect("ESP8266Client")
.set_auth("afdwjnnv", "wY1CUsaq5jn2"))) {
Serial.println();
Serial.println("Publish success.");
client.publish("showTemp","ESP8266connected"); //Publish/send message to clound on showTemp

Serial.println("Subscribe success.");
client.subscribe("showTemp"); //Subscribes topic to receive message from cloud and print on serial monitor

}
}

void loop()
{

client.loop();

//---press button to turn on/off LED and display temperature

// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);

// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (buttonState == HIGH) {
// turn LED off:
digitalWrite(ledPin, LOW);
}
else {
// turn LED on:
// send message to your topic (showTemp) when release button
digitalWrite(ledPin, HIGH);
client.publish("showTemp",String (tempSensor.readTemperature())) ; // send message to "showTemp" when release button
Serial.print("button is pushed");
Serial.println();
delay(300);
}

}
void blink(int a) {
for (int i=0; i <= a; i++){
digitalWrite(ledPin, HIGH); // turn the LED on (HIGH is the voltage level)
rgb.setPixelColor(0, 254); //set Neo Pixel color
rgb.show();//display Neo Pixel color
delay(100); // wait for a second
digitalWrite(ledPin, LOW); // turn the LED off by making the voltage LOW
rgb.setPixelColor(0, 0); //turn off
rgb.show();

delay(100); // wait for a second
}

}

จุดสังเกตุ
บรรทัดที่22 23 ให้ระบุ Login และ Password ของ WiFi ที่เราใช้เชื่อมต่ออินเทอร์เน็ต
บรรทัดที่ 26 ให้ระบุที่อยู่ของคลาวน์เซอเวอร์ ถ้าไม่ทราบเลขให้ทำการ ping ดูครับ
บรรทัดที่29 ให้ระบุพอร์ทของคลาวน์เซอเวอร์
บรรทัดที่83 ให้ระบุ User และ Password ของคลาวน์เซอเวอร์

Creating web page
Now, we need to create a web page to display and control LED on the ESP8266 board through cloudMQTT.

ในส่วนของการพัฒนาเว็บเพจ เราอ้างอิงจากตัวอย่างนี้ cloudmqtt websocket แล้วทำการเพิ่มเติมปุ่ม และส่วนแสดงผลอุณหภูมิ

Please apply the following script and try to test it. For example, when you hit a button on the Blynk board,


<!DOCTYPE html>
<html>
			<link async href="http://fonts.googleapis.com/css?family=Fredoka%20One" data-generated="http://enjoycss.com" rel="stylesheet" type="text/css"/>

<style>
.long-shadow {
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
bottom: 0;
padding: 25px;
border: none;
font: normal 30px/2 "Fredoka One", Helvetica, sans-serif;
color: rgba(255,255,255,1);
text-align: center;
-o-text-overflow: clip;
text-overflow: clip;
background: #93c47d;
text-shadow: 3px 3px 0 #0199d9 , 4px 4px 0 #0199d9 , 5px 5px 0 #0199d9 , 6px 6px 0 #0199d9 , 7px 7px 0 #0199d9 , 8px 8px 0 #0199d9 , 9px 9px 0 #0199d9 , 10px 10px 0 #0199d9 , 11px 11px 0 #0199d9 , 12px 12px 0 #0199d9 , 13px 13px 0 #0199d9 , 14px 14px 0 #0199d9 , 15px 15px 0 #0199d9 , 16px 16px 0 #0199d9 , 17px 17px 0 #0199d9 , 18px 18px 0 #0199d9 , 19px 19px 0 #0199d9 , 20px 20px 0 #0199d9 ;
}
.enjoy-css {
display: inline-block;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
margin: 0.5em;
padding: 0 1.5em;
border: 1px solid rgba(211,211,211,1);
-webkit-border-radius: 0.2em;
border-radius: 0.2em;
font: normal normal bold 1em/2em Arial, Helvetica, sans-serif;
color: rgba(114,114,114,1);
text-align: center;
-o-text-overflow: clip;
text-overflow: clip;
white-space: nowrap;
background: rgba(234,234,234,1);
-webkit-box-shadow: 0 0 1px 1px rgba(255,255,255,0.8) , 0 1px 0 0 rgba(0,0,0,0.298039) ;
box-shadow: 0 0 1px 1px rgba(255,255,255,0.8) , 0 1px 0 0 rgba(0,0,0,0.298039) ;
text-shadow: 0 1px 0 rgba(255,255,255,0.8) ;
-webkit-transition: all 200ms cubic-bezier(0.42, 0, 0.58, 1) 10ms;
-moz-transition: all 200ms cubic-bezier(0.42, 0, 0.58, 1) 10ms;
-o-transition: all 200ms cubic-bezier(0.42, 0, 0.58, 1) 10ms;
transition: all 200ms cubic-bezier(0.42, 0, 0.58, 1) 10ms;
}

.enjoy-css:hover {
cursor: pointer;
border: 1px solid rgba(178,178,178,1);
color: rgba(76,76,76,1);
-webkit-box-shadow: 0 0 1px 1px rgba(255,255,255,0.8) inset, 0 1px 0 0 rgba(0,0,0,0.298039) ;
box-shadow: 0 0 1px 1px rgba(255,255,255,0.8) inset, 0 1px 0 0 rgba(0,0,0,0.298039) ;
}

</style>

<body>
<div class="long-shadow">

Temperature (°C) = <temp></temp>
<div class="enjoy-css" onclick="blink()">Blink LED</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js" type="text/javascript"></script>
<script type="text/javascript">

 // Create a client instance
 //client = new Paho.MQTT.Client("host", Websockets Port,"client_id");
 client = new Paho.MQTT.Client("m20.cloudmqtt.com", 35346, "web_" + parseInt(Math.random() * 100, 10)); 

 // set callback handlers
 client.onConnectionLost = onConnectionLost;
 client.onMessageArrived = onMessageArrived;
 var options = {
 useSSL: true,
 userName: "afdwjnnv",
 password: "wY1CUsaq5jn2",
 onSuccess:onConnect,
 onFailure:doFail
 }

 // connect the client
 client.connect(options);

 // called when the client connects
 function onConnect() {
 // Once a connection has been made, make a subscription and send a message.
 console.log("onConnect");
 client.subscribe("showTemp");
 message = new Paho.MQTT.Message("Connected!!! Hello from web page");
 message.destinationName = "showTemp";
 client.send(message);
 }

 function doFail(e){
 console.log(e);
 }

 // called when the client loses its connection
 function onConnectionLost(responseObject) {
 if (responseObject.errorCode !== 0) {
 console.log("onConnectionLost:"+responseObject.errorMessage);
 }
 }

 // called when a message arrives
 function onMessageArrived(message) {
 console.log("onMessageArrived:"+message.payloadString);
 document.querySelector('temp').innerHTML = message.payloadString;
 }

 function blink() {
 // Once a connection has been made, make a subscription and send a message.

 message = new Paho.MQTT.Message("555");
 message.destinationName = "showTemp";
 client.send(message);
 }
 </script>

</body>
</html>

เสร็จแล้วทำการทดสอบเลยครับ เมื่อเปิดหน้าเว็บขึ้นมา เว็บจะทำการลงทะเบียนในหัวข้อที่เราตั้งขึ้นมาชื่อ showTemp และจะส่งข้อความ Hello… ไปที่Cloud และเว็บก็จะรับข้อความนั้นมาโชว์บนหน้าเว็บเพจ หลังจากนั้น เมื่อเรากดปุ่มที่บอร์ด ESP8266 บอร์ด ESP8266 จะส่งข้อมูลอุณหภูมิไปที่หัวข้อ showTemp และเว็บเพจก็จะนำค่านั้นมาแสดงผล เมื่อเรากดปุ่มที่เว็บเพจ เว็บเพจจะส่งข้อความ 555 ไปที่Cloud บอร์ดESP8266เช็คข้อความว่ามี 555 เข้ามาแล้วก็จะทำการกระพริบไฟ LED

11-11-2016-15-08-42

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s