ผู้เขียนบทความ : 069 นายวัชรพล แก้วคง COE #15
คณะวิศวกรรมศาสตร์ : สาขาวิศวกรรมคอมพิวเตอร์
วิชา : 04-513-201 การโปรแกรมคอมพิวเตอร์ขั้นสูง 1/2566
1.ความเป็นมา
จากการศึกษาพบปัญหาโดยการสอบถามนักศึกษาในมหาวิทยาลัยพบว่าปากกาจะน้ำหมึกหรือทำหายก็ไม่สามารถใช้ปากกาได้เพื่อแก้ปัญหาดังกล่าวผู้ประดิษฐ์จึงได้จัดทำ ตู้ขายปากกาขึ้นพอพูดถึงปากกาก็เป็นสิ่งที่ขาดไม่ได้ในสถานที่ต่างๆ ไม่ว่าจะเป็น โรงเรียน บริษัทต้องมีการใช้ปากกาในการเขียนสิ่งต่างๆ สิ่งจำเป็นต่อการทำงานเป็นอย่างมากแต่ไม่ว่าอย่างไร ก็ถึงเวลาหมดน้ำหมึก ก็ต้องไปซื้อตามร้านสะดวกซื้อ หรือร้านขายเครื่องเขียน ซึ่งทำต้องทำให้เราออกไปซื้ออยู่บ่อยๆ ซึ่งบ้างครั้งถึงเวลาจำเป็นที่ต้องการใช้ในยามดึก ร้านสะดวกหรือร้านเครื่องเขียนต่างๆก็ปิดร้าน ทำให้ไม่สามรถซื้อปากกาได้
จากการศึกษาพบปัญหาโดยการสอบถามนักศึกษาในมหาวิทยาลัยพบว่าปากกาจะน้ำหมึกหรือทำหายก็ไม่สามารถใช้ปากกาได้เพื่อแก้ปัญหาดังกล่าวผู้ประดิษฐ์จึงได้จัดทำ ตู้ขายปากกาขึ้น
2.วัตถุประสงค์
- เพื่อลดปัญหาการไปซื้อปากกาตามร้านสะดวกซื้อ
- เพื่อความสะดวกสบายในการซื้อปากกา
- เพื่อวิเคราะห์จำนวนของปากกาที่ขายออกไป
- เพื่อความสามารถบอร์ดEPS32 ในการควบคุมวงจร
3.ขอบเขต
- วงจรควบคุมจ่ายปากกาสามารถจ่ายปากกาได้โดยจ่ายได้ทีละอัน
- จอแสดงผลของเครื่องขายปากกาแบบหยอดเหรียญเป็นจอแอลซีดี
- วงจรเครื่องหยอดเหรียญสามารถโปรแกรมกำหนดราคาปากกาแต่ละอันได้
- เมื่อปากกาใกล้หมดจะมีการแจ้งเตือนหาผู้ประดิษฐ์
- เครื่องตู้ขายปากกาจะไม่มีระบบทอนเงินและจะคายเงินถ้าใส่เงินเกิดกว่าราคาที่กำหนดไว้
4.ประโยชน์ที่คาดว่าจะได้รับ
- สามารถช่วยให้ผู้คนส่วนในการซื้อปากกา
- สามารถลดปัญหาที่ร้านสะดวกปิด
- หารายได้เสริม
5.ทฤษฎีและงานอื่นที่เกี่ยวข้อง
- ทฤษฎีที่เกี่ยวข้องESP32
ESP32 คือ wifi microcontroller ที่ถูกพัฒนาต่อจาก ESP8266 โดยเพิ่ม CPU เป็น 2 core, Wi-Fi ที่เร็วขึ้น, มีขา GPIO ให้ใช้งานมากขึ้น และรองรับ Bluetooth อีกด้วย นอกจากนี้ ESP32 ยังมาพร้อมกับ touch-sensitive pins ที่สามารถใช้ปลุก ESP32 จากโหมด deep sleep และยังมี hall effect sensor และ temperature sensor ในตัว
2.ทฤษฎีที่เกี่ยวข้องเขียนโปรแกรมบนArduino
Arduino เป็นแพลตฟอร์มที่ใช้ภาษา C / C++ ในการเขียนโปรแกรมสั่งงาน แต่การเขียนโปรแกรมในแพลตฟอร์ม Arduino นั้นจะง่าย และสามารถเข้าใจได้ นอกจากนี้ แพลตฟอร์มยังมีฟังก์ชั่นทำงานหลาย ๆ ที่อำนวยความสะดวกไว้ให้แล้ว เช่น ฟังก์ชั่นหน่วงเวลา ฟังก์ชั่นอินเตอร์รัพท์ ฟังก์ชั่นอ่านค่า GPIO ซึ่งในแพลตฟอร์มอื่น ๆ จะไม่มีการเตรียมฟังก์ชั่นไว้ให้ใช้งานได้สะดวกเท่ากับ Arduino
3.ตัวหยอดเหรียญ (Coin Selector)
ตัวหยอดเหรียญสามารถรับเหรียญได้ทุกเหรียญ 1 เหรียญ 2 เหรียญ 5 และ เหรียญ 10 ใช้แรงดันไฟฟ้าเลี้ยง 12V ใช้กระแสต่ำ สามารถใช้งานกับไมโครคอนโทรลเลอร์ได้ทุกตะกูล แต่ต้องแปลงระดับแรงดันลอจิกก่อน มีกลไลคืนเหรียญกรณีเหรียญค้าง มีระบบป้องกันเหรียญปลอม และระบบป้องกันการดึงเหรียญกลับ
4.เซอร์โวมอเตอร์ (Servo Motor)
เซอร์โวมอเตอร์เป็นการรวมมอเตอร์ไฟฟ้ากระแสตรง (DC Motor) เข้ากับวงจรควบคุม โดยความแตกต่างที่สำคัญของเซอร์โวมอเตอร์กับมอเตอร์แบบอื่น ๆ คือเซอร์โวมอเตอร์จะรู้ตำแหน่งที่ตัวเองอยู่ และสั่งเปลี่ยนตำแหน่งโดยการเปลี่ยนองศาได้ นิยมใช้งานในเครื่องบินบังคับ เรือบังคับ โดยใช้กำหนดทิศทางของหางเสือเป็นองศา
5.เซ็นเซอร์ตรวจจับวัตถุ (IR Infrared )
เป็นโมดูลเซ็นเซอร์ตรวจจับวัตถุระยะใกล้ มีหลักการทำงานโดยให้หลอด Infrared LED ทำการสสัญญาณ เป็นแสงอินฟราเรดออกไปตกกระทบกับวัตถุที่ตรวจพบในระยะ และทำการสะท้อนกลับมายังตัวหลอดโฟโต้ไดโอดที่ทำหน้าที่รับแสงอินฟราเรด โดยจะให้ค่า output ออกมาเป็น Digital signal แต่สำหรับบางโมดูลอาจจะรองรับ output แบบ Analog signal ด้วย ส่วนตัว R ปรับค่านั้น ใช้ในการปรับความไวต่อการตรวจจับแสงอินฟราเรด ซึ่งจะส่งผลต่อระยะในการตรวจพบวัตถุของตัวเซนเซอร์
6.ผลการดำเนินงาน
Diagram : การทำงานของระบบวงจรตู้ขายปากกาแบบหยอดเหรียญ
การทำงานของระบบ
ขั้นตอนที่ 1 ศึกษาอุปกรณ์ต่างๆ : ทำการค้นหาข้อมูลแต่ละอุปกรณ์ที่จะเอามาใช้งาน เพื่อใช้งานได้อย่างถูกต้องและไม่มีปัญหาของแต่ละตัว
ขั้นตอนที่ 2 เริ่มประกอบ และ เขียนโค้ด : เริ่มต้นด้วยการออกแบบวงจรขึ้นมาเพื่อให้สามารถ ทุกส่วนทำงานพร้อมกัน
รูปการทำวงจร
พอเสร็จก็ถึงขั้นตอนการเขียนโค้ดโดยเขียนแบบ OOP (Object Oriented Programming) ซึ่งโค้ดจะเป็นดังนี้
โค้ดในส่วนของ public Code
#include <ESP32Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <TridentTD_LineNotify.h>
class CoinMachine {
public:
CoinMachine(int IRinf3, int sensorPin, int interruptPin3, int buzzerPin, int redLedPin, int blueLedPin, int whiteLedPin, String ssid, String password, String lineToken)
:ssid_(ssid), password_(password), lineToken_(lineToken) {
IRinf3_ =IRinf3;
sensorPin_ = sensorPin;
interruptPin3_ = interruptPin3;
buzzerPin_ = buzzerPin;
redLedPin_ = redLedPin;
blueLedPin_ = blueLedPin;
whiteLedPin_ = whiteLedPin;
LiquidCrystal_I2C lcd(0x27, 20, 4);
}
void doCounterFunction() {
isCounter = true;
count++;
}
void interruptFunction3Function() {
swW = digitalRead(interruptPin3_);
}
void interruptIR3Function() {
val3 = digitalRead(IRinf3_);
}
โค้ดในส่วนของ void begin Code
void begin() {
lcd->begin();
lcd->backlight();
WiFi.begin(ssid_, password_);
while (WiFi.status() != WL_CONNECTED) {
lcd->setCursor(3, 1);
lcd->print("LINE Notify");
lcd->setCursor(2, 2);
lcd->print("WiFi connecting.");
delay(400);
lcd->clear();
}
Serial.printf("\nWiFi connected\nIP: ");
Serial.println(WiFi.localIP());
LINE.setToken(lineToken_);
pinMode(sensorPin_, INPUT);
attachInterrupt(digitalPinToInterrupt(sensorPin_), CoinMachine::doCounterFunction,FALLING);
pinMode(interruptPin3_, INPUT);
attachInterrupt(digitalPinToInterrupt(interruptPin3_), CoinMachine::interruptFunction3Function,CHANGE);
pinMode(IRinf3_, INPUT);
attachInterrupt(digitalPinToInterrupt(IRinf3_), CoinMachine::interruptIR3Function,CHANGE);
servo1.attach(servoPin_);
pinMode(buzzerPin_, OUTPUT);
digitalWrite(buzzerPin_, HIGH);
pinMode(redLedPin_, OUTPUT);
digitalWrite(redLedPin_, HIGH);
Serial.begin(115200);
lcd->setCursor(5, 1);
lcd->print("Welcome To");
lcd->setCursor(4, 2);
lcd->print("Selling pens");
lcd->setCursor(1, 3);
lcd->print("By: Watcharapon.K");
delay(5000);
lcd->clear();
lcd->setCursor(0, 0);
lcd->print("Money : ");
lcd->setCursor(8, 0);
lcd->print("0");
lcd->setCursor(11, 0);
lcd->print("Bath");
lcd->setCursor(0, 1);
lcd->print("BLUE PEN = ");
lcd->setCursor(13, 1);
lcd->print(" 8 Bath");
lcd->setCursor(0, 2);
lcd->print("RED : coming soon");
lcd->setCursor(0, 3);
lcd->print("WHITE : coming soon");
}
โค้ดในส่วนของ void run Code
void run() {
if (isCounter == true) {
isCounter = false;
delay(250);
}
if (i != 10 && count != 0) {
i = i + 1;
}
if (i == 10) {
i = 0;
if (count == 10) {
i10 = i10 + 1;
k10 = i10 * 10;
kc10 = 10;
Serial.print("ชนิดเหรียญล่าสุด: ");
Serial.print(kc10);
Serial.println(" บาท");
Serial.println();
for (int i = 0; i < 3; i++) {
digitalWrite(buzzerPin_, LOW);
delay(100);
digitalWrite(buzzerPin_, HIGH);
delay(50);
}
}
if (count == 5) {
i5 = i5 + 1;
j5 = i5 * 5;
jc5 = 5;
Serial.print("ชนิดเหรียญล่าสุด: ");
Serial.print(jc5);
Serial.println(" บาท");
Serial.println();
for (int i = 0; i < 3; i++) {
digitalWrite(buzzerPin_, LOW);
delay(100);
digitalWrite(buzzerPin_, HIGH);
delay(50);
}
}
if (count == 2) {
i2 = i2 + 1;
g2 = i2 * 2;
gc2 = 2;
Serial.print("ชนิดเหรียญล่าสุด: ");
Serial.print(gc2);
Serial.println(" บาท");
Serial.println();
for (int i = 0; i < 3; i++) {
digitalWrite(buzzerPin_, LOW);
delay(100);
digitalWrite(buzzerPin_, HIGH);
delay(50);
}
}
if (count == 1) {
i1 = i1 + 1;
s1 = i1 * 1;
sc1 = 1;
Serial.print("ชนิดเหรียญล่าสุด: ");
Serial.print(sc1);
Serial.println(" บาท");
Serial.println();
for (int i = 0; i < 3; i++) {
digitalWrite(buzzerPin_, LOW);
delay(100);
digitalWrite(buzzerPin_, HIGH);
delay(50);
}
}
Serial.print(" รวมชนิดเหรียญ 10 บาท: ");
Serial.print(i10);
Serial.println(" เหรียญ");
Serial.print(" รวมชนิดเหรียญ 5 บาท: ");
Serial.print(i5);
Serial.println(" เหรียญ");
Serial.print(" รวมชนิดเหรียญ 1 บาท: ");
Serial.print(i1);
Serial.println(" เหรียญ");
Serial.println();
a = s1 + k10 + j5 + g2 - currentCredit;
Serial.print(" ยอดเงินรวมทั้งหมด: ");
Serial.print(a);
Serial.println(" บาท");
Serial.println();
count = 0;
lcd->setCursor(0, 0);
lcd->print("Money : ");
lcd->setCursor(8, 0);
lcd->print(a);
lcd->setCursor(11, 0);
lcd->print("Bath");
lcd->setCursor(0, 1);
lcd->print("BLUE PEN = ");
lcd->setCursor(13, 1);
lcd->print(" 8 Bath");
}
servo1.write(0);
if (a >= 8) {
digitalWrite(redLedPin_, LOW);
} else {
digitalWrite(redLedPin_, HIGH);
}
if (val3 == 1) {
if (val3 == 1 && a >= 8) {
swW = LOW;
digitalWrite(redLedPin_, HIGH);
}
lcd->setCursor(13, 1);
lcd->print("SOLDOUT");
LINE.notify(" ปากกาน้ำเงินหมดแล้ว โปรดไปเติมด้วย !!!");
delay(1000);
} else if (val3 == 0) {
lcd->setCursor(13, 1);
lcd->print(" 8 Bath");
}
if (a >= 8 && swW == HIGH) {
currentCredit += credit8;
a -= credit8;
digitalWrite(buzzerPin_, LOW);
delay(100);
digitalWrite(buzzerPin_, HIGH);
servo1.write(180);
delay(350);
servo1.write(175);
delay(350);
servo1.write(180);
delay(350);
servo1.write(175);
delay(350);
servo1.write(180);
delay(50);
digitalWrite(blueLedPin_, HIGH);
digitalWrite(whiteLedPin_, HIGH);
for (int i = 0; i < 3; i++) {
digitalWrite(redLedPin_, LOW);
delay(500);
digitalWrite(redLedPin_, HIGH);
delay(250);
}
Serial.print(" เครดิตที่ลบ: ");
Serial.print(credit8);
Serial.println(" บาท");
Serial.print(" ยอดเงินล่าสุด: ");
Serial.print(a);
Serial.println(" บาท");
delay(250);
lcd->setCursor(8, 0);
lcd->print(a);
if (a < 10) {
lcd->setCursor(9, 0);
lcd->print(" ");
}
soldBPens++;
LINE.notify(" ปากกาน้ำเงินที่ขายไป : " + String(soldBPens) + " แท่ง");
}
}
โค้ดในส่วนของ Variable Code
private:
Servo servo1;
LiquidCrystal_I2C* lcd;
int IRinf3_;
int lcdCols_;
int lcdRows_;
int sensorPin_;
int interruptPin3_;
int buzzerPin_;
int redLedPin_;
int blueLedPin_;
int whiteLedPin_;
String ssid_;
String password_;
String lineToken_;
int sensorPin = 15;
int i = 0;
int k10 = 0;
int kc10 = 0;
int s1 = 0;
int sc1 = 0;
int j5 = 0;
int jc5 = 0;
int a = 0;
int g2 = 0;
int gc2 = 0;
int i10 = 0;
int i5 = 0;
int i2 = 0;
int i1 = 0;
int currentCredit = 0;
int credit8 = 8;
int soldBPens = 0;
int interruptPin3 = 2;
volatile int swW = LOW;
boolean isCounter = false;
int count = 0;
int val3 = 0;
const int IRinf3 = 33;
const int servoPin_ = 27;
};
CoinMachine coinMachine(33, 15, 2, 0, 18, 5, 16, "Redmi Note 11", "123456789", "w2mg2535WVEi4jjFB1MloJEDJKW6SxyRwOOUuDY8MJj");
void setup() {
coinMachine.begin();
}
void loop() {
coinMachine.run();
}
ขั้นตอนที่ 3 สรุปผลการทดลอง
ได้โค้ดก็เริ่มการใช้งานตัวเครื่องเพื่อหาความลงตัวมากที่สุด แล้วได้ผลตามตารางต่อไปนี้
ผลการทดสอบการหยอดเหรียญ ชนิด 1 บาท 2 บาท 5 บาท และ 10 บาท
ชนิดเหรียญ | ทดสอบการใช้งาน | ผลที่ได้จากการทดสอบ | % |
1 บาท | 10 | 10 | 100 % |
2 บาท | 10 | 10 | 100 % |
5 บาท | 10 | 10 | 100 % |
10 บาท | 10 | 10 | 100 % |
ผลการทดลองการจ่ายปากกา
การกดจ่าย | ปากกา | ผลที่ได้ (Servo) | % |
ครั้งที่ 1 | 3 แท่ง | 2 แท่ง | 45% |
ครั้งที่ 2 | 3 แท่ง | 2 แท่ง | 45% |
ครั้งที่ 3 | 3 แท่ง | 1 แท่ง | 100% |
ครั้งที่ 4 | 3 แท่ง | 1 แท่ง | 100% |
ผลการทดลองเซนเซอร์ตรวจจับปากกา
การตรวจจับ | ปากกา | ผลที่ได้ (IR inf) | % |
ครั้งที่ 1 | 0 แท่ง | ตรวจพบปากกา | 0% |
ครั้งที่ 2 | 0 แท่ง | ตรวจพบปากกาบ้าง | 50% |
ครั้งที่ 3 | 0 แท่ง | ไม่พบปากกา | 100% |
ครั้งที่ 4 | 0 แท่ง | ไม่พบปากกา | 100% |
7.สรุปผลการทดลอง
การทดลองของอุปกรณ์ต่างๆนั้น มีความที่จะสมบูรณ์ สำหรับตู้ขายปากกาตัวนี้ โดยการทำงานจเริ่มจากลูกค้าเริ่มทำการดูที่หน้าจอLCD ว่าราคาปากกาเท่าไหร่ แล้วทำการหยอดเหรียญถ้าถึงค่าราคาปากกาแล้ว ปุ่มที่ตู้จะมีไฟLED ขึ้นมา เพื่อพร้อมใช้งาน ทำการกดปุ่มก็จะไปสั่งการ Servo ให้ทำการปล่อยปากกาลงมา แล้วเซนเซอร์ IRinf นั้นจะทำการตรวจว่าปากกาหมดยัง ถ้ายังก็ทำงานต่อ ถ้าหมดแล้ว ก็แจ้งหาผู้พัฒนา
การนำไปต่อยอด / ข้อแนะนำ
1.แนะนำขยายตู้ให้ใหญ่ขึ้นเพื่อ ให้ใส่ปากกาหลายชนิดได้
2.ต่อยอดไปในทางช่องทางจ่ายแบบแบงค์หรือ Qr payment
8.ข้อมูลอ้างอิง
1. ai-corporation การใช้งาน Arduino Uno ควบคุม Servo Moto รุ่น SG90. [ออนไลน์] 2565.
[สืบค้นวันที่ 20 ตุลาคม 2566].
จาก https://www.ai-corporation.net/2022/01/07/arduino-uno-control-servo-sg90/
2.Robotsiam การใช้งาน IR Infrared โมดูลเซ็นเซอร์แสงสำหรับตรวจจับวัตถุกีดขวาง. [ออนไลน์] 2559.
[สืบค้นวันที่ 20 ตุลาคม 2566].
จาก https://robotsiam.blogspot.com/2016/10/ir-infrared-obstacle-avoidance-sensor.html
3.cybertice สอนใช้งาน Arduino Coin Validator เครื่องรับเหรียญ. [ออนไลน์] 2564.
[สืบค้นวันที่ 20 ตุลาคม 2566].
จาก https://shorturl.asia/PbN2a
4.Chang Arduino Tutorial 3 : Digital input ,Debounce. [ออนไลน์] 2553.
[สืบค้นวันที่ 20 ตุลาคม 2566].
จาก http://www.ayarafun.com/2011/04/arduino-tutorial-3-digital-input-and-debounce/