Created
February 22, 2025 19:40
-
-
Save kmanadkat/172bdb9cc4d7591c2e6f533c81ea2d82 to your computer and use it in GitHub Desktop.
Arduino LCD I2C & Keypad Mini Project
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Arduino Weight Converter | |
| * This project allows the user to enter a weight (in Kg or Lbs) using a 4x4 matrix keypad. | |
| * The program then calculates and displays the equivalent weight on various celestial bodies | |
| * using an I2C LCD. | |
| * | |
| * Components: | |
| * - Arduino Uno | |
| * - 4x4 matrix keypad | |
| * - I2C 16x2 LCD module | |
| * - Wires, breadboard, etc. | |
| * | |
| * Author: Daksh Tanna, Jugal Somaiya | |
| * Date: 20 February, 2025 | |
| */ | |
| #include <Keypad.h> | |
| #include <LiquidCrystal_I2C.h> | |
| // ----------------------------- Constants & Pin Definitions ----------------------------- | |
| /** | |
| * 4x4 keypad mapping: | |
| * 1 2 3 A | |
| * 4 5 6 B | |
| * 7 8 9 C | |
| * * 0 # D | |
| * | |
| * rowPins[] and colPins[] define which Arduino pins connect to the keypad’s rows and columns. | |
| */ | |
| const byte ROWS = 4; //four rows | |
| const byte COLS = 4; //four columns | |
| char keys[ROWS][COLS] = { | |
| {'1','2','3','A'}, | |
| {'4','5','6','B'}, | |
| {'7','8','9','C'}, | |
| {'*','0','#','D'} | |
| }; | |
| byte rowPins[ROWS] = {9, 8, 7, 6}; //connect to the row pinouts of the keypad | |
| byte colPins[COLS] = {5, 4, 3, 2}; //connect to the column pinouts of the keypad | |
| // I2C LCD Format -> (Address,Width,Height) | |
| LiquidCrystal_I2C lcd(0x27, 16, 2); | |
| Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS); | |
| // ----------------------------- Gravity Data for Each Celestial Body ----------------------------- | |
| /** | |
| * planets[]: Stores the names of the celestial bodies | |
| * gravities[]: Stores the corresponding gravitational accelerations in m/s^2 | |
| * Index 0 of planets[] corresponds to index 0 of gravities[], etc. | |
| */ | |
| const char* planets[] = { | |
| "Moon", "Mercury", "Venus", "Mars", | |
| "Jupiter", "Saturn", "Uranus", "Neptune", | |
| "Pluto", "Ceres", "Eris", "Haumea", "Makemake" | |
| }; | |
| float gravities[] = { | |
| 1.62, 3.7, 8.87, 3.71, | |
| 24.79, 10.44, 8.69, 11.15, | |
| 0.62, 0.27, 0.82, 0.44, 0.5 | |
| }; | |
| #define EARTH_GRAVITY 9.81 // Earth's gravity in m/s^2 | |
| // ----------------------------- Global Variables ----------------------------- | |
| bool isKg = true; // Tracks current unit: true = Kg, false = Lbs | |
| float inputWeight = 0.0; // Holds the numeric value of the weight | |
| char inputBuffer[6]; // Temporary storage for weight input (as text) | |
| int inputIndex = 0; // Tracks the current position in inputBuffer | |
| // ----------------------------------- SETUP ----------------------------------- | |
| void setup() { | |
| lcd.init(); // initialize the lcd | |
| lcd.backlight(); // Turn on the Backlight | |
| welcomeMessage(); // Display a welcome message at startup | |
| } | |
| // ----------------------------------- LOOP ----------------------------------- | |
| void loop() { | |
| // Continuously read the keypad to check if any key has been pressed | |
| char key = keypad.getKey(); | |
| if (key) { | |
| // If the key is a digit (0-9), append it to the input buffer | |
| if (key >= '0' && key <= '9') { | |
| if (inputIndex < 5) { // We limit the buffer to 5 characters + null terminator | |
| inputBuffer[inputIndex++] = key; | |
| inputBuffer[inputIndex] = '\0'; // Mark the end of the string | |
| updateLCD(); // Refresh the LCD to show the new input | |
| } | |
| } | |
| // 'A' toggles between Kg and Lbs | |
| else if (key == 'A') { | |
| isKg = !isKg; // Flip the unit boolean | |
| updateLCD(); // Reflect the change on the LCD | |
| } | |
| // '#' triggers the weight calculation and display | |
| else if (key == '#') { | |
| if (inputIndex > 0) { // Only calculate if we actually have input | |
| inputWeight = atof(inputBuffer); // Convert string to float | |
| if (!isKg) { | |
| inputWeight /= 2.20462; // If the user input is in Lbs, convert to Kg before calculation | |
| } | |
| showWeights(); // Show the weights on all celestial bodies | |
| } | |
| } | |
| // '*' clears any current input | |
| else if (key == '*') { | |
| clearInput(); // Reset the input buffer | |
| } | |
| } | |
| } | |
| // ----------------------------------- FUNCTIONS ----------------------------------- | |
| /** | |
| * updateLCD() | |
| * This function clears the LCD and displays the current input buffer | |
| * along with the unit (Kg or Lbs). It also reminds the user to press '#' | |
| * to calculate the weights. | |
| */ | |
| void updateLCD() { | |
| lcd.clear(); | |
| lcd.setCursor(0, 0); | |
| lcd.print("Enter Wt: "); | |
| lcd.print(inputBuffer); | |
| lcd.print(isKg ? " Kg" : " Lbs"); // Show "Kg" or "Lbs" as the unit | |
| lcd.setCursor(0, 1); | |
| lcd.print("#: Calculate"); | |
| } | |
| /** | |
| * showWeights() | |
| * This function calculates and displays the user’s weight on each celestial body | |
| * listed in the `planets` array. It uses a loop to go through each body, compute | |
| * weight with: | |
| * W_planet = W_earth * (g_planet / g_earth) | |
| * Then displays for 2 seconds on the LCD before moving to the next body. | |
| * | |
| * After finishing, it clears the user input. | |
| */ | |
| void showWeights() { | |
| lcd.clear(); | |
| for (int i = 0; i < 13; i++) { | |
| float weightOnPlanet = inputWeight * (gravities[i] / EARTH_GRAVITY); | |
| // Print Planet Name | |
| lcd.setCursor(0, 0); | |
| lcd.print(planets[i]); | |
| // Print Weight on Planet | |
| lcd.setCursor(0,1); | |
| lcd.print(weightOnPlanet, 2); // Show up to 2 decimal places | |
| lcd.print(isKg ? " Kg" : " Lbs"); | |
| delay(2000); // Keep the result on screen for 2 seconds | |
| lcd.clear(); | |
| } | |
| clearInput(); // Clear the input buffer after displaying results | |
| } | |
| /** | |
| * clearInput() | |
| * Resets the input buffer (inputBuffer) and the inputIndex to zero. | |
| * Then calls updateLCD() to reflect an empty input state. | |
| */ | |
| void clearInput() { | |
| memset(inputBuffer, 0, sizeof(inputBuffer)); // Clear the array | |
| inputIndex = 0; // Reset index to 0 | |
| updateLCD(); // Update the LCD | |
| } | |
| /** | |
| * welcomeMessage() | |
| * Displays a brief welcome/instruction message on the LCD when the device is powered on. | |
| * After a delay, it clears the LCD and calls updateLCD() to initialize the main screen. | |
| */ | |
| void welcomeMessage() { | |
| lcd.setCursor(0, 0); | |
| lcd.print("Weight Converter"); | |
| lcd.setCursor(0, 1); | |
| lcd.print("A: Unit #: Calc"); | |
| delay(2000); // Keep this message visible for 2 seconds | |
| lcd.clear(); | |
| updateLCD(); // Show the main input prompt | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment