Arduino MySQL

Arduino có thể thu thập dữ liệu cảm biến và lưu trữ chúng vào cơ sở dữ liệu MySQL. Arduino cũng có thể nhận dữ liệu (lệnh) từ cơ sở dữ liệu MySQL và điều khiển đèn LED, động cơ, bộ truyền động, thiết bị...

Trong hướng dẫn này, chúng ta sẽ học:

Arduino mysql

Hướng dẫn cung cấp mã Arduino cho hai trường hợp:

Phần cứng cần chuẩn bị

1×Arduino UNO R4 WiFi
1×Alternatively, DIYables STEM V4 IoT
1×(Tùy chọn) DIYables STEM V4 IoT
1×USB Cable Type-A to Type-C (for USB-A PC)
1×USB Cable Type-C to Type-C (for USB-C PC)

Alternatively if using Ethernet:

1×Arduino Uno R3
1×USB 2.0 cable type A/B (for USB-A PC)
1×USB 2.0 cable type C/B (for USB-C PC)
1×Arduino Ethernet Shield
1×Ethernet Cable
1×(Khuyến nghị) Screw Terminal Block Shield for Arduino UNO R4
1×(Khuyến nghị) Breadboard Shield for Arduino UNO R4
1×(Khuyến nghị) Enclosure for Arduino UNO R4
1×(Khuyến nghị) Power Splitter for Arduino UNO R4
1×(Khuyến nghị) Prototyping Base Plate & Breadboard Kit for Arduino UNO

Or you can buy the following kits:

1×DIYables STEM V3 Starter Kit (Arduino included)
1×DIYables Sensor Kit (30 sensors/displays)
1×DIYables Sensor Kit (18 sensors/displays)

Arduino - MySQL

Nếu bạn không có nhiều kiến thức về kiến trúc hệ thống, hai thuật ngữ: Cơ sở dữ liệu MySQLMáy chủ MySQL có thể được hiểu là giống nhau. Bạn sẽ nhận ra sự khác biệt sau này khi bạn hiểu rõ hơn về kiến trúc hệ thống.

Có hai cách để Arduino tương tác với cơ sở dữ liệu MySQL:

  • Arduino tương tác trực tiếp với máy chủ MySQL thông qua kết nối MySQL (được gọi là cách trực tiếp)
  • Arduino tương tác gián tiếp với máy chủ MySQL thông qua kết nối HTTP (được gọi là cách gián tiếp)

Hãy tìm cái tốt nhất.

Arduino tương tác trực tiếp với Máy chủ MySQL

Arduino trực tiếp đến mysql

Nghe có vẻ đơn giản hơn nhưng có nhiều nhược điểm:

  • Điều này cho phép một tài khoản người dùng MySQL truy cập từ xa vào cơ sở dữ liệu MySQL ⇒ Đây là nguy hiểm về mặt bảo mật, ngay cả khi quyền hạn được cấp cho tài khoản người dùng bị giới hạn.
  • Dữ liệu PHẢI được xử lý trên Arduino và/hoặc máy chủ MySQL ⇒ Điều này làm tăng độ phức tạp của mã Arduino và tập lệnh MySQL. Đặc biệt, nó tiêu thụ nhiều tài nguyên của Arduino (RAM và CPU).
  • Máy chủ MySQL có thể trả về một lượng dữ liệu rất lớn cho Arduino trong một số trường hợp ⇒ Điều này có thể làm Arduino hết bộ nhớ.
  • Hầu hết các thư viện MySQL có sẵn đều không hỗ trợ SSL/TLS. Dữ liệu bao gồm tên người dùng và mật khẩu sẽ được gửi ở dạng văn bản thuần ⇒ một vấn đề bảo mật khác.

Arduino tương tác gián tiếp với máy chủ MySQL thông qua HTTP/HTTPS

Phương pháp gián tiếp này giải quyết mọi vấn đề mà phương pháp trực tiếp gặp phải. Trước khi xem xét cách phương pháp gián tiếp vượt qua những nhược điểm của phương pháp trực tiếp, hãy xem nó hoạt động như thế nào trước.

Cách hoạt động

  • Bước 1: Arduino gửi yêu cầu HTTP tới máy chủ web
  • Bước 2: Máy chủ web chạy tập lệnh PHP
  • Bước 3: Tập lệnh PHP lấy dữ liệu từ yêu cầu HTTP, xử lý dữ liệu và sau đó tương tác với cơ sở dữ liệu MySQL.
  • Bước 4: Tập lệnh PHP xử lý kết quả và trả kết quả về cho Arduino thông qua phản hồi HTTP
Arduino mysql http

Trong hướng dẫn này, máy chủ Web và máy chủ MySQL sẽ được cài đặt trên PC.

Có vẻ phức tạp nhưng không phải vậy. Bây giờ hãy xem cách phương pháp gián tiếp khắc phục những nhược điểm của phương pháp trực tiếp.

  • Bằng cách cài đặt máy chủ MySQL và máy chủ HTTP trên cùng một máy chủ vật lý, chúng ta có thể giới hạn một tài khoản người dùng MySQL chỉ được truy cập localhost. Hơn nữa, tên đăng nhập và mật khẩu của tài khoản MySQL được lưu trên máy chủ (bước 3); điều này làm cho hệ thống an toàn hơn.
  • Dữ liệu được xử lý bởi một script PHP (bước 3 và bước 4). Điều này làm giảm khối lượng công việc và độ phức tạp cho các máy chủ Arduino và MySQL. Việc xử lý dữ liệu bằng mã PHP dễ hơn nhiều so với mã Arduino và script MySQL.
  • Mã PHP có thể xử lý dữ liệu và gửi chỉ dữ liệu cần thiết cho Arduino (bước 4) để ngăn Arduino hết bộ nhớ.
  • Hầu hết các thư viện Ethernet/WiFi hỗ trợ TLS/SSL cho phép chúng ta thực hiện các yêu cầu HTTPS. Bằng cách sử dụng HTTPS, dữ liệu được mã hóa và trao đổi một cách an toàn qua Internet.

Trong bước 1, chúng ta có thể sử dụng một tên đăng nhập và mật khẩu khác để xác thực giữa Arduino và Web Server. Lưu ý rằng tên đăng nhập và mật khẩu HTTP nên khác với tên đăng nhập và mật khẩu MySQL để tăng cường bảo mật.

Với những lợi thế đó, phần còn lại của bài hướng dẫn này sẽ trình bày cách sử dụng Arduino với MySQL theo cách gián tiếp.

Arduino - MySQL thông qua HTTP/HTTPS

Chúng ta cần thực hiện bước sau:

  • Cài đặt máy chủ MySQL, máy chủ web và PHP trên máy tính của bạn
  • Kích hoạt MySQL và máy chủ web
  • Tạo một tài khoản người dùng MySQL
  • Tạo một cơ sở dữ liệu MySQL
  • Tạo một bảng MySQL
  • Viết một hoặc nhiều tập tin script PHP
  • Viết mã Arduino

Bây giờ hãy làm từng bước.

1. Cài đặt máy chủ MySQL, máy chủ Web và PHP trên máy tính của bạn

May mắn thay, gói XAMPP bao gồm tất cả những thứ này. Chúng ta chỉ cần cài đặt một lần.

Sau khi cài đặt, bạn sẽ thấy thư mục C:\xampp\htdocs trên máy tính của bạn. Đây là nơi bạn đặt mã PHP (xem phần sau).

2. Kích hoạt MySQL và máy chủ web

  • Mở bảng điều khiển XAMPP
  • Nhấn nút Start để kích hoạt MySQL và máy chủ web (Xem hình dưới đây)
Arduino xampp

3. Tạo tài khoản người dùng MySQL

Chúng tôi sẽ tạo một tài khoản MySQL chỉ được phép kết nối tới cơ sở dữ liệu MySQL từ localhost.

  • Ngay cả khi tên đăng nhập và mật khẩu bị tiết lộ, kẻ tấn công vẫn không thể truy cập cơ sở dữ liệu MySQL của bạn trừ khi họ chiếm quyền kiểm soát máy tính của bạn.
  • Vì PHP và MySQL được cài đặt trên cùng một máy tính, PHP có thể dùng tên đăng nhập và mật khẩu này để kết nối với cơ sở dữ liệu MySQL.

Hãy tạo một tài khoản người dùng MySQL với tên đăng nhập là Arduino và mật khẩu là ArduinoGetStarted.com:

  • Mở Dòng lệnh trên máy tính của bạn. Đừng đóng nó cho đến khi kết thúc hướng dẫn.
  • Nhập lệnh sau vào Dòng lệnh:
cd C:\xampp\mysql\bin
Command Prompt
C:\Users\youruser>cd C:\xampp\mysql\bin C:\xampp\mysql\bin>
  • Theo mặc định, MySQL có tài khoản root mà không có mật khẩu. Bạn nên thêm mật khẩu.

(ví dụ your-root-password) cho tài khoản root bằng cách gõ lệnh sau trong Command Prompt:

mysqladmin -u root password your-root-password
Command Prompt
C:\xampp\mysql\bin>mysqladmin -u root password your-root-password C:\xampp\mysql\bin>
  • Nhập lệnh sau vào Dòng lệnh:
mysql.exe -u root -p
  • Nhập mật khẩu root của bạn và nhấn phím Enter
Command Prompt
C:\xampp\mysql\bin>mysql.exe -u root -p Enter password: ****************** Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 9 Server version: 10.4.6-MariaDB mariadb.org binary distribution Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]>
  • Tạo một tài khoản người dùng MySQL với tên người dùng là Arduino và mật khẩu là ArduinoGetStarted.com bằng cách sao chép các lệnh dưới đây và dán vào Command Prompt:
CREATE USER 'Arduino'@'localhost' IDENTIFIED BY 'ArduinoGetStarted.com'; GRANT ALL PRIVILEGES ON *.* TO 'Arduino'@'localhost' WITH GRANT OPTION; FLUSH PRIVILEGES;
Command Prompt
MariaDB [(none)]> CREATE USER 'Arduino'@'localhost' IDENTIFIED BY 'ArduinoGetStarted.com'; Query OK, 0 rows affected (0.005 sec) MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 'Arduino'@'localhost' WITH GRANT OPTION; Query OK, 0 rows affected (0.005 sec) MariaDB [(none)]> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.001 sec) MariaDB [(none)]>

Bây giờ bạn đã tạo thành công một tài khoản người dùng MySQL. Hãy ghi nhớ tên đăng nhập và mật khẩu, chúng sẽ được sử dụng trong script PHP.

4. Tạo cơ sở dữ liệu MySQL

Hãy tạo một cơ sở dữ liệu có tên db_arduino bằng cách gõ lệnh sau trên Command Prompt:

CREATE DATABASE db_arduino CHARACTER SET = 'utf8' COLLATE = 'utf8_general_ci';
Command Prompt
MariaDB [(none)]> CREATE DATABASE db_arduino CHARACTER SET = 'utf8' COLLATE = 'utf8_general_ci'; Query OK, 1 row affected (0.003 sec) MariaDB [(none)]>

5. Tạo bảng MySQL

Hãy tạo một bảng có tên tbl_temp bằng cách sao chép các lệnh dưới đây và dán vào Dòng lệnh:

USE db_arduino; CREATE TABLE tbl_temp ( temp_id INT UNSIGNED NOT NULL AUTO_INCREMENT, temp_value FLOAT DEFAULT 0.00, PRIMARY KEY (temp_id) );
Command Prompt
MariaDB [(none)]> USE db_arduino; Database changed MariaDB [db_arduino]> MariaDB [db_arduino]> CREATE TABLE tbl_temp ( -> temp_id INT UNSIGNED NOT NULL AUTO_INCREMENT, -> temp_value FLOAT DEFAULT 0.00, -> PRIMARY KEY (temp_id) -> ); Query OK, 0 rows affected (0.044 sec) MariaDB [db_arduino]>

6. Viết một hoặc nhiều tệp PHP

Tạo một tệp PHP có tên insert_temp.php để lấy nhiệt độ từ yêu cầu HTTP và chèn nó vào cơ sở dữ liệu.

<?php if(isset($_GET["temperature"])) { $temperature = $_GET["temperature"]; // get temperature value from HTTP GET $servername = "localhost"; $username = "Arduino"; $password = "ArduinoGetStarted.com"; $dbname = "db_arduino"; // Create connection $conn = new mysqli($servername, $username, $password, $dbname); // Check connection if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } $sql = "INSERT INTO tbl_temp (temp_value) VALUES ($temperature)"; if ($conn->query($sql) === TRUE) { echo "New record created successfully"; } else { echo "Error: " . $sql . " => " . $conn->error; } $conn->close(); } else { echo "temperature is not set"; } ?>
  • Đặt tập tin này vào thư mục C:\xampp\htdocs
  • Lấy địa chỉ IP của PC bạn. Nếu bạn không biết cách làm thế nào, hãy tra trên Google.
  • Kiểm tra mã PHP bằng cách mở trình duyệt web (ví dụ Chrome) và truy cập liên kết này: http://192.168.0.26/insert_temp.php?temperature=27.5. Lưu ý rằng bạn cần thay địa chỉ IP ở trên bằng địa chỉ PC của bạn.
  • Kết quả hiển thị trên trình duyệt web
kiểm tra mysql
  • Kiểm tra xem dữ liệu có được lưu trữ trong cơ sở dữ liệu hay không bằng cách gõ lệnh sau vào Command Prompt:
SELECT * from tbl_temp;
Command Prompt
MariaDB [db_arduino]> SELECT * from tbl_temp; +---------+------------+ | temp_id | temp_value | +---------+------------+ | 1 | 27.5 | +---------+------------+ 1 row in set (0.001 sec) MariaDB [db_arduino]>

Như bạn có thể thấy, nhiệt độ 27,5 được lưu trong cơ sở dữ liệu. Bước tiếp theo là viết mã Arduino để thực hiện một yêu cầu HTTP tương tự tới PC của bạn.

7. Viết mã Arduino

Chúng tôi sẽ sử dụng Arduino Uno và Ethernet Shield hoặc Arduino Uno R4 WiFi cho bài kiểm tra.

Mã Arduino dưới đây gửi một yêu cầu HTTP tới máy tính của bạn để thêm nhiệt độ 29,1°C vào cơ sở dữ liệu.

Mã Arduino cho Arduino Uno R4 WiFi

/* * Mã Arduino này được phát triển bởi newbiely.vn * Mã Arduino này được cung cấp để sử dụng công khai, không có ràng buộc. * Để xem hướng dẫn chi tiết và sơ đồ kết nối, vui lòng truy cập: * https://newbiely.vn/tutorials/arduino/arduino-mysql */ #include <WiFiS3.h> const char ssid[] = "YOUR_WIFI_SSID"; // change your network SSID (name) const char pass[] = "YOUR_WIFI_PASSWORD"; // change your network password (use for WPA, or use as key for WEP) WiFiClient client; int status = WL_IDLE_STATUS; int HTTP_PORT = 80; String HTTP_METHOD = "GET"; char HOST_NAME[] = "192.168.0.26"; // change to your PC's IP address String PATH_NAME = "/insert_temp.php"; String queryString = "?temperature=29.1"; void setup() { Serial.begin(9600); // check for the WiFi module: if (WiFi.status() == WL_NO_MODULE) { Serial.println("Communication with WiFi module failed!"); // don't continue while (true) ; } String fv = WiFi.firmwareVersion(); if (fv < WIFI_FIRMWARE_LATEST_VERSION) { Serial.println("Please upgrade the firmware"); } // attempt to connect to WiFi network: while (status != WL_CONNECTED) { Serial.print("Attempting to connect to SSID: "); Serial.println(ssid); // Connect to WPA/WPA2 network. Change this line if using open or WEP network: status = WiFi.begin(ssid, pass); // wait 10 seconds for connection: delay(10000); } // print your board's IP address: Serial.print("IP Address: "); Serial.println(WiFi.localIP()); // connect to web server on port 80: if (client.connect(HOST_NAME, HTTP_PORT)) { // if connected: Serial.println("Connected to server"); // make a HTTP request: // send HTTP header client.println(HTTP_METHOD + " " + PATH_NAME + queryString + " HTTP/1.1"); client.println("Host: " + String(HOST_NAME)); client.println("Connection: close"); client.println(); // end HTTP header while (client.connected()) { if (client.available()) { // read an incoming byte from the server and print it to serial monitor: char c = client.read(); Serial.print(c); } } // the server's disconnected, stop the client: client.stop(); Serial.println(); Serial.println("disconnected"); } else { // if not connected: Serial.println("connection failed"); } } void loop() { }

Mã Arduino cho Arduino Uno/Mega và Ethernet Shield

/* * Mã Arduino này được phát triển bởi newbiely.vn * Mã Arduino này được cung cấp để sử dụng công khai, không có ràng buộc. * Để xem hướng dẫn chi tiết và sơ đồ kết nối, vui lòng truy cập: * https://newbiely.vn/tutorials/arduino/arduino-mysql */ #include <SPI.h> #include <Ethernet.h> // replace the MAC address below by the MAC address printed on a sticker on the Arduino Shield 2 byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; EthernetClient client; int HTTP_PORT = 80; String HTTP_METHOD = "GET"; char HOST_NAME[] = "192.168.0.26"; // change to your PC's IP address String PATH_NAME = "/insert_temp.php"; String queryString = "?temperature=29.1"; void setup() { Serial.begin(9600); // initialize the Ethernet shield using DHCP: if (Ethernet.begin(mac) == 0) { Serial.println("Failed to obtaining an IP address using DHCP"); while(true); } // connect to web server on port 80: if(client.connect(HOST_NAME, HTTP_PORT)) { // if connected: Serial.println("Connected to server"); // make a HTTP request: // send HTTP header client.println(HTTP_METHOD + " " + PATH_NAME + queryString + " HTTP/1.1"); client.println("Host: " + String(HOST_NAME)); client.println("Connection: close"); client.println(); // end HTTP header while(client.connected()) { if(client.available()){ // read an incoming byte from the server and print it to serial monitor: char c = client.read(); Serial.print(c); } } // the server's disconnected, stop the client: client.stop(); Serial.println(); Serial.println("disconnected"); } else {// if not connected: Serial.println("connection failed"); } } void loop() { }

Hướng dẫn từng bước

  • Nếu dùng Ethernet Shield, hãy ghép Ethernet Shield lên Arduino Uno
  • Kết nối cáp Ethernet với Ethernet Shield
  • Kết nối Arduino Uno với máy tính bằng cáp USB
  • Thay đổi địa chỉ IP trong mã cho phù hợp với địa chỉ IP của máy tính bạn
  • Biên dịch và tải mã lên Arduino
  • Mở Serial Monitor
  • Kết quả trên Serial Monitor
COM6
Send
Connected to server HTTP/1.1 200 OK Date: Tue, 12 Jan 2021 07:52:22 GMT Server: Apache/2.4.39 (Win64) OpenSSL/1.1.1c PHP/7.3.8 X-Powered-By: PHP/7.3.8 Content-Length: 31 Connection: close Content-Type: text/html; charset=UTF-8 New record created successfully disconnected
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  
  • Kiểm tra xem dữ liệu có được lưu trữ trong cơ sở dữ liệu hay không bằng cách gõ lệnh sau trên Command Prompt:
SELECT * from tbl_temp;
Command Prompt
MariaDB [db_arduino]> SELECT * from tbl_temp; +---------+------------+ | temp_id | temp_value | +---------+------------+ | 1 | 27.5 | | 2 | 29.1 | +---------+------------+ 2 rows in set (0.000 sec) MariaDB [db_arduino]>

Như bạn có thể thấy, nhiệt độ 29.1 được lưu vào cơ sở dữ liệu.

Cách Arduino chèn, cập nhật hoặc lấy dữ liệu từ cơ sở dữ liệu MySQL

Trong ví dụ ở trên, chúng ta đã học cách chèn dữ liệu vào cơ sở dữ liệu MySQL. Đối với cập nhật và lấy dữ liệu từ cơ sở dữ liệu, nó cũng tương tự. Bạn chỉ cần thay đổi các truy vấn MySQL trên mã PHP. Bạn có thể tìm hiểu thêm tại W3Schools

Cách sử dụng nâng cao

Để tăng cường bảo mật

※ Lưu ý:

Để xây dựng một hệ thống hoàn chỉnh ở mức bảo mật cao nhất, chúng ta cần làm nhiều hơn (ví dụ như ngăn ngừa tiêm SQL vào MySQL, biến HTTPS thành một REST API, sử dụng định dạng JSON cho dữ liệu, ...). Tuy nhiên, hướng dẫn này dành cho người mới bắt đầu học Arduino. Chúng tôi đã làm cho nó càng đơn giản càng tốt. Sau khi học xong hướng dẫn này, người dùng có thể mở rộng nó.

Video Tutorial

Việc sản xuất video tốn rất nhiều thời gian. Nếu video hướng dẫn hữu ích cho việc học của bạn, hãy đăng ký kênh YouTube để ủng hộ. Nếu nhu cầu đủ cao, chúng tôi sẽ cố gắng làm thêm nhiều video.