ผมจะไม่ review board นะครับ เพราะต้องให้ท่านอื่นที่มีความรู้แน่นอนกว่าผมเขียนจะดีกว่า หรือท่านอาจหาอ่านได้เองจากเว็บไซต์ของ Espressif เลยก็ดี ครับ ส่วนเรื่องที่จะเขียนคือการรับ-ส่งข้อมูลระหว่าง Node32s กับ Raspberry Pi ครับ ผ่าน TCP ครับ
ความจริงแล้วทาง Espressif เขามี SDK สำหรับการเขียนโปรแกรม แต่ด้วยความชอบ Arduino ผมเลยเลือกที่จะใช้ Arduino IDE เพื่อใช้การเขียนโปรแกรมทางฝั่ง Node32s ซึ่งก็มีข้อจำกัดอยู่ เพราะในเวลาที่เขียนเรื่องนี้ Arduino - IDE ยังไม่สนับสนุน Esp32 เต็มที่ สามารถเรียกใช้งานได้เพียงบางส่วนเท่านั้นเอง แต่ก็มีสนับสนุน WiFi Client แล้ว ซึ่งเป็นจุดที่จะนำมาเขียนในครั้งนี้ ครับ
1. ปรับแต่ง Arduino-IDE
ก่อนอื่นเลยต้องมี Arduino-IDE ก่อน ครับ (https://www.arduino.cc/en/Main/OldSoftwareReleases)ขั้นตอนการปรับแต่งในระบบปฏิบัติการ Windows อ่านได้จากhttp://www.ayarafun.com/2016/10/arduino-esp32-first-touch/ ครับ แต่ผมใช้ Ubuntu วิธีการจะต่างไปเล็กน้อย เพราะ Linux จะมี python 2.7 ติดตั้งมาแล้ว เหลือแต่ pyserial (ถ้าเป็น raspbian ข้ามไปเลย ครับ เพราะมีมาครบหมดแล้ว) ติดตั้งด้วย
$ sudo pip install pyserial
หมายเหตุ : pyserial จะทำงานกับระบบ 32 bit ครับหลังต่อ PC เข้ากับ Node32s แล้ว เปิด Arduino - IDE ขึ้นมา ผมเลือก Board เป็น Nano32
2. สร้าง Code ฝั่ง Node32s
ตอนนี้ท่านหา สาย micro USB มาต่อระหว่าง Node32s กับคอมพิวเตอร์ เหมือนการต่อ Arduino ได้เลย เปิด Arduino IDE ขึ้นมาแล้วพิมพ์ code ข้างล่างตามลำดับส่วนที่ 1 : Library
#include <WiFi.h>
ส่วนที่ 2 : กำหนดตัวแปร
const char* _SSID = "xxxxxxxxxx";
const char* _PWD = "xxxxxxxxxx";
const char* _HOST = "xxxxxxxxxx";
const uint16_t _PORT = 9999;
boolean _ready;
String msgs[3] = {"Hello I am Node32s ","I am from Thailand ","Nice to meet you "};
int c = 0;
_SSID คือชื่อของ router หรือ access point_PWD คือ รหัสผ่านของ router หรือ access point
_HOST คือ address ของ server ในกรณีนี้หมายถึง ip address ของ raspberry pi
_PORT คือ หมายเลข port สื่อสารบน raspberry pi
_ready คือ ตัวแปรใช้บอกสถานะการทำงาน
msgs คือ ข้อความที่ใช้ส่งไปยัง Raspberry Pi
ส่วนที่ 3 : ต่อ WiFi
void wifi_connect(){
if(WiFi.isConnected()) return;
Serial.println("Connecting to "+String(_SSID));
WiFi.begin(_SSID,_PWD);
while(WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi Connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
_ready = true;
}
code ส่วนนี้ใช้ในการเชื่อมต่อไปยัง router หรือ access point คำสั่งที่ควรรู้จักคือ- WiFi.begin(ssid,pwd) เป็นการเชื่อมไปยัง router เพื่อของ IP address
- WiFi.status() แจ้งให้ทราบถึงสถานะการเชื่อมต่อกับ router
- WiFi.isConnected() จะให้ true หากว่า Esp32 ได้ทำการติดต่อกับ router แล้ว
- WiFi.localIP() บอกให้ทราบว่าขณะนั้น Esp32 มี IP address เป็นอะไร
ส่วนที่ 4 : ส่งข้อความให้ Rasbperry Pi
void sendMsg(String msg){
WiFiClient client;
Serial.println("");
Serial.print("Send : ");
Serial.println(msg);
if(!client.connect(_HOST,_PORT)){
Serial.println("Connection faild.");
return;
}
byte buf[20];
msg.getBytes(buf,20);
client.write(buf,20);
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000)
{
Serial.println(">>> Client Timeout !");
client.stop();
return;
}
}
while (client.available()) {
String line = client.readStringUntil('\r');
Serial.print("Recieve :");
Serial.println(line);
Serial.println("--------------------------");
}
client.stop();
_ready = true;
}
- เริ่มต้นด้วยการสร้างตัวแปร client ซึ่งเป็น instance ของ WiFiClient
- ทำการเชื่อมต่อไปยังอุปกรณ์ปลายทาง (Raspberry Pi) ด้วยคำสั่ง client.connect(_HOST,_PORT)
- เนื่องจาก Python3 ที่จะใช้งานทางฝั่ง Raspberry Pi นั้นจะรับ-ส่งข้อมูลด้วย data type เป็น byte ไม่ใช่ String ดังนั้นเราต้องเปลี่ยนข้อความให้กลายเป็น byte ด้วยคำสั่ง getBytes(buf,length) โดย ข้อความที่เป็น byte จะถูกเก็บไว้ในตัวแปร buf ส่วน length นั้นคือความยาวหรือจำนวนตัวอักษรของข้อความ
- การส่งข้อความออกไปใช้คำสั่ง client.write(buf,length)
- ถัดลงมาเป็นการกำหนด timeout ในการรอข้อความตอบกลับจากอีกฝั่งหนึ่ง ซึ่งในกรณีนี้กำหนดไว้ 5000 milliseconds โดยการวนลูปจนกว่า client.available() จะไม่เท่ากับ 0
- เมื่อมีข้อความเข้ามา ก็ให้พิมพ์ข้อความนั้นออกหน้าจอ
ส่วนที่ 5 : Code หลัก
void setup() {
Serial.begin(115200);
wifi_connect();
_ready = false;
delay(1000);
}
void loop() {
if(_ready && c < 3){
sendMsg(msgs[c]);
c+=1;
}
delay(1000);
}
เป็นการทำงานแบบง่าย ๆ เพื่อให้เห็นขั้นตอนการทำงาน เริ่มต้นด้วยการเชื่อมต่อไปยัง router หรือ access point เพื่อขอ IP Address แล้วก็วนลูปเพื่อส่งข้อความออกไป รอ echo กลับcode ทั้งหมดของ Node32s
#include <WiFi.h>
const char* _SSID = "xxxxxxxxxx";
const char* _PWD = "xxxxxxxxxx";
const char* _HOST = "xxxxxxxxxx";
const uint16_t _PORT = 9999;
boolean _ready;
String msgs[3] = {"Hello I am Node32s ","I am from Thailand ","Nice to meet you "};
int c = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
wifi_connect();
_ready = true;
delay(1000);
}
void loop() {
if(_ready && c < 3){
sendMsg(msgs[c]);
c+=1;
}
delay(1000);
}
void wifi_connect(){
if(WiFi.isConnected()) return;
Serial.println("Connecting to "+String(_SSID));
WiFi.begin(_SSID,_PWD);
while(WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi Connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
void sendMsg(String msg){
WiFiClient client;
Serial.println("");
Serial.print("Send : ");
Serial.println(msg);
if(!client.connect(_HOST,_PORT)){
Serial.println("Connection faild.");
return;
}
byte buf[20];
msg.getBytes(buf,20);
client.write(buf,20);
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
Serial.println(">>> Client Timeout !");
client.stop();
return;
}
}
while (client.available()) {
String line = client.readStringUntil('\r');
Serial.print("Recieve :");
Serial.println(line);
Serial.println("--------------------------");
}
client.stop();
_ready = true;
}
ทำการ Save และ Compile เช่นเดียวกับการใช้ Arduino หาก compile เสร็จแล้วและไม่พบ error จะเห็นข้อความดังภาพทำการ upload ไปยัง Node32s ก็จะเห็นข้อความปรากฏตามภาพ เป็นอันเสร็จงานทางฝั่ง Node32s
3. สร้าง Code ฝั่ง Raspberry Pi
ทางฝั่งของ Raspberry Pi จะทำหน้าที่เพียงอย่างเดียวคือการรับข้อความแล้วส่งข้อความนั้นกลับไปยังผู้ส่ง (EchoServer) โดยจะใช้ Python3.4 ที่มีอยู่แล้ว เหตุเพราะว่าต้องการแนะนำ asyncio library ใหม่ที่เพิ่งเริ่มมีการใช้งานใน Python3.4 หรือใหม่กว่าเท่านั้น ซึ่ง asyncio ช่วยให้การพัฒนาโปรแกรมสื่อสารด้วย Python ง่ายขึ้นมากเมื่อเทียบกับการใช้ socket โดยตรง
import asyncio
msgs = [b'Hello I am Raspi ',b'I am from England ',b'Nice to meet you too']
c = 0
class EchoServer(asyncio.Protocol):
def connection_made(self,transport):
self.transport = transport
def data_recieved(self,data):
im = data.decode('utf-8')
if im[0] == 'H':
self.transport.write(msgs[0])
if im[0] == 'I':
self.transport.write(msgs[1])
else :
self.transport.write(msgs[2])
loop = asyncio.get_event_loop()
coro = loop.create_server(EchoServer,'',10000)
server = loop.run_until_complete(coro)
try:
loop.run_forever()
except :
pass
server.close()
loop.run_until_complete(server.wait_closed())
loop.close()
ลำดับการทำงานของ code ในส่วนที่ทำงานบน Raspberry Pi อย่างคร่าว ๆ มีดังนี้
- กำหนดค่าของข้อความสำหรับตอบกลับไปยัง Node32s
- สร้าง class EchoServer โดยทำงานอยู่สองอย่างคือ
- สร้าง transport ที่รับผิดชอบต่อ connection ที่มีเข้ามา
- ตอบข้อความไปยัง client ที่เชื่อมต่อเข้ามาผ่าน transport ที่ได้จากข้อ 1
- สร้าง loop ในการทำงาน
และสุดท้ายก็นำผลการทำงานมาให้ดูในวิดีโอนี้แสดงผลที่เกิดขึ้นทางฝั่ง Node32s ครับ จะเห็นได้ว่า Node32s กับ Raspberry Pi มีการส่งข้อความ โต้ตอบไปมาระหว่างกัน เหมือนการเล่นปิงปอง ซึ่งก็พอที่จะทำให้เห็นภาพการสื่อสารระหว่างอุปกรณ์ทั้งสองผ่าน Wireless Network นะครับ
Sign up here with your email
ConversionConversion EmoticonEmoticon