ผู้เขียนบทความ: นายภศฆ์เดช เพ็ชรพันธ์ COE-15
คณะวิศวกรรมศาสตร์: สาขาวิศวกรรมคอมพิวเตอร์
วิชา: 04-513-201 การโปรแกรมคอมพิวเตอร์ขั้นสูง 1/2566
1) ความเป็นมา
• ในปัจจุบันมีเทคโนโลยีที่ก้าวกระโดด ทั้งในประเทศไทยหรือต่างประเทศ ก็มีการผลิตอุปกรณ์ทำความสะอาดแว่นอัตโนมัติมาเพื่อความสะดวกสบายมากขึ้น แนวคิดก็มาจากการที่ตัวเองเป็นคนใส่แว่นโดยปกติประจำทุกวัน บางครั้งการล้างแว่นก็สามารถไปที่ร้านแว่นได้ แต่อาจมีค่าใช้จ่ายแล้วแต่ที่ เพื่อสนองความต้องการสำหรับการทำความสะอาดแว่นเพื่อฆ่าเชื้อ กำจัดสิ่งสกปรกไปได้ในระดับหนึ่งมากกว่าการเช็ดด้วยผ้าปกติ แต่ต้องแลกมาด้วยความล่าช้าในการทำความสะอาดประมาณ 1-2นาที
2) วัตถุประสงค์
2.1 เพื่อศึกษาและเข้าใจในการใช้คำสั่งทำงานอุปกรณ์ทำความสะอาดแว่น ในภาษา Python
2.2 เพื่อนำความรู้ในภาษา Python ไปต่อยอดในอนาคตได้
2.3 สามารถนำโค้ดภาษา Python ในการใช้ Servo motor หมุนเพื่อทำความสะอาดได้จริง
3) ขอบเขต
3.1 โปรแกรมสามารถตรวจจับกล่องได้
3.2 โปรแกรมสามารถสั่งให้ Servo motor หมุนได้
3.2.1 เมื่ออุปกรณ์ทำงานเสร็จโปรแกรมจะสั่งให้ Buzzer มีเสียง
3.3 โปรแกรมสามารถส่งข้อมูลไปยังไลน์เป็นข้อความได้
4) ประโยชน์ที่คาดว่าจะได้รับ
4.1 เข้าใจในการเขียนโปรแกรมภาษา Python สามารถนำไปประยุกต์ใช้งานได้จริง
4.2 สามารถเขียนโปรแกรมสั่งงานให้ Servo motor หมุนเพื่อทำความสะอาดได้
5) ความรู้ที่เกี่ยวข้อง
5.1 Ultrasonic Sensor
ใช้ Ultrasonic เป็นตัวควบคุมในการเริ่มต้นการทำงาน คือการกำหนดระยะของตัว sensor เมื่อระยะตรวจจับเจอกล่อง ว่าเจอหรือไม่เจอ ถ้าไม่เจอกล่องก็จะไม่มีการทำงาน ถ้าเจอกล่องภายในน้อยกว่าหรือเท่ากับ 15เซนติเมตร จะส่งค่ากลับไปที่ตัวบอร์ด ESP32 บอร์ดก็จะสั่งงานต่อไปให้ Servo ทำงาน
if distance_cm <= 15:
5.2 Servo Motor
การทำงานเริ่มต้นเมื่อ ESP32 ส่งค่ากลับมา ทำให้ Servo หมุน จะใช้เส้นเอ็นเป็นตัวยึดกับตัวฐานกล่องและใบพัดของ Servo, Servo จะหมุนตามองศาที่กำหนดไว้คือ 0องศา (0.5 วินาที) 180องศา (0.5 วินาที) กำหนดการทำงานของ Servo ไว้ที่ 120ครั้ง(120วินาที หรือ 2นาที) คือ (ซ้าย-ขวา) นับเป็น 1ครั้ง และเส้นเอ็นที่ยึดไว้ทำให้เกิดการเขย่า ซ้าย-ขวา
servo.write(0);
delay(500);
servo.write(180);
delay(500);
* คำสั่งที่ใช้หยุดไม่ให้ Servo วนอยู่ในลูปต่อคือ Servo.detach เมื่อทำตามค่าครบที่กำหนดไว้แล้วจะหยุดการเชื่อมต่อ *
servo.detach()
servoDetached = True
5.3 Active Buzzer
เมื่อการทำงานของ Servo สิ้นสุดลง Buzzer จะส่งเสียงแจ้งเตือนเป็นเวลา 5วินาที เพื่อให้สัญญาณว่าการทำงานได้เสร็จสิ้น ในโค้ดของ Arduino C++ จะใช้เป็น tone และกำหนดความถี่ของเสียงเป็น 1000 หยุดเสียงจะใช้ notone
tone(BUZZER_PIN, 1000);
delay(5000);
noTone(BUZZER_PIN);
5.4 โค้ดภาษา Python ที่ใช้ในการเขียน
การนำเข้าไลบรารีสำคัญเพื่อใช้งาน MicroPython และสื่อสารกับฮาร์ดแวร์และเครือข่าย รวมถึงการนำเข้าไลบรารี urequests
สำหรับการส่งคำขอ HTTP
import machine
import time
import network
import urequests as requests
ตัวแปรที่เก็บข้อมูล เช่น ชื่อและรหัสผ่านของเครือข่ายไร้สาย (WiFi) และโทเคนของ LINE Notify, ขาของพอร์ตสำหรับอุปกรณ์ต่าง ๆ เช่น ขาของ Ultrasonic Sensor, Servo Motor, LCD และขาของ Buzzer
SSID = "Aftershock_2.4G"
PASSWORD = "0992459870s"
LINE_TOKEN = "nRHjIAwjrqd60msCGdtzGhhyEp7WZJI942vIxQxUsj8"
ECHO_PIN = 19
TRIG_PIN = 18
SERVO_PIN = 13
SCL_PIN = 22
SDA_PIN = 21
BUZZER_PIN = 5
การสร้าง Instance ของ Object I2C สำหรับใช้งานหน้าจอ LCD ที่ต่อผ่าน I2C และ Servo สำหรับการควบคุมตำแหน่งของเฟอร์
i2c = machine.I2C(scl=machine.Pin(SCL_PIN), sda=machine.Pin(SDA_PIN))
lcd = machine.LCD(i2c)
servo = machine.Servo(SERVO_PIN)
ฟังก์ชันที่ใช้ในการเชื่อมต่อกับเครือข่ายไร้สาย WiFi โดยใช้ชื่อและรหัสผ่านที่ถูกกำหนด จากนั้นฟังก์ชันรอจนกว่าการเชื่อมต่อ WiFi จะเสร็จสมบูรณ์ และพิมพ์ข้อความ “WiFi connected” และที่อยู่ IP ลงบนหน้าจอ
def connect_wifi():
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect(SSID, PASSWORD)
while not sta_if.isconnected():
time.sleep(1)
print("WiFi connected")
print("IP:", sta_if.ifconfig()[0])
ฟังก์ชันที่ใช้ส่งข้อความการแจ้งเตือนผ่าน LINE Notify โดยใช้โทเคน (TOKEN) ที่ถูกกำหนดและข้อความที่คุณต้องการส่ง โค้ดนี้สร้างข้อความ JSON ที่มีส่วนข้อมูลข้อความและส่งไปยัง URL ของ LINE Notify API และพิมพ์ข้อมูลการตอบกลับจาก LINE Notify API
def send_line_notification(message):
url = "https://notify-api.line.me/api/notify"
headers = {"Authorization": "Bearer " + LINE_TOKEN}
data = {"message": message}
response = requests.post(url, headers=headers, json=data)
print("Line Notify Response:", response.text)
ฟังก์ชันนี้ทำงานอย่างต่อเนื่องโดยตรวจสอบระยะห่างจาก Ultrasonic Sensor, ควบคุม Servo motor, และแสดงข้อมูลบนหน้าจอ LCD ตามเงื่อนไขที่กำหนด
def main():
connect_wifi()
lcd.clear()
lcd.backlight(1)
while True:
machine.Pin(TRIG_PIN, machine.Pin.OUT).on()
time.sleep_us(10)
machine.Pin(TRIG_PIN, machine.Pin.OUT).off()
duration_us = machine.time_pulse_us(machine.Pin(ECHO_PIN, machine.Pin.IN), 1)
distance_cm = 0.017 * duration_us
if not servoDetached:
if distance_cm <= 15:
lcd.clear()
lcd.text("Work in progress...", 0, 0)
lcd.text("Time:", 3, 1)
lcd.text(str(cnt), 10, 1)
lcd.text("s", 13, 1)
if cnt > 0:
servo.angle(0)
time.sleep(0.5)
servo.angle(180)
time.sleep(0.5)
if cnt == 0:
send_line_notification("The Glasses is Success")
servo.detach()
time.sleep(10)
servoDetached = True
lcd.clear()
lcd.text("complete !!", 3, 0)
lcd.text(" ", 18, 1)
lcd.text(str(distance_cm), 18, 1)
machine.Pin(BUZZER_PIN, machine.Pin.OUT).on()
time.sleep(5)
machine.Pin(BUZZER_PIN, machine.Pin.OUT).off()
time.sleep(1)
time.sleep(10)
machine.reset()
cnt -= 1
else:
lcd.clear()
lcd.text("Already...", 3, 0)
time.sleep(0.3)
5.5 รายละเอียดการทำงานของโค้ด
ส่วนหลักของโค้ดทำงานอย่างต่อเนื่อง โดยเริ่มต้นด้วยการเชื่อมต่อ WiFi และจากนั้นทำงานในลูปไม่สิ้นสุด การทำงานของลูปเริ่มต้นด้วยการส่งสัญญาณส่งสัญญาณเปิด (ON) และสัญญาณปิด (OFF) ให้กับขา TRIG_PIN เพื่อเริ่มกระบวนการวัดระยะห่างด้วย Ultrasonic Sensor หลังจากนั้นระบบจะวัดระยะห่างและคำนวณระยะห่างในหน่วยเซนติเมตร
while True:
machine.Pin(TRIG_PIN, machine.Pin.OUT).on()
time.sleep_us(10)
machine.Pin(TRIG_PIN, machine.Pin.OUT).off()
duration_us = machine.time_pulse_us(machine.Pin(ECHO_PIN, machine.Pin.IN), 1)
distance_cm = 0.017 * duration_us
โค้ดตรวจสอบระยะห่าง และหากระยะห่างน้อยกว่าหรือเท่ากับ 15 เซนติเมตร ระบบจะทำการแจ้งเตือน “Work in progress…” บนหน้าจอ LCD และควบคุม Servo Motor ให้หมุนไปและกลับ เพื่อทำความสะอาดแว่น หากServo ทำงานเสร็จสิ้น หรือค่าเป็น 0 ระบบจะส่งข้อความการแจ้งเตือนผ่าน LINE Notify และแสดงข้อมูลบนหน้าจอ LCD “Complete !!!” และเปิดเสียง Buzzer แจ้งเตือนเป็นเวลา 5 วินาที จากนั้นให้รอ 10วินาทีระบบจะรีบูต (restart) และสามารถเริ่มใช้งานได้ใหม่อีกครั้ง
if not servoDetached:
if distance_cm <= 15:
lcd.clear()
lcd.text("Work in progress...", 0, 0)
lcd.text("Time:", 3, 1)
lcd.text(str(cnt), 10, 1)
lcd.text("s", 13, 1)
if cnt > 0:
servo.angle(0)
time.sleep(0.5)
servo.angle(180)
time.sleep(0.5)
if cnt == 0:
send_line_notification("The Glasses is Success")
servo.detach()
time.sleep(10)
servoDetached = True
lcd.clear()
lcd.text("complete !!", 3, 0)
lcd.text(" ", 18, 1)
lcd.text(str(distance_cm), 18, 1)
machine.Pin(BUZZER_PIN, machine.Pin.OUT).on()
time.sleep(5)
machine.Pin(BUZZER_PIN, machine.Pin.OUT).off()
time.sleep(1)
time.sleep(10)
machine.reset()
คำสั่งที่ใช้ในการสั่งให้ Servo Motor ลบครั้งละ1 เมื่อทำงานหมุนไป(180) กลับ(0)
cnt -= 1
เมื่อคำสั่งเป็น 0 Servo motor จะหยุดโดยใช้คำสั่ง servo.detach()
if cnt == 0:
send_line_notification("The Glasses is Success")
servo.detach()
time.sleep(10)
servoDetached = True
ถ้าระยะห่างมากกว่า 15 เซนติเมตร ระบบจะแสดงข้อความ “Already…” เพื่อบอกว่าเครื่องเตรียมพร้อม
else:
lcd.clear()
lcd.text("Already...", 3, 0)
time.sleep(0.3)
ทุกครั้งที่โค้ดถูกเรียกใช้โดยตรง โดยใช้ if __name__ == "__main__":
คำสั่ง main()
จะเริ่มการทำงาน
if __name__ == "__main__":
main()
5.6 โค้ดทั้งหมดของ Arduino ก่อนแปลงเป็น Python
#include <TridentTD_LineNotify.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <ESP32Servo.h>
#define SSID "Aftershock_2.4G"
#define PASSWORD "0992459870s"
#define LINE_TOKEN "nRHjIAwjrqd60msCGdtzGhhyEp7WZJI942vIxQxUsj8"
#define ECHO_PIN 19
#define TRIG_PIN 18
#define SERVO_PIN 13
#define SCL_PIN 22
#define SDA_PIN 21
#define BUZZER_PIN 5
LiquidCrystal_I2C lcd(0x27, 16, 2);
Servo servo;
float duration_us, distance_cm;
int cnt = 120;
bool servoDetached = false;
void setup() {
Serial.println(LINE.getVersion());
WiFi.begin(SSID, PASSWORD);
Serial.printf("WiFi connecting to %s\n", SSID);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(400);
}
Serial.printf("\nWiFi connected\nIP : ");
Serial.println(WiFi.localIP());
LINE.setToken(LINE_TOKEN);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
servo.attach(SERVO_PIN);
pinMode(BUZZER_PIN, OUTPUT);
noTone(BUZZER_PIN);
lcd.init();
lcd.backlight();
}
void loop() {
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
duration_us = pulseIn(ECHO_PIN, HIGH);
distance_cm = 0.017 * duration_us;
if (!servoDetached) {
if (distance_cm <= 15) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Work in progress...");
lcd.setCursor(3, 1);
lcd.print("Time:");
lcd.setCursor(10, 1);
lcd.print(cnt);
lcd.setCursor(13, 1);
lcd.print("s");
if (cnt > 0) {
servo.write(0);
delay(500);
servo.write(180);
delay(500);
}
if (cnt == 0) {
LINE.notify("The Glasses is Success");
servo.detach();
delay(10000);
servoDetached = true;
lcd.clear();
lcd.setCursor(3, 0);
lcd.print("complete !!");
lcd.setCursor(18, 1);
lcd.print(" ");
lcd.setCursor(18, 1);
lcd.print(distance_cm);
tone(BUZZER_PIN, 1000);
delay(5000);
noTone(BUZZER_PIN);
delay(1000);
delay(10000);
ESP.restart();
}
cnt--;
} else {
lcd.clear();
lcd.setCursor(3, 0);
lcd.print("Already...");
lcd.print(distance_cm);
}
delay(300);
}
}
6) ผลการดำเนินงาน
6.1 Diagram ระบบการทำงาน
6.2 วิธีการใช้งานอุปกรณ์
6.2.1 นำกล่องลงไปวางบนฐานรับเพื่อให้ Ultrasonic Sensor ตรวจจับระยะเจอ
แล้วคำสั่งจะ Process ส่งคำสั่งต่อไปยัง Servo ให้หมุน
เมื่ออุปกรณ์ทำงานเสร็จก็จะแสดงผลว่า Complete !! และมีแจ้งเตือนส่งมาที่ไลน์
6.3 ผลการทดลอง
7) สรุปผลและข้อเสนอแนะ
7.1 สรุปผล จากผลการทดลองทั้งหมด Servo Motor หมุนครบรอบตามรอบที่กำหนดไว้ 100% มีเสียง Buzzer แจ้งเตือนดังปกติ มีประสิทธิภาพตรงตามเงื่อนไขที่ทดลองไว้ ได้แก่
7.1.1 Servo Motor หมุนครบตามรอบที่กำหนดไว้
7.1.2 Ultrasonic Sensor ตรวจจับตามระยะได้ถูกต้อง
7.1.3 Buzzer มีเสียงสัญญาณดังปกติ
7.1.4 Line สามารถส่งแจ้งเตือนได้ตามปกติ
7.2 ข้อเสนอแนะ
7.2.1 ประยุกต์ชิ้นงานอุปกรณ์ให้มีอัตราส่วนที่เล็กกว่านี้ หรือน่าสนใจกว่านี้
7.2.2 เพิ่มฟังก์ชั่นการเติมน้ำหรือปล่อยน้ำอัตโนมัติ
8) อ้างอิง
8.2 https://ieeexplore.ieee.org/document/9970608
8.3 https://www.shop.princebot.co.th/article/1/บทที่-1-ติดตั้งโปรแกรม-arduino-และ-libraries-esp32
วิดีโอนำเสนอ อุปกรณ์ทำความสะอาดแว่นอัตโนมัติ