initial
@@ -0,0 +1,44 @@
|
||||
# macOS
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
.idea/
|
||||
|
||||
# KiCad temporary and backup files
|
||||
*.kicad_pcb-bak
|
||||
*.kicad_sch-bak
|
||||
*.kicad_prl
|
||||
*-backups/
|
||||
*-rescue.kicad_sch
|
||||
*.lck
|
||||
fp-info-cache
|
||||
|
||||
# Python
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.so
|
||||
.Python
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
|
||||
# OS files
|
||||
Thumbs.db
|
||||
.ehthumbs.db
|
||||
|
||||
# Build artifacts
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
dist/
|
||||
build/
|
||||
*.egg-info/
|
||||
@@ -0,0 +1,981 @@
|
||||
# ESPHome AiP650E Display Monitor Component Specification
|
||||
## Microcontroller Proxy Architecture
|
||||
|
||||
**Document Version:** 3.0
|
||||
**Date:** April 2026
|
||||
**Target Platform:** ESP32-S3 (with optional AVR/STM32 proxy)
|
||||
**Original IC:** Wuxi I-CORE AiP650E (2-line Serial Interface LED Controller/Driver)
|
||||
|
||||
---
|
||||
|
||||
## 1. Overview
|
||||
|
||||
This specification describes an ESPHome custom component for reading standing desk display information via a protocol proxy microcontroller. The architecture uses a small AVR or STM32 microcontroller to reliably capture the time-critical AiP650E protocol from the original desk controller, then exposes decoded display data to the ESP32-S3 via I2C.
|
||||
|
||||
### 1.1 Architecture Rationale
|
||||
|
||||
Given that the ESP32-S3 is already fully loaded with:
|
||||
- High-resolution display rendering (SPI)
|
||||
- Capacitive touchscreen input processing
|
||||
- WiFi/BLE connectivity with background tasks
|
||||
|
||||
A dedicated protocol proxy microcontroller provides:
|
||||
|
||||
- ✅ **Reliable timing capture** - No jitter from WiFi, rendering, or touch processing
|
||||
- ✅ **Clean separation of concerns** - Timing logic isolated from UI/connectivity logic
|
||||
- ✅ **Simpler integration** - ESP32 reads simple I2C data instead of complex protocol capture
|
||||
- ✅ **Better real-time guarantees** - AVR/STM32 can dedicate 100% resources to protocol
|
||||
- ✅ **Inexpensive** - Arduino Nano, STM32F401, etc. cost $5-15
|
||||
|
||||
### 1.2 System Overview
|
||||
|
||||
The original control board's microcontroller continues to manage motor control, height calculations via Hall sensors, and display updates. A small proxy microcontroller captures the AiP650E bus communication and makes display data available to the ESP32-S3 via I2C. The ESP32-S3 runs ESPHome with a simple I2C driver component to read display values and button states, focusing on UI rendering and Home Assistant integration.
|
||||
|
||||
---
|
||||
|
||||
## 2. System Architecture
|
||||
|
||||
### 2.1 Tri-Microcontroller Design (Recommended: ATtiny85 Proxy)
|
||||
|
||||
```
|
||||
┌───────────────────────────────────────────────────────────────────┐
|
||||
│ Standing Desk Control System │
|
||||
└───────────────────────────────────────────────────────────────────┘
|
||||
|
||||
ORIGINAL MICROCONTROLLER (32-bit MCU) - Original Board
|
||||
├── Function: Motor control, height calculation, display updates
|
||||
├── Connected:
|
||||
│ ├── H-Bridge Motor Driver (pins 1, 2, 3, 5)
|
||||
│ ├── Hall Sensor Inputs (pins 11, 12, 17, 18)
|
||||
│ ├── Motor Sense/Voltage Sense (pins 19, 20)
|
||||
│ ├── SEGM_CLK (pin 16) ──────────┐
|
||||
│ └── SEGM_DIO (pin 15) ──────────┼──→ [ATtiny85 Proxy]
|
||||
│ │
|
||||
└── Behavior: │
|
||||
└── Sends display commands via CLK/DIO
|
||||
|
||||
ATtiny85 PROXY MICROCONTROLLER (8-pin DIP)
|
||||
├── Function: AiP650E protocol capture & I2C bridge
|
||||
├── Pin Assignment (8 pins total):
|
||||
│ ├── Pin 2: PB3 ← SEGM_CLK (from original, CLK input/interrupt)
|
||||
│ ├── Pin 3: PB4 ← SEGM_DIO (from original, DIO data input)
|
||||
│ ├── Pin 5: PB0 → SCL (to ESP32 I2C, with 4.7k pull-up)
|
||||
│ ├── Pin 6: PB1 → SDA (to ESP32 I2C, with 4.7k pull-up)
|
||||
│ ├── Pin 7: PB2 (spare for future use)
|
||||
│ ├── Pin 4: GND (common ground)
|
||||
│ └── Pin 8: VCC (3.3V from ESP32)
|
||||
└── Behavior:
|
||||
├── Captures CLK/DIO protocol continuously
|
||||
├── Decodes display segments in real-time
|
||||
├── Exposes 7 I2C registers (0x00-0x04 + control)
|
||||
└── 100% reliability (no WiFi/render jitter)
|
||||
|
||||
ESP32-S3 (ESPHome) - With Touchscreen
|
||||
├── Function: UI rendering, touch input, WiFi, Home Assistant
|
||||
├── Connected:
|
||||
│ ├── Display panel (SPI) - 30+ pins
|
||||
│ ├── Touch controller (I2C/SPI)
|
||||
│ ├── I2C SCL (GPIO21) ← ATtiny85 (reads display data)
|
||||
│ ├── I2C SDA (GPIO20) ← ATtiny85 (reads display data)
|
||||
│ ├── GPIO14 ← KEY_UP (direct from original board pin 14)
|
||||
│ ├── GPIO13 ← KEY_DOWN (direct from original board pin 13)
|
||||
│ └── WiFi antenna (internal)
|
||||
└── Behavior:
|
||||
├── Renders touchscreen UI
|
||||
├── Polls I2C every 100ms for display data
|
||||
├── Updates Home Assistant via WiFi
|
||||
├── Handles touch input & button monitoring
|
||||
└── Lightweight I2C component (simple polling)
|
||||
```
|
||||
|
||||
### 2.1a Hardware Wiring Summary
|
||||
|
||||
```
|
||||
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
|
||||
│ Original │ │ ATtiny85 │ │ ESP32-S3 │
|
||||
│ Desk Micro │ │ Proxy │ │ (ESPHome) │
|
||||
├─────────────────┤ ├──────────────────┤ ├─────────────────┤
|
||||
│ Pin 16 (CLK) ──┼─→ Pin 2 (PB3) │ │ │
|
||||
│ Pin 15 (DIO) ──┼─→ Pin 3 (PB4) │ │ │
|
||||
│ Pin 14 (UP) ──┼──────────────────────→ GPIO14 │
|
||||
│ Pin 13 (DOWN) ──┼──────────────────────→ GPIO13 │
|
||||
│ │ Pin 5 (PB0/SCL) ─┬──→ GPIO21 (SCL) │
|
||||
│ │ Pin 6 (PB1/SDA) ─┼──→ GPIO20 (SDA) │
|
||||
│ GND ───┼─→ Pin 4 (GND) ────┼──→ GND │
|
||||
│ │ Pin 8 (VCC) ◄────┼── GPIO 3.3V │
|
||||
│ │ │ [4.7k pulls] │
|
||||
└─────────────────┘ └──────────────────┘ └─────────────────┘
|
||||
```
|
||||
|
||||
**Key Points:**
|
||||
- ✅ Buttons (UP/DOWN) connect directly to ESP32 - no proxy involvement
|
||||
- ✅ ATtiny85 focuses only on protocol capture (isolated, reliable)
|
||||
- ✅ ESP32 does UI/WiFi/rendering without timing pressure
|
||||
- ✅ Minimal wiring: just 4 GPIO + I2C + GND + 3.3V
|
||||
|
||||
AiP650E DISPLAY DRIVER
|
||||
├── Status: PHYSICALLY REMOVED from board
|
||||
├── Previously connected to:
|
||||
│ ├── Pin 2 (CLK) ← Original Micro (now disconnected)
|
||||
│ ├── Pin 3 (DIO) ← Original Micro (now disconnected)
|
||||
│ └── Segments/Grids (no longer needed)
|
||||
└── Replacement: ESP32-S3 software protocol decoder
|
||||
```
|
||||
|
||||
### 2.2 Hardware Connections
|
||||
|
||||
```
|
||||
ORIGINAL MICROCONTROLLER ESP32-S3
|
||||
┌──────────────────────┐ ┌──────────┐
|
||||
│ │ │ │
|
||||
│ Pin 16 (SEGM_CLK) ├─────────→ GPIO_CLK │
|
||||
│ Pin 15 (SEGM_DIO) ├─────────→ GPIO_DIO │
|
||||
│ │ │ │
|
||||
│ [Motor & Hall] │ │ [WiFi] │
|
||||
│ (isolated) │ │ [Touch] │
|
||||
└──────────────────────┘ └──────────┘
|
||||
│ │
|
||||
│ [To Touchscreen]
|
||||
│
|
||||
┌────┴────┐
|
||||
│ Removed │
|
||||
│ AiP650E │ (Physically removed from board)
|
||||
│ Display │
|
||||
│ Driver │
|
||||
└─────────┘
|
||||
|
||||
BUTTONS (Shared or Duplicated)
|
||||
┌──────────────┐
|
||||
│ Key_Up ├─→ ESP32-S3 GPIO
|
||||
│ Key_Down ├─→ ESP32-S3 GPIO
|
||||
│ Mem 1 (K15) ├─→ Originally via AiP650E key matrix
|
||||
│ Mem 2 (K12) ├─→ (No longer accessible - can be removed)
|
||||
│ Mem 3 (K11) ├─→ (No longer accessible - can be removed)
|
||||
└──────────────┘
|
||||
```
|
||||
|
||||
### 2.3 Protocol Monitoring Role
|
||||
|
||||
The ESP32-S3 acts as a **passive listener** on the AiP650E communication bus:
|
||||
|
||||
- **Does NOT send commands** to the AiP650E
|
||||
- **Does NOT interfere** with original microcontroller operation
|
||||
- **Listens to** CLK/DIO signals originating from the original microcontroller
|
||||
- **Decodes** display data, brightness, and mode commands
|
||||
- **Extracts** segment information from data writes to RAM addresses 0x68, 0x6A, 0x6C
|
||||
- **Reports** findings to ESPHome as sensors and binary sensors
|
||||
|
||||
This approach ensures:
|
||||
- ✅ Original motor control continues unaffected
|
||||
- ✅ Height sensing via Hall sensors remains intact
|
||||
- ✅ Display information is available to touchscreen UI
|
||||
- ✅ No conflicts or bus contention
|
||||
- ✅ Simple hardware modifications (just connect two lines and buttons)
|
||||
|
||||
---
|
||||
|
||||
## 3. Protocol Monitoring & Decoding
|
||||
|
||||
### 3.1 2-Line Serial Interface (Listener Perspective)
|
||||
|
||||
The ESP32-S3 monitors a 2-line serial protocol used by the original microcontroller to communicate with the AiP650E:
|
||||
|
||||
- **CLK (from original micro):** Clock signal - provides timing reference
|
||||
- **DIO (from original micro):** Data signal - carries command and data bytes (open-drain, pulled high by resistor)
|
||||
|
||||
### 3.2 Bus Monitoring Basics
|
||||
|
||||
**Frame Structure (as monitored):**
|
||||
- Start Condition: CLK high, DIO falling edge (high → low)
|
||||
- Data Phase: 8 bits + 1 ACK bit (9 bits total per byte)
|
||||
- Stop Condition: CLK high, DIO rising edge (low → high)
|
||||
|
||||
**Timing Requirements for Listening:**
|
||||
- CLK low level width: typically ≥100 ns
|
||||
- CLK high level width: typically ≥100 ns
|
||||
- Minimum delay to sample DIO after CLK edge: ≥30 ns (add margin in software)
|
||||
- Maximum transmission rate: 0-4 Mbps (typical 1-2 Mbps for this application)
|
||||
|
||||
**Key Difference - Listener Role:**
|
||||
- ESP32 does NOT drive CLK or DIO low (no open-drain outputs)
|
||||
- ESP32 only reads CLK and DIO states as inputs
|
||||
- ESP32 uses GPIO interrupts on CLK rising edges to time DIO sampling
|
||||
- No need to generate ACK bit (original micro is the master)
|
||||
|
||||
### 3.3 Command Decoding
|
||||
|
||||
The ESP32 monitors and decodes instructions sent by the original microcontroller:
|
||||
|
||||
**Instruction Format:** All instructions are 16-bit (2 bytes) transmitted MSB first:
|
||||
|
||||
```
|
||||
[System Instruction Byte] [Display/Control Instruction Byte]
|
||||
```
|
||||
|
||||
**System Instruction Byte (monitoring):**
|
||||
- Expected value: `0x48` (binary: `01001000`)
|
||||
- If received: System is being configured
|
||||
- Component logs this state
|
||||
|
||||
**Display Instruction Byte (monitoring):**
|
||||
```
|
||||
Bit Position: B7 B6 B5 B4 B3 B2 B1 B0
|
||||
Display Mode: D (B0: Display on=1 / off=0)
|
||||
Sleep Mode: W (B1: Sleep enable=1 / disable=0)
|
||||
SEG Control: S (B3: Seven-segment=1 / eight=0)
|
||||
Brightness: BR[2:0] (B5-B3: Brightness level 0-7)
|
||||
```
|
||||
|
||||
**Monitored Parameters:**
|
||||
- **Display On/Off:** Track whether display is active
|
||||
- **Brightness Level:** 0=1 level, 1=2 levels, ..., 7=8 levels (standard range)
|
||||
- **Display Mode:** 7-segment or 8-segment configuration
|
||||
- **Sleep Mode:** Whether sleep mode is enabled
|
||||
|
||||
### 3.4 Display Data Monitoring
|
||||
|
||||
Display data is written to RAM addresses on the AiP650E. The ESP32 intercepts these writes:
|
||||
|
||||
**RAM Address Mapping (Monitored):**
|
||||
```
|
||||
Address | Data Bits (B7-B0) | Display
|
||||
---------|-------------------------|---------
|
||||
0x68 | A B C D E F G DP | DIG1 (leftmost/hundreds)
|
||||
0x6A | A B C D E F G DP | DIG2 (middle/tens)
|
||||
0x6C | A B C D E F G DP | DIG3 (rightmost/ones)
|
||||
0x6E | (reserved) | DIG4 (not used for digits)
|
||||
```
|
||||
|
||||
**Segment Decoding:**
|
||||
- **A-G:** Standard 7-segment display segments (bits 0-6)
|
||||
- **DP:** Decimal point (bit 7)
|
||||
|
||||
When the component detects writes to these addresses, it:
|
||||
1. Captures the segment byte
|
||||
2. Decodes which digit is shown (0-9) based on segment pattern
|
||||
3. Reports the value as a sensor update
|
||||
4. Stores raw segment data for debug purposes
|
||||
|
||||
### 3.5 Key Press Monitoring
|
||||
|
||||
The original microcontroller can request key data from the AiP650E. The ESP32 intercepts these requests:
|
||||
|
||||
**Get Key Command (monitored):**
|
||||
```
|
||||
Bit: B7 B6 B5 B4 B3 B2 B1 B0
|
||||
Val: 0 1 0 0 1 X X 1 (0x49 with variable bits)
|
||||
```
|
||||
|
||||
**Key Data Response Format (captured):**
|
||||
```
|
||||
Format: 01_BBBKKKK (8 bits data + 1 ACK bit)
|
||||
- BBB: Button row (0-3 for DIG1-DIG4)
|
||||
- KKK: Button column (0-7 for KI1-KI7)
|
||||
- Special: 00_101_110 (0x2E) = No key pressed
|
||||
```
|
||||
|
||||
**Memory Button Status (via AiP650E monitoring):**
|
||||
|
||||
| Memory Button | AiP650E Row | AiP650E Column | Expected Value |
|
||||
|---------------|------------|----------------|----------------|
|
||||
| Mem 1 (K15 / KI5) | DIG4 (3) | KI5 (4) | `01_011_100` |
|
||||
| Mem 2 (K12 / KI2) | DIG4 (3) | KI2 (1) | `01_001_100` |
|
||||
| Mem 3 (K11 / KI1) | DIG4 (3) | KI1 (0) | `01_000_100` |
|
||||
| No Key | Any | - | `00_101_110` (0x2E) |
|
||||
|
||||
**Note:** Memory button monitoring via AiP650E is optional - direct physical button connections to ESP32 GPIO are more reliable.
|
||||
|
||||
**Memory Button Status (via AiP650E monitoring):**
|
||||
|
||||
| Memory Button | AiP650E Row | AiP650E Column | Expected Value |
|
||||
|---------------|------------|----------------|----------------|
|
||||
| Mem 1 (K15 / KI5) | DIG4 (3) | KI5 (4) | `01_011_100` |
|
||||
| Mem 2 (K12 / KI2) | DIG4 (3) | KI2 (1) | `01_001_100` |
|
||||
| Mem 3 (K11 / KI1) | DIG4 (3) | KI1 (0) | `01_000_100` |
|
||||
| No Key | Any | - | `00_101_110` (0x2E) |
|
||||
|
||||
**Note:** Memory button monitoring via AiP650E is optional - direct physical button connections to ESP32 GPIO are more reliable for the primary up/down buttons.
|
||||
|
||||
---
|
||||
|
||||
## 4. Component Specification
|
||||
|
||||
### 4.1 Component Name
|
||||
|
||||
```yaml
|
||||
display_driver_aip650e:
|
||||
```
|
||||
|
||||
### 4.2 Configuration Parameters
|
||||
|
||||
```yaml
|
||||
display_driver_aip650e:
|
||||
# Required: CLK and DIO pin definitions (listeners, not drivers)
|
||||
clk_pin: GPIO_PIN_NUMBER
|
||||
dio_pin: GPIO_PIN_NUMBER
|
||||
|
||||
# Optional: Button GPIO pins
|
||||
button_up_pin: GPIO_PIN_NUMBER # PIN 14 on original board (KEY_UP)
|
||||
button_down_pin: GPIO_PIN_NUMBER # PIN 13 on original board (KEY_DOWN)
|
||||
|
||||
# Optional: Display monitoring interval (default: 100ms)
|
||||
# How often to check for new display data from the original micro
|
||||
update_interval: 100ms
|
||||
|
||||
# Optional: Enable button monitoring (default: true)
|
||||
enable_buttons: true
|
||||
|
||||
# Optional: Debounce time for physical buttons (default: 50ms)
|
||||
button_debounce_time: 50ms
|
||||
|
||||
# Optional: AiP650E protocol monitoring settings
|
||||
protocol:
|
||||
# Attempt to decode memory buttons from AiP650E bus (default: false)
|
||||
# Set to true only if keeping original memory button hardware
|
||||
monitor_memory_buttons: false
|
||||
|
||||
# Communication timeout (default: 1000ms)
|
||||
# If no CLK edges detected for this duration, consider bus inactive
|
||||
timeout: 1000ms
|
||||
```
|
||||
|
||||
### 4.3 Exposed Sensors
|
||||
|
||||
#### 4.3.1 Display Value Sensor
|
||||
|
||||
Exposes the 3-digit height value being displayed by the original control board:
|
||||
|
||||
```yaml
|
||||
sensor:
|
||||
- platform: display_driver_aip650e
|
||||
name: "Standing Desk Height Display"
|
||||
id: desk_height_display
|
||||
unit_of_measurement: "mm"
|
||||
icon: "mdi:ruler-square"
|
||||
```
|
||||
|
||||
**Sensor Properties:**
|
||||
- **Type:** Numeric sensor
|
||||
- **Range:** 0-999 (3 digits)
|
||||
- **Update Rate:** Whenever the original microcontroller updates the display (typically 1-10 times per second)
|
||||
- **Source:** Decoded from segment data on 0x68, 0x6A, 0x6C RAM addresses
|
||||
- **Reliability:** Mirrors exactly what the original display shows
|
||||
|
||||
#### 4.3.2 Individual Digit Sensors
|
||||
|
||||
Optionally expose each digit separately:
|
||||
|
||||
```yaml
|
||||
sensor:
|
||||
- platform: display_driver_aip650e
|
||||
digit: 1 # DIG1 - hundreds
|
||||
name: "Desk Height - Hundreds"
|
||||
|
||||
- platform: display_driver_aip650e
|
||||
digit: 2 # DIG2 - tens
|
||||
name: "Desk Height - Tens"
|
||||
|
||||
- platform: display_driver_aip650e
|
||||
digit: 3 # DIG3 - ones
|
||||
name: "Desk Height - Ones"
|
||||
```
|
||||
|
||||
#### 4.3.3 Segment Data Sensor (Debug)
|
||||
|
||||
For troubleshooting, optionally expose raw segment data:
|
||||
|
||||
```yaml
|
||||
text_sensor:
|
||||
- platform: display_driver_aip650e
|
||||
name: "Display Raw Segments"
|
||||
id: raw_segments
|
||||
```
|
||||
|
||||
Returns segment data as: `"DIG1: ABCDEFGDP, DIG2: ..., DIG3: ..."`
|
||||
|
||||
#### 4.3.4 Display Control Status (Monitored)
|
||||
|
||||
Optional text sensor showing monitored control states:
|
||||
|
||||
```yaml
|
||||
text_sensor:
|
||||
- platform: display_driver_aip650e
|
||||
name: "Display Status"
|
||||
id: display_status
|
||||
```
|
||||
|
||||
Returns: `"on/off, brightness: X, mode: 7-seg/8-seg, ..."`
|
||||
|
||||
---
|
||||
|
||||
## 5. Button Interface
|
||||
|
||||
### 5.1 Physical Button Sensors
|
||||
|
||||
The component monitors the physical KEY_UP and KEY_DOWN buttons connected directly to the ESP32 GPIO:
|
||||
|
||||
```yaml
|
||||
binary_sensor:
|
||||
- platform: display_driver_aip650e
|
||||
name: "UP Button"
|
||||
id: key_up
|
||||
button: up # or specify: button_pin_name: up
|
||||
on_press:
|
||||
then:
|
||||
- logger.log: "UP button pressed"
|
||||
on_release:
|
||||
then:
|
||||
- logger.log: "UP button released"
|
||||
|
||||
- platform: display_driver_aip650e
|
||||
name: "DOWN Button"
|
||||
id: key_down
|
||||
button: down
|
||||
on_press:
|
||||
then:
|
||||
- logger.log: "DOWN button pressed"
|
||||
```
|
||||
|
||||
**Button Characteristics:**
|
||||
- **Type:** Binary sensor (pressed/released)
|
||||
- **Source:** Direct GPIO connection (pins 13, 14 on original board)
|
||||
- **Debounce:** Configurable (default 50ms)
|
||||
- **Update Rate:** Immediate on press/release
|
||||
|
||||
### 5.2 Optional Memory Button Monitoring
|
||||
|
||||
If the original memory button hardware is retained and connected to GPIO pins, they can be monitored:
|
||||
|
||||
```yaml
|
||||
binary_sensor:
|
||||
- platform: display_driver_aip650e
|
||||
name: "Memory Button 1"
|
||||
id: mem_button_1
|
||||
button: memory_1 # Optional: alternative to GPIO-based buttons
|
||||
on_press:
|
||||
then:
|
||||
- logger.log: "Memory 1 pressed"
|
||||
|
||||
- platform: display_driver_aip650e
|
||||
name: "Memory Button 2"
|
||||
id: mem_button_2
|
||||
button: memory_2
|
||||
|
||||
- platform: display_driver_aip650e
|
||||
name: "Memory Button 3"
|
||||
id: mem_button_3
|
||||
button: memory_3
|
||||
```
|
||||
|
||||
**Note:** Memory buttons are NOT decoded from the AiP650E bus by default (unreliable). Instead, they should be wired directly to GPIO pins if needed.
|
||||
|
||||
### 5.3 Button Configuration
|
||||
|
||||
```yaml
|
||||
display_driver_aip650e:
|
||||
# Physical button pins
|
||||
button_up_pin: GPIO14
|
||||
button_down_pin: GPIO13
|
||||
|
||||
# Optional memory button pins (if wired to ESP32)
|
||||
button_mem1_pin: GPIO_PIN # Optional
|
||||
button_mem2_pin: GPIO_PIN # Optional
|
||||
button_mem3_pin: GPIO_PIN # Optional
|
||||
|
||||
# Debouncing settings
|
||||
button_debounce_time: 50ms
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Display Monitoring & Integration
|
||||
|
||||
### 6.1 Real-Time Display Monitoring
|
||||
|
||||
The component continuously monitors the AiP650E communication bus and extracts display information in real-time:
|
||||
|
||||
- **Segment Capture:** Intercepts writes to display RAM (0x68, 0x6A, 0x6C)
|
||||
- **Digit Decoding:** Converts segment patterns to digit values (0-9)
|
||||
- **State Tracking:** Monitors brightness, display on/off status
|
||||
- **Update Rate:** Responds immediately to changes from original microcontroller
|
||||
|
||||
### 6.2 Integration with Touchscreen UI
|
||||
|
||||
The exposed sensors can be used to synchronize a touchscreen display with the original height information:
|
||||
|
||||
```yaml
|
||||
# Example: Display the monitored height on touchscreen
|
||||
display_runner:
|
||||
- id: my_display
|
||||
components:
|
||||
- lambda: |-
|
||||
it.printf(10, 10, id(font), "Height: %.0fmm", id(desk_height_display).state);
|
||||
```
|
||||
|
||||
### 6.3 Home Automation Integration
|
||||
|
||||
Button states can trigger automations:
|
||||
|
||||
```yaml
|
||||
automation:
|
||||
- trigger:
|
||||
platform: binary_sensor
|
||||
id: key_up
|
||||
action: press
|
||||
then:
|
||||
- logger.log: "User pressed UP - height increasing"
|
||||
- homeassistant.service:
|
||||
service: input_number.set_value
|
||||
data_template:
|
||||
entity_id: input_number.desk_height_setpoint
|
||||
value: "{{ (states('input_number.desk_height_actual') | float(0) + 10) | round(0) }}"
|
||||
```
|
||||
|
||||
### 6.4 Limitations & Constraints
|
||||
|
||||
⚠️ **Important Note:** The ESP32 component is a **passive listener only**:
|
||||
- ❌ Cannot control the display (original microcontroller is the master)
|
||||
- ❌ Cannot modify display values shown
|
||||
- ❌ Cannot control motor directly (connected to original microcontroller)
|
||||
- ✅ Can read what the original system is displaying
|
||||
- ✅ Can read button inputs
|
||||
- ✅ Can provide UI feedback via touchscreen
|
||||
|
||||
To control the motor or display, communicate with the original microcontroller via a separate interface (if available, e.g., UART, I²C).
|
||||
|
||||
---
|
||||
|
||||
## 7. Configuration Examples
|
||||
|
||||
### 7.1 Basic Configuration (Listener Mode)
|
||||
|
||||
```yaml
|
||||
esphome:
|
||||
name: standing-desk-controller
|
||||
|
||||
esp32_s3:
|
||||
board: esp32-s3-devkitc-1
|
||||
variant: esp32s3
|
||||
|
||||
# Display driver monitor component
|
||||
display_driver_aip650e:
|
||||
# Listen to SEGM_CLK and SEGM_DIO from original microcontroller
|
||||
clk_pin: GPIO16 # Connected to original board pin 16 (SEGM_CLK)
|
||||
dio_pin: GPIO15 # Connected to original board pin 15 (SEGM_DIO)
|
||||
|
||||
# Monitor physical buttons
|
||||
button_up_pin: GPIO14 # Connected to original board pin 14 (KEY_UP)
|
||||
button_down_pin: GPIO13 # Connected to original board pin 13 (KEY_DOWN)
|
||||
|
||||
# Update settings
|
||||
update_interval: 100ms
|
||||
button_debounce_time: 50ms
|
||||
|
||||
sensor:
|
||||
- platform: display_driver_aip650e
|
||||
name: "Desk Height Display"
|
||||
id: desk_height_display
|
||||
unit_of_measurement: "mm"
|
||||
icon: "mdi:ruler-square"
|
||||
|
||||
binary_sensor:
|
||||
- platform: display_driver_aip650e
|
||||
name: "UP Button"
|
||||
id: key_up
|
||||
button: up
|
||||
icon: "mdi:arrow-up"
|
||||
|
||||
- platform: display_driver_aip650e
|
||||
name: "DOWN Button"
|
||||
id: key_down
|
||||
button: down
|
||||
icon: "mdi:arrow-down"
|
||||
```
|
||||
|
||||
### 7.2 Advanced Configuration with Touchscreen Integration
|
||||
|
||||
```yaml
|
||||
esphome:
|
||||
name: standing-desk-esp32
|
||||
|
||||
esp32_s3:
|
||||
board: esp32-s3-devkitc-1
|
||||
variant: esp32s3
|
||||
psram:
|
||||
mode: quad
|
||||
speed: 80MHz
|
||||
|
||||
# Display driver monitor
|
||||
display_driver_aip650e:
|
||||
clk_pin: GPIO16
|
||||
dio_pin: GPIO15
|
||||
button_up_pin: GPIO14
|
||||
button_down_pin: GPIO13
|
||||
|
||||
update_interval: 50ms
|
||||
button_debounce_time: 75ms
|
||||
|
||||
protocol:
|
||||
timeout: 1000ms
|
||||
|
||||
# Touchscreen display
|
||||
spi:
|
||||
clk_pin: GPIO6
|
||||
mosi_pin: GPIO7
|
||||
miso_pin: GPIO8
|
||||
|
||||
display:
|
||||
- platform: ili9xxx
|
||||
id: my_display
|
||||
model: ILI9488
|
||||
cs_pin: GPIO5
|
||||
dc_pin: GPIO9
|
||||
reset_pin: GPIO10
|
||||
update_interval: 200ms
|
||||
|
||||
lambda: |-
|
||||
// Display the monitored height
|
||||
it.printf(160, 50, id(font_large), TextAlign::CENTER,
|
||||
"Height: %.0f mm", id(desk_height_display).state);
|
||||
|
||||
// Show button status
|
||||
if (id(key_up).state) {
|
||||
it.filled_rectangle(10, 120, 300, 50, COLOR_WHITE);
|
||||
it.printf(160, 145, id(font), TextAlign::CENTER, "UP PRESSED");
|
||||
}
|
||||
if (id(key_down).state) {
|
||||
it.filled_rectangle(10, 180, 300, 50, COLOR_WHITE);
|
||||
it.printf(160, 205, id(font), TextAlign::CENTER, "DOWN PRESSED");
|
||||
}
|
||||
|
||||
sensor:
|
||||
- platform: display_driver_aip650e
|
||||
name: "Desk Height Display"
|
||||
id: desk_height_display
|
||||
unit_of_measurement: "mm"
|
||||
icon: "mdi:ruler-square"
|
||||
on_value:
|
||||
then:
|
||||
- logger.log:
|
||||
format: "Display height updated to: %.0f mm"
|
||||
args: ['x']
|
||||
|
||||
- platform: display_driver_aip650e
|
||||
digit: 1
|
||||
name: "Height Hundreds"
|
||||
id: height_hundreds
|
||||
|
||||
- platform: display_driver_aip650e
|
||||
digit: 2
|
||||
name: "Height Tens"
|
||||
id: height_tens
|
||||
|
||||
- platform: display_driver_aip650e
|
||||
digit: 3
|
||||
name: "Height Ones"
|
||||
id: height_ones
|
||||
|
||||
text_sensor:
|
||||
- platform: display_driver_aip650e
|
||||
name: "Display Status"
|
||||
id: display_status
|
||||
|
||||
binary_sensor:
|
||||
- platform: display_driver_aip650e
|
||||
name: "UP Button"
|
||||
id: key_up
|
||||
button: up
|
||||
on_press:
|
||||
then:
|
||||
- logger.log: "UP button pressed - desk moving up"
|
||||
on_release:
|
||||
then:
|
||||
- logger.log: "UP button released"
|
||||
|
||||
- platform: display_driver_aip650e
|
||||
name: "DOWN Button"
|
||||
id: key_down
|
||||
button: down
|
||||
on_press:
|
||||
then:
|
||||
- logger.log: "DOWN button pressed - desk moving down"
|
||||
on_release:
|
||||
then:
|
||||
- logger.log: "DOWN button released"
|
||||
|
||||
# Home Assistant integration
|
||||
api:
|
||||
encryption:
|
||||
key: !secret api_key
|
||||
|
||||
ota:
|
||||
password: !secret ota_password
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_ssid
|
||||
password: !secret wifi_password
|
||||
|
||||
ap:
|
||||
ssid: "DeskScreen Fallback"
|
||||
password: !secret ap_password
|
||||
```
|
||||
|
||||
### 7.3 Minimal Configuration (Monitor Only, No Buttons)
|
||||
on_value:
|
||||
then:
|
||||
- logger.log:
|
||||
format: "Display height updated to: %.0f mm"
|
||||
args: ['x']
|
||||
|
||||
- platform: display_driver_aip650e
|
||||
digit: 1
|
||||
name: "Height Hundreds"
|
||||
id: height_hundreds
|
||||
|
||||
- platform: display_driver_aip650e
|
||||
digit: 2
|
||||
name: "Height Tens"
|
||||
id: height_tens
|
||||
|
||||
- platform: display_driver_aip650e
|
||||
digit: 3
|
||||
name: "Height Ones"
|
||||
id: height_ones
|
||||
|
||||
text_sensor:
|
||||
- platform: display_driver_aip650e
|
||||
name: "Display Status"
|
||||
id: display_status
|
||||
|
||||
binary_sensor:
|
||||
- platform: display_driver_aip650e
|
||||
name: "UP Button"
|
||||
id: key_up
|
||||
button: up
|
||||
on_press:
|
||||
then:
|
||||
- logger.log: "UP button pressed - desk moving up"
|
||||
on_release:
|
||||
then:
|
||||
- logger.log: "UP button released"
|
||||
|
||||
- platform: display_driver_aip650e
|
||||
name: "DOWN Button"
|
||||
id: key_down
|
||||
button: down
|
||||
on_press:
|
||||
then:
|
||||
- logger.log: "DOWN button pressed - desk moving down"
|
||||
on_release:
|
||||
then:
|
||||
- logger.log: "DOWN button released"
|
||||
|
||||
# Home Assistant integration
|
||||
api:
|
||||
encryption:
|
||||
key: !secret api_key
|
||||
|
||||
ota:
|
||||
password: !secret ota_password
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_ssid
|
||||
password: !secret wifi_password
|
||||
|
||||
ap:
|
||||
ssid: "DeskScreen Fallback"
|
||||
password: !secret ap_password
|
||||
```
|
||||
|
||||
### 7.3 Minimal Configuration (Monitor Only, No Buttons)
|
||||
|
||||
```yaml
|
||||
esphome:
|
||||
name: standing-desk-monitor
|
||||
|
||||
esp32_s3:
|
||||
board: esp32-s3-devkitc-1
|
||||
|
||||
display_driver_aip650e:
|
||||
clk_pin: GPIO16
|
||||
dio_pin: GPIO15
|
||||
# Note: button pins omitted - can be added later if needed
|
||||
|
||||
sensor:
|
||||
- platform: display_driver_aip650e
|
||||
name: "Desk Height"
|
||||
id: desk_height_display
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Data Structures
|
||||
|
||||
### 8.1 Segment Encoding
|
||||
|
||||
Standard 7-segment display layout:
|
||||
|
||||
```
|
||||
AAAA
|
||||
F B
|
||||
GGGG
|
||||
E C
|
||||
DDDD DP
|
||||
|
||||
Bit Mapping (byte):
|
||||
Bit 7: DP (decimal point)
|
||||
Bit 6: G (middle segment)
|
||||
Bit 5: F (top-left)
|
||||
Bit 4: E (bottom-left)
|
||||
Bit 3: D (bottom)
|
||||
Bit 2: C (bottom-right)
|
||||
Bit 1: B (top-right)
|
||||
Bit 0: A (top)
|
||||
```
|
||||
|
||||
### 8.2 7-Segment Character Set (Common)
|
||||
|
||||
| Char | Hex | Binary | Display |
|
||||
|------|-----|--------|---------|
|
||||
| 0 | 0x3F | 0011_1111 | 0 |
|
||||
| 1 | 0x06 | 0000_0110 | 1 |
|
||||
| 2 | 0x5B | 0101_1011 | 2 |
|
||||
| 3 | 0x4F | 0100_1111 | 3 |
|
||||
| 4 | 0x66 | 0110_0110 | 4 |
|
||||
| 5 | 0x6D | 0110_1101 | 5 |
|
||||
| 6 | 0x7D | 0111_1101 | 6 |
|
||||
| 7 | 0x07 | 0000_0111 | 7 |
|
||||
| 8 | 0x7F | 0111_1111 | 8 |
|
||||
| 9 | 0x6F | 0110_1111 | 9 |
|
||||
|
||||
### 8.3 Component Internal State
|
||||
|
||||
```yaml
|
||||
component_state:
|
||||
comm_protocol:
|
||||
clk_pin: GPIO number
|
||||
dio_pin: GPIO number
|
||||
last_clk_state: boolean
|
||||
last_dio_state: boolean
|
||||
comm_timeout: ms
|
||||
|
||||
display_state:
|
||||
digit1_segments: byte (0-255)
|
||||
digit2_segments: byte (0-255)
|
||||
digit3_segments: byte (0-255)
|
||||
brightness_level: 1-8
|
||||
power_on: boolean
|
||||
mode_7segment: boolean
|
||||
|
||||
button_state:
|
||||
button1_pressed: boolean
|
||||
button2_pressed: boolean
|
||||
button3_pressed: boolean
|
||||
debounce_counters: [0, 0, 0]
|
||||
last_key_value: byte
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Implementation Notes
|
||||
|
||||
### 9.1 Bus Listening & Protocol Decoding
|
||||
|
||||
- **No Active Driving:** ESP32 only reads CLK and DIO - does not drive them low (no open-drain output)
|
||||
- **GPIO Interrupt Handler:** Use CLK rising edge interrupt to trigger DIO sampling
|
||||
- **Timing Accuracy:** Sample DIO on CLK rising edges with ≥30ns setup margin
|
||||
- **Bit Shift Register:** Accumulate 8 bits per clock cycle, detect start/stop conditions
|
||||
|
||||
### 9.2 Hardware Connections
|
||||
|
||||
- **CLK & DIO Lines:** Connect directly from original microcontroller through appropriate level shifters (if voltage differs)
|
||||
- **Voltage Levels:** If original micro is 5V and ESP32 is 3.3V, use voltage divider or level shifter for DIO input
|
||||
- **Pull-ups:** CLK and DIO typically have internal or external pull-ups (10k) - no additional pull-ups needed on ESP32 side
|
||||
- **Ground:** Ensure common ground between original microcontroller and ESP32
|
||||
|
||||
### 9.3 Display Data Extraction
|
||||
|
||||
- **RAM Address Monitoring:** Intercept writes to addresses 0x68 (DIG1), 0x6A (DIG2), 0x6C (DIG3)
|
||||
- **Segment Decoding:** Convert captured segment bytes to 7-segment patterns, match against known digit set (0-9)
|
||||
- **Timing:** Updates happen naturally as the original micro commands the display - no polling required
|
||||
- **Jitter Reduction:** Debounce rapid segment changes (may indicate display refresh) before reporting state change
|
||||
|
||||
### 9.4 Button Input Handling
|
||||
|
||||
- **Physical Buttons (UP/DOWN):** Simple GPIO input with software debouncing
|
||||
- **Debounce Implementation:** Wait for 2 consecutive stable readings before reporting state change
|
||||
- **Debounce Duration:** Configurable, typically 50-75ms
|
||||
- **Optional Memory Buttons:** If wired to GPIO, use same debounce logic
|
||||
|
||||
### 9.5 Edge Cases & Error Handling
|
||||
|
||||
- **Bus Inactivity:** If no CLK transitions for > 1 second, consider bus inactive/error
|
||||
- **Partial Frames:** If data frame is incomplete, discard and wait for next frame
|
||||
- **ACK Bit Handling:** Don't generate ACK (ESP32 is listener only) - just skip bit 9
|
||||
- **Original Micro Disconnection:** Component gracefully handles loss of bus activity, reports "offline" status
|
||||
- **Voltage Spike Protection:** Add 100nF capacitor near GPIO inputs if experiencing noise
|
||||
|
||||
---
|
||||
|
||||
## 10. Troubleshooting Guide
|
||||
|
||||
| Issue | Likely Cause | Solution |
|
||||
|-------|-------------|----------|
|
||||
| No data received | Incorrect GPIO pins | Verify GPIO16 (CLK) and GPIO15 (DIO) are set correctly in config |
|
||||
| No data received | Hardware not connected | Check physical wiring: original micro pin 16→GPIO16, pin 15→GPIO15 |
|
||||
| No data received | Voltage levels | If original micro is 5V, add level shifter for DIO line |
|
||||
| Display values incorrect | Segment decoding error | Check 7-segment character set matches hardware (may use different convention) |
|
||||
| Display updates too slow | Bus monitoring timeout too high | Reduce `update_interval` config parameter |
|
||||
| Button presses not detected | Physical button wiring | Verify GPIO13/GPIO14 connected to KEY_DOWN/KEY_UP from original board |
|
||||
| Intermittent display reading | Electrical noise on CLK/DIO | Add 100nF capacitor from GPIO pins to GND; check wiring length/routing |
|
||||
| Bus detected but no display data | Original micro not sending | Original microcontroller may not be running; check its power and reset |
|
||||
| Memory button decoding fails | AiP650E not present | Memory button monitoring requires AiP650E to be connected (currently removed) |
|
||||
|
||||
---
|
||||
|
||||
## 11. Hardware Wiring Reference
|
||||
|
||||
### 11.1 GPIO Connection Map
|
||||
|
||||
| Function | Original Board | ESP32-S3 GPIO | Notes |
|
||||
|----------|----------------|---------------|-------|
|
||||
| Display Clock | Pin 16 (SEGM_CLK) | GPIO16 | CLK input (read only) |
|
||||
| Display Data | Pin 15 (SEGM_DIO) | GPIO15 | DIO input (read only) |
|
||||
| Up Button | Pin 14 (KEY_UP) | GPIO14 | Button input (optional) |
|
||||
| Down Button | Pin 13 (KEY_DOWN) | GPIO13 | Button input (optional) |
|
||||
| Ground | GND | GND | Common reference |
|
||||
|
||||
### 11.2 Level Shifting (if needed)
|
||||
|
||||
If original microcontroller operates at 5V and ESP32 at 3.3V:
|
||||
|
||||
```
|
||||
DIO Line (5V → 3.3V):
|
||||
5V source → [10k Ω] → GPIO15 (3.3V max)
|
||||
├→ [GND via 10k Ω]
|
||||
Result: voltage divider, ~2.5V on GPIO (safe for 3.3V input)
|
||||
|
||||
CLK Line:
|
||||
Same as DIO if switching at high frequency (>1 MHz)
|
||||
Direct connection OK if clock frequency < 100 kHz
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 12. Related Documents
|
||||
|
||||
- **Datasheet:** AiP650E-AX-XS-B037EN (Wuxi I-CORE Electronics)
|
||||
- **Reference:** 2-line Serial Interface / Common Cathode 8Seg 4Grid LED Controller/Driver
|
||||
- **Hardware:** Standing Desk Control Board (Original, with AiP650E physically removed)
|
||||
- **Integration:** ESP32-S3 with touchscreen UI
|
||||
- **Original System:** Microcontroller (32-bit) handling motor control and Hall sensors
|
||||
|
||||
---
|
||||
|
||||
## 13. Revision History
|
||||
|
||||
| Version | Date | Changes |
|
||||
|---------|------|---------|
|
||||
| 1.0 | 2026-04-23 | Initial specification (master-driven architecture) |
|
||||
| 2.0 | 2026-04-23 | Revised to listener-only architecture; ESP32 monitors bus instead of driving |
|
||||
|
||||
@@ -0,0 +1,480 @@
|
||||
# ESPHome Standing Desk Display Component
|
||||
## ATmega328P Proxy Architecture
|
||||
|
||||
**Version:** 3.1
|
||||
**Date:** April 2026
|
||||
**Platform:** ESP32-S3 + ATmega328P proxy
|
||||
**Protocol:** I2C (ATmega328P slave at 0x50)
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
This project uses an **ATmega328P microcontroller (28-pin) as a protocol proxy** to bridge the original desk controller's AiP650E display communication and memory keys to an ESP32-S3 running ESPHome.
|
||||
|
||||
**Architecture:**
|
||||
- **Original Desk Controller** → Sends CLK/DIO protocol + memory key signals
|
||||
- **ATmega328P Proxy** → Listens to CLK/DIO, reads memory keys, exposes I2C registers
|
||||
- **ESP32-S3** → Reads I2C registers, renders touchscreen UI, connects to Home Assistant
|
||||
|
||||
**Benefits:**
|
||||
- ✅ Timing-critical protocol capture isolated from ESP32 (no WiFi jitter)
|
||||
- ✅ Handles all 3 memory keys + common line (no ESP32 GPIO needed)
|
||||
- ✅ Serial debugging via UART (faster development)
|
||||
- ✅ Easy reprogramming via bootloader (after initial ISP)
|
||||
- ✅ Hardware I2C support (not bit-banged)
|
||||
- ✅ Minimal wiring (CLK/DIO + 3 keys + I2C + power)
|
||||
- ✅ Original motor control completely unaffected
|
||||
|
||||
---
|
||||
|
||||
## 1. Hardware Setup
|
||||
|
||||
### 1.1 ATmega328P Pin Assignment (28-pin QFN)
|
||||
|
||||
```
|
||||
┌─────────────┐
|
||||
PC6 ├───●───────┤ AVCC (pin 20)
|
||||
PD0 ├───────────┤ GND (pin 22)
|
||||
PD1 ├───────────┤ PC5
|
||||
PD2 ├───────────┤ PC4
|
||||
PD3 ├───────────┤ PC3
|
||||
PD4 ├───────────┤ PC2
|
||||
PD5 ├───────────┤ PC1
|
||||
PD6 ├───────────┤ PC0
|
||||
PD7 ├───────────┤ GND
|
||||
PB0 ├───────────┤ VCC
|
||||
PB1 ├───────────┤ PB2
|
||||
PB3 ├───────────┤ PB4
|
||||
PB5 ├───────────┤ PB6
|
||||
└─────────────┘
|
||||
```
|
||||
|
||||
| Pin # | Port | Function | Connect To | Notes |
|
||||
|-------|------|----------|-----------|-------|
|
||||
| 1 | PC6 | RESET | ISP Header (or button) | ISP programming reset |
|
||||
| 2 | PD0 | RXD | USB-UART TX (optional) | Serial debugging input |
|
||||
| 3 | PD1 | TXD | USB-UART RX (optional) | Serial debugging output |
|
||||
| 4 | PD2 | (spare) | — | Available for future use |
|
||||
| 5 | PD3 | (spare) | — | Available for future use |
|
||||
| 6 | PD4 | KEY_1 Input | Display Pin 13 | Memory key 1 input |
|
||||
| 7 | VCC | Power | ESP32 3.3V | Main power supply |
|
||||
| 8 | GND | Ground | Common GND | Ground reference |
|
||||
| 11 | PD5 | KEY_2 Input | Display Pin 9 | Memory key 2 input |
|
||||
| 12 | PD6 | KEY_3 Input | Display Pin 8 | Memory key 3 input |
|
||||
| 13 | PD7 | KEY_COMMON | Display Pin 7 | Memory key common line |
|
||||
| 14 | PB0 | SCL (I2C) | ESP32 GPIO21 | I2C Clock (4.7k pull-up to 3.3V) |
|
||||
| 15 | PB1 | SDA (I2C) | ESP32 GPIO20 | I2C Data (4.7k pull-up to 3.3V) |
|
||||
| 16 | PB2 | CLK Input | Display Pin 2 | Display protocol clock |
|
||||
| 17 | PB3 | MOSI (ISP) | ISP Header Pin 1 | SPI Data In (ISP only) |
|
||||
| 18 | PB4 | MISO (ISP) | ISP Header Pin 5 | SPI Data Out (ISP only) |
|
||||
| 19 | PB5 | SCK (ISP) | ISP Header Pin 3 | SPI Clock (ISP only) |
|
||||
| 20 | AVCC | Analog Ref | VCC + 0.1µF cap | Analog voltage reference |
|
||||
| 21 | PC1 | LED Output | LED Anode | Activity LED indicator (active HIGH) |
|
||||
| 22 | GND | Ground | Common GND | Ground reference |
|
||||
| 23 | PC0 | DIO Input | Display Pin 3 | Display protocol data |
|
||||
| 24 | PC2 | UP Button | Button to GND | UP button input (pull-up) |
|
||||
| 25 | PC3 | DOWN Button | Button to GND | DOWN button input (pull-up) |
|
||||
|
||||
**Key Layout Advantages:**
|
||||
- ✅ Protocol pins (CLK/DIO) on PB2/PC0 (safe from ISP)
|
||||
- ✅ Memory keys on PD4/5/6/7 (safe from ISP)
|
||||
- ✅ ISP pins (PB3/4/5) isolated and only used during programming
|
||||
- ✅ Serial debug on PD0/1 (useful for development)
|
||||
|
||||
### 1.2 Wiring Diagram
|
||||
|
||||
```
|
||||
┌──────────────────────────────┐ ┌──────────────────┐ ┌──────────────┐
|
||||
│ Display Driver Board │ │ ATmega328P │ │ ESP32-S3 │
|
||||
├──────────────────────────────┤ ├──────────────────┤ ├──────────────┤
|
||||
│ Pin 2 (CLK) ────────────────→├─→ │ Pin 16 PB2 │ │ │
|
||||
│ Pin 3 (DIO) ────────────────→├─→ │ Pin 23 PC0 │ │ │
|
||||
│ Pin 7 (KEY_COMMON) ─────────→├─→ │ Pin 13 PD7 │ │ │
|
||||
│ Pin 8 (KEY_3) ──────────────→├─→ │ Pin 12 PD6 │ │ │
|
||||
│ Pin 9 (KEY_2) ──────────────→├─→ │ Pin 11 PD5 │ │ │
|
||||
│ Pin 13 (KEY_1) ─────────────→├─→ │ Pin 6 PD4 │ │ │
|
||||
│ GND ────────────────────────→├─→ │ Pin 8 GND ──┬───→├──→ GND │
|
||||
│ │ │ Pin 21 PC1 ─┼──┐ │ │
|
||||
│ │ │ (LED → R ├─→└─┼→ +3.3V via R │
|
||||
│ │ │ Pin 24 PC2 ─┼──→├──→ UP Button │
|
||||
│ │ │ Pin 25 PC3 ─┼──→├──→ DOWN Button │
|
||||
│ │ │ Pin 14 PB0 ─┼──→├──→ GPIO21 (SCL) │
|
||||
│ │ │ (4.7k pull) │ │ │
|
||||
│ │ │ Pin 15 PB1 ─┼──→├──→ GPIO20 (SDA) │
|
||||
│ │ │ (4.7k pull) │ │ │
|
||||
│ │ │ Pin 7 VCC ◄─┴──→├──← GPIO 3.3V │
|
||||
│ │ │ │ │
|
||||
│ │ │ [ISP Header] │ │
|
||||
│ │ │ Pin 17 (MOSI) │ │
|
||||
│ │ │ Pin 18 (MISO) │ │
|
||||
│ │ │ Pin 19 (SCK) ────→ ISP Programmer │
|
||||
│ │ │ Pin 1 (RESET) │ │
|
||||
└──────────────────────────────┘ └──────────────────┘ └──────────────┘
|
||||
```
|
||||
|
||||
### 1.3 Bill of Materials
|
||||
|
||||
#### For Breadboard Prototype:
|
||||
| Part | Value | Qty | Cost | Notes |
|
||||
|------|-------|-----|------|-------|
|
||||
| ATmega328P | 28-pin QFN | 1 | $2-3 | Microchip or compatible |
|
||||
| Resistor | 4.7k | 2 | $0.20 | I2C pull-ups (3.3V side) |
|
||||
| Resistor | 330Ω | 1 | $0.05 | LED current limiting |
|
||||
| Resistor | 10k | 2 | $0.10 | Button pull-ups (optional) |
|
||||
| Capacitor | 100nF | 1 | $0.10 | Decoupling on VCC |
|
||||
| LED | Any color | 1 | $0.10 | Activity indicator |
|
||||
| Button | Tactile 6mm | 2 | $0.20 | UP and DOWN buttons |
|
||||
| **Total** | | | **$2.70-3.75** | Breadboard prototype |
|
||||
| Breadboard | — | 1 | $2-5 | For prototyping |
|
||||
| **Total** | | | **$5-15** | Estimated cost |
|
||||
|
||||
#### For Custom PCB Interposer:
|
||||
| Part | Value | Qty | Cost | Notes |
|
||||
|------|-------|-----|------|-------|
|
||||
| ATmega328P | 28-pin DIP/TQFP | 1 | $2-3 | Better for production |
|
||||
| Resistor | 4.7k | 2 | $0.10 | I2C pull-ups |
|
||||
| Resistor | 10k | 2 | $0.10 | LED resistors (optional) |
|
||||
| Capacitor | 100nF | 2 | $0.20 | Decoupling + AVCC filter |
|
||||
| **Connectors:** | | | | |
|
||||
| JST-SH4 (QWIIC) | — | 1 | $0.50 | I2C port (standard) |
|
||||
| 2×3 pin header | — | 1 | $0.20 | ISP programming header |
|
||||
| 1×6 pin header | — | 1 | $0.20 | Serial debug (optional) |
|
||||
| **Level Shifter** | TXB0104 | 1 | $0.80 | Shift 5V ↔ 3.3V (if needed) |
|
||||
| PCB | — | 1 | $5-15 | Small custom PCB |
|
||||
| **Total** | | | **$12-25** | Estimated cost |
|
||||
|
||||
**Notes:**
|
||||
- ISP header is required for initial firmware programming
|
||||
- Serial header enables easy reprogramming (after bootloader installed)
|
||||
- Level shifter needed only if running ATmega at 5V with 3.3V ESP32
|
||||
- QWIIC port provides standardized I2C connector
|
||||
|
||||
### 1.4 Interposer PCB Design Checklist
|
||||
|
||||
When designing the custom PCB, include:
|
||||
|
||||
- ✅ **Main Components:**
|
||||
- [ ] ATmega328P in 28-pin DIP or TQFP-32 package
|
||||
- [ ] 100nF decoupling capacitor across VCC/GND
|
||||
- [ ] 4.7k pull-up resistors on I2C lines (if not on ESP32 board)
|
||||
|
||||
- ✅ **Programming Headers:**
|
||||
- [ ] 6-pin ISP header (2×3 pin spacing, labeled clearly)
|
||||
- [ ] 6-pin serial FTDI header (for bootloader reprogramming)
|
||||
- [ ] Label each header with pin numbers (1-6)
|
||||
|
||||
- ✅ **External Connectors:**
|
||||
- [ ] JST-SH4 connector for QWIIC I2C (front-facing)
|
||||
- [ ] 4-pin header for CLK/DIO from original micro
|
||||
- [ ] 4-pin header for UP/DOWN buttons (optional)
|
||||
|
||||
- ✅ **Layout:**
|
||||
- [ ] ISP header on edge of board for programmer access
|
||||
- [ ] Serial header nearby ISP for easy access
|
||||
- [ ] QWIIC port on opposite edge from ISP
|
||||
- [ ] Clear silk-screen labeling
|
||||
|
||||
- ✅ **Routing:**
|
||||
- [ ] Keep ISP traces short (< 1 inch)
|
||||
- [ ] 4.7k pull-ups on I2C, close to connector
|
||||
- [ ] Ground plane if possible (connects all GNDs together)
|
||||
- [ ] No high-speed traces near ISP/serial headers
|
||||
|
||||
---
|
||||
|
||||
## 2. I2C Protocol (ATtiny85 → ESP32-S3)
|
||||
|
||||
### 2.1 Register Map
|
||||
|
||||
**Address:** 0x50 (1010_0000 in 8-bit format)
|
||||
|
||||
| Offset | Name | Type | Access | Description |
|
||||
|--------|------|------|--------|-------------|
|
||||
| 0x00 | DIG1 | uint8 | R | Digit 1 (hundreds): 0-9 or 0xFF |
|
||||
| 0x01 | DIG2 | uint8 | R | Digit 2 (tens): 0-9 or 0xFF |
|
||||
| 0x02 | DIG3 | uint8 | R | Digit 3 (ones): 0-9 or 0xFF |
|
||||
| 0x03 | STAT | uint8 | R | Display status (power, brightness, mode) |
|
||||
| 0x10 | VERSION | uint8 | R | Firmware version (0x10 = v1.0) |
|
||||
| 0x11 | ERROR | uint8 | R | Error flags |
|
||||
|
||||
### 2.2 Register Details
|
||||
|
||||
**DIG1, DIG2, DIG3 (0x00, 0x01, 0x02) - Shadow RAM:**
|
||||
- **Range:** 0-9 (valid digit) or 0xFF (invalid/not available)
|
||||
- **Combined Value:** `display_mm = DIG1*100 + DIG2*10 + DIG3`
|
||||
- **Example:** If DIG1=2, DIG2=5, DIG3=0 → display shows "250"
|
||||
|
||||
⚠️ **Important: Shadow RAM Behavior**
|
||||
|
||||
These registers contain **persistent** display values, maintained by the ATtiny85 even when the original desk display blanks (power saving mode). This means:
|
||||
|
||||
- **Display is awake:** Registers show current desk height
|
||||
- **Display goes to sleep (blanks after timeout):** Registers continue showing last known height
|
||||
- Original display might show brightness=0 or blank segments
|
||||
- ESP32 still reads the height value (e.g., "250")
|
||||
- This prevents "NaN" or error readings on your touchscreen UI
|
||||
- **Display wakes up:** Registers update with any new height changes
|
||||
|
||||
**Example Timeline:**
|
||||
```
|
||||
Time 0: Desk at 250mm → DIG1=2, DIG2=5, DIG3=0
|
||||
Time 60s: Sleep timeout → Original display blanks
|
||||
Time 60s: ESP32 reads DIG1/2/3 → Still gets "250" (shadow RAM)
|
||||
Time 120s: User presses UP button → Display wakes to 275mm
|
||||
Time 120s: DIG1=2, DIG2=7, DIG3=5 (updated)
|
||||
```
|
||||
|
||||
**Benefits of Shadow RAM:**
|
||||
- ✅ No stale data on ESP32 touchscreen
|
||||
- ✅ Display blanking doesn't disrupt UI
|
||||
- ✅ Seamless height display during sleep mode
|
||||
|
||||
**STAT Byte (0x03):**
|
||||
```
|
||||
Bit 7 (MSB): Display Power (1=on, 0=off)
|
||||
Bit 6-4: Brightness Level (0-7, 7=brightest)
|
||||
Bit 3: SEG Mode (1=7-segment, 0=8-segment)
|
||||
Bit 2: Sleep Mode (1=enabled, 0=disabled)
|
||||
Bit 1-0: Reserved (always 0)
|
||||
```
|
||||
|
||||
**VERSION Byte (0x10):**
|
||||
- `0x10` = ATtiny85 firmware v1.0
|
||||
|
||||
**ERROR Byte (0x11):**
|
||||
```
|
||||
Bit 7: I2C Communication Error (1=error, 0=ok)
|
||||
Bit 6: Frame Timeout (1=no CLK >1sec, 0=ok)
|
||||
Bit 5: Malformed Protocol Frame (1=error, 0=ok)
|
||||
Bit 4: Segment Data Corruption (1=error, 0=ok)
|
||||
Bit 3-0: Reserved
|
||||
```
|
||||
|
||||
### 2.3 Example I2C Read (C++)
|
||||
|
||||
```cpp
|
||||
#include <Wire.h>
|
||||
|
||||
#define PROXY_ADDR 0x50
|
||||
|
||||
void setup() {
|
||||
Wire.begin();
|
||||
Serial.begin(115200);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
uint8_t dig1, dig2, dig3, stat, err;
|
||||
|
||||
// Read digit 1
|
||||
Wire.beginTransmission(PROXY_ADDR);
|
||||
Wire.write(0x00);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(PROXY_ADDR, 1);
|
||||
dig1 = Wire.read();
|
||||
|
||||
// Read digit 2
|
||||
Wire.beginTransmission(PROXY_ADDR);
|
||||
Wire.write(0x01);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(PROXY_ADDR, 1);
|
||||
dig2 = Wire.read();
|
||||
|
||||
// Read digit 3
|
||||
Wire.beginTransmission(PROXY_ADDR);
|
||||
Wire.write(0x02);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(PROXY_ADDR, 1);
|
||||
dig3 = Wire.read();
|
||||
|
||||
// Combine into height value
|
||||
if (dig1 != 0xFF && dig2 != 0xFF && dig3 != 0xFF) {
|
||||
uint16_t height = dig1 * 100 + dig2 * 10 + dig3;
|
||||
Serial.printf("Desk Height: %d mm\n", height);
|
||||
}
|
||||
|
||||
delay(100); // Poll every 100ms
|
||||
}
|
||||
```
|
||||
|
||||
### 2.4 Example ESPHome Config
|
||||
|
||||
```yaml
|
||||
esphome:
|
||||
name: standing-desk
|
||||
|
||||
esp32_s3:
|
||||
board: esp32-s3-devkitc-1
|
||||
|
||||
i2c:
|
||||
sda: GPIO20
|
||||
scl: GPIO21
|
||||
frequency: 100kHz
|
||||
|
||||
sensor:
|
||||
- platform: i2c
|
||||
name: "Desk Height (from proxy)"
|
||||
address: 0x50
|
||||
register: 0x00
|
||||
value_type: U8
|
||||
id: proxy_dig1
|
||||
unit_of_measurement: ""
|
||||
|
||||
- platform: i2c
|
||||
name: "Desk Height Digit 2"
|
||||
address: 0x50
|
||||
register: 0x01
|
||||
value_type: U8
|
||||
id: proxy_dig2
|
||||
|
||||
- platform: i2c
|
||||
name: "Desk Height Digit 3"
|
||||
address: 0x50
|
||||
register: 0x02
|
||||
value_type: U8
|
||||
id: proxy_dig3
|
||||
|
||||
- platform: template
|
||||
name: "Desk Height (mm)"
|
||||
unit_of_measurement: "mm"
|
||||
icon: "mdi:ruler"
|
||||
update_interval: 100ms
|
||||
lambda: |-
|
||||
uint16_t d1 = (uint8_t)id(proxy_dig1).state;
|
||||
uint16_t d2 = (uint8_t)id(proxy_dig2).state;
|
||||
uint16_t d3 = (uint8_t)id(proxy_dig3).state;
|
||||
if (d1 != 0xFF && d2 != 0xFF && d3 != 0xFF) {
|
||||
return d1 * 100 + d2 * 10 + d3;
|
||||
}
|
||||
return {};
|
||||
|
||||
binary_sensor:
|
||||
- platform: gpio
|
||||
name: "UP Button"
|
||||
pin: GPIO14
|
||||
icon: "mdi:arrow-up"
|
||||
|
||||
- platform: gpio
|
||||
name: "DOWN Button"
|
||||
pin: GPIO13
|
||||
icon: "mdi:arrow-down"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. ATtiny85 Firmware
|
||||
|
||||
See: **ATTINY85_PROXY_FIRMWARE.md** for complete firmware source code
|
||||
|
||||
**Key functions:**
|
||||
- CLK interrupt handler: Capture protocol bits
|
||||
- Frame parser: Decode AiP650E commands
|
||||
- I2C slave: Expose registers 0x00-0x11
|
||||
- Timeout detection: Set error flags on bus inactivity
|
||||
|
||||
**Compilation:**
|
||||
- Arduino IDE + ATtinyCore
|
||||
- 8 MHz internal clock
|
||||
- 3-4 KB flash used
|
||||
|
||||
---
|
||||
|
||||
## 4. Expected Display Values
|
||||
|
||||
The ATtiny85 decodes AiP650E segment data and converts to digits.
|
||||
|
||||
### 4.1 7-Segment Character Mapping
|
||||
|
||||
| Digit | Hex | Segments | Pattern |
|
||||
|-------|-----|----------|---------|
|
||||
| 0 | 0x3F | A,B,C,D,E,F | `█████▓` |
|
||||
| 1 | 0x06 | B,C | `░░█████` |
|
||||
| 2 | 0x5B | A,B,D,E,G | `█▓█▓██` |
|
||||
| 3 | 0x4F | A,B,C,D,G | `█▓███▓` |
|
||||
| 4 | 0x66 | B,C,F,G | `░░██████` |
|
||||
| 5 | 0x6D | A,C,D,F,G | `██▓███` |
|
||||
| 6 | 0x7D | A,C,D,E,F,G | `██▓███` |
|
||||
| 7 | 0x07 | A,B,C | `░░█████` |
|
||||
| 8 | 0x7F | A,B,C,D,E,F,G | `███████` |
|
||||
| 9 | 0x6F | A,B,C,D,F,G | `██████▓` |
|
||||
|
||||
### 4.2 Typical Display Values
|
||||
|
||||
- **Minimum height:** 000 (all zeros: 0 mm)
|
||||
- **Normal range:** 600-1200 (standing desk typical)
|
||||
- **Maximum height:** 999 (3 digits max)
|
||||
|
||||
---
|
||||
|
||||
## 5. Troubleshooting
|
||||
|
||||
### I2C Issues
|
||||
|
||||
| Problem | Cause | Solution |
|
||||
|---------|-------|----------|
|
||||
| I2C not responding | Wrong address or not started | Check address 0x50, verify Wire.begin() in ESP32 sketch |
|
||||
| Reads return 0xFF | Protocol not capturing | Check CLK/DIO connections, verify ATtiny85 power |
|
||||
| Intermittent I2C | Weak pull-ups | Use external 4.7k resistors on SCL/SDA |
|
||||
| ATtiny85 won't program | ISP speed too fast | Reduce ISP clock to <500kHz in programmer |
|
||||
|
||||
### Protocol Issues
|
||||
|
||||
| Problem | Cause | Solution |
|
||||
|---------|-------|----------|
|
||||
| Display values always 0xFF | CLK interrupt not firing | Check PB3 connected to original pin 16 |
|
||||
| Display values wrong | Segment decoder bug | Check 7-segment lookup table in firmware |
|
||||
| ERROR byte shows bit 6 (timeout) | Original micro not running | Power-cycle original control board |
|
||||
|
||||
### Expected Behavior - Display Blanking
|
||||
|
||||
This is **not** a problem - it's expected behavior!
|
||||
|
||||
**Scenario:** Your desk display goes dark after timeout (sleep mode)
|
||||
- **Original desk display:** Blank/dark (brightness=0)
|
||||
- **ESP32 touchscreen:** Still shows the height value (e.g., "250mm")
|
||||
- **Explanation:** Shadow RAM keeps the last valid value even when the physical display blanks
|
||||
|
||||
**Why this is good:**
|
||||
- ✅ Your touchscreen UI remains responsive and shows current height
|
||||
- ✅ No "NaN" or error messages on screen
|
||||
- ✅ User always knows the desk position, even at night with display off
|
||||
- ✅ When desk wakes up, both displays sync automatically
|
||||
|
||||
**If you DON'T see height on touchscreen while original display is blank:**
|
||||
- Check I2C pull-ups (4.7k resistors on SCL/SDA)
|
||||
- Verify ESP32 is polling DIG1/DIG2/DIG3 registers
|
||||
- Check ATtiny85 power supply (should be 3.3V)
|
||||
|
||||
---
|
||||
|
||||
## 6. Performance
|
||||
|
||||
- **I2C Read Time:** ~5-10ms per register
|
||||
- **Display Update Rate:** 10-100ms (based on original micro)
|
||||
- **ESP32 Poll Interval:** 100ms recommended
|
||||
- **Power Consumption (ATtiny85):** ~10-50mA depending on load
|
||||
|
||||
---
|
||||
|
||||
## 7. Future Enhancements
|
||||
|
||||
- [ ] Decode memory buttons from AiP650E key matrix
|
||||
- [ ] Add CRC8 checksum for data validation
|
||||
- [ ] Support dual-display setup (multiple ATtiny85 proxies)
|
||||
- [ ] Energy monitoring (motor current sense)
|
||||
- [ ] Watchdog timer for crash recovery
|
||||
|
||||
---
|
||||
|
||||
## 8. References
|
||||
|
||||
- **ATtiny85 Datasheet:** Microchip ATtiny85 (8-bit AVR)
|
||||
- **AiP650E Datasheet:** Wuxi I-CORE Electronics (attached in spec)
|
||||
- **ESPHome Documentation:** https://esphome.io
|
||||
- **Arduino ATtinyCore:** https://github.com/SpenceKonde/ATTinyCore
|
||||
|
||||
---
|
||||
|
||||
**Document Version:** 3.0
|
||||
**Last Updated:** April 2026
|
||||
|
||||
|
After Width: | Height: | Size: 25 KiB |
@@ -0,0 +1,667 @@
|
||||
{
|
||||
"board": {
|
||||
"3dviewports": [],
|
||||
"design_settings": {
|
||||
"defaults": {
|
||||
"apply_defaults_to_fp_barcodes": false,
|
||||
"apply_defaults_to_fp_dimensions": false,
|
||||
"apply_defaults_to_fp_fields": false,
|
||||
"apply_defaults_to_fp_shapes": false,
|
||||
"apply_defaults_to_fp_text": false,
|
||||
"board_outline_line_width": 0.05,
|
||||
"copper_line_width": 0.2,
|
||||
"copper_text_italic": false,
|
||||
"copper_text_size_h": 1.5,
|
||||
"copper_text_size_v": 1.5,
|
||||
"copper_text_thickness": 0.3,
|
||||
"copper_text_upright": false,
|
||||
"courtyard_line_width": 0.05,
|
||||
"dimension_precision": 4,
|
||||
"dimension_units": 3,
|
||||
"dimensions": {
|
||||
"arrow_length": 1270000,
|
||||
"extension_offset": 500000,
|
||||
"keep_text_aligned": true,
|
||||
"suppress_zeroes": true,
|
||||
"text_position": 0,
|
||||
"units_format": 0
|
||||
},
|
||||
"fab_line_width": 0.1,
|
||||
"fab_text_italic": false,
|
||||
"fab_text_size_h": 1.0,
|
||||
"fab_text_size_v": 1.0,
|
||||
"fab_text_thickness": 0.15,
|
||||
"fab_text_upright": false,
|
||||
"other_line_width": 0.1,
|
||||
"other_text_italic": false,
|
||||
"other_text_size_h": 1.0,
|
||||
"other_text_size_v": 1.0,
|
||||
"other_text_thickness": 0.15,
|
||||
"other_text_upright": false,
|
||||
"pads": {
|
||||
"drill": 0.8,
|
||||
"height": 1.27,
|
||||
"width": 2.54
|
||||
},
|
||||
"silk_line_width": 0.1,
|
||||
"silk_text_italic": false,
|
||||
"silk_text_size_h": 1.0,
|
||||
"silk_text_size_v": 1.0,
|
||||
"silk_text_thickness": 0.1,
|
||||
"silk_text_upright": false,
|
||||
"zones": {
|
||||
"border_display_style": 2,
|
||||
"border_hatch_pitch": 0.5,
|
||||
"corner_radius": 0.0,
|
||||
"corner_smoothing": 0,
|
||||
"fill_mode": 0,
|
||||
"hatch_gap": 1.5,
|
||||
"hatch_orientation": 0.0,
|
||||
"hatch_smoothing_level": 0,
|
||||
"hatch_smoothing_value": 0.1,
|
||||
"hatch_thickness": 1.0,
|
||||
"min_clearance": 0.2,
|
||||
"min_island_area": 10.0,
|
||||
"min_thickness": 0.25,
|
||||
"pad_connection": 1,
|
||||
"remove_islands": 0,
|
||||
"thermal_relief_gap": 0.5,
|
||||
"thermal_relief_spoke_width": 0.5
|
||||
}
|
||||
},
|
||||
"diff_pair_dimensions": [],
|
||||
"drc_exclusions": [],
|
||||
"meta": {
|
||||
"version": 2
|
||||
},
|
||||
"rule_severities": {
|
||||
"annular_width": "error",
|
||||
"clearance": "error",
|
||||
"connection_width": "warning",
|
||||
"copper_edge_clearance": "error",
|
||||
"copper_sliver": "warning",
|
||||
"courtyards_overlap": "error",
|
||||
"creepage": "error",
|
||||
"diff_pair_gap_out_of_range": "error",
|
||||
"diff_pair_uncoupled_length_too_long": "error",
|
||||
"drill_out_of_range": "error",
|
||||
"duplicate_footprints": "warning",
|
||||
"extra_footprint": "warning",
|
||||
"footprint": "error",
|
||||
"footprint_filters_mismatch": "ignore",
|
||||
"footprint_symbol_field_mismatch": "warning",
|
||||
"footprint_symbol_mismatch": "warning",
|
||||
"footprint_type_mismatch": "ignore",
|
||||
"hole_clearance": "error",
|
||||
"hole_to_hole": "warning",
|
||||
"holes_co_located": "warning",
|
||||
"invalid_outline": "error",
|
||||
"isolated_copper": "warning",
|
||||
"item_on_disabled_layer": "error",
|
||||
"items_not_allowed": "error",
|
||||
"length_out_of_range": "error",
|
||||
"lib_footprint_issues": "warning",
|
||||
"lib_footprint_mismatch": "warning",
|
||||
"malformed_courtyard": "error",
|
||||
"microvia_drill_out_of_range": "error",
|
||||
"mirrored_text_on_front_layer": "warning",
|
||||
"missing_courtyard": "ignore",
|
||||
"missing_footprint": "warning",
|
||||
"missing_tuning_profile": "warning",
|
||||
"net_conflict": "warning",
|
||||
"nonmirrored_text_on_back_layer": "warning",
|
||||
"npth_inside_courtyard": "ignore",
|
||||
"padstack": "warning",
|
||||
"pth_inside_courtyard": "ignore",
|
||||
"shorting_items": "error",
|
||||
"silk_edge_clearance": "warning",
|
||||
"silk_over_copper": "warning",
|
||||
"silk_overlap": "warning",
|
||||
"skew_out_of_range": "error",
|
||||
"solder_mask_bridge": "error",
|
||||
"starved_thermal": "error",
|
||||
"text_height": "warning",
|
||||
"text_on_edge_cuts": "error",
|
||||
"text_thickness": "warning",
|
||||
"through_hole_pad_without_hole": "error",
|
||||
"too_many_vias": "error",
|
||||
"track_angle": "error",
|
||||
"track_dangling": "warning",
|
||||
"track_not_centered_on_via": "ignore",
|
||||
"track_on_post_machined_layer": "error",
|
||||
"track_segment_length": "error",
|
||||
"track_width": "error",
|
||||
"tracks_crossing": "error",
|
||||
"tuning_profile_track_geometries": "ignore",
|
||||
"unconnected_items": "error",
|
||||
"unresolved_variable": "error",
|
||||
"via_dangling": "warning",
|
||||
"zones_intersect": "error"
|
||||
},
|
||||
"rules": {
|
||||
"max_error": 0.005,
|
||||
"min_clearance": 0.0,
|
||||
"min_connection": 0.0,
|
||||
"min_copper_edge_clearance": 0.5,
|
||||
"min_groove_width": 0.0,
|
||||
"min_hole_clearance": 0.25,
|
||||
"min_hole_to_hole": 0.25,
|
||||
"min_microvia_diameter": 0.2,
|
||||
"min_microvia_drill": 0.1,
|
||||
"min_resolved_spokes": 2,
|
||||
"min_silk_clearance": 0.0,
|
||||
"min_text_height": 0.8,
|
||||
"min_text_thickness": 0.08,
|
||||
"min_through_hole_diameter": 0.3,
|
||||
"min_track_width": 0.0,
|
||||
"min_via_annular_width": 0.1,
|
||||
"min_via_diameter": 0.5,
|
||||
"solder_mask_to_copper_clearance": 0.0,
|
||||
"use_height_for_length_calcs": true
|
||||
},
|
||||
"teardrop_options": [
|
||||
{
|
||||
"td_onpthpad": true,
|
||||
"td_onroundshapesonly": false,
|
||||
"td_onsmdpad": true,
|
||||
"td_ontrackend": false,
|
||||
"td_onvia": true
|
||||
}
|
||||
],
|
||||
"teardrop_parameters": [
|
||||
{
|
||||
"td_allow_use_two_tracks": true,
|
||||
"td_curve_segcount": 0,
|
||||
"td_height_ratio": 1.0,
|
||||
"td_length_ratio": 0.5,
|
||||
"td_maxheight": 2.0,
|
||||
"td_maxlen": 1.0,
|
||||
"td_on_pad_in_zone": false,
|
||||
"td_target_name": "td_round_shape",
|
||||
"td_width_to_size_filter_ratio": 0.9
|
||||
},
|
||||
{
|
||||
"td_allow_use_two_tracks": true,
|
||||
"td_curve_segcount": 0,
|
||||
"td_height_ratio": 1.0,
|
||||
"td_length_ratio": 0.5,
|
||||
"td_maxheight": 2.0,
|
||||
"td_maxlen": 1.0,
|
||||
"td_on_pad_in_zone": false,
|
||||
"td_target_name": "td_rect_shape",
|
||||
"td_width_to_size_filter_ratio": 0.9
|
||||
},
|
||||
{
|
||||
"td_allow_use_two_tracks": true,
|
||||
"td_curve_segcount": 0,
|
||||
"td_height_ratio": 1.0,
|
||||
"td_length_ratio": 0.5,
|
||||
"td_maxheight": 2.0,
|
||||
"td_maxlen": 1.0,
|
||||
"td_on_pad_in_zone": false,
|
||||
"td_target_name": "td_track_end",
|
||||
"td_width_to_size_filter_ratio": 0.9
|
||||
}
|
||||
],
|
||||
"track_widths": [],
|
||||
"tuning_pattern_settings": {
|
||||
"diff_pair_defaults": {
|
||||
"corner_radius_percentage": 80,
|
||||
"corner_style": 1,
|
||||
"max_amplitude": 1.0,
|
||||
"min_amplitude": 0.2,
|
||||
"single_sided": false,
|
||||
"spacing": 1.0
|
||||
},
|
||||
"diff_pair_skew_defaults": {
|
||||
"corner_radius_percentage": 80,
|
||||
"corner_style": 1,
|
||||
"max_amplitude": 1.0,
|
||||
"min_amplitude": 0.2,
|
||||
"single_sided": false,
|
||||
"spacing": 0.6
|
||||
},
|
||||
"single_track_defaults": {
|
||||
"corner_radius_percentage": 80,
|
||||
"corner_style": 1,
|
||||
"max_amplitude": 1.0,
|
||||
"min_amplitude": 0.2,
|
||||
"single_sided": false,
|
||||
"spacing": 0.6
|
||||
}
|
||||
},
|
||||
"via_dimensions": [],
|
||||
"zones_allow_external_fillets": false
|
||||
},
|
||||
"ipc2581": {
|
||||
"bom_rev": "",
|
||||
"dist": "",
|
||||
"distpn": "",
|
||||
"internal_id": "",
|
||||
"mfg": "",
|
||||
"mpn": "",
|
||||
"sch_revision": ""
|
||||
},
|
||||
"layer_pairs": [],
|
||||
"layer_presets": [],
|
||||
"viewports": []
|
||||
},
|
||||
"boards": [],
|
||||
"component_class_settings": {
|
||||
"assignments": [],
|
||||
"meta": {
|
||||
"version": 0
|
||||
},
|
||||
"sheet_component_classes": {
|
||||
"enabled": false
|
||||
}
|
||||
},
|
||||
"cvpcb": {
|
||||
"equivalence_files": []
|
||||
},
|
||||
"erc": {
|
||||
"erc_exclusions": [],
|
||||
"meta": {
|
||||
"version": 0
|
||||
},
|
||||
"pin_map": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
1,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
]
|
||||
],
|
||||
"rule_severities": {
|
||||
"bus_definition_conflict": "error",
|
||||
"bus_entry_needed": "error",
|
||||
"bus_to_bus_conflict": "error",
|
||||
"bus_to_net_conflict": "error",
|
||||
"different_unit_footprint": "error",
|
||||
"different_unit_net": "error",
|
||||
"duplicate_reference": "error",
|
||||
"duplicate_sheet_names": "error",
|
||||
"endpoint_off_grid": "warning",
|
||||
"extra_units": "error",
|
||||
"footprint_filter": "ignore",
|
||||
"footprint_link_issues": "warning",
|
||||
"four_way_junction": "ignore",
|
||||
"global_label_dangling": "warning",
|
||||
"hier_label_mismatch": "error",
|
||||
"label_dangling": "error",
|
||||
"label_multiple_wires": "warning",
|
||||
"lib_symbol_issues": "warning",
|
||||
"lib_symbol_mismatch": "warning",
|
||||
"missing_bidi_pin": "warning",
|
||||
"missing_input_pin": "warning",
|
||||
"missing_power_pin": "error",
|
||||
"missing_unit": "warning",
|
||||
"multiple_net_names": "warning",
|
||||
"net_not_bus_member": "warning",
|
||||
"no_connect_connected": "warning",
|
||||
"no_connect_dangling": "warning",
|
||||
"pin_not_connected": "error",
|
||||
"pin_not_driven": "error",
|
||||
"pin_to_pin": "warning",
|
||||
"power_pin_not_driven": "error",
|
||||
"same_local_global_label": "warning",
|
||||
"similar_label_and_power": "warning",
|
||||
"similar_labels": "warning",
|
||||
"similar_power": "warning",
|
||||
"simulation_model_issue": "ignore",
|
||||
"single_global_label": "ignore",
|
||||
"unannotated": "error",
|
||||
"unconnected_wire_endpoint": "warning",
|
||||
"unit_value_mismatch": "error",
|
||||
"unresolved_variable": "error",
|
||||
"wire_dangling": "error"
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"pinned_footprint_libs": [],
|
||||
"pinned_symbol_libs": []
|
||||
},
|
||||
"meta": {
|
||||
"filename": "deskscreen_adapter.kicad_pro",
|
||||
"version": 3
|
||||
},
|
||||
"net_settings": {
|
||||
"classes": [
|
||||
{
|
||||
"bus_width": 12,
|
||||
"clearance": 0.2,
|
||||
"diff_pair_gap": 0.25,
|
||||
"diff_pair_via_gap": 0.25,
|
||||
"diff_pair_width": 0.2,
|
||||
"line_style": 0,
|
||||
"microvia_diameter": 0.3,
|
||||
"microvia_drill": 0.1,
|
||||
"name": "Default",
|
||||
"pcb_color": "rgba(0, 0, 0, 0.000)",
|
||||
"priority": 2147483647,
|
||||
"schematic_color": "rgba(0, 0, 0, 0.000)",
|
||||
"track_width": 0.2,
|
||||
"tuning_profile": "",
|
||||
"via_diameter": 0.6,
|
||||
"via_drill": 0.3,
|
||||
"wire_width": 6
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"version": 5
|
||||
},
|
||||
"net_colors": null,
|
||||
"netclass_assignments": null,
|
||||
"netclass_patterns": []
|
||||
},
|
||||
"pcbnew": {
|
||||
"last_paths": {
|
||||
"gencad": "",
|
||||
"idf": "",
|
||||
"netlist": "",
|
||||
"plot": "",
|
||||
"pos_files": "",
|
||||
"specctra_dsn": "",
|
||||
"step": "",
|
||||
"svg": "",
|
||||
"vrml": ""
|
||||
},
|
||||
"page_layout_descr_file": ""
|
||||
},
|
||||
"schematic": {
|
||||
"annotate_start_num": 0,
|
||||
"bom_export_filename": "${PROJECTNAME}.csv",
|
||||
"bom_fmt_presets": [],
|
||||
"bom_fmt_settings": {
|
||||
"field_delimiter": ",",
|
||||
"keep_line_breaks": false,
|
||||
"keep_tabs": false,
|
||||
"name": "CSV",
|
||||
"ref_delimiter": ",",
|
||||
"ref_range_delimiter": "",
|
||||
"string_delimiter": "\""
|
||||
},
|
||||
"bom_presets": [],
|
||||
"bom_settings": {
|
||||
"exclude_dnp": false,
|
||||
"fields_ordered": [
|
||||
{
|
||||
"group_by": false,
|
||||
"label": "Reference",
|
||||
"name": "Reference",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": false,
|
||||
"label": "Qty",
|
||||
"name": "${QUANTITY}",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": true,
|
||||
"label": "Value",
|
||||
"name": "Value",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": true,
|
||||
"label": "DNP",
|
||||
"name": "${DNP}",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": true,
|
||||
"label": "Exclude from BOM",
|
||||
"name": "${EXCLUDE_FROM_BOM}",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": true,
|
||||
"label": "Exclude from Board",
|
||||
"name": "${EXCLUDE_FROM_BOARD}",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": true,
|
||||
"label": "Footprint",
|
||||
"name": "Footprint",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": false,
|
||||
"label": "Datasheet",
|
||||
"name": "Datasheet",
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"filter_string": "",
|
||||
"group_symbols": true,
|
||||
"include_excluded_from_bom": true,
|
||||
"name": "Default Editing",
|
||||
"sort_asc": true,
|
||||
"sort_field": "Reference"
|
||||
},
|
||||
"bus_aliases": {},
|
||||
"connection_grid_size": 50.0,
|
||||
"drawing": {
|
||||
"dashed_lines_dash_length_ratio": 12.0,
|
||||
"dashed_lines_gap_length_ratio": 3.0,
|
||||
"default_line_thickness": 6.0,
|
||||
"default_text_size": 50.0,
|
||||
"field_names": [],
|
||||
"intersheets_ref_own_page": false,
|
||||
"intersheets_ref_prefix": "",
|
||||
"intersheets_ref_short": false,
|
||||
"intersheets_ref_show": false,
|
||||
"intersheets_ref_suffix": "",
|
||||
"junction_size_choice": 3,
|
||||
"label_size_ratio": 0.375,
|
||||
"operating_point_overlay_i_precision": 3,
|
||||
"operating_point_overlay_i_range": "~A",
|
||||
"operating_point_overlay_v_precision": 3,
|
||||
"operating_point_overlay_v_range": "~V",
|
||||
"overbar_offset_ratio": 1.23,
|
||||
"pin_symbol_size": 25.0,
|
||||
"text_offset_ratio": 0.15
|
||||
},
|
||||
"legacy_lib_dir": "",
|
||||
"legacy_lib_list": [],
|
||||
"meta": {
|
||||
"version": 1
|
||||
},
|
||||
"net_format_name": "",
|
||||
"page_layout_descr_file": "",
|
||||
"plot_directory": "",
|
||||
"space_save_all_events": true,
|
||||
"spice_current_sheet_as_root": false,
|
||||
"spice_external_command": "spice \"%I\"",
|
||||
"spice_model_current_sheet_as_root": true,
|
||||
"spice_save_all_currents": false,
|
||||
"spice_save_all_dissipations": false,
|
||||
"spice_save_all_voltages": false,
|
||||
"subpart_first_id": 65,
|
||||
"subpart_id_separator": 0,
|
||||
"top_level_sheets": [
|
||||
{
|
||||
"filename": "deskscreen_adapter.kicad_sch",
|
||||
"name": "deskscreen_adapter",
|
||||
"uuid": "00000000-0000-0000-0000-000000000000"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sheets": [
|
||||
[
|
||||
"1de92549-a8bb-4f99-9872-286ef796370a",
|
||||
"Root"
|
||||
]
|
||||
],
|
||||
"text_variables": {},
|
||||
"tuning_profiles": {
|
||||
"meta": {
|
||||
"version": 0
|
||||
},
|
||||
"tuning_profiles_impedance_geometric": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
(kicad_pcb (version 20241229) (generator "pcbnew") (generator_version "9.0")
|
||||
)
|
||||
@@ -0,0 +1,417 @@
|
||||
{
|
||||
"board": {
|
||||
"3dviewports": [],
|
||||
"design_settings": {
|
||||
"defaults": {},
|
||||
"diff_pair_dimensions": [],
|
||||
"drc_exclusions": [],
|
||||
"rules": {},
|
||||
"track_widths": [],
|
||||
"via_dimensions": []
|
||||
},
|
||||
"ipc2581": {
|
||||
"dist": "",
|
||||
"distpn": "",
|
||||
"internal_id": "",
|
||||
"mfg": "",
|
||||
"mpn": ""
|
||||
},
|
||||
"layer_pairs": [],
|
||||
"layer_presets": [],
|
||||
"viewports": []
|
||||
},
|
||||
"boards": [],
|
||||
"cvpcb": {
|
||||
"equivalence_files": []
|
||||
},
|
||||
"erc": {
|
||||
"erc_exclusions": [],
|
||||
"meta": {
|
||||
"version": 0
|
||||
},
|
||||
"pin_map": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
1,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
]
|
||||
],
|
||||
"rule_severities": {
|
||||
"bus_definition_conflict": "error",
|
||||
"bus_entry_needed": "error",
|
||||
"bus_to_bus_conflict": "error",
|
||||
"bus_to_net_conflict": "error",
|
||||
"different_unit_footprint": "error",
|
||||
"different_unit_net": "error",
|
||||
"duplicate_reference": "error",
|
||||
"duplicate_sheet_names": "error",
|
||||
"endpoint_off_grid": "warning",
|
||||
"extra_units": "error",
|
||||
"footprint_filter": "ignore",
|
||||
"footprint_link_issues": "warning",
|
||||
"four_way_junction": "ignore",
|
||||
"global_label_dangling": "warning",
|
||||
"hier_label_mismatch": "error",
|
||||
"label_dangling": "error",
|
||||
"label_multiple_wires": "warning",
|
||||
"lib_symbol_issues": "warning",
|
||||
"lib_symbol_mismatch": "warning",
|
||||
"missing_bidi_pin": "warning",
|
||||
"missing_input_pin": "warning",
|
||||
"missing_power_pin": "error",
|
||||
"missing_unit": "warning",
|
||||
"multiple_net_names": "warning",
|
||||
"net_not_bus_member": "warning",
|
||||
"no_connect_connected": "warning",
|
||||
"no_connect_dangling": "warning",
|
||||
"pin_not_connected": "error",
|
||||
"pin_not_driven": "error",
|
||||
"pin_to_pin": "warning",
|
||||
"power_pin_not_driven": "error",
|
||||
"same_local_global_label": "warning",
|
||||
"similar_label_and_power": "warning",
|
||||
"similar_labels": "warning",
|
||||
"similar_power": "warning",
|
||||
"simulation_model_issue": "ignore",
|
||||
"single_global_label": "ignore",
|
||||
"unannotated": "error",
|
||||
"unconnected_wire_endpoint": "warning",
|
||||
"unit_value_mismatch": "error",
|
||||
"unresolved_variable": "error",
|
||||
"wire_dangling": "error"
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"pinned_footprint_libs": [],
|
||||
"pinned_symbol_libs": []
|
||||
},
|
||||
"meta": {
|
||||
"filename": "deskscreen_reverse.kicad_pro",
|
||||
"version": 3
|
||||
},
|
||||
"net_settings": {
|
||||
"classes": [
|
||||
{
|
||||
"bus_width": 12,
|
||||
"clearance": 0.2,
|
||||
"diff_pair_gap": 0.25,
|
||||
"diff_pair_via_gap": 0.25,
|
||||
"diff_pair_width": 0.2,
|
||||
"line_style": 0,
|
||||
"microvia_diameter": 0.3,
|
||||
"microvia_drill": 0.1,
|
||||
"name": "Default",
|
||||
"pcb_color": "rgba(0, 0, 0, 0.000)",
|
||||
"priority": 2147483647,
|
||||
"schematic_color": "rgba(0, 0, 0, 0.000)",
|
||||
"track_width": 0.2,
|
||||
"via_diameter": 0.6,
|
||||
"via_drill": 0.3,
|
||||
"wire_width": 6
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"version": 4
|
||||
},
|
||||
"net_colors": null,
|
||||
"netclass_assignments": null,
|
||||
"netclass_patterns": []
|
||||
},
|
||||
"pcbnew": {
|
||||
"last_paths": {
|
||||
"gencad": "",
|
||||
"idf": "",
|
||||
"netlist": "",
|
||||
"plot": "",
|
||||
"pos_files": "",
|
||||
"specctra_dsn": "",
|
||||
"step": "",
|
||||
"svg": "",
|
||||
"vrml": ""
|
||||
},
|
||||
"page_layout_descr_file": ""
|
||||
},
|
||||
"schematic": {
|
||||
"annotate_start_num": 0,
|
||||
"bom_export_filename": "${PROJECTNAME}.csv",
|
||||
"bom_fmt_presets": [],
|
||||
"bom_fmt_settings": {
|
||||
"field_delimiter": ",",
|
||||
"keep_line_breaks": false,
|
||||
"keep_tabs": false,
|
||||
"name": "CSV",
|
||||
"ref_delimiter": ",",
|
||||
"ref_range_delimiter": "",
|
||||
"string_delimiter": "\""
|
||||
},
|
||||
"bom_presets": [],
|
||||
"bom_settings": {
|
||||
"exclude_dnp": false,
|
||||
"fields_ordered": [
|
||||
{
|
||||
"group_by": false,
|
||||
"label": "Reference",
|
||||
"name": "Reference",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": false,
|
||||
"label": "Qty",
|
||||
"name": "${QUANTITY}",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": true,
|
||||
"label": "Value",
|
||||
"name": "Value",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": true,
|
||||
"label": "DNP",
|
||||
"name": "${DNP}",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": true,
|
||||
"label": "Exclude from BOM",
|
||||
"name": "${EXCLUDE_FROM_BOM}",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": true,
|
||||
"label": "Exclude from Board",
|
||||
"name": "${EXCLUDE_FROM_BOARD}",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": true,
|
||||
"label": "Footprint",
|
||||
"name": "Footprint",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": false,
|
||||
"label": "Datasheet",
|
||||
"name": "Datasheet",
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"filter_string": "",
|
||||
"group_symbols": true,
|
||||
"include_excluded_from_bom": true,
|
||||
"name": "Default Editing",
|
||||
"sort_asc": true,
|
||||
"sort_field": "Reference"
|
||||
},
|
||||
"connection_grid_size": 50.0,
|
||||
"drawing": {
|
||||
"dashed_lines_dash_length_ratio": 12.0,
|
||||
"dashed_lines_gap_length_ratio": 3.0,
|
||||
"default_line_thickness": 6.0,
|
||||
"default_text_size": 50.0,
|
||||
"field_names": [],
|
||||
"intersheets_ref_own_page": false,
|
||||
"intersheets_ref_prefix": "",
|
||||
"intersheets_ref_short": false,
|
||||
"intersheets_ref_show": false,
|
||||
"intersheets_ref_suffix": "",
|
||||
"junction_size_choice": 3,
|
||||
"label_size_ratio": 0.375,
|
||||
"operating_point_overlay_i_precision": 3,
|
||||
"operating_point_overlay_i_range": "~A",
|
||||
"operating_point_overlay_v_precision": 3,
|
||||
"operating_point_overlay_v_range": "~V",
|
||||
"overbar_offset_ratio": 1.23,
|
||||
"pin_symbol_size": 25.0,
|
||||
"text_offset_ratio": 0.15
|
||||
},
|
||||
"legacy_lib_dir": "",
|
||||
"legacy_lib_list": [],
|
||||
"meta": {
|
||||
"version": 1
|
||||
},
|
||||
"net_format_name": "",
|
||||
"page_layout_descr_file": "",
|
||||
"plot_directory": "",
|
||||
"space_save_all_events": true,
|
||||
"spice_current_sheet_as_root": false,
|
||||
"spice_external_command": "spice \"%I\"",
|
||||
"spice_model_current_sheet_as_root": true,
|
||||
"spice_save_all_currents": false,
|
||||
"spice_save_all_dissipations": false,
|
||||
"spice_save_all_voltages": false,
|
||||
"subpart_first_id": 65,
|
||||
"subpart_id_separator": 0
|
||||
},
|
||||
"sheets": [
|
||||
[
|
||||
"e21673b6-3707-46b7-bb4a-b26eb6945d18",
|
||||
"Root"
|
||||
]
|
||||
],
|
||||
"text_variables": {}
|
||||
}
|
||||
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 1.7 MiB |
|
After Width: | Height: | Size: 4.4 MiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 9.9 MiB |
|
After Width: | Height: | Size: 9.0 MiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 1.7 MiB |
@@ -0,0 +1 @@
|
||||
51.694275, 5.271728
|
||||