This repository contains the Robotics Laboratory assignments. Each assignment comprises stipulated requirements, detailed implementation instructions, as well as the requisite code and image files.
In this project, I built a system to control an RGB LED using Arduino and three potentiometers. Each potentiometer adjusts the brightness of one of the LED’s color channels (Red, Green, and Blue), allowing color mixing to create different shades.
Homework 1 details
For each channel, I calculated the required resistor using Ohm's Law:
-
Vsupply = supply voltage (5V from Arduino)
-
Vled = forward voltage of the LED for each color (from the datasheet; typical: Red ≈ 2.0V, Green ≈ 3.0V, Blue ≈ 3.0V)
-
Idesired = desired current through the LED (≈20 mA = 0.02 A)
R = ( Vsupply - Vled ) / Idesired
This allowed me to choose the correct resistor for each channel, preventing the LED from burning out and ensuring optimal control of brightness.
On the software side, the Arduino code reads the analog values from the potentiometers and maps them to the PWM range to control the intensity of each color channel.
Photo of the setup:
Click here for the video demonstrating functionality: https://youtu.be/dbRXBAk0GDs
Click here for code: https://github.com/danaioa/Introduction-To-Robotics/blob/main/Homework1/Homework1.ino
This project implements an intelligent traffic light system for cars and pedestrians using the Arduino platform.
It manages pedestrian crossings using a request button, LED indicators, a buzzer for audio alerts, and a 7-segment display that shows the remaining time.
Homework 2 Details
The system simulates a real traffic light with automatic timing control and pedestrian request functionality.
It provides realistic behavior:
- Cars have default priority
- Pedestrians can request to cross by pressing a button
- The crossing is indicated visually (LEDs) and audibly (buzzer)
- The remaining seconds are shown on a 7-segment display
| Component | Function |
|---|---|
| LEDs (Cars): red, yellow, green | Indicate stop, transition, and go |
| LEDs (Pedestrians): red and green | Show when pedestrians can cross |
| Button | Allows pedestrians to request crossing |
| Buzzer | Emits slow/fast beeps for walking and warning phases |
| 7-Segment Display | Shows remaining seconds per phase |
The system operates as a finite state machine, using a variable called stareCurenta.
Each state represents a specific phase of the traffic light cycle:
- Cars: Green | Pedestrians: Red
- Waits for pedestrian button press
- If pressed → moves to State 2
- Gives cars 8 extra seconds before stopping
- Time remaining shown on the display
- After 8 seconds → green off, yellow on → State 3
- Yellow LED stays on for 3 seconds (warning for drivers)
- Then cars turn red, pedestrians turn green → State 4
- Pedestrians can cross safely
- Display shows countdown
- Buzzer beeps slowly every 500ms
- After 8 seconds → enters State 5 (Warning)
- Pedestrian green LED blinks every 500ms
- Buzzer beeps rapidly (every 200ms)
- After 4 seconds → pedestrians red, cars green
- Returns to State 1 (Idle)
Photo of the setup:
Click here for the video demonstrating functionality: https://youtu.be/iLezpLi28Ho
This project implements a simple and smart home alarm system using the Arduino platform.
It uses sensors to detect movement and light changes, providing audio-visual alerts and menu control via the Serial Monitor.
The system can be armed or disarmed with a password and offers a configuration menu for easy setup.
Homework 3 Details
The system simulates a real home security setup using:
- An ultrasonic sensor to detect motion or distance changes
- A LDR to detect darkness
- A buzzer and LEDs to indicate alarms and states
- Serial Monitor menu for control and configuration
It behaves like a real alarm system:
- Can be armed/disarmed
- Detects intrusions or darkness
- Triggers alarm with sound and blinking LED
- Password-protected deactivation
- Customizable settings for all sensors and components
| Component | Function |
|---|---|
| Ultrasonic Sensor | Detects movement by measuring distance changes |
| LDR | Detects light level to enable “night mode” |
| Buzzer | Audio alert when alarm triggers |
| Red LED | Indicates alarm active or system armed |
| Green LED | Indicates system ready or disarmed |
| Serial Monitor | Used for menu navigation and password input |
The system works in two main states – Armed and Disarmed – controlled via Serial Monitor.
- Green LED ON
- System inactive (safe)
- Menu options:
1️ Arm System
2️ Settings (submenu)
- LED green blinks for 3 seconds before system activation
- Ultrasonic sensor takes several readings to set the baseline distance
- After setup → system becomes Armed
- Red LED ON
- System monitors both sensors:
- If motion detected → triggers alarm
- If darkness detected → triggers alarm
- Serial Monitor shows current sensor readings
- Red LED blinks continuously
- Buzzer sounds at the set frequency
- Serial Monitor shows the cause (“Movement detected” / “Darkness detected”)
- System waits for password input to stop the alarm
- Correct password → alarm stops, green LED ON, system disarmed
- Wrong password → “Password incorrect!” message
Accessible from Serial Monitor → Option “2. Settings”
| Option | Description |
|---|---|
| 1 | Set ultrasonic tolerance (motion sensitivity) |
| 2 | Set LDR light threshold (for night mode) |
| 3 | Set buzzer frequency (tone) |
| 4 | Change system name (displayed at startup) |
| 5 | Change password (requires old password) |
| 6 | Return to main menu |
All settings update instantly and are confirmed with a feedback message.
- When intrusion detected:
- Red LED blinks every 300 ms
- Buzzer sounds continuously
- Serial Monitor asks for password
- After entering correct password:
- Alarm stops
- Red LED turns off
- Green LED turns on
- System returns to safe state
- Uses
millis()for all delays (non-blocking operation) - Modular structure:
citesteUltrasonic()→ motion detectioncitesteLdr()→ light detectionverificareSenzori()→ main sensor controldeclanseazaAlarma()/actualizeazaAlarma()→ alarm controlpazasiIncredereActivat()/verificaParolaDezactivare()→ arming/disarming
- User-friendly Serial Monitor interface
Click here for the video demonstrating functionality: Watch on YouTube
This project implements a “Simon Says” memory game on a 4-digit 7-segment display, using a joystick for input, a buzzer for audio feedback, a pause/menu button, and EEPROM to save the highest score between sessions.
Homework 4 Details
The game displays a random sequence of 4 digits on the 7-segment display.
The player must reproduce the sequence exactly using the joystick:
- move between digits,
- lock and modify values,
- submit the answer with a long press.
Correct answer → next level (sequence shows faster).
Wrong answer → “GAME OVER” + final score shown.
| Component | Function |
|---|---|
| 74HC595 | Drives the 7-segment display segments (reduces pin usage) |
| 4-digit 7-segment display | Shows numbers, text, and menu options |
| Joystick (X, Y, SW) | Player control for navigation, selection, and input |
| Push button (Pause/Menu) | Opens the pause/menu (“PAUS”) and returns to main menu |
| Buzzer | Audio feedback for moves, locks, errors, and success |
| EEPROM | Saves and loads the high score between sessions |
| Resistors | Segment current limiting (mandatory) |
| 595 Pin | Segment | Description |
|---|---|---|
| Q0 | a | top segment |
| Q1 | b | upper right |
| Q2 | c | lower right |
| Q3 | d | bottom |
| Q4 | e | lower left |
| Q5 | f | upper left |
| Q6 | g | middle |
| Q7 | DP | not used (always off) |
Display type: Common Cathode
Each digit cathode is controlled individually through NPN transistors.
| Component | Pin |
|---|---|
| latchPin | 11 |
| clockPin | 10 |
| dataPin | 12 |
| Digit select pins | 4, 5, 6, 7 |
| Joystick X / Y / SW | A0 / A1 / 2 |
| Pause/Menu button | 3 |
| Buzzer | 8 |
| State | Description |
|---|---|
| MENU | Main menu: options PLAy, SCOR, StOP |
| SHOW_SEQUENCE | Displays the current random 4-digit sequence |
| INPUT | Player enters digits using the joystick |
| CHECK | Compares player input to generated sequence |
| RESULT | Displays “GOOd” (correct) or “Err” (wrong) |
| PAUSE | Shows “PAUS” and halts game until resumed |
| SHOW_SCORE | Displays the saved high score (from EEPROM) |
| Action | Description |
|---|---|
| Left / Right | Move cursor between the 4 digits |
| Short press (SW) | Lock/unlock selected digit for editing |
| Long press (SW) | Submit the 4-digit answer |
| Up / Down | Change the value of the selected digit (0–9) |
| Pause/Menu button | Interrupt game → show “PAUS” → return to menu |
| Display | Function |
|---|---|
PLAy |
Starts a new game (generate new sequence) |
SCOR |
Displays the highest saved score |
StOP |
Cancels the current game and returns to menu |
| Text | Meaning |
|---|---|
PLAy |
Start game |
SCOR |
Show high score |
StOP |
Stop game |
PAUS |
Pause / menu state |
GOOd |
Correct answer |
Err |
Wrong answer |
Sc## |
Show score after failure |
BYE |
End animation |
GAME OVER |
Scrolling text at the end of game |
Implemented as a fontTable[] array in code, mapping each character to its segment pattern.
| Character | Description |
|---|---|
| 0–9 | Standard numeric glyphs |
| A, b, C, c, d, E, F, G, H, L, O, P, S, t, U, r, R, y, M, V, -, (space) | Custom letters for menu and messages |
| Type | Frequency | Usage |
|---|---|---|
| Fast (4 Hz) | 125 ms on/off | Selected (editable) digit |
| Slow (1 Hz) | 500 ms on/off | Locked digit |
| End flash | 3 flashes (150 ms interval) | Game over animation |
| “BYE” animation | Sequential fade-out of digits |
| Event | Frequency / Duration | Description |
|---|---|---|
| Move cursor | 1 kHz / 50 ms | Short tick |
| Lock/unlock digit | 1.5 kHz / 100 ms | Click tone |
| Error | 200 Hz / 300 ms | Low tone |
| Correct answer | 800 Hz → 1200 Hz | Two-tone success sound |
- Menu → Play
- Shows “PLAy”
- Generates random 4-digit sequence
- ShowSequence
- Displays digits one by one (faster each round)
- Input
- Player reproduces the sequence
- Check
- Compares input vs generated sequence
- Result
- If correct → score +1 → new round
- If wrong → show “Err”, score, scroll “GAME OVER”
- End
- Plays “BYE” animation → return to menu
- Reads high score at startup (
setup()). - Writes new high score automatically if beaten.
- Data remains stored even after power-off.
EEPROM high score persistence
Scrolling text (“GAME OVER”)
Multi-tone success sound
Different blink rates (locked vs selected digits)
Combo/time bonus scoring
Fancy animations - End animation (“BYE”)
- Non-blocking 4-digit multiplexing (
5 msper digit). - Display driven through 74HC595 using
shiftOut(). - No
delay()used anywhere — entirely event-based. - Structured state machine with clear transitions.
- Random seed generated from
analogRead(A2)for better randomness.
The game is a 2D side-scrolling platformer where the player, Grigore, fights for a greener environment.
Homework 5 Details
The game is a 2D side-scrolling platformer where the player, Grigore, fights for a greener environment.
- Mechanics: Grigore moves Left/Right and can jump (gravity is applied).
- Map: Composed of 80 columns (equivalent to 5 screens of 16x2), representing the landscape.
- Thematic Objective: Grigore must collect as many Trees (C) as possible to save the planet and make it greener. He must avoid the Bulldozers (F), agents of destruction, which represent the major hazards.
- Scrolling: The screen scrolls when the player approaches the screen edges (column 5 on the left, column 10 on the right).
- Objects:
*
C(ID 1 - Tree): Collectible object. Collecting them contributes to saving the planet and grants+10points. *F(ID 2 - Bulldozer/Hazard): Danger. Contact with a bulldozer results in the loss of a life and respawn at the starting position. *#(ID 3 - Ground): Platform. *E(ID 4 - Finish): The Final Flag that marks the success of the mission and the saving of the landscape. - Final Goal: Reach the final flag (
E), avoiding the bulldozers and collecting all the trees to save the planet.
- Tree (
C):+10points. - Finish (
E):+50points. - Time: Score based on collected items and time survived (
model.timpJoc).
The project adheres to the Separation of Concerns (SoC) principle, structuring the application logic into three distinct components:
-
This component is the data and logic core of the game. It manages the current state without knowing how the data is displayed or how input is processed.
- Data Management: Manages all primary game data: score, lives, player position (
x,y,coordGlobalaX), map data, and leaderboard. - Core Logic: Contains essential physics and game rules methods:
aplicaGravitatia()(applyGravity),verificaColiziuni()(checkCollisions), andactualizeazaJucator()(updatePlayer).
- Data Management: Manages all primary game data: score, lives, player position (
-
The controller manages the game flow and acts as the intermediary between the Model and the Renderer. It implements the State Machine logic.
- Flow Control: Manages the entire game flow using a State Machine.
- Input Handling: Reads and processes inputs from the hardware (Joystick, Buttons) via
gestioneazaIntrari()(handleInputs). - State Updates: Updates the Model based on inputs and time via
actualizeazaStareaJocului()(updateGameState). - Utility Management: Manages low-level timing concepts (Debouncing, Timers using
millis()) and Animation Sequences.
-
This is an abstract interface responsible solely for **output**. It defines how the game state is visually represented, decoupling the display mechanism from the game logic.
- Interface: Defined by the abstract method
deseneazaEcran()(drawScreen). - Implementations:
RedareSeriala(SerialRenderer): Used for **development and debugging** (outputs text to the Serial Monitor).AfisajLCD(LCDRenderer): The **final implementation** for rendering graphics on the 16x2 LCD display.
- Interface: Defined by the abstract method
The project includes multiple bonus functionalities, marked in the code as additional assignment requirements:
| Bonus | Implementation Details | Relevant Files |
|---|---|---|
| Pauză (Pause) | PAUZA state activated by an external button (PinButonPauza). The LED lights up upon entering pause. |
GestionarJoc.cpp, StareaJocului.h |
| Sunet (Buzzer) | Audio feedback for: jump/click (Type 1), select/confirm (Type 2), Game Over/Impact (Type 3). | GestionarJoc.cpp (emiteSunet() - emitSound), ConfigJoc.h |
| LED | Used to indicate alert states: Game Over and Pause. | GestionarJoc.cpp (controleazaLED() - controlLED), ConfigJoc.h |
| Clasament (EEPROM) | Top 3 Highscores read/written to EEPROM memory. | StareaJocului.cpp, StareaJocului.h |
| Nume Jucător (Highscore) | Option to enter 3 characters for the name if a top score is achieved. | GestionarJoc.cpp (gestioneazaNumeNou() - handleNewName), StareaJocului.h |
| Reset Clasament | Menu option to delete the saved leaderboard from EEPROM. | GestionarJoc.cpp (gestioneazaMeniu() - handleMenu) |
| Secțiune "Despre Joc" (About) | Display of information (static + animation) with text scrolling. | AfisajLCD.cpp (deseneazaDespreAnimatie() - drawAboutAnimation), GestionarJoc.cpp |
| Animație Game Over | Complex sequence: Fall (3 frames), Shake/Impact, Text scrolling (GAME OVER), Score display. |
GestionarJoc.cpp (ruleazaSecventaGameOver() - runGameOverSequence), AfisajLCD.cpp (deseneazaGameOverAnimatie() - drawGameOverAnimation), ConfigJoc.h |
| Animație Victorie (Win) | Dedicated sequence (JOC_CASTIGAT) when reaching the end. |
GestionarJoc.cpp (ruleazaSecventaVictorie() - runWinSequence), AfisajLCD.cpp (deseneazaVictorie() - drawVictory) |
All pin definitions are found in ConfigJoc.h and Platformer_Main.ino.
| Component | Pin (Arduino) | Config File |
|---|---|---|
| LCD RS | 9 |
Platformer_Main.ino |
| LCD EN | 8 |
Platformer_Main.ino |
| LCD D4-D7 | 7, 6, 5, 4 |
Platformer_Main.ino |
| Joystick X | A0 |
ConfigJoc.h (PinAxJocX) |
| Joystick Y | A1 |
ConfigJoc.h (PinAxJocY) |
| Joystick Select | 3 |
ConfigJoc.h (PinApasaJoc) |
| Buton Pauză (Pause) | 1 |
ConfigJoc.h (PinButonPauza) |
| LED | 2 |
ConfigJoc.h (PinLED) |
| Buzzer | 13 |
ConfigJoc.h (PinBuzzer) |
The leaderboard (Top 3 scores) is stored starting at address 0 of the EEPROM memory. Each entry is 8 bytes (4 for name + 4 for score).
- Start Address:
EEPROM_ADDR_CLASAMENT = 0(defined inStareaJocului.cpp). - Stored Structure:
ScorMax clasament[3]
| Index | Address (Bytes) | Content | Size |
|---|---|---|---|
| 1st Place | 0 - 7 |
char nume[4] + int valoare |
8 bytes |
| 2nd Place | 8 - 15 |
char nume[4] + int valoare |
8 bytes |
| 3rd Place | 16 - 23 |
char nume[4] + int valoare |
8 bytes |
Note:
EEPROM.get()/EEPROM.put()is used to directly read/write the structures.
The project implements the following game states, managed by the GestionarJoc (GameController). The table clearly shows the purpose of each state and its possible transitions.
| # | State (RO) | Description / Purpose | Transitions To |
|---|---|---|---|
| 1 | MENIU_PRINCIPAL | The initial state. Navigates between options: START GAME, LEADERBOARD, RESET, ABOUT GAME. | JOC_ACTIV, CLASAMENT_AFISARE, RESET_CLASAMENT, DESPRE_JOC_ANIMATIE |
| 2 | JOC_ACTIV | The main game loop (physics, input handling, collision checking). | PAUZA, GAME_OVER_ANIMATIE (on death), JOC_CASTIGAT (on reaching 'E') |
| 3 | PAUZA | Game execution is stopped. Waits for the Select button to resume or return to the main menu. | JOC_ACTIV, MENIU_PRINCIPAL |
| 4 | JOC_CASTIGAT | Victory animation sequence (Mission Accomplished). | CLASAMENT_NUME_NOU or JOC_TERMINAT |
| 5 | GAME_OVER_ANIMATIE | Complex sequence: Fall, Shake, Text Scroll (after collision with 'F' / Bulldozer). | CLASAMENT_NUME_NOU or JOC_TERMINAT |
| 6 | CLASAMENT_NUME_NOU | Input interface for the 3-character name if a new high score is achieved. | CLASAMENT_AFISARE |
| 7 | JOC_TERMINAT | Displays the final score. Waits for the Select button to proceed. | MENIU_PRINCIPAL |
| 8 | CLASAMENT_AFISARE | Displays the Top 3 Highscores (with navigation). | MENIU_PRINCIPAL |
| 9 | DESPRE_JOC_ANIMATIE | Displays the animated, scrolling "About Game" information text. | MENIU_PRINCIPAL |
| 10 | RESET_CLASAMENT | Displays the confirmation message for resetting the leaderboard. | MENIU_PRINCIPAL |
