#include <Wire.h>
#include <LiquidCrystal_I2C.h>
const int joyPinX = A0; // Analog pin for X-axis
const int joyPinY = A1; // Analog pin for Y-axis
const int joyButtonPin = 2; // Digital pin for joystick button
const int buzzerPin = 3; // Digital pin for active buzzer
const int ledPins[] = {4, 5, 6, 7}; // Digital pins for LEDs
const int vibrationMotorPin = 8; // Example pin for the vibration motor
const int joyCenterX = 512; // Center value for X-axis
const int joyCenterY = 512; // Center value for Y-axis
const int threshold = 50; // Threshold for detecting movement
const int resetThreshold = 100; // Threshold for detecting joystick button press
const long morseDelay = 500; // Delay for Morse code playback
const long buzzerDelay = 30000; // Delay between buzzer plays
long currentX = 0; // Current X coordinate
long currentY = 0; // Current Y coordinate
int ThresholdError = 750; // Additive value for thresholds
int xThresholdMin = 3000; // Minimum threshold for X coordinate
int xThresholdMax = xThresholdMin + ThresholdError; // Maximum threshold for X coordinate
int yThresholdMin = 5000; // Minimum threshold for Y coordinate
int yThresholdMax = yThresholdMin + ThresholdError; // Maximum threshold for Y coordinate
// Keypad pins
const int rowPins[4] = {9, 10, 11, 12}; // Rows 0 to 3
const int colPins[4] = {13, 14, 15, 16}; // Columns 0 to 3
// Ensure proper pin connections for your LCD
LiquidCrystal_I2C lcd(0x27, 16, 2); // Set the LCD I2C address to 0x27, and the LCD size to 16x2
unsigned long lastReadTime = 0; // Last time joystick was read
unsigned long lastButtonPressTime = 0; // Last time button was pressed
unsigned long lastBuzzerTime = 0; // Last time buzzer was played
bool buzzerPlaying = false; // Flag to track buzzer playing status
bool ledEnabled = true; // Flag to track LED functionality status
bool lcdEnabled = true; // Flag to track LCD functionality status
bool buzzerEnabled = true; // Flag to track buzzer functionality status
char keypadInput[17]; // Array to store keypad input
int keypadIndex = 0; // Index to keep track of the current position in keypadInput array
void setup() {
Serial.begin(9600); // Initialize serial communication
pinMode(joyButtonPin, INPUT_PULLUP); // Set joystick button pin as input with pull-up resistor
for (int i = 0; i < 4; i++) {
pinMode(ledPins[i], OUTPUT); // Set LED pins as output
}
pinMode(buzzerPin, OUTPUT); // Set buzzer pin as output
pinMode(vibrationMotorPin, OUTPUT); // Set vibration motor pin as output
// Initialize the Wire library (necessary for I2C communication)
Wire.begin();
// Initialize the LCD
lcd.init();
lcd.backlight(); // Turn on the backlight
lcd.print("Setup Complete");
currentX = 0; // Set current X coordinate to 0
currentY = 0; // Set current Y coordinate to 0
// Initialize keypad
for (int i = 0; i < 4; i++) {
pinMode(rowPins[i], INPUT_PULLUP);
pinMode(colPins[i], OUTPUT);
}
memset(keypadInput, 0, sizeof(keypadInput)); // Clear keypadInput array
}
void loop() {
unsigned long currentTime = millis();
// Start time count
if (currentTime - lastReadTime >= 1000) {
// Read joystick input
readJoystick();
if (((currentX > xThresholdMin) && (currentX < xThresholdMax)) && ((currentY > yThresholdMin) && (currentY < yThresholdMax)) && digitalRead(joyButtonPin) == LOW) {
currentX = 0;
currentY = 0;
Serial.println("Coordinates Reset");
delay(1000); // Delay for button debounce
}
lastReadTime = currentTime;
}
// Check for direction functions
if (ledEnabled && currentX < xThresholdMin - threshold) {
Left(currentTime - lastButtonPressTime >= 30000);
} else {
digitalWrite(ledPins[0], LOW); // Turn off LED
}
if (ledEnabled && currentX > xThresholdMax + threshold) {
Right(currentTime - lastButtonPressTime >= 30000);
} else {
digitalWrite(ledPins[1], LOW); // Turn off LED
}
if (ledEnabled && currentY < yThresholdMin - threshold) {
Forward(currentTime - lastButtonPressTime >= 30000);
} else {
digitalWrite(ledPins[2], LOW); // Turn off LED
}
if (ledEnabled && currentY > yThresholdMax + threshold) {
Backward(currentTime - lastButtonPressTime >= 30000);
} else {
digitalWrite(ledPins[3], LOW); // Turn off LED
}
if (currentTime - lastButtonPressTime >= 30000) {
lastButtonPressTime = currentTime; // Reset timer
}
// Check for keypad input
readKeypad();
}
void readJoystick() {
int joyX = analogRead(joyPinX); // Read X-axis value
int joyY = analogRead(joyPinY); // Read Y-axis value
// Calculate increments moved in X and Y directions
int deltaX = joyX - joyCenterX;
int deltaY = joyY - joyCenterY;
// Update current coordinates based on movement
currentX += deltaX;
currentY += deltaY;
// Output current coordinates
Serial.print("Current X: ");
Serial.print(currentX);
Serial.print(", Current Y: ");
Serial.println(currentY);
}
void readKeypad() {
for (int col = 0; col < 4; col++) {
pinMode(colPins[col], INPUT);
for (int row = 0; row < 4; row++) {
if (digitalRead(rowPins[row]) == LOW) {
char key = getKey(row, col);
if (key != '\0') { // Check if key is not null character
if (key == 'A') {
enableAll();
} else if (key == 'B') {
disableLEDAndLCD();
} else if (key == 'C') {
disableBuzzer();
}
delay(500); // Debounce delay
}
}
}
pinMode(colPins[col], OUTPUT);
digitalWrite(colPins[col], HIGH);
}
}
char getKey(int row, int col) {
const char keys[4][4] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
return keys[row][col];
}
void enableAll() {
ledEnabled = true;
lcdEnabled = true;
buzzerEnabled = true;
for (int i = 0; i < 4; i++) {
digitalWrite(ledPins[i], HIGH); // Turn on all LEDs
}
lcd.backlight(); // Turn on LCD backlight
}
void disableLEDAndLCD() {
ledEnabled = false;
lcdEnabled = false;
for (int i = 0; i < 4; i++) {
digitalWrite(ledPins[i], LOW); // Turn off all LEDs
}
lcd.noBacklight(); // Turn off LCD backlight
}
void disableBuzzer() {
buzzerEnabled = false;
}
void Left(bool morseActive) {
indicateDirection(0, "Left", morseL, morseActive);
}
void Right(bool morseActive) {
indicateDirection(1, "Right", morseR, morseActive);
}
void Forward(bool morseActive) {
indicateDirection(2, "Forward", morseF, morseActive);
}
void Backward(bool morseActive) {
indicateDirection(3, "Backward", morseB, morseActive);
}
void indicateDirection(int index, const char* message, void (*morseFunc)(), bool morseActive) {
if (morseActive) morseFunc(); // Play Morse code
if (lcdEnabled) lcd.print(message); // Display direction on LCD
}
void morseL() {
playMorse(".-..");
}
void morseR() {
playMorse(".-.");
}
void morseF() {
playMorse("..-.");
}
void morseB() {
playMorse("-...");
}
void playMorse(const char* morseCode) {
// Loop through Morse code characters and play
for (const char* p = morseCode; *p; p++) {
// New code to control vibration motor
if (*p == '.') {
dot(); // Vibrate for dot
} else if (*p == '-') {
dash(); // Vibrate for dash
} else if (*p == ' ') {
// Pause between characters
delay(2 * morseDelay);
}
}
}
// Function to vibrate for a dot
void dot() {
digitalWrite(vibrationMotorPin, HIGH); // Vibrate for dot
delay(morseDelay);
digitalWrite(vibrationMotorPin, LOW); // Turn off vibration motor
delay(morseDelay); // Pause between dots
}
// Function to vibrate for a dash
void dash() {
digitalWrite(vibrationMotorPin, HIGH); // Vibrate for dash
delay(3 * morseDelay);
digitalWrite(vibrationMotorPin, LOW); // Turn off vibration motor
delay(morseDelay); // Pause between dashes
}
void playBuzzer() {
if (buzzerEnabled) {
buzzerPlaying = true;
Serial.println("Playing buzzer");
// Play your desired buzzer tone here
digitalWrite(buzzerPin, HIGH);
delay(500); // Adjust as needed
digitalWrite(buzzerPin, LOW);
lastBuzzerTime = millis();
buzzerPlaying = false;
}
}