โปรเจกต์ สร้าง Human-Machine Interface (HMI) ด้วย Arduino
เรียนรู้วิธีการสร้าง HMI ที่สมบูรณ์ด้วย Arduino ซึ่งจะช่วยให้คุณสามารถโต้ตอบกับโปรเจกต์ของคุณได้อย่างง่ายดายและมองเห็นภาพได้ชัดเจน
เรียนรู้วิธีการสร้าง HMI ที่สมบูรณ์ด้วย Arduino ซึ่งจะช่วยให้คุณสามารถโต้ตอบกับโปรเจกต์ของคุณได้อย่างง่ายดายและมองเห็นภาพได้ชัดเจน
▶ กดเพื่อดูวิดีโอสาธิตโปรเจกต์
Project Supporter Team
โพสต์โดย
ลงมือสร้าง Human-Machine Interface (HMI) ของคุณเองด้วยขุมพลังของ Arduino GIGA R1 WiFi , หน้าจอสัมผัสแบบโต้ตอบ และ Arduino Opta โดย HMI จะเป็นตัวเชื่อมต่อระหว่างคุณและโปรเจกต์ ช่วยให้คุณควบคุมได้อย่างแม่นยำ แสดงผล Data แบบ Real-time และทำงานได้อย่างมีประสิทธิภาพ
ลองจินตนาการถึงการออกแบบ Interface ที่กำหนดเองซึ่งตอบสนองต่อการสัมผัสของคุณได้ทันที แสดงผลภาพและ Data ที่ชัดเจนเพื่อช่วยให้คุณตัดสินใจได้อย่างแม่นยำ พลังการประมวลผลของ GIGA ช่วยให้การทำงานราบรื่น ในขณะที่ Opta จะช่วยควบคุมงานอัตโนมัติตาม Input ของคุณหรือค่าที่อ่านได้จาก Sensor
พร้อมที่จะเริ่มหรือยัง? มาสำรวจคุณสมบัติหลักของส่วนประกอบ Arduino กัน:
ด้วยการรวมส่วนประกอบเหล่านี้เข้าด้วยกัน คุณจะสามารถสร้าง HMI ที่ช่วยให้คุณโต้ตอบกับโปรเจกต์ได้ในแบบที่ไม่เคยมีมาก่อน
ด้วย Library LVGL การเขียนโปรแกรม Arduino GIGA Display Shield จะกลายเป็นเรื่องง่าย คุณสามารถกำหนดจำนวน Button ที่ต้องการ หรือต้องการ Bar เพื่อแสดง Data เช่น Temperature หรือ Humidity ความเป็นไปได้นั้นไม่มีที่สิ้นสุด!
ขั้นตอนการทำ:
ต่อไป เราจะแนะนำขั้นตอนในการสร้าง Interface ของคุณ:
ในตัวอย่างนี้ มีการใช้ Button สองตัวเพื่อควบคุม Relay สองตัวโดยการส่ง Signal ไปยัง Arduino Opta นอกจากนี้ยังมีการเพิ่ม LED Indicator สองตัว ซึ่งจะสว่างขึ้นเมื่อมีการกด Button ภายนอกสองตัว
นอกจากนี้ ยังมีการตั้งค่า Bar สำหรับแสดง Temperature โดยใช้ Sensor LM35 เพื่อให้ข้อมูล
Library Arduino H7 Video ที่ใช้จัดการการแสดงผลนั้นเป็นส่วนหนึ่งของ GIGA Board Package
เราจะใช้ Library ที่แตกต่างกันสามตัว:
สำหรับการติดตั้ง ให้เปิด Library Manager แล้วค้นหา " Arduino_GigaDisplayTouch " และ " lvgl " เพื่อติดตั้งเวอร์ชันล่าสุด
ใน Sketch ให้ Include Library ดังนี้:
#include "Arduino_H7_Video.h"
#include "lvgl.h"
#include "Arduino_GigaDisplayTouch.h"
สิ่งแรกที่เราต้องทำคือการกำหนดหน้าจอที่เราใช้ โดยสร้าง Object จาก Class Arduino_H7_Video และระบุความสูง ความกว้าง และประเภทของหน้าจอ
Arduino_H7_Video Display(800, 480, GigaDisplayShield); //Display type and dimensions
นอกจากนี้ เพื่อให้สามารถใช้ความสามารถในการสัมผัสหน้าจอได้ เราจำเป็นต้องสร้าง Object จาก Class Arduino_GigaDisplayTouch
Arduino_GigaDisplayTouch TouchDetector;
ในฟังก์ชัน setup() เราจะเริ่มต้นด้วยการ Initializing หน้าจอและ Touch Detector
void setup(){
Display.begin();
TouchDetector.begin();
}
เมื่อตั้งค่าเหล่านี้เรียบร้อยแล้ว เราสามารถดำเนินการกำหนดค่า Element ของ LVGL ต่อไปได้
การสร้าง Grid เพื่อใช้สำหรับวาง Element ต่างๆ จะประกอบด้วย Column และ Row ที่กำหนดไว้
col_dsc[] = {370, 350, LV_GRID_TEMPLATE_LAST};
row_dsc[] = {440, LV_GRID_TEMPLATE_LAST};
จากนั้นเราต้องสร้าง Pointer สำหรับพื้นที่หน้าจอ
ในที่นี้จะเรียกว่า grid
lv_obj_t * grid = lv_obj_create(lv_scr_act());
สำหรับการตั้งค่า Grid Description ที่เรากำหนดไว้ก่อนหน้านี้ ให้ใช้คำสั่ง:
lv_obj_set_grid_dsc_array(grid, col_dsc, row_dsc);
เมื่อกำหนด Column และ Row แล้ว จะต้องคำนึงถึงขนาดหน้าจอโดยรวมด้วย ซึ่งทำได้โดยการใช้ lv_obj_set_size(grid, Display.width(), Display.height()) เพื่อให้ง่าย เราจะกำหนดให้ Grid ใช้พื้นที่เต็มหน้าจอ
lv_obj_set_size(grid, Display.width(), Display.height());
จากนั้น เพื่อทดสอบ ให้ลองเพิ่ม Object ลงใน Grid: ขั้นแรกให้ประกาศ Obj Pointer และเพิ่มลงใน Grid จากนั้นเราจะตั้งค่า Grid Cell ผ่าน Method lv_obj_set_grid_cell()
lv_obj_t* obj;
obj = lv_obj_create(grid);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 0, 1, //column
LV_GRID_ALIGN_STRETCH, 0, 1); //row
ฟังก์ชัน lv_obj_set_grid_cell() มีชุด Parameter ที่เกี่ยวข้องกับการวางตำแหน่งและการจัดแนวของ Object ในกรณีนี้ เราได้สร้าง Grid ขนาด 2x1 โดยที่ 0 (Column) และ 0 (Row) ระบุตำแหน่งที่จะวางบน Grid
#include "Arduino_H7_Video.h"
#include "lvgl.h"
#include "Arduino_GigaDisplayTouch.h"
Arduino_H7_Video Display(800, 480, GigaDisplayShield);
Arduino_GigaDisplayTouch TouchDetector;
void setup() {
Display.begin();
TouchDetector.begin();
//Display & Grid Setup
lv_obj_t* screen = lv_obj_create(lv_scr_act());
lv_obj_set_size(screen, Display.width(), Display.height());
static lv_coord_t col_dsc[] = { 370, 350, LV_GRID_TEMPLATE_LAST };
static lv_coord_t row_dsc[] = { 440, LV_GRID_TEMPLATE_LAST };
lv_obj_t* grid = lv_obj_create(lv_scr_act());
lv_obj_set_grid_dsc_array(grid, col_dsc, row_dsc);
lv_obj_set_size(grid, Display.width(), Display.height());
//left
lv_obj_t* obj;
obj = lv_obj_create(grid);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 0, 1, //column
LV_GRID_ALIGN_STRETCH, 0, 1); //row
//right
obj = lv_obj_create(grid);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 1, 1, //column
LV_GRID_ALIGN_STRETCH, 0, 1); //row
}
void loop() {
lv_timer_handler();
}
เมื่อเราได้ Grid แล้ว เราสามารถเริ่มเพิ่ม Object ที่เราต้องการได้
ในการแสดง Image บนหน้าจอ ขั้นแรกเราต้องกำหนดรูปภาพนั้นก่อน นำรูปภาพที่ต้องการมาแปลงเป็น Format ที่ถูกต้อง และวางไฟล์รูปภาพไว้ใน Folder เดียวกับ Sketch จากนั้นใช้คำสั่ง LV_IMG_DECLARE(filename); ตัวอย่างเช่น รูปภาพที่เราใช้จะชื่อว่า img_arduinologo
LV_IMG_DECLARE(img_arduinologo);
obj คือ Pointer ที่จะใช้เก็บข้อมูลเกี่ยวกับพื้นที่หน้าจอสำหรับรูปภาพ ส่วน img1 จะถูกใช้สำหรับ Element ของตัวรูปภาพเอง
lv_obj_t * obj;
lv_obj_t * img1;
ด้วยคำสั่ง lv_obj_set_size เราสามารถกำหนด Resolution ของรูปภาพได้
LV_IMG_DECLARE(img_arduinologo);
img1 = lv_img_create(obj_cb);
lv_img_set_src(img1, &img_arduinologo);
lv_obj_set_size(img1, 200, 150);
ตอนนี้เรามีรูปภาพแล้ว ถึงเวลาเพิ่ม Button และ LED Indicator ไปยังตำแหน่งที่เราต้องการบนหน้าจอ
ในการสร้าง Button Object ให้ใช้ lv_btn_create(obj) และกำหนดค่าให้กับตัวแปรที่เหมาะสม ในที่นี้เราใช้ Button Pointer จากนั้นตั้งค่าข้อความที่จะแสดงถัดจาก Button โดยใช้ lv_label_set_text(label_LR1, "Led/Relay1"); ซึ่งคำว่า Led/Relay1 จะถูกพิมพ์ลงใน Button
นอกจากนี้เรายังสามารถตั้งค่า Resolution เป็นหน่วย Pixel ได้อีกด้วย
cb_LR1 = lv_btn_create(obj_cb); // Create the button and store its object: button
lv_obj_set_size(cb_LR1, 100, 40);
label_LR1 = lv_label_create(cb_LR1);
lv_label_set_text(label_LR1, "Led/Relay1");
การสร้าง LED Indicator นั้นคล้ายกับ Button มาก โดยใช้ lv_led_create(obj_cb)
สถานะของ LED สามารถกำหนดได้ด้วยฟังก์ชัน lv_led_off หรือ lv_led_on
obj_led1 = lv_led_create(obj_cb);
lv_led_off(obj_led1);
Element สุดท้ายที่จะเพิ่มในหน้าจอสำหรับตัวอย่างนี้คือ Bar
Bar สามารถสร้างได้ด้วยคำสั่ง:
slider = lv_bar_create(obj_slide);
กำหนดขนาดของ Bar ที่ต้องการด้วย lv_obj_set_size
slider = lv_bar_create(obj_slide);
lv_obj_set_size(slider, 310, 20); // Set the width
lv_obj_align(slider, LV_ALIGN_CENTER, 0, 0);
ด้วย lv_obj_align เราสามารถจัดตำแหน่ง Object ไว้ที่ใดก็ได้ตามต้องการ ในตัวอย่างนี้ถูกจัดไว้ที่พิกัด 0, 0 เพื่อให้อยู่ตรงกลางของ Grid ที่สอง
ต้องขอบคุณ LM35 ที่เชื่อมต่อกับ Arduino Opta ทำให้เราสามารถรับค่า Temperature ของสภาพแวดล้อมและแสดงผลใน Bar ได้

ตอนนี้เรามี Element ทั้งหมดที่จะแสดงบนหน้าจอแล้ว ถึงเวลาเชื่อมต่อ Arduino Opta
เราจะใช้ WiFi Modbus TCP เพื่อส่ง Data จาก Arduino Opta ไปยัง Arduino GIGA
ขั้นแรก เราต้องตั้งค่า WiFi Modbus TCP Server บน Arduino Opta เพื่อให้สามารถส่ง Data (สถานะของ LED และ Input) ไปยัง Arduino GIGA ได้ การสื่อสารนี้เกิดขึ้นแบบไร้สายผ่าน Local Network ของคุณ
(โปรดดู Code ในไฟล์ที่แนบมากับโปรเจกต์นี้ในส่วน Opta_Server)
Code นี้ทำหน้าที่เป็นตัวแปลระหว่างโลกทางกายภาพ (Sensor, LED, Relay) และ Protocol เครือข่าย Modbus TCP
มันจะรับคำสั่งจาก Arduino GIGA ควบคุม Hardware ที่เชื่อมต่อตามลำดับ และส่งข้อมูลเกี่ยวกับ Input และค่า Analog กลับไป
ฟังก์ชัน updateOuts จะอ่านค่า Coil จาก Modbus Client และใช้ค่าเหล่านั้นเพื่อเปิด/ปิด LED และ Relay ที่เชื่อมต่ออยู่
ฟังก์ชัน updateWInputs จะอ่านสถานะของ Digital Input Pin และเขียนค่าไปยัง Modbus Coil ที่ระบุ เพื่อส่งข้อมูลนี้ไปยัง GIGA
ฟังก์ชัน updateWInputs ยังอ่านแรงดันไฟฟ้าจาก Analog Input Pin แปลงเป็นค่า Digital และเขียนไปยัง Modbus Register เพื่อให้ GIGA สามารถเข้าถึง Data นี้ได้
เมื่อเรามี Opta Code แล้ว ถึงเวลาทำให้ Arduino GIGA สามารถส่งและรับข้อมูลไปยัง Opta ผ่าน Modbus TCP
(โปรดดูไฟล์ที่แนบมากับโปรเจกต์นี้เพื่อดู Code ในส่วน HMI_Client)
สร้างการเชื่อมต่อกับ Modbus TCP Server ที่รันบน Arduino Opta (ระบุ IP address ใน Opta_server)
ใน Loop หลัก เราต้องตรวจสอบให้แน่ใจว่า Modbus TCP Client เชื่อมต่ออยู่
// client not connected
if (!modbusTCPClient.connected()) {
//Serial.println("Modbus TCP Client failed to connect! Restart HMI");
}
else {
// client connected
InWidgets();
//OutButtons();
}
หากเชื่อมต่อแล้ว เราจะอ่านค่า Coil จาก Arduino Opta เพื่อเปิด/ปิด LED ที่เกี่ยวข้อง อ่านค่า Analog Input Register จาก Opta แล้วแปลงเป็น Temperature เพื่อ Update ตำแหน่งของ Slider และแสดงค่าบนหน้าจอ GIGA
นอกจากนี้ เมื่อมีการกด/ปล่อย Button มันจะส่งคำสั่ง Coil Write ไปยัง Opta เพื่อเปิด/ปิด LED/Relay ที่เกี่ยวข้อง
void InWidgets (){
int voltFOpta;
float TempScreen;
char voltageStr[20];
/* Reading coils to update the LEDs on HMI */
if (modbusTCPClient.coilRead(0x02)){
lv_led_on(obj_led1);
}
else
{
lv_led_off(obj_led1);
}
if (modbusTCPClient.coilRead(0x03)){
lv_led_on(obj_led2);
}
else
{
lv_led_off(obj_led2);
}
/* Reading the input register to update the Temperature, analog in */
voltFOpta = modbusTCPClient.inputRegisterRead(0x04);
TempScreen = voltFOpta * (100.0/4095); //Analog input 0 - 10 volts; 12 bit resolution, 0 - 4095; 10mV/°C.
lv_bar_set_value(slider, TempScreen, LV_ANIM_OFF);
sprintf(voltageStr, "%.0f", TempScreen, "°C");
lv_label_set_text(label1, voltageStr);
}
ขอแสดงความยินดีกับการสร้าง Human-Machine Interface ของคุณเองโดยใช้ Arduino GIGA ที่ทรงพลัง, หน้าจอสัมผัส Arduino GIGA Display Shield และ Arduino Opta! จากโปรเจกต์นี้ คุณได้รับประสบการณ์อันมีค่าในการผสมผสาน Hardware, Software และการออกแบบ เพื่อสร้างเครื่องมือที่ช่วยให้คุณโต้ตอบกับโปรเจกต์ได้ดีกว่าที่เคย
จำไว้ว่า HMI ของคุณไม่ใช่แค่กลุ่มของ Button และการแสดงผลเท่านั้น แต่มันเป็นช่องทางสู่การควบคุมที่ราบรื่นและความเข้าใจในโปรเจกต์ที่ลึกซึ้งยิ่งขึ้น ด้วยความยืดหยุ่นของ Arduino GIGA และ Library LVGL คุณมีความสามารถที่จะ:
เมื่อคุณเดินทางต่อไปในโลกของ HMI จงจำไว้ว่าความเป็นไปได้นั้นไม่มีที่สิ้นสุด เปิดรับพลังแห่งการปรับแต่ง ปลดปล่อยความคิดสร้างสรรค์ของคุณ และปลดล็อกศักยภาพสูงสุดของโปรเจกต์ด้วย Human-Machine Interface หนึ่งเดียวในโลกของคุณ!
สนับสนุนเพื่อรับ Source Code หรือแอปพลิเคชันสำหรับโปรเจกต์นี้
ประเมิน Project
เอาฟอร์มยาวออกจากท้ายหน้า Project แล้ว เหลือเป็นปุ่มให้กดไปกรอกหน้าเดียว ตัวใหญ่ เว้นบรรทัดเยอะ อ่านง่ายกว่า
รีวิวจากคนใช้งานจริง
ถ้าเคยสั่งงาน เคยอ่านหน้านี้แล้วได้ประโยชน์ หรือมีข้อเสนอแนะ ฝากรีวิวไว้ได้เลย
ยังไม่มีรีวิวบนหน้านี้ ถ้าเคยใช้งานหรือมีข้อเสนอแนะ เขียนเป็นคนแรกได้เลย