Xem Nhiều 2/2023 #️ Hướng Dẫn Sử Dụng Esp8266 Trong Các Ứng Dụng Internet Of Things (Phần 6) # Top 8 Trend | Karefresh.com

Xem Nhiều 2/2023 # Hướng Dẫn Sử Dụng Esp8266 Trong Các Ứng Dụng Internet Of Things (Phần 6) # Top 8 Trend

Cập nhật thông tin chi tiết về Hướng Dẫn Sử Dụng Esp8266 Trong Các Ứng Dụng Internet Of Things (Phần 6) mới nhất trên website Karefresh.com. Hy vọng nội dung bài viết sẽ đáp ứng được nhu cầu của bạn, chúng tôi sẽ thường xuyên cập nhật mới nội dung để bạn nhận được thông tin nhanh chóng và chính xác nhất.

Phần 6: Demo lập trình trực tiếp ESP8266 với thư viện SDK

1/ Sử dụng các hàm API của Non-RTOS SDK

Làm việc với GPIO

ESP8266 có tổng cộng 17 chân GPIO, trong đó 4 chân đã được sử dụng để giao tiếp với Flash chip trên board nên chúng ta chỉ có thể sử dụng 13 chân GPIO còn lại cho ứng dụng của mình mà thôi.

Các file code để làm việc với GPIO bao gồm:

C:EspressifESP8266_SDKincludedrivergpio.h

C:EspressifESP8266_SDKdriver_libincludedrivergpio16.h

C:EspressifESP8266_SDKdriver_libincludedrivergpio16.c

Ví dụ các bạn có thể tham khảo trong C:EspressifexamplesESP8266gpio16_leddrivergpio16.c và C:EspressifexamplesESP8266gpio16_ledincludedrivergpio16.h

Các hàm API được cung cấp bao gồm:

int set_gpio_mode(unsigned pin, unsigned mode, unsigned pull) Chúng ta sẽ gọi hàm này để cấu hình chức năng cho chân GPIO cụ thể như input/output/interrupt và có pull up/pull down hay không. Giá trị cho “pin” là từ 0 đến 12 tương ứng cho 13 GPIO có thể sử dụng như sau:

Pin 0 = GPIO16 Pin 1 = GPIO5 Pin 2 = GPIO4 Pin 3 = GPIO0 Pin 4 = GPIO2 Pin 5 = GPIO14 Pin 6 = GPIO12 Pin 7 = GPIO13 Pin 8 = GPIO15 Pin 9 = GPIO3 Pin 10 = GPIO1 Pin 11 = GPIO9 Pin 12 = GPIO10

void gpio_intr_attach(gpio_intr_handler cb) Dùng để đăng ký hàm callback khi có interrupt từ module GPIO

int gpio_intr_init(unsigned pin, GPIO_INT_TYPE type) Dùng để cấu hình interrupt cho chân GPIO như ngắt theo cạnh lên/xuống hay ngắt theo mức

int gpio_write(unsigned pin, unsigned level) Dùng để điều khiển chân GPIO output mức 0/1

int gpio_read(unsigned pin) Dùng để đọc giá trị 0/1 của chân GPIO

Lưu ý khi sử dụng thư viện gpio16.c này, trong hàm callback khi interrupt, chúng ta chỉ cần kiểm tra chân GPIO cần xử lý, nếu đúng là chân GPIO thì thực hiện code chương trình cho ngắt, nếu không đúng thì thoát mà không cần quan tâm xóa cờ ngắt vì code bên trong gpio16.c đã xử lý việc xóa cờ ngắt rồi.

Dễ dàng phải không nào. Chỉ cần xử dụng các hàm được cung cấp bởi gpio16.c thì chúng ta đã có thể làm việc với GPIO mà không cần quan tâm đến các thanh ghi điều khiển bên dưới rất tiện lợi và nhanh chóng

Làm việc với I2C

ESP8266 không có phần cứng cho I2C mà sử dụng các chân GPIO để tạo tín hiệu I2C để giao tiếp với các IC khác trên board. Chúng ta có thể gọi loại I2C này software I2C và thư viện I2C của ESP8266 chỉ hộ trợ chức năng của Master I2C. Software I2C trên ESP8266 có tần số tối đa là 100kHz

Các file cần để làm việc với I2C:

C:EspressifESP8266_SDKdriver_libincludedriveri2c_master.h

C:EspressifESP8266_SDKdriver_libdriveri2c_master.c

Các hàm API để làm việc với I2C bao gồm:

void i2c_master_gpio_init(void) và void i2c_master_init(void) Chúng ta sẽ gọi khi khởi động để cấu hình các chân GPIO cho I2C và điều khiển GPIO để tạo tín hiệu ban đầu trên bus I2C

void i2c_master_start(void) Điều khiển chân GPIO để tạo tín hiệu START theo chuẩn I2C

void i2c_master_stop(void) Điều khiển chân GPIO để tạo tín hiệu STOP trên bus I2C sau khi truyền nhận dữ liệu hoàn thành

void i2c_master_send_ack(void) và void i2c_master_send_nack(void) Điều khiển chân GPIO để gửi tín hiệu ACK hoặc NAK trên bus I2C sau khi nhận được dữ liệu từ 1 Slave I2C

uint8 i2c_master_getAck(void) Kiểm tra xem Slave I2C có gửi ACK khi nhận được dữ liệu truyền từ ESP8266

uint8 i2c_master_readByte(void) Đọc 1 byte dữ liệu trên bus I2C

void i2c_master_writeByte(uint8 wrdata) Gửi 1 byte dữ liệu trên bus I2C

Mặc định thì GPIO2 làm tín hiệu SDA và GPIO14 làm tín hiệu SCL. Chúng ta có thể sử dụng chân GPIO khác bằng cách thay đổi các macro trong file i2c_master.h

Chúng ta có thể thấy thư viện cho I2C trên ESP8266 chỉ sử dụng GPIO để tạo các tín hiệu theo chuẩn I2C và chỉ hỗ trợ vai trò Master I2C. Ngoài ra chúng ta cũng không có FIFO, DMA, ngắt phần cứng khi truyền nhận dữ liệu trên I2C cũng như việc tạo tín hiệu START/STOP/ACK/NAK đều phải thực hiện trực tiếp bằng cách gọi các hàm tương ứng; do đó có thể nói I2C trên ESP8266 có thể dùng để giao tiếp 1 cách đơn giản với các sensor I2C không yêu cầu tốc độ cao.

Làm việc với PWM

Tương tự I2C, chúng ta cũng có software PWM từ thư viện SDK của ESP8266. Software PWM của ESP8266 sử dụng hardware timer là FRC1 và NMI interrupt để tạo xung PWM tại các chân GPIO đã chọn. Thư viện cho PWM hỗ trợ tối đa 8 channels với duty cycle khác nhau nhưng cùng chung tần số xung (chúng ta không thể tạo các xung PWM với các tần số khác nhau từ các hàm API cho PWM trong SDK)

Tần số xung PWM có thể cấu hình từ 100Hz – 1kHz với độ phân giải của duty cycle là 45ns

Các file cần để làm việc với PWM bao gồm:

C:EspressifESP8266_SDKincludepwm.h

Các hàm API của PWM sẽ được định nghĩa trong file thư viện /lib/libdriver.a mà chúng ta sẽ add vào trong Makefile khi biên dịch code ứng dụng. Lưu ý là software PWM sử dụng hardware TIMER để hoạt động; do đó chúng ta không thể sử dụng hardware TIMER nếu đã sử dụng chức năng PWM

Các hàm API cho software PWM:

void pwm_init(uint32 period, uint32 *duty,uint32 pwm_channel_num,uint32 (*pin_info_list)[3]) Khởi động module PWM với thông tin bao gồm tần số PWM, duty cycle , channel nào, và output ra chân GPIO nào Chúng ta có thể xác lập nhiều xung PWM ra nhiều chân GPIO bằng cách tạo các mảng *duty và mảng cho *pin_info_list ví dụ như:

uint32 io_info[][3] = { {PWM_0_OUT_IO_MUX,PWM_0_OUT_IO_FUNC,PWM_0_OUT_IO_NUM}, {PWM_1_OUT_IO_MUX,PWM_1_OUT_IO_FUNC,PWM_1_OUT_IO_NUM}, {PWM_2_OUT_IO_MUX,PWM_2_OUT_IO_FUNC,PWM_2_OUT_IO_NUM}, }; u32 duty[3] = {600,604,634}; pwm_init(1000, duty, 3, io_info);

Lưu ý period có đơn vị là us, duty được tính bằng công thức (duty cycle * 45)/(period * 1000)

void pwm_start(void) Bắt đầu chạy hardware Timer và tạo xung PWM ra chân GPIO

uint32 pwm_get_period(void) và uint32 pwm_get_duty(uint8 channel) Đọc lại giá trị period / duty đã cấu hình

void pwm_set_period(uint32 period) và void pwm_set_duty(uint32 duty, uint8 channel) Thay đổi tần số xung PWM và duty cycle của từng channel

Khá là đơn giản phải không nào. Chúng ta có thể dễ dàng tạo xung PWM ra các chân GPIO bằng cách gọi hàm pwm_init() và pwm_start(). Cần lưu ý các giới hạn của software PWM là không thể tạo các xung PWM với các tần số khác nhau và tần số hoạt động chỉ từ 100Hz đến 1kHz và không sử dụng được hardware TIMER nếu có sử dụng PWM.

Làm việc với UART

ESP8266 hỗ trợ 2 module UART là UART0 và UART1 với tốc độ truyền dữ liệu lên đến 4.5Mbps; tuy nhiên UART1 chỉ có chức năng Tx và thường được dùng để print debug log.

Mặc định sau khi cấp nguồn, firmware trong ROM của ESP8266 sẽ print 1 vài message từ UART0. Tốc độ baud của UARTo khi này sẽ thay đổi tùy theo giá trị thạch anh sử dụng trên board. Ví dụ như với thạch anh 40MHz thì baudrate sẽ là 115200, thạch anh 26MHz thì baudrate sẽ là 74880. Các UART module trên ESP8266 có hỗ trợ RX/TX FIFO 128bytes.

Các chân GPIO dùng cho UART bao gồm:

UART0: RX = GPIO03 , TX = GPIO01 , RTS = GPIO15 , CTS = GPIO13

UART1: TX = GPIO02

Các file code sử dụng cho UART:

C:EspressifESP8266_SDKdriver_libincludedriveruart.h

C:EspressifESP8266_SDKdriver_libincludedriveruart_register.h

C:EspressifESP8266_SDKdriver_libdriveruart.c

Các hàm API:

void uart_init(UartBautRate uart0_br, UartBautRate uart1_br) Khởi động UART0 và UART1 với baudrate tương ứng và cho phép ngắt trên 2 UART. Lưu ý là hàm uart_init() sẽ cấu hình 2 module UART theo thông số mặc định đã lưu trong ROM (8-bit dữ liệu, 1 stop bit, không parity, v.v…). Khi thực thi uart_init() cũng tự động đăng ký hàm interrupt callback là uart0_rx_intr_handler() để xử lý ngắt của UART0. Do đó chúng ta có thể add code trong hàm uart0_rx_intr_handler() để xử lý ngắt cần thiết cho ứng dụng của mình

void UART_SetWordLength(uint8 uart_no, UartBitsNum4Char len) Cấu hình lại size của dữ liệu truyền trên UART nếu cần

void UART_SetStopBits(uint8 uart_no, UartStopBitsNum bit_num) Cấu hình lại số lượng Stop bits nếu cần

void UART_SetParity(uint8 uart_no, UartParityMode Parity_mode) Cấu hình lại kiểu Parity nếu cần

void UART_SetFlowCtrl(uint8 uart_no,UART_HwFlowCtrl flow_ctrl,uint8 rx_thresh) Cấu hình lại HW flow control sử dụng tín hiệu RTS/CTS của UART0 nếu cần

void uart_rx_intr_enable(uint8 uart_no) Cho phép ngắt trên UART tương ứng.

void uart_rx_intr_disable(uint8 uart_no) Không cho phép ngắt trên UART tương ứng

void UART_SetIntrEna(uint8 uart_no,uint32 ena_mask) Cho phép tín hiệu ngắt cụ thể trên UART tương ứng. Các tín hiệu ngắt có thể xem trong uart_register.h như UART_RXFIFO_OVF_INT_ENA, UART_TXFIFO_EMPTY_INT_ENA, v.v…

void UART_ClearIntrStatus(uint8 uart_no,uint32 clr_mask) Xóa cờ interrupt của UART tương ứng. Các cờ interrupt có thể xem trong file uart_register.h như UART_RXFIFO_OVF_INT_CLR, UART_TXFIFO_EMPTY_INT_CLR, v.v…

STATUS uart_tx_one_char(uint8 uart, uint8 TxChar) Đợi TX FIFO có byte trống và ghi 1 byte dữ liệu vào TX FIFO

STATUS uart_tx_one_char_no_wait(uint8 uart, uint8 TxChar) Tương tự như hàm uart_tx_one_char() nhưng sẽ thoát hàm và không ghi dữ liệu nếu TX FIFO đầy

STATUS uart0_tx_one_char_no_wait(uint8 TxChar) Gọi hàm uart_tx_one_char_no_wait() cho UART0

void uart1_write_char(char c) Ghi 1 byte dữ liệu vào TX FIFO của UART1 bằng cách gọi hàm uart_tx_one_char()

void uart1_sendStr_no_wait(const char *str) Ghi dữ liệu vào TX FIFO và không đợi nếu TX FIFO đang đầy

void uart0_tx_buffer(uint8 *buf, uint16 len) Ghi nhiều bytes dữ liệu vào TX FIFO của UART0. Lưu ý là hàm này sẽ thực thi đến khi nào ghi hết dữ liệu vào FIFO

void uart0_sendStr(const char *str) Ghi các bye trong 1 string vào TX FIFO của UART0 và sẽ đợi đến khi ghi xong

void UART_WaitTxFifoEmpty(uint8 uart_no , uint32 time_out_us) Đợi TX FIFO trống, nếu hết thời gian time_out_us thì sẽ thoát

void UART_ResetFifo(uint8 uart_no) Reset RX FIFO và TX FIFO của UART tương ứng

Làm việc với TIMER

Chúng ta có thể sử dụng các hàm API của thư viện SDK để làm việc với software timer hoặc hardware timer.

File cần sử dụng C:EspressifESP8266_SDKincludeosapi.h

Các hàm API chính:

void os_timer_arm ( os_timer_t *ptimer, uint32_t milliseconds, bool repeat_flag ) Dùng để khởi tạo 1 software tỉmer với thời gian timeout và có tự động chạy lại hay không.

void os_timer_arm_us ( os_timer_t *ptimer, uint32_t microseconds, bool repeat_flag ) Tương tự như hàm os_timer_arm() nhưng thời gian sẽ tính theo đơn vị us

void os_timer_disarm (os_timer_t *ptimer) Dùng để stop 1 software timer

void os_timer_setfn( os_timer_t *ptimer, os_timer_func_t *pfunction, void *parg ) Dùng để đăng ký hàm callback cho 1 software timer

Ví dụ code khởi tạo software timer có thời gian tuần hoàn là 1000ms và hàm callback là timer_callback()

os_timer_t demo_sw_timer; os_timer_disarm(&demo_sw_timer); os_timer_setfn(&demo_sw_timer, (os_timer_func_t *)timer_callback, (void *)0); os_timer_arm(&demo_sw_timer, 1000, 1);

Và hàm timer_callback() có thể khai báo như sau:

LOCAL void ICACHE_FLASH_ATTR timer_callback(void *arg) {

File cần sử dụng C:EspressifESP8266_SDKdriver_libdriverhw_timer.c

Các hàm API chính:

void ICACHE_FLASH_ATTR hw_timer_init(FRC1_TIMER_SOURCE_TYPE source_type, u8 req) Dùng để khởi tạo hardware timer FRC1 cho chức năng timer và khai báo ngắt dùng NMI hay ngắt của timer cũng như timer có tuần hoàn hay không

void hw_timer_set_func (void (* user_hw_timer_cb_set)(void) ) Đăng ký hàm timer callback

void hw_timer_arm (uint32 val) Bắt đầu chạy timer với thời gian theo đơn vị us

Lưu ý là nếu PWM cũng sử dụng FRC1 timer nên chúng ta không thể dùng PWM và hardware timer cùng lúc mà phải chuyển sang dùng software timer nếu có PWM

Làm việc với Wifi, TCP/UDP

Chúng ta đã giới thiệu các hàm API của thư viện SDK để làm việc với các module hardware của ESP8266 như GPIO, UART, I2C, v.v… Ngoài các API trên, thư viện SDK còn cung cấp đầy đủ các API để chúng ta xác lập cấu hình mạng Wifi, yêu cầu kết nối Wifi, tạo kết nối TCP/UDP để truyền dữ liệu.

Do số lượng các hàm API cho Wifi và TCP/UDP khá nhiều nên bài viết sẽ không giới thiệu ở đây. Các bạn có thể tham khảo đầy đủ trong tài liệu hướng dẫn của thư viện SDK ở đây.

Để nhanh chóng tìm hiểu các hàm API thông dụng, chúng ta có thể tham khảo các sample project sau:

C:EspressifexamplesESP8266esp8266-nonos-sample-code2NetworkHTTP_Client_Demo C:EspressifexamplesESP8266wifi-sta-tcp-client C:EspressifexamplesESP8266lwip_open_demo_app Các project này sử dụng các hàm API để demo quá trình thiết lập ESP8266 tạo kết nối Wifi và truyền nhận dữ liệu qua TCP

2/ Demo lập trình vơi thư viện SDK

Trong phần này chúng ta làm 1 ứng dụng giống như 1 demo trong Phần 4 đó là điều khiển ESP8266 ping website của google, nếu ping thành công thì sẽ blink LED. Khác với phần 4 sử dụng firmware AT command có sẵn và 1 board arduino để truyền commands cho ESP8266 để thực hiện việc giao tiếp Wifi, thực hiện ping tới Google và việc điều khiển LED cũng từ board arduino, trong lần demo này, chúng ta sẽ lập trình ESP8266 thực hiện tất cả công việc trên mà không cần board MCU bên ngoài.

Chúng ta sẽ sử dụng 1 module ESP-01 và 1 module FT232 để nạp chương trình cho ESP-01

Tạo Eclipse project

Để tạo 1 eclipse project cho demo, chúng ta có thể đơn giản là copy 1 folder project có sẵn trong thư mục C:EspressifexamplesESP8266 và đặt tên lại cho ứng dụng của chúng ta

Ví dụ chúng ta sẽ copy thư mục C:EspressifexamplesESP8266gpio_led và đổi tên thành thư mục C:EspressifexamplesESP8266demo_phan6

Sau khi import, chúng ta sẽ có giao diện Eclipse như sau, chúng ta sẽ đổi tên project thành demo_phan6

Thế là xong, chúng ta đã tạo 1 Eclipse project cho demo của mình

Thêm thư viện SDK vào project

Trong demo project, chúng ta thấy có 2 file code thư viện trong thư mục driver/ là gpio16.c và uart.c. Đây là các thư viện được viết bởi cộng đồng phát triển để giúp lập trình phần cứng trên ESP8266 dễ dàng hơn vì không cần phải quan tâm các thanh ghi điều khiển bên dưới.

Trong demo này, chúng ta sẽ sử dụng file thư viện gpio16.c của gpio16_led project. Đây là thư viện được viết bởi cộng đồng phát triển ESP8266 giúp điều khiển các chân GPIO rất dễ dàng như đã giới thiệu ở phần đầu của bài viết. Về file code uart.c, chúng ta sẽ không sử dụng file code này mà sử dụng trực tiếp các hàm API cho UART từ thư viện SDK của Espressif như đã giới thiệu ở phần đầu. Do đó chúng ta sẽ xóa file /demo_phan6/driver/uart.c và thay thế 2 file /demo_phan6/include/driver/uart.h, /demo_phan6/include/driver/uart_register.h bằng 2 files trong thư mục C:EspressifESP8266_SDKdriver_libincludedriver

LIBS = c gcc hal phy pp net80211 lwip wpa main crypto driver

Viết code ứng dụng trong user_main.c

Chúng ta sẽ xóa hết nội dung của file user_main.c chỉ chừa lại hàm user_rf_cal_sector_set() và user_rf_pre_init() và bắt đầu viết code với hàm user_init()

user_init() Khởi tạo 1 software timer để gọi hàm app_start() sau 5s

uart_init(115200, 115200); os_timer_disarm(&start_timer); os_timer_setfn(&start_timer, (os_timer_func_t *)app_start, (void *)0); os_timer_arm(&start_timer, 10000, 1);

app_start() Gọi các hàm API của Wifi để thiết lập chế độ thiết bị Wifi, thông tin mạng Wifi cần kết nối, đăng ký hàm event callback là wifi_evt_callback() và bắt đầu kết nối vào mạng Wifi

struct station_config wifi_info; os_timer_disarm(&start_timer); os_printf("Khoi dongn"); ets_wdt_enable(); ets_wdt_disable(); wifi_set_opmode(STATION_MODE); wifi_station_disconnect(); os_memset(&wifi_info,0,sizeof(wifi_info)); os_memcpy(wifi_info.ssid, WIFI_SSID, sizeof(wifi_info.ssid)); os_memcpy(wifi_info.password, WIFI_PASSWORD, sizeof(wifi_info.password)); wifi_station_set_config(&wifi_info); wifi_set_event_handler_cb(wifi_evt_callback); wifi_station_connect();

wifi_evt_callback() Đợi event EVENT_STAMODE_GOT_IP sau khi module ESP01 đã kết nối thành công và gọi hàm do_ping() để tiến hành ping website google.com

int res; case EVENT_STAMODE_CONNECTED: os_printf(“Ket noi thanh congn”); break; case EVENT_STAMODE_DISCONNECTED: os_printf(“Ngat ket noin”); break; case EVENT_STAMODE_GOT_IP: os_printf(“Got IP:” IPSTR “,mask:” IPSTR “,gw:” IPSTR, os_printf(“n”); do_ping(); break; default: break; }

do_ping() Sử dụng API dns_gethostbyname() để lấy địa chỉ IP của tên miền “google.com”; chúng ta sẽ đăng ký hàm callback wifi_dns_found_callback() để xử lý sau khi đã có địa chỉ IP

os_printf("Get IP of host %sn", website); err_t ret = dns_gethostbyname(website, &web_ip, wifi_dns_found_callback, 0); if(ret == 0) { os_printf("Found ip right now:" IPSTR "n", IP2STR(web_ip.addr)); ping_opt.ip = web_ip.addr; ping_start(&ping_opt); } else { }

wifi_dns_found_callback() Nhận địa chỉ IP của tên miền “google.com” và gọi hàm API ping_start() để bắt đầu quá trình ping tới địa chỉ IP đó. Chúng ta cũng đăng ký hàm callback ping_recv_callback() để gọi khi nhận được dữ liệu khi ping

if(ipaddr) { ping_start(&ping_opt); }

ping_recv_callback() Nếu ping thành công, chúng ta sẽ bắt đầu chạy 1 software timer để blink LED. Trong demo này, chúng ta sẽ blink LED BLUE ngay trên board ESP01. Led Blue được điều khiển bởi chân GPIO01 và dùng cho tín hiệu TXD của UART0 nên chúng ta cần cấu hình lại để sử dụng GPIO01 cho việc blink LED của ứng dụng

struct ping_resp *ping_resp = pdata; struct ping_option *ping_opt = arg; os_printf("ping host fail rn"); else { os_printf("Ping thanh congn"); if(!is_led_blinking) { os_printf("Start blinkn"); set_gpio_mode(LED_GPIO, GPIO_OUTPUT, GPIO_PULLUP); gpio_write(LED_GPIO, 1); os_timer_disarm(&blink_timer); os_timer_setfn(&blink_timer, (os_timer_func_t *)blink_cb, (void *)0); os_timer_arm(&blink_timer, 2000, 1); is_led_blinking = true; } } void blink_cb(void *arg) { gpio_write(LED_GPIO, led_state); led_state ^=1; }

Các bạn có thể download file user_main.c ở đây. Để chạy ứng dụng, các bạn chỉ cần thay đổi tên mạng Wifi và password tương ứng cho marco WIFI_SSID và WIFI_PASSWORD trong user_main.c

Compile và chạy ứng dụng

Sau khi compile project trong Eclipse, chúng ta sẽ thấy 2 file firmware được tạo ra trong thư mục /demo_phan6/firmware/ là chúng tôi và chúng tôi Đây là 2 file bin để nạp trong trường hợp non-FOTA.

Mở Flash Download Tool của Espressif và thiết lập như sau:

Kết nối như hình trên và bắt đầu nạp code ứng dụng xuống ESP01

Khởi động lại module ESP01 với chân GPIO0 không còn nối GND, mở cổng COM trong chương trình Terminal với baudrate 115200, chúng ta có thể thấy log chương trình khi chạy và LED blue trên board sẽ blink chu kỳ 2s sau khi ping thành công với tên miền “google.com”

Hướng Dẫn Sử Dụng Esp8266 Trong Các Ứng Dụng Internet Of Things (Phần 4)

Phần 4: Demo giao tiếp với ESP8266 thông qua AT commands

Bước chuẩn bị

Chúng ta sẽ sử dụng các module phần cứng sau:

2 board Arduino Chúng ta sẽ có demo 2 board Arudino giao tiếp với nhau qua mạng Wifi tạo bởi ESP8266, do đó chúng ta cần tối thiểu 2 board Arduino để làm 2 node trong demo này. Ở đây chúng ta sẽ dùng board Due và board ATmega2560

1 module FTDI FT232RL để nạp firmware xuống module ESP-01

1 smartphone

1 wifi router

Về software thì chúng ta cần chuẩn bị:

Cài 2 app WIFI TCP Test Tool và WIFI UDP Test Tool vào iPhone. Với Android thì chúng ta có thể sử dụng app TCP Socket và Simple UDP Tester

Download và cài Arduino IDE. Download ở đây

Phần mềm ESP8266 Flash Download Tool. Download ở đây

Nạp firmware cho ESP8266

Bài viết trong phần 2 đã giới thiệu các file *.bin trong thư mục at/ của Non RTOS SDK và các file nào được nạp trong trường hợp chúng ta muốn có chức năng FOTA hoặc không có FTOA. Trong phần này, chúng ta sẽ demo việc nạp firmware theo cả 2 hướng.

Chúng ta sẽ kết nối module ESP-01 và module FT232RL để nạp firmware như hình bên dưới:

Nạp firmware không hỗ trợ FOTA

Chúng ta sẽ mở chương trình ESP8266 Flash Download Tool và chọn các file .bin, chọn các địa chỉ bắt đầu tương ứng và dung lượng chip Flash 8Mbit như hình bên dưới:

esp_init_data_default.bin = 0xfc000

blank.bin = 0x7e000 và 0xfe000

eagle.flash.bin = 0x00000

eagle.irom0text.bin = 0x10000

Chọn FLASH SIZE là 8Mbit Ấn Start để bắt đầu quá trình nạp firmware xuống module ESP-01

Nạp firmware có hỗ trợ FOTA

Chúng ta có thể nạp các file .bin khác để ESP8266 có thêm tính năng FOTA với ESP8266 Flash Download Tool như sau:

boot_v1.2.bin = 0x00000

user1.1024.new.2.bin = 0x01000

user2.1024.new.2.bin = 0x41000

esp_init_data_default.bin = 0xfc000

blank.bin = 0xfe000 và 0x7e000

OK, tới đây chúng ta đã nạp các file .bin cần thiết để module ESP-01 có thể hoạt động như 1 Wifi module độc lập rồi. Các bạn có thể chọn nạp có hỗ trợ FOTA hoặc không hỗ trợ chức năng này như trên. Hiện tại chúng ta chưa quan tâm đến FOTA nên cách nào cũng OK, tùy các bạn.

Demo truyền dữ liệu với web server dùng ESP8266

Với demo này, chúng ta sẽ lập trình Arduino gửi AT commands để module ESP-01 thành 1 thiết bị Wifi, kết nối vào mạng Wifi xung quanh, gửi lệnh PING lên 1 web server và nhận response từ web server đó.

Về phần cứng, chúng ta sẽ kết nối Arduino Due và ESP-01 như hình sau:

Flow chương trình trên Arduino sẽ như sau:

Gửi lệnh “AT” để kiểm tra kết nối module với ESP-01 và đợi nhận “OK” từ ESP8266

Gửi lệnh “AT+CWMODE=1” để module ESP-01 hoạt động như 1 thiết bị Wifi

Gửi lệnh “AT+PING=”google.com” ” để ping server của Google

Nhận PING response từ module ESP-01

Đơn giản phải không nào! Các bạn có thể download Arduino sketch của demo Adruino_Esp8266_PingGoogle

Hình bên dưới là màn hình log COM trên Arduino quá trình khởi động và ping web server của Google:

Demo giao tiếp với Smartphone dùng ESP8266

Trong demo này, chúng ta sẽ tạo 1 ứng dụng trong đó smartphone sẽ trao đổi dữ liệu với thiết bị có ESP8266. Chúng ta có thể sử dụng 1 wifi router trung gian giữa 2 thiết bị Wifi là ESP8266 và smartphone. Cách khác đơn giản và hiệu quả hơn là sử dụng ESP8266 như là 1 rounter để kết nối với smartphone, do đó sẽ không cần router trung gian nữa. Chúng ta sẽ chọn cách đơn giản bằng cách sử dụng module ESP-01 như 1 Access Point để smartphone có thể kết nối vào mạng Wifi tạo bởi module ESP-01. Đồng thời chúng ta cũng tạo TCP server và UDP server trên ESP8266 để truyền nhận dữ liệu với smartphone thông qua các port TCP, UDP

Về phần cứng chúng ta sẽ sử dụng board Arduino ATmega2560, module ESP-01 và iPhone như hình bên dưới:

Các lệnh AT commands được sử dụng theo thứ tự như sau:

Gửi lệnh “AT” đầu tiên để kiểm tra giao tiếp, kết nối với module ESP-01

Gửi lệnh “AT+CWMODE=2” để module ESP-01 hoạt động như 1 Access Point

Gửi lệnh “AT+CWSAP=”ESP_HTelectronics”,””,5,0″ đẻ tạo mạng Wifi tên là “ESP_HTelectronics”, không security và không password

Gửi lệnh “AT+CIPMUX=1” để cho phép các kết nối TCP/UDP

Gửi lệnh “AT+CIPSERVER=1,1234” để tạo 1 TCP server, port 1234 trên module ESP-01

Liên tục kiểm tra dữ liệu nhận được từ port 1234 gửi lên từ ESP-01 và xử lý dữ liệu tương ứng

Chỉ đơn giản vậy thôi. Các bạn có thể download demo sketch Adruino_Esp8266_TCP

Sau khi nạp code vào board ATmega2560, chúng ta sẽ dùng smartphone kết nối với module ESP-01 trong Wifi setting, sau đó mở app WIFI TCP Test Tool để truyền/nhận dữ liệu với board Arduino

Trên phone, chúng ta sẽ connect vào TCP port 1234 đã được mở trong ESP8266 và gửi dòng text “Who are you”, khi ESP-01 nhận được sẽ trả lời “I’m ESP_HTelectronics” lên smartphone và chúng ta thấy hiện trong phần Received data của app. Với nguyên lý này, chúng ta có thể tạo thiết bị IoT sử dụng ESP8266 để giao tiếp trực tiếp với Smartphone.

Truyền dữ liệu UDP với smartphone

Tương tự như demo trên, nhưng chúng ta sẽ thử truyền dữ liệu thông qua UDP server trên ESP8266

Các lệnh AT commands được sử dụng theo thứ tự như sau:

Gửi lệnh “AT” đầu tiên để kiểm tra giao tiếp, kết nối với module ESP-01

Gửi lệnh “AT+CWMODE=2” để module ESP-01 hoạt động như 1 Access Point

Gửi lệnh “AT+CWSAP=”ESP_HTelectronics”,””,5,0″ đẻ tạo mạng Wifi tên là “ESP_HTelectronics”, không security và không password

Gửi lệnh “AT+CIPMUX=1” để cho phép các kết nối TCP/UDP

Gửi lệnh “AT+CIPSTART=0,”UDP”,”255.255.255.255″,1234,1234,2″ để tạo 1 UDP server, port 1234 trên module ESP-01

Liên tục kiểm tra dữ liệu nhận được từ port 1234 gửi lên từ ESP-01 và xử lý dữ liệu tương ứng

Tương tự như demo trên, chúng ta sẽ mở app WIFI UDP Test Tool để truyền nhận dữ liệu với board ATmega2560 thông qua ESP-01 dùng UDP như hình bên dưới:

Các bạn có thể download demo sketch Adruino_Esp8266_UDP

Demo giao tiếp giữa 2 module ESP8266

OK, chúng ta đã đi qua 2 demo sử dụng 2 chế độ hoạt động của ESP8266 là chế độ thiết bị Wifi và chế độ Access Point. Trong phần demo này chúng ta sẽ tạo 1 ứng dụng trong đó 2 board arduino sẽ giao tiếp trực tiếp với nhau qua mạng Wifi được tạo bởi ESP8266. Chúng ta có thể ứng dụng demo này trong các mạng wireless sensor trong đó các thiết bị IoT là các node và nói chuyện trực tiếp với nhau mà không cần smartphone hay router hay web server ở trung gian.

Về kết nối phần cứng thì chúng ta sẽ giả lập 2 node trong 1 network dùng 2 board ATmega2560 và board Due cùng với 2 module ESP-01 như hình bên dưới:

Các lệnh AT commands truyền từ board Due như sau:

Gửi lệnh “AT” đầu tiên để kiểm tra giao tiếp, kết nối với module ESP-01

Gửi lệnh “AT+CWMODE=2” để module ESP-01 hoạt động như 1 Access Point

Gửi lệnh “AT+CWSAP=”ESP_HTelectronics”,””,5,0″ đẻ tạo mạng Wifi tên là “ESP_HTelectronics”, không security và không password

Gửi lệnh “AT+CIPMUX=1” để cho phép các kết nối TCP/UDP

Gửi lệnh “AT+CIPSTART=0,”UDP”,”255.255.255.255″,1234,1234,2″ để tạo 1 UDP server, port 1234 trên module ESP-01

Liên tục kiểm tra dữ liệu nhận được từ port 1234 gửi lên từ ESP-01 và xử lý dữ liệu tương ứng

Các lệnh AT commands truyền từ board ATmega2560 như sau:

Gửi lệnh “AT” đầu tiên để kiểm tra giao tiếp, kết nối với module ESP-01

Gửi lệnh “AT+CWMODE=1” để module ESP-01 hoạt động như 1 thiết bị Wifi

Gửi lệnh “AT+CWJAP=”ESP_HTelectronics”,””” để kết nối vào mạng Wifi “ESP_HTelectronics” được tạo bởi thiết bị bên board Due. Sau lệnh này chúng ta cần đợi vài giây để module ESP-01 kết nối vào mạng Wifi. Chúng ta sẽ liên tục nhận dữ liệu từ ESP8266 đến khi nhận được “OK”

Gửi lệnh “AT+CIPMUX=1” để cho phép các kết nối TCP/UDP

Gửi lệnh “AT+CIPSTART=0,”UDP”,”192.168.4.1″,1234,1234,2″ để kết nối vào UDP server, port 1234 trên server có địa chỉ IP là 192.168.4.1 Lưu ý địa chỉ IP mặc định của ESP8266 là 192.168.4.1, do đó chúng ta có thể hardcode trong code của UDP client. Nếu ESP8266 bên UDP Server thay đổi địa chỉ IP thì chúng ta cần thay đổi bên UDP client để 2 module ESP-01 có thể kết nối UDP với nhau

Gửi dữ liệu là text “Who are you” vào UDP port đã kết nối

Nhận dữ liệu truyền lại từ UDP server bên board Due

Các bạn có thể download sketch cho UDP Server và UDP Client Adruino_Esp8266_UDP_Server , Adruino_Esp8266_UDP_Client

Hướng Dẫn Sử Dụng Esp8266 Trong Các Ứng Dụng Internet Of Things (Phần 1) – Htelectronics

Giới thiệu về dòng chip Wifi ESP8266

Chip ESP8266 được phát triển bởi Espressif để cung cấp giải pháp giao tiếp Wifi cho các thiết bị IoT. Điểm đặc biệt của dòng ESP8266 là nó được tích hợp các mạch RF như balun, antenna switches, TX power amplifier và RX filter ngay bên trong chip với kích thước rất nhỏ chỉ 5x5mm nên các board sử dụng ESP8266 không cần kích thước board lớn cũng như không cần nhiều linh kiện xung quanh. Ngoài ra, giá thành của ESP8266 cũng rất thấp đủ để hấp dẫn các nhà phát triển sản phẩm IoT

Tóm lại, ESP8266 vừa tích hợp nhiều phần cứng hỗ trợ, vừa kích thước nhỏ, vừa hợp túi tiền thì sao chúng ta có thể cưỡng lại được, đúng không nào ?

Cấu trúc phần cứng của dòng chip ESP8266 có thể tóm tắt như sau:

Sử dụng 32-bit MCU core có tên là Tensilica

Tốc độ system clock có thể set ở 80MHz hoặc 160MHz

Không tích hợp bộ nhớ Flash để lưu chương trình

Tích hợp 50KB RAM để lưu dữ liệu ứng dụng khi chạy

Có đầy đủ các ngoại vi chuẩn đê giao tiếp như 17 GPIO, 1 Slave SDIO, 3 SPI, 1 I2C, 1 I2S, 2 UART, 2 PWM

Tích hợp các mạch RF để truyền nhận dữ liệu ở tần số 2.4GHz

Hỗ trợ các hoạt động truyền nhận các IP packages ở mức hardware như Acknowledgement, Fragmentation và Defragmentation, Aggregation, Frame Encapsulation v.v…  (và phần stack TCP/IP sẽ được thực hiện trên firmware của ESP8266)

Do không hỗ trợ bộ nhớ Flash nên các board sử dụng ESP8266 phải gắn thêm chip Flash bên ngoài và thường là Flash SPI để ESP8266 có thể đọc chương trình ứng dụng với chuẩn SDIO hoặc SPI.

Chúng ta có thể thấy board ESP8266 chỉ cần thạch anh và SPI flash chip và vài linh kiện điện trở rất đơn giản phải không nào. Do đó việc tích hợp giao tiếp Wifi vào board ứng dụng với ESP8266 rất dễ dàng và nhanh chóng.

Về mô hình lập trình ứng dụng với ESP8266, chúng ta có thể chia làm 2 loại như sau:

Sử dụng firmware được cung cấp bởi Espressif và giao tiếp thông qua AT commands

Lập trình firmware trực tiếp vào ESP8266 sử dụng bộ thư viện SDK cung cấp bởi Espressif

Các chế độ boot up của ESP8266

Do ESP8266 không tích hợp Flash bên trong chip để lưu code ứng dụng nên chúng ta phải lưu code ứng dụng trong bộ nhớ ngoài bao gồm chip SPI Flash hoặc SDCard. Chúng ta có thể kết nối 1 số chân GPIO để báo cho ESP8266 nơi lưu code ứng dụng để từ đó ESP8266 có thể đọc code và thực thi.

Các chế độ boot up của ESP và cấu hình chân GPIO tương ứng  như sau:

Chân MTD0 chính là chân GPIO15 của ESP8266. Chúng ta có thể kết nối điện trở kéo lên/kéo xuống hoặc dùng nút nhấn v.v.. trên board tạo tín hiệu High/Low cho các chân để chọn bộ nhớ chứa code trên board mà ESP8266 có thể đọc vào và thực thi (ví dụ như SPI Flash chip, SDCard). Ngoài ra ESP8266 còn chế độ cho phép truyền code ứng dụng từ máy tính thông qua UART và lưu vào bộ nhớ SPI Flash trên board. Chúng ta sẽ dùng chế độ này để nạp code mới cho các board ESP8266

Các loại module cho ESP8266 trên thị trường

Ngoại trừ module ESP-WROOM-02 được phát triển bởi chính Espressif cho mục đích nghiên cứu các tính năng của ESP8266, các module ứng dụng phổ biến hiện nay của ESP8266 đều được phát triển bởi công ty AI-Thinker

Hiện tại có khá nhiều module khác nhau cho ESP8266 được sản xuất bởi công ty AI-Thinker. Đặc điểm khác nhau giữa các module này bao gồm:

Loại anten sử dụng (PCB anten, chip anten hoặc gắn anten ngoài)

Dung lượng của chip Flash SPI trên board

Kích thước board của module

Có gắn khung nhôm chống nhiễu hay không

Số lượng pin GPIO đưa ra chân kết nối

Hiện tại AI-Thinker sản xuất 14 loại module cho ESP  từ module ESP-01 đến ESP-14. Các bạn có thể tham khảo chi tiết tất cả 14 loại module này trong website http://www.esp8266.com/wiki/doku.php?id=esp8266-module-family

Ở thị trường VN thì 3 module là ESP-01, ESP-07 và ESP-12F khá phổ biến và sẽ được sử dụng để demo trong các bài viết sau nên chúng ta sẽ giới thiệu sơ các module ở đây:

ESP-01

Sử dụng on-board PCB antenna Có 2 LED trên board để báo nguồn và báo TX Cung cấp 3 chân GPIO (GPIO0, GPIO2 và GPIO6) và 2 chân TXD/RXD cho UART Dung lượng SPI Flash 4MByte Đưa chân ra jumper luôn nên có thể kết nối trực tiếp với các board khác 1 cách nhanh chóng Thông tin chi tiết có thể tham khảo ở đây

ESP-07

Sử dụng chip anten on-board và có IPEX connector hỗ trợ gắn thêm anten ngoài để tăng khoảng cách truyền Có 2 LED trên board để báo nguồn và báo TX Đưa ra 9 chân GPIO, 2 chân TX/RX cho UART, 1 chân REST để reset chip, 1 chân ADC, 1 chân CH_PD để đưa chip vào chế độ low power Dung lượng SPI Flash trên board là 4MByte Có thể hàn thêm jumper để kết nối trực tiếp với board khác hoặc hàn trực tiếp lên board ứng dụng Thông tin chi tiết có thể tham khảo ở đây

ESP-12F

Sử dụng PCB anten on-board Đưa ra 11 chân GPIO, 2 chân TX/RX cho UART,  các chân cho SPI, chân RST để reset chip, 1 chân ADC Dung lượng SPI Flash là 4MByte Có thể hàn jumper để căm dây vào các board khác hoặc hàn trực tiếp lên board ứng dụng Thông tin chi tiết có thể tham khảo ở đây

Qua 3 module ESP8266 trên chúng ta có thể so sánh nhanh như sau:

ESP-01 đơn giản nhất, số chân GPIO ít nhất và không có shield chống nhiễu

ESP-07 thì nhiều chân GPIO hơn, có shield chống nhiễu nhưng dùng chip antenna nên khoảng cách truyền không xa bằng PCB anten. Tuy nhiên có thể tăng khoảng cách truyền bằng cách gắn thêm anten ngoài với IPEX connector trên board

ESP-12F đưa ra nhiều chân GPIO nhất, có shield chống nhiễu và on-board PCB anten  (lưu ý là mặc dù có các chân SPI nhưng đã được sử dụng để đọc SPI Flash bên trong nên chúng ta không thể sử dụng các chân này nha)

Do đó tùy vào yêu cầu của ứng dụng, chúng ta có thể lựa chọn module từ đơn giản đến phức tạp

Qua bài viết này, chúng ta đã được giới thiệu tổng quan về dòng chip ESP8266 cho giao tiếp Wifi của các thiết bị IoT. Đây là chip SOC tích hợp đầy đủ mạch RF và phần cứng để hỗ trợ truyền nhận dữ liệu trên Wifi nên không yêu cầu thiết kế board phức tạp; và đặc biệt giá thành lại rất rẻ nên rất phổ biến trong cộng đồng phát triển ứng dụng IoT. Trong bài viết, chúng ta đã khảo sát kiến trúc phần cứng, các ngoại vi, mạch nguyên lý cũng như các module phổ biến hiện nay của ESP8266. Đây chính là kiến thức cần thiết để tiếp tục tìm hiểu sâu hơn về cách sử dụng ESP8266 trong các bài viết tiếp theo.

Sử Dụng Arduino Ide Lập Trình Esp8266 Nodemcu

Song song với các phiên bản Arduino khác nhau như Arduino UNO R3, Tiny, … ESP8266 NodeMCU là một trong những mạch phổ biến trong việc phát triển các dự án IoTs. Ưu điểm của mạch này là module wifi được tích hợp sẵn và sử dụng một vi điều khiển mạnh mẽ hơn so với Arduino nguyên thủy.

Ngoài sử dụng ngôn ngữ lập trình Lua ta còn có thể lập trình sử dụng ngôn ngữ C/C++ thông qua Arduino IDE.

Tích hợp thư viện hỗ trợ ESP8266 NodeMCU

Lần lượt thực hiện các bước sau để tích hợp thư viện hỗ trợ lập trình mạch ESP8266 NodeMCU.

Bước 1: Thêm đường dẫn để tải các package cho NodeMCU vào Arduino IDE

Khởi động Arduino IDE, từ màn hình chính chọn File → Preferences, thêm đường dẫn bên dưới vào mục Addition Boards Manager URLs.

http://arduino.esp8266.com/stable/package_esp8266com_index.json

Chọn OK để xác nhận.

Bước 2: Tải thư viện hỗ trợ

Từ giao diện chính của Arduino IDE, chọn Tools → Board → Board Managers, … Tại thanh tìm kiếm của hộp thoại Board Managers nhập vào esp8266, chọn Install để tiến hành tải và cài đặt thư viện.

Cài đặt thành công, giao diện của Board Managers sẽ trở nên như hình dưới – hoàn tất cài đặt.

Caption

Lập trình cho ESP8266 NodeMCU

Do đây là một board Arduino-compatable, cấu trúc của một chương trình dành cho mạch này sẽ tuân theo cấu trúc của một chương trình viết cho mạch Arduino bao gồm có 2 phần chính:

Hàm setup(): được gọi một lần duy nhất khi mạch được khởi động.

Hàm loop(): được gọi lặp lại trong suốt quá trình hoạt động của mạch.

Để làm quen, viết một chương trình cho ESP điều khiển một đèn LED nhấp nháy theo chu kì 1 giây. Linh kiện cần chuẩn bị bao gồm:

Sơ đồ mạch

Lập trình

Đoạn code sau minh họa việc điều khiển đèn LED chớp theo chu kì 1 giây.

#define LED_PIN 12 #define DELAY_TIME 500 void setup() { pinMode(LED_PIN, OUTPUT); } void loop() { digitalWrite(LED_PIN, LOW); delay(DELAY_TIME); digitalWrite(LED_PIN, HIGH); delay(DELAY_TIME); }

Nạp code

Thao tác nạp code cho mạch ESP8266 NodeMCU cũng tương tự như nạp cho mạch Arduino thông thường. Tuy nhiên, phải chọn phiên bản phù hợp với board đang sử dụng bằng menu Tools → Board. Do mạch trong bài viết là ESP8266 NodeMCU (ESP-12 module) nên phiên bản phù hợp là NodeMCU 0.9.

Sau khi nạp code thành công, đèn LED nhấp nháy theo chu kì định sẵn.

Bạn đang xem bài viết Hướng Dẫn Sử Dụng Esp8266 Trong Các Ứng Dụng Internet Of Things (Phần 6) trên website Karefresh.com. Hy vọng những thông tin mà chúng tôi đã chia sẻ là hữu ích với bạn. Nếu nội dung hay, ý nghĩa bạn hãy chia sẻ với bạn bè của mình và luôn theo dõi, ủng hộ chúng tôi để cập nhật những thông tin mới nhất. Chúc bạn một ngày tốt lành!