ตู้ขายปากกาแบบหยอดเหรียญ (Coin-operated pencabinet)

ผู้เขียนบทความ : 069 นายวัชรพล แก้วคง COE #15

คณะวิศวกรรมศาสตร์ : สาขาวิศวกรรมคอมพิวเตอร์

วิชา : 04-513-201 การโปรแกรมคอมพิวเตอร์ขั้นสูง 1/2566

1.ความเป็นมา

        จากการศึกษาพบปัญหาโดยการสอบถามนักศึกษาในมหาวิทยาลัยพบว่าปากกาจะน้ำหมึกหรือทำหายก็ไม่สามารถใช้ปากกาได้เพื่อแก้ปัญหาดังกล่าวผู้ประดิษฐ์จึงได้จัดทำ ตู้ขายปากกาขึ้นพอพูดถึงปากกาก็เป็นสิ่งที่ขาดไม่ได้ในสถานที่ต่างๆ ไม่ว่าจะเป็น โรงเรียน บริษัทต้องมีการใช้ปากกาในการเขียนสิ่งต่างๆ สิ่งจำเป็นต่อการทำงานเป็นอย่างมากแต่ไม่ว่าอย่างไร ก็ถึงเวลาหมดน้ำหมึก ก็ต้องไปซื้อตามร้านสะดวกซื้อ หรือร้านขายเครื่องเขียน ซึ่งทำต้องทำให้เราออกไปซื้ออยู่บ่อยๆ ซึ่งบ้างครั้งถึงเวลาจำเป็นที่ต้องการใช้ในยามดึก ร้านสะดวกหรือร้านเครื่องเขียนต่างๆก็ปิดร้าน ทำให้ไม่สามรถซื้อปากกาได้

        จากการศึกษาพบปัญหาโดยการสอบถามนักศึกษาในมหาวิทยาลัยพบว่าปากกาจะน้ำหมึกหรือทำหายก็ไม่สามารถใช้ปากกาได้เพื่อแก้ปัญหาดังกล่าวผู้ประดิษฐ์จึงได้จัดทำ ตู้ขายปากกาขึ้น

2.วัตถุประสงค์

  1. เพื่อลดปัญหาการไปซื้อปากกาตามร้านสะดวกซื้อ
  2. เพื่อความสะดวกสบายในการซื้อปากกา
  3. เพื่อวิเคราะห์จำนวนของปากกาที่ขายออกไป
  4. เพื่อความสามารถบอร์ดEPS32 ในการควบคุมวงจร

3.ขอบเขต

  1. วงจรควบคุมจ่ายปากกาสามารถจ่ายปากกาได้โดยจ่ายได้ทีละอัน
  2. จอแสดงผลของเครื่องขายปากกาแบบหยอดเหรียญเป็นจอแอลซีดี
  3. วงจรเครื่องหยอดเหรียญสามารถโปรแกรมกำหนดราคาปากกาแต่ละอันได้
  4. เมื่อปากกาใกล้หมดจะมีการแจ้งเตือนหาผู้ประดิษฐ์
  5. เครื่องตู้ขายปากกาจะไม่มีระบบทอนเงินและจะคายเงินถ้าใส่เงินเกิดกว่าราคาที่กำหนดไว้

4.ประโยชน์ที่คาดว่าจะได้รับ

  1. สามารถช่วยให้ผู้คนส่วนในการซื้อปากกา
  2. สามารถลดปัญหาที่ร้านสะดวกปิด
  3. หารายได้เสริม

5.ทฤษฎีและงานอื่นที่เกี่ยวข้อง

  1. ทฤษฎีที่เกี่ยวข้อง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 บาท1010100 %
2 บาท1010100 %
5 บาท1010100 %
10 บาท1010100 %

ผลการทดลองการจ่ายปากกา

    การกดจ่ายปากกาผลที่ได้ (Servo)%
    ครั้งที่ 13 แท่ง2 แท่ง45%
    ครั้งที่ 23 แท่ง2 แท่ง45%
    ครั้งที่ 33 แท่ง1 แท่ง100%
    ครั้งที่ 43 แท่ง1 แท่ง100%

    ผลการทดลองเซนเซอร์ตรวจจับปากกา

      การตรวจจับปากกาผลที่ได้ (IR inf)%
      ครั้งที่ 10 แท่งตรวจพบปากกา0%
      ครั้งที่ 20 แท่งตรวจพบปากกาบ้าง50%
      ครั้งที่ 30 แท่งไม่พบปากกา100%
      ครั้งที่ 40 แท่งไม่พบปากกา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/

      วิดิโอการทำงานของตู้ขายปากกาแบบหยอดเหรียญ

      You may also like...

      ใส่ความเห็น

      อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *