ยุค Internet of Thing กำลังจะมาถึง ตอนนี้จะหันไปทางไหน ก็จะมีโฆษณา บ้านเมืองในอนาคต อุปกรณ์ต่างๆ สะดวกสบาย และอุปกรณ์จะควบคุมจากที่ไหน ก็ได้ (ถ้าอินเตอร์เน็ทเข้าถึง) ผมเลยอยากจุดประกาย ด้วยโครงการง่ายๆ อย่างเช่น Smart Bulb ,Smart Plug ,Smart Relay , Smart Outlet อยากจะเรียกอะไร ก็เรียกไปเลยนะครับ ซึ่งในโปรเจครูปแบบนี้ กำลังนิยมเป็นจำนวนเยอะมากใน Kickstarter เห็นระดมทุนเพื่อสร้างกันบ่อยๆ
สำหรับโปรเจคนี้ Wifi Light Bulb ของทางผม เป็นแบบเริ่มต้นนะครับ แค่เปิดปิดหลอดไฟ หรือ อุปกรณ์ใดๆ ผ่าน Smart phone ได้ แต่ผมขยับออกมาออกมาอีกนิด ให้เราดูสถานะการทำงานของหลอดไฟ ผ่านมือถือได้ ซึ่งตอนนี้จะควบคุมพร้อมกันหลายตัวได้ครับ โปรเจคนี้ยังไม่ได้ Smart มากนะครับ น่าจะพอจุดประกายให้ พวกเราได้ไอเดีย กับ หาแนวทางพัฒนากันต่อได้ อันนี้เป็น diagram บอกส่วนประกอบการทำงาน หัวใจหลักๆอยู่ที่บอร์ด arduino ที่เป็น web server
โปรเจคประกอบไปด้วย 2 ส่วน
Android App
- ใช้ App Inventor 2 ตั้งใจจะให้ต่อยอดกันง่ายๆ
- ตัวโปรแกรมสามารถกดเปลี่ยนหมายเลข IP ได้
- ควบคุมอุปกรณ์ ได้แค่ตัวเดียว ( ถ้าอยากเพิ่มต้องลองทำต่อเองนะ )
- อ่านสถานะของหลอดไฟได้ ว่าตอนนี้ เปิดหรือปิดอยู่
ให้ดูว่า App นี้ใช้อะไรบ้าง หลักที่ต้องใช้นะครับ คือ Web นะครับ ตัว Web จะทำให้ App ยิงคำสั่งไปยังหน้า WebServer ได้ครับ แล้วภายในตัวจะมีรับ Content เพื่อเอามาตรวจสอบเป็นสถานะได้ครับ ส่วนวิธีใช้ เราดูใน code ไฟล์ .aia ที่ผมทิ้งไว้แล้วกัน โปรแกรม App Inventor ผมใช้ไม่ได้ค่อยมากครับ ใครอยากจะเพิ่มเติมให้สวย ผมฝากด้วยนะครับ
ผมลองหาดูว่า App Inventor สามารถสื่อสาร รูปแบบไหน ผ่าน tcp/ip ได้บ้าง ก็พบแค่ สามารถต่อเข้าเวปได้ ผมจึงออกแบบส่วนใน arduino server ให้ต่อสนองกับเวป หาวิธีเปิด socket อย่างเดียวไม่เจอ เอาเป็นว่าใครพึ่งลองทำ ทำแบบนี้ไปก่อนครับ แต่ถ้าใครเชี่ยวชาญแล้ว เจอวิธีอะไรที่น่าสนใจ comment บอกผมด้วย
หน้าตาของส่วน Block
มาดูส่วนประกอบของ Block ใน App Intentor2 ผมจะใช้ส่วนประกอบที่เพิ่มเติม web และ Timer
- Web จะใช้ส่ง Request ไปยัง Server (Arduino) ซึ่งจะเหมือน server ได้รับคำสั่ง มันจะส่ง status กลับไปที่ตัว client ที่เรียกของข้อมูล เลยทำให้ App รู้สถานะ เปิด หรือ ปิดได้
- เพิ่มเติมจะมี timer ที่ทางผมตั้งเวลาให้ทำงานทุก 3000ms ให้เข้าไป update หน้า web ด้วย เพื่อ ที่จะได้ update สถานะหลอดไฟครับ
ผมก็ทิ้งไฟล์ App ไว้โหลดได้ตรงไหนล่ะครับ LightControlV2.aia
Arduino Mini WebServer ( Arduino + ESP8266 )
ถือเป็นการต่อยอดจากบทความที่ผ่านมา ที่ทางเราทำเวป server ลงไปใน Arduino + ESP8266 ซึ่งในครั้งนี้ เราได้แก้ไขปัญหาเรื่องการ update ข้อมูลไม่ทันบ้าง และ เพิ่มส่วนการ check Status ระหว่างการสื่อสาร Arduino กับ ESP8266 ให้มันทำงานถูกต้องยิ่งขึ้น ซึ่งมันเลยช่วยให้เสถียรขึ้น และ ทำงานได้พร้อมกัน ไม่มีปัญหา (แต่ยังมีหลุดๆบ้าง กด reset น่าจะหายครับ)
- ตัว Server ยังเป็น Webserver มีหน้า Page home และ Page led
- สามารถ Get Status ระหว่าง ESP8266 กับ Arduino ได้ดียิ่งขึ้น
- แก้ไขปัญหา เรื่องการรับส่งข้อมูล เชื่อมต่อพร้อมกัน หลายๆ client
- ทำงานได้ทั้ง Arduino UNO ,Arduino MEGA, Arduino Leonadro
- ยังไม่ได้ทำเป็น Library นะ เหมาะกับคนที่อยากรู้ลองแบบเบื้องต้น ว่ามันทำงานได้อย่างไง (ถือเป็นของดีหรือนิ)
โปรแกรม Webserver ตัวใหม่ หรือ ไปโหลดได้ที่ Github
#include <SoftwareSerial.h> //Leonardo //Serial_ & dbgTerminal = Serial; //HardwareSerial & espSerial = Serial1; ////UNO & M328P #include SoftwareSerial dbgTerminal(10, 11); // RX, TX HardwareSerial & espSerial = Serial; // ////MEGA2560 //HardwareSerial & dbgTerminal = Serial; //HardwareSerial & espSerial = Serial1; // set pin numbers: const int ledPin = 13; // the number of the LED pin const int ESP8266_CHPD = 4; // Variables will change: int ledState = HIGH; // ledState used to set the LED #define BUFFER_SIZE 128 char buffer[BUFFER_SIZE]; void setup() { pinMode(ledPin, OUTPUT); //pinMode(ESP8266_CHPD, OUTPUT); dbgTerminal.begin(9600); // Serial monitor espSerial.begin(115200); // ESP8266 //while (!dbgTerminal) { // ; // wait for serial port to connect. Needed for Leonardo only //} dbgTerminal.println(F("ESP8266 demo.")); //hardReset(); //delay(2000); clearSerialBuffer(); //connect to router //connectWiFi("YOUR_SSID", "YOUR_PASSWORD"); //test if the module is ready //dbgTerminal.print("AT : "); //dbgTerminal.println( GetResponse("AT",100) ); //Change to mode 1 //dbgTerminal.print("AT+CWMODE=1 : "); //dbgTerminal.println( GetResponse("AT+CWMODE=1",10) ); //set the multiple connection mode dbgTerminal.print(F("AT+CIPMUX=1 : ")); dbgTerminal.println( GetResponse("AT+CIPMUX=1",10) ); //set the server of port 80 check "no change" or "OK" dbgTerminal.print(F("AT+CIPSERVER=1,8888 : ")); dbgTerminal.println( GetResponse("AT+CIPSERVER=1,8888", 10) ); //set time out //dbgTerminal.print("AT+CIPSTO=15 : "); //dbgTerminal.println( GetResponse("AT+CIPSTO=15",10) ); //print the ip addr dbgTerminal.print(F("ip address : ")); dbgTerminal.println( GetResponse("AT+CIFSR", 10) ); delay(200); dbgTerminal.println(); dbgTerminal.println(F("Start Webserver")); digitalWrite(ledPin,ledState); } void loop() { int ch_id, packet_len; char *pb; espSerial.readBytesUntil('\n', buffer, BUFFER_SIZE); if(strncmp(buffer, "+IPD,", 5)==0) { // request: +IPD,ch,len:data sscanf(buffer+5, "%d,%d", &ch_id, &packet_len); if (packet_len > 0) { // read serial until packet_len character received // start from : pb = buffer+5; while(*pb!=':') pb++; pb++; if (strncmp(pb, "GET /led", 8) == 0) { dbgTerminal.print(millis()); dbgTerminal.print(" : "); dbgTerminal.println(buffer); dbgTerminal.print( "get led from ch :" ); dbgTerminal.println(ch_id); delay(100); clearSerialBuffer(); if (ledState == LOW) ledState = HIGH; else ledState = LOW; digitalWrite(ledPin, ledState); homepage(ch_id); } else if (strncmp(pb, "GET / ", 6) == 0) { dbgTerminal.print(millis()); dbgTerminal.print(" : "); dbgTerminal.println(buffer); dbgTerminal.print( "get Status from ch:" ); dbgTerminal.println(ch_id); delay(100); clearSerialBuffer(); homepage(ch_id); } } } clearBuffer(); } void homepage(int ch_id) { String Header; Header = "HTTP/1.1 200 OK\r\n"; Header += "Content-Type: text/html\r\n"; Header += "Connection: close\r\n"; //Header += "Refresh: 5\r\n"; String Content; Content = "D"; Content += String(ledState); Header += "Content-Length: "; Header += (int)(Content.length()); Header += "\r\n\r\n"; espSerial.print("AT+CIPSEND="); espSerial.print(ch_id); espSerial.print(","); espSerial.println(Header.length()+Content.length()); delay(10); // for debug buffer serial error //while (espSerial.available() >0 ) { // char c = espSerial.read(); // dbgTerminal.write(c); // if (c == '>') { // espSerial.print(Header); // espSerial.print(Content); // } //} if (espSerial.find(">")) { espSerial.print(Header); espSerial.print(Content); delay(10); } // Serial1.print("AT+CIPCLOSE="); // Serial1.println(ch_id); } // Get the data from the WiFi module and send it to the debug serial port String GetResponse(String AT_Command, int wait){ String tmpData; espSerial.println(AT_Command); delay(10); while (espSerial.available() >0 ) { char c = espSerial.read(); tmpData += c; if ( tmpData.indexOf(AT_Command) > -1 ) tmpData = ""; else tmpData.trim(); } return tmpData; } boolean hardReset() { String tmpData; digitalWrite(ESP8266_CHPD,LOW); delay(100); digitalWrite(ESP8266_CHPD,HIGH); delay(1000); while ( espSerial.available() > 0 ) { char c = espSerial.read(); tmpData +=c; espSerial.write(c); if ( tmpData.indexOf("Ready") > -1 ) { //Serial.println("Ready"); clearBuffer(); return 1; } } } void clearSerialBuffer(void) { while ( espSerial.available() > 0 ) { espSerial.read(); } } void clearBuffer(void) { for (int i =0;i<BUFFER_SIZE;i++ ) { buffer[i]=0; } } boolean connectWiFi(String NetworkSSID,String NetworkPASS) { String cmd = "AT+CWJAP=\""; cmd += NetworkSSID; cmd += "\",\""; cmd += NetworkPASS; cmd += "\""; dbgTerminal.println(cmd); dbgTerminal.println(GetResponse(cmd,10)); }
ขอโทษนะครับ รบกวนถามนิดนึงครับ ตัวนี้สมาร์ทโฟนต้องต่อกับ wifi อย่างเดียวหลอครับ ใช้ 3G แทนได้มั้ยครับ
พี่ครับใช้code ตามนี้ได้เลยหรือเปล่าครับ
วงจรคือตามนี้ใช้ไหมครับ
uno to esp8266
rx(10) tx
tx(11) rx
3.3v vcc
gnd gnd
4 ch_pd
code ต้องแก้ตรง
boolean connectWiFi(String NetworkSSID,String NetworkPASS)
เป็นชื่อ wifiของเรา และ pass ของเราใช่ไหมครับ
ผมทำตามนี้ถูกเปล่าครับ
ผมกำลังหัดเล่นครับ
ไม่ทราบว่าพี่ใช้ได้หรือยังครับ ถ้าได้แล้วช่วยแนะนำหน่อยนะครับ พอดีผมทำโปรเจ็คส่งอาจารย์อะครับ ขอบคุณมากครับ
ขอบคุณมากครับที่แบ่งปันความรู้ แต่ผมขอโค้ดที่พี่ช้างใช้เลยได้ไหม๋ครับ ของผมลองแล้ว ไม่ขึ้นอะครับ
ขออภัยใน Google แปลของฉัน ผมชอบคลิปวิดีโอของคุณผมต้องการที่จะเก็บมัน แต่ฉันสามเณร. ((
นี่คือโปรแกรมเฉพาะสำหรับ Arduino หรือไม่ ซอฟท์แว esp8266 ไม่?
พี่ครับ ถ้าหากผมใช้ nodeMCUสามารถใช้โค๊ตนี้ได้รึป่าวครับ
โหลดไฟล์แอบไม่ได้คับ
รบกวนสอบถามหากพอร์ต80ถูกปิดกั้น http://ย้ายไปพอร์ตอื่นแล้ว ใช้ไม่ได้ ต้องทำไงครับ