diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index f2bbb68..c86f2de 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,6 +1,6 @@ idf_component_register(SRCS "main.c" "draw.c" "ble.c" "game.c" INCLUDE_DIRS "." - PRIV_REQUIRES driver nvs_flash bt vfs) + PRIV_REQUIRES driver nvs_flash bt vfs esp_adc) if(DEBUG) target_compile_definitions(${COMPONENT_LIB} PUBLIC DEBUG) diff --git a/main/ble.c b/main/ble.c index 42f49c9..e16b98a 100644 --- a/main/ble.c +++ b/main/ble.c @@ -12,7 +12,6 @@ volatile int g_ble_scanning; volatile int g_ble_initialized; uint8_t g_own_addr_type; uint8_t g_own_addr[6]; -uint8_t g_player_id = 0xFF; volatile int g_reset_requested; int g_reset_cmd_ticks; @@ -29,10 +28,7 @@ static void ble_adv_start_internal(void) payload.life = (int16_t)g_life; payload.poison = (uint8_t)g_counters[0]; payload.eliminated = (uint8_t)g_eliminated; - payload.player_id = g_player_id; payload.reset_cmd = (g_reset_cmd_ticks > 0) ? 1 : 0; - for (int i = 0; i < MAX_OPPONENTS; i++) - payload.cmdr_dmg[i] = (uint8_t)g_cmdr_damage[i]; static uint8_t mfr[2 + sizeof(ble_payload_t)]; mfr[0] = 0xFF; mfr[1] = 0xFF; @@ -51,10 +47,10 @@ static void ble_adv_start_internal(void) ble_gap_adv_start(g_own_addr_type, NULL, BLE_HS_FOREVER, ¶ms, ble_gap_event_handler, NULL); #ifdef DEBUG - printf("DBG ADV_TX name=%-8.8s life=%d poison=%u game_id=%02X%02X eliminated=%u pid=%u reset=%u\n", + printf("DBG ADV_TX name=%-8.8s life=%d poison=%u game_id=%02X%02X eliminated=%u reset=%u\n", payload.name, (int)payload.life, (unsigned)payload.poison, payload.game_id[0], payload.game_id[1], (unsigned)payload.eliminated, - (unsigned)payload.player_id, (unsigned)payload.reset_cmd); + (unsigned)payload.reset_cmd); fflush(stdout); #endif } @@ -91,9 +87,7 @@ static void ble_update_peer(const ble_addr_t *addr, const ble_payload_t *p) g_peers[slot].life = p->life; g_peers[slot].poison = p->poison; g_peers[slot].eliminated = p->eliminated; - g_peers[slot].player_id = p->player_id; g_peers[slot].reset_cmd = p->reset_cmd; - memcpy(g_peers[slot].cmdr_dmg, p->cmdr_dmg, MAX_OPPONENTS); g_peers[slot].last_seen = g_tick; g_peers[slot].active = 1; memcpy(g_peers[slot].name, p->name, PLAYER_NAME_LEN); @@ -101,15 +95,13 @@ static void ble_update_peer(const ble_addr_t *addr, const ble_payload_t *p) if (p->reset_cmd && !prev_reset_cmd) g_reset_requested = 1; #ifdef DEBUG - printf("DBG PEER_RX slot=%d addr=%02X:%02X:%02X:%02X:%02X:%02X name=%-8.8s life=%d poison=%u game_id=%02X%02X eliminated=%u pid=%u reset=%u cmdr=[%u,%u,%u,%u]\n", + printf("DBG PEER_RX slot=%d addr=%02X:%02X:%02X:%02X:%02X:%02X name=%-8.8s life=%d poison=%u game_id=%02X%02X eliminated=%u reset=%u\n", slot, addr->val[5], addr->val[4], addr->val[3], addr->val[2], addr->val[1], addr->val[0], p->name, (int)p->life, (unsigned)p->poison, p->game_id[0], p->game_id[1], (unsigned)p->eliminated, - (unsigned)p->player_id, (unsigned)p->reset_cmd, - (unsigned)p->cmdr_dmg[0], (unsigned)p->cmdr_dmg[1], - (unsigned)p->cmdr_dmg[2], (unsigned)p->cmdr_dmg[3]); + (unsigned)p->reset_cmd); fflush(stdout); #endif } @@ -143,7 +135,6 @@ static void ble_on_sync(void) { ble_hs_id_infer_auto(0, &g_own_addr_type); ble_hs_id_copy_addr(g_own_addr_type, g_own_addr, NULL); - if (g_player_id == 0xFF) g_player_id = 0; g_ble_initialized = 1; if (g_ble_enabled) ble_adv_start_internal(); } @@ -182,29 +173,6 @@ static void ble_manager_task(void *arg) } } -void player_id_resolve(void) -{ - if (!g_ble_initialized || !g_ble_enabled) return; - for (int i = 0; i < MAX_BLE_PEERS; i++) { - if (!g_peers[i].active || g_peers[i].player_id != g_player_id) continue; - int we_lose = 0; - for (int b = 5; b >= 0; b--) { - if (g_peers[i].addr.val[b] < g_own_addr[b]) { we_lose = 1; break; } - if (g_peers[i].addr.val[b] > g_own_addr[b]) break; - } - if (!we_lose) continue; - uint8_t used[BLE_MAX_PLAYERS] = {0}; - for (int j = 0; j < MAX_BLE_PEERS; j++) - if (g_peers[j].active && g_peers[j].player_id < BLE_MAX_PLAYERS) - used[g_peers[j].player_id] = 1; - for (int id = 0; id < BLE_MAX_PLAYERS; id++) { - if (!used[id]) { g_player_id = (uint8_t)id; break; } - } - ble_adv_update(); - break; - } -} - void ble_init(void) { nimble_port_init(); diff --git a/main/ble.h b/main/ble.h index 22315dc..d88dbd6 100644 --- a/main/ble.h +++ b/main/ble.h @@ -10,9 +10,7 @@ typedef struct __attribute__((packed)) { int16_t life; uint8_t poison; uint8_t eliminated; - uint8_t player_id; uint8_t reset_cmd; - uint8_t cmdr_dmg[MAX_OPPONENTS]; } ble_payload_t; typedef struct { @@ -21,9 +19,7 @@ typedef struct { int16_t life; uint8_t poison; uint8_t eliminated; - uint8_t player_id; uint8_t reset_cmd; - uint8_t cmdr_dmg[MAX_OPPONENTS]; uint32_t last_seen; int active; } ble_peer_t; @@ -32,10 +28,8 @@ extern volatile int g_ble_scanning; extern volatile int g_ble_initialized; extern uint8_t g_own_addr_type; extern uint8_t g_own_addr[6]; -extern uint8_t g_player_id; extern volatile int g_reset_requested; extern int g_reset_cmd_ticks; void ble_init(void); void ble_adv_update(void); -void player_id_resolve(void); diff --git a/main/config.h b/main/config.h index ae0f508..4c10b5a 100644 --- a/main/config.h +++ b/main/config.h @@ -34,21 +34,26 @@ #define BLE_MFR_MAGIC_1 0xDE #define BLE_GAME_ID_0 0x42 #define BLE_GAME_ID_1 0x42 -#define BLE_MAX_PLAYERS 5 #define MAX_BLE_PEERS 4 #define BLE_PEER_TIMEOUT 3000 // ── Menus ───────────────────────────────────────────────────────────────────── -#define NUM_MENUS 4 +#define NUM_MENUS 5 #define MENU_LIFE 0 #define MENU_CMDR 1 #define MENU_COUNTERS 2 -#define MENU_SETTINGS 3 +#define MENU_DICE 3 +#define MENU_SETTINGS 4 extern const int menu_slot[NUM_MENUS]; +// ── Dice ────────────────────────────────────────────────────────────────────── +#define DICE_CSV_LEN 128 +#define NUM_DICE_SIDES 7 +extern const int die_sides[NUM_DICE_SIDES]; + // ── Settings ────────────────────────────────────────────────────────────────── -#define NUM_SETTINGS 12 +#define NUM_SETTINGS 13 #define SET_BRIGHTNESS 0 #define SET_START_LIFE 1 #define SET_NUM_OPP 2 @@ -61,6 +66,7 @@ extern const int menu_slot[NUM_MENUS]; #define SET_LR_HOLD 9 #define SET_DISPLAY_FLIP 10 #define SET_DELTA_TIMEOUT 11 +#define SET_AUTO_SLEEP 12 #define HOLD_MS_MIN 50 #define HOLD_MS_MAX 2000 #define DELTA_TIMEOUT_MIN 100 @@ -97,6 +103,14 @@ extern const char *counter_names[NUM_COUNTERS]; #define FONT_BASE 0x20 #define FONT_MAX 0x5A +// ── Battery ADC (GPIO34, ADC1 Channel 6) ────────────────────────────────────── +#define BATT_LOW_PCT 10 // flash battery indicator below this +#define BATT_SAMPLE_TICKS 500 // sample every 500 × 10ms = 5s + +// ── Auto-sleep ──────────────────────────────────────────────────────────────── +#define SLEEP_TIMEOUT_DEF 60 // default auto-sleep timeout (minutes) +#define SLEEP_TIMEOUT_MAX 120 // maximum timeout (minutes) + // ── NVS ─────────────────────────────────────────────────────────────────────── #define NVS_NS "settings" #define SAVE_DELAY 300 diff --git a/main/draw.c b/main/draw.c index 5ccc482..7545747 100644 --- a/main/draw.c +++ b/main/draw.c @@ -9,11 +9,13 @@ #include #include -const int menu_slot[NUM_MENUS] = {0, 1, 2, 7}; +const int menu_slot[NUM_MENUS] = {0, 1, 2, 3, 7}; +const int die_sides[NUM_DICE_SIDES] = {4, 6, 8, 10, 12, 20, 100}; const char *setting_names[NUM_SETTINGS] = { "LED BRIGHTNESS", "STARTING LIFE", "NUM OPPONENTS", "BLE", "RESET", "RESET ALL", "GAME ID", "PLAYER NAME", "MENU HOLD MS", "LR HOLD MS", "FLIP DISPLAY", "DELTA TIMEOUT", + "AUTO SLEEP", }; #define LEDC_TIMER_SEL LEDC_TIMER_0 @@ -149,6 +151,53 @@ void oled_draw_header(void) pages[1][sx+col] = bg ^ icon[1][col]; } } + // Slot 5 (cols 80-95): percentage text, page 0 + // Slot 6 (cols 96-111): vertical battery icon, nub at top, fill from bottom + if (g_battery_pct >= 0) { + int show = (g_battery_pct >= BATT_LOW_PCT || (g_tick / 50) % 2 == 0); + + if (show) { + // ── Percentage text, vertically centered (rows 4-11) ───────────── + char pct_str[5]; + int plen = snprintf(pct_str, sizeof(pct_str), "%d", g_battery_pct); + int tx = 5 * SEG_W + (SEG_W - plen * 5) / 2; + for (int ci = 0; ci < plen; ci++) { + uint8_t c = (uint8_t)pct_str[ci]; + if (c < FONT_BASE || c > FONT_MAX) continue; + const uint8_t *glyph = font5x8[c - FONT_BASE]; + for (int sc = 0; sc < 5; sc++, tx++) { + if (tx < 0 || tx >= OLED_WIDTH) continue; + pages[0][tx] &= ~(uint8_t)(glyph[sc] << 4); // font bits 0-3 → rows 4-7 + pages[1][tx] &= ~(uint8_t)(glyph[sc] >> 4); // font bits 4-7 → rows 8-11 + } + } + + // ── Vertical battery icon ───────────────────────────────────────── + // 1px inset from slot edges: body cols 2-13, rows 3-14. + // Nub: cols 5-10, rows 1-2. + // Inner: cols 3-12, rows 4-13 (10 rows). Fill rises from bottom. + int fill_rows = g_battery_pct * 10 / 100; + int fill_start = 14 - fill_rows; // first filled inner row + uint8_t p0_fill = 0, p1_fill = 0; + for (int r = 4; r <= 7; r++) if (r >= fill_start) p0_fill |= (1 << r); + for (int r = 8; r <= 13; r++) if (r >= fill_start) p1_fill |= (1 << (r-8)); + + int bbase = 6 * SEG_W; + for (int x = 0; x < 16; x++) { + uint8_t p0 = 0, p1 = 0; + if (x == 2 || x == 13) { + p0 = 0xF8; p1 = 0x7F; // side borders rows 3-14 + } else if (x >= 3 && x <= 12) { + p0 = 0x08 | p0_fill; // top border (row 3) + fill + p1 = 0x40 | p1_fill; // bottom border (row 14) + fill + } + if (x >= 5 && x <= 10) p0 |= 0x06; // nub rows 1-2 + pages[0][bbase + x] &= ~p0; + pages[1][bbase + x] &= ~p1; + } + } + } + for (int p = 0; p < HEADER_PAGES; p++) oled_write_page(p, pages[p]); } @@ -237,8 +286,8 @@ static void fill_cols(uint8_t pages[][OLED_WIDTH], int content_h, // 5×8 mini-icons (vertical-byte, bit0=top), same format as font5x8 columns. // Teardrop: pointed top, round bottom (for poison) static const uint8_t icon_mini_drop[5] = {0x3C, 0x7E, 0x7F, 0x7E, 0x3C}; -// Lightning bolt: zigzag (for storm) -static const uint8_t icon_mini_bolt[5] = {0x0C, 0x0E, 0x1F, 0x39, 0x70}; +// Lightning bolt: thin zigzag from center-top with multiple branches +static const uint8_t icon_mini_bolt[5] = {0x44, 0x2A, 0x51, 0x0C, 0x10}; static int pxbuf_icon(uint8_t pages[][OLED_WIDTH], int content_h, int base, int x, const uint8_t *cols, int width, int inv) @@ -374,9 +423,73 @@ void oled_draw_settings(void) snprintf(rows[SET_LR_HOLD].value, sizeof(rows[0].value), "%d", g_lr_hold_ms); snprintf(rows[SET_DISPLAY_FLIP].value, sizeof(rows[0].value), "%s", g_display_flip ? "ON" : "OFF"); snprintf(rows[SET_DELTA_TIMEOUT].value, sizeof(rows[0].value), "%dms", g_delta_timeout_ms); + if (g_sleep_timeout_min == 0) + snprintf(rows[SET_AUTO_SLEEP].value, sizeof(rows[0].value), "OFF"); + else + snprintf(rows[SET_AUTO_SLEEP].value, sizeof(rows[0].value), "%dmin", g_sleep_timeout_min); oled_draw_rows(rows, NUM_SETTINGS, g_active_setting); } +void oled_draw_dice(void) +{ + // 128px wide, labels start at x=2, 6px/char → 21 chars per row + static const int WRAP_COLS = 21; + static const int MAX_WRAP = 8; + + char wrap_lines[8][24]; + int wrap_count = 0; + + if (g_dice_rolled) { + const char *src = g_dice_csv; + while (*src && wrap_count < MAX_WRAP) { + int len = (int)strlen(src); + if (len <= WRAP_COLS) { + strncpy(wrap_lines[wrap_count], src, WRAP_COLS); + wrap_lines[wrap_count][WRAP_COLS] = '\0'; + wrap_count++; + break; + } + // find last comma within WRAP_COLS chars to avoid mid-number breaks + int cut = WRAP_COLS; + for (int j = WRAP_COLS - 1; j > 0; j--) { + if (src[j] == ',') { cut = j; break; } + } + strncpy(wrap_lines[wrap_count], src, cut); + wrap_lines[wrap_count][cut] = '\0'; + wrap_count++; + src += cut; + if (*src == ',') src++; + } + } + + oled_row_t rows[3 + 8]; + int n = 3; + + rows[0].label = "NUM"; + rows[0].cursor = -1; + snprintf(rows[0].value, sizeof(rows[0].value), "%d", g_dice_num); + + rows[1].label = "SIDES"; + rows[1].cursor = -1; + snprintf(rows[1].value, sizeof(rows[1].value), "D%d", die_sides[g_dice_sides]); + + rows[2].label = "ROLL"; + rows[2].cursor = -1; + if (g_dice_rolled) + snprintf(rows[2].value, sizeof(rows[2].value), "%d", g_dice_sum); + else + snprintf(rows[2].value, sizeof(rows[2].value), "---"); + + for (int i = 0; i < wrap_count; i++) { + rows[n].label = wrap_lines[i]; + rows[n].cursor = -1; + rows[n].value[0] = '\0'; + n++; + } + + oled_draw_rows(rows, n, g_dice_item); +} + void oled_draw_life(void) { const int content_pages = OLED_PAGES - HEADER_PAGES; diff --git a/main/draw.h b/main/draw.h index 60a3ab0..20418ff 100644 --- a/main/draw.h +++ b/main/draw.h @@ -22,3 +22,4 @@ void oled_draw_list(const char **labels, const int *values, int count, int activ void oled_draw_players(void); void oled_draw_settings(void); void oled_draw_life(void); +void oled_draw_dice(void); diff --git a/main/font.h b/main/font.h index 31821d9..c5029e6 100644 --- a/main/font.h +++ b/main/font.h @@ -74,6 +74,9 @@ static const uint8_t icons[NUM_MENUS][2][ICON_W] = { // Plus (counters) { {0x00,0x00,0x00,0xC0,0xC0,0xC0,0xF8,0xF8,0xF8,0xF8,0xC0,0xC0,0xC0,0x00,0x00,0x00}, {0x00,0x00,0x00,0x03,0x03,0x03,0x1F,0x1F,0x1F,0x1F,0x03,0x03,0x03,0x00,0x00,0x00} }, + // D6 showing 6-face: square outline + 6 dots in 2x3 arrangement + { {0x00,0xFE,0x02,0x02,0x9A,0x9A,0x02,0x02,0x02,0x02,0x9A,0x9A,0x02,0x02,0xFE,0x00}, + {0x00,0x7F,0x40,0x40,0x59,0x59,0x40,0x40,0x40,0x40,0x59,0x59,0x40,0x40,0x7F,0x00} }, // Cog (settings) { {0x00,0x80,0xDC,0xFC,0xFC,0xB8,0x9C,0xFE,0xFE,0x9C,0xB8,0xFC,0xFC,0xDC,0x80,0x00}, {0x00,0x01,0x3B,0x3F,0x3F,0x1D,0x39,0x7F,0x7F,0x39,0x1D,0x3F,0x3F,0x3B,0x01,0x00} }, diff --git a/main/game.c b/main/game.c index 631ae3a..d40acd7 100644 --- a/main/game.c +++ b/main/game.c @@ -26,6 +26,7 @@ void settings_reset_defaults(void) g_lr_hold_ms = 500; g_display_flip = 0; g_delta_timeout_ms = 1000; + g_sleep_timeout_min = SLEEP_TIMEOUT_DEF; } void game_reset(void) @@ -63,7 +64,7 @@ void settings_load(void) if (nvs_get_i32(nvs, "lr_hold", &val) == ESP_OK) g_lr_hold_ms = (int)val; if (nvs_get_i32(nvs, "disp_flip", &val) == ESP_OK) g_display_flip = (int)val; if (nvs_get_i32(nvs, "delta_to", &val) == ESP_OK) g_delta_timeout_ms = (int)val; - if (nvs_get_i32(nvs, "player_id", &val) == ESP_OK) g_player_id = (uint8_t)val; + if (nvs_get_i32(nvs, "sleep_to", &val) == ESP_OK) g_sleep_timeout_min = (int)val; if (nvs_get_i32(nvs, "life", &val) == ESP_OK) g_life = (int)val; char key[8]; for (int i = 0; i < MAX_OPPONENTS; i++) { @@ -90,8 +91,8 @@ void settings_save(void) nvs_set_i32(nvs, "lr_hold", (int32_t)g_lr_hold_ms); nvs_set_i32(nvs, "disp_flip", (int32_t)g_display_flip); nvs_set_i32(nvs, "delta_to", (int32_t)g_delta_timeout_ms); + nvs_set_i32(nvs, "sleep_to", (int32_t)g_sleep_timeout_min); nvs_set_str(nvs, "pname", g_player_name); - nvs_set_i32(nvs, "player_id", (int32_t)g_player_id); nvs_set_i32(nvs, "life", (int32_t)g_life); char key[8]; for (int i = 0; i < MAX_OPPONENTS; i++) { diff --git a/main/main.c b/main/main.c index ed3f271..b7e0bef 100644 --- a/main/main.c +++ b/main/main.c @@ -10,6 +10,11 @@ #include "nvs_flash.h" #include "nvs.h" #include "esp_err.h" +#include "esp_random.h" +#include "esp_sleep.h" +#include "esp_adc/adc_oneshot.h" +#include "esp_adc/adc_cali.h" +#include "esp_adc/adc_cali_scheme.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include @@ -18,6 +23,12 @@ // ── Global state ────────────────────────────────────────────────────────────── int g_sleep_mode = 0; +int g_battery_pct = -1; +int g_sleep_timeout_min = SLEEP_TIMEOUT_DEF; + +static adc_oneshot_unit_handle_t s_adc; +static adc_cali_handle_t s_adc_cali; +static bool s_adc_cali_ok; // Game int g_life; @@ -58,14 +69,22 @@ int g_life_delta = 0; int g_life_delta_tick = 0; int g_delta_timeout_ms = 1000; +// Dice +int g_dice_num = 1; +int g_dice_sides = 5; // index into die_sides: d20 +int g_dice_item = 0; +char g_dice_csv[DICE_CSV_LEN]; +int g_dice_rolled = 0; +int g_dice_sum = 0; + // ── Serial command task ─────────────────────────────────────────────────────── static void serial_print_state(void) { - printf("DBG STATE life=%d poison=%u cmdr=[%d,%d,%d,%d] counters=[%d,%d,%d] menu=%d ble=%d pid=%u eliminated=%d\n", + printf("DBG STATE life=%d poison=%u cmdr=[%d,%d,%d,%d] counters=[%d,%d,%d] menu=%d ble=%d eliminated=%d\n", g_life, (unsigned)g_counters[0], g_cmdr_damage[0], g_cmdr_damage[1], g_cmdr_damage[2], g_cmdr_damage[3], g_counters[0], g_counters[1], g_counters[2], - g_active_menu, g_ble_enabled, (unsigned)g_player_id, g_eliminated); + g_active_menu, g_ble_enabled, g_eliminated); fflush(stdout); } @@ -154,6 +173,21 @@ void app_main(void) check_elimination(); g_led_max = (uint8_t)(255 * g_brightness_pct / 100); + // ADC for battery voltage (GPIO34, ADC1 CH6, 100k/100k divider) + adc_oneshot_unit_init_cfg_t adc_cfg = {.unit_id = ADC_UNIT_1}; + adc_oneshot_new_unit(&adc_cfg, &s_adc); + adc_oneshot_chan_cfg_t ch_cfg = { + .atten = ADC_ATTEN_DB_11, + .bitwidth = ADC_BITWIDTH_DEFAULT, + }; + adc_oneshot_config_channel(s_adc, ADC_CHANNEL_6, &ch_cfg); + adc_cali_line_fitting_config_t cali_cfg = { + .unit_id = ADC_UNIT_1, + .atten = ADC_ATTEN_DB_11, + .bitwidth = ADC_BITWIDTH_DEFAULT, + }; + s_adc_cali_ok = (adc_cali_create_scheme_line_fitting(&cali_cfg, &s_adc_cali) == ESP_OK); + oled_init(); oled_set_flip(g_display_flip); oled_clear(); @@ -193,6 +227,13 @@ void app_main(void) int players_tick=0; int settings_dirty=0, settings_save_tick=0; int sleep_tick=0, sleep_fired=0, ble_pre_sleep=0; + uint32_t idle_ticks=0, batt_tick=0; + + gpio_wakeup_enable(BTN_FORWARD_GPIO, GPIO_INTR_LOW_LEVEL); + gpio_wakeup_enable(BTN_LEFT_GPIO, GPIO_INTR_LOW_LEVEL); + gpio_wakeup_enable(BTN_RIGHT_GPIO, GPIO_INTR_LOW_LEVEL); + gpio_wakeup_enable(BTN_BACK_GPIO, GPIO_INTR_LOW_LEVEL); + esp_sleep_enable_gpio_wakeup(); #define MARK_DIRTY() do { settings_dirty = 1; settings_save_tick = 0; } while (0) float breath_phase=0.0f; @@ -321,6 +362,9 @@ void app_main(void) } else if (g_active_menu == MENU_COUNTERS) { g_active_counter = (g_active_counter + 1) % NUM_COUNTERS; changed = 1; + } else if (g_active_menu == MENU_DICE) { + g_dice_item = (g_dice_item + 1) % 3; + changed = 1; } else if (g_active_menu == MENU_LIFE) { int nc = g_ble_enabled ? 0 : g_num_opponents; if (g_ble_enabled) @@ -389,6 +433,9 @@ void app_main(void) } else if (g_active_menu == MENU_COUNTERS) { g_active_counter = (g_active_counter - 1 + NUM_COUNTERS) % NUM_COUNTERS; changed = 1; + } else if (g_active_menu == MENU_DICE) { + g_dice_item = (g_dice_item - 1 + 3) % 3; + changed = 1; } else if (g_active_menu == MENU_LIFE) { int nc = g_ble_enabled ? 0 : g_num_opponents; if (g_ble_enabled) @@ -489,6 +536,28 @@ void app_main(void) g_counters[g_active_counter] += d; if (g_counters[g_active_counter] < 0) g_counters[g_active_counter] = 0; changed = 1; MARK_DIRTY(); check_elimination(); + } else if (g_active_menu == MENU_DICE) { + if (g_dice_item == 0) { + g_dice_num += d; + if (g_dice_num < 1) g_dice_num = 1; + } else if (g_dice_item == 1) { + g_dice_sides = (g_dice_sides + d + NUM_DICE_SIDES) % NUM_DICE_SIDES; + } else { + int sides = die_sides[g_dice_sides]; + g_dice_sum = 0; + int pos = 0; + g_dice_csv[0] = '\0'; + for (int i = 0; i < g_dice_num; i++) { + int roll = (int)(esp_random() % (uint32_t)sides) + 1; + g_dice_sum += roll; + if (pos < DICE_CSV_LEN - 5) { + if (i > 0) g_dice_csv[pos++] = ','; + pos += snprintf(g_dice_csv + pos, DICE_CSV_LEN - pos, "%d", roll); + } + } + g_dice_rolled = 1; + } + changed = 1; } else if (g_active_menu == MENU_SETTINGS) { changed = 1; MARK_DIRTY(); switch (g_active_setting) { @@ -564,6 +633,12 @@ void app_main(void) if (g_delta_timeout_ms < DELTA_TIMEOUT_MIN) g_delta_timeout_ms = DELTA_TIMEOUT_MIN; if (g_delta_timeout_ms > DELTA_TIMEOUT_MAX) g_delta_timeout_ms = DELTA_TIMEOUT_MAX; break; + case SET_AUTO_SLEEP: + g_sleep_timeout_min += d; + if (g_sleep_timeout_min < 0) g_sleep_timeout_min = 0; + if (g_sleep_timeout_min > SLEEP_TIMEOUT_MAX) g_sleep_timeout_min = SLEEP_TIMEOUT_MAX; + idle_ticks = 0; + break; } } } @@ -596,7 +671,6 @@ void app_main(void) g_peers[i].active = 0; } } - player_id_resolve(); } // ── Autosave settings ───────────────────────────────────────────────── @@ -639,6 +713,65 @@ void app_main(void) led_update_for_count(g_life, 255); } + // ── Battery voltage sampling ────────────────────────────────────────── + if (g_battery_pct >= 0 && g_battery_pct < BATT_LOW_PCT && g_tick % 50 == 0) + oled_draw_header(); + + if (++batt_tick >= BATT_SAMPLE_TICKS) { + batt_tick = 0; + int raw, voltage_mv; + adc_oneshot_read(s_adc, ADC_CHANNEL_6, &raw); + if (s_adc_cali_ok) + adc_cali_raw_to_voltage(s_adc_cali, raw, &voltage_mv); + else + voltage_mv = raw * 3100 / 4095; + int cell_mv = voltage_mv * 2; // 100k/100k voltage divider + // LiPo discharge curve: piecewise linear interpolation. + // Voltage stays flat ~3.7-4.2V through most of charge; linear + // mapping reads too high. Table derived from typical LiPo OCV curve. + static const int lipo_mv[] = {3000,3300,3400,3500,3600,3700,3800,3900,4000,4100,4200}; + static const int lipo_pct[] = { 0, 3, 8, 18, 34, 50, 62, 72, 81, 92, 100}; + static const int N = sizeof(lipo_mv)/sizeof(lipo_mv[0]); + int pct; + if (cell_mv <= lipo_mv[0]) { + pct = 0; + } else if (cell_mv >= lipo_mv[N-1]) { + pct = 100; + } else { + int i = 0; + while (i < N-2 && cell_mv >= lipo_mv[i+1]) i++; + pct = lipo_pct[i] + (cell_mv - lipo_mv[i]) * + (lipo_pct[i+1] - lipo_pct[i]) / (lipo_mv[i+1] - lipo_mv[i]); + } + g_battery_pct = pct; + oled_draw_header(); + } + + // ── Idle tracking and auto-sleep ────────────────────────────────────── + if (fwd == 0 || back == 0 || left == 0 || right == 0) + idle_ticks = 0; + else + idle_ticks++; + + if (!g_sleep_mode && g_sleep_timeout_min > 0 && + idle_ticks >= (uint32_t)g_sleep_timeout_min * 60 * 100) { + idle_ticks = 0; + if (settings_dirty) { settings_save(); settings_dirty = 0; settings_save_tick = 0; } + oled_set_contrast(SLEEP_CONTRAST); + led_off(); + int ble_pre_auto = g_ble_enabled; + if (g_ble_enabled) { g_ble_enabled = 0; ble_adv_update(); } + esp_light_sleep_start(); + // woke up — restore + oled_set_contrast(0xCF); + g_ble_enabled = ble_pre_auto; + if (g_ble_enabled) ble_adv_update(); + breath_phase = 0.0f; + led_update_for_count(g_life, 255); + oled_draw_header(); + changed = 1; + } + // ── Display dispatch ────────────────────────────────────────────────── if (changed) { switch (g_active_menu) { @@ -646,29 +779,22 @@ void app_main(void) oled_draw_life(); break; case MENU_CMDR: - for (int i = 0; i < g_num_opponents; i++) { - int found = 0; - if (g_ble_enabled) { - for (int j = 0; j < MAX_BLE_PEERS; j++) { - if (g_peers[j].active && g_peers[j].player_id == (uint8_t)i) { - snprintf(opponent_labels[i], sizeof(opponent_labels[i]), "%.4s", g_peers[j].name); - found = 1; - break; - } - } - } - if (!found) + if (!g_ble_enabled) { + for (int i = 0; i < g_num_opponents; i++) { snprintf(opponent_labels[i], sizeof(opponent_labels[i]), "CMD %d", i+1); - opponent_label_ptrs[i] = opponent_labels[i]; - } - if (!g_ble_enabled) + opponent_label_ptrs[i] = opponent_labels[i]; + } oled_draw_list(opponent_label_ptrs, g_cmdr_damage, g_num_opponents, g_active_opponent); - else + } else { oled_draw_players(); + } break; case MENU_COUNTERS: oled_draw_list(counter_names, g_counters, NUM_COUNTERS, g_active_counter); break; + case MENU_DICE: + oled_draw_dice(); + break; case MENU_SETTINGS: oled_draw_settings(); break; diff --git a/main/state.h b/main/state.h index 257e7c2..6c93e53 100644 --- a/main/state.h +++ b/main/state.h @@ -33,6 +33,10 @@ extern int g_display_flip; // Peers extern ble_peer_t g_peers[MAX_BLE_PEERS]; +// Battery / power +extern int g_battery_pct; // -1 = not yet sampled +extern int g_sleep_timeout_min; // 0 = disabled + // Timing extern uint32_t g_tick; @@ -40,3 +44,11 @@ extern uint32_t g_tick; extern int g_life_delta; extern int g_life_delta_tick; extern int g_delta_timeout_ms; + +// Dice +extern int g_dice_num; +extern int g_dice_sides; +extern int g_dice_item; +extern char g_dice_csv[DICE_CSV_LEN]; +extern int g_dice_rolled; +extern int g_dice_sum; diff --git a/pcb/commeownder.kicad_prl b/pcb/commeownder.kicad_prl new file mode 100644 index 0000000..48cada4 --- /dev/null +++ b/pcb/commeownder.kicad_prl @@ -0,0 +1,105 @@ +{ + "board": { + "active_layer": 0, + "active_layer_preset": "", + "auto_track_width": true, + "hidden_netclasses": [], + "hidden_nets": [], + "high_contrast_mode": 0, + "net_color_mode": 1, + "opacity": { + "images": 0.6, + "pads": 1.0, + "shapes": 1.0, + "tracks": 1.0, + "vias": 1.0, + "zones": 0.6 + }, + "prototype_zone_fills": false, + "selection_filter": { + "dimensions": true, + "footprints": true, + "graphics": true, + "keepouts": true, + "lockedItems": false, + "otherItems": true, + "pads": true, + "text": true, + "tracks": true, + "vias": true, + "zones": true + }, + "visible_items": [ + "vias", + "footprint_text", + "footprint_anchors", + "ratsnest", + "grid", + "footprints_front", + "footprints_back", + "footprint_values", + "footprint_references", + "tracks", + "drc_errors", + "drawing_sheet", + "bitmaps", + "pads", + "zones", + "drc_warnings", + "drc_exclusions", + "locked_item_shadows", + "conflict_shadows", + "shapes", + "board_outline_area", + "ly_points" + ], + "visible_layers": "ffffffff_ffffffff_ffffffff_ffffffff", + "zone_display_mode": 0 + }, + "git": { + "integration_disabled": false, + "repo_type": "", + "repo_username": "", + "ssh_key": "" + }, + "meta": { + "filename": "commeownder.kicad_prl", + "version": 5 + }, + "net_inspector_panel": { + "col_hidden": [], + "col_order": [], + "col_widths": [], + "custom_group_rules": [], + "expanded_rows": [], + "filter_by_net_name": true, + "filter_by_netclass": true, + "filter_text": "", + "group_by_constraint": false, + "group_by_netclass": false, + "show_time_domain_details": false, + "show_unconnected_nets": false, + "show_zero_pad_nets": false, + "sort_ascending": true, + "sorting_column": -1 + }, + "open_jobsets": [], + "project": { + "files": [] + }, + "schematic": { + "hierarchy_collapsed": [], + "selection_filter": { + "graphics": true, + "images": true, + "labels": true, + "lockedItems": false, + "otherItems": true, + "pins": true, + "ruleAreas": true, + "symbols": true, + "text": true, + "wires": true + } + } +} diff --git a/pcb/commeownder.kicad_pro b/pcb/commeownder.kicad_pro index 9e26dfe..adef254 100644 --- a/pcb/commeownder.kicad_pro +++ b/pcb/commeownder.kicad_pro @@ -1 +1,465 @@ -{} \ No newline at end of file +{ + "board": { + "3dviewports": [], + "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", + "field_name_whitespace": "warning", + "footprint_filter": "ignore", + "footprint_link_issues": "warning", + "four_way_junction": "ignore", + "ground_pin_not_ground": "warning", + "hier_label_mismatch": "error", + "isolated_pin_label": "warning", + "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", + "stacked_pin_name": "warning", + "unannotated": "error", + "unconnected_wire_endpoint": "warning", + "undefined_netclass": "error", + "unit_value_mismatch": "error", + "unresolved_variable": "error", + "wire_dangling": "error" + } + }, + "libraries": { + "pinned_footprint_libs": [], + "pinned_symbol_libs": [] + }, + "meta": { + "filename": "commeownder.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": { + "idf": "", + "netlist": "", + "plot": "", + "specctra_dsn": "", + "vrml": "" + }, + "page_layout_descr_file": "" + }, + "schematic": { + "annotate_start_num": 0, + "annotation": { + "method": 0, + "sort_order": 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 + }, + { + "group_by": false, + "label": "Sim.Pins", + "name": "Sim.Pins", + "show": false + }, + { + "group_by": false, + "label": "Sim.Type", + "name": "Sim.Type", + "show": false + }, + { + "group_by": false, + "label": "Sim.Device", + "name": "Sim.Device", + "show": false + }, + { + "group_by": false, + "label": "Description", + "name": "Description", + "show": false + }, + { + "group_by": false, + "label": "#", + "name": "${ITEM_NUMBER}", + "show": false + } + ], + "filter_string": "", + "group_symbols": true, + "include_excluded_from_bom": true, + "name": "", + "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": [], + "hop_over_size_choice": 0, + "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 + }, + "page_layout_descr_file": "", + "plot_directory": "", + "reuse_designators": true, + "subpart_first_id": 65, + "subpart_id_separator": 0, + "top_level_sheets": [ + { + "filename": "commeownder.kicad_sch", + "name": "Root", + "uuid": "4f1ddaab-5ed8-4280-ae9f-5da3efc5b3b5" + } + ], + "used_designators": "P1,BT1,SW1-4,D1-2,R1-3,Q1,U1-6", + "variants": [] + }, + "sheets": [ + [ + "4f1ddaab-5ed8-4280-ae9f-5da3efc5b3b5", + "Root" + ] + ], + "text_variables": {}, + "tuning_profiles": { + "meta": { + "version": 0 + }, + "tuning_profiles_impedance_geometric": [] + } +} diff --git a/pcb/commeownder.kicad_sch b/pcb/commeownder.kicad_sch index b874060..8629db4 100644 --- a/pcb/commeownder.kicad_sch +++ b/pcb/commeownder.kicad_sch @@ -2,13 +2,5954 @@ (version 20260306) (generator "eeschema") (generator_version "10.0") - (uuid 4f1ddaab-5ed8-4280-ae9f-5da3efc5b3b5) + (uuid "4f1ddaab-5ed8-4280-ae9f-5da3efc5b3b5") (paper "A4") - (lib_symbols) + (lib_symbols + (symbol "Battery_Management:TP4056-42-ESOP8" + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (duplicate_pin_numbers_are_jumpers no) + (property "Reference" "U" + (at -6.604 11.684 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "TP4056-42-ESOP8" + (at 10.16 11.684 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "Package_SO:SOIC-8-1EP_3.9x4.9mm_P1.27mm_EP2.41x3.3mm_ThermalVias" + (at 0.508 -22.86 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "https://www.lcsc.com/datasheet/lcsc_datasheet_2410121619_TOPPOWER-Nanjing-Extension-Microelectronics-TP4056-42-ESOP8_C16581.pdf" + (at 0 -25.4 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "1A Standalone Linear Li-ion/LiPo single-cell battery charger, 4.2V ±1% charge voltage, VCC = 4.0..8.0V, SOIC-8 (SOP-8)" + (at 0.508 -20.32 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_keywords" "lithium-ion lithium-polymer Li-Poly" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_fp_filters" "*SO*3.9x4.*P1.27mm*EP2.4*x3.3*mm*" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (symbol "TP4056-42-ESOP8_1_0" + (pin input line + (at 10.16 0 180) + (length 2.54) + (name "TEMP" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 10.16 -2.54 180) + (length 2.54) + (name "PROG" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin power_in line + (at 0 -12.7 90) + (length 2.54) + (name "GND" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "3" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin power_in line + (at 0 12.7 270) + (length 2.54) + (name "V_{CC}" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "4" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin power_out line + (at 10.16 5.08 180) + (length 2.54) + (name "BAT" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "5" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin open_collector line + (at -10.16 -2.54 0) + (length 2.54) + (name "~{STDBY}" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "6" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin open_collector line + (at -10.16 0 0) + (length 2.54) + (name "~{CHRG}" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "7" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin input line + (at -10.16 5.08 0) + (length 2.54) + (name "CE" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "8" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at -2.54 -12.7 90) + (length 2.54) + (name "EPAD" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "9" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + ) + (symbol "TP4056-42-ESOP8_1_1" + (rectangle + (start -7.62 10.16) + (end 7.62 -10.16) + (stroke + (width 0.254) + (type default) + ) + (fill + (type background) + ) + ) + ) + (embedded_fonts no) + ) + (symbol "Connector:USB_C_Plug_USB2.0" + (pin_names + (offset 1.016) + ) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (duplicate_pin_numbers_are_jumpers no) + (property "Reference" "P" + (at -10.16 19.05 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "USB_C_Plug_USB2.0" + (at 12.7 19.05 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify right) + ) + ) + (property "Footprint" "" + (at 3.81 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "https://www.usb.org/sites/default/files/documents/usb_type-c.zip" + (at 3.81 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "USB 2.0-only Type-C Plug connector" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_keywords" "usb universal serial bus type-C USB2.0" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_fp_filters" "USB*C*Plug*" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (symbol "USB_C_Plug_USB2.0_0_0" + (rectangle + (start -0.254 -17.78) + (end 0.254 -16.764) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (rectangle + (start 10.16 15.494) + (end 9.144 14.986) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (rectangle + (start 10.16 10.414) + (end 9.144 9.906) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (rectangle + (start 10.16 7.874) + (end 9.144 7.366) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (rectangle + (start 10.16 2.794) + (end 9.144 2.286) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (rectangle + (start 10.16 -2.286) + (end 9.144 -2.794) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + ) + (symbol "USB_C_Plug_USB2.0_0_1" + (rectangle + (start -10.16 17.78) + (end 10.16 -17.78) + (stroke + (width 0.254) + (type default) + ) + (fill + (type background) + ) + ) + (polyline + (pts + (xy -8.89 -3.81) (xy -8.89 3.81) + ) + (stroke + (width 0.508) + (type default) + ) + (fill + (type none) + ) + ) + (rectangle + (start -7.62 -3.81) + (end -6.35 3.81) + (stroke + (width 0.254) + (type default) + ) + (fill + (type outline) + ) + ) + (arc + (start -7.62 3.81) + (mid -6.985 4.4423) + (end -6.35 3.81) + (stroke + (width 0.254) + (type default) + ) + (fill + (type none) + ) + ) + (arc + (start -7.62 3.81) + (mid -6.985 4.4423) + (end -6.35 3.81) + (stroke + (width 0.254) + (type default) + ) + (fill + (type outline) + ) + ) + (arc + (start -8.89 3.81) + (mid -6.985 5.7067) + (end -5.08 3.81) + (stroke + (width 0.508) + (type default) + ) + (fill + (type none) + ) + ) + (arc + (start -5.08 -3.81) + (mid -6.985 -5.7067) + (end -8.89 -3.81) + (stroke + (width 0.508) + (type default) + ) + (fill + (type none) + ) + ) + (arc + (start -6.35 -3.81) + (mid -6.985 -4.4423) + (end -7.62 -3.81) + (stroke + (width 0.254) + (type default) + ) + (fill + (type none) + ) + ) + (arc + (start -6.35 -3.81) + (mid -6.985 -4.4423) + (end -7.62 -3.81) + (stroke + (width 0.254) + (type default) + ) + (fill + (type outline) + ) + ) + (polyline + (pts + (xy -5.08 3.81) (xy -5.08 -3.81) + ) + (stroke + (width 0.508) + (type default) + ) + (fill + (type none) + ) + ) + (circle + (center -2.54 1.143) + (radius 0.635) + (stroke + (width 0.254) + (type default) + ) + (fill + (type outline) + ) + ) + (polyline + (pts + (xy -1.27 4.318) (xy 0 6.858) (xy 1.27 4.318) (xy -1.27 4.318) + ) + (stroke + (width 0.254) + (type default) + ) + (fill + (type outline) + ) + ) + (polyline + (pts + (xy 0 -2.032) (xy 2.54 0.508) (xy 2.54 1.778) + ) + (stroke + (width 0.508) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 0 -3.302) (xy -2.54 -0.762) (xy -2.54 0.508) + ) + (stroke + (width 0.508) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 0 -5.842) (xy 0 4.318) + ) + (stroke + (width 0.508) + (type default) + ) + (fill + (type none) + ) + ) + (circle + (center 0 -5.842) + (radius 1.27) + (stroke + (width 0) + (type default) + ) + (fill + (type outline) + ) + ) + (rectangle + (start 1.905 1.778) + (end 3.175 3.048) + (stroke + (width 0.254) + (type default) + ) + (fill + (type outline) + ) + ) + ) + (symbol "USB_C_Plug_USB2.0_1_1" + (pin passive line + (at 0 -22.86 90) + (length 5.08) + (name "GND" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "A1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 15.24 15.24 180) + (length 5.08) + (name "VBUS" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "A4" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 10.16 180) + (length 5.08) + (name "CC" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "A5" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 -2.54 180) + (length 5.08) + (name "D+" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "A6" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 2.54 180) + (length 5.08) + (name "D-" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "A7" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 15.24 15.24 180) + (length 5.08) + (hide yes) + (name "VBUS" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "A9" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 0 -22.86 90) + (length 5.08) + (hide yes) + (name "GND" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "A12" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 0 -22.86 90) + (length 5.08) + (hide yes) + (name "GND" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "B1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 15.24 15.24 180) + (length 5.08) + (hide yes) + (name "VBUS" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "B4" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 7.62 180) + (length 5.08) + (name "VCONN" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "B5" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 15.24 15.24 180) + (length 5.08) + (hide yes) + (name "VBUS" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "B9" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 0 -22.86 90) + (length 5.08) + (hide yes) + (name "GND" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "B12" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at -7.62 -22.86 90) + (length 5.08) + (name "SHIELD" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "SH" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + ) + (embedded_fonts no) + ) + (symbol "Device:Battery_Cell" + (pin_numbers + (hide yes) + ) + (pin_names + (offset 0) + (hide yes) + ) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (duplicate_pin_numbers_are_jumpers no) + (property "Reference" "BT" + (at 2.54 2.54 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "Battery_Cell" + (at 2.54 0 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "" + (at 0 1.524 90) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "" + (at 0 1.524 90) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "Single-cell battery" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Sim.Device" "V" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Sim.Type" "DC" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Sim.Pins" "1=+ 2=-" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_keywords" "battery cell" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (symbol "Battery_Cell_0_1" + (rectangle + (start -2.286 1.778) + (end 2.286 1.524) + (stroke + (width 0) + (type default) + ) + (fill + (type outline) + ) + ) + (rectangle + (start -1.524 1.016) + (end 1.524 0.508) + (stroke + (width 0) + (type default) + ) + (fill + (type outline) + ) + ) + (polyline + (pts + (xy 0 1.778) (xy 0 2.54) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 0 0.762) (xy 0 0) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 0.762 3.048) (xy 1.778 3.048) + ) + (stroke + (width 0.254) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 1.27 3.556) (xy 1.27 2.54) + ) + (stroke + (width 0.254) + (type default) + ) + (fill + (type none) + ) + ) + ) + (symbol "Battery_Cell_1_1" + (pin passive line + (at 0 5.08 270) + (length 2.54) + (name "+" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 0 -2.54 90) + (length 2.54) + (name "-" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + ) + (embedded_fonts no) + ) + (symbol "Device:LED_BGKR" + (pin_names + (offset 0) + (hide yes) + ) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (duplicate_pin_numbers_are_jumpers no) + (property "Reference" "D" + (at 0 9.398 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "LED_BGKR" + (at 0 -8.89 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 0 -1.27 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "" + (at 0 -1.27 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "RGB LED, blue/green/cathode/red" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_keywords" "LED RGB diode" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_fp_filters" "LED* LED_SMD:* LED_THT:*" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (symbol "LED_BGKR_0_0" + (text "R" + (at 1.905 3.81 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (text "G" + (at 1.905 -1.27 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (text "B" + (at 1.905 -6.35 0) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (symbol "LED_BGKR_0_1" + (circle + (center -2.032 0) + (radius 0.254) + (stroke + (width 0) + (type default) + ) + (fill + (type outline) + ) + ) + (polyline + (pts + (xy -1.27 6.35) (xy -1.27 3.81) + ) + (stroke + (width 0.254) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy -1.27 6.35) (xy -1.27 3.81) (xy -1.27 3.81) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy -1.27 5.08) (xy 1.27 5.08) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy -1.27 5.08) (xy -2.032 5.08) (xy -2.032 -5.08) (xy -1.016 -5.08) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy -1.27 1.27) (xy -1.27 -1.27) + ) + (stroke + (width 0.254) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy -1.27 1.27) (xy -1.27 -1.27) (xy -1.27 -1.27) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy -1.27 0) (xy -2.54 0) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy -1.27 -3.81) (xy -1.27 -6.35) + ) + (stroke + (width 0.254) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy -1.27 -5.08) (xy 1.27 -5.08) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy -1.016 6.35) (xy 0.508 7.874) (xy -0.254 7.874) (xy 0.508 7.874) (xy 0.508 7.112) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy -1.016 1.27) (xy 0.508 2.794) (xy -0.254 2.794) (xy 0.508 2.794) (xy 0.508 2.032) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy -1.016 -3.81) (xy 0.508 -2.286) (xy -0.254 -2.286) (xy 0.508 -2.286) (xy 0.508 -3.048) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 0 6.35) (xy 1.524 7.874) (xy 0.762 7.874) (xy 1.524 7.874) (xy 1.524 7.112) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 0 1.27) (xy 1.524 2.794) (xy 0.762 2.794) (xy 1.524 2.794) (xy 1.524 2.032) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 0 -3.81) (xy 1.524 -2.286) (xy 0.762 -2.286) (xy 1.524 -2.286) (xy 1.524 -3.048) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 1.27 6.35) (xy 1.27 3.81) (xy -1.27 5.08) (xy 1.27 6.35) + ) + (stroke + (width 0.254) + (type default) + ) + (fill + (type none) + ) + ) + (rectangle + (start 1.27 6.35) + (end 1.27 6.35) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 1.27 5.08) (xy 2.54 5.08) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (rectangle + (start 1.27 3.81) + (end 1.27 6.35) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 1.27 1.27) (xy 1.27 -1.27) (xy -1.27 0) (xy 1.27 1.27) + ) + (stroke + (width 0.254) + (type default) + ) + (fill + (type none) + ) + ) + (rectangle + (start 1.27 1.27) + (end 1.27 1.27) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 1.27 0) (xy -1.27 0) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 1.27 0) (xy 2.54 0) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (rectangle + (start 1.27 -1.27) + (end 1.27 1.27) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 1.27 -3.81) (xy 1.27 -6.35) (xy -1.27 -5.08) (xy 1.27 -3.81) + ) + (stroke + (width 0.254) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 1.27 -5.08) (xy 2.54 -5.08) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (rectangle + (start 2.794 8.382) + (end -2.794 -7.62) + (stroke + (width 0.254) + (type default) + ) + (fill + (type background) + ) + ) + ) + (symbol "LED_BGKR_1_1" + (pin passive line + (at 5.08 -5.08 180) + (length 2.54) + (name "BA" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 5.08 0 180) + (length 2.54) + (name "GA" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at -5.08 0 0) + (length 2.54) + (name "K" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "3" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 5.08 5.08 180) + (length 2.54) + (name "RA" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "4" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + ) + (embedded_fonts no) + ) + (symbol "Device:R_Small" + (pin_numbers + (hide yes) + ) + (pin_names + (offset 0.254) + (hide yes) + ) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (duplicate_pin_numbers_are_jumpers no) + (property "Reference" "R" + (at 0 0 90) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.016 1.016) + ) + ) + ) + (property "Value" "R_Small" + (at 1.778 0 90) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "Resistor, small symbol" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_keywords" "R resistor" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_fp_filters" "R_*" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (symbol "R_Small_0_1" + (rectangle + (start -0.762 1.778) + (end 0.762 -1.778) + (stroke + (width 0.2032) + (type default) + ) + (fill + (type none) + ) + ) + ) + (symbol "R_Small_1_1" + (pin passive line + (at 0 2.54 270) + (length 0.762) + (name "" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 0 -2.54 90) + (length 0.762) + (name "" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + ) + (embedded_fonts no) + ) + (symbol "Display_Graphic:ER_OLEDM0.91_1x-I2C" + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (duplicate_pin_numbers_are_jumpers no) + (property "Reference" "U" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "ER_OLEDM0.91_1x-I2C" + (at 14.224 -10.668 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "Display:ER_OLEDM0.91_1x-I2C" + (at 18.034 -12.7 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "https://www.buydisplay.com/download/manual/ER-OLEDM0.91-1_Datasheet.pdf" + (at 42.672 -14.732 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "SSD1306 OLED module, 0.91 inch, 128x32, I2C" + (at 26.67 -16.764 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_keywords" "EastRising" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_fp_filters" "ER?OLEDM0.91?1x?I2C*" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (symbol "ER_OLEDM0.91_1x-I2C_1_1" + (rectangle + (start -7.62 7.62) + (end 7.62 -7.62) + (stroke + (width 0.254) + (type solid) + ) + (fill + (type background) + ) + ) + (pin power_in line + (at 0 -10.16 90) + (length 2.54) + (name "GND" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin power_in line + (at 0 10.16 270) + (length 2.54) + (name "VCC" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin input clock + (at -10.16 2.54 0) + (length 2.54) + (name "SCL" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "3" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at -10.16 -2.54 0) + (length 2.54) + (name "SDA" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "4" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + ) + (embedded_fonts no) + ) + (symbol "Interface_USB:MCP2200-I-SS" + (pin_names + (offset 1.016) + ) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (duplicate_pin_numbers_are_jumpers no) + (property "Reference" "U" + (at -20.32 -19.05 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "MCP2200-I-SS" + (at -20.32 19.05 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "Package_SO:SSOP-20_5.3x7.2mm_P0.65mm" + (at 0 -29.21 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "http://ww1.microchip.com/downloads/en/DeviceDoc/200022228D.pdf" + (at 0 -25.4 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "USB 2.0 to UART Protocol Converter with GPIO, SSOP-20" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_keywords" "USB UART Converter" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_fp_filters" "SSOP*20*5.3x7.2mm*P0.65mm*" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (symbol "MCP2200-I-SS_0_1" + (rectangle + (start -20.32 17.78) + (end 20.32 -17.78) + (stroke + (width 0.254) + (type default) + ) + (fill + (type background) + ) + ) + ) + (symbol "MCP2200-I-SS_1_1" + (pin power_in line + (at -2.54 20.32 270) + (length 2.54) + (name "VDD" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin input line + (at 22.86 -10.16 180) + (length 2.54) + (name "OSC1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin output line + (at 22.86 -15.24 180) + (length 2.54) + (name "OSC2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "3" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin input line + (at -22.86 15.24 0) + (length 2.54) + (name "RST" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "4" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at -22.86 -15.24 0) + (length 2.54) + (name "GP7/TxLED" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "5" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at -22.86 -12.7 0) + (length 2.54) + (name "GP6/RxLED" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "6" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at -22.86 -10.16 0) + (length 2.54) + (name "GP5" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "7" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at -22.86 -7.62 0) + (length 2.54) + (name "GP4" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "8" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at -22.86 -5.08 0) + (length 2.54) + (name "GP3" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "9" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin output line + (at -22.86 10.16 0) + (length 2.54) + (name "TX" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "10" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin output line + (at -22.86 7.62 0) + (length 2.54) + (name "RTS" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "11" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin input line + (at -22.86 12.7 0) + (length 2.54) + (name "RX" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "12" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin input line + (at -22.86 5.08 0) + (length 2.54) + (name "CTS" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "13" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at -22.86 -2.54 0) + (length 2.54) + (name "GP2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "14" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at -22.86 0 0) + (length 2.54) + (name "GP1/USB-CFG" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "15" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at -22.86 2.54 0) + (length 2.54) + (name "GP0/SSPND" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "16" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin power_in line + (at 2.54 20.32 270) + (length 2.54) + (name "V_USB" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "17" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 22.86 10.16 180) + (length 2.54) + (name "D-" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "18" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 22.86 15.24 180) + (length 2.54) + (name "D+" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "19" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin power_in line + (at 0 -20.32 90) + (length 2.54) + (name "VSS" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "20" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + ) + (embedded_fonts no) + ) + (symbol "RF_Module:ESP32-WROOM-32" + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (duplicate_pin_numbers_are_jumpers no) + (property "Reference" "U" + (at -12.7 34.29 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "ESP32-WROOM-32" + (at 1.27 34.29 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "RF_Module:ESP32-WROOM-32" + (at 0 -38.1 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "https://www.espressif.com/sites/default/files/documentation/esp32-wroom-32_datasheet_en.pdf" + (at -7.62 1.27 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "RF Module, ESP32-D0WDQ6 SoC, Wi-Fi 802.11b/g/n, Bluetooth, BLE, 32-bit, 2.7-3.6V, onboard antenna, SMD" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_keywords" "RF Radio BT ESP ESP32 Espressif onboard PCB antenna" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_fp_filters" "ESP32?WROOM?32*" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (symbol "ESP32-WROOM-32_0_1" + (rectangle + (start -12.7 33.02) + (end 12.7 -33.02) + (stroke + (width 0.254) + (type default) + ) + (fill + (type background) + ) + ) + ) + (symbol "ESP32-WROOM-32_1_1" + (pin power_in line + (at 0 -35.56 90) + (length 2.54) + (name "GND" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin power_in line + (at 0 35.56 270) + (length 2.54) + (name "VDD" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin input line + (at -15.24 30.48 0) + (length 2.54) + (name "EN" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "3" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin input line + (at -15.24 25.4 0) + (length 2.54) + (name "SENSOR_VP" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "4" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin input line + (at -15.24 22.86 0) + (length 2.54) + (name "SENSOR_VN" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "5" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin input line + (at 15.24 -25.4 180) + (length 2.54) + (name "IO34" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "6" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin input line + (at 15.24 -27.94 180) + (length 2.54) + (name "IO35" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "7" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 -20.32 180) + (length 2.54) + (name "IO32" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "8" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 -22.86 180) + (length 2.54) + (name "IO33" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "9" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 -12.7 180) + (length 2.54) + (name "IO25" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "10" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 -15.24 180) + (length 2.54) + (name "IO26" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "11" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 -17.78 180) + (length 2.54) + (name "IO27" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "12" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 10.16 180) + (length 2.54) + (name "IO14" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "13" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 15.24 180) + (length 2.54) + (name "IO12" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "14" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 0 -35.56 90) + (length 2.54) + (hide yes) + (name "GND" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "15" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 12.7 180) + (length 2.54) + (name "IO13" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "16" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at -15.24 -5.08 0) + (length 2.54) + (name "SHD/SD2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "17" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at -15.24 -7.62 0) + (length 2.54) + (name "SWP/SD3" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "18" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at -15.24 -12.7 0) + (length 2.54) + (name "SCS/CMD" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "19" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at -15.24 -10.16 0) + (length 2.54) + (name "SCK/CLK" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "20" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at -15.24 0 0) + (length 2.54) + (name "SDO/SD0" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "21" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at -15.24 -2.54 0) + (length 2.54) + (name "SDI/SD1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "22" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 7.62 180) + (length 2.54) + (name "IO15" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "23" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 25.4 180) + (length 2.54) + (name "IO2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "24" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 30.48 180) + (length 2.54) + (name "IO0" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "25" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 20.32 180) + (length 2.54) + (name "IO4" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "26" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 5.08 180) + (length 2.54) + (name "IO16" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "27" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 2.54 180) + (length 2.54) + (name "IO17" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "28" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 17.78 180) + (length 2.54) + (name "IO5" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "29" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 0 180) + (length 2.54) + (name "IO18" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "30" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 -2.54 180) + (length 2.54) + (name "IO19" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "31" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin no_connect line + (at -12.7 -27.94 0) + (length 2.54) + (hide yes) + (name "NC" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "32" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 -5.08 180) + (length 2.54) + (name "IO21" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "33" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 22.86 180) + (length 2.54) + (name "RXD0/IO3" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "34" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 27.94 180) + (length 2.54) + (name "TXD0/IO1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "35" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 -7.62 180) + (length 2.54) + (name "IO22" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "36" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin bidirectional line + (at 15.24 -10.16 180) + (length 2.54) + (name "IO23" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "37" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 0 -35.56 90) + (length 2.54) + (hide yes) + (name "GND" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "38" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 0 -35.56 90) + (length 2.54) + (hide yes) + (name "GND" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "39" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + ) + (embedded_fonts no) + ) + (symbol "Regulator_Linear:AMS1117-3.3" + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (duplicate_pin_numbers_are_jumpers no) + (property "Reference" "U" + (at -3.81 3.175 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "AMS1117-3.3" + (at 0 3.175 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "Package_TO_SOT_SMD:SOT-223-3_TabPin2" + (at 0 5.08 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "http://www.advanced-monolithic.com/pdf/ds1117.pdf" + (at 2.54 -6.35 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "1A Low Dropout regulator, positive, 3.3V fixed output, SOT-223" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_keywords" "linear regulator ldo fixed positive" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_fp_filters" "SOT?223*TabPin2*" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (symbol "AMS1117-3.3_0_1" + (rectangle + (start -5.08 -5.08) + (end 5.08 1.905) + (stroke + (width 0.254) + (type default) + ) + (fill + (type background) + ) + ) + ) + (symbol "AMS1117-3.3_1_1" + (pin power_in line + (at 0 -7.62 90) + (length 2.54) + (name "GND" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin power_out line + (at 7.62 0 180) + (length 2.54) + (name "VO" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin power_in line + (at -7.62 0 0) + (length 2.54) + (name "VI" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "3" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + ) + (embedded_fonts no) + ) + (symbol "Switch:SW_Push" + (pin_numbers + (hide yes) + ) + (pin_names + (offset 1.016) + (hide yes) + ) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (duplicate_pin_numbers_are_jumpers no) + (property "Reference" "SW" + (at 1.27 2.54 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "SW_Push" + (at 0 -1.524 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 0 5.08 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "" + (at 0 5.08 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "Push button switch, generic, two pins" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_keywords" "switch normally-open pushbutton push-button" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (symbol "SW_Push_0_1" + (circle + (center -2.032 0) + (radius 0.508) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 0 1.27) (xy 0 3.048) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (circle + (center 2.032 0) + (radius 0.508) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 2.54 1.27) (xy -2.54 1.27) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (pin passive line + (at -5.08 0 0) + (length 2.54) + (name "1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 5.08 0 180) + (length 2.54) + (name "2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + ) + (embedded_fonts no) + ) + (symbol "Transistor_Array:TPL7407LAD" + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (duplicate_pin_numbers_are_jumpers no) + (property "Reference" "U" + (at -8.128 13.716 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "TPL7407LAD" + (at 6.858 13.716 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "Package_SO:SOIC-16_3.9x9.9mm_P1.27mm" + (at 0 -27.686 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "https://www.ti.com/lit/gpn/tpl7407la" + (at 0 -25.654 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "7-Channel Low Side Driver, CMOS Improvement of Darlington Array, 30V, SOIC-16" + (at 0.254 -29.718 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_keywords" "Relay Driver" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_fp_filters" "SOIC*3.9x9.9mm*P1.27mm*" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (symbol "TPL7407LAD_0_1" + (rectangle + (start -7.62 12.7) + (end 7.62 -12.7) + (stroke + (width 0.254) + (type default) + ) + (fill + (type background) + ) + ) + (polyline + (pts + (xy -3.556 5.08) (xy -2.54 5.08) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy -2.54 6.096) (xy -2.54 4.064) (xy -1.016 5.08) (xy -2.54 6.096) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (circle + (center -1.27 2.54) + (radius 0.254) + (stroke + (width 0) + (type default) + ) + (fill + (type outline) + ) + ) + (circle + (center -1.27 0) + (radius 0.254) + (stroke + (width 0) + (type default) + ) + (fill + (type outline) + ) + ) + (circle + (center -1.27 -2.286) + (radius 0.254) + (stroke + (width 0) + (type default) + ) + (fill + (type outline) + ) + ) + (circle + (center -1.27 -4.572) + (radius 0.254) + (stroke + (width 0) + (type default) + ) + (fill + (type outline) + ) + ) + (circle + (center -0.762 5.08) + (radius 0.254) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy -0.508 5.08) (xy 2.032 5.08) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 0 7.874) (xy 0 5.08) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 0.508 6.985) (xy -0.508 6.985) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 0.508 6.223) (xy -0.508 6.223) (xy 0 6.985) (xy 0.508 6.223) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + ) + (symbol "TPL7407LAD_1_1" + (pin input line + (at -10.16 5.08 0) + (length 2.54) + (name "IN1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin input line + (at -10.16 2.54 0) + (length 2.54) + (name "IN2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin input line + (at -10.16 0 0) + (length 2.54) + (name "IN3" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "3" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin input line + (at -10.16 -2.54 0) + (length 2.54) + (name "IN4" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "4" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin input line + (at -10.16 -5.08 0) + (length 2.54) + (name "IN5" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "5" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin input line + (at -10.16 -7.62 0) + (length 2.54) + (name "IN6" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "6" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin input line + (at -10.16 -10.16 0) + (length 2.54) + (name "IN7" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "7" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin power_in line + (at 0 -15.24 90) + (length 2.54) + (name "GND" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "8" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin power_in line + (at 0 15.24 270) + (length 2.54) + (name "COM" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "9" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin open_collector line + (at 10.16 -10.16 180) + (length 2.54) + (name "OUT7" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "10" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin open_collector line + (at 10.16 -7.62 180) + (length 2.54) + (name "OUT6" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "11" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin open_collector line + (at 10.16 -5.08 180) + (length 2.54) + (name "OUT5" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "12" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin open_collector line + (at 10.16 -2.54 180) + (length 2.54) + (name "OUT4" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "13" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin open_collector line + (at 10.16 0 180) + (length 2.54) + (name "OUT3" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "14" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin open_collector line + (at 10.16 2.54 180) + (length 2.54) + (name "OUT2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "15" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin open_collector line + (at 10.16 5.08 180) + (length 2.54) + (name "OUT1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "16" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + ) + (embedded_fonts no) + ) + (symbol "Transistor_FET:AO3401A" + (pin_names + (hide yes) + ) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (duplicate_pin_numbers_are_jumpers no) + (property "Reference" "Q" + (at 5.08 1.905 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "AO3401A" + (at 5.08 0 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "Package_TO_SOT_SMD:SOT-23" + (at 5.08 -1.905 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + (italic yes) + ) + (justify left) + ) + ) + (property "Datasheet" "http://www.aosmd.com/pdfs/datasheet/AO3401A.pdf" + (at 5.08 -3.81 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Description" "-4.0A Id, -30V Vds, P-Channel MOSFET, SOT-23" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_keywords" "P-Channel MOSFET" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_fp_filters" "SOT?23*" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (symbol "AO3401A_0_1" + (polyline + (pts + (xy 0.254 1.905) (xy 0.254 -1.905) + ) + (stroke + (width 0.254) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 0.254 0) (xy -2.54 0) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 0.762 2.286) (xy 0.762 1.27) + ) + (stroke + (width 0.254) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 0.762 1.778) (xy 3.302 1.778) (xy 3.302 -1.778) (xy 0.762 -1.778) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 0.762 0.508) (xy 0.762 -0.508) + ) + (stroke + (width 0.254) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 0.762 -1.27) (xy 0.762 -2.286) + ) + (stroke + (width 0.254) + (type default) + ) + (fill + (type none) + ) + ) + (circle + (center 1.651 0) + (radius 2.794) + (stroke + (width 0.254) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 2.286 0) (xy 1.27 0.381) (xy 1.27 -0.381) (xy 2.286 0) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type outline) + ) + ) + (polyline + (pts + (xy 2.54 2.54) (xy 2.54 1.778) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (circle + (center 2.54 1.778) + (radius 0.254) + (stroke + (width 0) + (type default) + ) + (fill + (type outline) + ) + ) + (circle + (center 2.54 -1.778) + (radius 0.254) + (stroke + (width 0) + (type default) + ) + (fill + (type outline) + ) + ) + (polyline + (pts + (xy 2.54 -2.54) (xy 2.54 0) (xy 0.762 0) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 2.794 -0.508) (xy 2.921 -0.381) (xy 3.683 -0.381) (xy 3.81 -0.254) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 3.302 -0.381) (xy 2.921 0.254) (xy 3.683 0.254) (xy 3.302 -0.381) + ) + (stroke + (width 0) + (type default) + ) + (fill + (type none) + ) + ) + ) + (symbol "AO3401A_1_1" + (pin input line + (at -5.08 0 0) + (length 2.54) + (name "G" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "1" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 2.54 -5.08 90) + (length 2.54) + (name "S" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "2" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 2.54 5.08 270) + (length 2.54) + (name "D" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "3" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + ) + (embedded_fonts no) + ) + ) + (symbol + (lib_id "Switch:SW_Push") + (at 87.63 38.1 0) + (unit 1) + (body_style 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (dnp no) + (fields_autoplaced yes) + (uuid "0a226299-1c4e-4385-8d3a-ed67f1b3da9e") + (property "Reference" "SW1" + (at 87.63 30.48 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "SW_Push" + (at 87.63 33.02 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 87.63 33.02 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "" + (at 87.63 33.02 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "Push button switch, generic, two pins" + (at 87.63 38.1 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (pin "1" + (uuid "a35f1402-9132-4e9c-9544-c92803a72488") + ) + (pin "2" + (uuid "cd0c3281-8833-4e82-a959-f6539e9f6b89") + ) + (instances + (project "commeownder" + (path "/4f1ddaab-5ed8-4280-ae9f-5da3efc5b3b5" + (reference "SW1") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Regulator_Linear:AMS1117-3.3") + (at 57.15 121.92 0) + (unit 1) + (body_style 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (dnp no) + (fields_autoplaced yes) + (uuid "119cc83d-0052-4cc7-9f2e-76b4e1c56649") + (property "Reference" "U5" + (at 57.15 115.57 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "AMS1117-3.3" + (at 57.15 118.11 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "Package_TO_SOT_SMD:SOT-223-3_TabPin2" + (at 57.15 116.84 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "http://www.advanced-monolithic.com/pdf/ds1117.pdf" + (at 59.69 128.27 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "1A Low Dropout regulator, positive, 3.3V fixed output, SOT-223" + (at 57.15 121.92 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (pin "3" + (uuid "84500b34-599a-4ea5-af30-704379f21fab") + ) + (pin "1" + (uuid "7709da11-0fd1-4be3-96c2-c61b2d88702d") + ) + (pin "2" + (uuid "795ca23b-f08f-4c37-b50d-0102009c3088") + ) + (instances + (project "commeownder" + (path "/4f1ddaab-5ed8-4280-ae9f-5da3efc5b3b5" + (reference "U5") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Transistor_Array:TPL7407LAD") + (at 158.75 118.11 0) + (unit 1) + (body_style 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (dnp no) + (fields_autoplaced yes) + (uuid "126e7f60-8783-46f4-a86e-46f8faf1c7f3") + (property "Reference" "U3" + (at 160.8933 100.33 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "TPL7407LAD" + (at 160.8933 102.87 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "Package_SO:SOIC-16_3.9x9.9mm_P1.27mm" + (at 158.75 145.796 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "https://www.ti.com/lit/gpn/tpl7407la" + (at 158.75 143.764 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "7-Channel Low Side Driver, CMOS Improvement of Darlington Array, 30V, SOIC-16" + (at 159.004 147.828 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (pin "12" + (uuid "9eb00148-65c2-4cd5-9d5a-9ddc5b4bfe6f") + ) + (pin "13" + (uuid "df32d10b-1a85-4f5d-b9c4-9fe1408ad5d9") + ) + (pin "10" + (uuid "1d587a10-9de7-402f-9e3b-d38898fed940") + ) + (pin "3" + (uuid "415803b7-df52-4745-9fa2-84ece99ed0f8") + ) + (pin "4" + (uuid "ce6be858-ef78-4fab-8def-5a30bb58a821") + ) + (pin "2" + (uuid "5b1d3ba3-cf43-4171-9029-d28ba16e75f8") + ) + (pin "1" + (uuid "c31b4334-a762-4b75-85ee-9c1b36a052b4") + ) + (pin "8" + (uuid "5b059bb4-671b-49d7-b30b-281daab39f24") + ) + (pin "5" + (uuid "0504eb9b-bd84-4f5d-880f-e198ff4ba4ab") + ) + (pin "16" + (uuid "ae1f2529-5b6e-41e4-8f45-977f07e4f21e") + ) + (pin "15" + (uuid "52b019be-d9f7-41fa-859f-25c11a805f92") + ) + (pin "9" + (uuid "fba6d24c-9270-49f4-88d1-4c81c65a2f67") + ) + (pin "7" + (uuid "ef838fbd-f833-4428-bbac-ec25289f0b82") + ) + (pin "14" + (uuid "445e6bae-ad4c-4f86-a94a-9c1f82dd6aeb") + ) + (pin "11" + (uuid "7d2d41c3-784f-4350-826e-b8d8889fc6a5") + ) + (pin "6" + (uuid "e1d59d56-cb80-4059-9c61-9fc7360b2f0a") + ) + (instances + (project "commeownder" + (path "/4f1ddaab-5ed8-4280-ae9f-5da3efc5b3b5" + (reference "U3") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Interface_USB:MCP2200-I-SS") + (at 231.14 49.53 0) + (unit 1) + (body_style 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (dnp no) + (fields_autoplaced yes) + (uuid "1c33f246-5829-4d1c-b6ba-09d58f31964f") + (property "Reference" "U6" + (at 233.2833 69.85 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "MCP2200-I-SS" + (at 233.2833 72.39 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "Package_SO:SSOP-20_5.3x7.2mm_P0.65mm" + (at 231.14 78.74 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "http://ww1.microchip.com/downloads/en/DeviceDoc/200022228D.pdf" + (at 231.14 74.93 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "USB 2.0 to UART Protocol Converter with GPIO, SSOP-20" + (at 231.14 49.53 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (pin "6" + (uuid "c0650514-6a59-41c6-8a94-6da25e66fa1e") + ) + (pin "5" + (uuid "5f97df92-3914-4016-96ad-baaecb42cb43") + ) + (pin "20" + (uuid "170e1015-b214-4241-ae6e-b0b9f922fce8") + ) + (pin "3" + (uuid "544ebc70-a955-4be2-bc86-41dd590f90ed") + ) + (pin "12" + (uuid "6e4c436c-447c-45a0-879f-475a869a7610") + ) + (pin "2" + (uuid "22e522b2-5cdb-4bec-ae61-8e2379012a08") + ) + (pin "13" + (uuid "17184b5e-6abe-4b3b-bc3f-7ea2806f75eb") + ) + (pin "14" + (uuid "f2720a8d-5735-4131-b0ff-3bad3cb4138f") + ) + (pin "10" + (uuid "ffafa2b2-9d09-41bb-95ea-15a417d33d0f") + ) + (pin "8" + (uuid "f127fa0f-97ae-49ab-a659-13b83f923fc0") + ) + (pin "7" + (uuid "d3cd3c2e-3feb-4f66-b0ed-c4163fe7eb92") + ) + (pin "11" + (uuid "faaafd57-813b-4e3a-84ce-fd3a89d83cfc") + ) + (pin "9" + (uuid "598e601c-06e7-4176-a447-1f20e0a23a98") + ) + (pin "15" + (uuid "e0b3fa37-0eaa-44e7-a7de-2672b20a7b4b") + ) + (pin "1" + (uuid "bbef12c1-9296-45e7-b733-3af9697a1ff6") + ) + (pin "19" + (uuid "f2ba608f-70a1-471c-8f60-c530023bb781") + ) + (pin "18" + (uuid "ad8640a2-325a-42ae-9171-2bb4d5042d90") + ) + (pin "17" + (uuid "b14b306a-f871-4b57-a13a-ee9134152f66") + ) + (pin "16" + (uuid "3fa13bbe-1a78-4176-a36e-6ef8fb75119f") + ) + (pin "4" + (uuid "23582e6b-ec13-469f-b18c-2ceb1476890d") + ) + (instances + (project "commeownder" + (path "/4f1ddaab-5ed8-4280-ae9f-5da3efc5b3b5" + (reference "U6") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Switch:SW_Push") + (at 105.41 38.1 0) + (unit 1) + (body_style 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (dnp no) + (fields_autoplaced yes) + (uuid "33e5aab6-db86-41d6-b681-224f248d38c4") + (property "Reference" "SW2" + (at 105.41 30.48 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "SW_Push" + (at 105.41 33.02 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 105.41 33.02 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "" + (at 105.41 33.02 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "Push button switch, generic, two pins" + (at 105.41 38.1 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (pin "1" + (uuid "c37f36c4-0e8f-48b8-8215-ac934a9a853d") + ) + (pin "2" + (uuid "cd86b042-c40a-4ed7-b7bd-cb62a143c6b5") + ) + (instances + (project "commeownder" + (path "/4f1ddaab-5ed8-4280-ae9f-5da3efc5b3b5" + (reference "SW2") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Connector:USB_C_Plug_USB2.0") + (at 44.45 43.18 0) + (unit 1) + (body_style 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (dnp no) + (fields_autoplaced yes) + (uuid "434f1abd-07a3-4767-8d1c-5e158a652c83") + (property "Reference" "P1" + (at 44.45 20.32 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "USB_C_Plug_USB2.0" + (at 44.45 22.86 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 48.26 43.18 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "https://www.usb.org/sites/default/files/documents/usb_type-c.zip" + (at 48.26 43.18 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "USB 2.0-only Type-C Plug connector" + (at 44.45 43.18 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (pin "B4" + (uuid "63b3fdca-b68b-43e4-9991-3d4ec96fe5a8") + ) + (pin "A7" + (uuid "06dc59cf-ef03-442a-868e-08dff024d90d") + ) + (pin "A12" + (uuid "c28a230d-9d24-4304-8cd1-13c5b6b1baf3") + ) + (pin "B9" + (uuid "a206939c-32cd-4463-bad2-83102b46a7d9") + ) + (pin "A6" + (uuid "333d3cf1-995a-45e9-8c11-cc3075277a80") + ) + (pin "B1" + (uuid "345e51f9-0536-4fa6-b1c7-ce26aefc7c86") + ) + (pin "A4" + (uuid "9995cbb3-fa69-449b-9794-daf9627f3a72") + ) + (pin "A5" + (uuid "fb7a8580-f13d-44d5-95c4-d46ebb1e9200") + ) + (pin "A9" + (uuid "7b43536b-ae89-41db-b2c5-6e99d02d7355") + ) + (pin "SH" + (uuid "6bb74948-39e5-48b8-a182-441d7f53469a") + ) + (pin "B12" + (uuid "0b6c038f-d3d5-47b6-817e-1aa478f81031") + ) + (pin "A1" + (uuid "6d0da6f0-401f-4ea3-84b2-03ca0d41f320") + ) + (pin "B5" + (uuid "8411f5f2-3837-423a-a924-b70913d1e984") + ) + (instances + (project "commeownder" + (path "/4f1ddaab-5ed8-4280-ae9f-5da3efc5b3b5" + (reference "P1") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Device:LED_BGKR") + (at 210.82 95.25 0) + (unit 1) + (body_style 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (dnp no) + (fields_autoplaced yes) + (uuid "442a96b9-91eb-4916-b0a5-ebc9f77898d3") + (property "Reference" "D1" + (at 210.82 81.28 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "LED_BGKR" + (at 210.82 83.82 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 210.82 96.52 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "" + (at 210.82 96.52 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "RGB LED, blue/green/cathode/red" + (at 210.82 95.25 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (pin "4" + (uuid "e24471f6-1e4e-4024-a496-88ce213a3183") + ) + (pin "1" + (uuid "834cfc4a-2e07-45cb-bddb-c879194ccc74") + ) + (pin "2" + (uuid "2ff658d3-eefe-4e71-af66-794f545bb70c") + ) + (pin "3" + (uuid "58ab6322-ee2a-4af6-baf8-296ed4d59e3f") + ) + (instances + (project "commeownder" + (path "/4f1ddaab-5ed8-4280-ae9f-5da3efc5b3b5" + (reference "D1") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Display_Graphic:ER_OLEDM0.91_1x-I2C") + (at 157.48 80.01 0) + (unit 1) + (body_style 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (dnp no) + (fields_autoplaced yes) + (uuid "5fd6baf3-0b8f-4464-aa01-2ceb52c97c49") + (property "Reference" "U2" + (at 166.37 78.7399 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "ER_OLEDM0.91_1x-I2C" + (at 166.37 81.2799 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "Display:ER_OLEDM0.91_1x-I2C" + (at 175.514 92.71 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "https://www.buydisplay.com/download/manual/ER-OLEDM0.91-1_Datasheet.pdf" + (at 200.152 94.742 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "SSD1306 OLED module, 0.91 inch, 128x32, I2C" + (at 184.15 96.774 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (pin "1" + (uuid "a20ee7f7-74d3-4797-a9c2-169709e5c0e0") + ) + (pin "2" + (uuid "9fd512d2-6016-41d0-9427-857d4f2fc053") + ) + (pin "3" + (uuid "ab36ae92-f7d6-47a5-8b8c-18e97673ec92") + ) + (pin "4" + (uuid "27ec9cf8-5aaa-417f-918a-709be71ec808") + ) + (instances + (project "commeownder" + (path "/4f1ddaab-5ed8-4280-ae9f-5da3efc5b3b5" + (reference "U2") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Transistor_FET:AO3401A") + (at 53.34 149.86 0) + (unit 1) + (body_style 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (dnp no) + (fields_autoplaced yes) + (uuid "64123e0d-ad14-4b84-8e89-cd1d8a7aff3e") + (property "Reference" "Q1" + (at 59.69 148.5899 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "AO3401A" + (at 59.69 151.1299 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "Package_TO_SOT_SMD:SOT-23" + (at 58.42 151.765 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + (italic yes) + ) + (justify left) + ) + ) + (property "Datasheet" "http://www.aosmd.com/pdfs/datasheet/AO3401A.pdf" + (at 58.42 153.67 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Description" "-4.0A Id, -30V Vds, P-Channel MOSFET, SOT-23" + (at 53.34 149.86 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (pin "3" + (uuid "05bef9ba-0e11-44ac-9bd3-02752d1221f3") + ) + (pin "2" + (uuid "665e6d2f-b09e-4662-bed7-8d404afa7c97") + ) + (pin "1" + (uuid "a5a99efc-39ab-4326-9bef-f96e00f39861") + ) + (instances + (project "commeownder" + (path "/4f1ddaab-5ed8-4280-ae9f-5da3efc5b3b5" + (reference "Q1") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Device:Battery_Cell") + (at 31.75 149.86 0) + (unit 1) + (body_style 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (dnp no) + (fields_autoplaced yes) + (uuid "916bef7c-2c86-449d-8112-7404f33c0404") + (property "Reference" "BT1" + (at 35.56 146.7484 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "Battery_Cell" + (at 35.56 149.2884 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "" + (at 31.75 148.336 90) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "" + (at 31.75 148.336 90) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "Single-cell battery" + (at 31.75 149.86 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Sim.Device" "V" + (at 31.75 149.86 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Sim.Type" "DC" + (at 31.75 149.86 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Sim.Pins" "1=+ 2=-" + (at 31.75 149.86 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (pin "2" + (uuid "38f3e6bc-85d1-4206-9f41-d650ea03e9f1") + ) + (pin "1" + (uuid "394ba1ef-99b3-4fe1-b22d-33a7975edd82") + ) + (instances + (project "commeownder" + (path "/4f1ddaab-5ed8-4280-ae9f-5da3efc5b3b5" + (reference "BT1") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Device:R_Small") + (at 184.15 52.07 0) + (unit 1) + (body_style 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (dnp no) + (fields_autoplaced yes) + (uuid "a441144f-af6a-4332-acab-1621c6b03a0d") + (property "Reference" "R3" + (at 186.69 50.7999 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.016 1.016) + ) + (justify left) + ) + ) + (property "Value" "R_Small" + (at 186.69 53.3399 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "" + (at 184.15 52.07 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "" + (at 184.15 52.07 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "Resistor, small symbol" + (at 184.15 52.07 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (pin "1" + (uuid "7b2d4739-32d1-4892-b3ab-48f60bb0465f") + ) + (pin "2" + (uuid "7a65f0b2-341a-4dbd-8c1d-9c3a14edb00a") + ) + (instances + (project "commeownder" + (path "/4f1ddaab-5ed8-4280-ae9f-5da3efc5b3b5" + (reference "R3") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Device:R_Small") + (at 154.94 52.07 0) + (unit 1) + (body_style 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (dnp no) + (fields_autoplaced yes) + (uuid "bf3820d6-688d-4258-8f29-e4aa6915dc4f") + (property "Reference" "R1" + (at 157.48 50.7999 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.016 1.016) + ) + (justify left) + ) + ) + (property "Value" "R_Small" + (at 157.48 53.3399 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "" + (at 154.94 52.07 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "" + (at 154.94 52.07 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "Resistor, small symbol" + (at 154.94 52.07 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (pin "1" + (uuid "a236b72e-2da3-474d-af31-43d921a1b972") + ) + (pin "2" + (uuid "19ee23bc-f0d6-42fd-a698-90f9022b5fdc") + ) + (instances + (project "commeownder" + (path "/4f1ddaab-5ed8-4280-ae9f-5da3efc5b3b5" + (reference "R1") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Battery_Management:TP4056-42-ESOP8") + (at 52.07 86.36 0) + (unit 1) + (body_style 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (dnp no) + (fields_autoplaced yes) + (uuid "d80797ba-0c20-4b82-a65d-e94cd6f66f3d") + (property "Reference" "U4" + (at 54.2133 71.12 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "TP4056-42-ESOP8" + (at 54.2133 73.66 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "Package_SO:SOIC-8-1EP_3.9x4.9mm_P1.27mm_EP2.41x3.3mm_ThermalVias" + (at 52.578 109.22 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "https://www.lcsc.com/datasheet/lcsc_datasheet_2410121619_TOPPOWER-Nanjing-Extension-Microelectronics-TP4056-42-ESOP8_C16581.pdf" + (at 52.07 111.76 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "1A Standalone Linear Li-ion/LiPo single-cell battery charger, 4.2V ±1% charge voltage, VCC = 4.0..8.0V, SOIC-8 (SOP-8)" + (at 52.578 106.68 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (pin "1" + (uuid "a65f5a3c-01da-470f-bec0-01fdc4fc96a7") + ) + (pin "7" + (uuid "fd8942a3-23da-40ce-9d23-d16e2573ca28") + ) + (pin "2" + (uuid "eb41a963-459d-452d-b9f0-89b319de4ee6") + ) + (pin "3" + (uuid "a35f5b8d-31b6-4778-b160-28f5b6724d4f") + ) + (pin "4" + (uuid "4346f904-516f-434d-9447-fd964c0b8d3d") + ) + (pin "5" + (uuid "98c9b2a4-86b9-4094-b5c6-dc8b065f50dc") + ) + (pin "6" + (uuid "4d287707-5326-4031-9795-e87abe1a3be0") + ) + (pin "9" + (uuid "5d02ed57-3601-43d2-9972-55ccef776473") + ) + (pin "8" + (uuid "411f8ac1-9af3-4fd6-9673-f7f6f106ddff") + ) + (instances + (project "commeownder" + (path "/4f1ddaab-5ed8-4280-ae9f-5da3efc5b3b5" + (reference "U4") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Switch:SW_Push") + (at 123.19 38.1 0) + (unit 1) + (body_style 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (dnp no) + (fields_autoplaced yes) + (uuid "e3eb2c09-4694-4bb6-bbc4-620007ef0210") + (property "Reference" "SW3" + (at 123.19 30.48 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "SW_Push" + (at 123.19 33.02 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "" + (at 123.19 33.02 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "" + (at 123.19 33.02 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "Push button switch, generic, two pins" + (at 123.19 38.1 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (pin "1" + (uuid "9e5cabe3-7a1f-4a0c-8762-a07083d5a970") + ) + (pin "2" + (uuid "d00cd462-d3b4-4c1c-9afc-24e7d7233235") + ) + (instances + (project "commeownder" + (path "/4f1ddaab-5ed8-4280-ae9f-5da3efc5b3b5" + (reference "SW3") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Device:R_Small") + (at 168.91 52.07 0) + (unit 1) + (body_style 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (dnp no) + (fields_autoplaced yes) + (uuid "f3978802-a711-4d9d-9112-f8926c0bb497") + (property "Reference" "R2" + (at 171.45 50.7999 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.016 1.016) + ) + (justify left) + ) + ) + (property "Value" "R_Small" + (at 171.45 53.3399 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "" + (at 168.91 52.07 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "" + (at 168.91 52.07 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "Resistor, small symbol" + (at 168.91 52.07 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (pin "1" + (uuid "f8877ab4-6e1a-48fc-aff6-0c8f66ead407") + ) + (pin "2" + (uuid "fb6b541b-a978-49f1-9711-eeb3cd898850") + ) + (instances + (project "commeownder" + (path "/4f1ddaab-5ed8-4280-ae9f-5da3efc5b3b5" + (reference "R2") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "RF_Module:ESP32-WROOM-32") + (at 99.06 95.25 0) + (unit 1) + (body_style 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (dnp no) + (fields_autoplaced yes) + (uuid "fe0ac3fa-2b56-4af2-bdc7-ecc44763f213") + (property "Reference" "U1" + (at 101.2033 57.15 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Value" "ESP32-WROOM-32" + (at 101.2033 59.69 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + (justify left) + ) + ) + (property "Footprint" "RF_Module:ESP32-WROOM-32" + (at 99.06 133.35 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "https://www.espressif.com/sites/default/files/documentation/esp32-wroom-32_datasheet_en.pdf" + (at 91.44 93.98 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "RF Module, ESP32-D0WDQ6 SoC, Wi-Fi 802.11b/g/n, Bluetooth, BLE, 32-bit, 2.7-3.6V, onboard antenna, SMD" + (at 99.06 95.25 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (pin "17" + (uuid "67223d9f-5f14-47ff-84a9-c16b4db66645") + ) + (pin "33" + (uuid "45bfd758-7b12-4096-8483-975bae37a5c0") + ) + (pin "32" + (uuid "c9499fc6-da15-4b35-9b5f-4d9b6bf1f829") + ) + (pin "31" + (uuid "a8bcc6e5-d17d-4c17-9060-c79b48057eeb") + ) + (pin "30" + (uuid "b1c48ffd-321a-4a61-9eb9-a83ebcb36aac") + ) + (pin "29" + (uuid "03032c6c-78bb-4bf4-8c6b-5e628e61039c") + ) + (pin "28" + (uuid "a8b7e0c6-4d3b-47dc-a1f8-d427d0c5229d") + ) + (pin "27" + (uuid "a44a831b-4366-461b-b38d-583ce0c334bf") + ) + (pin "26" + (uuid "af4ff3e9-2bf0-4788-a35f-7266a4ca3995") + ) + (pin "25" + (uuid "d925e207-3b86-4d1b-a7f9-2d780446c9dd") + ) + (pin "24" + (uuid "f7df542e-fabd-4589-a95c-23a7df146ede") + ) + (pin "23" + (uuid "e99d5d61-033f-41fb-ac90-ad01a6ff0668") + ) + (pin "22" + (uuid "a5292254-387a-4a42-b033-34f1cc5c6715") + ) + (pin "21" + (uuid "91006f22-2f6e-4d13-929f-9790fb86307a") + ) + (pin "20" + (uuid "be7a81ee-6de3-4780-9bde-d141bcf5db9f") + ) + (pin "19" + (uuid "007308fa-ddbe-4e00-a188-cde05cff664b") + ) + (pin "18" + (uuid "220c5fa7-487c-4721-b4e7-d677071e78ad") + ) + (pin "34" + (uuid "f2289af4-c11d-4f84-890b-e597f2ed6141") + ) + (pin "36" + (uuid "5763c6d1-cca3-4dd6-934c-7e5b0a0728ed") + ) + (pin "37" + (uuid "4944e5d5-0fcb-4fd7-ba57-1abe76a54415") + ) + (pin "2" + (uuid "c4f31a2b-9edb-463d-9d5d-ac09c5a5edfd") + ) + (pin "5" + (uuid "95dda854-7828-4cf9-b2c1-522fe083af35") + ) + (pin "6" + (uuid "c643d6e5-e420-4e60-9de6-3689904b2aaf") + ) + (pin "14" + (uuid "8e99ec75-f1ee-4815-8ccf-16ad15be2c42") + ) + (pin "1" + (uuid "de9b184b-abdd-4b20-91a9-6fbe0fa20e31") + ) + (pin "12" + (uuid "28818c67-cc68-4904-af3a-cb6cb4e3d093") + ) + (pin "7" + (uuid "343cf81f-44df-47e1-8fe7-dfa1add4befe") + ) + (pin "38" + (uuid "e804bb34-e738-4c08-b2e1-157f43b4270c") + ) + (pin "13" + (uuid "139320ca-c4d9-45c8-81fd-11e3a4595867") + ) + (pin "3" + (uuid "0b130ef1-f0d7-47c3-99ae-bea1b0942fbb") + ) + (pin "39" + (uuid "82227d2e-5bc5-4ae7-b828-08401723df25") + ) + (pin "35" + (uuid "d3ef153e-de8f-4bfc-a990-e051f791a768") + ) + (pin "4" + (uuid "0dc2ca07-ad54-4f3b-b117-13228bca6b51") + ) + (pin "15" + (uuid "7936d8e6-839d-43d7-9614-eac768acec1b") + ) + (pin "9" + (uuid "9253040c-b74f-4941-8820-a4dcd6dcbecd") + ) + (pin "11" + (uuid "06055bc9-e2bd-45ff-b5ef-934cc01268ea") + ) + (pin "16" + (uuid "2df2f538-aa40-4487-a6cb-150be5331c58") + ) + (pin "10" + (uuid "e2459e1c-c4cb-4726-ae4e-14cdceb01ef1") + ) + (pin "8" + (uuid "53e6acbd-eaff-4c8c-9b74-f350bcc9d5d1") + ) + (instances + (project "commeownder" + (path "/4f1ddaab-5ed8-4280-ae9f-5da3efc5b3b5" + (reference "U1") + (unit 1) + ) + ) + ) + ) (sheet_instances (path "/" (page "1") ) ) (embedded_fonts no) -) \ No newline at end of file +) diff --git a/simulator/main.c b/simulator/main.c index 193af98..fdcd1f5 100644 --- a/simulator/main.c +++ b/simulator/main.c @@ -16,7 +16,6 @@ #define MAGIC_0 0xC0 #define MAGIC_1 0xDE #define PLAYER_NAME_LEN 8 -#define MAX_OPPONENTS 4 #pragma pack(push, 1) typedef struct { @@ -26,9 +25,7 @@ typedef struct { int16_t life; uint8_t poison; uint8_t eliminated; - uint8_t player_id; uint8_t reset_cmd; - uint8_t cmdr_dmg[MAX_OPPONENTS]; } ble_payload_t; #pragma pack(pop) @@ -42,9 +39,7 @@ static int16_t g_start_life = 40; static uint8_t g_poison = 0; static uint8_t g_game_id[2] = {0x42, 0x42}; static uint8_t g_eliminated = 0; -static uint8_t g_player_id = 0; static uint8_t g_reset_cmd = 0; -static uint8_t g_cmdr_dmg[MAX_OPPONENTS] = {0}; // Monotonic time of last processed reset (microseconds); 0 = never static gint64 g_last_reset_us = 0; @@ -61,9 +56,7 @@ static void start_advertising(void) { payload.life = g_life; payload.poison = g_poison; payload.eliminated = g_eliminated; - payload.player_id = g_player_id; payload.reset_cmd = g_reset_cmd; - memcpy(payload.cmdr_dmg, g_cmdr_dmg, MAX_OPPONENTS); GByteArray *data = g_byte_array_new(); g_byte_array_append(data, (const guint8 *)&payload, sizeof(payload)); @@ -75,10 +68,9 @@ static void start_advertising(void) { g_byte_array_free(data, TRUE); binc_adapter_start_advertising(default_adapter, adv); - fprintf(stderr, "advertising: name='%s' life=%d poison=%u game_id=%02X%02X pid=%u reset=%u cmdr=[%u,%u,%u,%u]\n", + fprintf(stderr, "advertising: name='%s' life=%d poison=%u game_id=%02X%02X reset=%u\n", g_name, (int)g_life, (unsigned)g_poison, - g_game_id[0], g_game_id[1], (unsigned)g_player_id, (unsigned)g_reset_cmd, - g_cmdr_dmg[0], g_cmdr_dmg[1], g_cmdr_dmg[2], g_cmdr_dmg[3]); + g_game_id[0], g_game_id[1], (unsigned)g_reset_cmd); } static void restart_advertising(void) { @@ -107,11 +99,9 @@ static void on_scan_result(Adapter *adapter, Device *device) { memcpy(name, p->name, PLAYER_NAME_LEN); name[PLAYER_NAME_LEN] = '\0'; - printf("PEER addr=%s name=%-8s life=%-5d poison=%u pid=%u cmdr=[%u,%u,%u,%u]%s%s\n", + printf("PEER addr=%s name=%-8s life=%-5d poison=%u%s%s\n", binc_device_get_address(device), name, - (int)p->life, (unsigned)p->poison, (unsigned)p->player_id, - (unsigned)p->cmdr_dmg[0], (unsigned)p->cmdr_dmg[1], - (unsigned)p->cmdr_dmg[2], (unsigned)p->cmdr_dmg[3], + (int)p->life, (unsigned)p->poison, p->eliminated ? " ELIMINATED" : "", p->reset_cmd ? " RESET_CMD" : ""); fflush(stdout); @@ -162,15 +152,13 @@ static gboolean cleanup_handler(gpointer user_data) { static void print_usage(const char *prog) { fprintf(stderr, - "Usage: %s --name [--life ] [--poison ] [--game-id ] [--player-id ] [--eliminated] [--reset-cmd] [--cmdr-dmg :]...\n" + "Usage: %s --name [--life ] [--poison ] [--game-id ] [--eliminated] [--reset-cmd]\n" " --name Player name (max 8 chars, required)\n" " --life Life total (default: 40)\n" " --poison Poison counters 0-9 (default: 0)\n" " --game-id 4-hex-digit game ID (default: 4242)\n" - " --player-id Player slot 0-4 (default: 0)\n" " --eliminated Mark player as eliminated\n" - " --reset-cmd Advertise reset_cmd=1 (tells peers to reset counters)\n" - " --cmdr-dmg Commander damage from opponent slot idx (0-3), e.g. --cmdr-dmg 0:7 (repeatable)\n", + " --reset-cmd Advertise reset_cmd=1 (tells peers to reset counters)\n", prog); } @@ -182,10 +170,8 @@ int main(int argc, char *argv[]) { {"life", required_argument, NULL, 'l'}, {"poison", required_argument, NULL, 'p'}, {"game-id", required_argument, NULL, 'g'}, - {"player-id", required_argument, NULL, 'i'}, {"eliminated", no_argument, NULL, 'e'}, {"reset-cmd", no_argument, NULL, 'r'}, - {"cmdr-dmg", required_argument, NULL, 'd'}, {NULL, 0, NULL, 0} }; @@ -214,24 +200,12 @@ int main(int argc, char *argv[]) { g_game_id[1] = (uint8_t)(id & 0xFF); break; } - case 'i': - g_player_id = (uint8_t)atoi(optarg); - break; case 'e': g_eliminated = 1; break; case 'r': g_reset_cmd = 1; break; - case 'd': { - int idx, val; - if (sscanf(optarg, "%d:%d", &idx, &val) != 2 || idx < 0 || idx >= MAX_OPPONENTS || val < 0 || val > 255) { - fprintf(stderr, "invalid cmdr-dmg '%s' (expected :, idx 0-%d, val 0-255)\n", optarg, MAX_OPPONENTS - 1); - return 1; - } - g_cmdr_dmg[idx] = (uint8_t)val; - break; - } default: print_usage(argv[0]); return 1; diff --git a/simulator/test_ble.c b/simulator/test_ble.c index c7840ea..ef810a9 100644 --- a/simulator/test_ble.c +++ b/simulator/test_ble.c @@ -219,26 +219,23 @@ static void sig_cleanup(int sig) /* ── Simulator subprocess helpers ─────────────────────────────────────────── */ static pid_t sim_start_ex(const char *name, int life, int poison, - const char *game_id, int eliminated, - int player_id, int reset_cmd) + const char *game_id, int eliminated, int reset_cmd) { pid_t pid = fork(); if (pid < 0) { perror("fork"); return -1; } if (pid == 0) { close(g_serial_fd); - char lbuf[16], pbuf[16], idbuf[16], n8[9]; - snprintf(lbuf, sizeof lbuf, "%d", life); - snprintf(pbuf, sizeof pbuf, "%d", poison); - snprintf(idbuf, sizeof idbuf, "%d", player_id); + char lbuf[16], pbuf[16], n8[9]; + snprintf(lbuf, sizeof lbuf, "%d", life); + snprintf(pbuf, sizeof pbuf, "%d", poison); strncpy(n8, name, 8); n8[8] = '\0'; - const char *args[20]; + const char *args[16]; int ai = 0; args[ai++] = g_sim_bin; args[ai++] = "--name"; args[ai++] = n8; args[ai++] = "--life"; args[ai++] = lbuf; args[ai++] = "--poison"; args[ai++] = pbuf; args[ai++] = "--game-id"; args[ai++] = game_id; - args[ai++] = "--player-id"; args[ai++] = idbuf; if (eliminated) args[ai++] = "--eliminated"; if (reset_cmd) args[ai++] = "--reset-cmd"; args[ai] = NULL; @@ -252,7 +249,7 @@ static pid_t sim_start_ex(const char *name, int life, int poison, static pid_t sim_start(const char *name, int life, int poison, const char *game_id, int eliminated) { - return sim_start_ex(name, life, poison, game_id, eliminated, 0, 0); + return sim_start_ex(name, life, poison, game_id, eliminated, 0); } static void sim_stop(pid_t pid) @@ -290,7 +287,7 @@ static void *sim_pipe_reader(void *arg) } static pid_t sim_start_tracked(const char *name, int life, int poison, - const char *game_id, int player_id) + const char *game_id) { int pipefd[2]; if (pipe(pipefd) < 0) { perror("pipe"); return -1; } @@ -303,18 +300,16 @@ static pid_t sim_start_tracked(const char *name, int life, int poison, close(pipefd[0]); dup2(pipefd[1], STDOUT_FILENO); close(pipefd[1]); - char lbuf[16], pbuf[16], idbuf[16], n8[9]; - snprintf(lbuf, sizeof lbuf, "%d", life); - snprintf(pbuf, sizeof pbuf, "%d", poison); - snprintf(idbuf, sizeof idbuf, "%d", player_id); + char lbuf[16], pbuf[16], n8[9]; + snprintf(lbuf, sizeof lbuf, "%d", life); + snprintf(pbuf, sizeof pbuf, "%d", poison); strncpy(n8, name, 8); n8[8] = '\0'; const char *args[] = { g_sim_bin, - "--name", n8, - "--life", lbuf, - "--poison", pbuf, - "--game-id", game_id, - "--player-id", idbuf, + "--name", n8, + "--life", lbuf, + "--poison", pbuf, + "--game-id", game_id, NULL }; execv(g_sim_bin, (char *const *)args); @@ -347,34 +342,6 @@ static int sim_wait2(const char *p1, const char *p2, int secs) return lq_wait(&g_sim_q, pats, secs, NULL); } -/* Variant of sim_start_ex with one cmdr-dmg entry, no pipe capture. */ -static pid_t sim_start_ex_cmdr(const char *name, int life, - const char *game_id, int cmdr_idx, int cmdr_val) -{ - pid_t pid = fork(); - if (pid < 0) { perror("fork"); return -1; } - if (pid == 0) { - close(g_serial_fd); - char lbuf[16], cdmg[16], n8[9]; - snprintf(lbuf, sizeof lbuf, "%d", life); - snprintf(cdmg, sizeof cdmg, "%d:%d", cmdr_idx, cmdr_val); - strncpy(n8, name, 8); n8[8] = '\0'; - const char *args[] = { - g_sim_bin, - "--name", n8, - "--life", lbuf, - "--poison", "0", - "--game-id", game_id, - "--player-id", "0", - "--cmdr-dmg", cdmg, - NULL - }; - execv(g_sim_bin, (char *const *)args); - _exit(1); - } - register_child(pid); - return pid; -} /* ── Key-value parsing ───────────────────────────────────────────────────── */ static int kv_int(const char *line, const char *key, int *out) @@ -671,20 +638,6 @@ static int t_active_peer_not_expired(void) return 0; } -/* PEER_RX player_id must match the simulator's --player-id argument. */ -static int t_peer_rx_player_id_matches(void) -{ - char line[LBUF]; - int pid_val; - pid_t sim = sim_start_ex("PIDCHK1", 40, 0, DEFAULT_GAME_ID, 0, 3, 0); - int found = wait2("DBG PEER_RX", "PIDCHK1", PEER_DETECT_S, line); - sim_stop(sim); - CHECK(found); - CHECK(kv_int(line, "pid", &pid_val)); - CHECK_EQ(pid_val, 3); - return 0; -} - /* * When a peer advertises reset_cmd=1, the firmware must reset its counters * (poison=0, eliminated=0, cmdr all 0) and emit a DBG STATE reflecting that. @@ -694,7 +647,7 @@ static int t_reset_cmd_resets_firmware(void) char line[LBUF]; int cmdr[4], poison, elim; - pid_t sim = sim_start_ex("RSTALL1", 40, 0, DEFAULT_GAME_ID, 0, 0, 1); + pid_t sim = sim_start_ex("RSTALL1", 40, 0, DEFAULT_GAME_ID, 0, 1); /* Wait until firmware logs PEER_RX carrying reset=1 */ int found = wait2("DBG PEER_RX", "reset=1", PEER_DETECT_S, NULL); @@ -748,7 +701,7 @@ static int t_fw_life_syncs_to_sim(void) serial_send("SET life=19\n"); wait1("DBG STATE", 5, NULL); - pid_t sim = sim_start_tracked("SYNCL1", 40, 0, DEFAULT_GAME_ID, 1); + pid_t sim = sim_start_tracked("SYNCL1", 40, 0, DEFAULT_GAME_ID); int found = sim_wait2("PEER", "life=19", PEER_DETECT_S); sim_stop_tracked(sim); serial_send("RESET\n"); @@ -765,7 +718,7 @@ static int t_fw_poison_syncs_to_sim(void) serial_send("SET counter0=3\n"); wait1("DBG STATE", 5, NULL); - pid_t sim = sim_start_tracked("SYNCP1", 40, 0, DEFAULT_GAME_ID, 1); + pid_t sim = sim_start_tracked("SYNCP1", 40, 0, DEFAULT_GAME_ID); int found = sim_wait2("PEER", "poison=3", PEER_DETECT_S); sim_stop_tracked(sim); serial_send("RESET\n"); @@ -787,36 +740,6 @@ static int t_sim_life_syncs_to_fw(void) return 0; } -/* Firmware logs correct cmdr_dmg from simulator PEER_RX. */ -static int t_sim_cmdr_syncs_to_fw(void) -{ - char line[LBUF]; int cmdr[4]; - pid_t sim = sim_start_ex_cmdr("SCMDR1", 40, DEFAULT_GAME_ID, 0, 9); - int found = wait2("DBG PEER_RX", "SCMDR1", PEER_DETECT_S, line); - sim_stop(sim); - CHECK(found); - CHECK(kv_intlist(line, "cmdr", cmdr, 4)); - CHECK_EQ(cmdr[0], 9); - return 0; -} - -/* After SET cmdr0 via serial, simulator sees updated cmdr in firmware adv. */ -static int t_fw_cmdr_syncs_to_sim(void) -{ - serial_send("SET ble=1\n"); - wait1("DBG STATE", 5, NULL); - serial_send("SET cmdr0=11\n"); - wait1("DBG STATE", 5, NULL); - - pid_t sim = sim_start_tracked("CMDR4", 40, 0, DEFAULT_GAME_ID, 1); - int found = sim_wait2("PEER", "cmdr=[11,", PEER_DETECT_S); - sim_stop_tracked(sim); - serial_send("RESET\n"); - wait1("DBG STATE", 5, NULL); - CHECK(found); - return 0; -} - /* After SET life=0 triggers elimination, simulator sees ELIMINATED in firmware adv. */ static int t_eliminated_syncs_to_adv(void) { @@ -825,7 +748,7 @@ static int t_eliminated_syncs_to_adv(void) serial_send("SET life=0\n"); wait1("DBG STATE", 5, NULL); - pid_t sim = sim_start_tracked("ELIMSYN1", 40, 0, DEFAULT_GAME_ID, 1); + pid_t sim = sim_start_tracked("ELIMSYN1", 40, 0, DEFAULT_GAME_ID); int found = sim_wait2("PEER", "ELIMINATED", PEER_DETECT_S); sim_stop_tracked(sim); serial_send("RESET\n"); @@ -853,7 +776,7 @@ static int t_life_cycle_visual(void) if (!wait1("DBG STATE", 5, NULL)) { FAIL_MSG("device not responding"); return 1; } lq_drain(&g_q); - pid_t sim = sim_start_tracked("VISLIFE1", 40, 0, DEFAULT_GAME_ID, 1); + pid_t sim = sim_start_tracked("VISLIFE1", 40, 0, DEFAULT_GAME_ID); /* Ramp 0→80 then 80→0, one step at a time. */ static const struct { int from; int to; const char *label; } ramps[] = { @@ -981,9 +904,6 @@ int main(int argc, char *argv[]) RUN(t_game_id_filter_wrong_rejected); RUN(t_game_id_filter_correct_accepted); - /* ── Player ID ──────────────────────────────────────────────────────── */ - RUN(t_peer_rx_player_id_matches); - /* ── Reset all ──────────────────────────────────────────────────────── */ RUN(t_reset_cmd_resets_firmware); @@ -998,9 +918,7 @@ int main(int argc, char *argv[]) /* ── Bidirectional sync ─────────────────────────────────────────────── */ RUN(t_fw_life_syncs_to_sim); RUN(t_fw_poison_syncs_to_sim); - RUN(t_fw_cmdr_syncs_to_sim); RUN(t_sim_life_syncs_to_fw); - RUN(t_sim_cmdr_syncs_to_fw); RUN(t_eliminated_syncs_to_adv); /* ── Visual life-cycle (operator can watch OLED + LED) ─────────────────── */