From 8a330b33ff41ffc1ec3f8fa39722e93115ea3f0f Mon Sep 17 00:00:00 2001 From: Legonut Date: Tue, 4 Dec 2018 21:15:52 -0500 Subject: Keyboard: Add new keyboard "Sol" from RGBKB (#4497) * Add final RGBKB Sol firmware * Apply suggestions from code review Apply most of the changes noroadsleft has suggested Co-Authored-By: Legonut * Cleanup readme * Cleanup keymaps per @noroadslefts suggestions * Remove eeproms, use set_single_persistent_default_layer * Suggestions from @noroadsleft and @drashna some small cleanup * Change RGB_SMOD to RGB_RMOD * fix RGB_SMOD * Apply suggestions from code review Remove redundant lines Co-Authored-By: Legonut --- keyboards/sol/rev1/config.h | 155 ++++++++++++++++++++ keyboards/sol/rev1/matrix.c | 304 ++++++++++++++++++++++++++++++++++++++++ keyboards/sol/rev1/rev1.c | 15 ++ keyboards/sol/rev1/rev1.h | 70 +++++++++ keyboards/sol/rev1/rules.mk | 2 + keyboards/sol/rev1/split_util.c | 54 +++++++ keyboards/sol/rev1/split_util.h | 17 +++ 7 files changed, 617 insertions(+) create mode 100644 keyboards/sol/rev1/config.h create mode 100644 keyboards/sol/rev1/matrix.c create mode 100644 keyboards/sol/rev1/rev1.c create mode 100644 keyboards/sol/rev1/rev1.h create mode 100644 keyboards/sol/rev1/rules.mk create mode 100644 keyboards/sol/rev1/split_util.c create mode 100644 keyboards/sol/rev1/split_util.h (limited to 'keyboards/sol/rev1') diff --git a/keyboards/sol/rev1/config.h b/keyboards/sol/rev1/config.h new file mode 100644 index 0000000000..fc91b8d499 --- /dev/null +++ b/keyboards/sol/rev1/config.h @@ -0,0 +1,155 @@ +/* +Copyright 2012 Jun Wako +Copyright 2015 Jack Humbert + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#ifndef REV1_CONFIG_H +#define REV1_CONFIG_H + + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0xFEED +#define PRODUCT_ID 0x3060 +#define DEVICE_VER 0x0001 +#define MANUFACTURER RGBKB +#define PRODUCT Sol +#define DESCRIPTION "An RGB, split, ortho-esque keyboard" + + +#define PREVENT_STUCK_MODIFIERS +#define TAPPING_FORCE_HOLD +#define TAPPING_TERM 150 + +#define USE_I2C +#define USE_SERIAL +#define USE_SERIAL_PD3 + +/* Select hand configuration */ +#define MASTER_LEFT +// #define MASTER_RIGHT +// #define EE_HANDS + +// Helix keyboard OLED support +// see ./rules.mk: OLED_ENABLE=yes or no +#ifdef OLED_ENABLE + #define SSD1306OLED +#endif + +/* Select rows configuration */ +// Rows are 4 or 5 +// #define HELIX_ROWS 5 see ./rules.mk + +/* key matrix size */ +// Rows are doubled-up +#define MATRIX_ROWS 12 +#define MATRIX_ROW_PINS { C6, B6, B5, B4, D7, E6} + +// wiring of each half +#define MATRIX_COLS 7 +#define MATRIX_COL_PINS { F0, F1, F4, F5, F6, F7, C7 } +// #define MATRIX_COL_PINS { B2, B3, B1, F7, F6, F5, F4 } //uncomment this line and comment line above if you need to reverse left-to-right key order + +/* define if matrix has ghost */ +//#define MATRIX_HAS_GHOST + +/* number of backlight levels */ +// #define BACKLIGHT_LEVELS 3 + +/* Set 0 if debouncing isn't needed */ +#define DEBOUNCING_DELAY 5 + +/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ +//#define LOCKING_SUPPORT_ENABLE +/* Locking resynchronize hack */ +//#define LOCKING_RESYNC_ENABLE + +/* key combination for command */ +#define IS_COMMAND() ( \ + keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \ +) + +/* ws2812 RGB LED */ +#define RGB_DI_PIN B3 +#define RGBLIGHT_TIMER +//#define RGBLED_NUM 12 // Number of LEDs. see ./keymaps/default/config.h +#define ws2812_PORTREG PORTD +#define ws2812_DDRREG DDRD + +#define DRIVER_COUNT 2 +#define DRIVER_LED_TOTAL 70 +// #define RGB_MATRIX_KEYPRESSES +#define BACKLIGHT_PIN B7 +#define BACKLIGHT_LEVELS 5 + +#ifdef LED_MIRRORED + #define RGBLED_NUM 35 +#else + #define RGBLED_NUM 70 +#endif + +#define RGBLIGHT_RAINBOW_SWIRL_RANGE 1950 + +#ifdef IOS_DEVICE_ENABLE + #define RGBLIGHT_LIMIT_VAL 40 + #define RGB_MATRIX_MAXIMUM_BRIGHTNESS 40 +#elif RGBLIGHT_FULL_POWER + #define RGBLIGHT_LIMIT_VAL 255 + #define RGB_MATRIX_MAXIMUM_BRIGHTNESS 255 +#else + #define RGBLIGHT_LIMIT_VAL 120 + #define RGB_MATRIX_MAXIMUM_BRIGHTNESS 120 +#endif + +#define RGBLIGHT_VAL_STEP (RGBLIGHT_LIMIT_VAL / 10) +#define RGBLIGHT_HUE_STEP 10 +#define RGBLIGHT_SAT_STEP 17 + +#define RGBLIGHT_ANIMATIONS + +#if defined(RGBLIGHT_ENABLE) && !defined(IOS_DEVICE_ENABLE) +// USB_MAX_POWER_CONSUMPTION value for Helix keyboard +// 120 RGBoff, OLEDoff +// 120 OLED +// 330 RGB 6 +// 300 RGB 32 +// 310 OLED & RGB 32 + #define USB_MAX_POWER_CONSUMPTION 500 +#else + // fix iPhone and iPad power adapter issue + // iOS device need lessthan 100 + #define USB_MAX_POWER_CONSUMPTION 100 +#endif + +/* + * Feature disable options + * These options are also useful to firmware size reduction. + */ + +/* disable debug print */ +// #define NO_DEBUG + +/* disable print */ +// #define NO_PRINT + +/* disable action features */ +//#define NO_ACTION_LAYER +//#define NO_ACTION_TAPPING +//#define NO_ACTION_ONESHOT +//#define NO_ACTION_MACRO +//#define NO_ACTION_FUNCTION + + +#endif diff --git a/keyboards/sol/rev1/matrix.c b/keyboards/sol/rev1/matrix.c new file mode 100644 index 0000000000..804d8b9809 --- /dev/null +++ b/keyboards/sol/rev1/matrix.c @@ -0,0 +1,304 @@ +/* +Copyright 2012 Jun Wako + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +/* + * scan matrix + */ +#include +#include +#include +#include +#include +#include +#include "print.h" +#include "debug.h" +#include "util.h" +#include "matrix.h" +#include "split_util.h" +#include + +#include "serial.h" + +#ifndef DEBOUNCE +# define DEBOUNCE 5 +#endif + +#ifdef ENCODER_ENABLE_CUSTOM + #include "common/knob_v2.h" +#endif + +#define ERROR_DISCONNECT_COUNT 5 + +static uint8_t debouncing = DEBOUNCE; +static const int ROWS_PER_HAND = MATRIX_ROWS/2; +static uint8_t error_count = 0; +uint8_t is_master = 0 ; + +static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; +static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; + +/* matrix state(1:on, 0:off) */ +static matrix_row_t matrix[MATRIX_ROWS]; +static matrix_row_t matrix_debouncing[MATRIX_ROWS]; + +static matrix_row_t read_cols(void); +static void init_cols(void); +static void unselect_rows(void); +static void select_row(uint8_t row); +static uint8_t matrix_master_scan(void); + + +__attribute__ ((weak)) +void matrix_init_kb(void) { + matrix_init_user(); +} + +__attribute__ ((weak)) +void matrix_scan_kb(void) { + matrix_scan_user(); +} + +__attribute__ ((weak)) +void matrix_init_user(void) { +} + +__attribute__ ((weak)) +void matrix_scan_user(void) { +} + +inline +uint8_t matrix_rows(void) +{ + return MATRIX_ROWS; +} + +inline +uint8_t matrix_cols(void) +{ + return MATRIX_COLS; +} + +void matrix_init(void) +{ + debug_enable = true; + debug_matrix = true; + debug_mouse = true; + // initialize row and col + unselect_rows(); + init_cols(); + + TX_RX_LED_INIT; + + // initialize matrix state: all keys off + for (uint8_t i=0; i < MATRIX_ROWS; i++) { + matrix[i] = 0; + matrix_debouncing[i] = 0; + } + + is_master = has_usb(); + + #ifdef ENCODER_ENABLE_CUSTOM + knob_init(); //FOR ENCODER + #endif + matrix_init_quantum(); +} + +uint8_t _matrix_scan(void) +{ + // Right hand is stored after the left in the matirx so, we need to offset it + int offset = isLeftHand ? 0 : (ROWS_PER_HAND); + + for (uint8_t i = 0; i < ROWS_PER_HAND; i++) { + select_row(i); + _delay_us(30); // without this wait read unstable value. + matrix_row_t cols = read_cols(); + if (matrix_debouncing[i+offset] != cols) { + matrix_debouncing[i+offset] = cols; + debouncing = DEBOUNCE; + } + unselect_rows(); + } + + if (debouncing) { + if (--debouncing) { + _delay_ms(1); + } else { + for (uint8_t i = 0; i < ROWS_PER_HAND; i++) { + matrix[i+offset] = matrix_debouncing[i+offset]; + } + } + } + + #ifdef ENCODER_ENABLE_CUSTOM + knob_report_t knob_report = knob_report_read(); + + knob_report_reset(); + + matrix[5 + offset] &= 0b11111100; + if (knob_report.phase) { // I check for phase to avoid handling the rotation twice (on 90 and 270 degrees). + if (knob_report.dir > 0) { + matrix[5 + offset] |= 0b00000001; + } else if (knob_report.dir < 0) { + matrix[5 + offset] |= 0b00000010; + } + } + #endif + + return 1; +} + +int serial_transaction(void) { + int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; + int ret=serial_update_buffers(); + if (ret ) { + return 1; + } + + for (int i = 0; i < ROWS_PER_HAND; ++i) { + matrix[slaveOffset+i] = serial_slave_buffer[i]; + } + return 0; +} + +uint8_t matrix_scan(void) +{ + if (is_master) { + matrix_master_scan(); + }else{ + matrix_slave_scan(); + + int offset = (isLeftHand) ? ROWS_PER_HAND : 0; + + for (int i = 0; i < ROWS_PER_HAND; ++i) { + matrix[offset+i] = serial_master_buffer[i]; + } + + matrix_scan_quantum(); + } + return 1; +} + + +uint8_t matrix_master_scan(void) { + + int ret = _matrix_scan(); + + int offset = (isLeftHand) ? 0 : ROWS_PER_HAND; + + for (int i = 0; i < ROWS_PER_HAND; ++i) { + serial_master_buffer[i] = matrix[offset+i]; + } + + if( serial_transaction() ) { + // turn on the indicator led when halves are disconnected + TXLED1; + + error_count++; + + if (error_count > ERROR_DISCONNECT_COUNT) { + // reset other half if disconnected + int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; + for (int i = 0; i < ROWS_PER_HAND; ++i) { + matrix[slaveOffset+i] = 0; + } + } + } else { + // turn off the indicator led on no error + TXLED0; + error_count = 0; + } + matrix_scan_quantum(); + return ret; +} + +void matrix_slave_scan(void) { + _matrix_scan(); + + int offset = (isLeftHand) ? 0 : ROWS_PER_HAND; + + for (int i = 0; i < ROWS_PER_HAND; ++i) { + serial_slave_buffer[i] = matrix[offset+i]; + } +} + +bool matrix_is_modified(void) +{ + if (debouncing) return false; + return true; +} + +inline +bool matrix_is_on(uint8_t row, uint8_t col) +{ + return (matrix[row] & ((matrix_row_t)1<> 4) + 1) &= ~_BV(col_pins[x] & 0xF); + _SFR_IO8((col_pins[x] >> 4) + 2) |= _BV(col_pins[x] & 0xF); + } +} + +static matrix_row_t read_cols(void) +{ + matrix_row_t result = 0; + for(int x = 0; x < MATRIX_COLS; x++) { + result |= (_SFR_IO8(col_pins[x] >> 4) & _BV(col_pins[x] & 0xF)) ? 0 : (1 << x); + } + return result; +} + +static void unselect_rows(void) +{ + for(int x = 0; x < ROWS_PER_HAND; x++) { + _SFR_IO8((row_pins[x] >> 4) + 1) &= ~_BV(row_pins[x] & 0xF); + _SFR_IO8((row_pins[x] >> 4) + 2) |= _BV(row_pins[x] & 0xF); + } +} + +static void select_row(uint8_t row) +{ + _SFR_IO8((row_pins[row] >> 4) + 1) |= _BV(row_pins[row] & 0xF); + _SFR_IO8((row_pins[row] >> 4) + 2) &= ~_BV(row_pins[row] & 0xF); +} diff --git a/keyboards/sol/rev1/rev1.c b/keyboards/sol/rev1/rev1.c new file mode 100644 index 0000000000..01ab577d45 --- /dev/null +++ b/keyboards/sol/rev1/rev1.c @@ -0,0 +1,15 @@ +#include "sol.h" + + +#ifdef SSD1306OLED +void led_set_kb(uint8_t usb_led) { + // put your keyboard LED indicator (ex: Caps Lock LED) toggling code here + //led_set_user(usb_led); +} +#endif + +void matrix_init_kb(void) { + + matrix_init_user(); +}; + diff --git a/keyboards/sol/rev1/rev1.h b/keyboards/sol/rev1/rev1.h new file mode 100644 index 0000000000..27b5ac8966 --- /dev/null +++ b/keyboards/sol/rev1/rev1.h @@ -0,0 +1,70 @@ +#ifndef REV1_H +#define REV1_H + +#include "sol.h" + +//void promicro_bootloader_jmp(bool program); +#include "quantum.h" + +#ifdef RGBLIGHT_ENABLE +//rgb led driver +#include "ws2812.h" +#endif + +#ifdef USE_I2C +#include +#ifdef __AVR__ + #include + #include +#endif +#endif + +//void promicro_bootloader_jmp(bool program); +// LEL/LER/REL/RER are +// LeftEncoderLeft, LeftEncoderRight, RightEncoderLeft, and RightEncoderRight + +#define LAYOUT( \ + L00, L01, L02, L03, L04, L05, L06, R06, R00, R01, R02, R03, R04, R05, \ + L10, L11, L12, L13, L14, L15, L16, R16, R10, R11, R12, R13, R14, R15, \ + L20, L21, L22, L23, L24, L25, L26, R26, R20, R21, R22, R23, R24, R25, \ + L30, L31, L32, L33, L34, L35, L36, R36, R30, R31, R32, R33, R34, R35, \ + L40, L41, L42, L43, L44, L45, L46, R46, R40, R41, R42, R43, R44, R45, \ + LEL, LER, L55, L56, R56, R50, REL, RER \ + ) \ + { \ + { L00, L01, L02, L03, L04, L05, L06 }, \ + { L10, L11, L12, L13, L14, L15, L16 }, \ + { L20, L21, L22, L23, L24, L25, L26 }, \ + { L30, L31, L32, L33, L34, L35, L36 }, \ + { L40, L41, L42, L43, L44, L45, L46 }, \ + { LEL, LER, KC_NO, KC_NO, KC_NO, L55, L56 }, \ + { R05, R04, R03, R02, R01, R00, R06 }, \ + { R15, R14, R13, R12, R11, R10, R16 }, \ + { R25, R24, R23, R22, R21, R20, R26 }, \ + { R35, R34, R33, R32, R31, R30, R36 }, \ + { R45, R44, R43, R42, R41, R40, R46 }, \ + { REL, RER, KC_NO, KC_NO, KC_NO, R50, R56 } \ + } + +#define KC________ KC_TRNS +#define KC_RGB_MOD RGB_MOD +#define KC_FN FN +#define KC_ADJ ADJ +#define LAYOUT_kc( \ + L00, L01, L02, L03, L04, L05, L06, R06, R00, R01, R02, R03, R04, R05, \ + L10, L11, L12, L13, L14, L15, L16, R16, R10, R11, R12, R13, R14, R15, \ + L20, L21, L22, L23, L24, L25, L26, R26, R20, R21, R22, R23, R24, R25, \ + L30, L31, L32, L33, L34, L35, L36, R36, R30, R31, R32, R33, R34, R35, \ + L40, L41, L42, L43, L44, L45, L46, R46, R40, R41, R42, R43, R44, R45, \ + LEL, LER, L55, L56, R56, R50, REL, RER \ + ) \ + LAYOUT( \ + KC_##L00, KC_##L01, KC_##L02, KC_##L03, KC_##L04, KC_##L05, KC_##L06, KC_##R06, KC_##R00, KC_##R01, KC_##R02, KC_##R03, KC_##R04, KC_##R05, \ + KC_##L10, KC_##L11, KC_##L12, KC_##L13, KC_##L14, KC_##L15, KC_##L16, KC_##R16, KC_##R10, KC_##R11, KC_##R12, KC_##R13, KC_##R14, KC_##R15, \ + KC_##L20, KC_##L21, KC_##L22, KC_##L23, KC_##L24, KC_##L25, KC_##L26, KC_##R26, KC_##R20, KC_##R21, KC_##R22, KC_##R23, KC_##R24, KC_##R25, \ + KC_##L30, KC_##L31, KC_##L32, KC_##L33, KC_##L34, KC_##L35, KC_##L36, KC_##R36, KC_##R30, KC_##R31, KC_##R32, KC_##R33, KC_##R34, KC_##R35, \ + KC_##L40, KC_##L41, KC_##L42, KC_##L43, KC_##L44, KC_##L45, KC_##L46, KC_##R46, KC_##R40, KC_##R41, KC_##R42, KC_##R43, KC_##R44, KC_##R45, \ + KC_##LEL, KC_##LER, KC_##L55, KC_##L56, KC_##R56, KC_##R50, KC_##REL, KC_##RER \ + ) + +#endif diff --git a/keyboards/sol/rev1/rules.mk b/keyboards/sol/rev1/rules.mk new file mode 100644 index 0000000000..99f4dd896c --- /dev/null +++ b/keyboards/sol/rev1/rules.mk @@ -0,0 +1,2 @@ +SRC += rev1/matrix.c \ + rev1/split_util.c diff --git a/keyboards/sol/rev1/split_util.c b/keyboards/sol/rev1/split_util.c new file mode 100644 index 0000000000..c645bbdfef --- /dev/null +++ b/keyboards/sol/rev1/split_util.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include +#include +#include "split_util.h" +#include "matrix.h" +#include "keyboard.h" +#include "serial.h" + +volatile bool isLeftHand = true; + +static void setup_handedness(void) { + #ifdef EE_HANDS + isLeftHand = eeprom_read_byte(EECONFIG_HANDEDNESS); + #else + #if defined(MASTER_RIGHT) + isLeftHand = !has_usb(); + #else + isLeftHand = has_usb(); + #endif + #endif +} + +static void keyboard_master_setup(void) { + serial_master_init(); +} + +static void keyboard_slave_setup(void) { + serial_slave_init(); +} + +bool has_usb(void) { + USBCON |= (1 << OTGPADE); //enables VBUS pad + _delay_us(5); + return (USBSTA & (1< +#include "eeconfig.h" + +extern volatile bool isLeftHand; + +// slave version of matix scan, defined in matrix.c +void matrix_slave_scan(void); + +void split_keyboard_setup(void); +bool has_usb(void); + +void matrix_master_OLED_init (void); + +#endif -- cgit v1.2.3 From a5b43b35fe7543c7d146029b05b8c6a13f17cd3e Mon Sep 17 00:00:00 2001 From: noroadsleft <18669334+noroadsleft@users.noreply.github.com> Date: Thu, 6 Dec 2018 07:27:04 -0800 Subject: Sol rev1 Configurator support (#4562) Adds Configurator support for the Sol rev. 1 by RGBKB. Notes: The Sol keyboard supports split thumb keys like the Ergodox - any of the 2u thumb keys can be split into two 1u keys. The matrix here is configured for fully 1u keys on the thumbs. The Sol also supports installing a rotary encoder on each half. The key matrix given includes the encoders' functions, which are shown in the Configurator as two 1u keys side by side below each half's main key block. The left key of the two (for each side) represents that half's rotary encoder's counter-clockwise function, and the right key is that encoder's clockwise function. --- keyboards/sol/rev1/info.json | 91 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 keyboards/sol/rev1/info.json (limited to 'keyboards/sol/rev1') diff --git a/keyboards/sol/rev1/info.json b/keyboards/sol/rev1/info.json new file mode 100644 index 0000000000..40bc01f7ff --- /dev/null +++ b/keyboards/sol/rev1/info.json @@ -0,0 +1,91 @@ +{ + "keyboard_name": "Sol", + "url": "", + "maintainer": "Legonut", + "width": 17, + "height": 6.5, + "layouts": { + "LAYOUT": { + "layout": [ + {"label":"L00", "x":0, "y":0, "w":1.5}, + {"label":"L01", "x":1.5, "y":0}, + {"label":"L02", "x":2.5, "y":0}, + {"label":"L03", "x":3.5, "y":0}, + {"label":"L04", "x":4.5, "y":0}, + {"label":"L05", "x":5.5, "y":0}, + {"label":"L06", "x":6.75, "y":0}, + {"label":"R06", "x":9.25, "y":0}, + {"label":"R00", "x":10.5, "y":0}, + {"label":"R01", "x":11.5, "y":0}, + {"label":"R02", "x":12.5, "y":0}, + {"label":"R03", "x":13.5, "y":0}, + {"label":"R04", "x":14.5, "y":0}, + {"label":"R05", "x":15.5, "y":0, "w":1.5}, + {"label":"L10", "x":0, "y":1, "w":1.5}, + {"label":"L11", "x":1.5, "y":1}, + {"label":"L12", "x":2.5, "y":1}, + {"label":"L13", "x":3.5, "y":1}, + {"label":"L14", "x":4.5, "y":1}, + {"label":"L15", "x":5.5, "y":1}, + {"label":"L16", "x":6.75, "y":1}, + {"label":"R16", "x":9.25, "y":1}, + {"label":"R10", "x":10.5, "y":1}, + {"label":"R11", "x":11.5, "y":1}, + {"label":"R12", "x":12.5, "y":1}, + {"label":"R13", "x":13.5, "y":1}, + {"label":"R14", "x":14.5, "y":1}, + {"label":"R15", "x":15.5, "y":1, "w":1.5}, + {"label":"L20", "x":0, "y":2, "w":1.5}, + {"label":"L21", "x":1.5, "y":2}, + {"label":"L22", "x":2.5, "y":2}, + {"label":"L23", "x":3.5, "y":2}, + {"label":"L24", "x":4.5, "y":2}, + {"label":"L25", "x":5.5, "y":2}, + {"label":"L26", "x":6.75, "y":2}, + {"label":"R26", "x":9.25, "y":2}, + {"label":"R20", "x":10.5, "y":2}, + {"label":"R21", "x":11.5, "y":2}, + {"label":"R22", "x":12.5, "y":2}, + {"label":"R23", "x":13.5, "y":2}, + {"label":"R24", "x":14.5, "y":2}, + {"label":"R25", "x":15.5, "y":2, "w":1.5}, + {"label":"L30", "x":0, "y":3, "w":1.5}, + {"label":"L31", "x":1.5, "y":3}, + {"label":"L32", "x":2.5, "y":3}, + {"label":"L33", "x":3.5, "y":3}, + {"label":"L34", "x":4.5, "y":3}, + {"label":"L35", "x":5.5, "y":3}, + {"label":"L36", "x":6.75, "y":3}, + {"label":"R36", "x":9.25, "y":3}, + {"label":"R30", "x":10.5, "y":3}, + {"label":"R31", "x":11.5, "y":3}, + {"label":"R32", "x":12.5, "y":3}, + {"label":"R33", "x":13.5, "y":3}, + {"label":"R34", "x":14.5, "y":3}, + {"label":"R35", "x":15.5, "y":3, "w":1.5}, + {"label":"L40", "x":0, "y":4, "w":1.5}, + {"label":"L41", "x":1.5, "y":4}, + {"label":"L42", "x":2.5, "y":4}, + {"label":"L43", "x":3.5, "y":4}, + {"label":"L44", "x":4.5, "y":4}, + {"label":"L45", "x":6, "y":4.5}, + {"label":"L46", "x":7, "y":4.5}, + {"label":"R46", "x":9, "y":4.5}, + {"label":"R40", "x":10, "y":4.5}, + {"label":"R41", "x":11.5, "y":4}, + {"label":"R42", "x":12.5, "y":4}, + {"label":"R43", "x":13.5, "y":4}, + {"label":"R44", "x":14.5, "y":4}, + {"label":"R45", "x":15.5, "y":4, "w":1.5}, + {"label":"Left Encoder, Counter-Clockwise", "x":2.5, "y":5.5}, + {"label":"Left Encoder, Clockwise", "x":3.5, "y":5.5}, + {"label":"L55", "x":6, "y":5.5}, + {"label":"L56", "x":7, "y":5.5}, + {"label":"R56", "x":9, "y":5.5}, + {"label":"R50", "x":10, "y":5.5}, + {"label":"Right Encoder, Counter-Clockwise", "x":12.5, "y":5.5}, + {"label":"Right Encoder, Clockwise", "x":13.5, "y":5.5} + ] + } + } +} -- cgit v1.2.3