การวัดรอบมอเตอร์ ด้วยบอร์ด Arduino UNO R3 กับ IR sensor และ LCD1602



 การวัดรอบมอเตอร์ ด้วยบอร์ด 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,


ความคิดเห็น