Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pm:prj2026:florin.stancu:dinu.merceanu [2026/05/13 20:36]
dinu.merceanu [Electrical schematic]
pm:prj2026:florin.stancu:dinu.merceanu [2026/05/13 22:48] (current)
dinu.merceanu [Introduction]
Line 3: Line 3:
  
 <note tip> <note tip>
-A two-player reaction time game inspired by the Romanian TV show "Ce spun romanii"​. Three red LEDs light up one by one, then turn off simultaneously after a random delay — this is the start signal. The first player to press their button wins: their blue LED lights up and an OLED display shows the winner and their reaction time in milliseconds.+A two-player reaction time game inspired by the Romanian TV show "Ce spun romanii" ​and by the start lights of Formula 1. Three red LEDs light up one by one, then turn off simultaneously after a random delay — this is the start signal. The first player to press their button wins: their blue LED lights up and an OLED display shows the winner and their reaction time in milliseconds.
 The goal of the project is to create a simple yet engaging interactive game that tests the reflexes of two players. The idea started from TV shows where contestants must react as fast as possible to a visual signal. The goal of the project is to create a simple yet engaging interactive game that tests the reflexes of two players. The idea started from TV shows where contestants must react as fast as possible to a visual signal.
 The project is useful as a practical demonstration of hardware interrupts, timers and I2C communication on an AVR microcontroller,​ while also being an accessible example of an interactive embedded system. The project is useful as a practical demonstration of hardware interrupts, timers and I2C communication on an AVR microcontroller,​ while also being an accessible example of an interactive embedded system.
Line 56: Line 56:
 | GND | All components | Common ground | | GND | All components | Common ground |
  
-==== Electrical schematic ​==== +==== Hardware Schematic Diagram ​==== 
- +{{ :​pm:​prj2026:​florin.stancu:​hardwareschematicdiagram.png?800 |}}
-{{ :​pm:​prj2026:​florin.stancu:​electrialschematic.jpg?nolink&​700|}}+
  
 ==== Signal diagram ==== ==== Signal diagram ====
Line 72: Line 71:
 ===== Software Design ===== ===== Software Design =====
  
 +==== Development Environment ====
  
-<note tip> +The firmware was developed using **PlatformIO** integrated into **Visual Studio Code**, ​ 
-Descrierea codului aplicaţiei ​(firmware): +targeting the ATmega328P with the Arduino framework ​(used only as a build system —  
-  * mediu de dezvoltare ​(if any) (e.g. AVR StudioCodeVisionAVR+all peripheral control is done via direct AVR register access, without any Arduino  
-  ​* librării şi surse 3rd-party (e.gProcyon AVRlib+library functions)
-  ​* algoritmi şi structuri pe care plănuiţi să le implementaţi + 
-  * (etapa 3surse şi funcţii implementate +Upload is done via the **xplainedmini** protocol using avrdude, over USB. 
-</note>+ 
 +==== Third-party Libraries and Sources ==== 
 + 
 +No external libraries were used. All drivers were implemented from scratch using  
 +AVR-libc headers only: 
 + 
 +  * ''<​avr/​io.h>''​ — register definitions 
 +  * ''<​avr/​interrupt.h>''​ — ISR macro and sei()/cli(
 +  * ''<​util/​delay.h>''​ — _delay_ms() for debouncing 
 + 
 +The SSD1306 OLED driver, TWI/I2C driver, USART driver, and timer modules were  
 +written entirely by hand, inspired by the laboratory implementations provided  
 +during the PM course. 
 + 
 +==== File Structure ==== 
 + 
 +^ File ^ Role ^ 
 +| ''​src/​main.cpp''​ | Game logic, state machine, ISR definitions | 
 +| ''​src/​uptime.cpp''​ | Timer2 CTC — 1ms system tick counter | 
 +| ''​src/​timers.cpp''​ | Timer1 CTC — reaction time measurement | 
 +| ''​src/​twi.cpp''​ | I2C/TWI driver using AVR hardware TWI module | 
 +| ''​src/​ssd1306.cpp''​ | SSD1306 OLED driver with 5x7 bitmap font | 
 +| ''​src/​usart.cpp''​ | UART driver for serial debug output | 
 +| ''​include/​uptime.h''​ | uptime_ms() declaration | 
 +| ''​include/​timers.h''​ | Timer1_init/​start/​stop/​get_ms declarations | 
 +| ''​include/​twi.h''​ | TWI function declarations and frequency config | 
 +| ''​include/​ssd1306.h''​ | SSD1306 function declarations | 
 +| ''​include/​usart.h''​ | USART function declarations | 
 + 
 +==== Algorithms and Data Structures ==== 
 + 
 +**Game state machine** 
 + 
 +The game runs as a sequential state machine inside the main loop: 
 + 
 +  - ''​IDLE''​ — display shows "​READY"​waiting for SW0 (PB7press 
 +  - ''​COUNTDOWN''​ — LED1, LED2, LED3 light up one by one at 1s intervals using non-blocking timing via uptime_ms()External interrupts INT0/INT1 are active during this phase to detect false starts. 
 +  - ''​RANDOM DELAY''​ — all 3 LEDs remain on for a random interval (1–3 seconds), generated via rand() seeded with uptime_ms(
 +  ​- ''​GO''​ — LEDs turn off, Timer1 starts counting reaction time 
 +  ​- ''​RESULT''​ — first player to press wins. If a false start was detected, the offending player is disqualified. Results are shown on OLED and serial. 
 + 
 +**Non-blocking timing** 
 + 
 +All delays during the countdown and random delay phases use the pattern: 
 + 
 +<code c> 
 +uint32_t t = uptime_ms()
 +while ((uptime_ms() - t) < 1000 && !false_start_p1 && !false_start_p2);​ 
 +</code> 
 + 
 +This allows the main loop to remain responsive to false start interrupts even  
 +while waiting. 
 + 
 +**False start detection** 
 + 
 +External interrupts INT0 (PD2) and INT1 (PD3) are configured for falling edge  
 +detection. ISRs set volatile flags only if ''​game_started == 0'':​ 
 + 
 +<code c> 
 +ISR(INT0_vect) { if (!game_started) false_start_p1 = 1; } 
 +ISR(INT1_vect) { if (!game_started) false_start_p2 = 1; } 
 +</​code>​ 
 + 
 +**Reaction time measurement** 
 + 
 +Timer1 is initialized in CTC mode at 16MHz with prescaler 8, generating an  
 +interrupt every 1ms (OCR1A = 1999). A volatile counter ''​reaction_ticks''​  
 +increments in the ISR. Timer1_start() resets and enables it; Timer1_get_ms()  
 +reads the counter atomically using cli()/​sei(). 
 + 
 +**I2C communication** 
 + 
 +The TWI hardware module is configured for 100kHz SCL frequency. The SSD1306  
 +driver sends initialization commands on startup, then writes character bitmaps  
 +page by page using twi_start/​twi_write/​twi_stop sequences. 
 + 
 +**OLED font rendering**
  
 +Characters are stored as a 5x7 bitmap font in Flash memory (PROGMEM) for 
 +58 ASCII characters (space through Z). Each character is 5 bytes wide plus 
 +1 byte spacing. ssd1306_print_str() renders a string at a specified page row (0–7).
 ===== Rezultate Obţinute ===== ===== Rezultate Obţinute =====
  
pm/prj2026/florin.stancu/dinu.merceanu.1778693778.txt.gz · Last modified: 2026/05/13 20:36 by dinu.merceanu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0