#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define ENCODER_A 32 // Pin for Encoder A
#define ENCODER_B 33 // Pin for Encoder B
volatile int encoder_value = 0; // Global variable for storing the encoder position
int last_encoder_value = 0; // Store the last encoder value
unsigned long last_time = 0; // Store the last time in milliseconds
float motor_rpm = 0; // Variable for storing the motor speed in RPM
// Encoder specification
const int PPR = 200; // Pulses per revolution (set according to your encoder's specification)
// Initialize the LCD (address 0x27 for a 16x2 LCD)
LiquidCrystal_I2C lcd(0x27, 16, 2);
void encoder_isr() {
// Reading the current state of encoder A and B
int A = digitalRead(ENCODER_A);
int B = digitalRead(ENCODER_B);
// If the state of A changed, it means the encoder has been rotated
if ((A == HIGH) != (B == LOW)) {
encoder_value--;
} else {
encoder_value++;
}
}
void setup() {
Serial.begin(115200); // Initialize serial communication
// Initialize the encoder pins
pinMode(ENCODER_A, INPUT_PULLUP);
pinMode(ENCODER_B, INPUT_PULLUP);
// Initialize the LCD and turn on the backlight
lcd.init();
lcd.backlight();
// Attach the ISR for encoder pin A
attachInterrupt(digitalPinToInterrupt(ENCODER_A), encoder_isr, CHANGE); // Pin for the encoder A
// Initialize the last time
last_time = millis();
}
void loop() {
// Get the current time
unsigned long current_time = millis();
// Calculate the time difference (delta_time) in seconds
float delta_time = (current_time - last_time) / 100.0;
// Prevent division by zero by setting a minimum time threshold
if (delta_time < 0.001) {
delta_time = 0.001; // Set a minimum time to avoid division by zero
}
// Calculate the encoder difference (delta_encoder)
int delta_encoder = encoder_value - last_encoder_value;
// Calculate the motor speed in RPM (ensure that PPR is non-zero)
if (PPR != 0) {
motor_rpm = (delta_encoder / (float)PPR) / delta_time * 60.0;
}
// Update the last encoder value and time
last_encoder_value = encoder_value;
last_time = current_time;
// Print encoder value and RPM to Serial Monitor
Serial.print("Encoder value: ");
Serial.println(encoder_value);
Serial.print("Motor RPM: ");
Serial.println(motor_rpm);
// Display encoder value and RPM on LCD
lcd.clear(); // Clear previous data from the screen
lcd.setCursor(0, 0); // Set cursor to the first column, first row
lcd.print("Enc Value: ");
lcd.print(encoder_value);
lcd.setCursor(0, 1); // Set cursor to the first column, second row
lcd.print("Motor RPM: ");
lcd.print(motor_rpm);
delay(200); // Adjust the delay to control update frequency
}