ผู้เขียนบทความ : นาย นวชาติ บ่าเหม COE#15
คณะวิศวกรรมศาสตร์ : สาขาวิชาวิศวกรรมคอมพิวเตอร์
วิชา : 04-513-201 การโปรแกรมคอมพิวเตอร์ขั้นสูง1/2566
1.ความเป็นมา
เนื่องจากในปัจจุบันนั้นการให้อาหารสัตว์เลี้ยงในแต่ละวันไม่สามารถทราบได้ว่าสัตว์เลี้ยงกินอาหารในปริมาณเท่าใด ทำให้ผู้เลี้ยงสัตว์ไม่สามารถให้อาหารที่เหมาะสมต่อความต้องการของสัตว์เลี้ยงได้ เพราะผู้เลี้ยงไม่ทราบถึงพฤติกรรมการกินของสัตว์เลี้ยงในแต่ละวัน
โครงงานนี้จึงได้ทำการสร้างเครื่องให้อาหารแมวอันโนมัติที่สามารถติดตามพฤติกรรมการกินอาหารของสัตว์เลี้ยงในแต่ละวันได้ โดยสามารถกำหนดปริมาณอาหารที่ให้ได้แต่ละครั้งด้วยการกำหนดน้ำหนักของโหลดเซลล์
2.วัตถุประสงค์
1.2.1 ความสะดวกสบายให้กับเจ้าของสัตว์: โครงการมุ่งหน้าเพิ่มความสะดวกสบายให้กับเจ้าของสัตว์เลี้ยงโดยลดความยุ่งยากในการให้อาหารสัตว์ของตัวเอง โดยมีความสามารถในการตั้งเวลา และปริมาณอาหารตามต้องการ.
1.2.2 การให้อาหารทันเวลา: โครงการช่วยให้สัตว์เลี้ยงได้รับอาหารทันเวลาแม้และเจ้าของอาจไม่อยู่บ้าน ซึ่งสามารถลดความกังวลเกี่ยวกับการอำนวยความสะดวกให้อาหารสัตว์เลี้ยงในช่วงเวลาที่เจ้าของต้องออกเที่ยวหรือทำงาน.
ความแม่นยำในการให้อาหาร: โครงการช่วยให้การให้อาหารสัตว์เลี้ยงมีความแม่นยำในปริมาณและเวลา เพื่อป้องกันการส่งผลกระทบต่อสุขภาพของสัตว์เลี้ยงที่อาจเกิดจากการให้อาหารไม่ถูกต้อง.
3.ขอบเขต
- ความแม่นยำในการวัดน้ำหนัก: ความแม่นยำในการวัดน้ำหนักขึ้นอยู่กับเซ็นเซอร์และเทคโนโลยีที่ใช้ บางเครื่องอาจมีความแม่นยำสูงในการวัดน้ำหนักขณะอื่นอาจไม่มีความแม่นยำเท่านั้น.
- การควบคุมการให้อาหาร: บางระบบอาจมีความยืดหยุ่นในการปรับปริมาณอาหารที่ให้ในแต่ละมื้อ ในขณะที่บางระบบจะมีการควบคุมแม่นยำของปริมาณอาหาร.
- การเชื่อมต่อและความสามารถในการควบคุมระยะไกล: บางเครื่องอาจมีความสามารถในการควบคุมผ่านโทรศัพท์มือถือหรืออินเทอร์เน็ต ในขณะที่บางเครื่องมีความสามารถจำกัดในการควบคุม.
- การแจ้งเตือน: บางเครื่องอาจมีระบบแจ้งเตือนผ่านแอปพลิเคชันหรืออีเมลเมื่อมีปัญหาหรือเมื่ออาหารใกล้หมด ในขณะที่บางเครื่องอาจไม่มีระบบแจ้งเตือน.
4.ประโยชน์ที่คาดว่าจะได้รับ
ได้เครื่องให้อาหารสัตว์อัตโนมัติที่สามารถติดตามพฤติกรรมการกินอาหารของสัตว์ในแต่ละวันได้และเป็นต้นแบบในการพัฒนาเครื่องให้อาหารสัตว์อัตโนมัติที่สามารถให้อาหารได้อย่าง อัตโนมัติ และติดตามพฤติกรรมการกินของสัตว์เลี้ยงให้มีประสิทธิภาพมากยิ่งขึ้น
5.ความรู้ที่เกี่ยวข้อง
5.1 Loadcell senser และ Hx711
โมดูล HX711 เป็นโมดูลขยายสัญญาณจาก Load cell สำหรับส่งให้บอร์ดไมโครคอนโทรลเลอร์ เป็นสัญญาณแบบดิจิตอล 24 bit เป็นบอร์ดภาคขยายสัญญาณจาก load cell. มีช่องอินพุตสำหรับต่อกับโหลดเซลล์ได้โดยตรง ใช้ไฟเลี้ยง 2.6-5.5 โวลต์
5.2 Servo motor
ซอร์โวมอเตอร์ (Servo Motor) คือ มอเตอร์ไฟฟ้ากระแสตรงที่มักถูกนำมาใช้ในการควบคุมมุมหรือตำแหน่งเชิงเส้นที่มีความละเอียดสูง โดยเซอร์โวมอเตอร์จะประกอบด้วยมอเตอร์ ชุดเกียร์ และบอร์ดควบคุม รวมไว้เป็นโมดูลเดียวกัน และจะรับสัญญาณควบคุม (signal, S) เพียง 1 เส้น ไฟเลี้ยง VCC และกราวด์ GND อีกอย่างละ 1 เส้น รวมเป็น 3 เส้น โดยทั่วไปเราสามารถควบคุมให้เซอร์โวมอเตอร์หมุนในทิศตามเข็มนาฬิกา (หมุนขวา) หรือ ทวนเข็มนาฬิกา (หมุนซ้าย) ได้ โดยมีมุมในการหมุนตั้งแต่ 0 องศา ถึง 180 องศา นั่นคือ เซอร์โวจะหมุนได้เพียง 180 องศาหรือครึ่งรอบเท่านั้น โดยมีตำแหน่งกึ่งกลางอยู่ที่ 90 องศา สัญญาณ S ที่ใช้ควบคุมมอเตอร์ชนิดนี้จะเป็นสัญญาณที่มีการมอดูเลตความกว้างพัลส์ (Pulse Width Modulation, PWM) และมีระดับแรงดันแบบ TTL ระดับแรงดัน VCC ที่จ่ายให้มอเตอร์นี้จะอยู่ในช่วงประมาณ 4 ถึง 6 โวลต์
5.3TridentTD_LineNotify
ซึ่งเป็นไลบรารีที่ใช้ในการส่งข้อความทาง LINE Notify และ WiFi.h ซึ่งใช้ในการเชื่อมต่อกับเครือข่าย WiFi ของคุณทำให้ผู้ใช้งานสามารถเขียนโปรแกรมเพื่อสร้างบริการที่ผู้พัฒนาต้องการ ผ่านการส่งข้อความและโต้ตอบกับผู้ใช้ในลักษณะ Chatbot นั่นเอง Line Messaging API มีฟังก์ชันการทำงานมากมาย แต่ที่เราใช้ฟังก์ชันการทำงานคือ การส่งข้อความ สามารถใช้ส่งข้อความแบบข้อความธรรมดา ข้อความรูปภาพ ข้อความวิดีโอ ข้อความเสียง ฯลฯ
ในการสร้างระบบนี้ จำเป็นต้องมี Token ของ Line Messaging API ซึ่งสามารถขอได้จาก Line Developer ข้อความแจ้งเตือนสามารถกำหนดค่าได้ตามต้องการ เช่น ข้อความแจ้งเตือน รูปภาพ หรือวิดีโอ ดังภาพ
ขั้นตอนการใช้ระบบการแจ้งเตือน Line Notify
1.เพิ่ม LINE Notify เป็นเพื่อน
โดยการสแกน QR Code นี้ หรือจาก https://notify-bot.line.me/my/
3. ล็อกอิน LINE เพื่อขอ Token
ที่หน้านี้ https://notify-bot.line.me/my/ แล้วกดปุ่ม ออก Token
4. ตั้งค่าการใช้งาน LINE Notify
กำหนดชื่อผู้ส่ง และเลือกกลุ่มที่ต้องการส่งข้อความไปหา
5. ขั้นตอนสุดท้าย รับ Token
ให้กรอกชื่อที่ใช่ส่งข้อมูลเข้า Line แล้วเลือกกลุ่มที่จะส่งข้อมูล กดปุ่ม “ออก Token” จะได้ค่า Token ให้ก็อปค่านี้ไว้ เพื่อนำไปใช้ในโปรแกรมของเรา เพียงเท่านี้ก็พร้อมส่งข้อความจาก NodeMCU ไปหา LINE แล้ว แต่ถ้าลืม สามารถ กลับไปทำตามข้อ 3 ขอรหัส Token ได้ใหม่
6. ดาวน์โหลด Library จากลิ้งค์ข้างล่าง
ดาวน์โหลด Library
วิธีลง Library ให้ดูตัวอย่างในบทความนี้
LINE.setToken(LINE_TOKEN);
float currentWeight = scale.get_units();
if (currentWeight >= targetWeight) {
if (!servoMoving) {
myServo.write(0);
servoMoving = true;
Serial.println("Servo moving to 90 degrees.");
LINE.notify("เจ้าแมวได้กินแล้ว");
}
} else {
if (servoMoving) {
myServo.write(90);
servoMoving = false;
Serial.println("Servo moving to 0 degrees.");
LINE.notify("อาหารไล่ลงมา");
}
}
บรรทัดโค๊ดในภาพ เป็นการเรียกใช้ฟังก์ชัน Line setToken เพื่อส่งข้อความแจ้งเตือนไปยังแอพลิเคชั่น Line ฟังก์ชันนี้จะส่งข้อความไปยังไลน์ของผู้ใช้ โดนใช้ Line Token ในบรรทัดถัดไปในโค๊ด จะเรียกใช้ Serial.println กับ LINE.notify ร่วมกัน เพื่อส่งข้อความไปยัง Line ของผู้ใช้งานนั้นเอง
ไลบรารีที่ใช้ในเป็นไลบรารี่ที่มีความารถสำหรับให้ Hx711 ทำงานร่วมกับ Servo motor เพื่อควบคุมการเปิด-ปิดของ Servo Motor เมื่อเปิดใช้งาน Servo motor จะหมุนไปที่ 0 องศา เพื่อให้อาหารไหลลงมา และเมื่อ Loadcell senser รับน้ำหนักได้ถึงที่กำหนดใว้ ในโค๊ดจะกำหนดใว้ 100 กรัม จะสั่งการให้ Servo Motor หมุนไปที่ 90 องศา เพื่อหยุดการไหลของอาหารลงมานั้นเอง ดังภาพ
#include <HX711.h>
#include <TridentTD_LineNotify.h>
#include <ESP32Servo.h>
#define SSID "POCO F3" //ใส่ ชื่อ Wifi ที่จะเชื่อมต่อ
#define PASSWORD "0997015275" //ใส่ รหัส Wifi
#define LINE_TOKEN "Z6GI6sUsdHgfrz3bNWRu1g5Esy5bbVHMPGiXKnSYXy9" //ใส่ รหัส TOKEN ที่ได้มาจากข้างบน
#define servoPin 13
#define LOADCELL_DOUT_PIN 22
#define LOADCELL_SCK_PIN 23
#define targetWeight 100
#define CALIBRATION_FACTOR 103.448
ในโค๊ด เราจะเรียกใช้ฟังชันก์ HX711.h เพื่อรับสัญญานหรือรับน้ำหนักจาก Loadcell senser และเราจะกำหนดค่าของLoadcell ด้วยขา pin คือ
LOADCELL_DOUT_PIN 22
LOADCELL_SCK_PIN 23
บรรทัดต่อไปจะเป็นการกำหนดน้ำหนักที่ให้ load cell รับได้ คือ 100 กรัม และบรรทัดสุดท้ายจะเป็นการกำหนดค่า CALIBRATION_FACTOR ของ Load cell คือค่าคงที่ แต่ละ Load cell จะมีค่าไม่เหมือนกัน ค่าในโค้ดคือ 103.448
Servo myServo;
HX711 scale;
bool servoMoving = false; // Declare 'servoMoving' as a global variable
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println(LINE.getVersion());
WiFi.begin(SSID, PASSWORD); //เชื่อมต่อ WiFi
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());
Serial.begin(9600);
myServo.attach(servoPin);
myServo.write(0);
scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
scale.set_scale(CALIBRATION_FACTOR);
scale.tare();
โค้ดในบรรทัดนี้
Servo myServo;
และHX711 scale;
: โค้ดนี้ประกาศตัวแปรสำหรับ Servo และ HX711 sensor โดยmyServo
เป็นตัวแปรที่จะใช้ควบคุมเซอร์โวมอเตอร์ และscale
เป็นตัวแปรสำหรับเซ็นเซอร์ HX711 ที่ใช้วัดน้ำหนักหรือแรงกระทำบนโครงของเซอร์โวมอเตอร์.bool servoMoving = false;
: ประกาศตัวแปรservoMoving
และกำหนดค่าเริ่มต้นเป็นfalse
ซึ่งใช้เพื่อติดตามสถานะของการเคลื่อนไหวของเซอร์โวมอเตอร์.WiFi.begin(SSID, PASSWORD);
: ความยอมรับชื่อและรหัสผ่านของเครือข่าย Wi-Fi และพยายามเชื่อมต่อ Wi-Fi.while (WiFi.status() != WL_CONNECTED) { ... }
: โค้ดนี้รอจนกว่า Arduino จะเชื่อมต่อกับ Wi-Fi สำเร็จ จะแสดงข้อความWiFi connected
และแสดง IP address ที่ได้.myServo.attach(servoPin);
: กำหนดพินของเซอร์โวมอเตอร์ที่เชื่อมต่อกับ Arduino โดยใช้servoPin
.myServo.write(0);
: ทำให้เซอร์โวมอเตอร์เคลื่อนไหวไปที่ตำแหน่ง 0 องศา (ส่วนหัวของเซอร์) เริ่มต้น.scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
: เริ่มต้นการใช้งานเซ็นเซอร์ HX711 โดยระบุพินที่ใช้สำหรับข้อมูลเข้า (DOUT) และสัญญาณนาฬิกา (SCK).scale.set_scale(CALIBRATION_FACTOR);
: กำหนดค่าเรตสเกลของเซนเซอร์ HX711 โดยใช้ค่า CALIBRATION_FACTOR.scale.tare();
: ลบค่าศูนย์ที่บันทึกไว้ในเซนเซอร์ HX711 เพื่อให้น้ำหนักเริ่มต้นเป็นศูนย์.
void loop() {
LINE.setToken(LINE_TOKEN);
float currentWeight = scale.get_units();
if (currentWeight >= targetWeight) {
if (!servoMoving) {
myServo.write(0);
servoMoving = true;
Serial.println("Servo moving to 90 degrees.");
LINE.notify("เจ้าแมวได้กินแล้ว");
}
} else {
if (servoMoving) {
myServo.write(90);
servoMoving = false;
Serial.println("Servo moving to 0 degrees.");
LINE.notify("อาหารไล่ลงมา");
}
}
Serial.print("Current Weight: ");
Serial.println(currentWeight, 2);
delay(500);
}
โค้ดในฟังก์ชัน loop
ทำงานเป็นลูปไม่มีที่สิ้นสุดและทำตามขั้นตอนต่อไปนี้:
LINE.setToken(LINE_TOKEN);
: ตั้งค่าโทเคน (Token) สำหรับการเชื่อมต่อกับบริการ LINE โดยใช้ค่าLINE_TOKEN
.float currentWeight = scale.get_units();
: อ่านค่าน้ำหนักปัจจุบันจากเซนเซอร์ HX711 และเก็บค่าไว้ในตัวแปรcurrentWeight
. นี่คือค่าน้ำหนักปัจจุบันของวัตถุที่วัดโดยเซนเซอร์ HX711.if (currentWeight >= targetWeight) { ... }
: ตรวจสอบว่าค่าน้ำหนักปัจจุบัน (currentWeight
) มากกว่าหรือเท่ากับค่าเป้าหมาย (targetWeight
) หรือไม่.- ถ้าค่าน้ำหนักปัจจุบันมากกว่าหรือเท่ากับค่าเป้าหมาย และ
servoMoving
เป็นfalse
, โค้ดจะเริ่มทำตามบล็อกนี้:myServo.write(0);
: เซอร์โวมอเตอร์จะถูกควบคุมให้หมุนไปที่ 0 องศา เมื่อคุณมีค่าน้ำหนักที่เพียงพอ.servoMoving
ถูกตั้งค่าเป็นtrue
เพื่อบ่งบอกว่าเซอร์โวมอเตอร์กำลังเคลื่อนไหว.- ข้อความ “Servo moving to 90 degrees.” จะถูกแสดงใน Serial Monitor.
- LINE จะแสดงข้อความ “เจ้าแมวได้กินแล้ว” ผ่าน LINE Notify.
- ถ้าค่าน้ำหนักปัจจุบันน้อยกว่าค่าเป้าหมาย และ
servoMoving
เป็นtrue
, โค้ดจะทำตามบล็อกนี้:myServo.write(90);
: เซอร์โวมอเตอร์จะถูกควบคุมให้หมุนไปที่ 90 องศา เมื่อคุณมีค่าน้ำหนักไม่เพียงพอ.servoMoving
ถูกตั้งค่าเป็นfalse
เพื่อบ่งบอกว่าเซอร์โวมอเตอร์ไม่กำลังเคลื่อนไหว.- ข้อความ “Servo moving to 0 degrees.” จะถูกแสดงใน Serial Monitor.
- LINE จะแสดงข้อความ “อาหารไล่ลงมา” ผ่าน LINE Notify.
- ถ้าค่าน้ำหนักปัจจุบันมากกว่าหรือเท่ากับค่าเป้าหมาย และ
Serial.print("Current Weight: ");
และSerial.println(currentWeight, 2);
: แสดงข้อมูลน้ำหนักปัจจุบันใน Serial Monitor โดยระบุให้แสดงเลขจุดทศนิยม 2 ตำแหน่ง.delay(500);
: ทำการหน่วงเวลา 500 มิลลิวินาที (ครึ่งวินาที) ก่อนที่ลูปจะเริ่มใหม่.
นั่นคือวิธีที่โค้ดทำงาน โดยตรวจสอบค่าน้ำหนักปัจจุบันและค่าเป้าหมาย และควบคุมการหมุนของเซอร์โวมอเตอร์ในการสั่งให้แมวได้รับอาหารตามค่าเป้าหมายที่กำหนด. ทั้งนี้ LINE Notify ใช้เพื่อแจ้งเตือนผ่าน LINE เมื่อเมื่องานเกิดขึ้น.
6. ผลการดำเนินงาน
ภาพรวมโมดูลทั้งหมดและระบบการทำงานของเครื่องให้อาหารแมว
การทำงานของเครื่องอาหารแมว เมื่อกดเปิดสวิตช์ จะสั่งให้ Servo หมุนไปที่ 0 องศา หลังจากนั้น เมื่ออาหารไหลลงมาบน loadcell senser ถึงที่กำหนดใว้ จะสั่งให้ Servo หมุนไปที่ 90 องศา และไม่สามารถทำงานได้จนกว่าอาหารจะลด หรือน้ำหนักบน loadcell จะลดลง และแจ้งเตือนผ่าน Line ในขั้นตอนสุดท้าย
โค้ดทั้งหมดของการทำงาน
#include <HX711.h>
#include <TridentTD_LineNotify.h>
#include <ESP32Servo.h>
#define SSID "POCO F3" //ใส่ ชื่อ Wifi ที่จะเชื่อมต่อ
#define PASSWORD "0997015275" //ใส่ รหัส Wifi
#define LINE_TOKEN "Z6GI6sUsdHgfrz3bNWRu1g5Esy5bbVHMPGiXKnSYXy9" //ใส่ รหัส TOKEN ที่ได้มาจากข้างบน
#define servoPin 13
#define LOADCELL_DOUT_PIN 22
#define LOADCELL_SCK_PIN 23
#define targetWeight 100
#define CALIBRATION_FACTOR 103.448
Servo myServo;
HX711 scale;
bool servoMoving = false; // Declare 'servoMoving' as a global variable
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println(LINE.getVersion());
WiFi.begin(SSID, PASSWORD); //เชื่อมต่อ WiFi
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());
Serial.begin(9600);
myServo.attach(servoPin);
myServo.write(0);
scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
scale.set_scale(CALIBRATION_FACTOR);
scale.tare();
}
void loop() {
LINE.setToken(LINE_TOKEN);
float currentWeight = scale.get_units();
if (currentWeight >= targetWeight) {
if (!servoMoving) {
myServo.write(0);
servoMoving = true;
Serial.println("Servo moving to 90 degrees.");
LINE.notify("เจ้าแมวได้กินแล้ว");
}
} else {
if (servoMoving) {
myServo.write(90);
servoMoving = false;
Serial.println("Servo moving to 0 degrees.");
LINE.notify("อาหารไล่ลงมา");
}
}
Serial.print("Current Weight: ");
Serial.println(currentWeight, 2);
delay(500);
}
การทดลอง
ทดลองเอาขวดน้ำมาวางบน Loadcell และแจ้งเตือนผ่าน Line
ผลทดลองที่ได้
เมื่อวางขวดน้ำบน loadcell senser จะทำให้ servo motor หมุนไปที่ 90 องศา จะทำให้อาหารหยุดไหลทันที
7.สรุปผลและข้อเสนอแนะ
1.สรุปผล
จากการทดลองเครื่องให้อาหารแมวอัติโนมัติแจ้งเตือนผ่าน Line ทำงานได้อย่างมีประสิทธิภาพตามเงื่อนไขที่ทดลองใว้ สามารถให้อาหารอย่างต่อเนื่องและเป็นไปตามปริมาณอาหารที่ได้กำหนดใว้
2.ข้อเสนอแนะ
2.1 สามารถนำไปต่อยอดในการเกษตร เพื่อให้อาหารแกสัตว์ที่มีขนาดใหญ่และจำนวนมาก
2.2 ตัว loadcell senser มีปัญหาตรงที่ค่าไม่ได้เริ่มต้นที่ 0 แนะนำให้หา loadcell ที่ดีกว่านี้และมีประสิทธิภาพดีกว่านี้
8.ข้อมูลอ้างอิง
(72) IoT Project การพัฒนาเครื่องให้อาหารแมว Cat Feeder – YouTube
ProceedingsEECON41Vol2.pdf (psu.ac.th)
B25-โครงงานเครื่องให้อาหารสุนัข4.0-Full.pdf (princess-it-foundation.org)(72) ทำเครื่องให้อาหารอัตโนมัติ ผ่านWIFI ในราคาแค่ 300 บาท!! – YouTube
ขออนุญาติถามนะคะ อยากทราบว่า ได้ใช้บอร์ด Arduino มั้ยคะ
ใช้ board ESP32