Chương 2 : TỔNG QUAN
2.2. Giao tiếp Arduino với ESP8266
2.2.4. Giao tiếp ESP8266 chuẩn SPI
Khái niệm : SPI (Serial Peripheral Interface) là chuẩn giao tiếp dạng bus được đưa ra bởi Motorola Corp.
SPI dùng 4 chân kết nối, nên ta thường gọi nó là kết nối dạng 4 dây.
SPI là full duplex master-slave communication protocol. Có nghĩa là chỉ một master và một slave có thể kết nối nhau thông qua bus interface trong cùng một thời điểm.
SPI cho phép device có thể làm việc mở 2 mode cơ bản là SPI Master Mode và SPI Slave Mode.
Master Device sẽ phản hồi thông tin thiết lập kết nối. Master Device tạo ra Serial Clock để đồng bộ data truyền nhận. Master Device cịn có thể quản lý nhiều slave devices trên bus bằng việc lựa chọn từng cái.
ESP8266 có chân SPI (SD1, CMD, SD0, CLK) dùng cho Quad-SPI communication với flash memory trên ESP-12E, vì thế ta sẽ khơng thể sử dụng những chân này được, ta sẽ dùng các chân thay thế là GPIO14-GPIO17, có thể xem hình dưới đây.
CHƯƠNG 2. TỔNG QUAN
Hình 2.11 Sơ đồ chân SPI ESP8266
MISO (Master In Slave Out): Master nhận data và slave truyền data qua pin này.
MOSI (Master Out Slave In): Master truyền data và slave nhận data qua pin này.
SCLK (Serial Clock): Master tạo clock cho kết nối, slave dùng clock này. Chỉ duy nhất master có thể thiết lập được serial clock.
CS (Chip Select): Master có thể lựa chọn slave device thơng qua pin này để bắt đầu kết nối với nó.
CHƯƠNG 2. TỔNG QUAN
Sơ đồ kết nối
Hình 2.12 Sơ đồ kết nối Arduino Uno với ESP8266 chuẩn SPI
Chương trình
Viết chương trình giao tiếp SPI cho ESP8266/NodeMCU và Uno/Mega, ở đây NodeMCU là master device và Uno/Mega là slave device.
NodeMCU sẽ gửi lời chào với chuỗi “Hello Slave” với ‘\n’ ở cuối chuỗi . Uno/Mega Slave device nhận chuỗi này và in nó ra serial.
Code cho NodeMCU
#include<SPI.h>
char buff[]="Hello Slave\n"; void setup() {
CHƯƠNG 2. TỔNG QUAN
SPI.begin(); /* begin SPI */ }
void loop() {
for(inti=0; i<sizeof buff; i++) /* transfer buff data per second */
SPI.transfer(buff[i]); delay(1000);
}
Code cho Uno/Mega
#include <SPI.h> char buff [100]; volatile byte index;
volatile bool receivedone; /* use reception complete flag */ void setup (void)
{
Serial.begin (9600);
SPCR |= bit(SPE); /* Enable SPI */
pinMode(MISO, OUTPUT); /* Make MISO pin as OUTPUT */ index = 0;
receivedone = false;
SPI.attachInterrupt(); /* Attach SPI interrupt */ }
void loop (void) {
if (receivedone) /* Check and print received buffer if any */ { buff[index] = 0; Serial.println(buff); index = 0; receivedone = false; } }
CHƯƠNG 2. TỔNG QUAN
// SPI interrupt routine ISR (SPI_STC_vect)
{
uint8_t oldsrg = SREG; cli();
char c = SPDR;
if (index <sizeof buff) {
buff [index++] = c;
if (c == '\n'){ /* Check for newline character as end of msg */ receivedone = true; } } SREG = oldsrg; }