├── .gitignore ├── arduino └── scout │ ├── Frequency.cpp │ ├── Frequency.h │ ├── KeyBuffer.cpp │ ├── KeyBuffer.h │ ├── Notes.cpp │ ├── Notes.h │ └── scout.ino ├── assembly_guide ├── README.md ├── babel.config.js ├── docs │ ├── 3d-printing-parts-and-slicing.md │ ├── 3d-printing-post-processing.md │ ├── assemble-battery-pack.md │ ├── assemble-bottom.md │ ├── assemble-top.md │ ├── assembly-troubleshooting.md │ ├── bom.md │ ├── boot-the-microcontroller.md │ ├── care.md │ ├── change-the-arduino-code.md │ ├── community-hacks.md │ ├── final-assembly.md │ ├── general-tips.md │ ├── get-logical.md │ ├── get-loud.md │ ├── get-louder.md │ ├── inventory.md │ ├── make-some-noise.md │ ├── more-notes.md │ ├── opening-the-enclosure.md │ ├── pcb-troubleshooting.md │ ├── power-up.md │ ├── prep-for-hacking.md │ ├── schematics.md │ ├── source-and-license.md │ ├── the-chord-problem.md │ └── what-youll-be-making.md ├── docusaurus.config.js ├── package-lock.json ├── package.json ├── sidebars.js ├── src │ ├── css │ │ └── custom.css │ └── pages │ │ └── styles.module.css └── static │ ├── .nojekyll │ └── img │ ├── favicon.ico │ ├── final_assembly │ ├── battery_holder.jpg │ ├── enclosure.jpg │ ├── insert_screws.jpg │ ├── keys.jpg │ ├── keys_mount_rail.jpg │ ├── knob.jpg │ ├── nuts.jpg │ ├── pcb.jpg │ ├── screws.jpg │ ├── speaker.jpg │ └── switch_clutch.jpg │ ├── hack │ ├── chord-cde.png │ ├── chord-edc.png │ ├── chord-individual.png │ ├── matrix-f_sharp.png │ ├── matrix-trio.png │ ├── matrix.png │ └── serial-plotter.png │ ├── keys_endstop.gif │ ├── pcb_assembly │ ├── 010201@0.5x.jpg │ ├── 010302@0.5x.jpg │ ├── 010303@0.5x.jpg │ ├── 010306@0.5x.jpg │ ├── 010308@0.5x.jpg │ ├── 020101@0.5x.jpg │ ├── 020102@0.5x.jpg │ ├── 020400@0.5x.jpg │ ├── 030400@0.5x.jpg │ ├── 040200@0.5x.jpg │ ├── 050300@0.5x.jpg │ ├── 060201@0.5x.jpg │ ├── 060500@0.5x.jpg │ ├── 070200@0.5x.jpg │ ├── 090200@0.5x.jpg │ ├── battery_tabs.jpg │ └── button_alignment.jpg │ ├── print_supports.gif │ ├── remove_print_support.jpg │ ├── schematics │ ├── keyboard_matrix-keyboard_matrix.svg │ └── scout.svg │ ├── scout-10-838-032.gif │ ├── scout.jpg │ ├── scout_3d_printed_parts.png │ ├── scout_assembly-16-420-8-128.gif │ ├── scout_pieces.png │ ├── scout_render.png │ ├── video-how_to_open.jpg │ └── video.jpg ├── burn_chip.sh ├── kicad ├── keyboard_matrix │ ├── fp-info-cache │ ├── keyboard_matrix-cache.lib │ ├── keyboard_matrix.kicad_pcb │ ├── keyboard_matrix.kicad_pcb-bak │ ├── keyboard_matrix.pro │ ├── keyboard_matrix.sch │ └── keyboard_matrix.sch-bak ├── scout │ ├── fp-lib-table │ ├── keyboard_matrix.sch │ ├── keyboard_matrix.sch-bak │ ├── scout-brd.svg │ ├── scout-cache.lib │ ├── scout.kicad_pcb │ ├── scout.kicad_pcb-bak │ ├── scout.pretty │ │ ├── branding.kicad_mod │ │ ├── logo.kicad_mod │ │ └── scout_back_2.kicad_mod │ ├── scout.pro │ ├── scout.sch │ └── scout.sch-bak └── svg2shenzhen │ ├── back.svg │ ├── branding.svg │ └── logo.svg ├── license.txt ├── make_stls.sh ├── openscad ├── batteries.scad ├── battery_contacts.scad ├── battery_holder.scad ├── enclosure.scad ├── enclosure_engraving.scad ├── enclosure_screw_cavities.scad ├── headphone_jack.scad ├── key_lip_endstop.scad ├── keys.scad ├── nuts_and_bolts.scad ├── pcb_fixtures.scad ├── pcb_mounting_columns.scad ├── pcb_stool.scad ├── scout.scad ├── scout_display.scad ├── scout_pcb.scad ├── speaker.scad ├── switch.scad ├── switch_clutch.scad └── utils.scad ├── print ├── fully_assembled-inserts.svg ├── inserts.pdf ├── inserts.svg ├── label_single-2.4.svg ├── label_single-pcb-2.4-min.svg ├── label_single-pcb-2.4.svg └── labels.svg └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | local/ 4 | build/ 5 | 6 | *.bin 7 | *.eep 8 | *.elf 9 | *.hex 10 | 11 | fp-info-cache 12 | 13 | # DOCUSAURUS 14 | 15 | # Dependencies 16 | assembly_guide/node_modules 17 | 18 | # Production 19 | assembly_guide/build 20 | 21 | # Generated files 22 | .docusaurus 23 | .cache-loader 24 | 25 | # Misc 26 | .env.local 27 | .env.development.local 28 | .env.test.local 29 | .env.production.local 30 | 31 | npm-debug.log* 32 | yarn-debug.log* 33 | yarn-error.log* 34 | 35 | kicad/*/*-backups/ 36 | -------------------------------------------------------------------------------- /arduino/scout/Frequency.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "Frequency.h" 3 | #include "Notes.h" 4 | 5 | Frequency::Frequency(float glide, int cyclesPerGlideMax) { 6 | _glide = glide; 7 | _cyclesPerGlideMax = cyclesPerGlideMax; 8 | } 9 | 10 | float Frequency::get() { 11 | return _frequency; 12 | } 13 | 14 | void Frequency::update(float target) { 15 | _target = target; 16 | bool needsUpdate = _frequency != _target; 17 | 18 | if (needsUpdate) { 19 | if ((_frequency == 0) || (_glide == 0)) { 20 | _frequency = _target; 21 | } else { 22 | if (_target != _previousTarget) { 23 | _glideStep = abs(_target - _previousTarget) 24 | / (_glide * _cyclesPerGlideMax); 25 | } 26 | 27 | _frequency = (_target > _frequency) 28 | ? min(_target, _frequency + _glideStep) 29 | : max(_target, _frequency - _glideStep); 30 | } 31 | } 32 | 33 | if (!needsUpdate) { 34 | _previousTarget = _target; 35 | } 36 | } 37 | 38 | void Frequency::reset() { 39 | _frequency = 0; 40 | } 41 | 42 | void Frequency::print() { 43 | Serial.println( 44 | "frequency:" + String(_frequency) 45 | + ",target:" + String(_target) 46 | + ",previousTargetFrequency:" + String(_previousTarget) 47 | ); 48 | } 49 | -------------------------------------------------------------------------------- /arduino/scout/Frequency.h: -------------------------------------------------------------------------------- 1 | #ifndef Frequency_h 2 | #define Frequency_h 3 | 4 | #include "Arduino.h" 5 | #include "Notes.h" 6 | 7 | class Frequency { 8 | public: 9 | Frequency(float glide, int cyclesPerGlideMax); 10 | void update(float target); 11 | float get(); 12 | void reset(); 13 | void print(); 14 | private: 15 | float _frequency = 0; 16 | float _glide; 17 | float _glideStep; 18 | float _previousTarget; 19 | float _target; 20 | int _cyclesPerGlideMax; 21 | }; 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /arduino/scout/KeyBuffer.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "KeyBuffer.h" 3 | 4 | #define CIRCULAR_BUFFER_DEBUG 5 | #include 6 | #include 7 | 8 | const byte ROWS = 4; 9 | const byte COLS = 5; 10 | byte key_indexes[ROWS][COLS] = { 11 | {1, 5, 9, 12, 15}, 12 | {2, 6, 10, 13, 16}, 13 | {3, 7, 11, 14, 17}, 14 | {4, 8} 15 | }; 16 | byte rowPins[ROWS] = {7, 8, 9, 10}; 17 | byte colPins[COLS] = {2, 3, 4, 5, 6}; 18 | 19 | Keypad _buttons = Keypad(makeKeymap(key_indexes), rowPins, colPins, ROWS, COLS); 20 | 21 | KeyBuffer::KeyBuffer() { 22 | CircularBuffer _buffer; 23 | 24 | const int KEYPAD_LIBRARY_MINIMUM_DEBOUNCE = 1; 25 | _buttons.setDebounceTime(KEYPAD_LIBRARY_MINIMUM_DEBOUNCE); 26 | } 27 | 28 | bool KeyBuffer::isEmpty() { 29 | return _buffer.isEmpty(); 30 | } 31 | 32 | bool KeyBuffer::isInBuffer(int c) { 33 | bool value = false; 34 | 35 | if (!_buffer.isEmpty()) { 36 | for (int i = 0; i < _buffer.size(); i++) { 37 | if (c == _buffer[i]) { 38 | value = true; 39 | break; 40 | } 41 | } 42 | } 43 | 44 | return value; 45 | } 46 | 47 | bool KeyBuffer::removeFromBuffer(int c) { 48 | int newStack[BUFFER_MAX - 1] = {}; 49 | int newI = 0; 50 | 51 | bool hasRemoval = false; 52 | 53 | for (int i = 0; i < _buffer.size(); i++) { 54 | if (c != _buffer[i]) { 55 | newStack[newI++] = _buffer[i]; 56 | } else { 57 | hasRemoval = true; 58 | } 59 | } 60 | 61 | if (hasRemoval) { 62 | _buffer.clear(); 63 | 64 | for (byte i = 0; i < newI; i++) { 65 | _buffer.push(newStack[i]); 66 | } 67 | } 68 | } 69 | 70 | void KeyBuffer::populate() { 71 | bool isActive = false; 72 | 73 | _buttons.getKeys(); // populate keys 74 | 75 | for (int i = 0; i < LIST_MAX; i++) { 76 | byte kstate = _buttons.key[i].kstate; 77 | byte kchar = _buttons.key[i].kchar - 1; 78 | 79 | if (kstate == PRESSED || kstate == HOLD) { 80 | if (!isInBuffer(kchar)) { 81 | _buffer.unshift(kchar); 82 | } 83 | 84 | isActive = true; 85 | } else if (isInBuffer(kchar)) { 86 | removeFromBuffer(kchar); 87 | } 88 | } 89 | 90 | if (!isActive) { 91 | _buffer.clear(); 92 | } 93 | } 94 | 95 | void KeyBuffer::print() { 96 | if (!_buffer.isEmpty()) { 97 | Serial.print("["); 98 | for (int i = 0; i < _buffer.size(); i++) { 99 | Serial.print(_buffer[i]); 100 | 101 | if (i < _buffer.size() - 1) { 102 | Serial.print(","); 103 | } 104 | } 105 | Serial.print( 106 | "] (" 107 | + String(_buffer.size()) + "/" + String(BUFFER_MAX) 108 | + ")" 109 | ); 110 | Serial.println(); 111 | } 112 | } 113 | 114 | char KeyBuffer::getFirst() { 115 | return _buffer.first(); 116 | } 117 | -------------------------------------------------------------------------------- /arduino/scout/KeyBuffer.h: -------------------------------------------------------------------------------- 1 | #define CIRCULAR_BUFFER_DEBUG 2 | #include 3 | #include 4 | 5 | #ifndef KeyBuffer_h 6 | #define KeyBuffer_h 7 | 8 | #include "Arduino.h" 9 | 10 | #define BUFFER_MAX 4 11 | 12 | class KeyBuffer { 13 | public: 14 | KeyBuffer(); 15 | bool isEmpty(); 16 | char getFirst(); 17 | void print(); 18 | void printBuffer(); 19 | void populate(); 20 | private: 21 | CircularBuffer _buffer; 22 | bool isInBuffer(int c); 23 | bool removeFromBuffer(int c); 24 | }; 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /arduino/scout/Notes.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "Notes.h" 3 | 4 | const float MIDDLE_A = 440; 5 | const float FREQUENCY_RATIO = 1.059463; // magic! 2 to the power of 1/12 6 | 7 | float getNoteFrequency(int distance, float origin = MIDDLE_A) { 8 | return origin * pow(FREQUENCY_RATIO, distance); 9 | } 10 | 11 | Notes::Notes(int startingNoteDistanceFromMiddleA) { 12 | for (int i = 0; i < NOTES_COUNT; i++) { 13 | _notes[i] = getNoteFrequency(startingNoteDistanceFromMiddleA + i); 14 | } 15 | } 16 | 17 | float Notes::get(int i) { 18 | return _notes[i]; 19 | } 20 | -------------------------------------------------------------------------------- /arduino/scout/Notes.h: -------------------------------------------------------------------------------- 1 | #ifndef Notes_h 2 | #define Notes_h 3 | 4 | #include "Arduino.h" 5 | 6 | const int NOTES_COUNT = 17; 7 | 8 | class Notes { 9 | public: 10 | Notes(int startingNoteDistanceFromMiddleA); 11 | float get(int i); 12 | private: 13 | float _notes[NOTES_COUNT]; 14 | }; 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /arduino/scout/scout.ino: -------------------------------------------------------------------------------- 1 | #include "Frequency.h" 2 | #include "KeyBuffer.h" 3 | #include "Notes.h" 4 | 5 | // SETTINGS 6 | int octave = 3; 7 | float glide = .25; 8 | bool glideOnFreshKeyPresses = true; 9 | bool printToSerial = false; 10 | 11 | const int CYCLES_PER_GLIDE_MAX = printToSerial ? 25 : 250; 12 | const int STARTING_NOTE_DISTANCE_FROM_MIDDLE_A = -9; 13 | 14 | const int SPEAKER_PIN = 11; 15 | 16 | Notes notes(STARTING_NOTE_DISTANCE_FROM_MIDDLE_A); 17 | KeyBuffer buffer; 18 | Frequency frequency(glide, CYCLES_PER_GLIDE_MAX); 19 | 20 | void blink(int count = 2, int wait = 200) { 21 | while (count >= 0) { 22 | digitalWrite(LED_BUILTIN, HIGH); 23 | delay(wait); 24 | digitalWrite(LED_BUILTIN, LOW); 25 | delay(wait); 26 | 27 | count = count - 1; 28 | } 29 | } 30 | 31 | void setup() { 32 | Serial.begin(9600); 33 | pinMode(LED_BUILTIN, OUTPUT); 34 | 35 | blink(); 36 | } 37 | 38 | void loop() { 39 | buffer.populate(); 40 | 41 | if (printToSerial) { 42 | frequency.print(); 43 | } 44 | 45 | if (buffer.isEmpty()) { 46 | if (!glideOnFreshKeyPresses) { 47 | frequency.reset(); 48 | } 49 | 50 | noTone(SPEAKER_PIN); 51 | digitalWrite(LED_BUILTIN, LOW); 52 | } else { 53 | frequency.update(notes.get(buffer.getFirst()) / 4 * pow(2, octave)); 54 | 55 | tone(SPEAKER_PIN, frequency.get()); 56 | digitalWrite(LED_BUILTIN, HIGH); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /assembly_guide/README.md: -------------------------------------------------------------------------------- 1 | # Website 2 | 3 | This website is built using [Docusaurus 2](https://v2.docusaurus.io/), a modern static website generator. 4 | 5 | ## Installation 6 | 7 | ```console 8 | yarn install 9 | ``` 10 | 11 | ## Local Development 12 | 13 | ```console 14 | yarn start 15 | ``` 16 | 17 | This command starts a local development server and open up a browser window. Most changes are reflected live without having to restart the server. 18 | 19 | ## Build 20 | 21 | ```console 22 | yarn build 23 | ``` 24 | 25 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 26 | 27 | ## Deployment 28 | 29 | ```console 30 | GIT_USER= USE_SSH=true yarn deploy 31 | ``` 32 | 33 | If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. 34 | -------------------------------------------------------------------------------- /assembly_guide/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /assembly_guide/docs/3d-printing-parts-and-slicing.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: 3d-printing-parts-and-slicing 3 | title: 3D-Printing Parts and Slicing 4 | description: How to 3D-print your Scout's parts. 5 | sidebar_label: Parts and Slicing 6 | image: /img/scout_3d_printed_parts.png 7 | slug: /3d-printing-parts-and-slicing 8 | --- 9 | 10 | :::note 11 | If you bought a kit with 3D-printed parts included, you can skip this section, but do [open up the enclosure](opening-the-enclosure.md) and confirm you have all the right pieces ready before continuing. 12 | ::: 13 | 14 | ## Download 15 | 16 | ![Scout 3D-printed parts](/img/scout_3d_printed_parts.png) 17 | 18 | Download STLs of the models on [Thingiverse](https://www.thingiverse.com/thing:4933700) or [PrusaPrinters](https://www.prusaprinters.org/prints/76472-scout-synth). 19 | 20 | ## Slicing 21 | 22 | There are seven files to print, taking about 11 hours total. 23 | 24 | | Part | Layer Height | Supports? | Color change at height | Estimated Time | 25 | | ---------------- | ------------ | --------- | ---------------------- | -------------- | 26 | | battery_holder | .2mm | No | n/a | 40min | 27 | | enclosure_bottom | .2mm | No | n/a | 3hr 10min | 28 | | enclosure_top | .2mm | No | n/a | 3hr | 29 | | keys_mount_rail | .2mm | No | n/a | 30min | 30 | | keys | .2mm | No | 7.2mm | 3hr | 31 | | knob | .2mm | No | n/a | 20min | 32 | | switch_clutch | .2mm | No | n/a | 20min | 33 | 34 | **Notes:** 35 | 36 | - Models assume Fused Deposition Modeling with a standard .4mm nozzle. Using a bigger nozzle will likely result in a loss of detail (like missing "VOL" label text on the enclosure_top) and possibly missing internal walls. 37 | - You may find the bottoms of the keys stick together because the plastic has expanded too far into the gap between them. See if your slicer has a setting called something like ["Elephant foot compensation"](https://help.prusa3d.com/en/article/elephant-foot-compensation_114487). Otherwise you'll need to carefully cut off the excess plastic with a utility knife. 38 | - The 3D-printed parts were designed using PLA. Other filament types like ABS are not recommended and will likely have fit or tolerance issues. (If you find that you need to drill or file your prints, that's a good sign there'll be other problems too.) 39 | - 20% infill works well across all models. I wouldn't advise going lower than 15% on the keys. 40 | - Some slicers have trouble with the "color change" GCODE. Try a smaller test print first if you're unfamiliar, and maybe try "pause at layer" instead of "color change". 41 | - Any supports the models need they'll already have, they'll already be rotated to the correct orientation for printing, and they shouldn't need brims. Brims on the keys, in fact, could cause warping on removal. (If you're experimenting with not using FDM, try the `*-no_support` STLs that don't have supports.) 42 | - Watch the first couple layers of the enclosure pieces while printing, especially around the text engravings -- if you see bad adhesion, stop the print to remedy the situation and start again. 43 | - If the prints aren't fitting together well, check to see that the corners aren't bulging. See if your slicer has settings for "coasting" or "linear advance." 44 | - The enclosure_top and switch_clutch both have narrow support walls that will break off when they're done printing. 45 | - If your slicer has it, you can experiment with "variable layer height", but pay attention to the details on the enclosure's text engravings and the aforementioned supports. 46 | - Similarly, you may also like to play around with "ironing" the tops of the keys to make them shiny and flat. _This will significantly increase print time!_ 47 | -------------------------------------------------------------------------------- /assembly_guide/docs/3d-printing-post-processing.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: 3d-printing-post-processing 3 | title: 3D-Printing Post-Processing 4 | description: Getting your new 3D prints ready. 5 | sidebar_label: Post-Processing 6 | image: /img/scout_3d_printed_parts.png 7 | slug: /3d-printing-post-processing 8 | --- 9 | 10 | :::note 11 | If you bought a kit with 3D-printed parts included, you can skip this section, but do [open up the enclosure](opening-the-enclosure.md) and confirm you have all the right pieces ready before continuing. 12 | ::: 13 | 14 | ![Scout 3D-printed parts](/img/scout_3d_printed_parts.png) 15 | 16 | As a reminder, you should have seven new prints. From top to bottom: 17 | 18 | * knob 19 | * enclosure top 20 | * keys 21 | * keys mount rail 22 | * battery holder 23 | * switch clutch 24 | * enclosure bottom 25 | 26 | ## Post-processing 27 | 28 | The **enclosure top** and **switch clutch** pieces both have print supports, highlighted here: 29 | 30 | ![Built-in print supports on the Scout's enclosure top and switch clutch pieces](/img/print_supports.gif) 31 | 32 | 1. Snap off supports 33 | 2. Use a utility knife to trim off any excess plastic on the **enclosure top** 34 | 35 | ![Snap off support on enclosure top](/img/remove_print_support.jpg) 36 | 37 | ## Test fit before soldering 38 | 39 | :::note 40 | Optional, but it's a good idea to confirm the printed pieces are sized correctly now rather than after you're done soldering! 41 | ::: 42 | 43 | Try as many of these as you have patience for. All should be tight fits, doable with just your hands and without any pliers or other tools. (Take a sneak peek at the [Final Assembly](final-assembly.md) step if any are unclear.) 44 | 45 | * Insert volume potentiometer shaft into its **knob**'s cavity. 46 | * Pop the speaker into its circular cavity on the **enclosure bottom**. 47 | * Glide the keys mount rail onto its aligners on the **enclosure top**. 48 | * Try snapping the two **enclosure** halves together. It's an intentionally tight fit; be brave! 49 | 50 | If any pieces don't fit, verify the printed dimensions match what you expected as visualized in your slicing program. Revisit the slicing information in the [3D-Printing Parts and Slicing](3d-printing-parts-and-slicing.md) section. 51 | -------------------------------------------------------------------------------- /assembly_guide/docs/assemble-battery-pack.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: assemble-battery-pack 3 | title: Assemble battery pack 4 | description: How to assemble the Scout's battery pack. 5 | sidebar_label: Assemble battery pack 6 | image: /img/pcb_assembly/010308@0.5x.jpg 7 | slug: /assemble-battery-pack 8 | --- 9 | 10 | ## Steps 11 | 12 | 1. Insert tabbed battery contact terminals 13 | 1. The springed contact goes to the spot with a "-". 14 | 2. The flat, button contact goes near "+". Its button should face inward towards where the battery will be. 15 | 3. These tabbed contacts will have a tight fit! You can use pliers to push/pull them in, then fold their tabs over to hold them in place. 16 | ![battery_tabs](/img/pcb_assembly/battery_tabs.jpg) 17 | 2. Insert wire dual contacts 18 | 1. Again, springs go to "-" and buttons to "+". 19 | ![010201@0.5x.jpg](/img/pcb_assembly/010201@0.5x.jpg) 20 | 3. Add wire 21 | 1. Cut your ribbon cable into two pieces of about 7" and 3". 22 | 2. With the battery holder oriented so its "+" contact tab is on the left and "-" on the right, thread the 7" ribbon cable through the hitch on the left, about halfway though, and then split the bottom pair of wires. 23 | ![010302@0.5x.jpg](/img/pcb_assembly/010302@0.5x.jpg) 24 | 3. Thread the darker wire of the now separated pair through the channel on the bottom of the battery holder and up through the right hitch. (Your ribbon cable will probably have different colors, and that's okay! A common convention is to use the darker color for "-" and the lighter one for "+".) 25 | ![010303@0.5x.jpg](/img/pcb_assembly/010303@0.5x.jpg) 26 | 4. Strip 1/4" of insulation off that right wire and solder to its contact tab. Try not to melt the plastic around it! 27 | 5. Cut the wire on the left to meet its tab, then strip and solder it. 28 | 6. Separate and strip the other side of wires. Make sure they don't touch! 29 | ![010306@0.5x.jpg](/img/pcb_assembly/010306@0.5x.jpg) 30 | 7. Insert three AAA batteries, matching their "+" and "-" sides to the battery holder's labels. 31 | 32 | ## Test 33 | 34 | Using a multimeter, measure the total voltage on those two wires. It should measure the sum of the three individual batteries' voltages -- ideally 3.6 to 4.5, depending on what kind of batteries they are. When done, remove the batteries to prevent accidentally draining them if the exposed wires touch. 35 | 36 | ![010308@0.5x.jpg](/img/pcb_assembly/010308@0.5x.jpg) 37 | 38 | If you're having trouble with your multimeter, try measuring each battery individually and see if they read as you expect. Then install them into the battery pack and check their combined voltage. 39 | 40 | Not working as expected? Check the [PCB troubleshooting](pcb-troubleshooting.md) section. Otherwise, continue to the next step. 41 | -------------------------------------------------------------------------------- /assembly_guide/docs/assemble-bottom.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: assemble-bottom 3 | title: Assemble bottom 4 | description: How to assemble the Scout bottom, after soldering is done. 5 | sidebar_label: Assemble bottom 6 | image: /img/final_assembly/switch_clutch.jpg 7 | slug: /assemble-bottom 8 | --- 9 | 10 | :::note 11 | You're almost done! Take your time to follow the directions in order. 12 | 13 | And check out the [Assembly troubleshooting](assembly-troubleshooting.md) section if you run into any trouble. 14 | ::: 15 | 16 | ## Steps 17 | 18 | ### 1. Speaker 19 | 20 | Pop the **speaker** into its circular cavity on the **enclosure bottom** with the speaker's shiny side up. 21 | 22 | ![speaker](/img/final_assembly/speaker.jpg) 23 | 24 | ### 2. Battery holder 25 | 26 | Pop the **battery holder** into its cavity in the middle of the **enclosure bottom**. 27 | 28 | ![battery_holder](/img/final_assembly/battery_holder.jpg) 29 | 30 | ### 3. PCB 31 | 32 | Insert **PCB** onto the **enclosure bottom**, nestled into its aligners. 33 | 34 | ![pcb](/img/final_assembly/pcb.jpg) 35 | 36 | Orient the wires so that they're relatively contained within the space there and won't poke up into where the keys will be. 37 | 38 | ### 4. Switch clutch 39 | 40 | Add the **switch clutch** into its spot around the switch. 41 | 42 | ![switch_clutch](/img/final_assembly/switch_clutch.jpg) 43 | 44 | This piece is vertically symmetrical, so either way is fine. 45 | -------------------------------------------------------------------------------- /assembly_guide/docs/assemble-top.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: assemble-top 3 | title: Assemble top 4 | description: How to assemble the Scout top, after soldering is done. 5 | sidebar_label: Assemble top 6 | image: /img/final_assembly/keys_mount_rail.jpg 7 | slug: /assemble-top 8 | --- 9 | 10 | :::note 11 | You're almost done! Take your time to follow the directions in order. 12 | 13 | And check out the [Assembly troubleshooting](assembly-troubleshooting.md) section if you run into any trouble. 14 | ::: 15 | 16 | With the PCB done soldering and working, it's time to finish the job! Let's put the rest together, and we'll start with the top. 17 | 18 | ## Steps 19 | 20 | ### 1. Nuts 21 | 22 | Slide **square nuts** into nut locks on **enclosure top**. It'll be snug, but they'll fit! Use needle-nose pliers or a similar tool to push them in until their holes line up with those on the enclosure. 23 | 24 | ![nuts](/img/final_assembly/nuts.jpg) 25 | 26 | ### 2. Keys 27 | 28 | This part can be a little tricky and is easy to mess up, so let's first take a look at a cross section of how the **keys** fit into the **enclosure top**: 29 | 30 | ![Cross section of the Scout with keys endstop annotated](/img/keys_endstop.gif) 31 | 32 | Notice a couple things: 33 | 34 | 1. The front of the **keys** (on the right side of the above picture) have an endstop cavity. 35 | 2. That cavity fits onto matching endstop lip on the **enclosure top**. 36 | 3. Those two together prevent the keys from being pressed too far down or being pulled up. 37 | 38 | Add the **keys**. Its rail has cavities on the sides that fit into matching aligners on the **enclosure top**. 39 | 40 | ![keys](/img/final_assembly/keys.jpg) 41 | 42 | It'll take some careful wiggling, but your goal is to guide the keys down _onto the aligners and into the endstop_. 43 | 44 | When done, view the keys from the side and confirm none of them are visibly held down. Then test that the endstop is working correctly by pushing the keys _both up and down_ — they shouldn't be able to travel too far. 45 | 46 | Here's a video showing exactly what that looks like: 47 | 48 |

49 | 50 | :::caution 51 | Don't move on until this looks good! 52 | ::: 53 | 54 | ### 3. Keys mount rail 55 | 56 | Glide the **keys mount rail** onto its aligners. Don't worry if it seems a little warped — it will be held flat by the screws. 57 | 58 | ![keys_mount_rail](/img/final_assembly/keys_mount_rail.jpg) 59 | -------------------------------------------------------------------------------- /assembly_guide/docs/assembly-troubleshooting.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: assembly-troubleshooting 3 | title: Assembly troubleshooting 4 | description: Common problems that come up when assembling the Scout. 5 | sidebar_label: Assembly troubleshooting 6 | image: /img/scout_assembly-16-420-8-128.gif 7 | slug: /assembly-troubleshooting 8 | --- 9 | 10 | - If the screws are hard to insert into the enclosure bottom, don't force them but look to see if the **keys mount rail** is in the way. It may have come loose from its aligners. 11 | - Key problems 12 | - A note is stuck on? 13 | - The key mounting screw(s) may be too tight. With the Scout turned on, try loosening the screw until the note turns off. 14 | - The next thing to check is if the front lip of the enclosure top is bending inwards, catching and holding a pressed key. If that's the case, try gently bending the lip back outwards until the parts no longer catch each other. You can also try trimming the plastic back with a utility knife. 15 | - A note needs to be pushed really far down to play? Or it turns off when pressing another near it? The key mounting screw(s) may be too loose. Try tightening! 16 | - The speaker/battery wires can sometimes get in the way of keys, making them difficult to actuate. [Pop the enclosure apart](opening-the-enclosure.md) and see if you can make them lay flatter. 17 | - Most other key problems are from some obstruction between the key piece and the enclosure. Read through the ["Assemble top"](assemble-top.md#2-keys) section again and verify everything looks correct. 18 | - If the volume knob is hard to press onto its pot shaft, don't force it -- that could permanently damage the potentiometer. Try filing the inside of the knob's shaft cavity. If printing at home, make sure you've got the most recent STL models. 19 | -------------------------------------------------------------------------------- /assembly_guide/docs/bom.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: bom 3 | title: Annotated BOM 4 | description: Bill of Materials, annotated. 5 | sidebar_label: Annotated BOM 6 | image: /img/scout_assembly-16-420-8-128.gif 7 | slug: /bom 8 | hide_table_of_contents: true 9 | --- 10 | 11 | | Designator | Designation | Quantity | Marking | Usage | 12 | | ---------- | ----------------------------- | -------- | ------------------ | ------------------------------------------------------------------------------------- | 13 | | BT1 | 3.6v-4.5v | 1 | n/a | Power; wires to 3\*AAA battery pack | 14 | | C1,C5 | 220uF | 2 | n/a | Big bypass cap, Amp output | 15 | | C3 | 1uF | 1 | n/a | Amp gain | 16 | | C2,C4,C6 | .1uF | 3 | 104 | Bypass caps, RESET pin cap (C4) | 17 | | D1 | LED_CRGB | 1 | n/a | On/off+playing indicators | 18 | | J1 | AudioJack2_SwitchT | 1 | n/a | Line out headphone jack | 19 | | J2 | Conn_01x06_Male | 1 | n/a | Programming header | 20 | | LS1 | Speaker, AZ40R 40mm x 5mm | 1 | n/a | Wires to output speaker | 21 | | R1,R2 | 220 | 2 | Red Red Brown | LED current limiters | 22 | | R3,R5 | 10k | 2 | Brown Black Orange | Brings volume closer to ear-safe level for line out, "pull up" resistor for RESET pin | 23 | | R4 | 1m | 1 | Brown Black Green | Drops volume even more before amp | 24 | | RV1 | 10k Log, RV09AF-40-20K-A10K | 1 | n/a | Volume control | 25 | | SW1 | SPDT, OS102011MA1QN1 | 1 | n/a | On/off power switch | 26 | | SW2-SW18 | SPST, 6mm tall | 17 | n/a | Key buttons | 27 | | U1 | ATmega328P-PU with bootloader | 1 | n/a | Microcontroller chip | 28 | | U2 | LM386 | 1 | n/a | Amplifier chip | 29 | | Y1 | 16.00MHz | 1 | n/a | Ceramic oscillator for microcontroller | 30 | 31 | Also: 32 | 33 | - 2 2-wire ribbon cables (or similar small gauge, stranded wire) 34 | - 1 7" for BT1 35 | - 1 3" for LS1 36 | - 4 battery terminal contacts for BT1 37 | - 2 dual spring+button wire contacts (Keystone 181) 38 | - 1 tabbed spring contact (Keystone 5204) 39 | - 1 tabbed button contact (Keystone 5226) 40 | - 2 DIP sockets 41 | - 1 28 pin for U1 42 | - 1 8 pin for U2 43 | - 4 nuts and bolts 44 | - 2 4/40 square nuts 45 | - 2 4/40 3/4" machine screws 46 | 47 | Alternate speakers for the AZ40R: 48 | 49 | - PSR-40N08A05-JQ 50 | - AS04008MR-21-R 51 | - CMS-4051-058SP 52 | 53 | Any circular 8ohm speaker that matches the dimensions will probably work, thought you may find you need a bit of hot glue to hold it in place. 54 | -------------------------------------------------------------------------------- /assembly_guide/docs/boot-the-microcontroller.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: boot-the-microcontroller 3 | title: Boot the microcontroller 4 | description: How to get the Scout's microcontroller working and booted up. 5 | sidebar_label: Boot the microcontroller 6 | image: /img/pcb_assembly/030400@0.5x.jpg 7 | slug: /boot-the-microcontroller 8 | --- 9 | 10 | ## Steps 11 | 12 | 1. Solder capacitors **C1** (220uF) and **C2** (.1uF, marked 104), oscillator **Y1**, and resistors **R2** (220, Red Red Brown) and **R5** (10k, Brown Black Orange). 13 | - **C1** has polarity. Match its white side to the white side of its footprint. 14 | - **Y1** has three legs and no polarity. 15 | 2. Solder **U1** socket. It will have a dimple at one end, which should match the footprint on the PCB. 16 | - Solder two pins on opposite sides and verify the socket is perfectly flat before soldering the rest. If it's not and you try pushing it in, you can accidentally pop out a pin — not good! 17 | 3. With the power off, carefully insert **ATmega328**. It will have a dimple (and/or a small dot in a corner), which should match the socket. 18 | 19 | ## Test 20 | 21 | Turn the power switch back on, and the LED should blink a new, different color a couple times. This lets you know that the ATmega is booted up and ready. Power off. 22 | 23 | ![030400@0.5x.jpg](/img/pcb_assembly/030400@0.5x.jpg) 24 | 25 | Not working as expected? Check the [PCB troubleshooting](pcb-troubleshooting.md) section. Otherwise, continue to the next step. 26 | -------------------------------------------------------------------------------- /assembly_guide/docs/care.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: care 3 | title: Care 4 | sidebar_label: Care 5 | --- 6 | 7 | - 3D-printed plastic is susceptible to warping under hot temperatures. Keep it out of prolonged direct sunlight. 8 | - When the Scout seems to reset randomly while playing (or doesn't turn on at all!), that's a sign that its 3 AAA batteries don't have enough voltage. [Open up the enclosure](opening-the-enclosure.md) and replace them. 9 | -------------------------------------------------------------------------------- /assembly_guide/docs/change-the-arduino-code.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: change-the-arduino-code 3 | title: Change the Arduino code 4 | description: Hack, hack, hack, hack, hack, hack. 5 | sidebar_label: Change the Arduino code 6 | image: /img/hack/serial-plotter.png 7 | slug: /change-the-arduino-code 8 | --- 9 | 10 | :::info 11 | This section is optional! 12 | ::: 13 | 14 | :::tip 15 | If you're building your [Scout from scratch](bom.md) and sourced your own ATmega328, it _must_ have a bootloader programmed onto it for these instructions to work. 16 | ::: 17 | 18 | ## Required equipment 19 | 20 | To keep the Scout's price more accessible, it doesn't come with a built-in USB controller chip, so, out of the box, you can't easily hook it up to your computer as-is. 21 | 22 | Thankfully, that USB chip is readily available as a cable, which you can connect between your Scout and your computer. 23 | 24 | These cables have been tested and confirmed to work with the Scout: 25 | 26 | - [FTDI Serial TTL-232 USB Cable](https://www.adafruit.com/product/70) from Adafruit 27 | - [USB Serial Cable](https://cornfieldelectronics.com/cfe/products/buy.php?productId=usbcable&PHPSESSID=oos5v81hlitjvb0grhgolsrq96) from Cornfield Electronics 28 | - [FT232RL FTDI USB to TTL Serial Adapter](http://www.hiletgo.com/ProductDetail/2152064.html) from HiLetgo 29 | 30 | :::note 31 | Successfully use a different brand of cable? [Contact me](https://www.oskitone.com/contact) and I can add it to the list. 32 | ::: 33 | 34 | ## Steps 35 | 36 | Ready to experiment and get your hands dirty with some code? 37 | 38 | 1. Install the [Arduino IDE](https://www.arduino.cc/en/software) and follow their instructions to install whatever drivers you'd need for an Arduino Uno. 39 | 2. With the Scout's power off, connect the Scout's UART header to your computer using one of the cables listed above. 40 | 1. The Scout's UART header has "B" and "G" labels on its sides to match the cables Black and Green wires. 41 | 2. The cable provides power to the Scout, so it should now be on and working normally 42 | 3. **Double check that the power switch is OFF!** Leaving it on can permanently damage the microcontroller or batteries! 43 | 3. In the IDE, under "Tools->Board", select "Arduino Uno". Under "Tools->Port" select your new cable; its exact name will depend on the brand. If you're not sure which it is, try unplugging and restarting the IDE -- whichever it was will no longer be listed, so you'll know which it is when reconnecting and restarting. 44 | 4. Download the code from this repo and load `arduino/scout.ino` in the Arduino IDE. You'll also need the `CircularBuffer` and `Keypad` libraries, so open up "Tools->Manage libraries" and search for those to install them. 45 | 1. Try uploading this to the Scout by going to "Sketch->Upload". If it works, after 10 seconds or so, it will blink just like it does when you switch its power on. If it doesn't work, the IDE will print out an error that you can google to find out how to fix. 46 | 2. Experiment with the `octave` and `glide` values at the top of `scout.ino` and observe how your Scout has changed its sound. 47 | 5. "Blink" 48 | 1. The Arduino IDE has a default program called "Blink" (available in "File->Examples->Basics->Blink"). 49 | 2. After uploading, the Scout won't be playable anymore but one of the colors on the RGB LED should blink off and on. 50 | 3. Try changing the delay values in the example to make it blink faster or slower. 51 | 4. Follow the steps above to bring the original Scout code back. 52 | 53 | ## Serial debugging 54 | 55 | Check out the `printToSerial` variable at the top of `scout.ino`. Setting it to `true` and opening up the Arduino's Serial Plotter while playing notes will visualize the notes being held and how the playing frequency glides between its targets. 56 | 57 | [![Screengrab of the Arduino serial plotter visualizing the Scout's frequency math](/img/hack/serial-plotter.png)](/img/hack/serial-plotter.png) 58 | 59 | Now swap `frequency.print();` in the `loop()` for `buffer.print();` and switch to the Serial Monitor, and you'll get a running list of the indexes of the key(s) the Scout sees being played. 60 | 61 | :::note 62 | All this observation slows down the Scout's performance/glide. Remember to put `printToSerial` back to `false` before disconnecting from your computer! 63 | ::: 64 | 65 | ## Pins 66 | 67 | Once you're comfortable with the Arduino code and really want to expand on what the Scout can do, take a look at the unpopulated HACK header on the PCB. It exposes all the unused pins on the ATmega328 that are safe to use for whatever you'd like: 68 | 69 | | HACK | ATmega pins | Description | 70 | | ------------ | ----------- | --------------------------------------------------- | 71 | | VCC | n/a | Voltage from batteries or USB | 72 | | A0-A5 | 23-28 | Analog pins | 73 | | D12 | 18 | There's only one unused digital pin, and this is it | 74 | | SWC, SW1-SW3 | 16; 6,11,12 | Unused spots in the key matrix | 75 | | GND | n/a | Ground | 76 | 77 | ## Troubleshooting 78 | 79 | * Does the ATmega328 have a [bootloader](https://docs.arduino.cc/retired/hacking/software/Bootloader/) on it? 80 | * Is the chip all the way in its socket at the correct orientation? 81 | * Confirm the Scout powers up and operates with just the cable (and Scout's power switch off!). 82 | * Are you using one of the [known good](#required-equipment) FTDI cables? Confirm it's plugged in with green/black sides correctly. 83 | * In the Arduino IDE, confirm you've got the right board selected, and try different ports. 84 | * Take a closer look at the at the [UART header and its cap's soldering](prep-for-hacking) if you haven't already. Refer to the [schematics](schematics) and confirm its contact to the appropriate chip pins with a multimeter's continuity tester. 85 | * As a last resort, try swapping to a new chip. Make sure it has a bootloader. -------------------------------------------------------------------------------- /assembly_guide/docs/community-hacks.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: community-hacks 3 | title: Community hacks 4 | description: Hack, hack, hack, hack, hack, hack. 5 | sidebar_label: Community hacks 6 | image: /img/scout-10-838-032.gif 7 | slug: /community-hacks 8 | --- 9 | 10 | :::info 11 | This section is optional! 12 | ::: 13 | 14 | :::note 15 | Got a hack you want to share? [Contact me](https://www.oskitone.com/contact) and I can add it to the list. 16 | ::: 17 | 18 | ## Community hacks 19 | 20 | - **[arpeggio_hack](https://github.com/shamlian/scout/tree/arpeggio_hack) from [Steven Shamlian](https://github.com/shamlian):** Adds polyphony by arpeggiating through the held notes. The full hack requires diodes on the switches to prevent key ghosting, but otherwise the Arduino code can work w/o any hardware changes... provided you only play certain chords or don't mind the occasional wrong note. Pretty interesting! 21 | - **[MozziScout](https://github.com/todbot/MozziScout) from [todbot](https://todbot.com/):** With some careful pin swapping on the ATmega328, the Scout can use [Mozzi](https://sensorium.github.io/Mozzi/), the popular sound synthesis library for Arduino. For this hack, it's a good idea to plug into an amplifier — the new sounds your Scout will make are much richer than what its built-in speaker is capable! 22 | - **[2-piece Keyboard Mod](https://cults3d.com/en/3d-model/game/oskitone-scout-2-piece-keyboard-mod) from [Cyb3rn0id](https://cults3d.com/en/users/Cyb3rn0id/creations):** If your 3D printer can't easily do the color channge GCODE for the keyboard color swap, this mod splits the keys' colors into two parts that snap and glue together. 23 | - **[Arduino Soundlab](https://www.hackster.io/john-bradnam/arduino-soundlab-bf8593) from John Bradnam:** Scout keys on a non-Scout synth? Sure! This hack swaps out the ATmega328 for an Arduino Nano and custom PCB to add FM synthesis. 24 | 25 | ## Other ideas 26 | 27 | - For extra stability, add ruber feet to the bottom of your Scout. 28 | -------------------------------------------------------------------------------- /assembly_guide/docs/final-assembly.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: final-assembly 3 | title: Final assembly 4 | description: How to assemble finish the Scout's assembly. 5 | sidebar_label: Final assembly 6 | image: /img/scout.jpg 7 | slug: /final-assembly 8 | --- 9 | 10 | :::note 11 | You're almost done! Take your time to follow the directions in order. 12 | 13 | And check out the [Assembly troubleshooting](assembly-troubleshooting.md) section if you run into any trouble. 14 | ::: 15 | 16 | ## Steps 17 | 18 | ### 1. Snap enclosure together 19 | 20 | Align **enclosure top** onto **enclosure bottom** and snap the two halves together. Try to make sure the **keys mount rail** and **keys** stay aligned as you do this. It's an intentionally tight fit; be brave! 21 | 22 | ![enclosure](/img/final_assembly/enclosure.jpg) 23 | 24 | ### 2. Quick test 25 | 26 | With the **enclosure** together, try turning the Scout on and pressing each key. 27 | 28 | You should find that: 29 | 30 | 1. No notes are playing unless you intentionally press them. 31 | 2. Some notes are kind of finicky and require more pressure. Don't worry, we'll fix those in a second! 32 | 33 | If not, [pop the enclosure open](opening-the-enclosure.md) and revisit adding the keys in the [Assemble Top](assemble-top.md) step. 34 | 35 | ### 3. Add knob 36 | 37 | Fix **knob** onto the volume pot shaft, aligning its dimple to to the little marker on the top of the pot shaft. 38 | 39 | ![knob](/img/final_assembly/knob.jpg) 40 | 41 | ### 4. Add machine screws 42 | 43 | Slide two **machine screws** up through the bottom of the **enclosure bottom**. 44 | 45 | ![insert screws](/img/final_assembly/insert_screws.jpg) 46 | 47 | If they don't insert easily, you may have something misaligned inside. [pop the enclosure open](opening-the-enclosure.md) and make sure the **PCB**, **keys mount rail**, and **keys** are all lined up correctly. 48 | 49 | ### 5. Tighten screws 50 | 51 | ![screws](/img/final_assembly/screws.jpg) 52 | 53 | 1. With the Scout on (and no notes playing, see above in "Quick test"), cautiosly tighten the **screws**. 54 | 2. If/when a note starts playing, that indicates the screw is too tight. Loosen it until the note subsides. 55 | 56 | As you may have figured out, the screws hold the Scout together _but also control the keys' "action"_ (how much effort is required to trigger each note). Without them, keys towards the middle are more difficult to play. 57 | 58 | You basically want the screws tight enough that all keys require the same amount of effort, so adjust them until everything feels good. 59 | 60 | ## All done! 61 | 62 | ![All done!](/img/scout.jpg) 63 | 64 | ## What's next 65 | 66 | ### Feedback 67 | 68 | When you can, please [let me know](https://www.oskitone.com/contact) how it went for you: 69 | 70 | - **What did you like?** Did you have fun?! 71 | - Not including printing time, about **how long did it take?** 72 | - **How'd the kit show up?** Were there any parts missing or damaged? Or any **problems with the instructions**? 73 | - The Scout is intentionally simple, but that doesn't mean future kits will be too. Any **feature requests** for the next Oskitone instrument? 74 | 75 | I act and rely on customers' feedback to make the next products even better. Even just knowing that you got it done successfully is valuable feedback, so I do want to hear from you. Thank you so much! 76 | 77 | ### Share your make 78 | 79 | Like your Scout? I'd love to have you share that! 80 | 81 | - If you 3D-printed it at home, share your make on the [Thingiverse](https://www.thingiverse.com/thing:4933700) or [PrusaPrinters](https://www.prusaprinters.org/prints/76472-scout-synth) page where you downloaded the models. It's a good signal to other potential makers to see successful makes. 82 | - Tell your friends, post on social, etc. You know the deal! 83 | 84 | ### Further reading 85 | 86 | For the curious, I've written [a blog post where you can read more about the Scout's development and history](https://blog.tommy.sh/posts/scout/). 87 | 88 | Each Oskitone product gets it's own blog post, so dig around in there and see if there's anything else you find interesting. 89 | -------------------------------------------------------------------------------- /assembly_guide/docs/general-tips.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: general-tips 3 | title: General tips and getting started 4 | description: Things to keep in mind as you solder your Scout. Take your time and be patient! 5 | sidebar_label: General tips and getting started 6 | image: /img/scout_assembly-16-420-8-128.gif 7 | slug: /general-tips 8 | --- 9 | 10 | [![Timelapse of soldering and assembling a Scout](/img/scout_assembly-16-420-8-128.gif)](https://vimeo.com/586501851) 11 | 12 | :::note 13 | Take your time and be patient! If you run into a problem, try to keep a cool head and refer to the [PCB troubleshooting](pcb-troubleshooting.md) section. If your problem remains unfixed and you can't figure it out, [please _email_ me to let me know](https://www.oskitone.com/contact)! I'll do my best to help you, and your feedback will help improve the guide and other future Oskitone designs. 14 | ::: 15 | 16 | ## General tips 17 | 18 | - **Component colors**
19 | This guide's components' brands and body colors (and even the PCB color itself) may look different from yours, and that's okay! What's important is that the part types and values are in the right spots. 20 | - **Resistors are labeled with colors, capacitors with numbers**
21 | Resistors' values are marked as colored bands on their body. Ceramic capacitors use a number system to denote their value. 22 | - **Ceramic and electrolytic capacitors**
23 | There are two kinds of “caps” used in this kit. Ceramic capacitors are small, circular, and have no polarity; they can be placed in either direction. Electrolytic caps are bigger, cylindrical, and have marked +/- polarities. 24 | - **IC chips are static-sensitive**
25 | The included IC chips can be damaged by static electricity. Leave them in their packaging until ready to install. Before handling, discharge any static electricity on your body by touching a large piece of metal. You can even use an anti-static mat and/or wrist strap for extra caution. 26 | - **ICs in sockets**
27 | Each IC chip comes with a corresponding socket with the same number of pins. You will solder the socket to the PCB, not the chip itself. This prevents overheating the IC with the soldering iron and makes it easier to switch a faulty one out. 28 | - **Component polarities**
29 | LEDs, batteries, and electrolytic capacitors have positive and negative leads. Where applicable, the PCB will be labeled where each lead goes or a component outline to denote orientation. 30 | - **IC orientation**
31 | The IC chips also have an orientation, marked by a notch at their top. Make sure these line up when soldering the sockets and again when inserting the chips. A chip can be permanently damaged if inserted incorrectly! 32 | - **Get tricky/sticky with short-lead components**
33 | Components with short leads can be hard to get to stay on the PCB, because you can't really bend their leads to get them to stay put. But there are tricks! Try using tape or "Blu-Tack" adhesive to hold them. Or clip the solder into your "holding hands", and try bringing the _board to the solder_ (instead of the typical reverse of solder to board). 34 | 35 | ## Let's get started! 36 | 37 | For reference, we'll end up with something like this when we're done: 38 | 39 | ![090200@0.5x.jpg](/img/pcb_assembly/090200@0.5x.jpg) 40 | 41 | ### How this guide is organized 42 | 43 | Each group of steps in the Scout's assembly has a test at the end to make sure everything you just did is working as expected, ie: "Make sure the LED lights up", "Make sure the microcontroller works", "Make sure the speaker has sound", etc. 44 | 45 | If it doesn't work, don't fret! Look over the [PCB troubleshooting](pcb-troubleshooting.md) tips. Don't move on in the instructions until you've got the test working. 46 | 47 | :::note Note for the experienced/impatient 48 | The guide's steps are intentionally ordered. If you don't want to follow the guide, that's okay! But it may be harder to debug later if anything doesn't work as expected. 49 | ::: 50 | -------------------------------------------------------------------------------- /assembly_guide/docs/get-logical.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: get-logical 3 | title: Get logical 4 | description: Test the microcontroller's logic! 5 | sidebar_label: Get logical 6 | image: /img/pcb_assembly/040200@0.5x.jpg 7 | slug: /get-logical 8 | --- 9 | 10 | :::note 11 | Take your time and make sure the switch is perfectly flat against the PCB before soldering all of its pins. 12 | ::: 13 | 14 | ## Steps 15 | 16 | 1. Solder an SPST switch to **SW2**. 17 | - **_Make sure the switch is absolutely flat against the PCB before soldering all of its pins._** 18 | - One way to do this is to solder one pin to hold it in place, then use one hand to push it into the PCB while melting the solder with your other hand; if there's any gap there it should pop in. Visually inspect to make sure it's good, then repeat with the pin on the _opposite corner_. Then inspect and do the remaining pins. It takes time but is worth it. 19 | 20 | ## Test 21 | 22 | With power on, press the switch. The LED should light just like it does on boot! Power off. 23 | 24 | ![040200@0.5x.jpg](/img/pcb_assembly/040200@0.5x.jpg) 25 | 26 | Not working as expected? Check the [PCB troubleshooting](pcb-troubleshooting.md) section. Otherwise, continue to the next step. 27 | -------------------------------------------------------------------------------- /assembly_guide/docs/get-loud.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: get-loud 3 | title: Get loud 4 | description: How to solder the Scout's amp to, you guessed it!, get loud. 5 | sidebar_label: Get loud 6 | image: /img/pcb_assembly/060500@0.5x.jpg 7 | slug: /get-loud 8 | --- 9 | 10 | ## Steps 11 | 12 | 1. Solder capacitors **C5** (220uF) and **C6** (.1uF, marked 104) and resistor **R4** (1m, Brown Black Green; resistor body may be blue in your kit). 13 | - Make sure **C5**'s polariy matches its footprint, just like **C1**. 14 | 2. Wire speaker to **LS1**. 15 | 1. Thread remaining ribbon cable through hole. 16 | ![060201@0.5x.jpg](/img/pcb_assembly/060201@0.5x.jpg) 17 | 2. Strip insulation and solder to **LS1**. 18 | 3. Strip and solder the other ends to the speaker, matching the "+" and "-" sides. 19 | 3. Solder socket **U2**. Match its dimple to the footprint, just like **U1**. 20 | 4. With the power off, carefully insert **LM386** chip, again making sure its inserted the correct way. 21 | 22 | ## Test 23 | 24 | Power on, unplug your headphones, and press the switch. It should be playing out of the speaker now. Power off. 25 | 26 | ![060500@0.5x.jpg](/img/pcb_assembly/060500@0.5x.jpg) 27 | 28 | Not working as expected? Check the [PCB troubleshooting](pcb-troubleshooting.md) section. Otherwise, continue to the next step. 29 | -------------------------------------------------------------------------------- /assembly_guide/docs/get-louder.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: get-louder 3 | title: Get louder 4 | description: Not loud enough for ya? Get LOUDER. 5 | sidebar_label: Get louder 6 | image: /img/scout_assembly-16-420-8-128.gif 7 | slug: /get-louder 8 | --- 9 | 10 | ## Steps 11 | 12 | :::note 13 | Optional. Skip if it's already loud enough for you (or whoever you're giving it to)! 14 | ::: 15 | 16 | 1. Solder cap **C3** (1uF). 17 | - Match polarity. 18 | 19 | ## Test 20 | 21 | Power on and press some switches. The speaker should be louder now! Power off. 22 | 23 | Not working as expected? Check the [PCB troubleshooting](pcb-troubleshooting.md) section. Otherwise, continue to the next step. 24 | -------------------------------------------------------------------------------- /assembly_guide/docs/inventory.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: inventory 3 | title: Inventory 4 | description: What you'll need to gather before getting started. 5 | sidebar_label: Inventory 6 | image: /img/scout-10-838-032.gif 7 | slug: /inventory 8 | --- 9 | 10 | #### Required 11 | 12 | - The [Oskitone Scout Synth DIY Electronics Kit](http://www.oskitone.com/product/scout-synth-diy-electronics-kit) and its 3D-printed parts 13 | - Soldering iron and solder specifically for electronics 14 | - Wire stripper or cutters 15 | - 3 AAA batteries 16 | - Headphones 17 | 18 | #### Recommended 19 | 20 | - Multimeter for debugging 21 | - PCB vice or “helping hands” holder 22 | - “Solder sucker” or desoldering braid 23 | - Patience, patience, patience 24 | -------------------------------------------------------------------------------- /assembly_guide/docs/make-some-noise.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: make-some-noise 3 | title: Make some noise 4 | description: How to start getting noises out of the Scout. 5 | sidebar_label: Make some noise 6 | image: /img/pcb_assembly/050300@0.5x.jpg 7 | slug: /make-some-noise 8 | --- 9 | 10 | ## Steps 11 | 12 | 1. Solder volume potentiometer (aka "pot") **RV1**, resistor **R3** (10k), and headphone jack **J1**. 13 | - A trick to get the pot to snap in better is to _gently_ push its tabs inward before popping it onto the PCB. 14 | - Make sure **RV1** and **J1** are pushed all the way into PCB before soldering all the way. 15 | - You can use a bit of tape or "Blu-Tack" adhesive to hold **J1** in place as you solder. 16 | 2. Connect your headphones into the headphone jack. _Push firmly until it clicks in all the way._ 17 | 18 | ## Test 19 | 20 | With power on, turn up the volume with the potentiometer and press **SW2**. You should hear a tone from the headphones in both the left and right channels. Power off. 21 | 22 | ![050300@0.5x.jpg](/img/pcb_assembly/050300@0.5x.jpg) 23 | 24 | If only one side of the headphones is making noise, check to see that the headphone jack is pushed all the way in. 25 | 26 | Not working as expected? Check the [PCB troubleshooting](pcb-troubleshooting.md) section. Otherwise, continue to the next step. 27 | -------------------------------------------------------------------------------- /assembly_guide/docs/more-notes.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: more-notes 3 | title: More notes 4 | description: Add the rest of the Scout's note buttons. 5 | sidebar_label: More notes 6 | image: /img/pcb_assembly/070200@0.5x.jpg 7 | slug: /more-notes 8 | --- 9 | 10 | :::note 11 | Take your time and make sure the switches are perfectly flat against the PCB before soldering all of their pins. 12 | ::: 13 | 14 | ## Steps 15 | 16 | 1. Solder the remaining tactile 16 switches, **SW3** through **SW18**. 17 | 18 | We want them all as flat against the PCB as **SW2**, so take your time here and verify as you go. When done, they should all line up _perfectly_. 19 | 20 | ![button alignment](/img/pcb_assembly/button_alignment.jpg) 21 | 22 | If they don't line up perfectly as pictured above, you'll have problems later with some notes playing accidentally when the enclosure snaps together. 23 | 24 | ## Test 25 | 26 | Power on and press each. They should all play different notes out of the speaker. See if you can play a little tune! Power off. 27 | 28 | ![070200@0.5x.jpg](/img/pcb_assembly/070200@0.5x.jpg) 29 | 30 | Not working as expected? Check the [PCB troubleshooting](pcb-troubleshooting.md) section. Otherwise, continue to the next step. 31 | -------------------------------------------------------------------------------- /assembly_guide/docs/opening-the-enclosure.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: opening-the-enclosure 3 | title: Opening the enclosure 4 | description: How to open up the Scout enclosure after it's snapped together. 5 | sidebar_label: Opening the enclosure 6 | image: /img/scout_assembly-16-420-8-128.gif 7 | slug: /opening-the-enclosure 8 | --- 9 | 10 | Later, when you need to change the batteries (or maybe just want to admire your hard work!), you'll need to open the enclosure back up. 11 | 12 | 1. Unscrew bottom **machine screws**. They don't have to come all the way out, just loosen. 13 | 2. Pop off the volume **knob**. A flathead screwdriver (or similar tool) may help provide leverage. 14 | 3. Insert that same flat tool on the UART cavity or the horizontal gap on the back right, then wedge the enclosure apart. 15 | 16 |

17 | -------------------------------------------------------------------------------- /assembly_guide/docs/pcb-troubleshooting.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: pcb-troubleshooting 3 | title: PCB troubleshooting 4 | description: Common problems that come up when soldering the Scout PCB. 5 | sidebar_label: PCB troubleshooting 6 | image: /img/scout_assembly-16-420-8-128.gif 7 | slug: /pcb-troubleshooting 8 | --- 9 | 10 | ## General tips 11 | 12 | Any of these problems can cause a variety of "just not working right" errors in a circuit. Familiarize yourself with these troubleshooting checks and do them regularly. 13 | 14 | - Turn the PCB over and check all solder joints. A majority of problems are caused by insufficient or errant soldering. Familiarize yourself with what a good joint looks like in the [Adafruit Guide To Excellent Soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering). 15 | - Are all chips in the right orientation? Each has a notch/dimple that should match the footprint outline on the PCB. 16 | - Do the batteries have enough power? The three batteries should have a total voltage of 3.6 to 4.5 volts. If the Scout seems like it's restarting a lot as you play it, that's a good sign the batteries need replacing. 17 | 18 | ## Specific issues 19 | 20 | - If there’s buzzing, check for any metal scraps stuck to the speaker’s magnet. 21 | - If some keys are touchy or behaving weird, check to see that their switches are inserted all the way and perfectly flat against the PCB. (See also: the "Key problems" section in [Assembly troubleshooting](assembly-troubleshooting.md)) 22 | - If multiple keys seem to be tied to the same note, there's probably a short (an accidental connection between soldering points) somewhere. Check all joints as described above, then try cleaning the bottom of the PCB with isopropyl alcohol. Leftover flux and resin from the soldering process _can_ be conductive! 23 | - If you're hearing an unwanted hum from the speaker when the Scout isn't being played, verify all .1uF caps are soldered well. It may also be from noise added by long wires, so do use the recommended wire lengths in this guide. 24 | -------------------------------------------------------------------------------- /assembly_guide/docs/power-up.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: power-up 3 | title: Power up 4 | description: Getting power to Scout's PCB and toggling an LED. 5 | sidebar_label: Power up 6 | image: /img/pcb_assembly/020400@0.5x.jpg 7 | slug: /power-up 8 | --- 9 | 10 | ## Steps 11 | 12 | 1. Solder LED at **D1** 13 | 1. The LED has four pins for three different colors plus ground. The longest one is to ground and it goes to the hole that has a line coming out of it. 14 | ![020101@0.5x.jpg](/img/pcb_assembly/020101@0.5x.jpg) 15 | 2. Get the LED as vertically close to the PCB as reasonable; it doesn't have to be flat against PCB but does need to be straight up and down -- no leaning! 16 | ![020102@0.5x.jpg](/img/pcb_assembly/020102@0.5x.jpg) 17 | 2. Solder sliding toggle switch **SW1** and resistor **R1** (220, Red Red Brown). 18 | - Make sure the switch is flat against the PCB and its actuator is pointing left, away from the PCB. 19 | - You can use a bit of tape or "Blu-Tack" adhesive to hold the switch in place as you solder. 20 | 3. Wire battery pack to **BT1** 21 | 1. Thread the other side of the ribbon cable connected to the battery pack up through the hole near **BT1**, then strip and solder in place. Make sure the "+" and "-" wires are going to the right places. 22 | 23 | ## Test 24 | 25 | Add the batteries back. Toggling **SW1** should now light one color of the LED! Yes, it is bright!! Power off before continuing soldering. 26 | 27 | ![020400@0.5x.jpg](/img/pcb_assembly/020400@0.5x.jpg) 28 | 29 | Not working as expected? Check the [PCB troubleshooting](pcb-troubleshooting.md) section. Otherwise, continue to the next step. 30 | -------------------------------------------------------------------------------- /assembly_guide/docs/prep-for-hacking.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: prep-for-hacking 3 | title: Prep for hacking 4 | description: Optionally solder the parts required to change the Scout's code. 5 | sidebar_label: Prep for hacking 6 | image: /img/pcb_assembly/090200@0.5x.jpg 7 | slug: /prep-for-hacking 8 | --- 9 | 10 | :::note 11 | If you have no intention of ever changing the Scout's code, you can skip this part and it will work perfectly fine. But, you know, you're here, so you might as well! 12 | ::: 13 | 14 | ## Steps 15 | 16 | 1. Solder **J2** header and **C4** (.1uF, marked 104) cap. 17 | - Try to get **J2**'s pins parallel to the PCB and sticking straight out. 18 | 19 | ## Test 20 | 21 | See ["Change the Arduino code" section](change-the-arduino-code) on how to use this! 22 | 23 | ![090200@0.5x.jpg](/img/pcb_assembly/090200@0.5x.jpg) 24 | -------------------------------------------------------------------------------- /assembly_guide/docs/schematics.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: schematics 3 | title: "Schematics" 4 | description: Scout circuit schematics 5 | sidebar_label: Schematics 6 | image: /img/schematics/scout.svg 7 | hide_table_of_contents: true 8 | --- 9 | 10 | [![Scout schematic](/img/schematics/scout.svg)](/img/schematics/scout.svg) 11 | 12 | [![Scout keyboard_matrix schematic](/img/schematics/keyboard_matrix-keyboard_matrix.svg)](/img/schematics/keyboard_matrix-keyboard_matrix.svg) 13 | -------------------------------------------------------------------------------- /assembly_guide/docs/source-and-license.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: source-and-license 3 | title: "Source and License" 4 | description: The Scout is open-source hardware. 5 | sidebar_label: Source and License 6 | image: /img/scout_assembly-16-420-8-128.gif 7 | --- 8 | 9 | ## Source 10 | 11 | The Scout is open-source hardware. 12 | 13 | [https://github.com/oskitone/scout](https://github.com/oskitone/scout) 14 | 15 | ## License 16 | 17 | > Designed by Oskitone. Please support future synth projects by purchasing from [Oskitone](https://www.oskitone.com/). 18 | > 19 | > Creative Commons Attribution/Share-Alike, all text above must be included in any redistribution. See license.txt for additional details. 20 | -------------------------------------------------------------------------------- /assembly_guide/docs/the-chord-problem.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: the-chord-problem 3 | title: The chord problem 4 | description: Sometimes playing specific chords 5 | sidebar_label: The chord problem 6 | image: /img/scout-10-838-032.gif 7 | slug: /the-chord-problem 8 | --- 9 | 10 | The Scout is monophonic; it can only play one note at a time. If you try to hold multiple notes simultaneously, it tries to do what's called "last note priority" and only plays the most recently held key's note. 11 | 12 | But sometimes, specific chords or sets of keys seem to add a note that you hadn't anticipated. 13 | 14 | ## Reproduce the issue 15 | 16 | 1. Play the first three white keys individually in succession. **C**, then **D**, then **E**. They should sound exactly as you'd expect. 17 | 2. Now, play them together. **C** _and_ **D** _and_ **E**. 18 | 3. Notice that it plays a totally different note at the end there instead of **E**. If you continue playing keys up individually, you'll discover that we got an **F#** at the end instead of the E we were expecting. 19 | 4. Now play the same run of those first three white keys but in the reverse order. **E** _and_ **D** _and_ **C**. 20 | 5. Again, notice that the third note at the end is **F#**. 21 | 22 | Super weird, right? Why is this happening? 23 | 24 | ## Debugging with the serial monitor 25 | 26 | If we [log out the indexes of the buttons](change-the-arduino-code.md#serial-debugging) being pressed and play **C**, **D**, **E** individually it looks like this: 27 | 28 | [![Screengrab of the Arduino serial monitor while playing C, D, and E individually](/img/hack/chord-individual.png)](/img/hack/chord-individual.png) 29 | 30 | Makes sense. **0** is **C**, **2** is **D**, and **4** is **E**. That's just what we expected! (In code, we order lists starting at 0 instead of 1, so the indexes of the list of 17 keys go from 0 to 16, not 1 to 17.) 31 | 32 | But holding them together looks like this: 33 | 34 | [![Screengrab of the Arduino serial monitor while playing C, D, and E together](/img/hack/chord-cde.png)](/img/hack/chord-cde.png) 35 | 36 | The **0**, **2**, **4** are in there (reverse ordered but that's irrelevant) but we also see a fourth index, **6**. That's the index of the **F#** key. 37 | 38 | Playing and holding **E**, **D**, **C** is the same with a different order: 39 | 40 | [![Screengrab of the Arduino serial monitor while playing E, D, and C together](/img/hack/chord-edc.png)](/img/hack/chord-edc.png) 41 | 42 | That doesn't solve our problem, but it does tell us that the microcontroller is indeed interpreting that the **C**, **D**, and **E** keys are being pressed but, for some reason, incorrectly _adding_ the **F#**. 43 | 44 | ## Checking the schematic 45 | 46 | ### A matrix of keys 47 | 48 | The Scout has 17 keys but they only take up 9 pins on the ATmega328. It does this by convincing the microcontroller that the 17 keys are arranged in a matrix of rows and columns: 4 rows \* 5 columns = 20 possible keys. 49 | 50 | When a key is pressed and its switch closes, the pins for its row and column connect. 51 | 52 | The matrix of rows and columns with the notes labelled, read from top to bottom and _then_ left to right: 53 | 54 | [![Matrix schematic with switches labelled to their corresponding notes](/img/hack/matrix.png)](/img/hack/matrix.png) 55 | 56 | - **Note 1:** The ATmega328 only has 14 digital input/output (IO) pins, which wouldn't be enough for all the keys if they were wired individually. There are other ways besides a matrix to get more IO out of our chip but they all require soldering more components. 57 | - **Note 2:** The 3 remaining, unused matrix spots in the bottom right are available for use on the ["HACK" header](change-the-arduino-code.md#pins). 58 | - **Note 3:** Awkwardly, the hardware components for the notes are indexed from SW2 to SW18, because only the code uses zero-indexing and the on/off switch was SW1. Thankfully, at least they are still in linear order! 59 | 60 | ### Connecting rows and columns 61 | 62 | We can see that **C** is **R1C1** (Row 1, column 1), **D** is **R3C1**, and **E** is **R1C2**. 63 | 64 | [![Matrix schematic with C, D, and E matrix points highlighted](/img/hack/matrix-trio.png)](/img/hack/matrix-trio.png) 65 | 66 | But to the microcontroller, it also sure looks like you're pressing **F#** at **R3C2**. I mean, how could it know you're not? So it just throws it in there. 67 | 68 | [![Matrix schematic with C, D, and E matrix points highlighted](/img/hack/matrix-f_sharp.png)](/img/hack/matrix-f_sharp.png) 69 | 70 | That's the culprit!! 71 | 72 | ## Is it a bug? 73 | 74 | Issues like this "chord problem" are normally avoided on more complex matrix circuits like your computer keyboard with diodes along the switches, but these were ommitted on the Scout to cut down on kit cost and assembly time. The Scout's monophony was an intentional limitation to deter encountering it. After all, _it is supposed to be simple instrument_! 75 | 76 | So it's _kind of_ a bug but _more_ like a "known issue" and a cost to be paid for the simplicity of the Scout's assembly. 77 | 78 | ### Homework 79 | 80 | Looking at the matrix schematic, can you find other key combinations that will have the "chord problem"? 81 | -------------------------------------------------------------------------------- /assembly_guide/docs/what-youll-be-making.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: what-youll-be-making 3 | title: Oskitone Scout Assembly Guide 4 | sidebar_label: What You'll Be Making 5 | description: How to solder and assemble the Oskitone Scout Electronics Kit 6 | image: /img/scout-10-838-032.gif 7 | slug: / 8 | --- 9 | 10 | ![Scout](/img/scout-10-838-032.gif) 11 | 12 | **Purchase:** 13 | 14 | - [Scout Synth (fully assembled)](https://www.oskitone.com/product/scout-synth) 15 | - [Scout Synth DIY Electronics Kit](https://www.oskitone.com/product/scout-synth-diy-electronics-kit) 16 | 17 | ## What You'll Be Making 18 | 19 | **scout** (_/skout/_): 20 | 21 | 1. _One sent to obtain information_ 22 | 2. _Jean Louise “Scout” Finch, of Atticus Finch_ 23 | 3. _The first synth from Oskitone to venture into the big ol' world of microcontrollers_ 24 | 25 | ![A finished Scout](/img/scout.jpg) 26 | 27 | The Scout is: 28 | 29 | - **Beginner-friendly:** All components are through-hole (instead of surface mount) for easier soldering, and full assembly takes about 45min. Standalone, battery-powered, doesn't need a computer or external speakers to work. Fun! 30 | - **3D-Printable:** Besides the electronics and nuts and bolts, all parts are 3D-printed. And with a total width of ~160mm (about 6.3"), the Scout can fit on smaller, "Mini" (18x18x18cm) size print beds. 31 | - **Hackable:** Arduino-compatible and fully open source! Hook up an [FTDI Serial TTL-232 cable](https://www.adafruit.com/product/70) (sold separately) to update its code using the Arduino IDE. 32 | - **Minimally featured:** 1.5 octaves of keys, a volume knob, on/off switch, speaker, headphone jack. Monophonic square wave with fixed glide and octave. 33 | 34 | In addition to it being the first microcontroller-controlled instrument from Oskitone, the Scout would also make a fine introductory DIY instrument for the budding electronics hobbyist. (Some experience soldering and a general familiarity with how electricity works are recommended though!) 35 | 36 | As such, it is intentionally minimal, with the goal of the shortest possible time from starting the kit to making music with it. No MIDI/CV or other IO, as is. If you're looking for a full-featured studio instrument, this ain't it, bub! :) 37 | 38 |

39 | 40 | More information about the Scout, its development, and history: [https://blog.tommy.sh/posts/scout/](https://blog.tommy.sh/posts/scout/) 41 | 42 | ### Disclaimers 43 | 44 | You've been warned! 45 | 46 | :::warning 47 | Not a toy. Choking hazard. Small parts. Not for children under 3 years. 48 | ::: 49 | 50 | ## About this guide 51 | 52 | To save cost, trees, and frustration from outdated information, printed instructions are not included by default with Scout kits. This online guide will always be up to date and the best source of information for how to assemble your new Scout. 53 | 54 | Thank you for understanding! 55 | 56 | :::note 57 | If you run into any problems with your build or something in the guide seems incorrect, please [please _email_ me to let me know](https://www.oskitone.com/contact)! I'll do my best to help you, and your feedback will help improve the guide and other future Oskitone designs. 58 | ::: 59 | -------------------------------------------------------------------------------- /assembly_guide/docusaurus.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | title: "Oskitone Scout Assembly Guide", 3 | url: "https://oskitone.github.io", 4 | baseUrl: "/scout/", 5 | onBrokenLinks: "throw", 6 | onBrokenMarkdownLinks: "warn", 7 | favicon: "img/favicon.ico", 8 | organizationName: "oskitone", // Usually your GitHub org/user name. 9 | projectName: "scout", // Usually your repo name. 10 | themeConfig: { 11 | navbar: { 12 | title: "Oskitone Scout Assembly Guide" 13 | }, 14 | footer: { 15 | style: "dark", 16 | copyright: `Copyright © ${new Date().getFullYear()} Oskitone. Built with Docusaurus.` 17 | } 18 | }, 19 | presets: [ 20 | [ 21 | "@docusaurus/preset-classic", 22 | { 23 | docs: { 24 | path: "./docs", 25 | routeBasePath: "/", 26 | sidebarPath: require.resolve("./sidebars.js") 27 | }, 28 | theme: { 29 | customCss: require.resolve("./src/css/custom.css") 30 | } 31 | } 32 | ] 33 | ] 34 | }; 35 | -------------------------------------------------------------------------------- /assembly_guide/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "scout-docs", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "docusaurus": "docusaurus", 7 | "start": "docusaurus start", 8 | "build": "docusaurus build", 9 | "swizzle": "docusaurus swizzle", 10 | "deploy": "docusaurus deploy", 11 | "clear": "docusaurus clear", 12 | "serve": "docusaurus serve", 13 | "write-translations": "docusaurus write-translations", 14 | "write-heading-ids": "docusaurus write-heading-ids" 15 | }, 16 | "dependencies": { 17 | "@docusaurus/core": "3.7.0", 18 | "@docusaurus/preset-classic": "3.7.0", 19 | "@mdx-js/react": "^3.0.0", 20 | "clsx": "^2.0.0", 21 | "prism-react-renderer": "^2.3.0", 22 | "react": "^19.0.0", 23 | "react-dom": "^19.0.0" 24 | }, 25 | "devDependencies": { 26 | "@docusaurus/module-type-aliases": "3.7.0", 27 | "@docusaurus/types": "3.7.0" 28 | }, 29 | "browserslist": { 30 | "production": [ 31 | ">0.5%", 32 | "not dead", 33 | "not op_mini all" 34 | ], 35 | "development": [ 36 | "last 3 chrome version", 37 | "last 3 firefox version", 38 | "last 5 safari version" 39 | ] 40 | }, 41 | "engines": { 42 | "node": ">=18.0" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /assembly_guide/sidebars.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | someSidebar: { 3 | "Getting Started": ["what-youll-be-making", "inventory"], 4 | "3D-Printing": [ 5 | "3d-printing-parts-and-slicing", 6 | "3d-printing-post-processing" 7 | ], 8 | "PCB Assembly": [ 9 | "general-tips", 10 | "assemble-battery-pack", 11 | "power-up", 12 | "boot-the-microcontroller", 13 | "get-logical", 14 | "make-some-noise", 15 | "get-loud", 16 | "more-notes", 17 | "get-louder", 18 | "prep-for-hacking" 19 | ], 20 | Assembly: ["assemble-top", "assemble-bottom", "final-assembly", "care"], 21 | Hacking: ["change-the-arduino-code", "community-hacks"], 22 | Appendix: [ 23 | "bom", 24 | "pcb-troubleshooting", 25 | "assembly-troubleshooting", 26 | "opening-the-enclosure", 27 | "the-chord-problem", 28 | "schematics", 29 | "source-and-license" 30 | ] 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /assembly_guide/src/css/custom.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable docusaurus/copyright-header */ 2 | /** 3 | * Any CSS included here will be global. The classic template 4 | * bundles Infima by default. Infima is a CSS framework designed to 5 | * work well for content-centric websites. 6 | */ 7 | 8 | /* You can override the default Infima variables here. */ 9 | :root { 10 | --ifm-color-primary: #25c2a0; 11 | --ifm-color-primary-dark: rgb(33, 175, 144); 12 | --ifm-color-primary-darker: rgb(31, 165, 136); 13 | --ifm-color-primary-darkest: rgb(26, 136, 112); 14 | --ifm-color-primary-light: rgb(70, 203, 174); 15 | --ifm-color-primary-lighter: rgb(102, 212, 189); 16 | --ifm-color-primary-lightest: rgb(146, 224, 208); 17 | --ifm-code-font-size: 95%; 18 | } 19 | 20 | .docusaurus-highlight-code-line { 21 | background-color: rgb(72, 77, 91); 22 | display: block; 23 | margin: 0 calc(-1 * var(--ifm-pre-padding)); 24 | padding: 0 var(--ifm-pre-padding); 25 | } 26 | -------------------------------------------------------------------------------- /assembly_guide/src/pages/styles.module.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable docusaurus/copyright-header */ 2 | 3 | /** 4 | * CSS files with the .module.css suffix will be treated as CSS modules 5 | * and scoped locally. 6 | */ 7 | 8 | .heroBanner { 9 | padding: 4rem 0; 10 | text-align: center; 11 | position: relative; 12 | overflow: hidden; 13 | } 14 | 15 | @media screen and (max-width: 966px) { 16 | .heroBanner { 17 | padding: 2rem; 18 | } 19 | } 20 | 21 | .buttons { 22 | display: flex; 23 | align-items: center; 24 | justify-content: center; 25 | } 26 | 27 | .features { 28 | display: flex; 29 | align-items: center; 30 | padding: 2rem 0; 31 | width: 100%; 32 | } 33 | 34 | .featureImage { 35 | height: 200px; 36 | width: 200px; 37 | } 38 | -------------------------------------------------------------------------------- /assembly_guide/static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/.nojekyll -------------------------------------------------------------------------------- /assembly_guide/static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/favicon.ico -------------------------------------------------------------------------------- /assembly_guide/static/img/final_assembly/battery_holder.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/final_assembly/battery_holder.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/final_assembly/enclosure.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/final_assembly/enclosure.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/final_assembly/insert_screws.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/final_assembly/insert_screws.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/final_assembly/keys.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/final_assembly/keys.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/final_assembly/keys_mount_rail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/final_assembly/keys_mount_rail.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/final_assembly/knob.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/final_assembly/knob.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/final_assembly/nuts.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/final_assembly/nuts.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/final_assembly/pcb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/final_assembly/pcb.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/final_assembly/screws.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/final_assembly/screws.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/final_assembly/speaker.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/final_assembly/speaker.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/final_assembly/switch_clutch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/final_assembly/switch_clutch.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/hack/chord-cde.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/hack/chord-cde.png -------------------------------------------------------------------------------- /assembly_guide/static/img/hack/chord-edc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/hack/chord-edc.png -------------------------------------------------------------------------------- /assembly_guide/static/img/hack/chord-individual.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/hack/chord-individual.png -------------------------------------------------------------------------------- /assembly_guide/static/img/hack/matrix-f_sharp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/hack/matrix-f_sharp.png -------------------------------------------------------------------------------- /assembly_guide/static/img/hack/matrix-trio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/hack/matrix-trio.png -------------------------------------------------------------------------------- /assembly_guide/static/img/hack/matrix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/hack/matrix.png -------------------------------------------------------------------------------- /assembly_guide/static/img/hack/serial-plotter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/hack/serial-plotter.png -------------------------------------------------------------------------------- /assembly_guide/static/img/keys_endstop.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/keys_endstop.gif -------------------------------------------------------------------------------- /assembly_guide/static/img/pcb_assembly/010201@0.5x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/pcb_assembly/010201@0.5x.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/pcb_assembly/010302@0.5x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/pcb_assembly/010302@0.5x.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/pcb_assembly/010303@0.5x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/pcb_assembly/010303@0.5x.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/pcb_assembly/010306@0.5x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/pcb_assembly/010306@0.5x.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/pcb_assembly/010308@0.5x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/pcb_assembly/010308@0.5x.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/pcb_assembly/020101@0.5x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/pcb_assembly/020101@0.5x.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/pcb_assembly/020102@0.5x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/pcb_assembly/020102@0.5x.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/pcb_assembly/020400@0.5x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/pcb_assembly/020400@0.5x.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/pcb_assembly/030400@0.5x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/pcb_assembly/030400@0.5x.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/pcb_assembly/040200@0.5x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/pcb_assembly/040200@0.5x.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/pcb_assembly/050300@0.5x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/pcb_assembly/050300@0.5x.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/pcb_assembly/060201@0.5x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/pcb_assembly/060201@0.5x.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/pcb_assembly/060500@0.5x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/pcb_assembly/060500@0.5x.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/pcb_assembly/070200@0.5x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/pcb_assembly/070200@0.5x.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/pcb_assembly/090200@0.5x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/pcb_assembly/090200@0.5x.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/pcb_assembly/battery_tabs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/pcb_assembly/battery_tabs.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/pcb_assembly/button_alignment.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/pcb_assembly/button_alignment.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/print_supports.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/print_supports.gif -------------------------------------------------------------------------------- /assembly_guide/static/img/remove_print_support.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/remove_print_support.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/scout-10-838-032.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/scout-10-838-032.gif -------------------------------------------------------------------------------- /assembly_guide/static/img/scout.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/scout.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/scout_3d_printed_parts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/scout_3d_printed_parts.png -------------------------------------------------------------------------------- /assembly_guide/static/img/scout_assembly-16-420-8-128.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/scout_assembly-16-420-8-128.gif -------------------------------------------------------------------------------- /assembly_guide/static/img/scout_pieces.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/scout_pieces.png -------------------------------------------------------------------------------- /assembly_guide/static/img/scout_render.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/scout_render.png -------------------------------------------------------------------------------- /assembly_guide/static/img/video-how_to_open.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/video-how_to_open.jpg -------------------------------------------------------------------------------- /assembly_guide/static/img/video.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/assembly_guide/static/img/video.jpg -------------------------------------------------------------------------------- /burn_chip.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | { 4 | 5 | # Exit on error 6 | set -o errexit 7 | set -o errtrace 8 | 9 | use_uart_for_upload=true 10 | 11 | avrdude_folder="$HOME/Library/Arduino15/packages/arduino" 12 | avrdude="$avrdude_folder/tools/avrdude/6.3.0-arduino17/bin/avrdude" 13 | avrdude_config="$avrdude_folder/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf" 14 | 15 | optiboot="$avrdude_folder/hardware/avr/1.8.3/bootloaders/optiboot/optiboot_atmega328.hex" 16 | scout_hex="build/scout.ino.hex" 17 | scout_hex_with_bootloader="build/scout.ino.with_bootloader.hex" 18 | 19 | function burn_bootloader_using_programmer() { 20 | $avrdude \ 21 | -C"$avrdude_config" \ 22 | -v \ 23 | -patmega328p \ 24 | -cusbtiny \ 25 | -e \ 26 | -Ulock:w:0x3F:m \ 27 | -Uefuse:w:0xFD:m \ 28 | -Uhfuse:w:0xDE:m \ 29 | -Ulfuse:w:0xFF:m 30 | 31 | $avrdude \ 32 | -C"$avrdude_config" \ 33 | -v \ 34 | -patmega328p \ 35 | -cusbtiny \ 36 | -U"flash:w:$optiboot:i" \ 37 | -Ulock:w:0x0F:m 38 | } 39 | 40 | function upload_program_with_bootloader_using_programmer() { 41 | $avrdude \ 42 | -C"$avrdude_config" \ 43 | -v \ 44 | -patmega328p \ 45 | -cusbtiny \ 46 | -U"flash:w:$scout_hex_with_bootloader:i" 47 | } 48 | 49 | function upload_program_using_adafruit_cable() { 50 | $avrdude \ 51 | -C"$avrdude_config" \ 52 | -v \ 53 | -patmega328p \ 54 | -carduino \ 55 | -P/dev/cu.usbserial-AB0LJLX7 \ 56 | -b115200 \ 57 | -D \ 58 | -U"flash:w:$scout_hex:i" 59 | } 60 | 61 | function wait_for_space_key() { 62 | read -s -d ' ' 63 | } 64 | 65 | function verify_file_exists() { 66 | if [ ! -f "$1" ]; then 67 | echo "ERROR: $1 does not exist" 68 | exit 1 69 | fi 70 | } 71 | 72 | function compile_hex() { 73 | mkdir -pv build 74 | 75 | arduino-cli compile \ 76 | --fqbn arduino:avr:uno \ 77 | --build-path=$PWD/build \ 78 | arduino/scout 79 | } 80 | 81 | compile_hex 82 | 83 | verify_file_exists "$optiboot" 84 | verify_file_exists "$scout_hex" 85 | 86 | while true; do 87 | start=`date +%s` 88 | 89 | if $use_uart_for_upload; then 90 | burn_bootloader_using_programmer 91 | upload_program_using_adafruit_cable 92 | else 93 | upload_program_with_bootloader_using_programmer 94 | fi 95 | 96 | end=`date +%s` 97 | runtime=$((end-start)) 98 | 99 | echo 100 | echo "Done! Finished in $runtime seconds." 101 | echo "Press SPACE to burn another chip or CTRL+C to quit." 102 | wait_for_space_key 103 | 104 | echo 105 | done 106 | 107 | } 108 | -------------------------------------------------------------------------------- /kicad/keyboard_matrix/keyboard_matrix-cache.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.4 2 | #encoding utf-8 3 | # 4 | # Connector_Conn_01x09_Male 5 | # 6 | DEF Connector_Conn_01x09_Male J 0 40 Y N 1 F N 7 | F0 "J" 0 500 50 H V C CNN 8 | F1 "Connector_Conn_01x09_Male" 0 -500 50 H V C CNN 9 | F2 "" 0 0 50 H I C CNN 10 | F3 "" 0 0 50 H I C CNN 11 | $FPLIST 12 | Connector*:*_1x??_* 13 | $ENDFPLIST 14 | DRAW 15 | S 34 -395 0 -405 1 1 6 F 16 | S 34 -295 0 -305 1 1 6 F 17 | S 34 -195 0 -205 1 1 6 F 18 | S 34 -95 0 -105 1 1 6 F 19 | S 34 5 0 -5 1 1 6 F 20 | S 34 105 0 95 1 1 6 F 21 | S 34 205 0 195 1 1 6 F 22 | S 34 305 0 295 1 1 6 F 23 | S 34 405 0 395 1 1 6 F 24 | P 2 1 1 6 50 -400 34 -400 N 25 | P 2 1 1 6 50 -300 34 -300 N 26 | P 2 1 1 6 50 -200 34 -200 N 27 | P 2 1 1 6 50 -100 34 -100 N 28 | P 2 1 1 6 50 0 34 0 N 29 | P 2 1 1 6 50 100 34 100 N 30 | P 2 1 1 6 50 200 34 200 N 31 | P 2 1 1 6 50 300 34 300 N 32 | P 2 1 1 6 50 400 34 400 N 33 | X Pin_1 1 200 400 150 L 50 50 1 1 P 34 | X Pin_2 2 200 300 150 L 50 50 1 1 P 35 | X Pin_3 3 200 200 150 L 50 50 1 1 P 36 | X Pin_4 4 200 100 150 L 50 50 1 1 P 37 | X Pin_5 5 200 0 150 L 50 50 1 1 P 38 | X Pin_6 6 200 -100 150 L 50 50 1 1 P 39 | X Pin_7 7 200 -200 150 L 50 50 1 1 P 40 | X Pin_8 8 200 -300 150 L 50 50 1 1 P 41 | X Pin_9 9 200 -400 150 L 50 50 1 1 P 42 | ENDDRAW 43 | ENDDEF 44 | # 45 | # Switch_SW_SPST 46 | # 47 | DEF Switch_SW_SPST SW 0 0 Y N 1 F N 48 | F0 "SW" 0 125 50 H V C CNN 49 | F1 "Switch_SW_SPST" 0 -100 50 H V C CNN 50 | F2 "" 0 0 50 H I C CNN 51 | F3 "" 0 0 50 H I C CNN 52 | DRAW 53 | C -80 0 20 0 0 0 N 54 | C 80 0 20 0 0 0 N 55 | P 2 0 0 0 -60 10 60 70 N 56 | X A 1 -200 0 100 R 50 50 1 1 P 57 | X B 2 200 0 100 L 50 50 1 1 P 58 | ENDDRAW 59 | ENDDEF 60 | # 61 | #End Library 62 | -------------------------------------------------------------------------------- /kicad/keyboard_matrix/keyboard_matrix.pro: -------------------------------------------------------------------------------- 1 | update=Friday, January 29, 2021 at 12:09:05 PM 2 | version=1 3 | last_client=kicad 4 | [general] 5 | version=1 6 | RootSch= 7 | BoardNm= 8 | [cvpcb] 9 | version=1 10 | NetIExt=net 11 | [eeschema] 12 | version=1 13 | LibDir= 14 | [eeschema/libraries] 15 | [pcbnew] 16 | version=1 17 | PageLayoutDescrFile= 18 | LastNetListRead= 19 | CopperLayerCount=2 20 | BoardThickness=1.6 21 | AllowMicroVias=0 22 | AllowBlindVias=0 23 | RequireCourtyardDefinitions=0 24 | ProhibitOverlappingCourtyards=1 25 | MinTrackWidth=0.2 26 | MinViaDiameter=0.4 27 | MinViaDrill=0.3 28 | MinMicroViaDiameter=0.2 29 | MinMicroViaDrill=0.09999999999999999 30 | MinHoleToHole=0.25 31 | TrackWidth1=0.25 32 | TrackWidth2=0.5 33 | ViaDiameter1=0.8 34 | ViaDrill1=0.4 35 | dPairWidth1=0.2 36 | dPairGap1=0.25 37 | dPairViaGap1=0.25 38 | SilkLineWidth=0.12 39 | SilkTextSizeV=1 40 | SilkTextSizeH=1 41 | SilkTextSizeThickness=0.15 42 | SilkTextItalic=0 43 | SilkTextUpright=1 44 | CopperLineWidth=0.2 45 | CopperTextSizeV=1.5 46 | CopperTextSizeH=1.5 47 | CopperTextThickness=0.3 48 | CopperTextItalic=0 49 | CopperTextUpright=1 50 | EdgeCutLineWidth=0.05 51 | CourtyardLineWidth=0.05 52 | OthersLineWidth=0.15 53 | OthersTextSizeV=1 54 | OthersTextSizeH=1 55 | OthersTextSizeThickness=0.15 56 | OthersTextItalic=0 57 | OthersTextUpright=1 58 | SolderMaskClearance=0.05 59 | SolderMaskMinWidth=0 60 | SolderPasteClearance=0 61 | SolderPasteRatio=-0 62 | [pcbnew/Layer.F.Cu] 63 | Name=F.Cu 64 | Type=0 65 | Enabled=1 66 | [pcbnew/Layer.In1.Cu] 67 | Name=In1.Cu 68 | Type=0 69 | Enabled=0 70 | [pcbnew/Layer.In2.Cu] 71 | Name=In2.Cu 72 | Type=0 73 | Enabled=0 74 | [pcbnew/Layer.In3.Cu] 75 | Name=In3.Cu 76 | Type=0 77 | Enabled=0 78 | [pcbnew/Layer.In4.Cu] 79 | Name=In4.Cu 80 | Type=0 81 | Enabled=0 82 | [pcbnew/Layer.In5.Cu] 83 | Name=In5.Cu 84 | Type=0 85 | Enabled=0 86 | [pcbnew/Layer.In6.Cu] 87 | Name=In6.Cu 88 | Type=0 89 | Enabled=0 90 | [pcbnew/Layer.In7.Cu] 91 | Name=In7.Cu 92 | Type=0 93 | Enabled=0 94 | [pcbnew/Layer.In8.Cu] 95 | Name=In8.Cu 96 | Type=0 97 | Enabled=0 98 | [pcbnew/Layer.In9.Cu] 99 | Name=In9.Cu 100 | Type=0 101 | Enabled=0 102 | [pcbnew/Layer.In10.Cu] 103 | Name=In10.Cu 104 | Type=0 105 | Enabled=0 106 | [pcbnew/Layer.In11.Cu] 107 | Name=In11.Cu 108 | Type=0 109 | Enabled=0 110 | [pcbnew/Layer.In12.Cu] 111 | Name=In12.Cu 112 | Type=0 113 | Enabled=0 114 | [pcbnew/Layer.In13.Cu] 115 | Name=In13.Cu 116 | Type=0 117 | Enabled=0 118 | [pcbnew/Layer.In14.Cu] 119 | Name=In14.Cu 120 | Type=0 121 | Enabled=0 122 | [pcbnew/Layer.In15.Cu] 123 | Name=In15.Cu 124 | Type=0 125 | Enabled=0 126 | [pcbnew/Layer.In16.Cu] 127 | Name=In16.Cu 128 | Type=0 129 | Enabled=0 130 | [pcbnew/Layer.In17.Cu] 131 | Name=In17.Cu 132 | Type=0 133 | Enabled=0 134 | [pcbnew/Layer.In18.Cu] 135 | Name=In18.Cu 136 | Type=0 137 | Enabled=0 138 | [pcbnew/Layer.In19.Cu] 139 | Name=In19.Cu 140 | Type=0 141 | Enabled=0 142 | [pcbnew/Layer.In20.Cu] 143 | Name=In20.Cu 144 | Type=0 145 | Enabled=0 146 | [pcbnew/Layer.In21.Cu] 147 | Name=In21.Cu 148 | Type=0 149 | Enabled=0 150 | [pcbnew/Layer.In22.Cu] 151 | Name=In22.Cu 152 | Type=0 153 | Enabled=0 154 | [pcbnew/Layer.In23.Cu] 155 | Name=In23.Cu 156 | Type=0 157 | Enabled=0 158 | [pcbnew/Layer.In24.Cu] 159 | Name=In24.Cu 160 | Type=0 161 | Enabled=0 162 | [pcbnew/Layer.In25.Cu] 163 | Name=In25.Cu 164 | Type=0 165 | Enabled=0 166 | [pcbnew/Layer.In26.Cu] 167 | Name=In26.Cu 168 | Type=0 169 | Enabled=0 170 | [pcbnew/Layer.In27.Cu] 171 | Name=In27.Cu 172 | Type=0 173 | Enabled=0 174 | [pcbnew/Layer.In28.Cu] 175 | Name=In28.Cu 176 | Type=0 177 | Enabled=0 178 | [pcbnew/Layer.In29.Cu] 179 | Name=In29.Cu 180 | Type=0 181 | Enabled=0 182 | [pcbnew/Layer.In30.Cu] 183 | Name=In30.Cu 184 | Type=0 185 | Enabled=0 186 | [pcbnew/Layer.B.Cu] 187 | Name=B.Cu 188 | Type=0 189 | Enabled=1 190 | [pcbnew/Layer.B.Adhes] 191 | Enabled=1 192 | [pcbnew/Layer.F.Adhes] 193 | Enabled=1 194 | [pcbnew/Layer.B.Paste] 195 | Enabled=1 196 | [pcbnew/Layer.F.Paste] 197 | Enabled=1 198 | [pcbnew/Layer.B.SilkS] 199 | Enabled=1 200 | [pcbnew/Layer.F.SilkS] 201 | Enabled=1 202 | [pcbnew/Layer.B.Mask] 203 | Enabled=1 204 | [pcbnew/Layer.F.Mask] 205 | Enabled=1 206 | [pcbnew/Layer.Dwgs.User] 207 | Enabled=1 208 | [pcbnew/Layer.Cmts.User] 209 | Enabled=1 210 | [pcbnew/Layer.Eco1.User] 211 | Enabled=1 212 | [pcbnew/Layer.Eco2.User] 213 | Enabled=1 214 | [pcbnew/Layer.Edge.Cuts] 215 | Enabled=1 216 | [pcbnew/Layer.Margin] 217 | Enabled=1 218 | [pcbnew/Layer.B.CrtYd] 219 | Enabled=1 220 | [pcbnew/Layer.F.CrtYd] 221 | Enabled=1 222 | [pcbnew/Layer.B.Fab] 223 | Enabled=1 224 | [pcbnew/Layer.F.Fab] 225 | Enabled=1 226 | [pcbnew/Layer.Rescue] 227 | Enabled=0 228 | [pcbnew/Netclasses] 229 | [pcbnew/Netclasses/Default] 230 | Name=Default 231 | Clearance=0.2 232 | TrackWidth=0.25 233 | ViaDiameter=0.8 234 | ViaDrill=0.4 235 | uViaDiameter=0.3 236 | uViaDrill=0.1 237 | dPairWidth=0.2 238 | dPairGap=0.25 239 | dPairViaGap=0.25 240 | [pcbnew/Netclasses/1] 241 | Name=Fat 242 | Clearance=0.2 243 | TrackWidth=0.5 244 | ViaDiameter=0.8 245 | ViaDrill=0.4 246 | uViaDiameter=0.3 247 | uViaDrill=0.1 248 | dPairWidth=0.2 249 | dPairGap=0.25 250 | dPairViaGap=0.25 251 | -------------------------------------------------------------------------------- /kicad/keyboard_matrix/keyboard_matrix.sch-bak: -------------------------------------------------------------------------------- 1 | EESchema Schematic File Version 4 2 | EELAYER 30 0 3 | EELAYER END 4 | $Descr A4 11693 8268 5 | encoding utf-8 6 | Sheet 1 1 7 | Title "" 8 | Date "" 9 | Rev "" 10 | Comp "" 11 | Comment1 "" 12 | Comment2 "" 13 | Comment3 "" 14 | Comment4 "" 15 | $EndDescr 16 | $Comp 17 | L Switch:SW_SPST SW1 18 | U 1 1 6017F202 19 | P 3700 3200 20 | F 0 "SW1" H 3700 3435 50 0000 C CNN 21 | F 1 "SPST" H 3700 3344 50 0000 C CNN 22 | F 2 "" H 3700 3200 50 0001 C CNN 23 | F 3 "~" H 3700 3200 50 0001 C CNN 24 | 1 3700 3200 25 | 1 0 0 -1 26 | $EndComp 27 | Wire Wire Line 28 | 3900 3200 4000 3200 29 | Wire Wire Line 30 | 4000 3200 4000 2850 31 | Wire Wire Line 32 | 3500 3200 3400 3200 33 | Wire Wire Line 34 | 3400 3200 3400 3700 35 | $Comp 36 | L Switch:SW_SPST SW5 37 | U 1 1 60188B3A 38 | P 4450 3200 39 | F 0 "SW5" H 4450 3435 50 0000 C CNN 40 | F 1 "SPST" H 4450 3344 50 0000 C CNN 41 | F 2 "" H 4450 3200 50 0001 C CNN 42 | F 3 "~" H 4450 3200 50 0001 C CNN 43 | 1 4450 3200 44 | 1 0 0 -1 45 | $EndComp 46 | Wire Wire Line 47 | 4650 3200 4750 3200 48 | Wire Wire Line 49 | 4750 3200 4750 2850 50 | Wire Wire Line 51 | 4250 3200 4150 3200 52 | Wire Wire Line 53 | 4150 3200 4150 3700 54 | $Comp 55 | L Switch:SW_SPST SW9 56 | U 1 1 6018A55A 57 | P 5200 3200 58 | F 0 "SW9" H 5200 3435 50 0000 C CNN 59 | F 1 "SPST" H 5200 3344 50 0000 C CNN 60 | F 2 "" H 5200 3200 50 0001 C CNN 61 | F 3 "~" H 5200 3200 50 0001 C CNN 62 | 1 5200 3200 63 | 1 0 0 -1 64 | $EndComp 65 | Wire Wire Line 66 | 5400 3200 5500 3200 67 | Wire Wire Line 68 | 5500 3200 5500 2850 69 | Wire Wire Line 70 | 5000 3200 4900 3200 71 | Wire Wire Line 72 | 4900 3200 4900 3700 73 | $Comp 74 | L Switch:SW_SPST SW13 75 | U 1 1 6018A564 76 | P 5950 3200 77 | F 0 "SW13" H 5950 3435 50 0000 C CNN 78 | F 1 "SPST" H 5950 3344 50 0000 C CNN 79 | F 2 "" H 5950 3200 50 0001 C CNN 80 | F 3 "~" H 5950 3200 50 0001 C CNN 81 | 1 5950 3200 82 | 1 0 0 -1 83 | $EndComp 84 | Wire Wire Line 85 | 6150 3200 6250 3200 86 | Wire Wire Line 87 | 6250 3200 6250 2850 88 | Wire Wire Line 89 | 5750 3200 5650 3200 90 | Wire Wire Line 91 | 5650 3200 5650 3700 92 | $Comp 93 | L Switch:SW_SPST SW17 94 | U 1 1 6018B40B 95 | P 6700 3200 96 | F 0 "SW17" H 6700 3435 50 0000 C CNN 97 | F 1 "SPST" H 6700 3344 50 0000 C CNN 98 | F 2 "" H 6700 3200 50 0001 C CNN 99 | F 3 "~" H 6700 3200 50 0001 C CNN 100 | 1 6700 3200 101 | 1 0 0 -1 102 | $EndComp 103 | Wire Wire Line 104 | 6900 3200 7000 3200 105 | Wire Wire Line 106 | 7000 3200 7000 2850 107 | Wire Wire Line 108 | 6500 3200 6400 3200 109 | Wire Wire Line 110 | 6400 3200 6400 3700 111 | $Comp 112 | L Switch:SW_SPST SW2 113 | U 1 1 6019D891 114 | P 3700 3700 115 | F 0 "SW2" H 3700 3935 50 0000 C CNN 116 | F 1 "SPST" H 3700 3844 50 0000 C CNN 117 | F 2 "" H 3700 3700 50 0001 C CNN 118 | F 3 "~" H 3700 3700 50 0001 C CNN 119 | 1 3700 3700 120 | 1 0 0 -1 121 | $EndComp 122 | Wire Wire Line 123 | 3900 3700 4000 3700 124 | Wire Wire Line 125 | 4650 3700 4750 3700 126 | $Comp 127 | L Switch:SW_SPST SW10 128 | U 1 1 6019D8A1 129 | P 5200 3700 130 | F 0 "SW10" H 5200 3935 50 0000 C CNN 131 | F 1 "SPST" H 5200 3844 50 0000 C CNN 132 | F 2 "" H 5200 3700 50 0001 C CNN 133 | F 3 "~" H 5200 3700 50 0001 C CNN 134 | 1 5200 3700 135 | 1 0 0 -1 136 | $EndComp 137 | Wire Wire Line 138 | 5400 3700 5500 3700 139 | $Comp 140 | L Switch:SW_SPST SW14 141 | U 1 1 6019D8A9 142 | P 5950 3700 143 | F 0 "SW14" H 5950 3935 50 0000 C CNN 144 | F 1 "SPST" H 5950 3844 50 0000 C CNN 145 | F 2 "" H 5950 3700 50 0001 C CNN 146 | F 3 "~" H 5950 3700 50 0001 C CNN 147 | 1 5950 3700 148 | 1 0 0 -1 149 | $EndComp 150 | Wire Wire Line 151 | 6150 3700 6250 3700 152 | $Comp 153 | L Switch:SW_SPST SW18 154 | U 1 1 6019D8B1 155 | P 6700 3700 156 | F 0 "SW18" H 6700 3935 50 0000 C CNN 157 | F 1 "SPST" H 6700 3844 50 0000 C CNN 158 | F 2 "" H 6700 3700 50 0001 C CNN 159 | F 3 "~" H 6700 3700 50 0001 C CNN 160 | 1 6700 3700 161 | 1 0 0 -1 162 | $EndComp 163 | Wire Wire Line 164 | 6900 3700 7000 3700 165 | $Comp 166 | L Switch:SW_SPST SW6 167 | U 1 1 6019D899 168 | P 4450 3700 169 | F 0 "SW6" H 4450 3935 50 0000 C CNN 170 | F 1 "SPST" H 4450 3844 50 0000 C CNN 171 | F 2 "" H 4450 3700 50 0001 C CNN 172 | F 3 "~" H 4450 3700 50 0001 C CNN 173 | 1 4450 3700 174 | 1 0 0 -1 175 | $EndComp 176 | Wire Wire Line 177 | 4000 2850 4750 2850 178 | Wire Wire Line 179 | 4750 2850 5500 2850 180 | Connection ~ 4750 2850 181 | Wire Wire Line 182 | 5500 2850 6250 2850 183 | Connection ~ 5500 2850 184 | Wire Wire Line 185 | 6250 2850 7000 2850 186 | Connection ~ 6250 2850 187 | Wire Wire Line 188 | 3500 3700 3400 3700 189 | Connection ~ 3400 3700 190 | Wire Wire Line 191 | 3400 3700 3400 4200 192 | Wire Wire Line 193 | 4150 3700 4250 3700 194 | Connection ~ 4150 3700 195 | Wire Wire Line 196 | 4150 3700 4150 4200 197 | Wire Wire Line 198 | 4900 3700 5000 3700 199 | Connection ~ 4900 3700 200 | Wire Wire Line 201 | 4900 3700 4900 4200 202 | Wire Wire Line 203 | 5650 3700 5750 3700 204 | Connection ~ 5650 3700 205 | Wire Wire Line 206 | 5650 3700 5650 4200 207 | Wire Wire Line 208 | 6400 3700 6500 3700 209 | Connection ~ 6400 3700 210 | Wire Wire Line 211 | 6400 3700 6400 4200 212 | Wire Wire Line 213 | 4000 3350 4000 3700 214 | Wire Wire Line 215 | 4000 3350 4750 3350 216 | Wire Wire Line 217 | 4750 3350 4750 3700 218 | Wire Wire Line 219 | 4750 3350 5500 3350 220 | Wire Wire Line 221 | 5500 3350 5500 3700 222 | Connection ~ 4750 3350 223 | Wire Wire Line 224 | 5500 3350 6250 3350 225 | Wire Wire Line 226 | 6250 3350 6250 3700 227 | Connection ~ 5500 3350 228 | Wire Wire Line 229 | 6250 3350 7000 3350 230 | Wire Wire Line 231 | 7000 3350 7000 3700 232 | Connection ~ 6250 3350 233 | $Comp 234 | L Switch:SW_SPST SW3 235 | U 1 1 601BC6E8 236 | P 3700 4200 237 | F 0 "SW3" H 3700 4435 50 0000 C CNN 238 | F 1 "SPST" H 3700 4344 50 0000 C CNN 239 | F 2 "" H 3700 4200 50 0001 C CNN 240 | F 3 "~" H 3700 4200 50 0001 C CNN 241 | 1 3700 4200 242 | 1 0 0 -1 243 | $EndComp 244 | $Comp 245 | L Switch:SW_SPST SW7 246 | U 1 1 601BC6EE 247 | P 4450 4200 248 | F 0 "SW7" H 4450 4435 50 0000 C CNN 249 | F 1 "SPST" H 4450 4344 50 0000 C CNN 250 | F 2 "" H 4450 4200 50 0001 C CNN 251 | F 3 "~" H 4450 4200 50 0001 C CNN 252 | 1 4450 4200 253 | 1 0 0 -1 254 | $EndComp 255 | $Comp 256 | L Switch:SW_SPST SW11 257 | U 1 1 601BC6F4 258 | P 5200 4200 259 | F 0 "SW11" H 5200 4435 50 0000 C CNN 260 | F 1 "SPST" H 5200 4344 50 0000 C CNN 261 | F 2 "" H 5200 4200 50 0001 C CNN 262 | F 3 "~" H 5200 4200 50 0001 C CNN 263 | 1 5200 4200 264 | 1 0 0 -1 265 | $EndComp 266 | $Comp 267 | L Switch:SW_SPST SW15 268 | U 1 1 601BC6FA 269 | P 5950 4200 270 | F 0 "SW15" H 5950 4435 50 0000 C CNN 271 | F 1 "SPST" H 5950 4344 50 0000 C CNN 272 | F 2 "" H 5950 4200 50 0001 C CNN 273 | F 3 "~" H 5950 4200 50 0001 C CNN 274 | 1 5950 4200 275 | 1 0 0 -1 276 | $EndComp 277 | $Comp 278 | L Switch:SW_SPST SW19 279 | U 1 1 601BC700 280 | P 6700 4200 281 | F 0 "SW19" H 6700 4435 50 0000 C CNN 282 | F 1 "SPST" H 6700 4344 50 0000 C CNN 283 | F 2 "" H 6700 4200 50 0001 C CNN 284 | F 3 "~" H 6700 4200 50 0001 C CNN 285 | 1 6700 4200 286 | 1 0 0 -1 287 | $EndComp 288 | $Comp 289 | L Switch:SW_SPST SW4 290 | U 1 1 601C0013 291 | P 3700 4750 292 | F 0 "SW4" H 3700 4985 50 0000 C CNN 293 | F 1 "SPST" H 3700 4894 50 0000 C CNN 294 | F 2 "" H 3700 4750 50 0001 C CNN 295 | F 3 "~" H 3700 4750 50 0001 C CNN 296 | 1 3700 4750 297 | 1 0 0 -1 298 | $EndComp 299 | $Comp 300 | L Switch:SW_SPST SW8 301 | U 1 1 601C0019 302 | P 4450 4750 303 | F 0 "SW8" H 4450 4985 50 0000 C CNN 304 | F 1 "SPST" H 4450 4894 50 0000 C CNN 305 | F 2 "" H 4450 4750 50 0001 C CNN 306 | F 3 "~" H 4450 4750 50 0001 C CNN 307 | 1 4450 4750 308 | 1 0 0 -1 309 | $EndComp 310 | $Comp 311 | L Switch:SW_SPST SW12 312 | U 1 1 601C001F 313 | P 5200 4750 314 | F 0 "SW12" H 5200 4985 50 0000 C CNN 315 | F 1 "SPST" H 5200 4894 50 0000 C CNN 316 | F 2 "" H 5200 4750 50 0001 C CNN 317 | F 3 "~" H 5200 4750 50 0001 C CNN 318 | 1 5200 4750 319 | 1 0 0 -1 320 | $EndComp 321 | $Comp 322 | L Switch:SW_SPST SW16 323 | U 1 1 601C0025 324 | P 5950 4750 325 | F 0 "SW16" H 5950 4985 50 0000 C CNN 326 | F 1 "SPST" H 5950 4894 50 0000 C CNN 327 | F 2 "" H 5950 4750 50 0001 C CNN 328 | F 3 "~" H 5950 4750 50 0001 C CNN 329 | 1 5950 4750 330 | 1 0 0 -1 331 | $EndComp 332 | $Comp 333 | L Switch:SW_SPST SW20 334 | U 1 1 601C002B 335 | P 6700 4750 336 | F 0 "SW20" H 6700 4985 50 0000 C CNN 337 | F 1 "SPST" H 6700 4894 50 0000 C CNN 338 | F 2 "" H 6700 4750 50 0001 C CNN 339 | F 3 "~" H 6700 4750 50 0001 C CNN 340 | 1 6700 4750 341 | 1 0 0 -1 342 | $EndComp 343 | Wire Wire Line 344 | 3500 4200 3400 4200 345 | Connection ~ 3400 4200 346 | Wire Wire Line 347 | 3400 4200 3400 4750 348 | Wire Wire Line 349 | 3400 4750 3500 4750 350 | Wire Wire Line 351 | 4250 4200 4150 4200 352 | Connection ~ 4150 4200 353 | Wire Wire Line 354 | 4150 4200 4150 4750 355 | Wire Wire Line 356 | 4250 4750 4150 4750 357 | Wire Wire Line 358 | 5000 4200 4900 4200 359 | Connection ~ 4900 4200 360 | Wire Wire Line 361 | 4900 4200 4900 4750 362 | Wire Wire Line 363 | 5000 4750 4900 4750 364 | Wire Wire Line 365 | 5750 4200 5650 4200 366 | Connection ~ 5650 4200 367 | Wire Wire Line 368 | 5650 4200 5650 4750 369 | Wire Wire Line 370 | 5750 4750 5650 4750 371 | Wire Wire Line 372 | 6500 4200 6400 4200 373 | Connection ~ 6400 4200 374 | Wire Wire Line 375 | 6400 4200 6400 4750 376 | Wire Wire Line 377 | 6500 4750 6400 4750 378 | Wire Wire Line 379 | 4000 3850 4000 4200 380 | Wire Wire Line 381 | 4000 4200 3900 4200 382 | Wire Wire Line 383 | 4000 3850 4750 3850 384 | Wire Wire Line 385 | 4750 3850 4750 4200 386 | Wire Wire Line 387 | 4750 4200 4650 4200 388 | Wire Wire Line 389 | 4750 3850 5500 3850 390 | Wire Wire Line 391 | 5500 3850 5500 4200 392 | Wire Wire Line 393 | 5500 4200 5400 4200 394 | Connection ~ 4750 3850 395 | Wire Wire Line 396 | 5500 3850 6250 3850 397 | Wire Wire Line 398 | 6250 3850 6250 4200 399 | Wire Wire Line 400 | 6250 4200 6150 4200 401 | Connection ~ 5500 3850 402 | Wire Wire Line 403 | 6250 3850 7000 3850 404 | Wire Wire Line 405 | 7000 3850 7000 4200 406 | Wire Wire Line 407 | 7000 4200 6900 4200 408 | Connection ~ 6250 3850 409 | Wire Wire Line 410 | 3900 4750 4000 4750 411 | Wire Wire Line 412 | 4000 4750 4000 4400 413 | Wire Wire Line 414 | 4000 4400 4750 4400 415 | Wire Wire Line 416 | 4750 4400 4750 4750 417 | Wire Wire Line 418 | 4750 4750 4650 4750 419 | Wire Wire Line 420 | 4750 4400 5500 4400 421 | Wire Wire Line 422 | 5500 4400 5500 4750 423 | Wire Wire Line 424 | 5500 4750 5400 4750 425 | Connection ~ 4750 4400 426 | Wire Wire Line 427 | 5500 4400 6250 4400 428 | Wire Wire Line 429 | 6250 4400 6250 4750 430 | Wire Wire Line 431 | 6250 4750 6150 4750 432 | Connection ~ 5500 4400 433 | Wire Wire Line 434 | 6250 4400 7000 4400 435 | Wire Wire Line 436 | 7000 4400 7000 4750 437 | Wire Wire Line 438 | 7000 4750 6900 4750 439 | Connection ~ 6250 4400 440 | $Comp 441 | L Connector:Conn_01x09_Male J1 442 | U 1 1 601E9991 443 | P 8450 4000 444 | F 0 "J1" H 8300 4200 50 0000 C CNN 445 | F 1 "Conn_01x09" H 8150 4050 50 0000 C CNN 446 | F 2 "" H 8450 4000 50 0001 C CNN 447 | F 3 "~" H 8450 4000 50 0001 C CNN 448 | 1 8450 4000 449 | 1 0 0 -1 450 | $EndComp 451 | Text Label 7200 2850 0 50 ~ 0 452 | R1 453 | Text Label 7200 3350 0 50 ~ 0 454 | R2 455 | Text Label 7200 3850 0 50 ~ 0 456 | R3 457 | Text Label 7200 4400 0 50 ~ 0 458 | R4 459 | Text Label 3400 5050 0 50 ~ 0 460 | C1 461 | Text Label 4150 5050 0 50 ~ 0 462 | C2 463 | Text Label 4900 5050 0 50 ~ 0 464 | C3 465 | Text Label 5650 5050 0 50 ~ 0 466 | C4 467 | Text Label 6400 5050 0 50 ~ 0 468 | C5 469 | Wire Wire Line 470 | 3400 4750 3400 5050 471 | Connection ~ 3400 4750 472 | Wire Wire Line 473 | 4150 4750 4150 5050 474 | Connection ~ 4150 4750 475 | Wire Wire Line 476 | 4900 4750 4900 5050 477 | Connection ~ 4900 4750 478 | Wire Wire Line 479 | 5650 4750 5650 5050 480 | Connection ~ 5650 4750 481 | Wire Wire Line 482 | 6400 4750 6400 5050 483 | Connection ~ 6400 4750 484 | Wire Wire Line 485 | 7000 2850 7200 2850 486 | Connection ~ 7000 2850 487 | Wire Wire Line 488 | 7000 3350 7200 3350 489 | Connection ~ 7000 3350 490 | Wire Wire Line 491 | 7200 3850 7000 3850 492 | Connection ~ 7000 3850 493 | Wire Wire Line 494 | 7200 4400 7000 4400 495 | Connection ~ 7000 4400 496 | Text Label 8650 3600 0 50 ~ 0 497 | C1 498 | Text Label 8650 3700 0 50 ~ 0 499 | C2 500 | Text Label 8650 3800 0 50 ~ 0 501 | C3 502 | Text Label 8650 3900 0 50 ~ 0 503 | C4 504 | Text Label 8650 4100 0 50 ~ 0 505 | R1 506 | Text Label 8650 4000 0 50 ~ 0 507 | C5 508 | Text Label 8650 4200 0 50 ~ 0 509 | R2 510 | Text Label 8650 4300 0 50 ~ 0 511 | R3 512 | Text Label 8650 4400 0 50 ~ 0 513 | R4 514 | $EndSCHEMATC 515 | -------------------------------------------------------------------------------- /kicad/scout/fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (lib (name sparkfun-connectors)(type KiCad)(uri /Users/tommy/SparkFun-KiCad-Libraries/Footprints/Connectors.pretty)(options "")(descr "")) 3 | (lib (name digikey)(type KiCad)(uri /Users/tommy/digikey-kicad-library/digikey-footprints.pretty)(options "")(descr "")) 4 | (lib (name scout)(type KiCad)(uri ${KIPRJMOD}/scout.pretty)(options "")(descr "")) 5 | ) 6 | -------------------------------------------------------------------------------- /kicad/scout/keyboard_matrix.sch: -------------------------------------------------------------------------------- 1 | EESchema Schematic File Version 4 2 | EELAYER 30 0 3 | EELAYER END 4 | $Descr A4 11693 8268 5 | encoding utf-8 6 | Sheet 2 2 7 | Title "" 8 | Date "" 9 | Rev "" 10 | Comp "" 11 | Comment1 "" 12 | Comment2 "" 13 | Comment3 "" 14 | Comment4 "" 15 | $EndDescr 16 | $Comp 17 | L Switch:SW_SPST SW2 18 | U 1 1 6017F202 19 | P 3700 3200 20 | F 0 "SW2" H 3700 3435 50 0000 C CNN 21 | F 1 "SPST" H 3700 3344 50 0000 C CNN 22 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 3700 3200 50 0001 C CNN 23 | F 3 "~" H 3700 3200 50 0001 C CNN 24 | 1 3700 3200 25 | 1 0 0 -1 26 | $EndComp 27 | Wire Wire Line 28 | 3900 3200 4000 3200 29 | Wire Wire Line 30 | 4000 3200 4000 2850 31 | Wire Wire Line 32 | 3500 3200 3400 3200 33 | Wire Wire Line 34 | 3400 3200 3400 3700 35 | $Comp 36 | L Switch:SW_SPST SW6 37 | U 1 1 60188B3A 38 | P 4450 3200 39 | F 0 "SW6" H 4450 3435 50 0000 C CNN 40 | F 1 "SPST" H 4450 3344 50 0000 C CNN 41 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 4450 3200 50 0001 C CNN 42 | F 3 "~" H 4450 3200 50 0001 C CNN 43 | 1 4450 3200 44 | 1 0 0 -1 45 | $EndComp 46 | Wire Wire Line 47 | 4650 3200 4750 3200 48 | Wire Wire Line 49 | 4750 3200 4750 2850 50 | Wire Wire Line 51 | 4250 3200 4150 3200 52 | Wire Wire Line 53 | 4150 3200 4150 3700 54 | $Comp 55 | L Switch:SW_SPST SW10 56 | U 1 1 6018A55A 57 | P 5200 3200 58 | F 0 "SW10" H 5200 3435 50 0000 C CNN 59 | F 1 "SPST" H 5200 3344 50 0000 C CNN 60 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 5200 3200 50 0001 C CNN 61 | F 3 "~" H 5200 3200 50 0001 C CNN 62 | 1 5200 3200 63 | 1 0 0 -1 64 | $EndComp 65 | Wire Wire Line 66 | 5400 3200 5500 3200 67 | Wire Wire Line 68 | 5500 3200 5500 2850 69 | Wire Wire Line 70 | 5000 3200 4900 3200 71 | Wire Wire Line 72 | 4900 3200 4900 3700 73 | $Comp 74 | L Switch:SW_SPST SW13 75 | U 1 1 6018A564 76 | P 5950 3200 77 | F 0 "SW13" H 5950 3435 50 0000 C CNN 78 | F 1 "SPST" H 5950 3344 50 0000 C CNN 79 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 5950 3200 50 0001 C CNN 80 | F 3 "~" H 5950 3200 50 0001 C CNN 81 | 1 5950 3200 82 | 1 0 0 -1 83 | $EndComp 84 | Wire Wire Line 85 | 6150 3200 6250 3200 86 | Wire Wire Line 87 | 6250 3200 6250 2850 88 | Wire Wire Line 89 | 5750 3200 5650 3200 90 | Wire Wire Line 91 | 5650 3200 5650 3700 92 | $Comp 93 | L Switch:SW_SPST SW16 94 | U 1 1 6018B40B 95 | P 6700 3200 96 | F 0 "SW16" H 6700 3435 50 0000 C CNN 97 | F 1 "SPST" H 6700 3344 50 0000 C CNN 98 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 6700 3200 50 0001 C CNN 99 | F 3 "~" H 6700 3200 50 0001 C CNN 100 | 1 6700 3200 101 | 1 0 0 -1 102 | $EndComp 103 | Wire Wire Line 104 | 6900 3200 7000 3200 105 | Wire Wire Line 106 | 7000 3200 7000 2850 107 | Wire Wire Line 108 | 6500 3200 6400 3200 109 | Wire Wire Line 110 | 6400 3200 6400 3700 111 | $Comp 112 | L Switch:SW_SPST SW3 113 | U 1 1 6019D891 114 | P 3700 3700 115 | F 0 "SW3" H 3700 3935 50 0000 C CNN 116 | F 1 "SPST" H 3700 3844 50 0000 C CNN 117 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 3700 3700 50 0001 C CNN 118 | F 3 "~" H 3700 3700 50 0001 C CNN 119 | 1 3700 3700 120 | 1 0 0 -1 121 | $EndComp 122 | Wire Wire Line 123 | 3900 3700 4000 3700 124 | Wire Wire Line 125 | 4650 3700 4750 3700 126 | $Comp 127 | L Switch:SW_SPST SW11 128 | U 1 1 6019D8A1 129 | P 5200 3700 130 | F 0 "SW11" H 5200 3935 50 0000 C CNN 131 | F 1 "SPST" H 5200 3844 50 0000 C CNN 132 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 5200 3700 50 0001 C CNN 133 | F 3 "~" H 5200 3700 50 0001 C CNN 134 | 1 5200 3700 135 | 1 0 0 -1 136 | $EndComp 137 | Wire Wire Line 138 | 5400 3700 5500 3700 139 | $Comp 140 | L Switch:SW_SPST SW14 141 | U 1 1 6019D8A9 142 | P 5950 3700 143 | F 0 "SW14" H 5950 3935 50 0000 C CNN 144 | F 1 "SPST" H 5950 3844 50 0000 C CNN 145 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 5950 3700 50 0001 C CNN 146 | F 3 "~" H 5950 3700 50 0001 C CNN 147 | 1 5950 3700 148 | 1 0 0 -1 149 | $EndComp 150 | Wire Wire Line 151 | 6150 3700 6250 3700 152 | $Comp 153 | L Switch:SW_SPST SW17 154 | U 1 1 6019D8B1 155 | P 6700 3700 156 | F 0 "SW17" H 6700 3935 50 0000 C CNN 157 | F 1 "SPST" H 6700 3844 50 0000 C CNN 158 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 6700 3700 50 0001 C CNN 159 | F 3 "~" H 6700 3700 50 0001 C CNN 160 | 1 6700 3700 161 | 1 0 0 -1 162 | $EndComp 163 | Wire Wire Line 164 | 6900 3700 7000 3700 165 | $Comp 166 | L Switch:SW_SPST SW7 167 | U 1 1 6019D899 168 | P 4450 3700 169 | F 0 "SW7" H 4450 3935 50 0000 C CNN 170 | F 1 "SPST" H 4450 3844 50 0000 C CNN 171 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 4450 3700 50 0001 C CNN 172 | F 3 "~" H 4450 3700 50 0001 C CNN 173 | 1 4450 3700 174 | 1 0 0 -1 175 | $EndComp 176 | Wire Wire Line 177 | 4000 2850 4750 2850 178 | Wire Wire Line 179 | 4750 2850 5500 2850 180 | Connection ~ 4750 2850 181 | Wire Wire Line 182 | 5500 2850 6250 2850 183 | Connection ~ 5500 2850 184 | Wire Wire Line 185 | 6250 2850 7000 2850 186 | Connection ~ 6250 2850 187 | Wire Wire Line 188 | 3500 3700 3400 3700 189 | Connection ~ 3400 3700 190 | Wire Wire Line 191 | 3400 3700 3400 4200 192 | Wire Wire Line 193 | 4150 3700 4250 3700 194 | Connection ~ 4150 3700 195 | Wire Wire Line 196 | 4150 3700 4150 4200 197 | Wire Wire Line 198 | 4900 3700 5000 3700 199 | Connection ~ 4900 3700 200 | Wire Wire Line 201 | 4900 3700 4900 4200 202 | Wire Wire Line 203 | 5650 3700 5750 3700 204 | Connection ~ 5650 3700 205 | Wire Wire Line 206 | 5650 3700 5650 4200 207 | Wire Wire Line 208 | 6400 3700 6500 3700 209 | Connection ~ 6400 3700 210 | Wire Wire Line 211 | 6400 3700 6400 4200 212 | Wire Wire Line 213 | 4000 3350 4000 3700 214 | Wire Wire Line 215 | 4000 3350 4750 3350 216 | Wire Wire Line 217 | 4750 3350 4750 3700 218 | Wire Wire Line 219 | 4750 3350 5500 3350 220 | Wire Wire Line 221 | 5500 3350 5500 3700 222 | Connection ~ 4750 3350 223 | Wire Wire Line 224 | 5500 3350 6250 3350 225 | Wire Wire Line 226 | 6250 3350 6250 3700 227 | Connection ~ 5500 3350 228 | Wire Wire Line 229 | 6250 3350 7000 3350 230 | Wire Wire Line 231 | 7000 3350 7000 3700 232 | Connection ~ 6250 3350 233 | $Comp 234 | L Switch:SW_SPST SW4 235 | U 1 1 601BC6E8 236 | P 3700 4200 237 | F 0 "SW4" H 3700 4435 50 0000 C CNN 238 | F 1 "SPST" H 3700 4344 50 0000 C CNN 239 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 3700 4200 50 0001 C CNN 240 | F 3 "~" H 3700 4200 50 0001 C CNN 241 | 1 3700 4200 242 | 1 0 0 -1 243 | $EndComp 244 | $Comp 245 | L Switch:SW_SPST SW8 246 | U 1 1 601BC6EE 247 | P 4450 4200 248 | F 0 "SW8" H 4450 4435 50 0000 C CNN 249 | F 1 "SPST" H 4450 4344 50 0000 C CNN 250 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 4450 4200 50 0001 C CNN 251 | F 3 "~" H 4450 4200 50 0001 C CNN 252 | 1 4450 4200 253 | 1 0 0 -1 254 | $EndComp 255 | $Comp 256 | L Switch:SW_SPST SW12 257 | U 1 1 601BC6F4 258 | P 5200 4200 259 | F 0 "SW12" H 5200 4435 50 0000 C CNN 260 | F 1 "SPST" H 5200 4344 50 0000 C CNN 261 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 5200 4200 50 0001 C CNN 262 | F 3 "~" H 5200 4200 50 0001 C CNN 263 | 1 5200 4200 264 | 1 0 0 -1 265 | $EndComp 266 | $Comp 267 | L Switch:SW_SPST SW15 268 | U 1 1 601BC6FA 269 | P 5950 4200 270 | F 0 "SW15" H 5950 4435 50 0000 C CNN 271 | F 1 "SPST" H 5950 4344 50 0000 C CNN 272 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 5950 4200 50 0001 C CNN 273 | F 3 "~" H 5950 4200 50 0001 C CNN 274 | 1 5950 4200 275 | 1 0 0 -1 276 | $EndComp 277 | $Comp 278 | L Switch:SW_SPST SW18 279 | U 1 1 601BC700 280 | P 6700 4200 281 | F 0 "SW18" H 6700 4435 50 0000 C CNN 282 | F 1 "SPST" H 6700 4344 50 0000 C CNN 283 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 6700 4200 50 0001 C CNN 284 | F 3 "~" H 6700 4200 50 0001 C CNN 285 | 1 6700 4200 286 | 1 0 0 -1 287 | $EndComp 288 | $Comp 289 | L Switch:SW_SPST SW5 290 | U 1 1 601C0013 291 | P 3700 4750 292 | F 0 "SW5" H 3700 4985 50 0000 C CNN 293 | F 1 "SPST" H 3700 4894 50 0000 C CNN 294 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 3700 4750 50 0001 C CNN 295 | F 3 "~" H 3700 4750 50 0001 C CNN 296 | 1 3700 4750 297 | 1 0 0 -1 298 | $EndComp 299 | $Comp 300 | L Switch:SW_SPST SW9 301 | U 1 1 601C0019 302 | P 4450 4750 303 | F 0 "SW9" H 4450 4985 50 0000 C CNN 304 | F 1 "SPST" H 4450 4894 50 0000 C CNN 305 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 4450 4750 50 0001 C CNN 306 | F 3 "~" H 4450 4750 50 0001 C CNN 307 | 1 4450 4750 308 | 1 0 0 -1 309 | $EndComp 310 | Wire Wire Line 311 | 3500 4200 3400 4200 312 | Connection ~ 3400 4200 313 | Wire Wire Line 314 | 3400 4200 3400 4750 315 | Wire Wire Line 316 | 3400 4750 3500 4750 317 | Wire Wire Line 318 | 4250 4200 4150 4200 319 | Connection ~ 4150 4200 320 | Wire Wire Line 321 | 4150 4200 4150 4750 322 | Wire Wire Line 323 | 4250 4750 4150 4750 324 | Wire Wire Line 325 | 5000 4200 4900 4200 326 | Wire Wire Line 327 | 5750 4200 5650 4200 328 | Wire Wire Line 329 | 6500 4200 6400 4200 330 | Wire Wire Line 331 | 4000 3850 4000 4200 332 | Wire Wire Line 333 | 4000 4200 3900 4200 334 | Wire Wire Line 335 | 4000 3850 4750 3850 336 | Wire Wire Line 337 | 4750 3850 4750 4200 338 | Wire Wire Line 339 | 4750 4200 4650 4200 340 | Wire Wire Line 341 | 4750 3850 5500 3850 342 | Wire Wire Line 343 | 5500 3850 5500 4200 344 | Wire Wire Line 345 | 5500 4200 5400 4200 346 | Connection ~ 4750 3850 347 | Wire Wire Line 348 | 5500 3850 6250 3850 349 | Wire Wire Line 350 | 6250 3850 6250 4200 351 | Wire Wire Line 352 | 6250 4200 6150 4200 353 | Connection ~ 5500 3850 354 | Wire Wire Line 355 | 6250 3850 7000 3850 356 | Wire Wire Line 357 | 7000 3850 7000 4200 358 | Wire Wire Line 359 | 7000 4200 6900 4200 360 | Connection ~ 6250 3850 361 | Wire Wire Line 362 | 3900 4750 4000 4750 363 | Wire Wire Line 364 | 4000 4750 4000 4400 365 | Wire Wire Line 366 | 4000 4400 4750 4400 367 | Wire Wire Line 368 | 4750 4400 4750 4750 369 | Wire Wire Line 370 | 4750 4750 4650 4750 371 | Text HLabel 7200 2850 2 50 Input ~ 0 372 | R1 373 | Text HLabel 7200 3350 2 50 Input ~ 0 374 | R2 375 | Text HLabel 7200 3850 2 50 Input ~ 0 376 | R3 377 | Text HLabel 7200 4400 2 50 Input ~ 0 378 | R4 379 | Text HLabel 3400 5000 3 50 Input ~ 0 380 | C1 381 | Text HLabel 4150 5000 3 50 Input ~ 0 382 | C2 383 | Text HLabel 4900 5000 3 50 Input ~ 0 384 | C3 385 | Text HLabel 5650 5000 3 50 Input ~ 0 386 | C4 387 | Wire Wire Line 388 | 7000 2850 7200 2850 389 | Connection ~ 7000 2850 390 | Wire Wire Line 391 | 7200 3350 7000 3350 392 | Connection ~ 7000 3350 393 | Wire Wire Line 394 | 7000 3850 7200 3850 395 | Connection ~ 7000 3850 396 | Wire Wire Line 397 | 4750 4400 7000 4400 398 | Connection ~ 4750 4400 399 | Wire Wire Line 400 | 3400 4750 3400 5000 401 | Connection ~ 3400 4750 402 | Wire Wire Line 403 | 4150 4750 4150 5000 404 | Connection ~ 4150 4750 405 | Wire Wire Line 406 | 4900 4200 4900 4750 407 | Connection ~ 4900 4200 408 | Wire Wire Line 409 | 5650 4200 5650 4750 410 | Connection ~ 5650 4200 411 | Wire Wire Line 412 | 6400 4200 6400 4750 413 | Connection ~ 6400 4200 414 | Text HLabel 6400 5000 3 50 Input ~ 0 415 | C5 416 | Text HLabel 5100 4750 2 50 Output Italic 0 417 | SW1 418 | Text HLabel 5850 4750 2 50 Output Italic 0 419 | SW2 420 | Text HLabel 6600 4750 2 50 Output Italic 0 421 | SW3 422 | Wire Wire Line 423 | 4900 4750 5100 4750 424 | Connection ~ 4900 4750 425 | Wire Wire Line 426 | 4900 4750 4900 5000 427 | Wire Wire Line 428 | 5650 4750 5850 4750 429 | Connection ~ 5650 4750 430 | Wire Wire Line 431 | 5650 4750 5650 5000 432 | Wire Wire Line 433 | 6600 4750 6400 4750 434 | Connection ~ 6400 4750 435 | Wire Wire Line 436 | 6400 4750 6400 5000 437 | Text HLabel 7200 4600 2 50 Output Italic 0 438 | SWC 439 | Wire Wire Line 440 | 7000 4400 7000 4600 441 | Wire Wire Line 442 | 7000 4600 7200 4600 443 | Connection ~ 7000 4400 444 | Wire Wire Line 445 | 7000 4400 7200 4400 446 | Text Notes 7450 7500 0 50 ~ 0 447 | Scout keyboard matrix 448 | Text Notes 10600 7650 0 50 ~ 0 449 | A 450 | Text Notes 8150 7650 0 50 ~ 0 451 | 2020/07/16 452 | $EndSCHEMATC 453 | -------------------------------------------------------------------------------- /kicad/scout/keyboard_matrix.sch-bak: -------------------------------------------------------------------------------- 1 | EESchema Schematic File Version 4 2 | EELAYER 30 0 3 | EELAYER END 4 | $Descr A4 11693 8268 5 | encoding utf-8 6 | Sheet 2 2 7 | Title "" 8 | Date "" 9 | Rev "" 10 | Comp "" 11 | Comment1 "" 12 | Comment2 "" 13 | Comment3 "" 14 | Comment4 "" 15 | $EndDescr 16 | $Comp 17 | L Switch:SW_SPST SW2 18 | U 1 1 6017F202 19 | P 3700 3200 20 | F 0 "SW2" H 3700 3435 50 0000 C CNN 21 | F 1 "SPST" H 3700 3344 50 0000 C CNN 22 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 3700 3200 50 0001 C CNN 23 | F 3 "~" H 3700 3200 50 0001 C CNN 24 | 1 3700 3200 25 | 1 0 0 -1 26 | $EndComp 27 | Wire Wire Line 28 | 3900 3200 4000 3200 29 | Wire Wire Line 30 | 4000 3200 4000 2850 31 | Wire Wire Line 32 | 3500 3200 3400 3200 33 | Wire Wire Line 34 | 3400 3200 3400 3700 35 | $Comp 36 | L Switch:SW_SPST SW6 37 | U 1 1 60188B3A 38 | P 4450 3200 39 | F 0 "SW6" H 4450 3435 50 0000 C CNN 40 | F 1 "SPST" H 4450 3344 50 0000 C CNN 41 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 4450 3200 50 0001 C CNN 42 | F 3 "~" H 4450 3200 50 0001 C CNN 43 | 1 4450 3200 44 | 1 0 0 -1 45 | $EndComp 46 | Wire Wire Line 47 | 4650 3200 4750 3200 48 | Wire Wire Line 49 | 4750 3200 4750 2850 50 | Wire Wire Line 51 | 4250 3200 4150 3200 52 | Wire Wire Line 53 | 4150 3200 4150 3700 54 | $Comp 55 | L Switch:SW_SPST SW10 56 | U 1 1 6018A55A 57 | P 5200 3200 58 | F 0 "SW10" H 5200 3435 50 0000 C CNN 59 | F 1 "SPST" H 5200 3344 50 0000 C CNN 60 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 5200 3200 50 0001 C CNN 61 | F 3 "~" H 5200 3200 50 0001 C CNN 62 | 1 5200 3200 63 | 1 0 0 -1 64 | $EndComp 65 | Wire Wire Line 66 | 5400 3200 5500 3200 67 | Wire Wire Line 68 | 5500 3200 5500 2850 69 | Wire Wire Line 70 | 5000 3200 4900 3200 71 | Wire Wire Line 72 | 4900 3200 4900 3700 73 | $Comp 74 | L Switch:SW_SPST SW13 75 | U 1 1 6018A564 76 | P 5950 3200 77 | F 0 "SW13" H 5950 3435 50 0000 C CNN 78 | F 1 "SPST" H 5950 3344 50 0000 C CNN 79 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 5950 3200 50 0001 C CNN 80 | F 3 "~" H 5950 3200 50 0001 C CNN 81 | 1 5950 3200 82 | 1 0 0 -1 83 | $EndComp 84 | Wire Wire Line 85 | 6150 3200 6250 3200 86 | Wire Wire Line 87 | 6250 3200 6250 2850 88 | Wire Wire Line 89 | 5750 3200 5650 3200 90 | Wire Wire Line 91 | 5650 3200 5650 3700 92 | $Comp 93 | L Switch:SW_SPST SW16 94 | U 1 1 6018B40B 95 | P 6700 3200 96 | F 0 "SW16" H 6700 3435 50 0000 C CNN 97 | F 1 "SPST" H 6700 3344 50 0000 C CNN 98 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 6700 3200 50 0001 C CNN 99 | F 3 "~" H 6700 3200 50 0001 C CNN 100 | 1 6700 3200 101 | 1 0 0 -1 102 | $EndComp 103 | Wire Wire Line 104 | 6900 3200 7000 3200 105 | Wire Wire Line 106 | 7000 3200 7000 2850 107 | Wire Wire Line 108 | 6500 3200 6400 3200 109 | Wire Wire Line 110 | 6400 3200 6400 3700 111 | $Comp 112 | L Switch:SW_SPST SW3 113 | U 1 1 6019D891 114 | P 3700 3700 115 | F 0 "SW3" H 3700 3935 50 0000 C CNN 116 | F 1 "SPST" H 3700 3844 50 0000 C CNN 117 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 3700 3700 50 0001 C CNN 118 | F 3 "~" H 3700 3700 50 0001 C CNN 119 | 1 3700 3700 120 | 1 0 0 -1 121 | $EndComp 122 | Wire Wire Line 123 | 3900 3700 4000 3700 124 | Wire Wire Line 125 | 4650 3700 4750 3700 126 | $Comp 127 | L Switch:SW_SPST SW11 128 | U 1 1 6019D8A1 129 | P 5200 3700 130 | F 0 "SW11" H 5200 3935 50 0000 C CNN 131 | F 1 "SPST" H 5200 3844 50 0000 C CNN 132 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 5200 3700 50 0001 C CNN 133 | F 3 "~" H 5200 3700 50 0001 C CNN 134 | 1 5200 3700 135 | 1 0 0 -1 136 | $EndComp 137 | Wire Wire Line 138 | 5400 3700 5500 3700 139 | $Comp 140 | L Switch:SW_SPST SW14 141 | U 1 1 6019D8A9 142 | P 5950 3700 143 | F 0 "SW14" H 5950 3935 50 0000 C CNN 144 | F 1 "SPST" H 5950 3844 50 0000 C CNN 145 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 5950 3700 50 0001 C CNN 146 | F 3 "~" H 5950 3700 50 0001 C CNN 147 | 1 5950 3700 148 | 1 0 0 -1 149 | $EndComp 150 | Wire Wire Line 151 | 6150 3700 6250 3700 152 | $Comp 153 | L Switch:SW_SPST SW17 154 | U 1 1 6019D8B1 155 | P 6700 3700 156 | F 0 "SW17" H 6700 3935 50 0000 C CNN 157 | F 1 "SPST" H 6700 3844 50 0000 C CNN 158 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 6700 3700 50 0001 C CNN 159 | F 3 "~" H 6700 3700 50 0001 C CNN 160 | 1 6700 3700 161 | 1 0 0 -1 162 | $EndComp 163 | Wire Wire Line 164 | 6900 3700 7000 3700 165 | $Comp 166 | L Switch:SW_SPST SW7 167 | U 1 1 6019D899 168 | P 4450 3700 169 | F 0 "SW7" H 4450 3935 50 0000 C CNN 170 | F 1 "SPST" H 4450 3844 50 0000 C CNN 171 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 4450 3700 50 0001 C CNN 172 | F 3 "~" H 4450 3700 50 0001 C CNN 173 | 1 4450 3700 174 | 1 0 0 -1 175 | $EndComp 176 | Wire Wire Line 177 | 4000 2850 4750 2850 178 | Wire Wire Line 179 | 4750 2850 5500 2850 180 | Connection ~ 4750 2850 181 | Wire Wire Line 182 | 5500 2850 6250 2850 183 | Connection ~ 5500 2850 184 | Wire Wire Line 185 | 6250 2850 7000 2850 186 | Connection ~ 6250 2850 187 | Wire Wire Line 188 | 3500 3700 3400 3700 189 | Connection ~ 3400 3700 190 | Wire Wire Line 191 | 3400 3700 3400 4200 192 | Wire Wire Line 193 | 4150 3700 4250 3700 194 | Connection ~ 4150 3700 195 | Wire Wire Line 196 | 4150 3700 4150 4200 197 | Wire Wire Line 198 | 4900 3700 5000 3700 199 | Connection ~ 4900 3700 200 | Wire Wire Line 201 | 4900 3700 4900 4200 202 | Wire Wire Line 203 | 5650 3700 5750 3700 204 | Connection ~ 5650 3700 205 | Wire Wire Line 206 | 5650 3700 5650 4200 207 | Wire Wire Line 208 | 6400 3700 6500 3700 209 | Connection ~ 6400 3700 210 | Wire Wire Line 211 | 6400 3700 6400 4200 212 | Wire Wire Line 213 | 4000 3350 4000 3700 214 | Wire Wire Line 215 | 4000 3350 4750 3350 216 | Wire Wire Line 217 | 4750 3350 4750 3700 218 | Wire Wire Line 219 | 4750 3350 5500 3350 220 | Wire Wire Line 221 | 5500 3350 5500 3700 222 | Connection ~ 4750 3350 223 | Wire Wire Line 224 | 5500 3350 6250 3350 225 | Wire Wire Line 226 | 6250 3350 6250 3700 227 | Connection ~ 5500 3350 228 | Wire Wire Line 229 | 6250 3350 7000 3350 230 | Wire Wire Line 231 | 7000 3350 7000 3700 232 | Connection ~ 6250 3350 233 | $Comp 234 | L Switch:SW_SPST SW4 235 | U 1 1 601BC6E8 236 | P 3700 4200 237 | F 0 "SW4" H 3700 4435 50 0000 C CNN 238 | F 1 "SPST" H 3700 4344 50 0000 C CNN 239 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 3700 4200 50 0001 C CNN 240 | F 3 "~" H 3700 4200 50 0001 C CNN 241 | 1 3700 4200 242 | 1 0 0 -1 243 | $EndComp 244 | $Comp 245 | L Switch:SW_SPST SW8 246 | U 1 1 601BC6EE 247 | P 4450 4200 248 | F 0 "SW8" H 4450 4435 50 0000 C CNN 249 | F 1 "SPST" H 4450 4344 50 0000 C CNN 250 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 4450 4200 50 0001 C CNN 251 | F 3 "~" H 4450 4200 50 0001 C CNN 252 | 1 4450 4200 253 | 1 0 0 -1 254 | $EndComp 255 | $Comp 256 | L Switch:SW_SPST SW12 257 | U 1 1 601BC6F4 258 | P 5200 4200 259 | F 0 "SW12" H 5200 4435 50 0000 C CNN 260 | F 1 "SPST" H 5200 4344 50 0000 C CNN 261 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 5200 4200 50 0001 C CNN 262 | F 3 "~" H 5200 4200 50 0001 C CNN 263 | 1 5200 4200 264 | 1 0 0 -1 265 | $EndComp 266 | $Comp 267 | L Switch:SW_SPST SW15 268 | U 1 1 601BC6FA 269 | P 5950 4200 270 | F 0 "SW15" H 5950 4435 50 0000 C CNN 271 | F 1 "SPST" H 5950 4344 50 0000 C CNN 272 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 5950 4200 50 0001 C CNN 273 | F 3 "~" H 5950 4200 50 0001 C CNN 274 | 1 5950 4200 275 | 1 0 0 -1 276 | $EndComp 277 | $Comp 278 | L Switch:SW_SPST SW18 279 | U 1 1 601BC700 280 | P 6700 4200 281 | F 0 "SW18" H 6700 4435 50 0000 C CNN 282 | F 1 "SPST" H 6700 4344 50 0000 C CNN 283 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 6700 4200 50 0001 C CNN 284 | F 3 "~" H 6700 4200 50 0001 C CNN 285 | 1 6700 4200 286 | 1 0 0 -1 287 | $EndComp 288 | $Comp 289 | L Switch:SW_SPST SW5 290 | U 1 1 601C0013 291 | P 3700 4750 292 | F 0 "SW5" H 3700 4985 50 0000 C CNN 293 | F 1 "SPST" H 3700 4894 50 0000 C CNN 294 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 3700 4750 50 0001 C CNN 295 | F 3 "~" H 3700 4750 50 0001 C CNN 296 | 1 3700 4750 297 | 1 0 0 -1 298 | $EndComp 299 | $Comp 300 | L Switch:SW_SPST SW9 301 | U 1 1 601C0019 302 | P 4450 4750 303 | F 0 "SW9" H 4450 4985 50 0000 C CNN 304 | F 1 "SPST" H 4450 4894 50 0000 C CNN 305 | F 2 "Button_Switch_THT:SW_PUSH_6mm" H 4450 4750 50 0001 C CNN 306 | F 3 "~" H 4450 4750 50 0001 C CNN 307 | 1 4450 4750 308 | 1 0 0 -1 309 | $EndComp 310 | Wire Wire Line 311 | 3500 4200 3400 4200 312 | Connection ~ 3400 4200 313 | Wire Wire Line 314 | 3400 4200 3400 4750 315 | Wire Wire Line 316 | 3400 4750 3500 4750 317 | Wire Wire Line 318 | 4250 4200 4150 4200 319 | Connection ~ 4150 4200 320 | Wire Wire Line 321 | 4150 4200 4150 4750 322 | Wire Wire Line 323 | 4250 4750 4150 4750 324 | Wire Wire Line 325 | 5000 4200 4900 4200 326 | Wire Wire Line 327 | 5750 4200 5650 4200 328 | Wire Wire Line 329 | 6500 4200 6400 4200 330 | Wire Wire Line 331 | 4000 3850 4000 4200 332 | Wire Wire Line 333 | 4000 4200 3900 4200 334 | Wire Wire Line 335 | 4000 3850 4750 3850 336 | Wire Wire Line 337 | 4750 3850 4750 4200 338 | Wire Wire Line 339 | 4750 4200 4650 4200 340 | Wire Wire Line 341 | 4750 3850 5500 3850 342 | Wire Wire Line 343 | 5500 3850 5500 4200 344 | Wire Wire Line 345 | 5500 4200 5400 4200 346 | Connection ~ 4750 3850 347 | Wire Wire Line 348 | 5500 3850 6250 3850 349 | Wire Wire Line 350 | 6250 3850 6250 4200 351 | Wire Wire Line 352 | 6250 4200 6150 4200 353 | Connection ~ 5500 3850 354 | Wire Wire Line 355 | 6250 3850 7000 3850 356 | Wire Wire Line 357 | 7000 3850 7000 4200 358 | Wire Wire Line 359 | 7000 4200 6900 4200 360 | Connection ~ 6250 3850 361 | Wire Wire Line 362 | 3900 4750 4000 4750 363 | Wire Wire Line 364 | 4000 4750 4000 4400 365 | Wire Wire Line 366 | 4000 4400 4750 4400 367 | Wire Wire Line 368 | 4750 4400 4750 4750 369 | Wire Wire Line 370 | 4750 4750 4650 4750 371 | Text HLabel 7200 2850 2 50 Input ~ 0 372 | R1 373 | Text HLabel 7200 3350 2 50 Input ~ 0 374 | R2 375 | Text HLabel 7200 3850 2 50 Input ~ 0 376 | R3 377 | Text HLabel 7200 4400 2 50 Input ~ 0 378 | R4 379 | Text HLabel 3400 5000 3 50 Input ~ 0 380 | C1 381 | Text HLabel 4150 5000 3 50 Input ~ 0 382 | C2 383 | Text HLabel 4900 5000 3 50 Input ~ 0 384 | C3 385 | Text HLabel 5650 5000 3 50 Input ~ 0 386 | C4 387 | Wire Wire Line 388 | 7000 2850 7200 2850 389 | Connection ~ 7000 2850 390 | Wire Wire Line 391 | 7200 3350 7000 3350 392 | Connection ~ 7000 3350 393 | Wire Wire Line 394 | 7000 3850 7200 3850 395 | Connection ~ 7000 3850 396 | Wire Wire Line 397 | 4750 4400 7000 4400 398 | Connection ~ 4750 4400 399 | Wire Wire Line 400 | 3400 4750 3400 5000 401 | Connection ~ 3400 4750 402 | Wire Wire Line 403 | 4150 4750 4150 5000 404 | Connection ~ 4150 4750 405 | Wire Wire Line 406 | 4900 4200 4900 4750 407 | Connection ~ 4900 4200 408 | Wire Wire Line 409 | 5650 4200 5650 4750 410 | Connection ~ 5650 4200 411 | Wire Wire Line 412 | 6400 4200 6400 4750 413 | Connection ~ 6400 4200 414 | Text HLabel 6400 5000 3 50 Input ~ 0 415 | C5 416 | Text HLabel 5100 4750 2 50 Output Italic 0 417 | SW1 418 | Text HLabel 5850 4750 2 50 Output Italic 0 419 | SW2 420 | Text HLabel 6600 4750 2 50 Output Italic 0 421 | SW3 422 | Wire Wire Line 423 | 4900 4750 5100 4750 424 | Connection ~ 4900 4750 425 | Wire Wire Line 426 | 4900 4750 4900 5000 427 | Wire Wire Line 428 | 5650 4750 5850 4750 429 | Connection ~ 5650 4750 430 | Wire Wire Line 431 | 5650 4750 5650 5000 432 | Wire Wire Line 433 | 6600 4750 6400 4750 434 | Connection ~ 6400 4750 435 | Wire Wire Line 436 | 6400 4750 6400 5000 437 | Text HLabel 7200 4600 2 50 Output Italic 0 438 | SWC 439 | Wire Wire Line 440 | 7000 4400 7000 4600 441 | Wire Wire Line 442 | 7000 4600 7200 4600 443 | Connection ~ 7000 4400 444 | Wire Wire Line 445 | 7000 4400 7200 4400 446 | Text Notes 7450 7500 0 50 ~ 0 447 | Scout keyboard matrix 448 | Text Notes 10600 7650 0 50 ~ 0 449 | A 450 | Text Notes 8150 7650 0 50 ~ 0 451 | 2020/07/16 452 | $EndSCHEMATC 453 | -------------------------------------------------------------------------------- /kicad/scout/scout.pretty/branding.kicad_mod: -------------------------------------------------------------------------------- 1 | (module branding (layer F.Cu) (tedit 0) 2 | (fp_text reference Ref** (at 0 0) (layer F.SilkS) hide 3 | (effects (font (size 1.27 1.27) (thickness 0.15))) 4 | ) 5 | (fp_text value Val** (at 0 0) (layer F.SilkS) hide 6 | (effects (font (size 1.27 1.27) (thickness 0.15))) 7 | ) 8 | (fp_poly (pts (xy -4.493753 -0.882712) (xy -4.333462 -0.859195) (xy -4.198267 -0.812323) (xy -4.081757 -0.739832) 9 | (xy -3.977523 -0.639457) (xy -3.972013 -0.633076) (xy -3.898628 -0.530196) (xy -3.846589 -0.414343) 10 | (xy -3.813097 -0.276815) (xy -3.795352 -0.108911) (xy -3.793814 -0.079228) (xy -3.795282 0.145306) 11 | (xy -3.822539 0.337793) (xy -3.8767 0.500582) (xy -3.958876 0.636025) (xy -4.070182 0.74647) 12 | (xy -4.211729 0.834267) (xy -4.230793 0.843389) (xy -4.288138 0.86786) (xy -4.342704 0.884332) 13 | (xy -4.405733 0.894637) (xy -4.488469 0.900605) (xy -4.602155 0.904066) (xy -4.60375 0.9041) 14 | (xy -4.759966 0.903756) (xy -4.875984 0.895217) (xy -4.946945 0.880515) (xy -5.112957 0.806277) 15 | (xy -5.251966 0.701212) (xy -5.360928 0.568099) (xy -5.423263 0.446179) (xy -5.442079 0.39448) 16 | (xy -5.455191 0.343201) (xy -5.463594 0.283186) (xy -5.468281 0.205281) (xy -5.470245 0.100329) 17 | (xy -5.470532 0.010583) (xy -5.470219 -0.048559) (xy -4.970261 -0.048559) (xy -4.967822 0.125485) 18 | (xy -4.940987 0.268457) (xy -4.890258 0.379001) (xy -4.816136 0.455758) (xy -4.775279 0.478916) 19 | (xy -4.695414 0.498618) (xy -4.600274 0.499146) (xy -4.509752 0.481807) (xy -4.457059 0.457996) 20 | (xy -4.413975 0.417411) (xy -4.369671 0.357339) (xy -4.355589 0.333065) (xy -4.333807 0.286363) 21 | (xy -4.319744 0.237575) (xy -4.311785 0.175827) (xy -4.308315 0.090247) (xy -4.307692 0.010583) 22 | (xy -4.308857 -0.09962) (xy -4.313641 -0.178179) (xy -4.323512 -0.23573) (xy -4.339943 -0.282907) 23 | (xy -4.351591 -0.306917) (xy -4.419941 -0.399121) (xy -4.506591 -0.459021) (xy -4.603542 -0.486614) 24 | (xy -4.702796 -0.481898) (xy -4.796353 -0.444871) (xy -4.876214 -0.375529) (xy -4.920006 -0.307106) 25 | (xy -4.949901 -0.214904) (xy -4.967717 -0.08727) (xy -4.970261 -0.048559) (xy -5.470219 -0.048559) 26 | (xy -5.469855 -0.11721) (xy -5.467147 -0.211894) (xy -5.461396 -0.28268) (xy -5.451585 -0.338782) 27 | (xy -5.436702 -0.389411) (xy -5.422295 -0.427602) (xy -5.341582 -0.57544) (xy -5.229273 -0.701217) 28 | (xy -5.092716 -0.797169) (xy -5.05461 -0.816062) (xy -4.987491 -0.844264) (xy -4.925537 -0.863003) 29 | (xy -4.855849 -0.874693) (xy -4.765523 -0.88175) (xy -4.685551 -0.885139) (xy -4.493753 -0.882712)) (layer F.SilkS) (width 0.01)) 30 | (fp_poly (pts (xy -3.002982 -0.884152) (xy -2.848773 -0.866365) (xy -2.709154 -0.834524) (xy -2.682875 -0.826067) 31 | (xy -2.612824 -0.800233) (xy -2.561876 -0.77786) (xy -2.540172 -0.763447) (xy -2.54 -0.762672) 32 | (xy -2.54745 -0.737111) (xy -2.567009 -0.683856) (xy -2.594493 -0.614288) (xy -2.595346 -0.612191) 33 | (xy -2.626361 -0.535595) (xy -2.653174 -0.468652) (xy -2.66907 -0.428191) (xy -2.683048 -0.398648) 34 | (xy -2.702619 -0.390988) (xy -2.741442 -0.403238) (xy -2.767183 -0.41402) (xy -2.886641 -0.456261) 35 | (xy -3.001555 -0.481457) (xy -3.104808 -0.48951) (xy -3.189282 -0.480317) (xy -3.247862 -0.453777) 36 | (xy -3.27094 -0.421158) (xy -3.274229 -0.387084) (xy -3.258452 -0.353725) (xy -3.219107 -0.317369) 37 | (xy -3.15169 -0.274307) (xy -3.0517 -0.220829) (xy -2.990977 -0.19045) (xy -2.840434 -0.109707) 38 | (xy -2.726718 -0.032796) (xy -2.645129 0.04467) (xy -2.590966 0.127079) (xy -2.561448 0.210492) 39 | (xy -2.542909 0.367991) (xy -2.563769 0.51325) (xy -2.621932 0.642329) (xy -2.715306 0.751284) 40 | (xy -2.841795 0.836172) (xy -2.909476 0.865663) (xy -3.022689 0.89458) (xy -3.161964 0.90991) 41 | (xy -3.313294 0.911725) (xy -3.462671 0.9001) (xy -3.596089 0.875109) (xy -3.640666 0.861792) 42 | (xy -3.77825 0.814916) (xy -3.784282 0.597958) (xy -3.785075 0.505966) (xy -3.782277 0.433968) 43 | (xy -3.776402 0.390285) (xy -3.770927 0.381) (xy -3.742807 0.388015) (xy -3.686784 0.406502) 44 | (xy -3.614423 0.432621) (xy -3.606605 0.435553) (xy -3.498671 0.46865) (xy -3.380636 0.492711) 45 | (xy -3.266179 0.50592) (xy -3.168979 0.506459) (xy -3.123679 0.499708) (xy -3.072402 0.470311) 46 | (xy -3.043922 0.433418) (xy -3.034398 0.391879) (xy -3.04848 0.352523) (xy -3.090162 0.311601) 47 | (xy -3.163438 0.265361) (xy -3.272303 0.210051) (xy -3.291416 0.200991) (xy -3.446602 0.121864) 48 | (xy -3.56494 0.046032) (xy -3.651071 -0.03161) (xy -3.709641 -0.116163) (xy -3.745291 -0.212732) 49 | (xy -3.761785 -0.315968) (xy -3.756827 -0.467821) (xy -3.714449 -0.601131) (xy -3.636527 -0.712986) 50 | (xy -3.524937 -0.800473) (xy -3.418416 -0.848995) (xy -3.301276 -0.875887) (xy -3.158307 -0.887466) 51 | (xy -3.002982 -0.884152)) (layer F.SilkS) (width 0.01)) 52 | (fp_poly (pts (xy 1.938669 -0.876757) (xy 2.033699 -0.872753) (xy 2.103242 -0.865182) (xy 2.155702 -0.853208) 53 | (xy 2.19075 -0.840012) (xy 2.339941 -0.756508) (xy 2.457825 -0.650901) (xy 2.546787 -0.51965) 54 | (xy 2.609214 -0.359216) (xy 2.647492 -0.166057) (xy 2.648081 -0.161412) (xy 2.658691 0.039005) 55 | (xy 2.64087 0.229849) (xy 2.596652 0.405756) (xy 2.528076 0.561361) (xy 2.437178 0.691296) 56 | (xy 2.325994 0.790198) (xy 2.275417 0.820324) (xy 2.162746 0.863157) (xy 2.022721 0.892975) 57 | (xy 1.868527 0.908952) (xy 1.713349 0.910264) (xy 1.570372 0.896088) (xy 1.467153 0.870855) 58 | (xy 1.308365 0.798237) (xy 1.18045 0.699912) (xy 1.0823 0.574182) (xy 1.012805 0.419349) 59 | (xy 0.970857 0.233714) (xy 0.957552 0.090043) (xy 0.957251 0.010051) (xy 1.471584 0.010051) 60 | (xy 1.478656 0.160573) (xy 1.500672 0.276549) (xy 1.540037 0.363868) (xy 1.599153 0.428417) 61 | (xy 1.657367 0.465158) (xy 1.760102 0.497753) (xy 1.866298 0.498013) (xy 1.961907 0.466553) 62 | (xy 1.986793 0.450753) (xy 2.045384 0.396267) (xy 2.086365 0.327502) (xy 2.112061 0.237169) 63 | (xy 2.124798 0.11798) (xy 2.12725 0.010583) (xy 2.125795 -0.101611) (xy 2.120491 -0.182108) 64 | (xy 2.109926 -0.241477) (xy 2.092691 -0.290284) (xy 2.084917 -0.306638) (xy 2.017988 -0.399796) 65 | (xy 1.932544 -0.459901) (xy 1.836535 -0.48694) (xy 1.737909 -0.480902) (xy 1.644615 -0.441775) 66 | (xy 1.564603 -0.369549) (xy 1.524798 -0.307449) (xy 1.499331 -0.25232) (xy 1.48342 -0.199867) 67 | (xy 1.47495 -0.137473) (xy 1.471805 -0.052521) (xy 1.471584 0.010051) (xy 0.957251 0.010051) 68 | (xy 0.956823 -0.10348) (xy 0.976326 -0.268202) (xy 1.017679 -0.413343) (xy 1.06355 -0.514038) 69 | (xy 1.147047 -0.640424) (xy 1.252089 -0.739319) (xy 1.388341 -0.819717) (xy 1.396034 -0.82336) 70 | (xy 1.446152 -0.845488) (xy 1.49203 -0.860736) (xy 1.543156 -0.870358) (xy 1.609021 -0.875609) 71 | (xy 1.699115 -0.877743) (xy 1.80975 -0.878033) (xy 1.938669 -0.876757)) (layer F.SilkS) (width 0.01)) 72 | (fp_poly (pts (xy -1.984887 -0.520122) (xy -1.979083 -0.17241) (xy -1.511423 -0.85725) (xy -1.242545 -0.863175) 73 | (xy -1.141465 -0.864553) (xy -1.057732 -0.864079) (xy -0.999292 -0.861918) (xy -0.97409 -0.858233) 74 | (xy -0.973666 -0.857596) (xy -0.985277 -0.837647) (xy -1.017771 -0.788256) (xy -1.067644 -0.714581) 75 | (xy -1.131391 -0.62178) (xy -1.205507 -0.515013) (xy -1.23825 -0.468154) (xy -1.315675 -0.356885) 76 | (xy -1.38416 -0.257175) (xy -1.44019 -0.174248) (xy -1.480255 -0.113323) (xy -1.50084 -0.079622) 77 | (xy -1.502833 -0.074896) (xy -1.493046 -0.054372) (xy -1.465865 -0.002842) (xy -1.424565 0.073757) 78 | (xy -1.372417 0.169486) (xy -1.312693 0.278406) (xy -1.248668 0.394577) (xy -1.183613 0.51206) 79 | (xy -1.120801 0.624918) (xy -1.063504 0.72721) (xy -1.014996 0.812997) (xy -0.980428 0.873125) 80 | (xy -0.996763 0.878923) (xy -1.047998 0.883721) (xy -1.126702 0.887095) (xy -1.225446 0.888621) 81 | (xy -1.252876 0.888664) (xy -1.534583 0.888328) (xy -1.866869 0.237214) (xy -1.989399 0.306916) 82 | (xy -1.989533 0.597958) (xy -1.989666 0.889) (xy -2.4765 0.889) (xy -2.4765 -0.867834) 83 | (xy -1.99069 -0.867834) (xy -1.984887 -0.520122)) (layer F.SilkS) (width 0.01)) 84 | (fp_poly (pts (xy -0.402166 0.889) (xy -0.910166 0.889) (xy -0.910166 -0.867834) (xy -0.402166 -0.867834) 85 | (xy -0.402166 0.889)) (layer F.SilkS) (width 0.01)) 86 | (fp_poly (pts (xy 0.994834 -0.465667) (xy 0.5715 -0.465667) (xy 0.5715 0.889) (xy 0.084667 0.889) 87 | (xy 0.084667 -0.465667) (xy -0.338666 -0.465667) (xy -0.338666 -0.867834) (xy 0.994834 -0.867834) 88 | (xy 0.994834 -0.465667)) (layer F.SilkS) (width 0.01)) 89 | (fp_poly (pts (xy 3.585352 -0.396875) (xy 3.655946 -0.260603) (xy 3.723479 -0.130716) (xy 3.784447 -0.013917) 90 | (xy 3.835347 0.083094) (xy 3.872678 0.153616) (xy 3.888224 0.182474) (xy 3.947584 0.290866) 91 | (xy 3.932992 -0.867834) (xy 4.3815 -0.867834) (xy 4.3815 0.889) (xy 4.058709 0.888574) 92 | (xy 3.735917 0.888149) (xy 3.439584 0.307793) (xy 3.14325 -0.272563) (xy 3.137624 0.308218) 93 | (xy 3.131997 0.889) (xy 2.709334 0.889) (xy 2.709334 -0.306917) (xy 3.1115 -0.306917) 94 | (xy 3.122084 -0.296334) (xy 3.132667 -0.306917) (xy 3.122084 -0.3175) (xy 3.1115 -0.306917) 95 | (xy 2.709334 -0.306917) (xy 2.709334 -0.867834) (xy 3.341841 -0.867834) (xy 3.585352 -0.396875)) (layer F.SilkS) (width 0.01)) 96 | (fp_poly (pts (xy 5.482167 -0.465667) (xy 4.931834 -0.465667) (xy 4.931834 -0.211667) (xy 5.462589 -0.211667) 97 | (xy 5.456503 -0.015875) (xy 5.450417 0.179916) (xy 5.191125 0.185859) (xy 4.931834 0.191802) 98 | (xy 4.931834 0.486833) (xy 5.482167 0.486833) (xy 5.482167 0.889) (xy 4.445 0.889) 99 | (xy 4.445 -0.867834) (xy 5.482167 -0.867834) (xy 5.482167 -0.465667)) (layer F.SilkS) (width 0.01)) 100 | ) 101 | -------------------------------------------------------------------------------- /kicad/scout/scout.pro: -------------------------------------------------------------------------------- 1 | update=Monday, April 26, 2021 at 05:46:38 PM 2 | version=1 3 | last_client=kicad 4 | [general] 5 | version=1 6 | RootSch= 7 | BoardNm= 8 | [cvpcb] 9 | version=1 10 | NetIExt=net 11 | [eeschema] 12 | version=1 13 | LibDir= 14 | [eeschema/libraries] 15 | [pcbnew] 16 | version=1 17 | PageLayoutDescrFile= 18 | LastNetListRead= 19 | CopperLayerCount=2 20 | BoardThickness=1.6 21 | AllowMicroVias=0 22 | AllowBlindVias=0 23 | RequireCourtyardDefinitions=0 24 | ProhibitOverlappingCourtyards=1 25 | MinTrackWidth=0.2 26 | MinViaDiameter=0.4 27 | MinViaDrill=0.3 28 | MinMicroViaDiameter=0.2 29 | MinMicroViaDrill=0.09999999999999999 30 | MinHoleToHole=0.25 31 | TrackWidth1=0.25 32 | TrackWidth2=0.5 33 | ViaDiameter1=0.8 34 | ViaDrill1=0.4 35 | dPairWidth1=0.2 36 | dPairGap1=0.25 37 | dPairViaGap1=0.25 38 | SilkLineWidth=0.12 39 | SilkTextSizeV=1 40 | SilkTextSizeH=1 41 | SilkTextSizeThickness=0.15 42 | SilkTextItalic=0 43 | SilkTextUpright=1 44 | CopperLineWidth=0.2 45 | CopperTextSizeV=1.5 46 | CopperTextSizeH=1.5 47 | CopperTextThickness=0.3 48 | CopperTextItalic=0 49 | CopperTextUpright=1 50 | EdgeCutLineWidth=0.05 51 | CourtyardLineWidth=0.05 52 | OthersLineWidth=0.15 53 | OthersTextSizeV=1 54 | OthersTextSizeH=1 55 | OthersTextSizeThickness=0.15 56 | OthersTextItalic=0 57 | OthersTextUpright=1 58 | SolderMaskClearance=0.05 59 | SolderMaskMinWidth=0 60 | SolderPasteClearance=0 61 | SolderPasteRatio=-0 62 | [pcbnew/Layer.F.Cu] 63 | Name=F.Cu 64 | Type=0 65 | Enabled=1 66 | [pcbnew/Layer.In1.Cu] 67 | Name=In1.Cu 68 | Type=0 69 | Enabled=0 70 | [pcbnew/Layer.In2.Cu] 71 | Name=In2.Cu 72 | Type=0 73 | Enabled=0 74 | [pcbnew/Layer.In3.Cu] 75 | Name=In3.Cu 76 | Type=0 77 | Enabled=0 78 | [pcbnew/Layer.In4.Cu] 79 | Name=In4.Cu 80 | Type=0 81 | Enabled=0 82 | [pcbnew/Layer.In5.Cu] 83 | Name=In5.Cu 84 | Type=0 85 | Enabled=0 86 | [pcbnew/Layer.In6.Cu] 87 | Name=In6.Cu 88 | Type=0 89 | Enabled=0 90 | [pcbnew/Layer.In7.Cu] 91 | Name=In7.Cu 92 | Type=0 93 | Enabled=0 94 | [pcbnew/Layer.In8.Cu] 95 | Name=In8.Cu 96 | Type=0 97 | Enabled=0 98 | [pcbnew/Layer.In9.Cu] 99 | Name=In9.Cu 100 | Type=0 101 | Enabled=0 102 | [pcbnew/Layer.In10.Cu] 103 | Name=In10.Cu 104 | Type=0 105 | Enabled=0 106 | [pcbnew/Layer.In11.Cu] 107 | Name=In11.Cu 108 | Type=0 109 | Enabled=0 110 | [pcbnew/Layer.In12.Cu] 111 | Name=In12.Cu 112 | Type=0 113 | Enabled=0 114 | [pcbnew/Layer.In13.Cu] 115 | Name=In13.Cu 116 | Type=0 117 | Enabled=0 118 | [pcbnew/Layer.In14.Cu] 119 | Name=In14.Cu 120 | Type=0 121 | Enabled=0 122 | [pcbnew/Layer.In15.Cu] 123 | Name=In15.Cu 124 | Type=0 125 | Enabled=0 126 | [pcbnew/Layer.In16.Cu] 127 | Name=In16.Cu 128 | Type=0 129 | Enabled=0 130 | [pcbnew/Layer.In17.Cu] 131 | Name=In17.Cu 132 | Type=0 133 | Enabled=0 134 | [pcbnew/Layer.In18.Cu] 135 | Name=In18.Cu 136 | Type=0 137 | Enabled=0 138 | [pcbnew/Layer.In19.Cu] 139 | Name=In19.Cu 140 | Type=0 141 | Enabled=0 142 | [pcbnew/Layer.In20.Cu] 143 | Name=In20.Cu 144 | Type=0 145 | Enabled=0 146 | [pcbnew/Layer.In21.Cu] 147 | Name=In21.Cu 148 | Type=0 149 | Enabled=0 150 | [pcbnew/Layer.In22.Cu] 151 | Name=In22.Cu 152 | Type=0 153 | Enabled=0 154 | [pcbnew/Layer.In23.Cu] 155 | Name=In23.Cu 156 | Type=0 157 | Enabled=0 158 | [pcbnew/Layer.In24.Cu] 159 | Name=In24.Cu 160 | Type=0 161 | Enabled=0 162 | [pcbnew/Layer.In25.Cu] 163 | Name=In25.Cu 164 | Type=0 165 | Enabled=0 166 | [pcbnew/Layer.In26.Cu] 167 | Name=In26.Cu 168 | Type=0 169 | Enabled=0 170 | [pcbnew/Layer.In27.Cu] 171 | Name=In27.Cu 172 | Type=0 173 | Enabled=0 174 | [pcbnew/Layer.In28.Cu] 175 | Name=In28.Cu 176 | Type=0 177 | Enabled=0 178 | [pcbnew/Layer.In29.Cu] 179 | Name=In29.Cu 180 | Type=0 181 | Enabled=0 182 | [pcbnew/Layer.In30.Cu] 183 | Name=In30.Cu 184 | Type=0 185 | Enabled=0 186 | [pcbnew/Layer.B.Cu] 187 | Name=B.Cu 188 | Type=0 189 | Enabled=1 190 | [pcbnew/Layer.B.Adhes] 191 | Enabled=1 192 | [pcbnew/Layer.F.Adhes] 193 | Enabled=1 194 | [pcbnew/Layer.B.Paste] 195 | Enabled=1 196 | [pcbnew/Layer.F.Paste] 197 | Enabled=1 198 | [pcbnew/Layer.B.SilkS] 199 | Enabled=1 200 | [pcbnew/Layer.F.SilkS] 201 | Enabled=1 202 | [pcbnew/Layer.B.Mask] 203 | Enabled=1 204 | [pcbnew/Layer.F.Mask] 205 | Enabled=1 206 | [pcbnew/Layer.Dwgs.User] 207 | Enabled=1 208 | [pcbnew/Layer.Cmts.User] 209 | Enabled=1 210 | [pcbnew/Layer.Eco1.User] 211 | Enabled=1 212 | [pcbnew/Layer.Eco2.User] 213 | Enabled=1 214 | [pcbnew/Layer.Edge.Cuts] 215 | Enabled=1 216 | [pcbnew/Layer.Margin] 217 | Enabled=1 218 | [pcbnew/Layer.B.CrtYd] 219 | Enabled=1 220 | [pcbnew/Layer.F.CrtYd] 221 | Enabled=1 222 | [pcbnew/Layer.B.Fab] 223 | Enabled=1 224 | [pcbnew/Layer.F.Fab] 225 | Enabled=1 226 | [pcbnew/Layer.Rescue] 227 | Enabled=0 228 | [pcbnew/Netclasses] 229 | [pcbnew/Netclasses/Default] 230 | Name=Default 231 | Clearance=0.2 232 | TrackWidth=0.25 233 | ViaDiameter=0.8 234 | ViaDrill=0.4 235 | uViaDiameter=0.3 236 | uViaDrill=0.1 237 | dPairWidth=0.2 238 | dPairGap=0.25 239 | dPairViaGap=0.25 240 | -------------------------------------------------------------------------------- /make_stls.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | { 4 | 5 | # Exit on error 6 | set -o errexit 7 | set -o errtrace 8 | 9 | # Constants 10 | openscad="/Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD" 11 | timestamp=$(git log -n1 --date=unix --format="%ad" openscad) 12 | commit_hash=$(git log -n1 --format="%h" openscad) 13 | 14 | # Flags 15 | bonk= 16 | # prefix="oskitone-apc" 17 | prefix="scout" 18 | dir="local/3d-models/$prefix-$timestamp-$commit_hash" 19 | query= 20 | 21 | # Internal variables 22 | _found_matches= 23 | 24 | function help() { 25 | echo "\ 26 | Renders APC STL models. 27 | 28 | Usage: 29 | ./make_stls.sh [-hectb] [-p PREFIX] [-d DIRECTORY] [-q COMMA,SEPARATED,QUERY] 30 | 31 | Usage: 32 | ./make_stls.sh Export all STLs 33 | ./make_stls.sh -h Show this message and quit 34 | ./make_stls.sh -e Echo out output directory and quit 35 | ./make_stls.sh -c Echo out commit hash and quit 36 | ./make_stls.sh -t Echo out timestamp and quit 37 | ./make_stls.sh -b Bonk and open folder when done 38 | ./make_stls.sh -p Set filename prefix 39 | Default is 'oskitone-apc' 40 | ./make_stls.sh -d Set output directory 41 | Default is local/3d-models/... 42 | ./make_stls.sh -q Export only STLs whose filename stubs match 43 | comma-separated query 44 | 45 | Examples: 46 | ./make_stls.sh -p test -q switch Exports test-...-switch_clutch.stl 47 | ./make_stls.sh -p wheels,enc Exports oskitone-apc-...-wheels.stl, 48 | oskitone-apc-...-enclosure_bottom.stl, 49 | and oskitone-apc-...-enclosure_top.stl 50 | " 51 | } 52 | 53 | function export_stl() { 54 | stub="$1" 55 | override="$2" 56 | show_dfm="$3" 57 | flip_vertically="$4" 58 | 59 | function _run() { 60 | ascii_filename="$dir/$prefix-$timestamp-$commit_hash-$stub-ascii.stl" 61 | filename="$dir/$prefix-$timestamp-$commit_hash-$stub.stl" 62 | 63 | echo "Exporting $filename..." 64 | 65 | $openscad "openscad/scout.scad" \ 66 | --quiet \ 67 | -o "$ascii_filename" \ 68 | --export-format "asciistl" \ 69 | -D 'SHOW_ENCLOSURE_BOTTOM=false '\ 70 | -D 'SHOW_BATTERY_HOLDER=false '\ 71 | -D 'SHOW_PCB=false '\ 72 | -D 'SHOW_KEYS_MOUNT_RAIL=false '\ 73 | -D 'SHOW_KEYS=false '\ 74 | -D 'SHOW_SWITCH_CLUTCH=false '\ 75 | -D 'SHOW_ENCLOSURE_TOP=false '\ 76 | -D 'SHOW_ACCOUTREMENTS=false '\ 77 | -D 'SHOW_KNOB=false '\ 78 | -D "SHOW_DFM=$show_dfm "\ 79 | -D 'SHOW_CLEARANCES=false' \ 80 | -D "FLIP_VERTICALLY=$flip_vertically" \ 81 | -D "$override=true" \ 82 | 83 | echo "Compressing $filename..." 84 | admesh "$ascii_filename" \ 85 | --no-check \ 86 | --write-binary-stl="$filename" \ 87 | > /dev/null 88 | 89 | rm "$ascii_filename" 90 | } 91 | 92 | if [[ -z "$query" ]]; then 93 | _run 94 | else 95 | for query_iterm in "${query[@]}"; do 96 | if [[ "$stub" == *"$query_iterm"* ]]; then 97 | _found_matches=true 98 | _run 99 | fi 100 | done 101 | fi 102 | } 103 | 104 | function create_zip() { 105 | if [[ -z "$query" ]]; then 106 | echo 107 | echo "Creating zip" 108 | pushd $dir 109 | zip "$prefix-$timestamp-$commit_hash-ALL.zip" *.stl 110 | popd > /dev/null 111 | fi 112 | } 113 | 114 | function run() { 115 | mkdir -pv $dir 116 | 117 | function finish() { 118 | # Kill descendent processes 119 | pkill -P "$$" 120 | } 121 | trap finish EXIT 122 | 123 | start=`date +%s` 124 | 125 | # The "& \" at the end runs everything in parallel! 126 | export_stl 'enclosure_bottom' 'SHOW_ENCLOSURE_BOTTOM' 'true' 'false' & \ 127 | export_stl 'battery_holder' 'SHOW_BATTERY_HOLDER' 'true' 'false' & \ 128 | export_stl 'keys_mount_rail' 'SHOW_KEYS_MOUNT_RAIL' 'true' 'false' & \ 129 | export_stl 'keys' 'SHOW_KEYS' 'true' 'false' & \ 130 | export_stl 'switch_clutch' 'SHOW_SWITCH_CLUTCH' 'true' 'false' & \ 131 | export_stl 'switch_clutch-no_support' 'SHOW_SWITCH_CLUTCH' 'false' 'false' & \ 132 | export_stl 'enclosure_top' 'SHOW_ENCLOSURE_TOP' 'true' 'true' & \ 133 | export_stl 'enclosure_top-no_support' 'SHOW_ENCLOSURE_TOP' 'false' 'true' & \ 134 | export_stl 'knob' 'SHOW_KNOB' 'true' 'false' & \ 135 | wait 136 | 137 | end=`date +%s` 138 | runtime=$((end-start)) 139 | 140 | if [[ "$query" && -z $_found_matches ]]; then 141 | echo "Found no matches for query '$query'" 142 | else 143 | # create_zip 144 | 145 | if [[ $bonk ]]; then 146 | printf "\a" 147 | open $dir 148 | fi 149 | fi 150 | 151 | echo 152 | echo "Finished in $runtime seconds" 153 | } 154 | 155 | while getopts "h?b?p:d:e?c?t?q:" opt; do 156 | case "$opt" in 157 | h) help; exit ;; 158 | b) bonk=true ;; 159 | p) prefix="$OPTARG" ;; 160 | d) dir="$OPTARG" ;; 161 | e) echo "$dir"; exit ;; 162 | c) echo "$commit_hash"; exit ;; 163 | t) echo "$timestamp"; exit ;; 164 | q) IFS="," read -r -a query <<< "$OPTARG" ;; 165 | *) help; exit ;; 166 | esac 167 | done 168 | 169 | run "${query[@]}" 170 | 171 | } 172 | -------------------------------------------------------------------------------- /openscad/batteries.scad: -------------------------------------------------------------------------------- 1 | AAA_BATTERY_DIAMETER = 10.5; 2 | AAA_BATTERY_LENGTH = 44.5; 3 | 4 | AAA_BATTERY_POSITIVE_CONTACT_MIN_LENGTH = .8; 5 | AAA_BATTERY_POSITIVE_CONTACT_MAX_DIAMETER = 3.8; 6 | 7 | AAA_BATTERY_TOTAL_LENGTH = AAA_BATTERY_LENGTH + 8 | AAA_BATTERY_POSITIVE_CONTACT_MIN_LENGTH; 9 | 10 | module battery( 11 | reverse = false, 12 | $fn = 24 13 | ) { 14 | module _output() { 15 | translate([0, AAA_BATTERY_DIAMETER / 2, AAA_BATTERY_DIAMETER / 2]) { 16 | rotate([0, 90, 0]) { 17 | cylinder( 18 | d = AAA_BATTERY_DIAMETER, 19 | h = AAA_BATTERY_LENGTH 20 | ); 21 | 22 | translate([0, 0, AAA_BATTERY_LENGTH]) { 23 | cylinder( 24 | d = AAA_BATTERY_POSITIVE_CONTACT_MAX_DIAMETER, 25 | h = AAA_BATTERY_POSITIVE_CONTACT_MIN_LENGTH 26 | ); 27 | } 28 | } 29 | } 30 | } 31 | 32 | if (reverse) { 33 | translate([AAA_BATTERY_TOTAL_LENGTH, 0, 0]) { 34 | mirror([1, 0, 0]) { 35 | _output(); 36 | } 37 | } 38 | } else { 39 | _output(); 40 | } 41 | } 42 | 43 | module battery_array( 44 | count = 3, 45 | gutter = KEYSTONE_181_GUTTER, 46 | 47 | positive_x = KEYSTONE_181_BUTTON_LENGTH, 48 | negative_x = KEYSTONE_181_SPRING_COMPRESSED_LENGTH 49 | ) { 50 | plot = AAA_BATTERY_DIAMETER + gutter; 51 | 52 | for (i = [0 : count - 1]) { 53 | is_odd = i % 2 == 1; 54 | 55 | translate([is_odd ? positive_x : negative_x, i * plot, 0]) { 56 | battery(reverse = is_odd); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /openscad/battery_contacts.scad: -------------------------------------------------------------------------------- 1 | KEYSTONE_181_HEIGHT = 7; 2 | KEYSTONE_181_CONTACT_X = KEYSTONE_181_HEIGHT / 2; 3 | KEYSTONE_181_CADENCE = 10.5; 4 | KEYSTONE_181_WIDTH = KEYSTONE_181_CADENCE + KEYSTONE_181_CONTACT_X * 2; 5 | KEYSTONE_181_DIAMETER = .5; 6 | 7 | KEYSTONE_181_SPRING_LENGTH = 7.2; 8 | KEYSTONE_181_SPRING_COMPRESSED_LENGTH = KEYSTONE_181_SPRING_LENGTH * .25; 9 | 10 | KEYSTONE_181_BUTTON_LENGTH = 1.4; 11 | 12 | KEYSTONE_181_GUTTER = 0; 13 | 14 | KEYSTONE_180_CUT_LEAD_HEIGHT = 5; 15 | 16 | // 5204: NEGATIVE SPRING WITH TAB 17 | // 5226: POSITIVE BUTTON WITH TAB 18 | KEYSTONE_5204_5226_WIDTH = 9.2; 19 | KEYSTONE_5204_5226_LENGTH = .51; 20 | KEYSTONE_5204_5226_FULL_LENGTH = 1; // includes lil tabs 21 | KEYSTONE_5204_5226_HEIGHT = 10.4; 22 | KEYSTONE_5204_5226_CONTACT_Z = 5.5; 23 | KEYSTONE_5204_5226_TAB_WIDTH = 3; 24 | KEYSTONE_5204_5226_TAB_HEIGHT = 17 - KEYSTONE_5204_5226_HEIGHT; 25 | KEYSTONE_5204_5226_DIMPLE_LENGTH = 1; 26 | 27 | DUAL = "dual"; 28 | BUTTON = "button"; 29 | SPRING = "spring"; 30 | 31 | module keystone_wire_contact( 32 | type = DUAL, 33 | flip = false, 34 | 35 | compressed = true, 36 | 37 | height = KEYSTONE_181_HEIGHT, 38 | contact_x = KEYSTONE_181_CONTACT_X, 39 | cadence = KEYSTONE_181_CADENCE, 40 | width = KEYSTONE_181_WIDTH, 41 | diameter = KEYSTONE_181_DIAMETER, 42 | 43 | spring_length = KEYSTONE_181_SPRING_LENGTH, 44 | spring_compressed_length = KEYSTONE_181_SPRING_COMPRESSED_LENGTH, 45 | 46 | button_length = KEYSTONE_181_BUTTON_LENGTH 47 | ) { 48 | e = .094; 49 | 50 | module _contact( 51 | contact_length, 52 | x = 0, 53 | $fn = 12 54 | ) { 55 | translate([x, 0, height / 2]) { 56 | rotate([270, 0, 0]) { 57 | cylinder( 58 | d = height, 59 | h = diameter + e 60 | ); 61 | 62 | translate([0, 0, diameter]) { 63 | cylinder( 64 | d1 = height, 65 | d2 = height * .67, 66 | h = contact_length - diameter 67 | ); 68 | } 69 | } 70 | } 71 | } 72 | 73 | module _connector() { 74 | translate([contact_x, diameter / 2, height - diameter / 2]) { 75 | rotate([0, 90, 0]) { 76 | cylinder( 77 | d = diameter, 78 | h = cadence 79 | ); 80 | } 81 | } 82 | } 83 | 84 | module arrange(z = 0) { 85 | y = flip ? KEYSTONE_181_HEIGHT / -2 : KEYSTONE_181_HEIGHT / 2; 86 | 87 | translate([0, z, y]) { 88 | rotate(flip ? [0, 0, 90] : [0, 180, -90]) { 89 | children(); 90 | } 91 | } 92 | } 93 | 94 | module _spring() { 95 | _contact( 96 | compressed ? spring_compressed_length : spring_length, contact_x 97 | ); 98 | } 99 | 100 | module _button(x = 0) { 101 | _contact(button_length, x); 102 | } 103 | 104 | module _dual_contacts() { 105 | arrange() { 106 | _spring(); 107 | _button(width - contact_x); 108 | _connector(); 109 | } 110 | } 111 | 112 | if (type == DUAL) { 113 | _dual_contacts(); 114 | } else if (type == BUTTON) { 115 | arrange(AAA_BATTERY_DIAMETER / 2) { 116 | _button(); 117 | 118 | translate([0, 0, height - e]) { 119 | cylinder( 120 | d = diameter, 121 | h = KEYSTONE_180_CUT_LEAD_HEIGHT + e 122 | ); 123 | } 124 | } 125 | } else if (type == SPRING) { 126 | arrange() { 127 | _spring(); 128 | 129 | translate([height / 2, 0, e - KEYSTONE_180_CUT_LEAD_HEIGHT]) { 130 | cylinder( 131 | d = diameter, 132 | h = KEYSTONE_180_CUT_LEAD_HEIGHT + e 133 | ); 134 | } 135 | } 136 | } 137 | } 138 | 139 | module keystone_tabbed_contact( 140 | type = BUTTON, 141 | flip = false, 142 | show_tab = true, 143 | 144 | width = KEYSTONE_5204_5226_WIDTH, 145 | length = KEYSTONE_5204_5226_LENGTH, 146 | height = KEYSTONE_5204_5226_HEIGHT, 147 | 148 | contact_diameter = 6, 149 | contact_button_length = 1, 150 | contact_spring_length = KEYSTONE_181_SPRING_COMPRESSED_LENGTH, 151 | contact_z = KEYSTONE_5204_5226_CONTACT_Z, 152 | 153 | tab_width = KEYSTONE_5204_5226_TAB_WIDTH, 154 | tab_height = KEYSTONE_5204_5226_TAB_HEIGHT 155 | ) { 156 | e = .072; 157 | 158 | module _output() { 159 | cube([width, length, height]); 160 | 161 | if (show_tab) { 162 | translate([(width - tab_width) / 2, 0, -tab_height]) { 163 | cube([tab_width, length, tab_height + e]); 164 | } 165 | } 166 | 167 | translate([width / 2, length - e, contact_z]) { 168 | rotate([-90, 0, 0]) { 169 | cylinder( 170 | d1 = contact_diameter, 171 | d2 = contact_diameter * .67, 172 | h = type == SPRING 173 | ? contact_spring_length + e 174 | : contact_button_length + e 175 | ); 176 | } 177 | } 178 | } 179 | 180 | if (flip) { 181 | translate([0, 0, -contact_z]) { 182 | rotate([0, 0, 90]) { 183 | _output(); 184 | } 185 | } 186 | } else { 187 | translate([0, width, -contact_z]) { 188 | rotate([0, 0, -90]) { 189 | _output(); 190 | } 191 | } 192 | } 193 | } 194 | 195 | module battery_contacts( 196 | tolerance = 0, 197 | show_tabs = true, 198 | gutter = KEYSTONE_181_GUTTER, 199 | count = 3, 200 | end_terminal_bottom_right = true 201 | ) { 202 | e = .091; 203 | 204 | cavity_width = get_battery_holder_cavity_width(tolerance); 205 | start_on_right = end_terminal_bottom_right; 206 | 207 | function get_y(contact_width, i, is_dual = false) = ( 208 | (AAA_BATTERY_DIAMETER + gutter) * i 209 | + (AAA_BATTERY_DIAMETER * (is_dual ? 2 : 1) - contact_width) / 2 210 | ); 211 | 212 | if (floor(count) > 1) { 213 | for (i = [0 : floor(count)]) { 214 | is_even = i % 2 == 0; 215 | 216 | left_x = e; 217 | right_x = cavity_width - tolerance * 2 - e; 218 | 219 | z = AAA_BATTERY_DIAMETER / 2; 220 | 221 | if (i <= count - 2) { 222 | x = is_even 223 | ? start_on_right ? right_x : left_x 224 | : start_on_right ? left_x : right_x; 225 | 226 | translate([x, get_y(KEYSTONE_181_WIDTH, i, true), z]) { 227 | keystone_wire_contact( 228 | flip = start_on_right ? is_even : !is_even 229 | ); 230 | } 231 | } 232 | 233 | if (i == 0) { 234 | x = start_on_right ? left_x : right_x; 235 | 236 | translate([x, get_y(KEYSTONE_5204_5226_WIDTH, i), z]) { 237 | keystone_tabbed_contact( 238 | flip = !start_on_right, 239 | type = BUTTON, 240 | show_tab = show_tabs 241 | ); 242 | } 243 | } else if (i == count - 1) { 244 | x = start_on_right ? right_x : left_x; 245 | 246 | translate([x, get_y(KEYSTONE_5204_5226_WIDTH, i), z]) { 247 | keystone_tabbed_contact( 248 | flip = start_on_right, 249 | type = SPRING, 250 | show_tab = show_tabs 251 | ); 252 | } 253 | } 254 | } 255 | } 256 | } 257 | -------------------------------------------------------------------------------- /openscad/enclosure_engraving.scad: -------------------------------------------------------------------------------- 1 | /* TODO: extract into common parts repo */ 2 | use <../../poly555/openscad/lib/basic_shapes.scad>; 3 | use <../../poly555/openscad/lib/engraving.scad>; 4 | 5 | ENCLOSURE_ENGRAVING_DEPTH = 1.2; 6 | OSKITONE_LENGTH_WIDTH_RATIO = 4.6 / 28; // TODO: extract 7 | SIDE_ENGRAVING_DEFAULT_WIDTH = 15; 8 | 9 | function get_branding_model_length( 10 | gutter = 0, 11 | make_to_model_ratio = .5, 12 | available_length = 10 13 | ) = ( 14 | (available_length - gutter) * (1 - make_to_model_ratio) 15 | ); 16 | function get_branding_make_width( 17 | gutter = 0, 18 | make_to_model_ratio = .5, 19 | available_length = 10 20 | ) = ( 21 | get_branding_make_length(gutter, make_to_model_ratio, available_length) 22 | / OSKITONE_LENGTH_WIDTH_RATIO 23 | ); 24 | function get_branding_make_length( 25 | gutter = 0, 26 | make_to_model_ratio = .5, 27 | available_length = 10 28 | ) = ( 29 | (available_length - gutter) * make_to_model_ratio 30 | ); 31 | 32 | module enclosure_engraving( 33 | string, 34 | size, 35 | bleed = -.1, 36 | chamfer = .4, 37 | center = true, 38 | position = [0, 0], 39 | font = "Orbitron:style=Black", 40 | depth = ENCLOSURE_ENGRAVING_DEPTH, 41 | 42 | placard = undef, 43 | chamfer_placard_top = false, 44 | 45 | bottom = false, 46 | 47 | quick_preview = true, 48 | enclosure_height = 0 49 | ) { 50 | e = .0135; 51 | 52 | translate([ 53 | position.x, 54 | position.y, 55 | bottom ? depth : enclosure_height - depth 56 | ]) { 57 | rotate([0, bottom ? 180 : 0, 0]) { 58 | difference() { 59 | if (placard) { 60 | translate([ 61 | placard.x / (center ? -2 : 1), 62 | placard.y / (center ? -2 : 1) 63 | ]) { 64 | flat_top_rectangular_pyramid( 65 | top_width = placard.x, 66 | top_length = chamfer_placard_top 67 | ? placard.y + depth / 2 68 | : placard.y, 69 | bottom_width = placard.x, 70 | bottom_length = chamfer_placard_top 71 | ? placard.y - depth / 2 72 | : placard.y, 73 | height = depth + e, 74 | top_weight_y = 0 75 | ); 76 | } 77 | } 78 | 79 | translate(placard ? [0, 0, -e] : [0, 0, 0]) { 80 | engraving( 81 | string = string ? string : undef, 82 | svg = string ? undef : "../../branding.svg", 83 | font = font, 84 | size = string ? size : undef, 85 | resize = string 86 | ? undef 87 | : [size / OSKITONE_LENGTH_WIDTH_RATIO, size], 88 | bleed = quick_preview ? 0 : bleed, 89 | height = placard ? depth + e * 2 : depth + e, 90 | center = center, 91 | chamfer = quick_preview ? 0 : (placard ? 0 : chamfer) 92 | ); 93 | } 94 | } 95 | } 96 | } 97 | } 98 | 99 | /* // All of these are fine but -.1 bleed and .4 chamfer seems to look best 100 | // .2 chamfer could also be fine if .4 isn't defined enough 101 | bleeds = [-.1]; 102 | chamfers = [.2, .3, .4, .6]; 103 | 104 | bottom_engraving_length = 8; 105 | 106 | gutter = 1; 107 | plot_width = 50; 108 | plot_length = 9; 109 | 110 | difference() { 111 | cube([ 112 | plot_width * len(bleeds) + gutter * 2, 113 | plot_length * len(chamfers) + gutter * 2, 114 | 2 115 | ]); 116 | 117 | for (i = [0 : len(bleeds) - 1]) { 118 | for (ii = [0 : len(chamfers) - 1]) { 119 | translate([0, 0, -.01]) { 120 | enclosure_engraving( 121 | size = bottom_engraving_length, 122 | bleed = bleeds[i], 123 | chamfer = chamfers[ii], 124 | center = true, 125 | position = [ 126 | gutter + plot_width * i + plot_width / 2, 127 | gutter + plot_length * ii + plot_length / 2 128 | ], 129 | bottom = true, 130 | enclosure_height = 2, 131 | reduced_test_case = false, 132 | quick_preview = false // $preview 133 | ); 134 | } 135 | } 136 | } 137 | } */ 138 | -------------------------------------------------------------------------------- /openscad/enclosure_screw_cavities.scad: -------------------------------------------------------------------------------- 1 | use <../../poly555/openscad/lib/screw_head_exposures.scad>; 2 | 3 | module enclosure_screw_cavities( 4 | screw_head_clearance = 0, 5 | 6 | pcb_position = [0, 0, 0], 7 | pcb_screw_hole_positions = [], 8 | 9 | tolerance = 0, 10 | 11 | pcb_hole_diameter = 3.2, // PCB_HOLE_DIAMETER 12 | 13 | show_dfm = false, 14 | 15 | quick_preview = true 16 | ) { 17 | e = .0539; 18 | 19 | for (p = pcb_screw_hole_positions) { 20 | translate([pcb_position.x + p.x, pcb_position.y + p.y, 0]) { 21 | screw_head_exposure( 22 | tolerance = tolerance, 23 | clearance = screw_head_clearance, 24 | show_dfm = show_dfm 25 | ); 26 | 27 | translate([0, 0, -e]) { 28 | cylinder( 29 | d = pcb_hole_diameter, 30 | h = pcb_position.z + e * 2, 31 | $fn = quick_preview ? undef : 120 32 | ); 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /openscad/headphone_jack.scad: -------------------------------------------------------------------------------- 1 | HEADPHONE_JACK_WIDTH = 12; 2 | HEADPHONE_JACK_LENGTH = 11; 3 | HEADPHONE_JACK_HEIGHT = 5; 4 | HEADPHONE_JACK_BARREL_LENGTH = 3; 5 | HEADPHONE_JACK_BARREL_DIAMETER = 6; 6 | HEADPHONE_JACK_BARREL_Z = HEADPHONE_JACK_BARREL_DIAMETER / 2; 7 | 8 | module headphone_jack() { 9 | e = .0341; 10 | 11 | cube([ 12 | HEADPHONE_JACK_WIDTH, 13 | HEADPHONE_JACK_LENGTH, 14 | HEADPHONE_JACK_HEIGHT 15 | ]); 16 | 17 | translate([ 18 | HEADPHONE_JACK_WIDTH / 2, 19 | HEADPHONE_JACK_LENGTH - e, 20 | HEADPHONE_JACK_BARREL_Z 21 | ]) { 22 | rotate([-90, 0, 0]) { 23 | cylinder( 24 | d = HEADPHONE_JACK_BARREL_DIAMETER, 25 | h = HEADPHONE_JACK_BARREL_LENGTH + e 26 | ); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /openscad/key_lip_endstop.scad: -------------------------------------------------------------------------------- 1 | module key_lip_endstop( 2 | keys_cavity_height_z, 3 | keys_full_width, 4 | 5 | distance_into_keys_bleed = 0, 6 | travel = 0, 7 | 8 | key_gutter, 9 | 10 | // HEY! These values are eyeballed and that's okay, I guess. What we want 11 | // is for the keys to have a good bottom lip and for their fillets to not 12 | // get messed up too much. 13 | distance_from_cavity_z = 1.5, 14 | distance_into_keys = .6 15 | ) { 16 | e = .038; 17 | 18 | length = distance_into_keys + distance_into_keys_bleed + key_gutter + e; 19 | width = keys_full_width + key_gutter * 2 + e * 2; 20 | 21 | z = keys_cavity_height_z - distance_from_cavity_z; 22 | 23 | module _endstop(_z) { 24 | translate([ENCLOSURE_WALL - e, ENCLOSURE_WALL, _z]) { 25 | rotate([0, 90, 0]) { 26 | cylinder( 27 | d = length * 2, 28 | h = width, 29 | $fn = 4 30 | ); 31 | } 32 | } 33 | } 34 | 35 | hull() { 36 | _endstop(z); 37 | 38 | if (travel > 0) { 39 | _endstop(z + travel); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /openscad/keys.scad: -------------------------------------------------------------------------------- 1 | /* TODO: extract into common parts repo */ 2 | use <../../poly555/openscad/lib/keys.scad>; 3 | use <../../poly555/openscad/lib/utils.scad>; 4 | 5 | include ; 6 | include ; 7 | 8 | KEYS_COUNT = 17; 9 | KEYS_MOUNT_LENGTH = NUT_DIAMETER; 10 | KEYS_FRONT_BOTTOM_CHAMFER = 1; 11 | 12 | function get_key_to_pcb_x_offset( 13 | key_width, 14 | key_gutter 15 | ) = ((key_width - BUTTON_DIAMETER) / 2 - key_gutter); 16 | 17 | function get_keys_full_width( 18 | key_width, 19 | key_gutter 20 | ) = ( 21 | let (natural_key_count = get_natural_key_count(KEYS_COUNT, 0)) 22 | natural_key_count * key_width + (natural_key_count - 1) * key_gutter 23 | ); 24 | 25 | function get_keys_to_enclosure_distance( 26 | tolerance = 0, 27 | key_gutter 28 | ) = ( 29 | key_gutter - tolerance * 2 30 | ); 31 | 32 | function get_keys_mount_rail_width( 33 | tolerance, 34 | key_width, 35 | key_gutter 36 | ) = ( 37 | get_keys_full_width(key_width, key_gutter) 38 | + get_keys_to_enclosure_distance(tolerance, key_gutter) * 2 39 | ); 40 | 41 | module keys_mount_alignment_fixture( 42 | height, 43 | cavity, 44 | key_width, 45 | key_gutter, 46 | tolerance = 0, 47 | 48 | fixture_width = 1, 49 | fixture_length = 2 50 | ) { 51 | e = .0825; 52 | 53 | x_bleed = cavity ? 0 : tolerance + e; 54 | z_bleed = cavity ? e : 0; 55 | 56 | fixture_width = cavity 57 | ? fixture_width + tolerance 58 | : fixture_width + x_bleed - tolerance; 59 | fixture_length = cavity 60 | ? fixture_length + tolerance 61 | : fixture_length - tolerance * 2; 62 | 63 | xs = [ 64 | -e - x_bleed, 65 | get_keys_mount_rail_width(tolerance, key_width, key_gutter) 66 | - fixture_width + x_bleed 67 | ]; 68 | 69 | for (x = xs) { 70 | y = (KEYS_MOUNT_LENGTH - fixture_length) / 2; 71 | translate([x, y, -z_bleed]) { 72 | cube([fixture_width + e, fixture_length, height + z_bleed * 2]); 73 | } 74 | } 75 | } 76 | 77 | module keys_mount_rail( 78 | height, 79 | key_width, 80 | key_length, 81 | key_gutter, 82 | front_y_bleed = 0, 83 | include_alignment_fixture = true, 84 | pcb_screw_hole_positions = [], 85 | tolerance = 0 86 | ) { 87 | keys_to_enclosure_distance = 88 | get_keys_to_enclosure_distance(tolerance, key_gutter); 89 | 90 | translate([-keys_to_enclosure_distance, key_length - front_y_bleed, 0]) { 91 | difference() { 92 | cube([ 93 | get_keys_mount_rail_width(tolerance, key_width, key_gutter), 94 | KEYS_MOUNT_LENGTH + front_y_bleed, 95 | height 96 | ]); 97 | 98 | translate([ 99 | get_key_to_pcb_x_offset(key_width, key_gutter) 100 | + keys_to_enclosure_distance, 101 | KEYS_MOUNT_LENGTH / 2 + front_y_bleed, 102 | 0 103 | ]) { 104 | scout_pcb_holes( 105 | y = 0, 106 | height = height, 107 | positions = pcb_screw_hole_positions, 108 | include_relief_holes = false 109 | ); 110 | } 111 | 112 | if (include_alignment_fixture) { 113 | translate([0, front_y_bleed, 0]) { 114 | keys_mount_alignment_fixture( 115 | height = height, 116 | key_width = key_width, 117 | key_gutter = key_gutter, 118 | cavity = true, 119 | tolerance = tolerance 120 | ); 121 | } 122 | } 123 | } 124 | } 125 | } 126 | 127 | module keys( 128 | key_height = 7, 129 | accidental_height = 0, 130 | tolerance = 0, 131 | 132 | cantilever_length = 0, 133 | cantilever_height = 0, 134 | cantilver_mount_height = 0, 135 | nut_lock_floor = 0, 136 | 137 | keys_count = KEYS_COUNT, 138 | starting_natural_key_index = 0, 139 | 140 | keys_position = [], 141 | pcb_position = [], 142 | pcb_screw_hole_positions = [], 143 | 144 | keys_cavity_height_z, 145 | key_width, 146 | key_length, 147 | travel = 0, 148 | key_gutter, 149 | 150 | front_bottom_chamfer = KEYS_FRONT_BOTTOM_CHAMFER, 151 | 152 | accidental_color = "#444", 153 | natural_color = "#fff", 154 | natural_color_cavity = "#eee", 155 | 156 | quick_preview = true, 157 | show_clearance = false 158 | ) { 159 | e = .0234; 160 | 161 | keys_full_width = get_keys_full_width(key_width, key_gutter); 162 | 163 | module _keys( 164 | include_natural = false, 165 | include_accidental = false, 166 | include_cantilevers = false 167 | ) { 168 | mounted_keys( 169 | count = keys_count, 170 | starting_natural_key_index = starting_natural_key_index, 171 | 172 | natural_length = key_length, 173 | natural_width = key_width, 174 | natural_height = key_height, 175 | 176 | accidental_width = PCB_KEY_PLOT * 2 * .5, 177 | accidental_length = key_length * 3/5, 178 | accidental_height = key_height + accidental_height, 179 | 180 | front_fillet = quick_preview ? 0 : 1.5, 181 | sides_fillet = quick_preview ? 0 : 1, 182 | 183 | gutter = key_gutter, 184 | 185 | include_mount = false, 186 | include_natural = include_natural, 187 | include_accidental = include_accidental, 188 | include_cantilevers = include_cantilevers, 189 | 190 | cantilever_length = cantilever_length, 191 | cantilever_height = cantilever_height, 192 | cantilever_recession = cantilever_length 193 | ); 194 | } 195 | 196 | difference() { 197 | union() { 198 | e_translate(keys_position, [0, 1, -1]) { 199 | color(accidental_color) { 200 | _keys( 201 | include_natural = false, 202 | include_accidental = true, 203 | include_cantilevers = true 204 | ); 205 | } 206 | } 207 | 208 | color(natural_color) { 209 | translate(keys_position) { 210 | _keys( 211 | include_natural = true, 212 | include_accidental = false, 213 | include_cantilevers = true 214 | ); 215 | 216 | keys_mount_rail( 217 | height = cantilver_mount_height, 218 | key_width = key_width, 219 | key_length = key_length, 220 | key_gutter = key_gutter, 221 | front_y_bleed = e, 222 | pcb_screw_hole_positions = pcb_screw_hole_positions, 223 | tolerance = tolerance 224 | ); 225 | } 226 | } 227 | } 228 | 229 | color(natural_color_cavity) { 230 | key_lip_endstop( 231 | keys_cavity_height_z, 232 | keys_full_width = keys_full_width, 233 | distance_into_keys_bleed = tolerance * 4, 234 | travel = travel, 235 | key_gutter = key_gutter 236 | ); 237 | 238 | if (front_bottom_chamfer > 0) { 239 | translate([ 240 | keys_position.x - e, 241 | keys_position.y - e, 242 | keys_position.z - e 243 | ]) { 244 | flat_top_rectangular_pyramid( 245 | top_width = keys_full_width + e * 2, 246 | top_length = 0, 247 | bottom_width = keys_full_width + e * 2, 248 | bottom_length = front_bottom_chamfer, 249 | height = front_bottom_chamfer, 250 | top_weight_y = 0 251 | ); 252 | } 253 | } 254 | } 255 | } 256 | 257 | if (show_clearance) { 258 | translate([ 259 | keys_position.x, 260 | keys_position.y, 261 | keys_position.z - travel 262 | ]) { 263 | % flat_top_rectangular_pyramid( 264 | top_width = keys_full_width, 265 | top_length = key_length + e, 266 | bottom_width = keys_full_width, 267 | bottom_length = 0, 268 | height = travel + e, 269 | top_weight_y = 0 270 | ); 271 | } 272 | } 273 | } 274 | -------------------------------------------------------------------------------- /openscad/nuts_and_bolts.scad: -------------------------------------------------------------------------------- 1 | /* TODO: extract into common parts repo */ 2 | SCREW_HEAD_DIAMETER = 6; 3 | SCREW_HEAD_HEIGHT = 2.1; 4 | NUT_DIAMETER = 6.4; 5 | NUT_HEIGHT = 2.4; 6 | 7 | SCREW_LENGTH = 3/4 * 25.4; 8 | 9 | FLATHEAD_SCREWDRIVER_POINT = .8; 10 | 11 | module nuts( 12 | pcb_position = [], 13 | positions = [], 14 | y = 0, 15 | z = 0, 16 | diameter = NUT_DIAMETER, 17 | height = NUT_HEIGHT 18 | ) { 19 | e = .019; 20 | 21 | for (xy = positions) { 22 | translate([ 23 | pcb_position.x + xy.x - diameter / 2, 24 | y + pcb_position.y + xy.y - diameter / 2, 25 | z 26 | ]) { 27 | cube([diameter, diameter, height]); 28 | } 29 | } 30 | } 31 | 32 | module screws( 33 | positions = PCB_HOLE_POSITIONS, 34 | pcb_position = [], 35 | diameter = PCB_HOLE_DIAMETER - .2, 36 | length = SCREW_LENGTH, 37 | z = 0 38 | ) { 39 | e = .03; 40 | 41 | for (xy = positions) { 42 | translate([ 43 | pcb_position.x + xy.x, 44 | pcb_position.y + xy.y, 45 | z 46 | ]) { 47 | cylinder( 48 | d = SCREW_HEAD_DIAMETER, 49 | h = SCREW_HEAD_HEIGHT 50 | ); 51 | 52 | translate([0, 0, SCREW_HEAD_HEIGHT - e]) { 53 | cylinder( 54 | d = diameter, 55 | h = length + e 56 | ); 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /openscad/pcb_fixtures.scad: -------------------------------------------------------------------------------- 1 | include ; 2 | include ; 3 | 4 | PCB_FIXTURE_CLEARANCE = .3; 5 | 6 | PCB_FIXTURE_BUTTON_RAIL_LENGTH = 3; 7 | 8 | module _fixture_pcb_difference( 9 | pcb_position = [0, 0, 0], 10 | z = undef, 11 | height = PCB_HEIGHT, 12 | clearance = PCB_FIXTURE_CLEARANCE, 13 | tolerance = DEFAULT_TOLERANCE 14 | ) { 15 | e = .031; 16 | offset = clearance + tolerance; 17 | 18 | translate([ 19 | pcb_position.x - offset, 20 | pcb_position.y - offset, 21 | (z != undef ? z : pcb_position.z) - e 22 | ]) { 23 | cube([ 24 | PCB_WIDTH + offset * 2, 25 | PCB_LENGTH + offset * 2, 26 | height + e * 2 27 | ]); 28 | } 29 | } 30 | 31 | module pcb_enclosure_top_fixtures( 32 | pcb_position = [0, 0, 0], 33 | enclosure_dimensions = [0, 0, 0], 34 | 35 | // NOTE: these are eyeballed, and that's okay! 36 | positions = [ 37 | [PCB_WIDTH * .07, PCB_LENGTH * .7], 38 | [PCB_WIDTH * .5, PCB_LENGTH * .8], 39 | ] 40 | ) { 41 | e = .0876; 42 | 43 | z = pcb_position.z + PCB_HEIGHT; 44 | height = enclosure_dimensions.z - ENCLOSURE_FLOOR_CEILING - z; 45 | 46 | for (position = positions) { 47 | translate([ 48 | pcb_position.x + position.x, 49 | pcb_position.y + position.y, 50 | z 51 | ]) { 52 | translate([0, 0, height + e]) mirror([0, 0, 1]) { 53 | pcb_stool(height = height + e); 54 | } 55 | } 56 | } 57 | } 58 | 59 | module pcb_bottom_fixtures( 60 | pcb_position = [0, 0, 0], 61 | pcb_screw_hole_positions = [], 62 | pcb_post_hole_positions = [], 63 | screw_head_clearance = 0, 64 | 65 | corner_coverage = 3, // eyeballed to not collide w/ switch_clutch 66 | corner_fixture_wall = 2, 67 | mounting_column_wall = ENCLOSURE_INNER_WALL, 68 | 69 | clearance = PCB_FIXTURE_CLEARANCE, 70 | tolerance = DEFAULT_TOLERANCE, 71 | 72 | quick_preview = true 73 | ) { 74 | e = .09876; 75 | offset = clearance + tolerance; 76 | 77 | z = ENCLOSURE_FLOOR_CEILING - e; 78 | 79 | module _back_stools(size = PCB_STOOL_DIAMETER) { 80 | corner_inset = size / 2 + PCB_STOOL_CHAMFER; 81 | y = PCB_LENGTH - corner_inset; 82 | 83 | for (position = [[corner_inset, y], [PCB_WIDTH - corner_inset, y]]) { 84 | translate([ 85 | pcb_position.x + position.x, 86 | pcb_position.y + position.y, 87 | z 88 | ]) { 89 | pcb_stool(height = pcb_position.z - z); 90 | } 91 | } 92 | } 93 | 94 | module _button_rail(length = PCB_FIXTURE_BUTTON_RAIL_LENGTH) { 95 | translate([ 96 | pcb_position.x, 97 | pcb_position.y + PCB_BUTTON_POSITIONS[0].y - length / 2, 98 | z 99 | ]) { 100 | cube([PCB_WIDTH, length, pcb_position.z - z]); 101 | } 102 | } 103 | 104 | module _corners( 105 | wall = corner_fixture_wall, 106 | height_extension = 1 107 | ) { 108 | offset = wall + tolerance; 109 | 110 | corner_size = offset + corner_coverage; 111 | corner_xs = [-offset, PCB_WIDTH + offset - corner_size]; 112 | corner_ys = [-offset]; 113 | 114 | z = ENCLOSURE_FLOOR_CEILING - e; 115 | 116 | height = pcb_position.z - z + PCB_HEIGHT + height_extension; 117 | 118 | difference() { 119 | for (x = corner_xs, y = corner_ys) { 120 | translate([pcb_position.x + x, pcb_position.y + y, z]) { 121 | cube([corner_size, corner_size, height]); 122 | } 123 | } 124 | 125 | _fixture_pcb_difference( 126 | pcb_position, 127 | z = z, 128 | height = height 129 | ); 130 | } 131 | } 132 | 133 | _back_stools(); 134 | _button_rail(); 135 | _corners(); 136 | 137 | pcb_mounting_columns( 138 | pcb_position = pcb_position, 139 | 140 | screw_head_clearance = screw_head_clearance, 141 | wall = mounting_column_wall, 142 | 143 | pcb_screw_hole_positions = pcb_screw_hole_positions, 144 | pcb_post_hole_positions = pcb_post_hole_positions, 145 | 146 | tolerance = tolerance, 147 | 148 | enclosure_floor_ceiling = ENCLOSURE_FLOOR_CEILING, 149 | screw_head_diameter = SCREW_HEAD_DIAMETER, 150 | pcb_hole_diameter = PCB_HOLE_DIAMETER, 151 | 152 | quick_preview = quick_preview 153 | ); 154 | } 155 | -------------------------------------------------------------------------------- /openscad/pcb_mounting_columns.scad: -------------------------------------------------------------------------------- 1 | include ; 2 | include ; 3 | 4 | module pcb_mounting_columns( 5 | pcb_position = [0,0,0], 6 | 7 | screw_head_clearance = 0, 8 | wall = 0, 9 | 10 | pcb_screw_hole_positions = [[0,0]], 11 | pcb_post_hole_positions = [[0,0]], 12 | 13 | tolerance = 0, 14 | 15 | enclosure_floor_ceiling = 1.8, // ENCLOSURE_FLOOR_CEILING 16 | screw_head_height = SCREW_HEAD_HEIGHT, 17 | screw_head_diameter = SCREW_HEAD_DIAMETER, 18 | pcb_hole_diameter = 3.2, // PCB_HOLE_DIAMETER 19 | 20 | support_web_length = undef, 21 | 22 | quick_preview = true 23 | ) { 24 | e = .0419; 25 | 26 | z = enclosure_floor_ceiling - e; 27 | 28 | head_column_height = screw_head_height + enclosure_floor_ceiling 29 | + screw_head_clearance; 30 | shaft_column_z = head_column_height - e; 31 | 32 | module _column(p, screw = false, post = false) { 33 | x = pcb_position.x + p.x; 34 | y = pcb_position.y + p.y; 35 | 36 | if (screw) { 37 | translate([x, y, z]) { 38 | cylinder( 39 | h = head_column_height - z, 40 | d = screw_head_diameter + tolerance * 2 + wall * 2 41 | ); 42 | } 43 | 44 | translate([x, y, shaft_column_z]) { 45 | cylinder( 46 | h = pcb_position.z - shaft_column_z, 47 | d = pcb_hole_diameter + tolerance * 2 + wall * 2 48 | ); 49 | } 50 | } else { 51 | translate([x, y, z]) { 52 | pcb_stool( 53 | height = pcb_position.z - z, 54 | support_web_length = support_web_length, 55 | registration_nub = true, 56 | tolerance = tolerance, 57 | quick_preview = quick_preview 58 | ); 59 | } 60 | } 61 | } 62 | 63 | for (p = pcb_screw_hole_positions) { 64 | _column(p, screw = true); 65 | } 66 | 67 | for (p = pcb_post_hole_positions) { 68 | _column(p, post = true); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /openscad/pcb_stool.scad: -------------------------------------------------------------------------------- 1 | /* TODO: extract into common parts repo */ 2 | use <../../poly555/openscad/lib/basic_shapes.scad>; 3 | 4 | PCB_STOOL_DIAMETER = 4; 5 | PCB_STOOL_CHAMFER = 2; 6 | 7 | module pcb_stool( 8 | height, 9 | 10 | diameter = PCB_STOOL_DIAMETER, 11 | chamfer = PCB_STOOL_CHAMFER, 12 | 13 | support_web_count = 3, 14 | support_web_width = 1.2, // ENCLOSURE_INNER_WALL 15 | support_web_length = undef, 16 | 17 | registration_nub = false, 18 | registration_nub_height = 1.6, // PCB_HEIGHT 19 | registration_nub_hole_diameter = 3.2, // PCB_HOLE_DIAMETER 20 | registration_nub_clearance = .2, 21 | 22 | tolerance = 0, 23 | 24 | hidef_rounding = 120, // HIDEF_ROUNDING 25 | 26 | quick_preview = false 27 | ) { 28 | e = .0524; 29 | 30 | cylinder(d = diameter, h = height); 31 | 32 | cylinder( 33 | d1 = diameter + chamfer * 2, 34 | d2 = diameter, 35 | h = chamfer 36 | ); 37 | 38 | overlap = diameter / 6; 39 | for (i = [0 : support_web_count - 1]) { 40 | rotate([0, 0, 360 / support_web_count * i]) { 41 | translate([support_web_width / -2, diameter / 2 - overlap, 0]) { 42 | flat_top_rectangular_pyramid( 43 | top_width = support_web_width, 44 | top_length = 0, 45 | bottom_width = support_web_width, 46 | bottom_length = support_web_length 47 | ? support_web_length 48 | : overlap + chamfer, 49 | height = height - e, 50 | top_weight_y = 0 51 | ); 52 | } 53 | } 54 | } 55 | 56 | if (registration_nub) { 57 | translate([0, 0, height - e]) { 58 | cylinder( 59 | d = registration_nub_hole_diameter 60 | - tolerance * 2 61 | - registration_nub_clearance * 2, 62 | h = registration_nub_height + e, 63 | $fn = quick_preview ? 12 : hidef_rounding 64 | ); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /openscad/scout_display.scad: -------------------------------------------------------------------------------- 1 | use ; 2 | 3 | // HACK: obv, right? 4 | 5 | $vpr = [90 - 10, 0, $t * 360]; 6 | $vpt = [0, 0, 76]; 7 | $vpd = 500; 8 | 9 | translate([86.9 / 2, 38, 0]) 10 | rotate([19.4, 0, 0]) 11 | translate([0, 0, 158.2]) 12 | rotate([0, 90, 90]) 13 | scout( 14 | show_pcb = false, 15 | show_keys_mount_rail = false, 16 | show_dfm = false, 17 | quick_preview = false 18 | ); 19 | -------------------------------------------------------------------------------- /openscad/scout_pcb.scad: -------------------------------------------------------------------------------- 1 | /* TODO: extract into common parts repo */ 2 | use <../../apc/openscad/pcb.scad>; 3 | 4 | include ; 5 | include ; 6 | 7 | PCB_WIDTH = 177.292 - 32.004; 8 | PCB_LENGTH = 124.968 - 80.518; 9 | PCB_HEIGHT = 1.6; 10 | 11 | PCB_KEY_PLOT = 2.54 * 3; 12 | 13 | function _(xy, nudge = [0, 0]) = ( 14 | [(xy.x + nudge.x - 32.004), -(xy.y - 123.444) + nudge.y] 15 | ); 16 | 17 | // It's easier to magically nudge things around than reconcile KiCad's 18 | // awkward non-zero-origin positioning. 19 | MAGIC = .28; 20 | 21 | PCB_BUTTON_POSITIONS = [ 22 | _([170.942 + 2.54 * .9, 121.92], [0, 2.54 * 1.9]), 23 | _([163.322 + 2.54 * .9, 121.92], [0, 2.54 * 1.9]), 24 | _([155.702 + 2.54 * .9, 121.92], [0, 2.54 * 1.9]), 25 | _([148.082 + 2.54 * .9, 121.92], [0, 2.54 * 1.9]), 26 | _([140.462 + 2.54 * .9, 121.92], [0, 2.54 * 1.9]), 27 | _([125.222 + 2.54 * .9, 121.92], [0, 2.54 * 1.9]), 28 | _([117.602 + 2.54 * .9, 121.92], [0, 2.54 * 1.9]), 29 | _([109.982 + 2.54 * .9, 121.92], [0, 2.54 * 1.9]), 30 | _([102.362 + 2.54 * .9, 121.92], [0, 2.54 * 1.9]), 31 | _([94.742 + 2.54 * .9, 121.92], [0, 2.54 * 1.9]), 32 | _([87.122 + 2.54 * .9, 121.92], [0, 2.54 * 1.9]), 33 | _([79.502 + 2.54 * .9, 121.92], [0, 2.54 * 1.9]), 34 | _([64.262 + 2.54 * .9, 121.92], [0, 2.54 * 1.9]), 35 | _([56.642 + 2.54 * .9, 121.92], [0, 2.54 * 1.9]), 36 | _([49.022 + 2.54 * .9, 121.92], [0, 2.54 * 1.9]), 37 | _([41.402 + 2.54 * .9, 121.92], [0, 2.54 * 1.9]), 38 | _([33.782 + 2.54 * .9, 121.92], [0, 2.54 * 1.9]), 39 | ]; 40 | 41 | PCB_HOLE_DIAMETER = 3.2; 42 | PCB_HOLE_POSITIONS = [ 43 | _([65.066, 107.696], [0, 2.54 / 2 + MAGIC]), 44 | _([78.26, 107.696], [0, 2.54 / 2 + MAGIC]), 45 | _([104.648, 107.696], [0, 2.54 / 2 + MAGIC]), 46 | _([131.036, 107.696], [0, 2.54 / 2 + MAGIC]), 47 | _([144.23, 107.696], [0, 2.54 / 2 + MAGIC]), 48 | ]; 49 | 50 | PCB_RELIEF_HOLE_DIAMETER = 3.5; 51 | PCB_RELIEF_HOLE_POSITIONS = [ 52 | _([74.168, 122.555], [0, 2.54 / 2 + MAGIC]), 53 | _([135.128, 122.555], [0, 2.54 / 2 + MAGIC]), 54 | ]; 55 | 56 | PCB_LED_Z = 3; // RGB LED pin footprint prevents it from resting directly on PCB 57 | PCB_LED_POSITION = _([156.474, 86.706], [-2.54, 2.54 - MAGIC]); 58 | PCB_POT_POSITION = _([172.824, 97.796], [-2.54, 7 + 2.54 / 2 + MAGIC]); 59 | PCB_SWITCH_POSITION = _([34.544, 91.98], [0, -2.54]); 60 | 61 | // https://www.digikey.com/en/products/detail/adam-tech/PH1RB-06-UA/9830592 62 | PCB_UART_HEADER_POSITION = _([42.926, 88.773], [2.54 / -2, 2.54 / 2]); 63 | PCB_UART_HEADER_WIDTH = 2.54 * 6; 64 | PCB_UART_HEADER_HEIGHT = 2.5; 65 | UART_HEADER_PIN_SIZE = .8; 66 | 67 | PCB_HEADPHONE_JACK_POSITION = _( 68 | [138.176, 84.11], 69 | [HEADPHONE_JACK_WIDTH / -2, HEADPHONE_JACK_LENGTH / -2 - MAGIC] 70 | ); 71 | 72 | LED_DIAMETER = 5.9; 73 | LED_HEIGHT = 8.6; 74 | 75 | PTV09A_POT_BASE_WIDTH = 10; 76 | PTV09A_POT_BASE_HEIGHT = 6.8; 77 | PTV09A_POT_ACTUATOR_DIAMETER = 6; 78 | PTV09A_POT_ACTUATOR_BASE_DIAMETER = 6.9; 79 | PTV09A_POT_ACTUATOR_BASE_HEIGHT = 2; 80 | PTV09A_POT_ACTUATOR_HEIGHT = 20 - PTV09A_POT_BASE_HEIGHT; 81 | PTV09A_POT_ACTUATOR_D_SHAFT_HEIGHT = 7; 82 | PTV09A_POT_ACTUATOR_D_SHAFT_DEPTH = PTV09A_POT_ACTUATOR_DIAMETER - 4.5; 83 | 84 | BUTTON_DIAMETER = 6; 85 | BUTTON_HEIGHT = 6; 86 | 87 | PCB_CIRCUITRY_CLEARANCE = 12; 88 | PCB_PIN_CLEARANCE = 2; 89 | PCB_FRONT_PIN_Y = 2; 90 | 91 | module scout_pcb_holes( 92 | y, 93 | height = PCB_HEIGHT, 94 | diameter = PCB_HOLE_DIAMETER, 95 | diameter_bleed = 0, 96 | positions = PCB_HOLE_POSITIONS, 97 | include_relief_holes = true 98 | ) { 99 | e = .0343; 100 | 101 | for (xy = positions) { 102 | translate([xy.x, y != undef ? y : xy.y, -e]) { 103 | cylinder( 104 | d = diameter + diameter_bleed * 2, 105 | h = height + e * 2 + 3, 106 | $fn = 12 107 | ); 108 | } 109 | } 110 | 111 | if (include_relief_holes) { 112 | scout_pcb_holes( 113 | y = y, 114 | height = height, 115 | diameter = PCB_RELIEF_HOLE_DIAMETER, 116 | diameter_bleed = diameter_bleed, 117 | positions = PCB_RELIEF_HOLE_POSITIONS, 118 | include_relief_holes = false 119 | ); 120 | } 121 | } 122 | 123 | module scout_pcb( 124 | show_board = true, 125 | show_buttons = true, 126 | show_silkscreen = true, 127 | show_led = true, 128 | show_pot = true, 129 | show_switch = true, 130 | show_pcb_uart_header = true, 131 | show_headphone_jack = true, 132 | show_circuitry_clearance = true, 133 | 134 | switch_position = 0 135 | ) { 136 | e = .0143; 137 | silkscreen_height = e; 138 | 139 | if (show_board) { 140 | difference() { 141 | union() { 142 | color("purple") cube([PCB_WIDTH, PCB_LENGTH, PCB_HEIGHT]); 143 | 144 | if (show_silkscreen) { 145 | translate([0, 0, PCB_HEIGHT - e]) { 146 | linear_extrude(silkscreen_height + e) { 147 | offset(.1) { 148 | import("../kicad/scout/scout-brd.svg"); 149 | } 150 | } 151 | } 152 | } 153 | } 154 | 155 | scout_pcb_holes(); 156 | 157 | translate([9.4, 40.4, -e]) cube([15.8, 10, PCB_HEIGHT + e * 2]); 158 | translate([103.2, 43.4, -e]) cube([6, 10, PCB_HEIGHT + e * 2]); 159 | } 160 | } 161 | 162 | if (show_buttons) { 163 | for (xy = PCB_BUTTON_POSITIONS) { 164 | translate([xy.x, xy.y, PCB_HEIGHT - e]) { 165 | % cylinder( 166 | h = BUTTON_HEIGHT + e, 167 | d = BUTTON_DIAMETER 168 | ); 169 | } 170 | } 171 | } 172 | 173 | module _translate(position, z = PCB_HEIGHT - e) { 174 | translate([position.x, position.y, z]) { 175 | children(); 176 | } 177 | } 178 | 179 | if (show_led) { 180 | _translate(PCB_LED_POSITION, PCB_LED_Z) { 181 | % cylinder( 182 | d = LED_DIAMETER, 183 | h = LED_HEIGHT + e, 184 | $fn = 12 185 | ); 186 | } 187 | } 188 | 189 | if (show_pot) { 190 | _translate(PCB_POT_POSITION) { 191 | % pot(); 192 | } 193 | } 194 | 195 | if (show_switch) { 196 | _translate(PCB_SWITCH_POSITION) { 197 | % switch(switch_position); 198 | } 199 | } 200 | 201 | if (show_pcb_uart_header) { 202 | x = 2.54 / 2 - UART_HEADER_PIN_SIZE / 2; 203 | z = PCB_UART_HEADER_HEIGHT / 2 - UART_HEADER_PIN_SIZE / 2; 204 | 205 | _translate(PCB_UART_HEADER_POSITION) { 206 | translate([0, 1.8, 0]) { 207 | % cube([ 208 | PCB_UART_HEADER_WIDTH, 209 | PCB_UART_HEADER_HEIGHT, 210 | PCB_UART_HEADER_HEIGHT 211 | ]); 212 | } 213 | 214 | for (i = [0 : 5]) { 215 | translate([x + i * 2.54, 0, z]) { 216 | % cube([UART_HEADER_PIN_SIZE, 10.25, UART_HEADER_PIN_SIZE]); 217 | } 218 | } 219 | } 220 | } 221 | 222 | if (show_headphone_jack) { 223 | _translate(PCB_HEADPHONE_JACK_POSITION) { 224 | % headphone_jack(); 225 | } 226 | } 227 | 228 | if (show_circuitry_clearance) { 229 | length = PCB_LENGTH - PCB_HOLE_POSITIONS[0].y - KEYS_MOUNT_LENGTH / 2; 230 | 231 | translate([0, PCB_LENGTH - length, PCB_HEIGHT - e]) { 232 | % cube([PCB_WIDTH, length, PCB_CIRCUITRY_CLEARANCE + e]); 233 | } 234 | 235 | translate([0, PCB_FRONT_PIN_Y, -PCB_PIN_CLEARANCE]) { 236 | % cube([ 237 | PCB_WIDTH, 238 | PCB_LENGTH - PCB_FRONT_PIN_Y, 239 | PCB_PIN_CLEARANCE + e 240 | ]); 241 | } 242 | 243 | } 244 | } 245 | -------------------------------------------------------------------------------- /openscad/speaker.scad: -------------------------------------------------------------------------------- 1 | /* Arndt AZ40R 1.6" */ 2 | /* https://www.jameco.com/Jameco/Products/ProdDS/2227516.pdf */ 3 | 4 | use <../../poly555/openscad/lib/basic_shapes.scad>; 5 | 6 | SPEAKER_DIAMETER = 39.7; 7 | SPEAKER_HEIGHT = 5.4; 8 | 9 | module speaker() { 10 | cylinder( 11 | d = SPEAKER_DIAMETER, 12 | h = SPEAKER_HEIGHT 13 | ); 14 | } 15 | 16 | function get_speaker_fixture_diameter( 17 | tolerance = 0, 18 | wall = ENCLOSURE_INNER_WALL, 19 | speaker_diameter = SPEAKER_DIAMETER 20 | ) = ( 21 | SPEAKER_DIAMETER + wall * 2 + tolerance * 2 22 | ); 23 | 24 | module speaker_fixture( 25 | height = SPEAKER_HEIGHT, 26 | wall = 1, 27 | tab_cavity_rotation = 90, 28 | tab_cavity_size = 15, 29 | tolerance = 0, 30 | quick_preview = true 31 | ) { 32 | e = .053; 33 | 34 | ring_z = height - SPEAKER_HEIGHT; 35 | diameter = get_speaker_fixture_diameter(tolerance, wall); 36 | 37 | difference() { 38 | ring( 39 | diameter = diameter, 40 | height = height, 41 | thickness = wall, 42 | $fn = quick_preview ? undef : HIDEF_ROUNDING 43 | ); 44 | 45 | rotate([0, 0, tab_cavity_rotation]) { 46 | translate([tab_cavity_size / -2, 0, ring_z - e]) { 47 | cube([tab_cavity_size, diameter / 2, height + e * 2]); 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /openscad/switch.scad: -------------------------------------------------------------------------------- 1 | // https://www.ckswitches.com/media/1428/os.pdf 2 | // OS102011MA1QN1 3 | 4 | SWITCH_BASE_WIDTH = 4.4; 5 | SWITCH_BASE_LENGTH = 8.6; 6 | SWITCH_BASE_HEIGHT = 4.7; 7 | SWITCH_ACTUATOR_WIDTH = 4; 8 | SWITCH_ACTUATOR_LENGTH = 2; 9 | SWITCH_ACTUATOR_HEIGHT = 2; 10 | SWITCH_ACTUATOR_TRAVEL = 2; 11 | SWITCH_ORIGIN = [SWITCH_BASE_WIDTH / 2, SWITCH_BASE_LENGTH - 6.36]; 12 | 13 | module switch(position = 0) { 14 | e = .05234; 15 | 16 | switch_actuator_y = (SWITCH_BASE_LENGTH - SWITCH_ACTUATOR_LENGTH) / 2 17 | - SWITCH_ACTUATOR_TRAVEL / 2 + SWITCH_ACTUATOR_TRAVEL * position; 18 | 19 | translate([-SWITCH_ORIGIN.x, -SWITCH_ORIGIN.y, 0]) { 20 | cube([ 21 | SWITCH_BASE_WIDTH, 22 | SWITCH_BASE_LENGTH, 23 | SWITCH_BASE_HEIGHT 24 | ]); 25 | 26 | translate([ 27 | -SWITCH_ACTUATOR_WIDTH, 28 | switch_actuator_y, 29 | (SWITCH_BASE_HEIGHT - SWITCH_ACTUATOR_HEIGHT) / 2 30 | ]) { 31 | cube([ 32 | SWITCH_ACTUATOR_WIDTH + e, 33 | SWITCH_ACTUATOR_LENGTH, 34 | SWITCH_ACTUATOR_HEIGHT 35 | ]); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /openscad/switch_clutch.scad: -------------------------------------------------------------------------------- 1 | /* TODO: extract into common parts repo */ 2 | use <../../apc/openscad/rib_cavities.scad>; 3 | 4 | include ; 5 | include ; 6 | 7 | ACCESSORY_FILLET = 1; 8 | DEFAULT_TOLERANCE = .1; 9 | 10 | SWITCH_CLUTCH_GRIP_LENGTH = 10; 11 | SWITCH_CLUTCH_GRIP_HEIGHT = 7; 12 | 13 | function get_switch_clutch_length_with_travel(web_length_extension) = ( 14 | SWITCH_CLUTCH_GRIP_LENGTH + SWITCH_ACTUATOR_TRAVEL 15 | + web_length_extension * 2 16 | ); 17 | 18 | module switch_clutch( 19 | position = 0, 20 | 21 | web_available_width = 2, 22 | web_length_extension = 1, 23 | 24 | enclosure_height = 0, 25 | vertical_clearance = DEFAULT_DFM_LAYER_HEIGHT, 26 | 27 | x_clearance = .2, 28 | 29 | grip_length = SWITCH_CLUTCH_GRIP_LENGTH, 30 | grip_height = SWITCH_CLUTCH_GRIP_HEIGHT, 31 | 32 | fillet = ACCESSORY_FILLET, 33 | chamfer = .6, 34 | side_overexposure = ENCLOSURE_SIDE_OVEREXPOSURE, 35 | tolerance = DEFAULT_TOLERANCE, 36 | 37 | outer_color = undef, 38 | cavity_color = undef, 39 | 40 | show_dfm = false, 41 | quick_preview = true 42 | ) { 43 | e = .0592; 44 | 45 | web_height_extension = ( 46 | enclosure_height 47 | - grip_height 48 | - vertical_clearance * 2 49 | - ENCLOSURE_FLOOR_CEILING * 2 50 | ) / 2; 51 | web_x_gap = tolerance * 2 + x_clearance; 52 | web_width = web_available_width - web_x_gap * 2; 53 | web_length = SWITCH_CLUTCH_GRIP_LENGTH + web_length_extension * 2; 54 | web_height = grip_height + web_height_extension * 2; 55 | 56 | exposed_grip_width = ENCLOSURE_WALL + side_overexposure 57 | + (web_available_width - web_width); 58 | 59 | dfm_support_x = -web_width - exposed_grip_width + fillet; 60 | dfm_support_y = (web_length - grip_length) / 2; 61 | 62 | module _exposed_grip() { 63 | x = -web_width - exposed_grip_width; 64 | y = (web_length - grip_length) / 2; 65 | 66 | translate([x, y, web_height_extension]) { 67 | difference() { 68 | color(outer_color) { 69 | rounded_cube( 70 | [ 71 | exposed_grip_width + fillet + e, 72 | grip_length, 73 | grip_height 74 | ], 75 | quick_preview ? 0 : fillet, 76 | $fn = LOFI_ROUNDING 77 | ); 78 | } 79 | 80 | color(cavity_color) { 81 | rib_cavities( 82 | length = grip_length, 83 | height = grip_height 84 | ); 85 | } 86 | } 87 | } 88 | } 89 | 90 | module _web() { 91 | module _end(bottom) { 92 | connecting_width = web_width - tolerance; 93 | connecting_length = web_length; 94 | 95 | end_width = connecting_width - chamfer * 2; 96 | end_length = connecting_length - chamfer * 2; 97 | 98 | position = bottom 99 | ? [-web_width + chamfer, chamfer, 0] 100 | : [-web_width, 0, web_height - chamfer]; 101 | 102 | translate(position) { 103 | flat_top_rectangular_pyramid( 104 | top_width = bottom ? connecting_width : end_width, 105 | top_length = bottom ? connecting_length : end_length, 106 | bottom_width = bottom ? end_width : connecting_width, 107 | bottom_length = bottom ? end_length : connecting_length, 108 | height = chamfer 109 | ); 110 | } 111 | } 112 | 113 | _end(bottom = true); 114 | translate([-web_width, 0, chamfer - e]) { 115 | cube([ 116 | web_width - tolerance, 117 | web_length, 118 | web_height - chamfer * 2 + e 119 | ]); 120 | } 121 | _end(bottom = false); 122 | } 123 | 124 | module _actuator_cavity() { 125 | width = SWITCH_ACTUATOR_WIDTH - web_x_gap + tolerance; 126 | length = SWITCH_ACTUATOR_LENGTH + tolerance * 2; 127 | 128 | translate([-width, (web_length - length) / 2, -e]) { 129 | cube([width + e, length, web_height + e * 2]); 130 | } 131 | } 132 | 133 | module _dfm_support(brim_depth = 1) { 134 | height = web_height_extension - DEFAULT_DFM_LAYER_HEIGHT; 135 | 136 | translate([dfm_support_x, dfm_support_y, 0]) { 137 | cube([BREAKAWAY_SUPPORT_DEPTH, grip_length, height]); 138 | 139 | translate([-brim_depth, -brim_depth, 0]) { 140 | cube([ 141 | BREAKAWAY_SUPPORT_DEPTH + brim_depth * 2, 142 | grip_length + brim_depth * 2, 143 | DEFAULT_DFM_LAYER_HEIGHT 144 | ]); 145 | } 146 | } 147 | } 148 | 149 | module _dfm_cavity() { 150 | x = dfm_support_x + BREAKAWAY_SUPPORT_DEPTH; 151 | y = dfm_support_y + BREAKAWAY_SUPPORT_DEPTH + fillet; 152 | z = web_height_extension; 153 | 154 | width = exposed_grip_width - fillet - BREAKAWAY_SUPPORT_DEPTH + e; 155 | length = grip_length - BREAKAWAY_SUPPORT_DEPTH * 2 - fillet * 2; 156 | 157 | translate([x, y, z - e]) { 158 | cube([width, length, DEFAULT_DFM_LAYER_HEIGHT + e]); 159 | } 160 | } 161 | 162 | translate([ 163 | -SWITCH_ORIGIN.x - web_x_gap, 164 | -SWITCH_ORIGIN.y 165 | + SWITCH_BASE_LENGTH / 2 166 | - grip_length / 2 167 | + SWITCH_ACTUATOR_TRAVEL / 2 168 | - (1 - position) * SWITCH_ACTUATOR_TRAVEL 169 | - web_length_extension, 170 | ENCLOSURE_FLOOR_CEILING + vertical_clearance 171 | ]) { 172 | difference() { 173 | union() { 174 | _exposed_grip(); 175 | 176 | color(outer_color) { 177 | _web(); 178 | 179 | if (show_dfm) { 180 | _dfm_support(); 181 | } 182 | } 183 | } 184 | 185 | color(cavity_color) { 186 | _actuator_cavity(); 187 | } 188 | 189 | if (show_dfm) { 190 | _dfm_cavity(); 191 | } 192 | } 193 | } 194 | } 195 | 196 | * group() { 197 | switch_clutch(abs($t - .5) * 2); 198 | % switch(abs($t - .5) * 2); 199 | } 200 | -------------------------------------------------------------------------------- /openscad/utils.scad: -------------------------------------------------------------------------------- 1 | module e_translate( 2 | p = [0, 0, 0], 3 | direction = [1, 1, 1], 4 | e = .00678 5 | ) { 6 | position = $preview 7 | ? [p.x + e * direction.x, p.y + e * direction.y, p.z + e * direction.z] 8 | : p; 9 | 10 | translate(position) { 11 | children(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /print/inserts.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskitone/scout/dc6873ea70fb0c3e0f11761d9cdb9811e58bf1c1/print/inserts.pdf -------------------------------------------------------------------------------- /print/label_single-pcb-2.4-min.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 38 | 40 | 44 | 47 | 52 | OSKITONE SCOUTPCBRev A 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Scout 2 | 3 | ![Scout](assembly_guide/static/img/scout-10-838-032.gif) 4 | 5 | **scout** (_/skout/_): 6 | 7 | 1. _One sent to obtain information_ 8 | 2. _Jean Louise “Scout” Finch, of Atticus Finch_ 9 | 3. _The first synth from Oskitone to venture into the big ol' world of microcontrollers_ 10 | 11 | The Scout is: 12 | 13 | - **Beginner-friendly:** All components are through-hole (instead of surface mount) for easier soldering, and full assembly takes about 45min. Standalone, battery-powered, doesn't need a computer or external speakers to work. Fun! 14 | - **3D-Printable:** Besides the electronics and nuts and bolts, all parts are 3D-printed. And with a total width of ~160mm (about 6.3"), the Scout can fit on smaller, "Mini" (18x18x18cm) size print beds. 15 | - **Hackable:** Arduino-compatible and fully open source! Hook up an [FTDI Serial TTL-232 cable](https://www.adafruit.com/product/70) (sold separately) to update its code using the Arduino IDE. 16 | - **Minimally featured:** 1.5 octaves of keys, a volume knob, on/off switch, speaker, headphone jack. Monophonic square wave with fixed glide and octave. 17 | 18 | In addition to it being the first microcontroller-controlled instrument from Oskitone, the Scout would also make a fine introductory DIY instrument for the budding electronics hobbyist. (Some experience soldering and a general familiarity with how electricity works are recommended though!) 19 | 20 | As such, it is intentionally minimal, with the goal of the shortest possible time from starting the kit to making music with it. No MIDI/CV or other IO, as is. If you're looking for a full-featured studio instrument, this ain't it, bub! :) 21 | 22 | **Demo:** [https://vimeo.com/587660426](https://vimeo.com/587660426)
23 | **Purchase a kit:** [https://www.oskitone.com/product/scout-synth-diy-electronics-kit](https://www.oskitone.com/product/scout-synth-diy-electronics-kit)
24 | **Assembly guide:** [https://oskitone.github.io/scout/](https://oskitone.github.io/scout/)
25 | **Blog post:** [https://blog.tommy.sh/posts/scout/](https://blog.tommy.sh/posts/scout/) 26 | 27 | ## 3D Models 28 | 29 | The Scout's 3D-printed models are written in OpenSCAD. 30 | 31 | ### Dependencies 32 | 33 | Assumes `poly555` and `apc` repos are in a sibling directory and are _both up to date_ on the `main` branch. Here's how I've got it: 34 | 35 | \ oskitone 36 | \ apc 37 | \ poly555 38 | \ scout 39 | 40 | You'll also need to install the [Orbitron](https://fonts.google.com/specimen/Orbitron) font. 41 | 42 | ### Building 43 | 44 | STLs are generated with `make_stls.sh`. Run `./make_stls.sh -h` for full flags list. 45 | 46 | ### Changelog 47 | 48 | - **September 6, 2021:** Loosen knob fit on pot shaft (6cce7a7) 49 | - **August 9, 2021:** Init (9b5ffe5) 50 | 51 | ## Documentation 52 | 53 | To develop, `cd assembly_guide` then `npm run start`. 54 | 55 | 59 | 60 | ## License 61 | 62 | Designed by Oskitone. Please support future synth projects by purchasing from [Oskitone](https://www.oskitone.com/). 63 | 64 | Creative Commons Attribution/Share-Alike, all text above must be included in any redistribution. See license.txt for additional details. 65 | --------------------------------------------------------------------------------