Skip to content

ItayVazana1/STMS_Embedded_Programming

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

STMS — North/South Intersection FSM (UNO R3 / ATmega328P) 🚦

A bare-metal traffic-light controller for a two-approach intersection (North/South) with pedestrian service, FSR weight sensors, maintenance override, and dual 16×2 LCDs via I²C (MCP23008).
Written in C/C++ directly against AVR registers (GPIO/ADC/INT/Timer). Deterministic timing via a 1 kHz Timer1 tick and fast Serial logs.

Arduino Uno Clock License I2C


✨ Features

  • Deterministic timing: Timer1 CTC @ 1 kHz (1 ms scheduler tick).
  • Global time scaling: SPEED_PCT scales all timings (100 = real time, 10 = 10× faster, e.g., 25 ≈ 4× faster).
  • I²C @ 400 kHz: Snappy dual-LCD updates (A4 = SDA, A5 = SCL) via MCP23008.
  • Pedestrian priority: Pressing the ped button on the current side can cut GREEN immediately (after minimum green).
  • Fairness & safety: Ped requests are served in the first ALL-RED after press with a “WALK NOW” window.
  • Maintenance mode: Dominant override — blinking YELLOW on both approaches until released.
  • Efficient LCD updates: Re-renders only on state changes (no countdown spam).
  • Verbose logging: Human-readable events/phase changes over Serial @ 230400 baud.

🧭 System Overview

Components

Subsystem Purpose Key APIs/Regs
FSM Phased intersection control phase_t, fsm_step()
GPIO LEDs + buttons + maintenance PORTx/DDRx/PINx
ADC FSR weight sensing (A1/A2) ADMUX, ADCSRA, ADC
INT Pedestrian buttons (D2/D3) INT0, INT1, EICRA, EIMSK
Timer 1 ms scheduler tick Timer1 CTC (OCR1A=249, prescale 64)
I²C LCDs Two 16×2 displays via MCP23008 Wire, Adafruit_LiquidCrystal

Phase Diagram (High-level)

          +-------------------+
          |      ALL_RED      |
          +---------+---------+
                    | (next: N)
                    v
         +----------+-----------+
         |        N_GREEN       |---> N_YELLOW ---> ALL_RED (+extra if ped)
         +----------+-----------+
                    |
                (next)
                    v
         +----------+-----------+
         |    S_PRE_RED_AMBER   |
         +----------+-----------+
                    v
         +----------+-----------+
         |        S_GREEN       |---> S_YELLOW ---> ALL_RED (+extra if ped)
         +----------------------+

Pedestrian & FSR Policy (Summary)

  • Ped on current side: Clamp GREEN to MIN and schedule extra ALL-RED; may cut immediately if current green > MIN.
  • Ped on opposite side: Suppresses FSR-based green extension of current side.
  • FSR extend: If current has weight and opposite has none, extend current green up to MAX.
  • FSR cut: If no weight on current side, reduce to MIN.

⏱️ Timing & Config

All user-tunable constants live in config.h. Times are human-readable seconds and scaled via SPEED_PCT.

Symbol Meaning Default
SPEED_PCT Global time scale 25 (≈4× faster sim)
TICK_MS Scheduler tick 1 ms
GREEN_MIN_S Minimum green 4 s
GREEN_BASE_S Base green 7 s
GREEN_MAX_S Max green (with extend) 10 s
YELLOW_S Yellow duration 1 s
ALL_RED_S All-red safety 2 s
S_PRE_RED_AMBER_S South pre-red amber 1 s
GREEN_BLINK_LAST_S Green tail blink window 3 s
PED_RED_EXTEND_S Extra all-red for ped 3 s
FSR_ON_TH / OFF_TH Hysteresis thresholds 300 / 250

Scaling macros: always use SCALED_MS_FROM_S(sec) / SCALED_MS(ms); avoid raw delays.


🛠️ Hardware

  • Board: Arduino UNO R3 (ATmega328P @ 16 MHz)
  • I²C: MCP23008-based 16×2 LCDs @ 0x20 (North), 0x21 (South) — A4=SDA, A5=SCL
  • LEDs:
    • North (PORTD): D5=GRN, D6=YEL, D7=RED
    • South (PORTB): D11=GRN, D12=YEL, D13=RED
  • Ped Buttons: D2 (INT0) North, D3 (INT1) South (active-LOW with pull-ups)
  • Maintenance Switch: A0 (active-LOW with pull-up)
  • FSR Sensors: A1 (South), A2 (North)
Signal Pin Notes
North GREEN D5 (PD5) Output
North YELLOW D6 (PD6) Output
North RED D7 (PD7) Output
South GREEN D11 (PB3) Output
South YELLOW D12 (PB4) Output
South RED D13 (PB5) Output
Ped North Btn D2 (INT0) Input, pull-up
Ped South Btn D3 (INT1) Input, pull-up
Maintenance A0 (PC0) Input, pull-up, active LOW
FSR South A1 (ADC1) Analog in
FSR North A2 (ADC2) Analog in
LCD North I²C 0x20 MCP23008
LCD South I²C 0x21 MCP23008

📦 Project Layout

Two dev workflows are supported:

.
├─ arduino_ide/                 # Flat layout for Arduino IDE
│  └─ STMS_Refactor/
│     ├─ stms.ino
│     ├─ config.h, pins.h, types.h
│     ├─ state.{h,cpp}, logging.{h,cpp}, gpio.{h,cpp}
│     ├─ adc.{h,cpp}, maint.{h,cpp}, timer.{h,cpp}, extint.{h,cpp}
│     ├─ phases.{h,cpp}, policy.{h,cpp}, blink.{h,cpp}, fsm.{h,cpp}
│     └─ lcd_ui.{h,cpp}, README.md
├─ platformio/                  # PlatformIO project
│  ├─ platformio.ini
│  └─ src/
│     └─ (same module files as above)
└─ docs/
   ├─ overview.md               # Module map & init order
   └─ timing.md                 # Scaling details & notes

Why two layouts? Arduino IDE compiles files in the sketch root; PlatformIO prefers src/.


▶️ Quick Start

Arduino IDE

  1. Open arduino_ide/STMS_Refactor/stms.ino.
  2. Select Board: Arduino Uno.
  3. Upload and open Serial Monitor @ 230400 baud.

PlatformIO (VS Code)

cd platformio
pio run -t upload
pio device monitor -b 230400

🧩 Key Modules

Module What it does
fsm.* One-step state machine; calls policy, blink, phases
policy.* Ped/FSR rules: clamp/extend/ignore as needed
phases.* enter_* helpers that set LEDs, timers, and logs
blink.* Green tail blink + maintenance yellow blink
extint.* INT0/INT1 ISRs for ped buttons
timer.* Timer1 1 kHz tick + ISR (g_ms++)
adc.* ADC init/read; FSR sampling with hysteresis
gpio.* LED writes + GPIO init (buttons & pull-ups)
lcd_ui.* Minimal LCD re-render on change
logging.* Serial event helpers (timestamps in ms)
state.* All extern globals (with volatile where needed)

🖥️ Runtime Logs (Sample)

[0ms] [BOOT] Turbo mode SPEED_PCT=25%, starting ALL_RED then N_GREEN
[1234ms] [FSM] N_GREEN (7000 ms)
[2450ms] [N PED] Button pressed
[2450ms] [N PED] Immediate: Cut North green for North ped
[2451ms] [FSM] N_YELLOW (1000 ms)
[3452ms] [FSM] ALL_RED (2000 ms)
[3452ms] [N PED] Extra ALL_RED (WALK NOW)

🔧 Configuration Tips

  • SPEED_PCT is your demo turbo: try 25 for ≈4× speed.
  • Keep init order: Serial → Wire → cli() → gpio/adc/timer/extint → FSM seed → sei() → LCD init → first render.
  • For reproducible tests, avoid changing scaling or thresholds between runs.

🧪 Testing & Troubleshooting

  • Button bounce: ISRs set flags only; the logic is idempotent. If your hardware bounces excessively, add physical debouncing or extend the debounce at the interrupt source.
  • Torn reads of g_ms: On AVR (8-bit), read g_ms atomically if you access it outside the main loop tick. The default loop pattern already uses the ISR-driven scheduler correctly.
  • LCD artifacts: Strings are padded to clear leftovers. If you customize labels, keep line length ≤16 and pad with spaces.
  • FSRs noisy? Tune FSR_ON_TH / FSR_OFF_TH to your sensor range; hysteresis prevents chatter.

🧱 Behavior Guarantees (Submission-Safe)

  • Zero behavior change vs the single-file baseline: identical timings, ISR behavior, transitions, and LCD text.
  • volatile globals preserved; ISRs remain minimal and deterministic.
  • LCD updates occur only on state changes.

🙌 Contributing

PRs and issues welcome! Please:

  • Keep any refactors behavior-identical unless explicitly flagged as optional.
  • Add unit-style checks or log snippets demonstrating no timing/phase regressions.
  • Match code style (C headers, small helpers, explicit side-effects in enter_*).

📄 License (MIT — “free license”)

This project is released under the MIT License. You are free to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the software.


📚 Credits


Updated: 2025-09-21 12:22

About

An embedded project of smart traffic management system with (built for Arduino UNO R3)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published