Hướng dẫn chi tiết cách tạo server và điều khiển Arduino cho dự án IoT | Cộng đồng Arduino Việt Nam

Internet of Things – Iot đang dần phổ cập, nhưng số lượng bài viết hoàn thành xong khá ít. Mình từng gặp yếu tố này, bỏ nhiều thời hạn điều tra và nghiên cứu và đã thành công xuất sắc .
Câu hỏi tiên phong của những bạn khi muốn làm IoT là mở màn từ đâu ? Khó phải không. Bài viết này mình sẽ đi từ bước tiên phong ( tạo server ) tới bước sau cuối ( tinh chỉnh và điều khiển arduino ) nhé. Ưu điểm của tạo webserver là bạn hoàn toàn có thể tinh chỉnh và điều khiển arduino từ bất kỳ đâu có internet, 3G ( so với cách tạo local server của ESP8266 )
Bố cục bài viết gồm có : Tạo server -> Viết code php đơn thuần để nhận lệnh -> ứng dụng android gửi lệnh lên server -> Lập trình arduino với command line đọc lệnh từ server và đổi trạng thái led .

1. Tạo server

Đây là bước quan trọng nhất. Mình tốn khá nhiều thời gian để tìm server nào miễn phí và hỗ trợ php. Rất may đã tìm được.

Đầu tiên bạn vào trang này nhé https://www.000webhost.com/
Nhấn vào Free Signup. Nhập thông tin Tên, E-Mail, Mật Khẩu, nhớ chọn phần Free Subdomain, nhập tên website mình mong ước. Ví dụ như hình mình chọn luutruthongtin, thì sau này webserver của mình sẽ có dạng luutruthongtin.net16.net ( rất lâu rồi mình tạo nó cho chọn số tự do ko phải 16 )

Sau khi xác nhận email, chờ khoảng 30 phút trạng thái tài khoản sẽ được chuyển thành active. Bắt đầu code thôi heart

Nhấn vào Go to CPanel, tìm File Manager 2. Trong hành lang cửa số hiện lên, mở thư mục public_html. Đây là nơi ta lập trình php .

Ra ngoài desktop, tạo 1 file text bất kể, dán đoạn code này vào

Lưu lại với tên bất kể bạn muốn. Trong trường hợp của mình là ReceiveData. php
Quay lại server, bên góc trái trên cùng nhấn Upload file, chọn file của mình rồi OK. Đến đây xong bước 1 rồi đó .

Nếu bạn nào thấy khó có thể bỏ qua bước này, mình đã tạo sẵn server, bạn chỉ cần gửi lệnh lên http://luutruthongtin.net46.net/ReceiveData.php, rồi dán địa chỉ http://luutruthongtin.net46.net/report.php để xem kết quả. Biến là State

2. Gửi lệnh điều khiển Arduino lên server

Có 2 cách để gửi dữ liệu .

  • Cách 1: Viết thêm 1 file php khác tạo textbox, nhập lệnh rồi nhấn gửi (mình đề cập sau vì hơi phức tạp với những bạn chưa quen php)
  • Cách 2: Đơn giản hơn. Bạn tải ứng dụng Android mình làm sẵn trên Play Store

https://play.google.com/store/apps/details?id=com.pub.home.data2server&hl=vi

Cách sử dụng

Hỗ trợ điều khiển và tinh chỉnh 9 thiết bị. Nhấn vào menu bên phải như trên hình để vào thiết lập

Các bạn nhập như trong hình ( Chức năng Various Settings )

  • Web address: Địa chỉ webserver mới tạo (lưu ý không có http://)
  • Ping web address: Chức năng phụ, nhập địa chỉ webserver của bạn để chương trình kiểm tra xem còn kết nối không.
  • Check connection time interval: Thời gian lặp lại kiểm tra (Dành cho ping địa chỉ)

Save Settings để lưu lại .

Chức năng Button settings

Dùng để đặt tên thiết bị, lệnh gửi đi khi nhấn ON và OFF. Các bạn lưu ý biến State tương ứng với file php mình viết ở trên.

Save Settings để lưu lại .
Thoát ra màn hình hiển thị chính, nhấn vào icon mình vừa đổi tên để gửi lệnh. Màu icon sẽ đổi theo lệnh vừa gửi ON / OFF

Đối với những bạn muốn test thử trước khi làm, chỉ cần tải ứng dụng của mình về, thiết lập y hệt như trên hình, nhấn Light, sau đó mở Chrome / Firefox / IE lên nhập địa chỉ http://luutruthongtin.net46.net/report.php sẽ thấy đổi khác tương ứng ( Sau khi nhấn thì refresh lại website sẽ nhìn thấy )

3. Code Arduino

Đoạn code dưới đây mình đã test nhiều lần, có thể tự reset chip ESP8266 khi bị lỗi. Sơ đồ chân cẳng như sau (Arduino Pro Mini)

Arduino ESP8266
2 RX
3 TX
7 CN_PD
3v3 VCC
GND GND

Các bạn thay đổi tên wifi, mật khẩu, tên webserver, tên html theo ý mình nhé. Đoạn code lấy đèn LED 13 của Arduino Pro Mini để hiển thị trạng thái ON/OFF luôn cho tiện laugh

#include 
SoftwareSerial esp(2, 3); // RX | TX

#define BUFFER_SIZE 512
#define GET_SIZE 64
#define CH_PH 7

char OKrn[] = "OK\r\n"; 
char buffer[BUFFER_SIZE];
char get_s[GET_SIZE];
boolean start = false;  //Signal Start
boolean run = false;   //Run loop check internet
boolean conn = false; //Allow connection
String response;    
 
byte wait(int timeout, char* term=OKrn) {
  unsigned long t=millis();
  bool found=false;
  int i=0;
  int len=strlen(term);
  // wait for at most timeout milliseconds
  // or if OK\r\n is found
  while(millis()=len) {
        if(strncmp(buffer+i-len, term, len)==0) {
          found=true;
          break;
        }
      }
    }
  }
  
  buffer[i]=0;
  response.concat(buffer);
  Serial.print(buffer);
  return found;
}

void setup() 
{
    pinMode(CH_PH, OUTPUT);
    pinMode(13, OUTPUT);
    Serial.begin(9600);     while (!Serial)   { ; }
 
    esp.begin(9600); 
    Serial.println("Ready");
    Serial.println("");
    start = true;
}
 
void loop() 
{
  if(start){
    start = false;
    run = true;
    reset();   delay(1000);
    esp.println("AT+CWMODE=3");    wait(1000);   CheckESPResponse();
    esp.println("AT+CWJAP=\"password\",\"ten_wifi\"");    wait(5000); CheckESPResponse();
    
  }
  if(run){  getData();  delay(5000);}
}

void reset(){
  digitalWrite(CH_PH, LOW); 
  digitalWrite(13, HIGH);
  Serial.print("Reset Module.");  delay(500);
  Serial.print(".");              delay(500);
  digitalWrite(CH_PH, HIGH);         delay(1000);
  digitalWrite(13, LOW);
  wait(2000);     delay(2000);
  Serial.println(". Ready"); 
}

void CheckESPResponse(){
  if(response.indexOf("200 OK") >= 0) {conn = true;  Serial.println("connect ok");}
  else if (response.indexOf("SEND OK") >= 0){response = "";  Serial.println("send OK");}
  else if(response.indexOf("ERROR") >= 0){esp.print("AT+CIPCLOSE=0"); wait(1000); conn = false;   response = ""; run = false;  start = true;}
  else if(response.indexOf("OK") >= 0){response = ""; Serial.println("ok");}
}

void getData(){
    esp.println("AT+CIPMUX=1");    wait(3000);  CheckESPResponse();
    String data = "GET /data.html HTTP/1.1\r\nHost: www.luutruthongtin.net46.net\r\n\r\n";
    esp.println("AT+CIPSTART=0,\"TCP\",\"www.luutruthongtin.net46.net\",80\"");    wait(4000); CheckESPResponse(); 
    esp.print("AT+CIPSEND=0,");  
    esp.println(data.length());  wait(2000);  
    esp.print(data); 
    wait(5000);
    CheckESPResponse();
    wait(1000);
    wait(1000);   
    wait(1000);
    wait(1000);
    wait(1000);
    CheckESPResponse();
    delay(1500);
    if(conn){ //Lấy chuỗi
      int index = response.indexOf('<');
      String command = response.substring(index-1, index);
      Serial.println(command);
      if(command == "1")   digitalWrite(13, HIGH);
      else if(command = "0")  digitalWrite(13, LOW);
      esp.print("AT+CIPCLOSE=0"); wait(1000);wait(1000);
      response = "";
    }
}
/*
void SerialEvent(){
  while(Serial.available()){
    char inChar = Serial.read(); 
    if(inChar=='s'){  start = true;  Serial.println("Start!");}
    if(inChar=='t'){  start = false; Serial.println("Stop!"); run = false;}
  }
}*/

Cảm ơn những bạn đã chăm sóc

Có gì vướng mắc xin gửi tin nhắn đến kysiphieulang hoặc comment bên dưới !

Hướng dẫn chi tiết cách tạo server và điều khiển Arduino cho dự án IoT | Cộng đồng Arduino Việt Nam

Bài viết liên quan
Hotline 24/7: O984.666.352
Alternate Text Gọi ngay