การเชื่อมต่อ บอร์ด Arduino Nano กับ IR sensor วัดความเร็วรอบ Oled 0.96
หรือ งานเปิด-ปิดสวิสซ์ แบบสัมผัส,การควบคุมอุปกรณ์ไฟฟ้าต่าง ๆ
การเชื่อมต่อ บอร์ด Arduino Nano กับ Oled 096
เชื่อมต่อ Oled 0.96 กับ Arduino Nano
Vin ---------------> 5V
GND ---------------> GND
SCL ---------------> SCL (BASE Or A5)
SDA ---------------> SDA (BASE Or A4)
ติดตั้ง ไลบราลี่ที่จำเป็น
1. Open your Arduino IDE and go to Sketch > Include Library > Manage Libraries
2. Type “SSD1306” in the search box and install the SSD1306 library from Adafruit.
3. Type “GFX” in the search box and install the library.
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.display(); //Display logo
delay(1000);
display.clearDisplay();
}
void loop() {
delay(1000);
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print("RPM:1200");
display.display();
}
// End Nano & OLED code
การเชื่อมต่อ บอร์ด Arduino Nano กับ IR sensor
GND ------> GND
3.3V ------> VCC
2 ------> OUT
เขียนโปรแกรมเพื่อสั่งให้จอ Oled แสดงผล และทดสอบการทำงาน
// code oled 0.96 +IR
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int ir_pin =2;
int ir_val;
void setup() {
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.display(); //Display logo
delay(1000);
display.clearDisplay();
}
void loop() {
ir_val = digitalRead(ir_pin);//อ่านค่าสัญญาณ digital ขา D2 ที่ต่อกับ เซ็นเซอร์ตรวจจับวัตถุ IR Infrared
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print("RPM:");
display.print(ir_val);
display.display();
delay(100);
}
// END code oled 0.96 +IR
การเขียนโปรแกรม การวัดรอบของใบพัด
รูปแบบคำสั่ง 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 <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int ir_pin =2;
int ir_val;
//const int IR_PIN = 2; // IR sensor input pin
int PPR=4; // 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() {
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.display(); //Display logo
delay(1000);
display.clearDisplay();
pinMode(ir_pin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ir_pin), IRinterrupt, FALLING);
}
void loop() {
unsigned long currentMillis = millis();
//จับเวลา 1 วินาที ถ้าครบ ก็หยุดการทำงานของ ตัวนับ counter
if (currentMillis - previousMillis >= 1000) {
detachInterrupt(digitalPinToInterrupt(ir_pin));
rpm = (counter / PPR) * 60; // Calculate RPM perminute
counter = 0;
attachInterrupt(digitalPinToInterrupt(ir_pin), IRinterrupt, FALLING);
previousMillis = currentMillis;
//ir_val = digitalRead(ir_pin);//อ่านค่าสัญญาณ digital ขา D2 ที่ต่อกับ เซ็นเซอร์ตรวจจับวัตถุ IR Infrared
//display.fillRect(x, y, width, height,BLACK);
display.clearDisplay();
display.fillRect(0, 25, 128, 12,BLACK);
display.fillRect(0,25, map(rpm, 0, 1600, 0, 126), 8,WHITE);
display.display();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print("RPM:");
display.print(rpm);
display.display();
delay(100);
}
}
// END RPM
Ref:
https://www.allnewstep.com/article/252/
https://projecthub.arduino.cc/mircemk/arduino-tachometer-rpm-meter-with-ir-sensor-module-a36d7c
https://www.w3schools.com/tags/canvas_fillrect.asp

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