/*
Author: Technical Shubham
* Date: 02 May 2024
*Description: This code controls a servo motor using Arduino and displays the angle on an LCD screen.
It allows control via serial input or potentiometer, with a menu system on the LCD for mode switching.
A pushbutton confirms selections. Serial input sets servo angles, while the potentiometer offers analog control.
Real-time feedback is provided on the LCD display and LED bar graph.
* Copyright © 2024 Technical Shubham. All rights reserved.
*/
#include <Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
Servo myServo;
String inputString = ""; // String to hold incoming serial data
boolean stringComplete = false; // Whether the string is complete
int potPin = A0; // Analog pin connected to potentiometer
int buttonPin = 2; // Digital pin connected to pushbutton
int leds[10] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; // Digital pins connected to LEDs
// Define LCD properties (columns, rows)
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Define mode variables
enum ControlMode { SerialControl, PotControl };
ControlMode mode = SerialControl;
void setup() {
Serial.begin(9600);
myServo.attach(9); // Assuming the servo is connected to pin 9
pinMode(buttonPin, INPUT_PULLUP); // Set button pin as input with internal pull-up resistor
for (int i = 0; i < 10; i++) {
pinMode(leds[i], OUTPUT); // Set LED pins as output
}
lcd.init(); // Initialize the LCD
lcd.backlight(); // Turn on backlight
lcd.setCursor(0, 0);
lcd.print("Servo: ");
lcd.setCursor(0, 1);
lcd.print("Mode: Serial");
}
void loop() {
if (digitalRead(buttonPin) == LOW) {
// Button is pressed, switch mode
switchMode();
}
if (mode == SerialControl) {
processSerialInput(); // Process serial input
} else {
controlServo(); // Control servo based on potentiometer input
}
}
void processSerialInput() {
if (Serial.available() > 0) {
char inChar = Serial.read(); // Read incoming character
if (inChar == '\n') { // If newline character is received
stringComplete = true; // Set string complete flag
} else { // Otherwise, append character to inputString
inputString += inChar;
}
}
if (stringComplete) { // If the string is complete
if (inputString == "H" || inputString == "h") {
myServo.write(0); // Move servo to 0 degrees
delay(100); // Add a delay for servo stabilization
Serial.println("Servo moved to 0 degrees");
displayAngle(0);
updateBarGraph(0);
} else if (inputString == "F" || inputString == "f") {
myServo.write(180); // Move servo to 180 degrees
delay(100); // Add a delay for servo stabilization
Serial.println("Servo moved to 180 degrees");
displayAngle(180);
updateBarGraph(180);
} else {
int angle = inputString.toInt(); // Convert inputString to integer
if (angle >= 0 && angle <= 180) { // Ensure angle is within valid range
myServo.write(angle); // Move servo to specified angle
delay(100); // Add a delay for servo stabilization
Serial.print("Servo moved to ");
Serial.print(angle);
Serial.println(" degrees");
displayAngle(angle);
updateBarGraph(angle);
} else { // If angle is out of range, print error message
Serial.println("Invalid angle. Angle must be between 0 and 180 degrees.");
}
}
inputString = ""; // Clear the input string
stringComplete = false; // Reset the string complete flag
}
}
void controlServo() {
// Read potentiometer value and map it to servo angle
int potValue = analogRead(potPin); // Read potentiometer value (0-1023)
int servoAngle = map(potValue, 0, 1023, 0, 180); // Map potentiometer value to servo angle
myServo.write(servoAngle); // Move servo to the mapped angle
delay(100); // Add a delay for servo stabilization
displayAngle(servoAngle);
updateBarGraph(servoAngle);
}
void switchMode() {
if (mode == SerialControl) {
mode = PotControl;
Serial.println("Switched to Pot Control Mode");
lcd.setCursor(0, 1);
lcd.print("Mode: Pot "); // Display current control mode
} else {
mode = SerialControl;
Serial.println("Switched to Serial Control Mode");
lcd.setCursor(0, 1);
lcd.print("Mode: Serial "); // Display current control mode
}
delay(200); // Delay to debounce button
}
void displayAngle(int angle) {
lcd.setCursor(7, 0);
lcd.print(" "); // Clear previous servo angle value
lcd.setCursor(7, 0);
lcd.print(angle); // Display current servo angle
}
void updateBarGraph(int angle) {
int numLeds = map(angle, 0, 180, 0, 10); // Map servo angle to number of LEDs
for (int i = 0; i < 10; i++) {
digitalWrite(leds[i], i < numLeds ? HIGH : LOW); // Turn on LEDs up to the mapped number
}
}