Mình xin giới thiệu cách để gửi dữ liệu lên thingspeak với TIVA C và ESP8266. Trong các bài viết trước mình có chia sẻ cách lấy dữ liệu với TIVA nhưng đây chỉ là cách cục bộ, tức là chỉ quan sát được tại chỗ, không thể giám sát và theo dõi từ xa được. Nhân tiện kết hợp được TIVA C và ESP8266 thì mình đã có trợ thủ đắc lực có thể giúp đỡ gửi dữ liệu lên trên mây thông qua internet, nhờ đó mình có thể giám sát được dữ liệu ở bất kỳ đâu.
Để dễ hình dung bạn có thể xem hình sau
Ta có thể thấy tất cả mọi thông tin về nhiệt độ, độ ẩm, ánh sáng,… sẽ được TIVA C thu thập, sau đó sẽ gửi lên internet thông qua Wifi ở đây là modul ESP8266, những thông tin được gửi lên sẽ được lưu lại trên một server, server có sẵn được chọn là thingspeak. Từ điện thoại và máy tính ở bất kỳ đâu thì ta cũng có thể truy cập vào thingspeak để quan sát được các thông số mà TIVA C đã gửi lên.
Chuẩn bị
Phần cứng
- TIVA C Launchpad
- Dây nối
- ESP8266 phiên bản từ v1 tới v12 (mình dùng v1) dùng firmware AT command
Phần mềm
- Energia IDE
Tạo tài khoản thingspeak
Bên thingspeak hơi làm khó chúng ta một chút là phải có tài khoản matwork, do đó mình cứ làm một tài khoản bên đó rồi đăng nhập sang bên này nhé.
Sau khi tạo xong tài khoản và đăng nhập thành công thì chọn New Channel để có kênh mới nhận dữ liệu
Chúng ta có tên, mô tả, và Field 1 – 8 là trường để nhận dữ liệu, thingspeak giới hạn tối đa 8 trường, do đó nếu muốn sử dụng hơn thì chắc phải chọn thằng khác hoặc tự dựng server, nhưng các bạn yên tâm, với 8 trường này thì đủ cho chúng ta có thể thử nghiệm rồi.
Tick chọn public nếu bạn muốn cho mọi người xem được kênh của mình
Phần quan trọng nhất còn lại là lấy API Key để Read và Write dữ liệu lên, bạn chọn vào thẻ API Keys, sau đó copy lại 2 mục Key chỗ Write/Read API Key đê sử dụng trong lập trình
Gửi dữ liệu bằng tay
Mình sẽ thử gửi dữ liệu bằng tay, gõ các đoạn mã gửi cho ESP8266 trước thông qua phần mềm sscom để kiểm tra xem có kết nối và đưa được dữ liệu lên thingspeak không ?
Ta sẽ thử gửi lệnh theo bảng mô tả dưới dây
Lệnh AT | Phản hồi | Mô tả |
---|---|---|
AT+CWMODE =1 | OK | Cài đặt chế độ station |
AT+CWJAP = "ten_wifi", "pass" | OK | Kết nối với mạng wifi |
AT+CIPMUX = 1 | OK | Cài đặt chế độ đa kết nối |
AT+CIFSR | OK | Hiển thị IP |
AT+CIPSTART=1,"TCP","184.106.153.149",80 | OK | Kết nối tới thingspeak địa chỉ 184.106.153.149, port 80 thông qua TCP |
AT+CIPSEND=1,44 | > | Gửi gói tin TCP/IP với 1 là id, 44 là độ dài gói tin |
GET /update?key=B549R51BLLQxxxx&field1=67 | SEND OKOK | Cập nhật thông số field1 với key Write của thingspeak |
Kết quả ta sẽ thấy 1 điểm trên biểu đồ và phần update last entry sẽ là thời gian gần nhất
Gửi dữ liệu tự động
Tạm thời yên tâm là kết nối server, gửi dữ liệu thủ công lên đã ổn, giờ tranh thủ lập trình thêm một chút để TIVA C làm nhiệm vụ này thay cho chúng ta
Lại lục chút kiến thức bài cũ ra một chút, thử lại kết nối giữa TIVA C và ESP8266 xem có ổn không, nếu gửi AT nhận OK thì bắt đầu bước tiếp theo thôi
Bước 1: thực hiện lập trình kết nối server thingspeak, cách nối dây các bạn xem trong code luôn nhé
/* Chương trình giao tiếp giữa TIVA và ESP8266 dùng firmware AT-Command của ai-thinker
Kết nối với server thingspeak
Tạo bởi Hocarm.org
Kết nối
ESP8266 | TIVA | Nguồn ngoài
VCC | x | 3.3v
GND | GND | GND
CH_PD | x | 3.3v
RX | PB1 | x
TX | PB0 | x
Tốc độ baud kết nối với ESP tùy thuộc vào baud của firmware.
*/
char IP[] = "184.106.153.149";
char msg[] = "GET /update?key=xxxxxxxxx"; //Thay xxxxxxxxx bằng key của bạn ở mục API Write key
char aux_str[100];
int leg;
void setup() {
Serial.begin(115200); //Cấu hình debug với baud 115200
Serial1.begin(9600); //Cấu hình giao tiếp với ESP8266 baud 9600
sendATcommand("AT", "OK", 3000); //Kiểm tra kết nối
sendATcommand("AT+CWMODE=1", "OK", 3000); //Cấu hình chế độ station
sendATcommand("AT+CWJAP=\"ten_wifi\",\"mat_khau\"", "OK", 3000); //Thay ten_wifi và mat_khau của bạn
sendATcommand("AT+CIPMUX=1", "OK", 3000); // Bật chế độ đa kết nối
sendATcommand("AT+CIFSR", "OK", 3000); // Hiển thị ip
//Kết nối tới server thingspeak
snprintf(aux_str, sizeof(aux_str), "AT+CIPSTART=1,\"TCP\",\"%s\",80", IP);
if (sendATcommand2(aux_str, "OK", "ERROR", 30000) == 1)
{
Serial.println("OK Connected Thingspeak");
}
sendATcommand("AT+CIPCLOSE=1", "OK", 5000); //Đóng kết nối
}
void loop() {
// sendATcommand("AT", "OK", 3000);
// delay(1000);
}
// Hàm gửi lệnh AT
int8_t sendATcommand(char* ATcommand, char* expected_answer, unsigned int timeout) {
uint8_t x = 0, answer = 0;
char response[100];
unsigned long previous;
memset(response, '\0', 100); // xóa buffer
delay(100);
while ( Serial1.available() > 0) Serial1.read(); // đọc input
Serial1.println(ATcommand); // Gửi lệnh AT
x = 0;
previous = millis();
// Chờ phản hồi
do {
if (Serial1.available() != 0) {
// Nếu có dữ liệu trong buffer UART, đọc và kiểm tra nó với expected_answer
response[x] = Serial1.read();
x++;
// Nếu đúng thì trả kết quả answer = 1, thoát hàm
if (strstr(response, expected_answer) != NULL)
{
answer = 1;
}
}
} while ((answer == 0) && ((millis() - previous) < timeout)); // Nếu sai thì tiếp tục thử lại cho tới hết thời gian timeout
Serial.println(response); // In giá trị nhận được để debug
return answer;
}
// Hàm gửi lệnh AT 2 để gửi dữ liệu
int8_t sendATcommand2(char* ATcommand, char* expected_answer1,
char* expected_answer2, unsigned int timeout) {
uint8_t x = 0, answer = 0;
char response[100];
unsigned long previous;
memset(response, '\0', 100); // Khởi tạo lại chuỗi về 0
delay(100);
while ( Serial1.available() > 0) Serial1.read(); // Xóa buffer
Serial1.println(ATcommand); // Gửi lệnh AT
x = 0;
previous = millis();
// Chờ phản hồi
do {
// Nếu có dữ liệu từ UART thì đọc và kiểm tra
if (Serial1.available() != 0) {
response[x] = Serial1.read();
x++;
// Trả về giá trị 1 nếu nhận được expected_answer1
if (strstr(response, expected_answer1) != NULL)
{
answer = 1;
}
// Trả về giá trị 2 nếu nhận được expected_answer2
else if (strstr(response, expected_answer2) != NULL)
{
answer = 2;
}
}
}
// Đợi time out
while ((answer == 0) && ((millis() - previous) < timeout));
Serial.println(response); // In giá trị nhận được để debug
return answer;
}
Kết quả
Bước 2: Thực hiện gửi dữ liệu lên field1 của thingspeak
/* Chương trình giao tiếp giữa TIVA và ESP8266 dùng firmware AT-Command của ai-thinker
Kết nối với server thingspeak và gửi dữ liệu lên field1
Tạo bởi Hocarm.org
Kết nối
ESP8266 | TIVA | Nguồn ngoài
VCC | x | 3.3v
GND | GND | GND
CH_PD | x | 3.3v
RX | PB1 | x
TX | PB0 | x
Tốc độ baud kết nối với ESP tùy thuộc vào baud của firmware.
*/
char IP[] = "184.106.153.149";
char msg[] = "GET /update?key=xxxxxxxxx"; //Thay xxxxxxxxx bằng key của bạn ở mục API Write key
char aux_str[100];
char cmd[100];
int leg;
int number = 12; // Giá trị sẽ gửi lên thingspeak
void setup() {
Serial.begin(115200); //Cấu hình debug với baud 115200
Serial1.begin(9600); //Cấu hình giao tiếp với ESP8266 baud 9600
sendATcommand("AT", "OK", 5000); //Kiểm tra kết nối
sendATcommand("AT+CWMODE=1", "OK", 5000); //Cấu hình chế độ station
sendATcommand("AT+CWJAP=\"ten_wifi\",\"mat_khau\"", "OK", 5000); //Thay ten_wifi và mat_khau của bạn
sendATcommand("AT+CIPMUX=1", "OK", 5000); // Bật chế độ đa kết nối
sendATcommand("AT+CIFSR", "OK", 5000); // Hiển thị ip
//Kết nối tới server thingspeak
memset(aux_str, '\0', 100); //Đặt lại giá trị của aux_str
snprintf(aux_str, sizeof(aux_str), "AT+CIPSTART=1,\"TCP\",\"%s\",80", IP); //Kết nối server thingspeak
if (sendATcommand2(aux_str, "OK", "ERROR", 30000) == 1)
{
Serial.println("OK Connected Thingspeak"); //Kiểm tra nếu kết nối thì thông báo
}
//Gửi data lên thingspeak
sprintf(cmd, "%s&field1=%d", msg, number); //Gộp dữ liệu
leg = strlen(cmd) + 2; // Tính chiều dài dữ liệu, +2 cho ký tự > và dấu cách
sprintf(aux_str, "AT+CIPSEND=1,%d", leg); //Gửi kết nối và chờ >
if (sendATcommand2(aux_str, ">", "ERROR", 30000) == 1)
{
sprintf(cmd, "%s&field1=%d", msg, number); //Gửi toàn bộ thông tin có dạng GET /update?key=xxxxxx&field1=xx
sendATcommand2(cmd, "SEND OK", "ERROR", 10000);
}
else
{
Serial.println("Failed"); //nếu không gửi được báo failed
}
sendATcommand("AT+CIPCLOSE=1", "OK", 5000); //Đóng kết nối
}
void loop() {
// sendATcommand("AT", "OK", 3000);
// delay(1000);
}
// Hàm gửi lệnh AT
int8_t sendATcommand(char* ATcommand, char* expected_answer, unsigned int timeout) {
uint8_t x = 0, answer = 0;
char response[100];
unsigned long previous;
memset(response, '\0', 100); // xóa buffer
delay(100);
while ( Serial1.available() > 0) Serial1.read(); // đọc input
Serial1.println(ATcommand); // Gửi lệnh AT
x = 0;
previous = millis();
// Chờ phản hồi
do {
if (Serial1.available() != 0) {
// Nếu có dữ liệu trong buffer UART, đọc và kiểm tra nó với expected_answer
response[x] = Serial1.read();
x++;
// Nếu đúng thì trả kết quả answer = 1, thoát hàm
if (strstr(response, expected_answer) != NULL)
{
answer = 1;
}
}
} while ((answer == 0) && ((millis() - previous) < timeout)); // Nếu sai thì tiếp tục thử lại cho tới hết thời gian timeout
Serial.println(response); // In giá trị nhận được để debug
return answer;
}
// Hàm gửi lệnh AT 2 để gửi dữ liệu
int8_t sendATcommand2(char* ATcommand, char* expected_answer1,
char* expected_answer2, unsigned int timeout) {
uint8_t x = 0, answer = 0;
char response[100];
unsigned long previous;
memset(response, '\0', 100); // Khởi tạo lại chuỗi về 0
delay(100);
while ( Serial1.available() > 0) Serial1.read(); // Xóa buffer
Serial1.println(ATcommand); // Gửi lệnh AT
x = 0;
previous = millis();
// Chờ phản hồi
do {
// Nếu có dữ liệu từ UART thì đọc và kiểm tra
if (Serial1.available() != 0) {
response[x] = Serial1.read();
x++;
// Trả về giá trị 1 nếu nhận được expected_answer1
if (strstr(response, expected_answer1) != NULL)
{
answer = 1;
}
// Trả về giá trị 2 nếu nhận được expected_answer2
else if (strstr(response, expected_answer2) != NULL)
{
answer = 2;
}
}
}
// Đợi time out
while ((answer == 0) && ((millis() - previous) < timeout));
Serial.println(response); // In giá trị nhận được để debug
return answer;
}
Lưu ý:
Bạn cần thay đúng API thingspeak, tên và mật khẩu wifi của bạn vào code
Nếu không kết nối được server thì bạn có thể reset lại kit TIVA
Cần phải đóng kết nối lại sau khi gửi dữ liệu xong bằng AT+CIPCLOSE=1
Kết quả
Ta thấy log bên dưới sẽ khá giống với những gì làm bằng tay thông qua sscom, thế là cũng tạm ổn rồi
Tiếp theo xem thử trên thingspeak xem thế nào
Giá trị mới là 23 đã được cập nhật lên thingspeak, tuyệt vời ông mặt trời 😀
Bạn có thể xem demo thingspeak của hocarm tại
Ngoài ra ta có thể dùng trang check độ dài online nếu muốn kiểm tra về độ dài của chuỗi
Tạm kết
Vậy là mình đã giới thiệu sơ bộ về cách để gửi dữ liệu lên thingspeak với TIVA C và ESP8266 ở mức độ đơn giản nhất. Nếu không có TIVA C thì bạn có thể chọn cách lập trình trực tiếp gửi dữ liệu từ ESP8266 lên thinkspeak luôn, bài này mình xin phép trình bày ở một bài viết sau.