เชื่อม Raspberry PI กับ ESP8266 ด้วย Lua

รู้จักกับ ESP8266
ในยุคที่ Internet of Things (IoT) กำลังได้รับความสนใจอย่างมากทำให้ ESP8266 [http://wiki.iteadstudio.com/ESP8266_Serial_WIFI_Module] พลอยได้รับความสนใจมากตามไปด้วย



แผงวงจรของ ESP8266 มาพร้อมทั้ง RAM, ROM และ WiFi Radio เราสามารถนำเอามาใช้ประโยชน์ในเรื่อง WiFi Networking ได้หลายอย่าง เช่น WiFi Sheild สำหรับ Arduino หรือ สร้าง Application Hosting

ภาพจากเว็บไซต์ http://www.electrodragon.com


มีบทความภาษาไทยหลายบทความที่กล่าวถึง ESP8266 การใช้งาน รวมถึงการ update firmware  ได้แก่
สำหรับภาษาอังกฤษนั้นเยอะมาก ได้แก่
การใช้ Arduino IDE  กับ ESP8266 ได้แก่
ถึงตรงนี้ท่านที่ยังไม่เคยได้ใช้งาน ESP8266 หากได้อ่านบทความที่ยกตัวอย่างมาแล้ว ก็น่าจะครบถ้วนแล้วสำหรับการทำความรู้จักและการใช้งานแบบต่าง ๆ 

Raspberry PI กับ ESP8266

 จากบทความต่าง ๆ ข้างต้นทำให้เราทราบว่าการเชื่อมต่อระหว่าง ESP8266 กับ Raspberry PI ทำได้สองทางคือ

1.ผ่าน USB Port ซึ่งจะต้องใช้อุปกรณ์แปลงสัญญาณมาต่อคั่น วิธีการนี้จะเป็นวิธีที่นิยมใช้กันครับ

รูปภาพตัวอย่างอุปกรณ์แปลงสัญญาณจากเว็บไซต์ http://www.arduitronics.com

2.ผ่านทาง GPIO Pin ตำแหน่งที่ 8 (Tx) และ 10 (Rx) ซึ่งในบทความนี้จะเลือกใช้วิธีนี้ครับ

Pin Diagram ของ ESP8266  รุ่นที่ใช้ในบทความนี้



การต่อสายสัญญาณจาก Raspberry PI กับ ESP8266 ผ่าน GPIO 



Raspberry PI              ESP8266
Tx (Pin 8)           <->       Rx
Rx (Pin 10)        <->       Tx
GND (Pin 6)       <->       GND
3.3 V (Pin 1)      <->       Vcc,CH_PD




สิ่งที่ต้องระวังในการต่อแบบนี้คือ ESP8266 ใช้แรงดันไฟฟ้าที่ 3.3 V 


ทำให้ ESP8266 ใช้ภาษา Lua 

Firmware ที่ติดตั้งมาจากผู้ผลิตจะยังไม่สามารถทำให้ ESP8266 รู้จักภาษา Lua จะรู้จักแต่ชุดคำสั่ง AT (https://nurdspace.nl/ESP8266#AT_Commands) เราต้องทำการปรับเปลี่ยนก่อน แต่ทำไมต้องเป็นภาษา Lua ? เหตุผลของผมคือ

1. Lua เป็นภาษาที่ถูกใช้งานใน NodeMCU ซึ่งเป็น developement board สำหรับ ESP8266 ครับ มีเอกสารอ้างอิงและเว็บไซต์ให้ค้นคว้ามากมาย ได้แก่
รูปภาพจากเว็บไซต์ http://www.nodemcu.com


2. Lua (http://www.lua.org/) เป็นภาษา High Level เรียนรู้ได้ง่าย มี style การเขียนคล้ายกับ NodeJs หรือ Javascript 

ในขณะที่เขียนบทความนี้ผมยังไม่มี  NodeMCU developement board ครับ ดังนั้นผมจะนำเอา firmware ของ NodeMCU มา flash ลงบน ESP8266 โดยตรงเลย  และตัว firmware นี้ทางทีมพัฒนาของ NodeMCU ก็ได้ทำตัว pre-built ไว้ให้เราเอามาใช้งานเลยไม่ต้องทำ cross compile ครับ นับว่าอำนวยความสะดวกกันดีมาก

ขั้นตอนการ flash firmware ESP8266 ด้วย Raspberry PI


1. ดาวน์โหลด pre-built firmware  หรือสร้าง firmware ที่มี modules ที่ต้องการจาก http://frightanic.com/nodemcu-custom-build/index.php หรือ compile จาก source code จาก https://github.com/nodemcu/nodemcu-firmware

2. ดาวน์โหลดซอฟต์แวร์และติดตั้ง flasher tools (https://github.com/themadinventor/esptool) ครับ (ท่านที่ใช้งาน Windows   จะง่ายหน่อย เพราะมีเอกสารพร้อมเลยที่ https://github.com/nodemcu/nodemcu-flasher ) การจะใช้งาน esptool กับ Raspberry PI ที่ติดตั้ง Raspbian ได้นั้นต้องมีการปรับเปลี่ยนบางอย่าง คือ
   2.1 แก้ไข /boot/cmdline.txt โดยการนำเอาข้อความที่มี ttyAMA0 ออกไป หลังจากแก้ไขแล้วจะเหลือข้อความดังนี้

dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p6 rootfstype=ext4 elevator=deadline rootwait

  2.2 แก้ไข /etc/inittab โดยการทำเครื่องหมาย # ไว้หน้าบรรทัดที่มีข้อความ TO:23:respawn:/sbin/getty -L ttyAMA0 115200 v   จะได้เป็น

#TO:23:respawn:/sbin/getty -L ttyAMA0 115200 v

  2.3 reboot Raspberry PI

3. เชื่อมต่อ Raspberry กับ ESP8266  ซึ่งจะเหมือนกับแผนภาพที่ข้างบน เพียงแต่เพิ่มมี 1 สายคือ GPIO 0 ของ ESP8266 ต่อไปที่ GND ครับ เพื่อให้ ESP8266 เข้าสู่ flash mode (http://www.electrodragon.com/w/ESP8266)


ต่อ GND ให้กับ GPIO 0 ของ ESP8266 ก่อนทำการ flash firmware


 4. การต่อผ่าน GPIO แบบนี้ ตัว flasher tools บน Raspberry PI จะมองเห็น ESP8266 ผ่านทางพอร์ตสื่อสาร /dev/ttyAMA0  ครับ ถ้า ESP8266 พร้อมแล้วจะสังเกตุเห็นไฟสีฟ้าสว่างแว็บขึ้นมา

5. ใช้คำสั่ง
sudo python esptool.py -p /dev/ttyAMA0 write_flash 0x00000 [path to firmware ]
ท่านควรจะเห็นข้อความแบบนี้บน  Terminal ของ Raspberry PI
connecting ...
Erasing flash...
writing at 0x00000 ... (0%)
รอจนเสร็จ จะเห็นข้อความ

Leaving

ก็เป็นอันเสร็จวิธีการ

ทดสอบ

หลังจาก flash NodeMCU firmware ลงบน ESP8266 แล้ว ดังนั้น ESP8266 ก็ควรจะรู้จักและทำตามคำสั่งด้วยภาษา Lua ได้แล้ว

1. ต่อสายสัญญาณตามแบบการใช้งาน (ไม่ต้องต่อ GPIO 0 ) ระหว่าง Raspberry PI กับ ESP8266
2. เรียกใช้งาน minicom (หากไม่มีให้ติดตั้งก่อน sudo apt-get install minicom) ซึ่งเป็น utility ในการสื่อสารระหว่าง Linux กับอุปกรณ์ผ่านทาง Serial Port ด้วยคำสั่ง
minicom -b 9600 -o -D /dev/ttyAMA0
หมายถึงให้ทำการติดต่อไปยังพอร์ต /dev/ttyAMA0 (ซึ่งเป็นช่องทางไปยัง ESP8266) ด้วย baud rate 9600 (ผมลองค่าอื่นดูแล้วแต่ไม่ได้ผล) ก็จะได้หน้าจอดังภาพ (ผมพบว่าหากมีปัญหาในการติดต่อ ให้ลองดึงสาย GND ของ ESP8266 ออกแล้วเสียบกลับเข้าไปจะแก้ปัญหาได้ ยังไม่ทราบเหตุผล)





จากภาพจะบอกเราว่า ESP8266 พร้อมแล้วที่จะรับคำสั่งภาษา Lua (ยังไม่ต้องสนใจข้อความ lua: cannot open init.lua)

3. ลองคำสั่ง (https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_en) ง่าย ๆ ก่อน




ในภาพใช้คำสั่ง wifi.sta.getip() ซึ่งเป็นการสอบถามว่า ESP8266 ได้รับ IP address มาจาก WiFi Router หรือยัง คำตอบคือ nil  คือ ไม่มีอะไร

สร้าง Application อย่างง่ายก่อน

ผมจะลองสร้างApplication โต้ตอบกันระหว่าง Raspberry PI กับ ESP8266 ขึ้นมาครับ

ฝั่ง Raspberry PI (Linux )

 ใช้ python 2.7  สร้างไฟล์ชื่อ simple_esp.py แล้วสร้าง code ตามข้างล่างนี้
import socket

UDP_IP=""
UDP_PORT = 8888

sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock.bind((UDP_IP,UDP_PORT))
while True:
   data,addr = sock.recvfrom(1024)
   print "Incoming %s" % (data)
   sock.sendto("You sent me : "+data,(addr[0],addr[1]))
แล้วเรียกใช้งาน
sudo python simple_esp.py

ฝั่ง ESP8266

1. รับ IP Address จาก WiFi Router ก่อน
wifi.setmode(wifi.STATION)
wifi.sta.config("SSID","PASSWORD") 
print (wifi.sta.getip())



2. สร้าง UDP Client
sock_out = net.createConnection(net.UDP)
sock_out:on("receive",
                         function(sck,data)
                              print(data)
                         end)
sock_out:connect(8888,"IP Address of Raspberry PI") 
sock_out:send("Hello, I'am ESP8266")
                          

sock_out = net.createConnection(net.UDP)
การสร้าง network connection ขึ้นมาชื่อ sock_out ซึ่งจะใช้ UDP package

sock_out:on("receive",
                       function(sck,data)
                         print(data)
                        end)
เป็นการสร้าง callback function ขึ้นเพื่อตอบสนองต่อเหตุการณ์ชื่อ "receive" หรือเหตุการณ์ที่มีข้อมูลจากอีกฝั่งหนึ่งเข้ามา โดยทำงานเดียวคือการพิมพ์ข้อมูลออกทางหน้าจอ

sock_out:connect(...)
ให้ sock_out ทำการติดต่อไปยังปลายทางด้วย IP adress และ port ที่กำหนด

sock_out:send("...")
ทำการส่งข้อความไปยังปลายทาง


 

 

สรุป

เป้าหมายของบทความนี้คือ
1. การ Flash firmware ESP8266 ให้รองรับการภาษา Lua
2. เรียนรู้การใช้ชุดคำสั่ง Lua  กับ ESP8266 
3. เข้าใจพื้นฐานการสร้าง Application สื่อสารระหว่าง Rasbpbery PI (หรืออุปกรณ์อื่น) กับ ESP8266 ซึ่งจะเป็นพื้นฐานในการสร้างระบบงานตามแนวคิดของ Internet of Things ต่อไป

ความคิดเห็น