NTP_PRO gửi vào
- 26575 lượt xem
Xin chào các bạn, hôm qua có một bạn hỏi rằng: Làm sao để ghi dữ liệu từ Arduino vào file excel, vấn đề này khá hay nhưng lại chưa có bài viết nào trên cộng đồng nên mình sẽ thực hiện Logging data với Processing 3. (Có nhiều ngôn ngữ có thể thực hiện được logging data nhưng mình thích Processing nên nhích thôi!^^).
CHUẨN BỊ
- Processing 3 (https://processing.org/download/?processing)
- 1 project với Arduino mà bạn cần logging dữ liệu. Trong bài viết này, mình sẽ ghi dữ liệu mình đọc được từ RFID card vào file .csv để có thể đọc với Excel.
ARDUINO SIDE
Dữ liệu bạn đọc được (nhiệt độ, độ ẩm, nồng độ CO2,....) sẽ cần được print ra Serial Monitor theo 1 định dạng nào đó mà bạn đưa ra, VD như: data1,data2,data3 hoặc là data1:data2:data3 hoặc là data1+data2+data3 v.v.. cái này là do bạn quy định. Trong bài viết này, mình sẽ print ra theo định dạng sau: UID;Name;Age
Mình dùng hàm sprintf(...) để in ra 1 chuỗi theo 1 định dạng trước là: uid[0]-uid[1]-uid[2]-uid[3];name;age (mình dùng dấy chẩm phẩy để ngăn cách các dữ liệu).
Trong đó, uid là mảng kiểu byte chứa 4 byte UID của RFID card, name và age là 2 biến dữ liệu kiểu string.
char uidStr[80]; sprintf(uidStr, "%d-%d-%d-%d;%s;%s", uid[0], uid[1], uid[2], uid[3], name, age); Serial.print(uidStr);
Ví dụ, khi print ra thì mình có chuỗi này ở Serial Monitor:
102-27-39-86;NTP_PRO;22
Nếu bạn cũng đã print ra được chuỗi theo đúng định dạng bạn đã chọn thì ngon lành rồi đó, sang bước tiếp theo nào.
PROCESSING SIDE
Mình sẽ lưu dữ liệu nhận được từ cổng Serial theo định dạng csv, để có thể mở được bằng Excel.
LẬP TRÌNH
import processing.serial.*; Serial port; Table table; // Table object PFont font; String rawData; String[] data; void setup() { size(400, 400); port = new Serial(this, "COM19", 115200); /* hiển thị ra màn hình */ font = loadFont("TimesNewRomanPSMT-48.vlw"); textFont(font, 32); textAlign(CENTER); fill(0); /* tạo bảng lưu dữ liệu */ table = new Table(); /* thêm cột cho bảng */ table.addColumn("UID"); table.addColumn("Name"); table.addColumn("Age"); } void draw() { background(255); rawData = ""; if (port.available() > 0) { rawData = port.readString(); } if (rawData != "") { /* tách dữ liệu từ raw data nhận từ Serial */ data = split(rawData, ';'); /* Exception handling */ try { text(data[0], 200, 50); text(data[1], 200, 150); text(data[2], 200, 250); TableRow row = table.addRow(); row.setString("UID", data[0]); row.setString("Name", data[1]); row.setString("Age", data[2]); saveTable(table, "C:\\Users\\T\\Desktop\\IDtable.csv"); } catch (Exception e) { background(255); data = new String[3]; data[0] = data[1] = data[2] = "Error"; text(data[0], 200, 50); text(data[1], 200, 150); text(data[2], 200, 250); } } delay(500); }
GIẢI THÍCH
- table = new Table(): tạo 1 Table object mới.
- table.addColumn("column name"): dùng để thêm 1 cột có tên "column name" cho bảng. Tên của cột được dùng để truy cập vào cột tương ứng.
- TableRow row = table.addRow(): dùng để thêm 1 hàng vào bảng.
- row.setString("column name", "string data"): thêm dữ liệu kiểu string vào cột tương ứng của hàng.
- row.setInt("column name", data): thêm dữ liệu kiểu integer vào cột tương ứng của hàng.
- saveTable(table, "file name"): lưu bảng vừa tạo vào file. VD: saveTable(table, "C:\\Users\\T\\Desktop\\IDtable.csv"): lưu bảng vừa tạo vào file IDtable.csv ở Desktop. Lưu ý là dấu \\ không phải dấu \ nha!
- Nếu chẳng may cổng Serial có vấn đề, dữ liệu nhận được không đầy đủ thì phần Exception Handling sẽ báo lỗi ra màn hình và chương trình sẽ vẫn tiếp tục chạy bình thường.
Mình đã dùng và cảm nhận sự khác biệt, còn các bạn thì sao?!
Các bạn cứ còm men nếu có thắc mắc. Cảm ơn vì đã đọc bài viết của mình.
Chúc các bạn thành công!^^