การวัดรอบมอเตอร์ ด้วยบอร์ด Arduino UNO R3 กับ IR sensor และ LCD1602
การเชื่อมต่อ บอร์ด Arduino UNO R3 กับ IR sensor
GND ------> GND
3.3V ------> VCC
2 ------> OUT
เขียนโปรแกรมเพื่อสั่งให้จอ LCD แสดงผล
และทดสอบการทำงาน
int ir_sensor =2;
int ir_val;
void setup() {
Serial.begin(115200);
}
void loop() {
ir_val = digitalRead(ir_sensor);//อ่านค่าสัญญาณ digital ขา D1 ที่ต่อกับ เซ็นเซอร์ตรวจจับวัตถุ IR Infrared
if (ir_val>0){
Serial.print("No Detect VaLue:");
Serial.println(ir_val);
} else{
Serial.print("Detect Value:");
Serial.println(ir_val);
}
}
เช่น งานเปิด-ปิดสวิสซ์ ,การควบคุมอุปกรณ์ไฟฟ้าต่าง ๆ
//////////////////////////////////
เชื่อมต่อจอ LCD เข้ากับ Arduino UNO R3 ผ่านสายสัญญาณ I2C
I2C module Arduino UNO R3
VCC ------> 5V Pin
GND ------> Ground Pin
SDA ------> A4 Pin
SCL ------> A5 Pin
ติดตั้งไลบารีสำหรับควบคุมจอ LCD ผ่าน I2C
ติดตั้งไลบรารี LiquidCrystal ให้ไปที่ Arduino IDE:
ไปที่เมนู Sketch > Include Library > Manage Libraries...
ค้นหา LiquidCrystal I2C และติดตั้ง
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd (0x27, 16,2); //
int ir_sensor =2;
int ir_val;
void setup() {
lcd.init (); //initialize LCD
// Turn on the backlight on LCD.
lcd. backlight ();
Serial.begin(115200);
}
void loop() {
ir_val = digitalRead(ir_sensor);//อ่านค่าสัญญาณ digital ขา D1 ที่ต่อกับ เซ็นเซอร์ตรวจจับวัตถุ IR Infrared
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" IR sensor ");
lcd.print(ir_val);
Serial.println(ir_val);
delay(1000);
}
///////////////////////////////////////
การเขียนโปรแกรม การวัดรอบของใบพัด
รูปแบบคำสั่ง attachInterrupt(digitalPinToInterrupt(ir_sensor), IRinterrupt, FALLING);
digitalPinToInterrupt(ir_sensor) คือลำดับขาอินเตอร์รัพท์ตามที่ได้ดูไปในตารางที่ผ่านมา ใน Arduino Due สามารถใส่หมายเลขขาลงไปได้เลย
IRinterrupt คือชื่อฟังก์ชั่นที่จะไปถูกเรียกขึ้นมาเมื่อเกิดอินเตอร์รัพท์
mode รูปแบบที่จะให้เกิดอินเตอร์รัพท์ มีทั้งหมด 4 รูปแบบดังนี้
LOW จะเกิดอินเตอร์รัพท์ต่อเมื่อพอร์ตที่กำหนดไว้มีสถานะเป็น LOW
CHANGE จะเกิดอินเตอร์รัพท์เมื่อพอร์ตที่กำหนดไว้มีการเปลี่ยนสถานะ เช่น จากสถานะ HIGH เป็น LOW หรือจาก LOW เป็น HIGH
RISING จะเกิดอินเตอร์รัพท์เมื่อพอร์ตที่กำหนดไว้มีการเปลี่ยนสถานะจาก LOW เป็น HIGH
FALLING จะเกิดอินเตอร์รัพท์เมื่อพอร์ตที่กำหนดไว้มีการเปลี่ยนสถานะจาก HIGH เป็น LOW
HIGH จะเกิดอินเตอร์รัพท์ต่อเมื่อพอร์ตที่กำหนดไว้มีสถานะเป็น HIGH
volatile unsigned int counter = 0; // Counter variable for revolutions
volatile: คำสำคัญนี้บ่งบอกให้คอมไพเลอร์ (compiler) ทราบว่า ค่าของตัวแปร counter อาจเปลี่ยนแปลงได้โดยกระบวนการอื่นที่โปรแกรม
ไม่สามารถควบคุมได้ เช่น อินเทอร์รัปต์ (interrupt) หรือฮาร์ดแวร์ภายนอก ดังนั้น คอมไพเลอร์จะไม่พยายามเพิ่มประสิทธิภาพโค้ด โดยการเก็บค่าของ
counter ไว้ในแคช (cache) หรือรีจิสเตอร์ (register) แต่จะเข้าไปอ่านค่าจากหน่วยความจำจริงทุกครั้งที่ใช้ตัวแปรนี้
unsigned int: นี่คือชนิดข้อมูลของตัวแปร counter ซึ่งหมายถึงตัวแปรนี้จะเก็บค่าจำนวนเต็มบวกเท่านั้น (ไม่มีเครื่องหมายลบ)
และมีขนาดที่ขึ้นอยู่กับสถาปัตยกรรมของระบบ (โดยทั่วไปจะใช้ 2 หรือ 4 ไบต์)
counter: นี่คือชื่อของตัวแปรที่ใช้เก็บค่าจำนวนเต็มบวก
unsigned long currentMillis = millis();
ฟังก์ชัน millis() คืออะไร?
millis() เป็นฟังก์ชันที่พบได้บ่อยในภาษาโปรแกรมที่เกี่ยวข้องกับไมโครคอนโทรลเลอร์ เช่น Arduino โดยฟังก์ชันนี้จะคืนค่าเวลาที่ผ่านไป
นับตั้งแต่เริ่มต้นโปรแกรมทำงานเป็นหน่วยมิลลิวินาที (milliseconds) หรือ 1/1000 ของหนึ่งวินาที
การวัดเวลา: ใช้ในการวัดระยะเวลาที่ผ่านไป เพื่อควบคุมการทำงานของโปรแกรมให้เกิดขึ้นในช่วงเวลาที่กำหนด เช่น การกระพริบ LED ในช่วงเวลาที่แน่นอน
การอ่านค่าเซ็นเซอร์ในช่วงเวลาที่กำหนด เป็นต้น
การสร้างการหน่วงเวลา: แม้ว่าจะมีฟังก์ชัน delay() ที่ใช้ในการหน่วงเวลา แต่ฟังก์ชัน millis() จะให้ความยืดหยุ่นมากกว่าในการสร้างการหน่วงเวลา
ที่ซับซ้อนหรือการทำงานหลายอย่างพร้อมกัน
การควบคุมการทำงานแบบไม่บล็อก (Non-blocking): เมื่อใช้ millis() ร่วมกับโครงสร้างการควบคุม เช่น if-else หรือ switch-case
จะทำให้โปรแกรมสามารถทำสิ่งอื่นๆ ได้ในขณะที่รอให้เวลาผ่านไป ไม่เหมือนกับการใช้ delay() ที่จะทำให้โปรแกรมหยุดทำงานชั่วคราว
// Complete code IR RPM
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd (0x27, 16,2); //
int ir_sensor =2;
int ir_val;
//const int IR_PIN = 2; // IR sensor input pin
int PPR=3; // Pulse per rotation
volatile unsigned int counter = 0; // Counter variable for revolutions
unsigned long previousMillis = 0; // Variable to store previous time
unsigned int rpm = 0; // Variable to store RPM value
void IRinterrupt() {
counter++;
}
void setup() {
lcd.init (); //initialize LCD
lcd.backlight ();
pinMode(ir_sensor, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ir_sensor), IRinterrupt, FALLING);
Serial.begin(115200);
delay(2000);
}
void loop() {
unsigned long currentMillis = millis();
//จับเวลา 1 วินาที ถ้าครบ ก็หยุดการทำงานของ ตัวนับ counter
if (currentMillis - previousMillis >= 1000) {
detachInterrupt(digitalPinToInterrupt(ir_sensor));
rpm = (counter / PPR) * 60; // Calculate RPM perminute
counter = 0;
attachInterrupt(digitalPinToInterrupt(ir_sensor), IRinterrupt, FALLING);
previousMillis = currentMillis;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("RPM=");
lcd.print(rpm);
Serial.println(rpm);
delay(1000);
}
}
// END
Ref:
https://www.allnewstep.com/article/252/
https://www.youtube.com/watch?v=NvXb7dr-ETw
https://www.instructables.com/Simple-Motor-Speed-Tester-Tachometer/
Tag:
Arduino UNO R3,LCD1602 i2C,speed motor,counter,RPM,
attachInterrupt,digitalPinToInterrupt,interrupt,FALLING,

ความคิดเห็น
แสดงความคิดเห็น