{"id":50857935,"url":"https://github.com/leonidasdev/pic16f886-smart-lamp","last_synced_at":"2026-06-14T19:31:57.316Z","repository":{"id":329405699,"uuid":"1119194132","full_name":"leonidasdev/pic16f886-smart-lamp","owner":"leonidasdev","description":"Firmware for a PIC16F886‑based smart lamp: sensor acquisition (temp, humidity, noise, lux, CO₂) and actuator control (fan, LEDs) with UART protocol","archived":false,"fork":false,"pushed_at":"2025-12-31T16:16:09.000Z","size":162,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-05T01:13:44.923Z","etag":null,"topics":["c","embedded-systems","pic16f886"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leonidasdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-18T22:33:58.000Z","updated_at":"2025-12-31T16:16:12.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/leonidasdev/pic16f886-smart-lamp","commit_stats":null,"previous_names":["leonidasdev/pic16f886-smart-lamp"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/leonidasdev/pic16f886-smart-lamp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonidasdev%2Fpic16f886-smart-lamp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonidasdev%2Fpic16f886-smart-lamp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonidasdev%2Fpic16f886-smart-lamp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonidasdev%2Fpic16f886-smart-lamp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leonidasdev","download_url":"https://codeload.github.com/leonidasdev/pic16f886-smart-lamp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonidasdev%2Fpic16f886-smart-lamp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34335688,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-14T02:00:07.365Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","embedded-systems","pic16f886"],"created_at":"2026-06-14T19:31:55.442Z","updated_at":"2026-06-14T19:31:57.310Z","avatar_url":"https://github.com/leonidasdev.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SMA-LAMP (LMDE-MA) - Firmware Documentation\r\n\r\n**Microcontroller:** PIC16F886 @ 20 MHz  \r\n**Project:** Sistema de Monitorización \u0026 Actuación -  Lámpara de Mesa Diseñada para el Estudio\r\n**Version:** 1.0  \r\n**Date:** December 2025  \r\n**Language:** C (XC8 Compiler)  \r\n**Institution:** Universidad Politécnica de Madrid\r\n\r\n---\r\n\r\n## Table of Contents\r\n\r\n1. [System Overview](#system-overview)\r\n2. [Hardware Architecture](#hardware-architecture)\r\n3. [Software Architecture](#software-architecture)\r\n4. [Project Structure](#project-structure)\r\n5. [Quick Start](#quick-start)\r\n6. [Communication Protocol](#communication-protocol)\r\n7. [Building \u0026 Deployment](#building--deployment)\r\n8. [Testing](#testing)\r\n9. [Troubleshooting](#troubleshooting)\r\n10. [Documentation](#documentation)\r\n\r\n---\r\n\r\n## System Overview\r\n\r\nSMA-LAMP is an embedded monitoring and control system that:\r\n- **Monitors** environmental conditions (temperature, humidity, noise, light, CO₂)\r\n- **Controls** RGB LED lighting and fan speed\r\n- **Communicates** with SMA-COMP host via UART protocol\r\n- **Persists** configuration in EEPROM\r\n- **Operates** autonomously with timed sensor readings\r\n\r\n### Key Features\r\n- Real-time noise monitoring (10ms sampling, 1s window)\r\n- Environmental sensors (5s periodic readings)\r\n- CO₂ sensor with 5-minute warmup handling\r\n- UART protocol with timeout protection\r\n- Automatic configuration persistence (every 5s)\r\n- LED activity indicator on command reception\r\n- Brown-out reset protection\r\n\r\n---\r\n\r\n## Hardware Architecture\r\n\r\n### Microcontroller Specifications\r\n```\r\nMCU:        PIC16F886\r\nFrequency:  20 MHz (HS crystal)\r\nVoltage:    5V\r\nFlash:      8 KB\r\nRAM:        368 bytes\r\nEEPROM:     256 bytes\r\n```\r\n\r\n### Pin Assignment\r\n\r\n#### Port A\r\n| Pin | Function | Type | Device | Notes |\r\n|-----|----------|------|--------|-------|\r\n| RA0 | AN0 | Analog Input | LM35 Temperature | 0-5V → 0-500°C |\r\n| RA1 | AN1 | Analog Input | HIH4000 Humidity | 0-5V → 0-100% RH |\r\n| RA2 | AN2 | Analog Input | Microphone Noise | Sampled every 10ms |\r\n\r\n#### Port C\r\n| Pin | Function | Type | Device | Notes |\r\n|-----|----------|------|--------|-------|\r\n| RC0 | SPI_CLK | Digital Output | SK9822 LEDs | Bit-bang SPI clock |\r\n| RC1 | SPI_SDO | Digital Output | SK9822 LEDs | Bit-bang SPI data |\r\n| RC2 | CCP1/PWM | PWM Output | Fan Motor | 20 kHz, 10-bit resolution |\r\n| RC3 | SCL | I2C | VEML7700, iAQ-Core | Requires 4.7kΩ pull-up |\r\n| RC4 | SDA | I2C | VEML7700, iAQ-Core | Requires 4.7kΩ pull-up |\r\n| RC6 | TX | UART Output | SMA-COMP | 9600 baud |\r\n| RC7 | RX | UART Input | SMA-COMP | 9600 baud |\r\n\r\n### Peripheral Usage\r\n\r\n| Peripheral | Usage | Configuration |\r\n|------------|-------|---------------|\r\n| **Timer0** | 10ms tick | Prescaler 1:256, preload 61 |\r\n| **Timer1** | ~105ms tick | Prescaler 1:8, 16-bit overflow |\r\n| **Timer2** | PWM base | PR2=249 → 20 kHz |\r\n| **ADC** | 3 channels | 10-bit, VDD/VSS ref, 10µs acq time |\r\n| **MSSP** | I2C Master | 100 kHz, SSPADD=49 |\r\n| **EUSART** | UART | 9600 8N1, SPBRG=129 |\r\n| **CCP1** | PWM | Fan control, duty 0-100% |\r\n\r\n### Sensor Details\r\n\r\n| Sensor | Interface | Address/Channel | Range | Update Rate |\r\n|--------|-----------|-----------------|-------|-------------|\r\n| **LM35** | ADC | AN0 | 0-255°C | 5 seconds |\r\n| **HIH4000** | ADC | AN1 | 0-100% RH | 5 seconds |\r\n| **Microphone** | ADC | AN2 | 3 categories | 1 second (max of 100 samples) |\r\n| **VEML7700** | I2C | 0x10 | 0-65535 lux | 5 seconds |\r\n| **iAQ-Core** | I2C | 0x5A | 0-65535 ppm CO₂ | 5 seconds (warmup 5 min) |\r\n\r\n### Actuator Details\r\n\r\n| Actuator | Interface | Control | Range | Notes |\r\n|----------|-----------|---------|-------|-------|\r\n| **SK9822 RGB LED** | SPI (bit-bang) | R, G, B, Brightness | 0-255 RGB, 0-31 brightness | N_LEDS configurable |\r\n| **Fan** | PWM (CCP1) | Speed percentage | 0-100% | 20 kHz frequency |\r\n\r\n---\r\n\r\n## Software Architecture\r\n\r\n### Layer Hierarchy\r\n\r\n```\r\n┌─────────────────────────────────────────┐\r\n│              main.c                     │  ← Application Logic\r\n│  • Initialization                       │\r\n│  • ISR (Timer0/Timer1)                  │\r\n│  • Main Loop (scheduler-driven)         │\r\n└───────────────┬─────────────────────────┘\r\n                │\r\n    ┌───────────┴───────────┬─────────────┬──────────────┐\r\n    ▼                       ▼             ▼              ▼\r\n┌─────────┐         ┌──────────────┐  ┌──────────┐  ┌────────────┐\r\n│ sensor/ │         │  actuador/   │  │protocol/ │  │    hal/    │\r\n│         │         │              │  │          │  │            │\r\n│ • temp  │         │  • led       │  │• uart    │  │• adc       │\r\n│ • hum   │         │  • fan       │  │• sched   │  │• i2c       │\r\n│ • noise │         │              │  │          │  │• spi       │\r\n│ • lux   │         │              │  │          │  │• pwm       │\r\n│ • co2   │         │              │  │          │  │• uart      │\r\n│         │         │              │  │          │  │• eeprom    │\r\n└────┬────┘         └──────┬───────┘  └────┬─────┘  └─────┬──────┘\r\n     │                     │               │               │\r\n     │                     │               │               │\r\n     └─────────────────────┴───────────────┴───────────────┘\r\n                                  │\r\n                           ┌──────┴──────┐\r\n                           │    lib/     │  ← Official Libraries\r\n                           │             │\r\n                           │ • i2c-v2    │  (Read-only)\r\n                           │ • spi-v1    │\r\n                           └─────────────┘\r\n```\r\n\r\n### Design Principles\r\n\r\n1. **Layered Architecture**: Clear separation of concerns\r\n2. **Single Responsibility**: Each module has one job\r\n3. **HAL Abstraction**: Hardware access only through HAL layer\r\n4. **No Re-initialization**: Peripherals initialized once in main()\r\n5. **Event-Driven**: Scheduler triggers periodic operations\r\n6. **Non-Blocking**: All operations use timeouts or polling\r\n\r\n---\r\n\r\n## Project Structure\r\n\r\n```\r\nSMA-LAMP/\r\n├── main.c                  # Application entry point and main loop\r\n├── README.md              # This file - project overview\r\n├── REGISTERS_MAP.md       # PIC16F886 register reference\r\n│\r\n├── lib/                   # Official vendor libraries (read-only)\r\n│   ├── README.md         # Library documentation\r\n│   ├── i2c-v2.c/h        # Hardware I2C driver\r\n│   └── spi-master-v1.c/h # Bit-bang SPI driver\r\n│\r\n├── hal/                   # Hardware Abstraction Layer\r\n│   ├── README.md         # HAL architecture and API reference\r\n│   ├── hal_adc.c/h       # ADC peripheral (3 channels, 10-bit)\r\n│   ├── hal_uart.c/h      # UART communication (9600 baud)\r\n│   ├── hal_i2c.c/h       # I2C master (100 kHz)\r\n│   ├── hal_spi.c/h       # SPI bit-bang implementation\r\n│   ├── hal_pwm.c/h       # PWM generation (20 kHz)\r\n│   └── hal_eeprom.c/h    # EEPROM read/write\r\n│\r\n├── sensor/                # Sensor driver implementations\r\n│   ├── README.md         # Sensor specifications and usage\r\n│   ├── sensor_temp.c/h   # LM35 temperature sensor (ADC)\r\n│   ├── sensor_hum.c/h    # HIH4000 humidity sensor (ADC)\r\n│   ├── sensor_noise.c/h  # Microphone noise level (ADC)\r\n│   ├── sensor_lux.c/h    # VEML7700 light sensor (I2C)\r\n│   └── sensor_co2.c/h    # iAQ-Core CO₂ sensor (I2C)\r\n│\r\n├── actuador/              # Actuator driver implementations\r\n│   ├── README.md         # Actuator specifications and usage\r\n│   ├── actuator_led.c/h  # SK9822 RGB LED strip (SPI)\r\n│   └── actuator_fan.c/h  # PWM fan control\r\n│\r\n├── protocol/              # Communication and timing\r\n│   ├── README.md         # Protocol specification\r\n│   ├── protocol_uart.c/h # UART command protocol with CRC-8\r\n│   └── scheduler.c/h     # Time-based event scheduler\r\n│\r\n└── test/                  # Individual component tests\r\n    ├── README.md         # Testing documentation and procedures\r\n    ├── test_fan.c        # Fan PWM ramp test\r\n    ├── test_led.c        # LED color cycling test\r\n    ├── test_command.c    # UART command reception test\r\n    ├── test_co2.c        # CO₂ sensor I2C test\r\n    ├── test_lux.c        # Light sensor I2C test\r\n    ├── test_temperature.c # Temperature sensor ADC test\r\n    ├── test_noise.c      # Noise sensor ADC test\r\n    ├── test_humidity.c   # Humidity sensor ADC test\r\n    └── test_eeprom.c     # EEPROM read/write test\r\n```\r\n\r\n### Documentation Structure\r\n\r\nEach module folder contains detailed documentation:\r\n\r\n- **[lib/README.md](lib/README.md)** - Vendor library API and integration notes\r\n- **[hal/README.md](hal/README.md)** - HAL design principles, peripheral configurations, API reference\r\n- **[sensor/README.md](sensor/README.md)** - Sensor datasheets summary, calibration, wiring diagrams\r\n- **[actuador/README.md](actuador/README.md)** - Actuator specifications, control algorithms, safety limits\r\n- **[protocol/README.md](protocol/README.md)** - Complete protocol specification, frame format, CRC details\r\n- **[test/README.md](test/README.md)** - Test procedures, expected results, troubleshooting\r\n\r\n---\r\n\r\n## Quick Start\r\n\r\n### Prerequisites\r\n- **Hardware**: PIC16F886 microcontroller @ 20 MHz crystal\r\n- **Software**: MPLAB X IDE v6.0+, XC8 Compiler v2.40+\r\n- **Programmer**: PICkit 3/4 or compatible\r\n\r\n### Basic Setup\r\n\r\n1. **Clone/Download** this project\r\n2. **Open** `main.c` project in MPLAB X\r\n3. **Configure** device as PIC16F886\r\n4. **Build** the project (Production mode)\r\n5. **Program** the device using PICkit\r\n6. **Connect** UART terminal @ 9600 baud to RC6 (TX)\r\n7. **Observe** periodic sensor data transmission\r\n\r\n### First Power-On\r\n\r\nAfter programming, the system will:\r\n1. Initialize all peripherals (200ms)\r\n2. Restore saved configuration from EEPROM\r\n3. Send diagnostic frames:\r\n   - `CMD_NOISE = 0` (noise sensor baseline)\r\n   - `CMD_TEMP = 25°C` (temperature test)\r\n4. Begin periodic operation:\r\n   - Every 1s: Noise level report\r\n   - Every 5s: Temperature, humidity, light, CO₂ reports\r\n\r\n### Hardware Checklist\r\n\r\nBefore first power-on:\r\n- [ ] 20 MHz crystal + 15-33pF capacitors on OSC1/OSC2\r\n- [ ] 10kΩ pull-up resistor on MCLR pin\r\n- [ ] 100nF decoupling capacitor near VDD\r\n- [ ] 4.7kΩ pull-up resistors on RC3 (SCL) and RC4 (SDA)\r\n- [ ] 5V power supply (stable, ±5%)\r\n- [ ] UART connection: TX(RC6)→RX, RX(RC7)→TX, GND common\r\n\r\n---\r\n\r\n## Module Overview\r\n\r\n### Hardware Abstraction Layer (HAL)\r\n\r\nThe HAL provides a clean interface to PIC16F886 peripherals:\r\n\r\n| Module | Purpose | Key Functions |\r\n|--------|---------|---------------|\r\n| **hal_adc** | Analog-to-Digital conversion | `adc_init()`, `adc_read(ch)` |\r\n| **hal_uart** | Serial communication | `uart_init(baud)`, `uart_send_byte()` |\r\n| **hal_i2c** | I2C bus communication | `hal_i2c_init()`, `hal_i2c_read/write()` |\r\n| **hal_spi** | SPI communication | `spi_init()`, `spi_send_byte()` |\r\n| **hal_pwm** | PWM signal generation | `pwm_init()`, `pwm_set_percent()` |\r\n| **hal_eeprom** | Non-volatile storage | `eeprom_read/write(addr, val)` |\r\n\r\n**Design Principle**: Upper layers never access registers directly - all hardware interaction goes through HAL.\r\n\r\nSee [hal/README.md](hal/README.md) for detailed API reference and configuration details.\r\n\r\n### Sensor Layer\r\n\r\n| Sensor | Interface | Range | Update Rate | Special Notes |\r\n|--------|-----------|-------|-------------|---------------|\r\n| **LM35** | ADC AN0 | 0-255°C | 5s | 10mV/°C, direct read |\r\n| **HIH4000** | ADC AN1 | 0-100% RH | 5s | Requires temperature compensation |\r\n| **Microphone** | ADC AN2 | 3 categories | 1s | Maximum of 100 samples |\r\n| **VEML7700** | I2C 0x10 | 0-65535 lux | 5s | 16-bit light sensor |\r\n| **iAQ-Core** | I2C 0x5A | 0-65535 ppm | 5s | 5-minute warmup period |\r\n\r\nSee [sensor/README.md](sensor/README.md) for calibration procedures, wiring diagrams, and troubleshooting.\r\n\r\n### Actuator Layer\r\n\r\n| Actuator | Interface | Control Range | Notes |\r\n|----------|-----------|---------------|-------|\r\n| **SK9822 LED** | SPI (RC0/RC1) | RGB: 0-255, Brightness: 0-31 | Supports multiple LEDs (N_LEDS) |\r\n| **Fan** | PWM (RC2) | 0-100% speed | 20 kHz frequency, 10-bit resolution |\r\n\r\nSee [actuador/README.md](actuador/README.md) for control algorithms and safety considerations.\r\n\r\n### Protocol Layer\r\n\r\n**UART Protocol**: Custom binary protocol with CRC-8 error detection\r\n\r\n- **Frame Format**: `[HEADER][LEN][CMD][DATA...][CRC_L][CRC_H]`\r\n- **Baudrate**: 9600 bps (8N1)\r\n- **Commands**: 7 bidirectional commands (see protocol documentation)\r\n- **Error Detection**: CRC-8-CCITT (polynomial 0x07)\r\n\r\n**Scheduler**: Time-based event system driven by Timer0 (10ms) and Timer1 (~105ms)\r\n\r\nSee [protocol/README.md](protocol/README.md) for complete protocol specification and examples.\r\n\r\n---\r\n\r\n## Communication Protocol\r\n\r\n### Data Flow: PIC → Host (SMA-COMP)\r\n\r\n```\r\nEvery 1 second:\r\n    └─→ [AA 04 00 {cat} 00 00]          CMD_NOISE\r\n    \r\nEvery 5 seconds:\r\n    ├─→ [AA 04 06 {temp} 00 00]         CMD_TEMP\r\n    ├─→ [AA 05 03 {hh} {hl} 00 00]      CMD_HUM\r\n    ├─→ [AA 05 01 {lh} {ll} 00 00]      CMD_LUX\r\n    └─→ [AA 05 02 {ch} {cl} 00 00]      CMD_CO2\r\n```\r\n\r\n### Data Flow: Host → PIC\r\n\r\n```\r\nAsynchronous (any time):\r\n    ├─→ [AA 04 04 {speed} 00 00]              CMD_FAN\r\n    └─→ [AA 07 05 {r} {g} {b} {br} 00 00]     CMD_LEDS\r\n```\r\n\r\n### Example Frames\r\n\r\n**Send Temperature 25°C**:\r\n```\r\nAA 04 06 19 00 00\r\n│  │  │  │  └─ CRC\r\n│  │  │  └──── Data: 25 (0x19)\r\n│  │  └─────── Command: TEMP (0x06)\r\n│  └────────── Length: 4\r\n└───────────── Header: 0xAA\r\n```\r\n\r\n**Receive LED Command (Red, max brightness)**:\r\n```\r\nAA 07 05 FF 00 00 1F 00 00\r\n│  │  │  │  │  │  │  └─ CRC\r\n│  │  │  │  │  │  └──── Brightness: 31\r\n│  │  │  │  │  └─────── Blue: 0\r\n│  │  │  │  └──────────Green: 0\r\n│  │  │  └───────────── Red: 255\r\n│  │  └──────────────── Command: LEDS (0x05)\r\n│  └─────────────────── Length: 7\r\n└────────────────────── Header: 0xAA\r\n```\r\n\r\n---\r\n\r\n## Timing \u0026 Scheduling\r\n\r\n### Timer Configuration\r\n\r\n#### Timer0 (10ms tick)\r\n```\r\nFosc/4 = 20MHz / 4 = 5 MHz\r\nPeriod = 0.2 µs\r\nPrescaler 1:256 → tick every 51.2 µs\r\n10ms / 51.2µs = 195.3 ticks\r\nPreload = 256 - 195 = 61\r\n\r\nOPTION_REG = 0b10000111  // nRBPU=1 (PORTB pull-ups OFF), PSA=0, PS=111 (1:256), T0CS=0 (Fosc/4)\r\nTMR0 += 61               // Compensated reload\r\n```\r\n\r\n#### Timer1 (~105ms tick)\r\n```\r\nFosc/4 = 5 MHz\r\nPrescaler 1:8 → tick every 1.6 µs\r\nOverflow = 65536 × 1.6µs = 104.8576 ms\r\n\r\nT1CON = 0b00110001      // TMR1ON=1, TMR1CS=0 (Fosc/4), T1CKPS=11 (1:8), TMR1GE=0 (always count)\r\n```\r\n\r\n### ISR (Interrupt Service Routine)\r\n\r\n```c\r\nvoid __interrupt() isr(void) {\r\n    // Every 10ms\r\n    if(TMR0IF \u0026\u0026 TMR0IE) {\r\n        TMR0IF = 0;\r\n        TMR0 += 61;  // Compensated reload (avoids drift)\r\n        \r\n        scheduler_tick_10ms();\r\n        \r\n        // Sample noise and keep maximum over 1s window\r\n        noise_cat_t cat = noise_read_category();\r\n        if(cat \u003e noise_max_cat) noise_max_cat = cat;\r\n    }\r\n    \r\n    // Every ~105ms\r\n    if(TMR1IF \u0026\u0026 TMR1IE) {\r\n        TMR1IF = 0;\r\n        scheduler_tick_100ms();\r\n    }\r\n}\r\n```\r\n\r\n**IMPORTANT**: `TMR0 += 61` compensates for ISR latency, preventing cumulative drift.\r\n\r\n---\r\n\r\n## Testing\r\n\r\nThe project includes 9 standalone test programs in the `test/` folder:\r\n\r\n| Test | Purpose | Hardware Required |\r\n|------|---------|-------------------|\r\n| **test_fan** | PWM fan ramp (0→80%→0%) | Fan on RC2 |\r\n| **test_led** | LED color cycling | SK9822 on RC0/RC1 |\r\n| **test_command** | UART command reception | UART terminal |\r\n| **test_temperature** | Temperature reading | LM35 on RA0 |\r\n| **test_humidity** | Humidity reading | HIH4000 on RA1 |\r\n| **test_noise** | Noise level sampling | Microphone on RA2 |\r\n| **test_lux** | Light sensor I2C | VEML7700 on I2C |\r\n| **test_co2** | CO₂ sensor I2C | iAQ-Core on I2C |\r\n| **test_eeprom** | EEPROM read/write | None (internal) |\r\n\r\n**Usage**: Each test is a standalone `.c` file with its own `main()`. Compile and program individually to verify hardware functionality before deploying the full system.\r\n\r\nSee [test/README.md](test/README.md) for detailed test procedures and expected outputs.\r\n\r\n---\r\n\r\n## System Operation\r\n\r\n```\r\n1. Power-On Reset → PWRTE waits 72ms\r\n2. main() starts\r\n3. init_pins_min()          Configure TRIS registers\r\n4. init_timers()            Start Timer0, Timer1, enable GIE\r\n5. scheduler_init()         Reset tick counters\r\n6. protocol_init(9600)      Initialize UART\r\n7. Peripheral Init (once):\r\n   ├─ adc_init()\r\n   ├─ hal_i2c_init()\r\n   ├─ spi_init()\r\n   └─ pwm_init()\r\n8. Sensor Init:\r\n   ├─ temp_init()           (No-op)\r\n   ├─ hum_init()            (No-op)\r\n   ├─ noise_init()          (No-op)\r\n   ├─ lux_init()            (No-op)\r\n   └─ co2_init()            Reset warmup counter\r\n9. Actuator Init:\r\n   ├─ led_init()            Set default white color\r\n   └─ fan_init()            Set speed to 0%\r\n10. Restore from EEPROM:\r\n    ├─ Read addresses 0x00-0x04\r\n    ├─ Validate (check for 0xFF = empty)\r\n    └─ Apply configuration\r\n11. Diagnostic Test:\r\n    ├─ Send CMD_NOISE = 0\r\n    └─ Send CMD_TEMP = 25°C\r\n12. Enter main loop\r\n```\r\n\r\n### Main Loop (Infinite)\r\n\r\n```\r\nwhile(1) {\r\n    // Event 1: Noise report (every 1s)\r\n    if(scheduler_noise_ready()) {\r\n        protocol_send(CMD_NOISE, {noise_max_cat}, 1);\r\n        noise_max_cat = NOISE_LOW;  // Reset window\r\n    }\r\n    \r\n    // Event 2: Environmental sensors (every 5s)\r\n    if(scheduler_env_ready()) {\r\n        save_actuators_state();     // Persist to EEPROM\r\n        co2_update_warmup();         // Increment warmup counter\r\n        \r\n        temp = temp_read_degC();\r\n        hum = hum_read_percent();\r\n        lux = lux_read();\r\n        co2 = co2_read_ppm();        // Returns 0xFFFF if not ready\r\n        \r\n        protocol_send(CMD_TEMP, ...);\r\n        protocol_send(CMD_HUM, ...);\r\n        protocol_send(CMD_LUX, ...);\r\n        protocol_send(CMD_CO2, ...);\r\n    }\r\n    \r\n    // Event 3: Command reception (asynchronous)\r\n    if(protocol_receive(\u0026cmd, buf, \u0026len)) {\r\n        switch(cmd) {\r\n            case CMD_FAN:\r\n                current_fan_speed = buf[0];\r\n                fan_set_speed(current_fan_speed);\r\n                break;\r\n            case CMD_LEDS:\r\n                current_led_r = buf[0];\r\n                current_led_g = buf[1];\r\n                current_led_b = buf[2];\r\n                current_led_brightness = buf[3];\r\n                led_set_color(...);\r\n                break;\r\n        }\r\n        \r\n        // Activity indicator: flash green LED\r\n        led_set_color(0, 255, 0, 10);\r\n        __delay_ms(50);\r\n        led_set_color(current_led_r, current_led_g, current_led_b, current_led_brightness);\r\n    }\r\n}\r\n```\r\n\r\n**Non-blocking**: All operations use polling or timeouts (no infinite loops).\r\n\r\n---\r\n\r\n## EEPROM Persistence\r\n\r\n### Memory Map\r\n\r\n| Address | Content | Range | Description |\r\n|---------|---------|-------|-------------|\r\n| 0x00 | LED Brightness | 0-31 | Masked with 0x1F |\r\n| 0x01 | LED Red | 0-255 | RGB component |\r\n| 0x02 | LED Green | 0-255 | RGB component |\r\n| 0x03 | LED Blue | 0-255 | RGB component |\r\n| 0x04 | Fan Speed | 0-100 | Percentage |\r\n\r\n### Save Strategy\r\n\r\n**When**: Every 5 seconds (called from `scheduler_env_ready()`)\r\n\r\n**Why**: \r\n- Protects against power loss\r\n- Reduces EEPROM wear (~1M cycle limit)\r\n- Max 5s data loss window\r\n\r\n**Function**:\r\n```c\r\nstatic void save_actuators_state(void) {\r\n    eeprom_write(0x00, current_led_brightness);\r\n    eeprom_write(0x01, current_led_r);\r\n    eeprom_write(0x02, current_led_g);\r\n    eeprom_write(0x03, current_led_b);\r\n    eeprom_write(0x04, current_fan_speed);\r\n}\r\n```\r\n\r\n### Restore on Boot\r\n\r\n1. Read all 5 addresses\r\n2. Check if empty (`0xFF` indicates first boot)\r\n3. If empty: use defaults (white LED, fan off)\r\n4. If valid: apply saved configuration\r\n\r\n---\r\n\r\n## Building \u0026 Deployment\r\n\r\n### Requirements\r\n- **IDE**: MPLAB X v6.0 or later\r\n- **Compiler**: XC8 v2.40 or later\r\n- **Programmer**: PICkit 3/4 or compatible\r\n\r\n### Compilation Steps\r\n\r\n1. Open project in MPLAB X\r\n2. Select device: PIC16F886\r\n3. Configure toolchain: XC8\r\n4. Build (Production): `Ctrl+Shift+F11`\r\n5. Verify configuration bits match `main.c` pragmas\r\n\r\n### Configuration Bits Verification\r\n\r\n```c\r\n#pragma config FOSC = HS        // Crystal 20 MHz\r\n#pragma config WDTE = OFF       // Watchdog disabled\r\n#pragma config PWRTE = ON       // Power-up timer enabled\r\n#pragma config MCLRE = ON       // MCLR enabled\r\n#pragma config BOREN = ON       // Brown-out reset enabled\r\n#pragma config LVP = OFF        // Low-voltage programming disabled\r\n```\r\n\r\n### Hardware Checklist\r\n\r\nBefore powering on:\r\n- ☐ 20 MHz crystal between OSC1/OSC2 with 15-33pF capacitors\r\n- ☐ MCLR pulled up to VDD with 10kΩ\r\n- ☐ VDD = 5V stable (100nF decoupling capacitor)\r\n- ☐ I2C pull-ups (4.7kΩ on RC3/RC4)\r\n- ☐ UART connected to SMA-COMP (TX→RX, RX→TX, GND common)\r\n\r\n---\r\n\r\n## Troubleshooting\r\n\r\n### Common Issues\r\n\r\n| Symptom | Cause | Solution |\r\n|---------|-------|----------|\r\n| No UART output | Crystal not oscillating | Verify crystal, capacitors, FOSC=HS |\r\n| UART sends garbage | Baudrate mismatch | Verify SPBRG=129, _XTAL_FREQ=20MHz |\r\n| I2C sensors don't respond | Missing pull-ups | Add 4.7kΩ on RC3 (SCL) and RC4 (SDA) |\r\n| CO₂ always reads 0xFFFF | Sensor in warmup | Wait 5 minutes after power-on |\r\n| Fan doesn't run | Pin not configured | Verify TRISC2=0, CCP1CON=0x0C |\r\n| LEDs don't light | Wrong SPI pins | Verify RC0 (CLK), RC1 (SDO) connections |\r\n| Random resets | Brown-out | Check 5V supply stable, BOREN=ON |\r\n| EEPROM data lost | Not saving | Verify save_actuators_state() called every 5s |\r\n\r\n### Diagnostic Features\r\n\r\n**Startup Test Frames** (100ms after boot):\r\n```\r\nAA 04 00 00 00 00    → CMD_NOISE = 0\r\nAA 04 06 19 00 00    → CMD_TEMP = 25°C\r\n```\r\n**Purpose**: Verify UART TX works immediately after boot.\r\n\r\n**LED Activity Indicator**:\r\n- Green flash (50ms) when valid command received\r\n- Indicates: UART RX works + protocol parsing OK\r\n\r\n### Debug Terminal Test\r\n\r\n1. Connect terminal @ 9600 8N1 to RC6 (TX)\r\n2. Power on PIC\r\n3. Should see 2 frames within 200ms\r\n4. Every 1s: CMD_NOISE frame\r\n5. Every 5s: 4 sensor frames (TEMP, HUM, LUX, CO2)\r\n\r\nIf no output → hardware issue (crystal, power, connections).\r\n\r\n---\r\n\r\n## Performance Metrics\r\n\r\n| Metric | Value | Notes |\r\n|--------|-------|-------|\r\n| **CPU Usage** | ~15% | ISR: 2%, Main loop: 13% |\r\n| **RAM Usage** | ~200 bytes | 54% of 368 bytes |\r\n| **Flash Usage** | ~5-8 KB | 60-100% of 8KB (depends on optimization) |\r\n| **EEPROM Writes** | 5 writes/5s | ~100k cycles = 139 hours continuous |\r\n| **ISR Frequency** | 110 Hz | Timer0: 100 Hz, Timer1: 10 Hz |\r\n| **Worst ISR Latency** | \u003c50 µs | Including noise sampling |\r\n\r\n---\r\n\r\n## Safety Features\r\n\r\n1. **Brown-Out Reset**: Detects low voltage, resets safely\r\n2. **UART Timeout**: Prevents infinite blocking (100ms)\r\n3. **EEPROM Wear Leveling**: Saves every 5s (not every command)\r\n4. **Watchdog**: Disabled (system is deterministic)\r\n5. **Interrupt Priority**: Timers only (no nesting issues)\r\n\r\n---\r\n\r\n## Documentation\r\n\r\n### Module-Specific Documentation\r\n\r\nFor detailed technical information, refer to the README in each module folder:\r\n\r\n- **[lib/README.md](lib/README.md)** - Official library API reference and integration guidelines\r\n- **[hal/README.md](hal/README.md)** - Complete HAL architecture, register configurations, timing analysis\r\n- **[sensor/README.md](sensor/README.md)** - Sensor datasheets, calibration procedures, wiring diagrams\r\n- **[actuador/README.md](actuador/README.md)** - Actuator control algorithms, safety limits, performance specs\r\n- **[protocol/README.md](protocol/README.md)** - Protocol specification, frame format, CRC implementation, examples\r\n- **[test/README.md](test/README.md)** - Test procedures, expected outputs, debugging guide\r\n\r\n### Additional Resources\r\n\r\n- **REGISTERS_MAP.md** - Complete PIC16F886 register reference with bit definitions\r\n- **PIC16F886 Datasheet** - [DS41291E](https://www.microchip.com/) (official Microchip documentation)\r\n- **XC8 Compiler Guide** - Microchip XC8 C Compiler User's Guide\r\n- **I2C Specification** - I²C-bus specification and user manual (NXP)\r\n- **SPI Protocol** - Serial Peripheral Interface documentation\r\n\r\n---\r\n\r\n## Version History\r\n\r\n| Version | Date | Changes |\r\n|---------|------|---------|\r\n| **1.0** | Dec 2025 | **Initial production release** |\r\n| | | - Modular layered architecture (lib/hal/sensor/actuador/protocol) |\r\n| | | - CO₂ sensor warmup handling (5-minute automatic) |\r\n| | | - EEPROM persistence (auto-save every 5s) |\r\n| | | - CRC-8 error detection in UART protocol |\r\n| | | - Complete test suite (9 standalone tests) |\r\n| | | - Comprehensive documentation structure |\r\n\r\n---\r\n\r\n## Authors \u0026 Support\r\n\r\n**Project**: SMA-LAMP (LMDE-MA)  \r\n**Institution**: Universidad Politécnica de Madrid  \r\n**Course**: Sistemas Empotrados (Embedded Systems)  \r\n**Academic Year**: 2024-2025  \r\n**Semester**: 1st Half - 4th Year\r\n\r\n### Technical Support\r\n\r\nFor issues or questions:\r\n1. Check the [Troubleshooting](#troubleshooting) section in this README\r\n2. Consult module-specific README files for detailed information\r\n3. Refer to PIC16F886 datasheet (DS41291E) for hardware details\r\n4. Review test programs in `test/` folder for working examples\r\n\r\n### Contributing\r\n\r\nThis is an academic project. If you're working on modifications:\r\n1. Maintain the layered architecture (lib → hal → sensor/actuador → protocol → main)\r\n2. Never modify `lib/` folder (vendor code)\r\n3. Document all changes in module-specific README files\r\n4. Create test programs for new functionality\r\n5. Update REGISTERS_MAP.md if adding new peripheral usage\r\n\r\n---\r\n\r\n## License\r\n\r\nThis project is licensed under the MIT License. See the [LICENSE](./LICENSE) file for details.\r\n\r\n---\r\n\r\n## Support\r\n\r\nFor issues, questions, or contributions, please open an issue on the [GitHub repository](https://github.com/leonidasdev/pic16f886-smart-lamp).\r\n\r\n---\r\n\r\n**Version**: 0.1.0  \r\n**Last Updated**: December 2025\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleonidasdev%2Fpic16f886-smart-lamp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleonidasdev%2Fpic16f886-smart-lamp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleonidasdev%2Fpic16f886-smart-lamp/lists"}