├── BOM_and_schematic ├── miniMO_schematic.png ├── miniMO_breadboard.fzz ├── Gerber_panel_2x2 │ ├── minimo_Combined_Top.png │ ├── minimo_Combined_Bottom.png │ ├── combined.txt │ ├── combined.drl │ ├── combined.gbs │ └── combined.gts ├── license.txt ├── BOM_PCB_model.txt ├── BOM_3Dprinted_model.txt └── Gerber │ ├── miniMO.drl │ ├── miniMO-B.Mask.gbs │ ├── miniMO-F.Mask.gts │ ├── miniMO-Edge.Cuts.gm1 │ ├── miniMO-F.Cu.gtl │ └── miniMO-B.SilkS.gbo ├── 3D_parts ├── 3Dprinted_model │ ├── Structure │ │ ├── top.stl │ │ ├── battery_lid.stl │ │ ├── breadboard.stl │ │ ├── ports_holder.stl │ │ ├── shaft_neck.stl │ │ ├── battery_holder.stl │ │ └── breadboard_holder.stl │ ├── miniMO_3Dprint.jpg │ ├── Covers │ │ ├── down_cover.stl │ │ └── up_cover.stl │ ├── miniMO_3Dprint_exploded.jpg │ └── parts_description.txt ├── PCB_model │ ├── Tools │ │ ├── resistor_bend_tool.stl │ │ └── circuit_placement_jig.stl │ ├── Case │ │ ├── Covers │ │ │ ├── 2_part_case_up_cover.stl │ │ │ └── 2_part_case_down_cover.stl │ │ └── Bases │ │ │ ├── for_rigid_cover │ │ │ ├── 2_part_case_down_base.stl │ │ │ └── 2_part_case_up_base.stl │ │ │ └── for_flexible_cover │ │ │ ├── 2_part_case_up_base_for_flexible_cover.stl │ │ │ └── 2_part_case_down_base_for_flexible_cover.stl │ ├── Connectors_and_Legs │ │ ├── hex_connector.stl │ │ ├── hex_leg_10mm.stl │ │ ├── hex_connector_b.stl │ │ └── hex_legs_stabilizer.stl │ └── parts_description.txt └── license.txt ├── README.md ├── Libraries ├── readME.md └── SoftwareSerialminiMO │ ├── keywords.txt │ └── SoftwareSerialminiMO.h └── Programs ├── Display_Example ├── Display_Example.ino ├── oled.h └── oled.cpp ├── LunaMod_Generator ├── LunaMod_Generator.cpp.hex └── LunaMod_Generator.ino ├── Noise_Generator └── Noise_Generator.ino ├── Delay └── Delay.ino ├── Noise_Random_Generator └── Noise_Random_Generator.ino ├── Low_Power_Beacon └── Low_Power_Beacon.ino ├── DCO └── DCO.cpp.hex ├── LPF └── LPF.ino ├── Algorithmic_Generator └── Algorithmic_Generator.ino ├── Phaser └── Phaser.ino ├── Tuned_Controller └── Tuned_Controller.ino └── ADSR └── ADSR.ino /BOM_and_schematic/miniMO_schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/BOM_and_schematic/miniMO_schematic.png -------------------------------------------------------------------------------- /BOM_and_schematic/miniMO_breadboard.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/BOM_and_schematic/miniMO_breadboard.fzz -------------------------------------------------------------------------------- /3D_parts/3Dprinted_model/Structure/top.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/3D_parts/3Dprinted_model/Structure/top.stl -------------------------------------------------------------------------------- /3D_parts/3Dprinted_model/miniMO_3Dprint.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/3D_parts/3Dprinted_model/miniMO_3Dprint.jpg -------------------------------------------------------------------------------- /3D_parts/3Dprinted_model/Covers/down_cover.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/3D_parts/3Dprinted_model/Covers/down_cover.stl -------------------------------------------------------------------------------- /3D_parts/3Dprinted_model/Covers/up_cover.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/3D_parts/3Dprinted_model/Covers/up_cover.stl -------------------------------------------------------------------------------- /3D_parts/PCB_model/Tools/resistor_bend_tool.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/3D_parts/PCB_model/Tools/resistor_bend_tool.stl -------------------------------------------------------------------------------- /3D_parts/3Dprinted_model/Structure/battery_lid.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/3D_parts/3Dprinted_model/Structure/battery_lid.stl -------------------------------------------------------------------------------- /3D_parts/3Dprinted_model/Structure/breadboard.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/3D_parts/3Dprinted_model/Structure/breadboard.stl -------------------------------------------------------------------------------- /3D_parts/3Dprinted_model/Structure/ports_holder.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/3D_parts/3Dprinted_model/Structure/ports_holder.stl -------------------------------------------------------------------------------- /3D_parts/3Dprinted_model/Structure/shaft_neck.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/3D_parts/3Dprinted_model/Structure/shaft_neck.stl -------------------------------------------------------------------------------- /3D_parts/PCB_model/Tools/circuit_placement_jig.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/3D_parts/PCB_model/Tools/circuit_placement_jig.stl -------------------------------------------------------------------------------- /3D_parts/3Dprinted_model/Structure/battery_holder.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/3D_parts/3Dprinted_model/Structure/battery_holder.stl -------------------------------------------------------------------------------- /3D_parts/3Dprinted_model/miniMO_3Dprint_exploded.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/3D_parts/3Dprinted_model/miniMO_3Dprint_exploded.jpg -------------------------------------------------------------------------------- /3D_parts/3Dprinted_model/Structure/breadboard_holder.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/3D_parts/3Dprinted_model/Structure/breadboard_holder.stl -------------------------------------------------------------------------------- /3D_parts/PCB_model/Case/Covers/2_part_case_up_cover.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/3D_parts/PCB_model/Case/Covers/2_part_case_up_cover.stl -------------------------------------------------------------------------------- /3D_parts/PCB_model/Connectors_and_Legs/hex_connector.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/3D_parts/PCB_model/Connectors_and_Legs/hex_connector.stl -------------------------------------------------------------------------------- /3D_parts/PCB_model/Connectors_and_Legs/hex_leg_10mm.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/3D_parts/PCB_model/Connectors_and_Legs/hex_leg_10mm.stl -------------------------------------------------------------------------------- /3D_parts/PCB_model/Case/Covers/2_part_case_down_cover.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/3D_parts/PCB_model/Case/Covers/2_part_case_down_cover.stl -------------------------------------------------------------------------------- /3D_parts/PCB_model/Connectors_and_Legs/hex_connector_b.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/3D_parts/PCB_model/Connectors_and_Legs/hex_connector_b.stl -------------------------------------------------------------------------------- /BOM_and_schematic/Gerber_panel_2x2/minimo_Combined_Top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/BOM_and_schematic/Gerber_panel_2x2/minimo_Combined_Top.png -------------------------------------------------------------------------------- /BOM_and_schematic/Gerber_panel_2x2/minimo_Combined_Bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/BOM_and_schematic/Gerber_panel_2x2/minimo_Combined_Bottom.png -------------------------------------------------------------------------------- /3D_parts/PCB_model/Connectors_and_Legs/hex_legs_stabilizer.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/3D_parts/PCB_model/Connectors_and_Legs/hex_legs_stabilizer.stl -------------------------------------------------------------------------------- /3D_parts/PCB_model/Case/Bases/for_rigid_cover/2_part_case_down_base.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/3D_parts/PCB_model/Case/Bases/for_rigid_cover/2_part_case_down_base.stl -------------------------------------------------------------------------------- /3D_parts/PCB_model/Case/Bases/for_rigid_cover/2_part_case_up_base.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/3D_parts/PCB_model/Case/Bases/for_rigid_cover/2_part_case_up_base.stl -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # miniMO 2 | Programmable mini Synthesizer Module
3 | 4 | https://minimosynth.com/ 5 | 6 | we've got a forum! 7 | 8 | https://www.minimosynth.com/forum/ 9 | 10 | 11 | -------------------------------------------------------------------------------- /3D_parts/PCB_model/Case/Bases/for_flexible_cover/2_part_case_up_base_for_flexible_cover.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/3D_parts/PCB_model/Case/Bases/for_flexible_cover/2_part_case_up_base_for_flexible_cover.stl -------------------------------------------------------------------------------- /3D_parts/PCB_model/Case/Bases/for_flexible_cover/2_part_case_down_base_for_flexible_cover.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enveloop/miniMO/HEAD/3D_parts/PCB_model/Case/Bases/for_flexible_cover/2_part_case_down_base_for_flexible_cover.stl -------------------------------------------------------------------------------- /3D_parts/license.txt: -------------------------------------------------------------------------------- 1 | /* 2 | //************************ 3 | //* miniMO 3D Parts * 4 | //* 2017 by enveloop * 5 | //************************ 6 | // 7 | http://www.minimosynth.com/ 8 | CC BY 4.0 9 | Licensed under a Creative Commons Attribution 4.0 International license: 10 | http://creativecommons.org/licenses/by/4.0/ 11 | // 12 | */ -------------------------------------------------------------------------------- /BOM_and_schematic/license.txt: -------------------------------------------------------------------------------- 1 | /* 2 | //************************ 3 | //* miniMO Schematics * 4 | //* 2017 by enveloop * 5 | //************************ 6 | // 7 | http://www.minimosynth.com/ 8 | CC BY 4.0 9 | Licensed under a Creative Commons Attribution 4.0 International license: 10 | http://creativecommons.org/licenses/by/4.0/ 11 | // 12 | */ -------------------------------------------------------------------------------- /Libraries/readME.md: -------------------------------------------------------------------------------- 1 | CONTENTS 2 | 3 | -SoftwareSerialminiMO 4 | 5 | Needed for: MIDI programs 6 | 7 | Description: A version of SoftwareSerial slightly modified 8 | so that it won't interfere with the MIDI programs' own interrupts 9 | 10 | How to Install: 11 | 12 | Locate your Arduino folder and copy the library folder to 13 | 14 | Arduino/hardware/tiny/avr/libraries 15 | 16 | Restart the Arduino IDE 17 | 18 | -------------------------------------------------------------------------------- /BOM_and_schematic/BOM_PCB_model.txt: -------------------------------------------------------------------------------- 1 | miniMO PCB - Bill of Materials 2 | 3 | 4 | Attiny85 | 1x | 5 | Battery Holder cr2032 | 1x | 6 | Socket 6pin, Female | 1x | 7 | Pin header 2 pin, Male | 4x | 8 | Pin Header 3 pin, Male | 1x | 9 | Resistor 1M | 1x | 10 | Resistor 10K | 3x | 11 | Resistor 750 | 1x | 12 | Resistor 470 | 1x | 13 | Capacitor 0.1uF | 3x | 14 | LED, red | 1x | 15 | Push Button | 1x | 16 | Potentiometer 10K | 1x | 17 | Jumper 1x2, Female | 2x | 18 | 19 | 20 | -------------------------------------------------------------------------------- /3D_parts/3Dprinted_model/parts_description.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 3D Printed Model 4 | 5 | /Structure 6 | 7 | In order of assembly (bottom to top): 8 | 9 | *battery_holder 10 | *battery_lid 11 | *breadboard_holder 12 | *breadboard 13 | *ports_holder 14 | *top 15 | *shaft neck 16 | 17 | Settings: 18 | All parts Rigid filament (PLA), layer height 0.3 mm, default speed 40 mm/s 19 | Head diameter 0.40 EXCEPT for the breadboard, which needs a 0.25 or less 20 | 21 | /Covers 22 | 23 | *down_cover 24 | *up_cover 25 | 26 | Settings: same as above -------------------------------------------------------------------------------- /Libraries/SoftwareSerialminiMO/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map for SoftwareSerial 3 | # (formerly NewSoftSerial) 4 | ####################################### 5 | 6 | ####################################### 7 | # Datatypes (KEYWORD1) 8 | ####################################### 9 | 10 | SoftwareSerial KEYWORD1 11 | 12 | ####################################### 13 | # Methods and Functions (KEYWORD2) 14 | ####################################### 15 | 16 | begin KEYWORD2 17 | end KEYWORD2 18 | read KEYWORD2 19 | write KEYWORD2 20 | available KEYWORD2 21 | isListening KEYWORD2 22 | overflow KEYWORD2 23 | flush KEYWORD2 24 | listen KEYWORD2 25 | peek KEYWORD2 26 | 27 | ####################################### 28 | # Constants (LITERAL1) 29 | ####################################### 30 | 31 | -------------------------------------------------------------------------------- /BOM_and_schematic/BOM_3Dprinted_model.txt: -------------------------------------------------------------------------------- 1 | miniMO 3D Printed - Bill of Materials 2 | 3 | Attiny85 | 1x | 4 | Socket 5pin, Female | 1x | 5 | Pin header 2 pin, Male | 4x | 6 | Resistor 1M | 1x | 7 | Resistor 10K | 3x | 8 | Resistor 100 | 1x | 9 | Resistor 470 | 1x | 10 | Capacitor 0.1uF | 3x | 11 | LED, red | 1x | 12 | Push Button | 1x |NINIGI TACT-69K-F 13 | Potentiometer 10K | 1x |ACP CA9MV-10K 14 | Potentiometer knob | 1x |ACP CA9MA 9006 15 | Jumper 1x2, Female | 2x |CAB 9 GS 16 | 17 | Also - 18 | 19 | Single core wire to make breadboard jumpers (or a premade set), 20 | 11cm of stranded wire, 21 | 1 male to male jumper cable for the circuit, 22 | 5 male-to-male jumper cables to connect to an Arduino, 23 | Female-to-Female jumper cables to connect to other miniMOs, 24 | 2 pin Female header - to - (audio connector of your choice) to connect with audio equipment. -------------------------------------------------------------------------------- /BOM_and_schematic/Gerber_panel_2x2/combined.txt: -------------------------------------------------------------------------------- 1 | % 2 | M48 3 | METRIC,000.000 4 | T01C0.50 5 | % 6 | T01 7 | X023881Y040513 8 | X022881Y040513 9 | X021881Y040513 10 | X020881Y040513 11 | X019881Y040513 12 | X018881Y040513 13 | X019181Y042113 14 | X020181Y042113 15 | X021181Y042113 16 | X022181Y042113 17 | X023181Y042113 18 | X024181Y042113 19 | X040849Y058734 20 | X040849Y059734 21 | X040849Y060734 22 | X040849Y061734 23 | X040849Y062734 24 | X040849Y063734 25 | X042549Y064280 26 | X042549Y063280 27 | X042549Y062280 28 | X042549Y061280 29 | X042549Y060280 30 | X042549Y059280 31 | X064075Y040486 32 | X063075Y040486 33 | X062075Y040486 34 | X061075Y040486 35 | X060075Y040486 36 | X059075Y040486 37 | X059761Y042186 38 | X060761Y042186 39 | X061761Y042186 40 | X062761Y042186 41 | X063761Y042186 42 | X064761Y042186 43 | X040849Y018634 44 | X040849Y019634 45 | X040849Y020634 46 | X040849Y021634 47 | X040849Y022634 48 | X040849Y023634 49 | X042650Y024080 50 | X042650Y023080 51 | X042650Y022080 52 | X042650Y021080 53 | X042650Y020080 54 | X042650Y019080 55 | M30 -------------------------------------------------------------------------------- /BOM_and_schematic/Gerber/miniMO.drl: -------------------------------------------------------------------------------- 1 | M48 2 | INCH,TZ 3 | T1C0.013 4 | T2C0.031 5 | T3C0.032 6 | T4C0.039 7 | T5C0.039 8 | T6C0.040 9 | T7C0.098 10 | % 11 | G90 12 | G05 13 | T1 14 | X46400Y-47325 15 | X49975Y-47200 16 | X49975Y-48125 17 | T2 18 | X44200Y-44800 19 | X44200Y-45800 20 | X44200Y-46800 21 | X44200Y-47800 22 | X44500Y-50700 23 | X47200Y-44800 24 | X47200Y-45800 25 | X47200Y-46800 26 | X47200Y-47800 27 | X47200Y-49500 28 | X47200Y-50800 29 | T3 30 | X44500Y-49716 31 | X46216Y-49500 32 | X46216Y-50800 33 | X46689Y-54631 34 | X46689Y-55773 35 | X48657Y-50340 36 | X48657Y-51443 37 | X48736Y-44041 38 | X48736Y-46049 39 | X49689Y-54631 40 | X49689Y-55773 41 | X51657Y-50340 42 | X51657Y-51443 43 | X51736Y-44041 44 | X51736Y-46049 45 | T4 46 | X48346Y-44986 47 | X48346Y-52860 48 | X48858Y-48214 49 | X50729Y-47230 50 | X50729Y-49198 51 | T5 52 | X43681Y-51974 53 | X43681Y-53746 54 | X46241Y-51974 55 | X46241Y-53746 56 | X54157Y-44277 57 | X55157Y-44277 58 | T6 59 | X42900Y-45500 60 | X42900Y-46500 61 | X42900Y-49500 62 | X42900Y-50500 63 | X46000Y-42600 64 | X47000Y-42600 65 | X50000Y-42600 66 | X51000Y-42600 67 | X51386Y-52795 68 | X52386Y-52795 69 | X53386Y-52795 70 | X53701Y-45891 71 | X53701Y-46891 72 | X53701Y-47891 73 | X53701Y-48891 74 | X53701Y-49891 75 | X53701Y-50891 76 | T7 77 | X43071Y-42624 78 | X43071Y-55222 79 | X55669Y-42624 80 | X55669Y-55222 81 | T0 82 | M30 83 | -------------------------------------------------------------------------------- /3D_parts/PCB_model/parts_description.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | PCB MODEL 4 | 5 | /Case 6 | /Bases 7 | 8 | Print in rigid filament (PLA) 9 | There are two sets, for rigid and flexible covers 10 | 11 | Settings: head diameter 0.4 mm, layer height 0.3 mm, default speed 50 mm/s 12 | 13 | /Covers 14 | 15 | Print either in rigid or flexible filament (choose the bases accordingly) 16 | 17 | *Rigid (PLA) 18 | Settings: head diameter 0.4 mm, layer height 0.3 mm, default speed 50 mm/s 19 | 20 | *Flexible 21 | Settings: head diameter 0.4 mm, layer height 0.3 mm, default speed 20 mm/s, Retraction 1.20, coasting 0.20 22 | 23 | /Connectors_and_Legs 24 | 25 | A set of useful parts if you are using the modules without a case 26 | 27 | *hex_leg_10mm.stl: hexagonal leg, 10 mm tall 28 | 29 | Settings: head diameter 0.4 mm, layer height 0.2 mm, default speed 30 mm/s 30 | 31 | *hex_connector.stl: attaches to the hexagonal legs to group the modules together 32 | 33 | *hex_connector_b.stl: same as above, with the hexes rotated 90 degrees 34 | 35 | *hex_legs_stabilizer: locks the legs' rotation 36 | 37 | Settings: head diameter 0.4 mm, layer height 0.2 mm, default speed 50 mm/s 38 | 39 | /Tools 40 | 41 | Parts that help with PCB soldering. The resistor tool allows you to bend the legs to the right measures 42 | 43 | *circuit_placement_jig.stl 44 | 45 | Keeps everything in place while soldering 46 | Settings: layer height 0.2 mm; print with two perimeters and fairly solid infill 47 | 48 | *resistor_bend_tool.stl 49 | 50 | Bends the resistors' legs to match the PCB's distance 51 | 52 | -------------------------------------------------------------------------------- /BOM_and_schematic/Gerber/miniMO-B.Mask.gbs: -------------------------------------------------------------------------------- 1 | G04 #@! TF.FileFunction,Soldermask,Bot* 2 | %FSLAX46Y46*% 3 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 4 | G04 Created by KiCad (PCBNEW 4.0.1-stable) date 10/18/2017 12:48:17 AM* 5 | %MOMM*% 6 | G01* 7 | G04 APERTURE LIST* 8 | %ADD10C,0.100000*% 9 | %ADD11R,1.700000X1.700000*% 10 | %ADD12C,1.700000*% 11 | %ADD13R,2.400000X2.400000*% 12 | %ADD14C,2.400000*% 13 | %ADD15O,2.000000X2.000000*% 14 | %ADD16R,2.432000X2.432000*% 15 | %ADD17O,2.432000X2.432000*% 16 | %ADD18C,2.398980*% 17 | %ADD19R,2.432000X2.127200*% 18 | %ADD20O,2.432000X2.127200*% 19 | %ADD21R,2.127200X2.432000*% 20 | %ADD22O,2.127200X2.432000*% 21 | G04 APERTURE END LIST* 22 | D10* 23 | D11* 24 | X119888000Y-125730000D03* 25 | D12* 26 | X117388000Y-125730000D03* 27 | D11* 28 | X113030000Y-128778000D03* 29 | D12* 30 | X113030000Y-126278000D03* 31 | D11* 32 | X119888000Y-129032000D03* 33 | D12* 34 | X117388000Y-129032000D03* 35 | D13* 36 | X140100000Y-112464000D03* 37 | D14* 38 | X137560000Y-112464000D03* 39 | D15* 40 | X112268000Y-113792000D03* 41 | X112268000Y-116332000D03* 42 | X112268000Y-118872000D03* 43 | X112268000Y-121412000D03* 44 | X119888000Y-121412000D03* 45 | X119888000Y-118872000D03* 46 | X119888000Y-116332000D03* 47 | X119888000Y-113792000D03* 48 | D16* 49 | X119380000Y-108204000D03* 50 | D17* 51 | X116840000Y-108204000D03* 52 | D16* 53 | X129540000Y-108204000D03* 54 | D17* 55 | X127000000Y-108204000D03* 56 | D16* 57 | X108966000Y-125730000D03* 58 | D17* 59 | X108966000Y-128270000D03* 60 | D16* 61 | X108966000Y-115570000D03* 62 | D17* 63 | X108966000Y-118110000D03* 64 | D18* 65 | X123590000Y-130664000D03* 66 | X131210000Y-130664000D03* 67 | X118590000Y-138764000D03* 68 | X126210000Y-138764000D03* 69 | X126210000Y-141664000D03* 70 | X118590000Y-141664000D03* 71 | X123790000Y-111864000D03* 72 | X131410000Y-111864000D03* 73 | X131210000Y-127864000D03* 74 | X123590000Y-127864000D03* 75 | X131410000Y-116964000D03* 76 | X123790000Y-116964000D03* 77 | X117451200Y-132013560D03* 78 | X110948800Y-136514440D03* 79 | X117451200Y-136514440D03* 80 | X110948800Y-132013560D03* 81 | D19* 82 | X136400000Y-129264000D03* 83 | D20* 84 | X136400000Y-126724000D03* 85 | X136400000Y-124184000D03* 86 | X136400000Y-121644000D03* 87 | X136400000Y-119104000D03* 88 | X136400000Y-116564000D03* 89 | D14* 90 | X122800000Y-134264000D03* 91 | X122800000Y-114264000D03* 92 | D18* 93 | X128851260Y-124963360D03* 94 | X124100000Y-122464000D03* 95 | X128851260Y-119964640D03* 96 | D21* 97 | X135600000Y-134100000D03* 98 | D22* 99 | X133060000Y-134100000D03* 100 | X130520000Y-134100000D03* 101 | M02* 102 | -------------------------------------------------------------------------------- /BOM_and_schematic/Gerber/miniMO-F.Mask.gts: -------------------------------------------------------------------------------- 1 | G04 #@! TF.FileFunction,Soldermask,Top* 2 | %FSLAX46Y46*% 3 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 4 | G04 Created by KiCad (PCBNEW 4.0.1-stable) date 10/18/2017 12:48:17 AM* 5 | %MOMM*% 6 | G01* 7 | G04 APERTURE LIST* 8 | %ADD10C,0.100000*% 9 | %ADD11R,1.700000X1.700000*% 10 | %ADD12C,1.700000*% 11 | %ADD13R,2.400000X2.400000*% 12 | %ADD14C,2.400000*% 13 | %ADD15O,2.000000X2.000000*% 14 | %ADD16R,2.432000X2.432000*% 15 | %ADD17O,2.432000X2.432000*% 16 | %ADD18C,2.398980*% 17 | %ADD19R,2.432000X2.127200*% 18 | %ADD20O,2.432000X2.127200*% 19 | %ADD21R,2.127200X2.432000*% 20 | %ADD22O,2.127200X2.432000*% 21 | G04 APERTURE END LIST* 22 | D10* 23 | D11* 24 | X119888000Y-125730000D03* 25 | D12* 26 | X117388000Y-125730000D03* 27 | D11* 28 | X113030000Y-128778000D03* 29 | D12* 30 | X113030000Y-126278000D03* 31 | D11* 32 | X119888000Y-129032000D03* 33 | D12* 34 | X117388000Y-129032000D03* 35 | D13* 36 | X140100000Y-112464000D03* 37 | D14* 38 | X137560000Y-112464000D03* 39 | D15* 40 | X112268000Y-113792000D03* 41 | X112268000Y-116332000D03* 42 | X112268000Y-118872000D03* 43 | X112268000Y-121412000D03* 44 | X119888000Y-121412000D03* 45 | X119888000Y-118872000D03* 46 | X119888000Y-116332000D03* 47 | X119888000Y-113792000D03* 48 | D16* 49 | X119380000Y-108204000D03* 50 | D17* 51 | X116840000Y-108204000D03* 52 | D16* 53 | X129540000Y-108204000D03* 54 | D17* 55 | X127000000Y-108204000D03* 56 | D16* 57 | X108966000Y-125730000D03* 58 | D17* 59 | X108966000Y-128270000D03* 60 | D16* 61 | X108966000Y-115570000D03* 62 | D17* 63 | X108966000Y-118110000D03* 64 | D18* 65 | X123590000Y-130664000D03* 66 | X131210000Y-130664000D03* 67 | X118590000Y-138764000D03* 68 | X126210000Y-138764000D03* 69 | X126210000Y-141664000D03* 70 | X118590000Y-141664000D03* 71 | X123790000Y-111864000D03* 72 | X131410000Y-111864000D03* 73 | X131210000Y-127864000D03* 74 | X123590000Y-127864000D03* 75 | X131410000Y-116964000D03* 76 | X123790000Y-116964000D03* 77 | X117451200Y-132013560D03* 78 | X110948800Y-136514440D03* 79 | X117451200Y-136514440D03* 80 | X110948800Y-132013560D03* 81 | D19* 82 | X136400000Y-129264000D03* 83 | D20* 84 | X136400000Y-126724000D03* 85 | X136400000Y-124184000D03* 86 | X136400000Y-121644000D03* 87 | X136400000Y-119104000D03* 88 | X136400000Y-116564000D03* 89 | D14* 90 | X122800000Y-134264000D03* 91 | X122800000Y-114264000D03* 92 | D18* 93 | X128851260Y-124963360D03* 94 | X124100000Y-122464000D03* 95 | X128851260Y-119964640D03* 96 | D21* 97 | X135600000Y-134100000D03* 98 | D22* 99 | X133060000Y-134100000D03* 100 | X130520000Y-134100000D03* 101 | M02* 102 | -------------------------------------------------------------------------------- /BOM_and_schematic/Gerber/miniMO-Edge.Cuts.gm1: -------------------------------------------------------------------------------- 1 | G04 #@! TF.FileFunction,Profile,NP* 2 | %FSLAX46Y46*% 3 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 4 | G04 Created by KiCad (PCBNEW 4.0.1-stable) date 10/18/2017 12:48:17 AM* 5 | %MOMM*% 6 | G01* 7 | G04 APERTURE LIST* 8 | %ADD10C,0.100000*% 9 | %ADD11C,0.150000*% 10 | G04 APERTURE END LIST* 11 | D10* 12 | D11* 13 | X146066666Y-143264000D02* 14 | G75* 15 | G03X146066666Y-143264000I-1666666J0D01* 16 | G01* 17 | X141900000Y-143264000D02* 18 | X146900000Y-143264000D01* 19 | X144400000Y-140764000D02* 20 | X144400000Y-145764000D01* 21 | X108066666Y-143264000D02* 22 | G75* 23 | G03X108066666Y-143264000I-1666666J0D01* 24 | G01* 25 | X103900000Y-143264000D02* 26 | X108900000Y-143264000D01* 27 | X106400000Y-140764000D02* 28 | X106400000Y-145764000D01* 29 | X146066666Y-105264000D02* 30 | G75* 31 | G03X146066666Y-105264000I-1666666J0D01* 32 | G01* 33 | X141900000Y-105264000D02* 34 | X146900000Y-105264000D01* 35 | X144400000Y-102764000D02* 36 | X144400000Y-107764000D01* 37 | X108066666Y-105264000D02* 38 | G75* 39 | G03X108066666Y-105264000I-1666666J0D01* 40 | G01* 41 | X103900000Y-105264000D02* 42 | X108900000Y-105264000D01* 43 | X106400000Y-102764000D02* 44 | X106400000Y-107764000D01* 45 | X106400000Y-140264000D02* 46 | X106400000Y-108264000D01* 47 | X141400000Y-143264000D02* 48 | X109400000Y-143264000D01* 49 | X144400000Y-108264000D02* 50 | X144400000Y-140264000D01* 51 | X109400000Y-105264000D02* 52 | X141400000Y-105264000D01* 53 | X106400000Y-140264000D02* 54 | G75* 55 | G03X109400000Y-143264000I3000000J0D01* 56 | G01* 57 | X141400000Y-143264000D02* 58 | G75* 59 | G03X144400000Y-140264000I0J3000000D01* 60 | G01* 61 | X144400000Y-108264000D02* 62 | G75* 63 | G03X141400000Y-105264000I-3000000J0D01* 64 | G01* 65 | X109400000Y-105264000D02* 66 | G75* 67 | G03X106400000Y-108264000I0J-3000000D01* 68 | G01* 69 | X111066666Y-108264000D02* 70 | G75* 71 | G03X111066666Y-108264000I-1666666J0D01* 72 | G01* 73 | X106900000Y-108264000D02* 74 | X111900000Y-108264000D01* 75 | X109400000Y-105764000D02* 76 | X109400000Y-110764000D01* 77 | X143066666Y-108264000D02* 78 | G75* 79 | G03X143066666Y-108264000I-1666666J0D01* 80 | G01* 81 | X138900000Y-108264000D02* 82 | X143900000Y-108264000D01* 83 | X141400000Y-105764000D02* 84 | X141400000Y-110764000D01* 85 | X143066666Y-140264000D02* 86 | G75* 87 | G03X143066666Y-140264000I-1666666J0D01* 88 | G01* 89 | X138900000Y-140264000D02* 90 | X143900000Y-140264000D01* 91 | X141400000Y-137764000D02* 92 | X141400000Y-142764000D01* 93 | X111066666Y-140264000D02* 94 | G75* 95 | G03X111066666Y-140264000I-1666666J0D01* 96 | G01* 97 | X106900000Y-140264000D02* 98 | X111900000Y-140264000D01* 99 | X109400000Y-137764000D02* 100 | X109400000Y-142764000D01* 101 | M02* 102 | -------------------------------------------------------------------------------- /Programs/Display_Example/Display_Example.ino: -------------------------------------------------------------------------------- 1 | /* 2 | //****************************** 3 | //* miniMO DISPLAY EXAMPLE * 4 | //* 2017-18 by enveloop * 5 | //****************************** 6 | 7 | // 8 | http://www.minimosynth.com/ 9 | CC BY 4.0 10 | Licensed under a Creative Commons Attribution 4.0 International license: 11 | http://creativecommons.org/licenses/by/4.0/ 12 | // 13 | 14 | CONCEPT 15 | 16 | This is an example program to show how to work with OLED SSD1306 I2C Screens. 17 | The program reads inputs attached to I/O 3, shows the readings on the screen, 18 | and toggles the outputs ON or OFF depending on the value; 19 | this last behavior will work even if the screen is not connected. 20 | The program also detects button clicks, and shows a text accordingly. 21 | 22 | I/O 23 | 1&2: Outputs (ON or OFF) 24 | 3: Input 25 | 4: not used 26 | 27 | SCREEN SETUP - HARDWARE 28 | 29 | -Locate miniMO's programming header, under the LED light 30 | -Note the vertical writing next to the pins, from bottom to top: GND, SCK, MI, MO, RST, VCC 31 | -Connect the Screen's VCC to the header's VCC 32 | -Connect the screen's GND to the header's GND 33 | -Connect the screen's SCL to miniMO's MO 34 | -Connect the screen's SDA to miniMO's SCK 35 | -With the screen connected, 36 | -Load a battery in miniMO's holder 37 | -Connect all three pins of the Battery-External male header AT ONCE 38 | -The easiest way to do this is to get a three pin female header and wire or solder its terminals together 39 | 40 | SCREEN SETUP - SOFTWARE 41 | 42 | In oled.h , set the width, height, and orientation of your screen 43 | 44 | OPERATION 45 | 46 | Knob: Adjust the readings according to the input. Range: 0 - 255 47 | -If you'd prefer a wider range (0 to 1023), simply remove " >>2 " from line 79 48 | Click: Shows the text "PUSH" on screen while clicking 49 | 50 | */ 51 | 52 | #include 53 | #include "oled.h" 54 | 55 | OLED oled = OLED(); 56 | byte valueDisplayLine = 3; 57 | char inputChar[] = "0000"; 58 | 59 | //external input smoothing 60 | const byte numReadings = 5; //smoothing factor 61 | int readings[numReadings]; // stores readings from the analog input 62 | byte readIndex = 0; // the index of the current reading 63 | int total = 0; // the running total 64 | static int smoothRead; 65 | 66 | void setup() 67 | { 68 | delay(40); 69 | oled.init(); 70 | oled.fillscreen(0x00); // clear screen 71 | oled.char_f6x8(0, 0, "INPUT"); 72 | oled.char_f6x8(0, 1, "READING"); 73 | delay(100); 74 | 75 | pinMode(1, INPUT); //Digital input (push button) 76 | pinMode(3, INPUT); //Analog input - potentiometer and I/O 3 77 | pinMode(4, OUTPUT); //Outputs 1 and 2 78 | 79 | } 80 | 81 | void loop() 82 | { 83 | smoothRead = inputRead(3); //take an averaged reading and store it in a variable 84 | itoa(smoothRead, inputChar, 10); //convert the stored reading, in base 10, to ascii, and store the result it in var inputChar 85 | oled.fillLine(valueDisplayLine,0x00); //clear the line 86 | oled.char_f6x8(10, valueDisplayLine, inputChar); //print the reading 87 | 88 | if (smoothRead > 200) digitalWrite(4, 255); //activate the output depending on the reading 89 | else digitalWrite(4, 0); 90 | 91 | if (digitalRead(1) == HIGH) 92 | { 93 | oled.char_f6x8(30, 0, "PUSH"); 94 | //tone(4, 440, 10); 95 | } 96 | else 97 | { 98 | oled.char_f6x8(30, 0, " "); 99 | } 100 | delay(500); //interval between readings 101 | } 102 | 103 | int inputRead(byte pin) { //with averaging 104 | total = total - readings[readIndex]; 105 | readings[readIndex] = analogRead(pin) >> 2; // right shifting by 2 to get values between 0 and 255 (0-1023/2^2) 106 | total = total + readings[readIndex]; 107 | readIndex = readIndex + 1; 108 | if (readIndex >= numReadings) readIndex = 0; 109 | return total / numReadings; 110 | } 111 | -------------------------------------------------------------------------------- /Libraries/SoftwareSerialminiMO/SoftwareSerialminiMO.h: -------------------------------------------------------------------------------- 1 | /* 2 | SoftwareSerial.h (formerly NewSoftSerial.h) - 3 | Multi-instance software serial library for Arduino/Wiring 4 | -- Interrupt-driven receive and other improvements by ladyada 5 | (http://ladyada.net) 6 | -- Tuning, circular buffer, derivation from class Print/Stream, 7 | multi-instance support, porting to 8MHz processors, 8 | various optimizations, PROGMEM delay tables, inverse logic and 9 | direct port writing by Mikal Hart (http://www.arduiniana.org) 10 | -- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com) 11 | -- 20MHz processor support by Garrett Mace (http://www.macetech.com) 12 | -- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/) 13 | 14 | This library is free software; you can redistribute it and/or 15 | modify it under the terms of the GNU Lesser General Public 16 | License as published by the Free Software Foundation; either 17 | version 2.1 of the License, or (at your option) any later version. 18 | 19 | This library is distributed in the hope that it will be useful, 20 | but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 | Lesser General Public License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public 25 | License along with this library; if not, write to the Free Software 26 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 27 | 28 | The latest version of this library can always be found at 29 | http://arduiniana.org. 30 | */ 31 | 32 | #ifndef SoftwareSerial_h 33 | #define SoftwareSerial_h 34 | 35 | #include 36 | #include 37 | 38 | /****************************************************************************** 39 | * Definitions 40 | ******************************************************************************/ 41 | 42 | #define _SS_MAX_RX_BUFF 64 // RX buffer size 43 | #ifndef GCC_VERSION 44 | #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) 45 | #endif 46 | 47 | class SoftwareSerial : public Stream 48 | { 49 | private: 50 | // per object data 51 | uint8_t _receivePin; 52 | uint8_t _receiveBitMask; 53 | volatile uint8_t *_receivePortRegister; 54 | uint8_t _transmitBitMask; 55 | volatile uint8_t *_transmitPortRegister; 56 | 57 | uint16_t _rx_delay_centering; 58 | uint16_t _rx_delay_intrabit; 59 | uint16_t _rx_delay_stopbit; 60 | uint16_t _tx_delay; 61 | 62 | uint16_t _buffer_overflow:1; 63 | uint16_t _inverse_logic:1; 64 | 65 | // static data 66 | static char _receive_buffer[_SS_MAX_RX_BUFF]; 67 | static volatile uint8_t _receive_buffer_tail; 68 | static volatile uint8_t _receive_buffer_head; 69 | static SoftwareSerial *active_object; 70 | 71 | // private methods 72 | void recv(); 73 | uint8_t rx_pin_read(); 74 | void tx_pin_write(uint8_t pin_state); 75 | void setTX(uint8_t transmitPin); 76 | void setRX(uint8_t receivePin); 77 | 78 | // private static method for timing 79 | static inline void tunedDelay(uint16_t delay); 80 | 81 | public: 82 | // public methods 83 | SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false); 84 | ~SoftwareSerial(); 85 | void begin(long speed); 86 | bool listen(); 87 | void end(); 88 | bool isListening() { return this == active_object; } 89 | bool overflow() { bool ret = _buffer_overflow; _buffer_overflow = false; return ret; } 90 | int peek(); 91 | void handle_interrupt(); 92 | 93 | virtual size_t write(uint8_t byte); 94 | virtual int read(); 95 | virtual int available(); 96 | virtual void flush(); 97 | 98 | using Print::write; 99 | 100 | // public only for easy access by interrupt handlers 101 | //static inline void handle_interrupt(); 102 | 103 | }; 104 | 105 | // Arduino 0012 workaround 106 | #undef int 107 | #undef char 108 | #undef long 109 | #undef byte 110 | #undef float 111 | #undef abs 112 | #undef round 113 | 114 | #endif 115 | -------------------------------------------------------------------------------- /BOM_and_schematic/Gerber_panel_2x2/combined.drl: -------------------------------------------------------------------------------- 1 | % 2 | M48 3 | METRIC,000.000 4 | T01C0.33 5 | T02C0.79 6 | T03C0.81 7 | T04C0.99 8 | T05C0.99 9 | T06C1.02 10 | T07C2.49 11 | % 12 | T01 13 | X029144Y017205 14 | X020063Y016888 15 | X020063Y019237 16 | X029144Y057305 17 | X020063Y056987 18 | X020063Y059337 19 | X054355Y025294 20 | X063436Y025612 21 | X063436Y023262 22 | X054256Y065494 23 | X063336Y065812 24 | X063336Y063462 25 | T02 26 | X034732Y010792 27 | X034732Y013332 28 | X034732Y015872 29 | X034732Y018412 30 | X033970Y025777 31 | X027112Y010792 32 | X027112Y013332 33 | X027112Y015872 34 | X027112Y018412 35 | X027112Y022730 36 | X027112Y026032 37 | X034732Y050891 38 | X034732Y053431 39 | X034732Y055971 40 | X034732Y058511 41 | X033970Y065877 42 | X027112Y050891 43 | X027112Y053431 44 | X027112Y055971 45 | X027112Y058511 46 | X027112Y062829 47 | X027112Y066131 48 | X048767Y031708 49 | X048767Y029168 50 | X048767Y026628 51 | X048767Y024087 52 | X049530Y016722 53 | X056387Y031708 54 | X056387Y029168 55 | X056387Y026628 56 | X056387Y024087 57 | X056387Y019769 58 | X056387Y016468 59 | X048668Y071908 60 | X048668Y069368 61 | X048668Y066828 62 | X048668Y064288 63 | X049430Y056922 64 | X056288Y071908 65 | X056288Y069368 66 | X056288Y066828 67 | X056288Y064288 68 | X056288Y059970 69 | X056288Y056668 70 | T03 71 | X033970Y023278 72 | X029611Y022730 73 | X029611Y026032 74 | X028409Y035762 75 | X028409Y038663 76 | X023411Y024863 77 | X023411Y027665 78 | X023210Y008864 79 | X023210Y013964 80 | X020789Y035762 81 | X020789Y038663 82 | X015791Y024863 83 | X015791Y027665 84 | X015590Y008864 85 | X015590Y013964 86 | X033970Y063378 87 | X029611Y062829 88 | X029611Y066131 89 | X028409Y075862 90 | X028409Y078763 91 | X023411Y064962 92 | X023411Y067765 93 | X023210Y048964 94 | X023210Y054064 95 | X020789Y075862 96 | X020789Y078763 97 | X015791Y064962 98 | X015791Y067765 99 | X015590Y048964 100 | X015590Y054064 101 | X049530Y019221 102 | X053888Y019769 103 | X053888Y016468 104 | X055090Y006737 105 | X055090Y003836 106 | X060088Y017636 107 | X060088Y014834 108 | X060289Y033635 109 | X060289Y028535 110 | X062710Y006737 111 | X062710Y003836 112 | X067708Y017636 113 | X067708Y014834 114 | X067909Y033635 115 | X067909Y028535 116 | X049430Y059421 117 | X053788Y059970 118 | X053788Y056668 119 | X054990Y046937 120 | X054990Y044036 121 | X059988Y057836 122 | X059988Y055034 123 | X060189Y073835 124 | X060189Y068735 125 | X062610Y046937 126 | X062610Y044036 127 | X067608Y057836 128 | X067608Y055034 129 | X067809Y073835 130 | X067809Y068735 131 | T04 132 | X024201Y011264 133 | X024201Y031264 134 | X022900Y019463 135 | X018148Y016964 136 | X018148Y021962 137 | X024201Y051364 138 | X024201Y071364 139 | X022900Y059563 140 | X018148Y057064 141 | X018148Y062062 142 | X036050Y069113 143 | X036050Y073614 144 | X029547Y069113 145 | X029547Y073614 146 | X009441Y049563 147 | X006901Y049563 148 | X059298Y031235 149 | X059298Y011235 150 | X060599Y023036 151 | X065351Y025535 152 | X065351Y020537 153 | X047449Y013486 154 | X047449Y008985 155 | X053952Y013486 156 | X053952Y008985 157 | X074058Y033036 158 | X076598Y033036 159 | X059198Y071435 160 | X059198Y051435 161 | X060499Y063236 162 | X065251Y065735 163 | X065251Y060737 164 | X047349Y053686 165 | X047349Y049185 166 | X053852Y053686 167 | X053852Y049185 168 | X073958Y073236 169 | X076498Y073236 170 | T05 171 | X036050Y029013 172 | X036050Y033514 173 | X029547Y029013 174 | X029547Y033514 175 | X009441Y009463 176 | X006901Y009463 177 | T06 178 | X038034Y012570 179 | X038034Y015110 180 | X038034Y022730 181 | X038034Y025269 182 | X030160Y005204 183 | X027620Y005204 184 | X020000Y005204 185 | X017460Y005204 186 | X016479Y031099 187 | X013939Y031099 188 | X011399Y031099 189 | X010599Y013563 190 | X010599Y016103 191 | X010599Y018643 192 | X010599Y021183 193 | X010599Y023723 194 | X010599Y026263 195 | X038034Y052669 196 | X038034Y055209 197 | X038034Y062829 198 | X038034Y065369 199 | X030160Y045303 200 | X027620Y045303 201 | X020000Y045303 202 | X017460Y045303 203 | X016479Y071199 204 | X013939Y071199 205 | X011399Y071199 206 | X010599Y053663 207 | X010599Y056203 208 | X010599Y058743 209 | X010599Y061283 210 | X010599Y063823 211 | X010599Y066363 212 | X045465Y029930 213 | X045465Y027390 214 | X045465Y019769 215 | X045465Y017230 216 | X053339Y037296 217 | X055879Y037296 218 | X063500Y037296 219 | X066039Y037296 220 | X067020Y011400 221 | X069560Y011400 222 | X072100Y011400 223 | X072900Y028936 224 | X072900Y026396 225 | X072900Y023856 226 | X072900Y021316 227 | X072900Y018776 228 | X072900Y016236 229 | X045366Y070130 230 | X045366Y067590 231 | X045366Y059970 232 | X045366Y057430 233 | X053240Y077496 234 | X055780Y077496 235 | X063400Y077496 236 | X065940Y077496 237 | X066920Y051600 238 | X069460Y051600 239 | X072000Y051600 240 | X072800Y069136 241 | X072800Y066596 242 | X072800Y064056 243 | X072800Y061516 244 | X072800Y058976 245 | X072800Y056436 246 | T07 247 | X037599Y005264 248 | X037599Y037263 249 | X005600Y005264 250 | X005600Y037263 251 | X037599Y045364 252 | X037599Y077363 253 | X005600Y045364 254 | X005600Y077363 255 | X045900Y037235 256 | X045900Y005236 257 | X077899Y037235 258 | X077899Y005236 259 | X045800Y077435 260 | X045800Y045436 261 | X077799Y077435 262 | X077799Y045436 263 | M30 -------------------------------------------------------------------------------- /Programs/LunaMod_Generator/LunaMod_Generator.cpp.hex: -------------------------------------------------------------------------------- 1 | :1000000017C031C030C02FC0CFC12EC02CC02BC0F4 2 | :100010002AC029C028C027C026C025C024C001028C 3 | :1000200004081020010101010101003600380037E9 4 | :1000300011241FBECFE5D2E0DEBFCDBF10E0A0E6A9 5 | :10004000B0E0ECE6F6E002C005900D92A23EB107EA 6 | :10005000D9F721E0A2EEB0E001C01D92A93FB2079E 7 | :10006000E1F7FED201C3CCCF1F920F920FB60F92D1 8 | :1000700011242F933F938F939F93EF93FF9380913E 9 | :10008000E4008BBD2091E2003091E300E32FFF27D5 10 | :10009000E551FF4F80818093E4008091EB019091C6 11 | :1000A000EC01820F931F9093E3008093E200FF9195 12 | :1000B000EF919F918F913F912F910F900FBE0F90D5 13 | :1000C0001F9018958091E5008823B9F083E018D23D 14 | :1000D0009093E8008093E7009C0144E035952795D4 15 | :1000E0004A95E1F72093E600880F991F880F991F22 16 | :1000F0009093610080936000089583E001D224E032 17 | :10010000959587952A95E1F72091E60030E08217D2 18 | :10011000930719F481E08093E50008958BEE90E059 19 | :10012000FC012E2F281B219321E0EB3EF207C9F79B 20 | :100130000895EBEEF0E080E090E0282F220F21936D 21 | :10014000019680389105C9F7EBE6F1E08FEF90E07A 22 | :10015000819302978F3F2FEF9207D1F70895EBEE2F 23 | :10016000F0E08FEF819391E0EB36F907D9F7EBE6FA 24 | :10017000F1E081E0819391E0EB3EF907D9F7089532 25 | :100180008130910531F08230910521F0892B19F4ED 26 | :10019000D0CFE5CFC3CF08958091E9009091EA00D8 27 | :1001A0000196833091052CF49093EA008093E90046 28 | :1001B00004C01092EA001092E9008091E900909149 29 | :1001C000EA00DECFEF92FF920F931F93CF93DF935E 30 | :1001D000C0E0D0E00CEF1FE0D093EE01C093ED0142 31 | :1001E000209739F0CE018F7E0F9719F0CF32D105CD 32 | :1001F00021F461E080E0DAD10DC0CE018F7C079759 33 | :1002000049F460E080E0D2D181E07AD18C3B924029 34 | :100210000CF4C2DF81E0F9D10197A9F41092E50056 35 | :10022000E090ED01F090EE0183E06AD1F701EE0F6E 36 | :10023000FF1FEE59FF4FA4E0880F991FAA95E1F721 37 | :100240009183808301C03EDFE091ED01F091EE01EA 38 | :10025000EE0FFF1FEE59FF4F808191819093EC01CB 39 | :100260008093EB018091600090916100B801681B60 40 | :10027000790B882777FD8095982F04D12196C0347B 41 | :10028000D10509F0A9CFDF91CF911F910F91FF9078 42 | :10029000EF900895CF92DF92EF92FF920F931F930A 43 | :1002A000CF93DF938C01C0E0D0E06B01EE24D7FC4C 44 | :1002B000E094FE2CC017D10774F461E080E076D1A1 45 | :1002C000C701B601DFD060E080E070D1C701B601A0 46 | :1002D000D9D02196EFCFDF91CF911F910F91FF9051 47 | :1002E000EF90DF90CF90089517B83D9A87B18C605A 48 | :1002F00087B96AEF70E080E090E0C4D0369A369912 49 | :10030000FECF85B1883628F064E670E088E090E0A2 50 | :1003100004C06AEF70E081E090E0BCCF82E080BD75 51 | :100320008CE084BB61E080E009D161E084E006D12B 52 | :1003300060E083E003D160E082E000D160E081E032 53 | :10034000FDD0D2DF17B887B5826087BD87EC90E01B 54 | :100350000197F1F700C0000007B400FEFDCF87B59C 55 | :10036000846087BDF89480E68CBD8FEF8DBD81E001 56 | :1003700080BF93E09ABD83BF82E089BF7894D9DEC5 57 | :1003800060E47CE980E090E07DC083B7887F83BF34 58 | :100390008AB58C7F81608ABD83B7877F83BF83B72F 59 | :1003A000887F836083BF08951F920F920FB60F92CC 60 | :1003B00011242F933F938F939F93AF93BF9380917B 61 | :1003C000F0019091F101A091F201B091F30130910F 62 | :1003D000EF0126E0230F2D3730F029E8230F039695 63 | :1003E000A11DB11D03C00296A11DB11D2093EF01F7 64 | :1003F0008093F0019093F101A093F201B093F30187 65 | :100400008091F4019091F501A091F601B091F7016E 66 | :100410000196A11DB11D8093F4019093F501A09365 67 | :10042000F601B093F701BF91AF919F918F913F91EA 68 | :100430002F910F900FBE0F901F9018953FB7F89413 69 | :100440008091F4019091F501A091F601B091F7012E 70 | :100450002FB508B602FE05C02F3F19F00196A11D69 71 | :10046000B11D3FBF6627782F892F9A2F620F711D0C 72 | :10047000811D911D43E0660F771F881F991F4A95C4 73 | :10048000D1F70895CF92DF92EF92FF92CF93DF934F 74 | :100490006B017C01D3DFEB01C114D104E104F10451 75 | :1004A00071F0CCDF6C1B7D0B683E7340A8F381E0DC 76 | :1004B000C81AD108E108F108C851DC4FEDCFDF912F 77 | :1004C000CF91FF90EF90DF90CF900895789480B710 78 | :1004D000806880BF80B7806480BF8CB580648CBD2D 79 | :1004E0008FEF8DBD80B7807F876080BF89B78460C4 80 | :1004F00089BF4BDF86B1887F866086B9379A0895B9 81 | :10050000863008F086503091F80127B1932F9295EC 82 | :10051000990F990F907C2F72922B32FB332730F971 83 | :100520003295307F932B97B997B1907F982B97B9DD 84 | :10053000369A3699FECF84B195B10895CF93DF9363 85 | :10054000C82FD0E0FE01E25EFF4F8491FE01EC5D1A 86 | :10055000FF4FC491CC2339F1D0E0FE01E25DFF4FA3 87 | :10056000A491B0E0FE01E45DFF4FC491D0E02FB74D 88 | :10057000611108C0F8949C91809598239C93988170 89 | :1005800098230AC0623051F4F8949C91382F30952A 90 | :1005900093239C939881982B988304C0F8949C9102 91 | :1005A000982B9C932FBFDF91CF910895A82FB0E097 92 | :1005B000FD01E25EFF4F9491FD01EC5DFF4FE49180 93 | :1005C000EE2311F1811103C08AB58F7304C081300D 94 | :1005D00021F48AB58F7C8ABD05C0843019F48CB5AE 95 | :1005E0008F7C8CBDF0E0E45DFF4FA491B0E02FB7AD 96 | :1005F000611105C0F8948C919095892303C0F894FB 97 | :100600008C91892B8C932FBF0895282F30E0F9010E 98 | :10061000E25EFF4F9491F901EC5DFF4FE491EE2310 99 | :10062000E1F0811103C08AB58F7304C0813021F4D9 100 | :100630008AB58F7C8ABD05C0843019F48CB58F7C57 101 | :100640008CBDF0E0E65DFF4FE491F0E020812923CE 102 | :1006500081E090E021F480E0089580E090E008954A 103 | :0C06600035DF5CDEAFDDFECFF894FFCF8D 104 | :10066C00D007F401F40164006400640064006400C9 105 | :10067C00640064006400640064006400640064004E 106 | :10068C006400F401F401640064006400640064001C 107 | :10069C00640064006400640064006400640064002E 108 | :1006AC006400F401F40164006400640064006400FC 109 | :1006BC00640064006400640064006400640064000E 110 | :1006CC006400F401F40164006400640064006400DC 111 | :1006DC0064006400640064006400640064006400EE 112 | :0206EC006400A8 113 | :00000001FF 114 | -------------------------------------------------------------------------------- /BOM_and_schematic/Gerber/miniMO-F.Cu.gtl: -------------------------------------------------------------------------------- 1 | G04 #@! TF.FileFunction,Copper,L1,Top,Signal* 2 | %FSLAX46Y46*% 3 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 4 | G04 Created by KiCad (PCBNEW 4.0.1-stable) date 10/18/2017 12:48:17 AM* 5 | %MOMM*% 6 | G01* 7 | G04 APERTURE LIST* 8 | %ADD10C,0.100000*% 9 | %ADD11R,1.300000X1.300000*% 10 | %ADD12C,1.300000*% 11 | %ADD13R,2.000000X2.000000*% 12 | %ADD14C,2.000000*% 13 | %ADD15O,1.600000X1.600000*% 14 | %ADD16R,2.032000X2.032000*% 15 | %ADD17O,2.032000X2.032000*% 16 | %ADD18C,1.998980*% 17 | %ADD19R,2.032000X1.727200*% 18 | %ADD20O,2.032000X1.727200*% 19 | %ADD21R,1.727200X2.032000*% 20 | %ADD22O,1.727200X2.032000*% 21 | %ADD23C,0.685800*% 22 | %ADD24C,0.203200*% 23 | %ADD25C,0.304800*% 24 | G04 APERTURE END LIST* 25 | D10* 26 | D11* 27 | X119888000Y-125730000D03* 28 | D12* 29 | X117388000Y-125730000D03* 30 | D11* 31 | X113030000Y-128778000D03* 32 | D12* 33 | X113030000Y-126278000D03* 34 | D11* 35 | X119888000Y-129032000D03* 36 | D12* 37 | X117388000Y-129032000D03* 38 | D13* 39 | X140100000Y-112464000D03* 40 | D14* 41 | X137560000Y-112464000D03* 42 | D15* 43 | X112268000Y-113792000D03* 44 | X112268000Y-116332000D03* 45 | X112268000Y-118872000D03* 46 | X112268000Y-121412000D03* 47 | X119888000Y-121412000D03* 48 | X119888000Y-118872000D03* 49 | X119888000Y-116332000D03* 50 | X119888000Y-113792000D03* 51 | D16* 52 | X119380000Y-108204000D03* 53 | D17* 54 | X116840000Y-108204000D03* 55 | D16* 56 | X129540000Y-108204000D03* 57 | D17* 58 | X127000000Y-108204000D03* 59 | D16* 60 | X108966000Y-125730000D03* 61 | D17* 62 | X108966000Y-128270000D03* 63 | D16* 64 | X108966000Y-115570000D03* 65 | D17* 66 | X108966000Y-118110000D03* 67 | D18* 68 | X123590000Y-130664000D03* 69 | X131210000Y-130664000D03* 70 | X118590000Y-138764000D03* 71 | X126210000Y-138764000D03* 72 | X126210000Y-141664000D03* 73 | X118590000Y-141664000D03* 74 | X123790000Y-111864000D03* 75 | X131410000Y-111864000D03* 76 | X131210000Y-127864000D03* 77 | X123590000Y-127864000D03* 78 | X131410000Y-116964000D03* 79 | X123790000Y-116964000D03* 80 | X117451200Y-132013560D03* 81 | X110948800Y-136514440D03* 82 | X117451200Y-136514440D03* 83 | X110948800Y-132013560D03* 84 | D19* 85 | X136400000Y-129264000D03* 86 | D20* 87 | X136400000Y-126724000D03* 88 | X136400000Y-124184000D03* 89 | X136400000Y-121644000D03* 90 | X136400000Y-119104000D03* 91 | X136400000Y-116564000D03* 92 | D14* 93 | X122800000Y-134264000D03* 94 | X122800000Y-114264000D03* 95 | D18* 96 | X128851260Y-124963360D03* 97 | X124100000Y-122464000D03* 98 | X128851260Y-119964640D03* 99 | D21* 100 | X135600000Y-134100000D03* 101 | D22* 102 | X133060000Y-134100000D03* 103 | X130520000Y-134100000D03* 104 | D23* 105 | X117856000Y-120205500D03* 106 | X126936500Y-119888000D03* 107 | X126936500Y-122237500D03* 108 | D24* 109 | X119888000Y-125730000D02* 110 | X121456000Y-125730000D01* 111 | X121456000Y-125730000D02* 112 | X123590000Y-127864000D01* 113 | X108966000Y-128270000D02* 114 | X110900000Y-128264000D01* 115 | X118154000Y-127464000D02* 116 | X119888000Y-125730000D01* 117 | X110900000Y-127464000D02* 118 | X118154000Y-127464000D01* 119 | X110900000Y-128264000D02* 120 | X110900000Y-127464000D01* 121 | X108966000Y-128270000D02* 122 | X109594000Y-128270000D01* 123 | X108966000Y-121830000D02* 124 | X108966000Y-118110000D01* 125 | X110900000Y-123764000D02* 126 | X108966000Y-121830000D01* 127 | X110900000Y-127464000D02* 128 | X110900000Y-123764000D01* 129 | X108966000Y-128270000D02* 130 | X109093000Y-128270000D01* 131 | D25* 132 | X133096000Y-119964640D02* 133 | X133096000Y-115697000D01* 134 | X127973100Y-114020600D02* 135 | X125816500Y-111864000D01* 136 | X131419600Y-114020600D02* 137 | X127973100Y-114020600D01* 138 | X133096000Y-115697000D02* 139 | X131419600Y-114020600D01* 140 | X128851260Y-119964640D02* 141 | X133096000Y-119964640D01* 142 | X133096000Y-119964640D02* 143 | X133100000Y-132364000D01* 144 | X117451200Y-132013560D02* 145 | X122149560Y-132013560D01* 146 | X122500000Y-132364000D02* 147 | X133100000Y-132364000D01* 148 | X122149560Y-132013560D02* 149 | X122500000Y-132364000D01* 150 | X133100000Y-133964000D02* 151 | X133100000Y-132364000D01* 152 | X123790000Y-111864000D02* 153 | X125816500Y-111864000D01* 154 | X119888000Y-113792000D02* 155 | X119888000Y-112776000D01* 156 | X120800000Y-111864000D02* 157 | X123790000Y-111864000D01* 158 | X119888000Y-112776000D02* 159 | X120800000Y-111864000D01* 160 | X113030000Y-128778000D02* 161 | X113030000Y-129994000D01* 162 | X115049560Y-132013560D02* 163 | X117451200Y-132013560D01* 164 | X113030000Y-129994000D02* 165 | X115049560Y-132013560D01* 166 | D24* 167 | X117856000Y-120205500D02* 168 | X117919500Y-120142000D01* 169 | X117919500Y-120142000D02* 170 | X121348500Y-120142000D01* 171 | X121348500Y-120142000D02* 172 | X121412000Y-120142000D01* 173 | X121412000Y-120142000D02* 174 | X121666000Y-120396000D01* 175 | X121666000Y-120396000D02* 176 | X124650500Y-120396000D01* 177 | X124650500Y-120396000D02* 178 | X128082500Y-116964000D01* 179 | X128082500Y-116964000D02* 180 | X131410000Y-116964000D01* 181 | X117856000Y-120205500D02* 182 | X113768000Y-116332000D01* 183 | X113768000Y-116332000D02* 184 | X112268000Y-116332000D01* 185 | X126210000Y-138764000D02* 186 | X135619500Y-138764000D01* 187 | X135619500Y-138764000D02* 188 | X140081000Y-133604000D01* 189 | X140081000Y-133604000D02* 190 | X140081000Y-112395000D01* 191 | X137560000Y-112464000D02* 192 | X138200000Y-113104000D01* 193 | X138200000Y-113104000D02* 194 | X138200000Y-119844000D01* 195 | X138200000Y-119844000D02* 196 | X136400000Y-121644000D01* 197 | X112276000Y-118864000D02* 198 | X114800000Y-118864000D01* 199 | X127698500Y-127825500D02* 200 | X131171500Y-127825500D01* 201 | X125095000Y-125222000D02* 202 | X127698500Y-127825500D01* 203 | X123380500Y-125222000D02* 204 | X125095000Y-125222000D01* 205 | X122047000Y-123888500D02* 206 | X123380500Y-125222000D01* 207 | X118618000Y-123888500D02* 208 | X122047000Y-123888500D01* 209 | X116967000Y-122237500D02* 210 | X118618000Y-123888500D01* 211 | X116967000Y-121031000D02* 212 | X116967000Y-122237500D01* 213 | X114800000Y-118864000D02* 214 | X116967000Y-121031000D01* 215 | X131171500Y-127825500D02* 216 | X131210000Y-127864000D01* 217 | X126936500Y-119888000D02* 218 | X126936500Y-122237500D01* 219 | D25* 220 | X123100000Y-133964000D02* 221 | X130600640Y-133964000D01* 222 | X122800000Y-134264000D02* 223 | X123100000Y-133964000D01* 224 | X136398000Y-116586000D02* 225 | X134620000Y-117856000D01* 226 | X134620000Y-130302000D02* 227 | X135636000Y-131318000D01* 228 | X134620000Y-117856000D02* 229 | X134620000Y-130302000D01* 230 | X134620000Y-117856000D02* 231 | X134620000Y-117856000D01* 232 | X135636000Y-131318000D02* 233 | X135636000Y-133858000D01* 234 | M02* 235 | -------------------------------------------------------------------------------- /Programs/Display_Example/oled.h: -------------------------------------------------------------------------------- 1 | /* 2 | //****************************** 3 | //* miniMO OLED_SSD1306 * 4 | //* 2017 by enveloop * 5 | //****************************** 6 | Adapted from the SSD1306xLED library 7 | by Neven Boyanov, 8 | as described Here: 9 | https://tinusaur.org/projects/ssd1306xled/ 10 | SCROLL DOWN FOR SSD1306xLED LICENSE 11 | 12 | // 13 | http://www.minimosynth.com/ 14 | CC BY 4.0 15 | Licensed under a Creative Commons Attribution 4.0 International license: 16 | http://creativecommons.org/licenses/by/4.0/ 17 | // 18 | 19 | */ 20 | 21 | #include 22 | 23 | #define OLED_h 24 | 25 | ///////////USER SETTINGS///////////// 26 | 27 | #define SCREEN_WIDTH 64 28 | #define SCREEN_HEIGHT 48 29 | 30 | #define FLIPSCREEN 0 // 0 or 1 31 | 32 | ///////////////////////////////////// 33 | 34 | #define SCL PB0 // SCL, MO in miniMO 35 | #define SDA PB2 // SDA, SCK in miniMO (you lose I/O 4) 36 | //#define SDA PB1 // SDA, MI in miniMO (you lose push button) 37 | 38 | #define SA 0x78 // Slave address 39 | 40 | class OLED 41 | { 42 | public: 43 | void init(void); 44 | void initB(void); 45 | void fillscreen(unsigned int fill_Data); 46 | void fillLine(unsigned int line, unsigned int fill_Data); 47 | void char_f6x8(uint8_t x, uint8_t y, const char ch[]); 48 | 49 | private: 50 | void xfer_start(void); 51 | void xfer_stop(void); 52 | void send_byte(uint8_t byte); 53 | void send_command(uint8_t command); 54 | void send_data_start(void); 55 | void send_data_stop(void); 56 | void setpos(unsigned int x, unsigned int y); 57 | }; 58 | 59 | /* Standard ASCII 6x8 font */ 60 | const uint8_t font6x8 [] PROGMEM = 61 | { 62 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sp 63 | 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, // ! 64 | 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, // " 65 | 0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14, // # 66 | 0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12, // $ 67 | 0x00, 0x62, 0x64, 0x08, 0x13, 0x23, // % 68 | 0x00, 0x36, 0x49, 0x55, 0x22, 0x50, // & 69 | 0x00, 0x00, 0x05, 0x03, 0x00, 0x00, // ' 70 | 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00, // ( 71 | 0x00, 0x00, 0x41, 0x22, 0x1c, 0x00, // ) 72 | 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14, // * 73 | 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, // + 74 | 0x00, 0x00, 0x00, 0xA0, 0x60, 0x00, // , 75 | 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, // - 76 | 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, // . 77 | 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, // / 78 | 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0 79 | 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00, // 1 80 | 0x00, 0x42, 0x61, 0x51, 0x49, 0x46, // 2 81 | 0x00, 0x21, 0x41, 0x45, 0x4B, 0x31, // 3 82 | 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10, // 4 83 | 0x00, 0x27, 0x45, 0x45, 0x45, 0x39, // 5 84 | 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30, // 6 85 | 0x00, 0x01, 0x71, 0x09, 0x05, 0x03, // 7 86 | 0x00, 0x36, 0x49, 0x49, 0x49, 0x36, // 8 87 | 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E, // 9 88 | 0x00, 0x00, 0x36, 0x36, 0x00, 0x00, // : 89 | 0x00, 0x00, 0x56, 0x36, 0x00, 0x00, // ; 90 | 0x00, 0x08, 0x14, 0x22, 0x41, 0x00, // < 91 | 0x00, 0x14, 0x14, 0x14, 0x14, 0x14, // = 92 | 0x00, 0x00, 0x41, 0x22, 0x14, 0x08, // > 93 | 0x00, 0x02, 0x01, 0x51, 0x09, 0x06, // ? 94 | 0x00, 0x32, 0x49, 0x59, 0x51, 0x3E, // @ 95 | 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C, // A 96 | 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36, // B 97 | 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22, // C 98 | 0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C, // D 99 | 0x00, 0x7F, 0x49, 0x49, 0x49, 0x41, // E 100 | 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01, // F 101 | 0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A, // G 102 | 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F, // H 103 | 0x00, 0x00, 0x41, 0x7F, 0x41, 0x00, // I 104 | 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, // J 105 | 0x00, 0x7F, 0x08, 0x14, 0x22, 0x41, // K 106 | 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40, // L 107 | 0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F, // M 108 | 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F, // N 109 | 0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E, // O 110 | 0x00, 0x7F, 0x09, 0x09, 0x09, 0x06, // P 111 | 0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E, // Q 112 | 0x00, 0x7F, 0x09, 0x19, 0x29, 0x46, // R 113 | 0x00, 0x46, 0x49, 0x49, 0x49, 0x31, // S 114 | 0x00, 0x01, 0x01, 0x7F, 0x01, 0x01, // T 115 | 0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F, // U 116 | 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F, // V 117 | 0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F, // W 118 | 0x00, 0x63, 0x14, 0x08, 0x14, 0x63, // X 119 | 0x00, 0x07, 0x08, 0x70, 0x08, 0x07, // Y 120 | 0x00, 0x61, 0x51, 0x49, 0x45, 0x43, // Z 121 | 0x00, 0x00, 0x7F, 0x41, 0x41, 0x00, // [ 122 | 0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55, // 55 123 | 0x00, 0x00, 0x41, 0x41, 0x7F, 0x00, // ] 124 | 0x00, 0x04, 0x02, 0x01, 0x02, 0x04, // ^ 125 | 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, // _ 126 | 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, // ' 127 | 0x00, 0x20, 0x54, 0x54, 0x54, 0x78, // a 128 | 0x00, 0x7F, 0x48, 0x44, 0x44, 0x38, // b 129 | 0x00, 0x38, 0x44, 0x44, 0x44, 0x20, // c 130 | 0x00, 0x38, 0x44, 0x44, 0x48, 0x7F, // d 131 | 0x00, 0x38, 0x54, 0x54, 0x54, 0x18, // e 132 | 0x00, 0x08, 0x7E, 0x09, 0x01, 0x02, // f 133 | 0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C, // g 134 | 0x00, 0x7F, 0x08, 0x04, 0x04, 0x78, // h 135 | 0x00, 0x00, 0x44, 0x7D, 0x40, 0x00, // i 136 | 0x00, 0x40, 0x80, 0x84, 0x7D, 0x00, // j 137 | 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00, // k 138 | 0x00, 0x00, 0x41, 0x7F, 0x40, 0x00, // l 139 | 0x00, 0x7C, 0x04, 0x18, 0x04, 0x78, // m 140 | 0x00, 0x7C, 0x08, 0x04, 0x04, 0x78, // n 141 | 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, // o 142 | 0x00, 0xFC, 0x24, 0x24, 0x24, 0x18, // p 143 | 0x00, 0x18, 0x24, 0x24, 0x18, 0xFC, // q 144 | 0x00, 0x7C, 0x08, 0x04, 0x04, 0x08, // r 145 | 0x00, 0x48, 0x54, 0x54, 0x54, 0x20, // s 146 | 0x00, 0x04, 0x3F, 0x44, 0x40, 0x20, // t 147 | 0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C, // u 148 | 0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C, // v 149 | 0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C, // w 150 | 0x00, 0x44, 0x28, 0x10, 0x28, 0x44, // x 151 | 0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C, // y 152 | 0x00, 0x44, 0x64, 0x54, 0x4C, 0x44, // z 153 | 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, // horiz lines 154 | }; 155 | 156 | /* 157 | //SSD1306xLED LICENSE// 158 | Copyright (c) 2016 Neven Boyanov, Tinusaur Team. All Rights Reserved. 159 | 160 | Permission is hereby granted, free of charge, to any person obtaining a copy 161 | of this software and associated documentation files (the "Software"), to deal 162 | in the Software without restriction, including without limitation the rights 163 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 164 | copies of the Software, and to permit persons to whom the Software is 165 | furnished to do so, subject to the following conditions: 166 | 167 | The above copyright notice and this permission notice shall be included 168 | in all copies or substantial portions of the Software. 169 | 170 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 171 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 172 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 173 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 174 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 175 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 176 | THE SOFTWARE. 177 | */ 178 | 179 | 180 | 181 | 182 | -------------------------------------------------------------------------------- /Programs/Display_Example/oled.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | //****************************** 3 | //* miniMO OLED_SSD1306 * 4 | //* 2017 by enveloop * 5 | //****************************** 6 | Adapted from the SSD1306xLED library 7 | by Neven Boyanov, 8 | as described Here: 9 | https://tinusaur.org/projects/ssd1306xled/ 10 | SCROLL DOWN FOR SSD1306xLED LICENSE 11 | 12 | // 13 | http://www.minimosynth.com/ 14 | CC BY 4.0 15 | Licensed under a Creative Commons Attribution 4.0 International license: 16 | http://creativecommons.org/licenses/by/4.0/ 17 | // 18 | 19 | */ 20 | 21 | #include "oled.h" 22 | 23 | #define sbi(bit) PORTB |= (1 << (bit)) //macro to set a bit in PORTB 24 | #define cbi(bit) PORTB &= ~(1 << (bit)) //macro to clear a bit in PORTB 25 | 26 | #define HOR_OFFSET (128 - SCREEN_WIDTH) / 2 27 | 28 | void OLED::init(void) 29 | { 30 | DDRB |= (1 << SDA); //set port as output 31 | DDRB |= (1 << SCL); //set port as output 32 | 33 | send_command(0xAE); //display off 34 | send_command(0xD5); send_command(0x80); //0xD5 command to set display clock // 0x80 recommended value 35 | 36 | if (SCREEN_HEIGHT == 32) 37 | { 38 | send_command(0xA8); send_command(0x1F); //set multiplex: 0x1F for height = 32, 0x3F for height = 64 39 | } 40 | else send_command(0xA8); send_command(0x3F); 41 | 42 | send_command(0x40); //zero start line 43 | send_command(0x8D); send_command(0x14); //charge pump 44 | 45 | send_command(0x20); send_command(0x02); //0x20 command to set memory mode: 0x02, page addressing 46 | 47 | if (SCREEN_HEIGHT == 32) 48 | { 49 | send_command(0xDA); send_command(0x02); //0xDA set com pins 50 | } 51 | else send_command(0xDA); send_command(0x12); 52 | 53 | send_command(0xD3); send_command(0x00); //0xD3 command to set display offset (vertical) 54 | send_command(0xA6); //command to set Display color 0xA6 Normal 0xA7=Inverse 55 | 56 | send_command(0x81); send_command(0x7F); //0x81 command to send contrast, 7F actual value (0x00 to 0xFF) 57 | 58 | if (FLIPSCREEN) 59 | { 60 | send_command(0xA1); //0xA0/0xA1 flip horizontally 61 | send_command(0xC8); //0xC0/0xC8 flip vertically 62 | } 63 | 64 | send_command(0xD9); send_command(0xF1); //0xD9 command to set pre charge 65 | 66 | send_command(0xDB); send_command(0x80); //set vcom detect 67 | 68 | send_command(0xA4); //entire display ON, follow RAM 69 | send_command(0xAF); //display ON 70 | 71 | fillscreen(0x00); //clear screen 72 | } 73 | 74 | void OLED::xfer_start(void) 75 | { 76 | sbi(SCL); 77 | sbi(SDA); 78 | cbi(SDA); 79 | cbi(SCL); 80 | } 81 | 82 | void OLED::xfer_stop(void) 83 | { 84 | cbi(SCL); 85 | cbi(SDA); 86 | sbi(SCL); 87 | sbi(SDA); 88 | } 89 | 90 | void OLED::send_byte(uint8_t byte) 91 | { 92 | uint8_t i; 93 | for (i = 0; i < 8; i++) 94 | { 95 | if ((byte << i) & 0x80) sbi(SDA); 96 | else cbi(SDA); 97 | sbi(SCL); 98 | cbi(SCL); 99 | } 100 | sbi(SDA); 101 | sbi(SCL); 102 | cbi(SCL); 103 | } 104 | 105 | void OLED::send_command(uint8_t command) 106 | { 107 | xfer_start(); 108 | send_byte(SA); // slave address 109 | send_byte(0x00); // write command 110 | send_byte(command); 111 | xfer_stop(); 112 | } 113 | 114 | void OLED::send_data_start(void) 115 | { 116 | xfer_start(); 117 | send_byte(SA); // slave address 118 | send_byte(0x40); // write data 119 | } 120 | 121 | void OLED::send_data_stop(void) 122 | { 123 | xfer_stop(); 124 | } 125 | 126 | void OLED::setpos(unsigned int x, unsigned int y) 127 | { 128 | xfer_start(); 129 | send_byte(SA); //slave address 130 | send_byte(0x00); //write command 131 | send_byte(0xb0 + y); 132 | send_byte((((x + HOR_OFFSET - 1) & 0xf0) >> 4) | 0x10); // |0x10 133 | send_byte(((x + HOR_OFFSET - 1) & 0x0f) | 0x01); // |0x01 134 | xfer_stop(); 135 | } 136 | 137 | void OLED::fillscreen(unsigned int fill_Data) 138 | { 139 | uint8_t k, m, n; 140 | k = SCREEN_HEIGHT >> 3; //screenHeight / 8 141 | for (m = 0; m < k; m++) 142 | { 143 | send_command(0xb0 + m); //page0-page1 144 | send_command(0x00); //low column start address 145 | send_command(0x10); //high column start address 146 | send_command(0x21); send_command(HOR_OFFSET); send_command(127 - HOR_OFFSET); //0x21 command to setup column start and end address. Values are decimal 147 | send_data_start(); 148 | for (n = 0; n < SCREEN_WIDTH; n++) 149 | { 150 | send_byte(fill_Data); 151 | } 152 | send_data_stop(); 153 | } 154 | } 155 | 156 | void OLED::fillLine(unsigned int line, unsigned int fill_Data) 157 | { 158 | uint8_t n; 159 | send_command(0xb0 + line); //page0-page1 160 | send_command(0x00); //low column start address 161 | send_command(0x10); //high column start address 162 | send_command(0x21); send_command(HOR_OFFSET); send_command(127 - HOR_OFFSET); //0x21 command to setup column start and end address. Values are decimal 163 | send_data_start(); 164 | for (n = 0; n < SCREEN_WIDTH; n++) 165 | { 166 | send_byte(fill_Data); 167 | } 168 | send_data_stop(); 169 | } 170 | 171 | void OLED::char_f6x8(uint8_t x, uint8_t y, const char ch[]) 172 | { 173 | uint8_t c, i, j = 0; 174 | while (ch[j] != '\0') 175 | { 176 | c = ch[j] - 32; 177 | 178 | //without this check, if the characters are longer than the size of the screen, they wrap up and overwrite the line 179 | if (x > (SCREEN_WIDTH - 2)) //orig 126 --screenwidth - 2 180 | { 181 | x = 0; 182 | y++; 183 | } 184 | setpos(x, y); 185 | send_data_start(); 186 | for (i = 0; i < 6; i++) 187 | { 188 | send_byte(pgm_read_byte(&font6x8[c * 6 + i])); 189 | } 190 | send_data_stop(); 191 | x += 6; 192 | j++; 193 | } 194 | } 195 | 196 | /* 197 | //SSD1306xLED LICENSE// 198 | Copyright (c) 2016 Neven Boyanov, Tinusaur Team. All Rights Reserved. 199 | 200 | Permission is hereby granted, free of charge, to any person obtaining a copy 201 | of this software and associated documentation files (the "Software"), to deal 202 | in the Software without restriction, including without limitation the rights 203 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 204 | copies of the Software, and to permit persons to whom the Software is 205 | furnished to do so, subject to the following conditions: 206 | 207 | The above copyright notice and this permission notice shall be included 208 | in all copies or substantial portions of the Software. 209 | 210 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 211 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 212 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 213 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 214 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 215 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 216 | THE SOFTWARE. 217 | */ 218 | 219 | -------------------------------------------------------------------------------- /BOM_and_schematic/Gerber/miniMO-B.SilkS.gbo: -------------------------------------------------------------------------------- 1 | G04 #@! TF.FileFunction,Legend,Bot* 2 | %FSLAX46Y46*% 3 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 4 | G04 Created by KiCad (PCBNEW 4.0.1-stable) date 10/18/2017 12:48:17 AM* 5 | %MOMM*% 6 | G01* 7 | G04 APERTURE LIST* 8 | %ADD10C,0.100000*% 9 | %ADD11C,0.150000*% 10 | %ADD12C,0.200000*% 11 | G04 APERTURE END LIST* 12 | D10* 13 | D11* 14 | X142614286Y-133742856D02* 15 | X141947619Y-133552380D01* 16 | X142423810Y-133361903D01* 17 | X141947619Y-133171427D01* 18 | X142614286Y-132980951D01* 19 | X142614286Y-132695237D02* 20 | X141947619Y-132504761D01* 21 | X142423810Y-132314284D01* 22 | X141947619Y-132123808D01* 23 | X142614286Y-131933332D01* 24 | X142614286Y-131647618D02* 25 | X141947619Y-131457142D01* 26 | X142423810Y-131266665D01* 27 | X141947619Y-131076189D01* 28 | X142614286Y-130885713D01* 29 | X142042857Y-130504761D02* 30 | X141995238Y-130457142D01* 31 | X141947619Y-130504761D01* 32 | X141995238Y-130552380D01* 33 | X142042857Y-130504761D01* 34 | X141947619Y-130504761D01* 35 | X141947619Y-130028571D02* 36 | X142614286Y-130028571D01* 37 | X142519048Y-130028571D02* 38 | X142566667Y-129980952D01* 39 | X142614286Y-129885714D01* 40 | X142614286Y-129742856D01* 41 | X142566667Y-129647618D01* 42 | X142471429Y-129599999D01* 43 | X141947619Y-129599999D01* 44 | X142471429Y-129599999D02* 45 | X142566667Y-129552380D01* 46 | X142614286Y-129457142D01* 47 | X142614286Y-129314285D01* 48 | X142566667Y-129219047D01* 49 | X142471429Y-129171428D01* 50 | X141947619Y-129171428D01* 51 | X141947619Y-128695238D02* 52 | X142614286Y-128695238D01* 53 | X142947619Y-128695238D02* 54 | X142900000Y-128742857D01* 55 | X142852381Y-128695238D01* 56 | X142900000Y-128647619D01* 57 | X142947619Y-128695238D01* 58 | X142852381Y-128695238D01* 59 | X142614286Y-128219048D02* 60 | X141947619Y-128219048D01* 61 | X142519048Y-128219048D02* 62 | X142566667Y-128171429D01* 63 | X142614286Y-128076191D01* 64 | X142614286Y-127933333D01* 65 | X142566667Y-127838095D01* 66 | X142471429Y-127790476D01* 67 | X141947619Y-127790476D01* 68 | X141947619Y-127314286D02* 69 | X142614286Y-127314286D01* 70 | X142947619Y-127314286D02* 71 | X142900000Y-127361905D01* 72 | X142852381Y-127314286D01* 73 | X142900000Y-127266667D01* 74 | X142947619Y-127314286D01* 75 | X142852381Y-127314286D01* 76 | X141947619Y-126838096D02* 77 | X142614286Y-126838096D01* 78 | X142519048Y-126838096D02* 79 | X142566667Y-126790477D01* 80 | X142614286Y-126695239D01* 81 | X142614286Y-126552381D01* 82 | X142566667Y-126457143D01* 83 | X142471429Y-126409524D01* 84 | X141947619Y-126409524D01* 85 | X142471429Y-126409524D02* 86 | X142566667Y-126361905D01* 87 | X142614286Y-126266667D01* 88 | X142614286Y-126123810D01* 89 | X142566667Y-126028572D01* 90 | X142471429Y-125980953D01* 91 | X141947619Y-125980953D01* 92 | X141947619Y-125361906D02* 93 | X141995238Y-125457144D01* 94 | X142042857Y-125504763D01* 95 | X142138095Y-125552382D01* 96 | X142423810Y-125552382D01* 97 | X142519048Y-125504763D01* 98 | X142566667Y-125457144D01* 99 | X142614286Y-125361906D01* 100 | X142614286Y-125219048D01* 101 | X142566667Y-125123810D01* 102 | X142519048Y-125076191D01* 103 | X142423810Y-125028572D01* 104 | X142138095Y-125028572D01* 105 | X142042857Y-125076191D01* 106 | X141995238Y-125123810D01* 107 | X141947619Y-125219048D01* 108 | X141947619Y-125361906D01* 109 | X141995238Y-124647620D02* 110 | X141947619Y-124552382D01* 111 | X141947619Y-124361906D01* 112 | X141995238Y-124266667D01* 113 | X142090476Y-124219048D01* 114 | X142138095Y-124219048D01* 115 | X142233333Y-124266667D01* 116 | X142280952Y-124361906D01* 117 | X142280952Y-124504763D01* 118 | X142328571Y-124600001D01* 119 | X142423810Y-124647620D01* 120 | X142471429Y-124647620D01* 121 | X142566667Y-124600001D01* 122 | X142614286Y-124504763D01* 123 | X142614286Y-124361906D01* 124 | X142566667Y-124266667D01* 125 | X142614286Y-123885715D02* 126 | X141947619Y-123647620D01* 127 | X142614286Y-123409524D02* 128 | X141947619Y-123647620D01* 129 | X141709524Y-123742858D01* 130 | X141661905Y-123790477D01* 131 | X141614286Y-123885715D01* 132 | X142614286Y-123028572D02* 133 | X141947619Y-123028572D01* 134 | X142519048Y-123028572D02* 135 | X142566667Y-122980953D01* 136 | X142614286Y-122885715D01* 137 | X142614286Y-122742857D01* 138 | X142566667Y-122647619D01* 139 | X142471429Y-122600000D01* 140 | X141947619Y-122600000D01* 141 | X142614286Y-122266667D02* 142 | X142614286Y-121885715D01* 143 | X142947619Y-122123810D02* 144 | X142090476Y-122123810D01* 145 | X141995238Y-122076191D01* 146 | X141947619Y-121980953D01* 147 | X141947619Y-121885715D01* 148 | X141947619Y-121552381D02* 149 | X142947619Y-121552381D01* 150 | X141947619Y-121123809D02* 151 | X142471429Y-121123809D01* 152 | X142566667Y-121171428D01* 153 | X142614286Y-121266666D01* 154 | X142614286Y-121409524D01* 155 | X142566667Y-121504762D01* 156 | X142519048Y-121552381D01* 157 | X142042857Y-120647619D02* 158 | X141995238Y-120600000D01* 159 | X141947619Y-120647619D01* 160 | X141995238Y-120695238D01* 161 | X142042857Y-120647619D01* 162 | X141947619Y-120647619D01* 163 | X141995238Y-119742857D02* 164 | X141947619Y-119838095D01* 165 | X141947619Y-120028572D01* 166 | X141995238Y-120123810D01* 167 | X142042857Y-120171429D01* 168 | X142138095Y-120219048D01* 169 | X142423810Y-120219048D01* 170 | X142519048Y-120171429D01* 171 | X142566667Y-120123810D01* 172 | X142614286Y-120028572D01* 173 | X142614286Y-119838095D01* 174 | X142566667Y-119742857D01* 175 | X141947619Y-119171429D02* 176 | X141995238Y-119266667D01* 177 | X142042857Y-119314286D01* 178 | X142138095Y-119361905D01* 179 | X142423810Y-119361905D01* 180 | X142519048Y-119314286D01* 181 | X142566667Y-119266667D01* 182 | X142614286Y-119171429D01* 183 | X142614286Y-119028571D01* 184 | X142566667Y-118933333D01* 185 | X142519048Y-118885714D01* 186 | X142423810Y-118838095D01* 187 | X142138095Y-118838095D01* 188 | X142042857Y-118885714D01* 189 | X141995238Y-118933333D01* 190 | X141947619Y-119028571D01* 191 | X141947619Y-119171429D01* 192 | X141947619Y-118409524D02* 193 | X142614286Y-118409524D01* 194 | X142519048Y-118409524D02* 195 | X142566667Y-118361905D01* 196 | X142614286Y-118266667D01* 197 | X142614286Y-118123809D01* 198 | X142566667Y-118028571D01* 199 | X142471429Y-117980952D01* 200 | X141947619Y-117980952D01* 201 | X142471429Y-117980952D02* 202 | X142566667Y-117933333D01* 203 | X142614286Y-117838095D01* 204 | X142614286Y-117695238D01* 205 | X142566667Y-117600000D01* 206 | X142471429Y-117552381D01* 207 | X141947619Y-117552381D01* 208 | X126100000Y-136664000D02* 209 | X126100000Y-131164000D01* 210 | X119500000Y-136664000D02* 211 | X119500000Y-131164000D01* 212 | X126100000Y-136664000D02* 213 | X119500000Y-136664000D01* 214 | X134200000Y-120264000D02* 215 | G75* 216 | G03X134200000Y-120264000I-11400000J0D01* 217 | G01* 218 | X124483714Y-120324571D02* 219 | X124340857Y-120372190D01* 220 | X124293238Y-120419810D01* 221 | X124245619Y-120515048D01* 222 | X124245619Y-120657905D01* 223 | X124293238Y-120753143D01* 224 | X124340857Y-120800762D01* 225 | X124436095Y-120848381D01* 226 | X124817048Y-120848381D01* 227 | X124817048Y-119848381D01* 228 | X124483714Y-119848381D01* 229 | X124388476Y-119896000D01* 230 | X124340857Y-119943619D01* 231 | X124293238Y-120038857D01* 232 | X124293238Y-120134095D01* 233 | X124340857Y-120229333D01* 234 | X124388476Y-120276952D01* 235 | X124483714Y-120324571D01* 236 | X124817048Y-120324571D01* 237 | X123959905Y-119848381D02* 238 | X123388476Y-119848381D01* 239 | X123674191Y-120848381D02* 240 | X123674191Y-119848381D01* 241 | X122531333Y-120848381D02* 242 | X123102762Y-120848381D01* 243 | X122817048Y-120848381D02* 244 | X122817048Y-119848381D01* 245 | X122912286Y-119991238D01* 246 | X123007524Y-120086476D01* 247 | X123102762Y-120134095D01* 248 | D12* 249 | X123942857Y-129528286D02* 250 | X121657143Y-129528286D01* 251 | X122800000Y-130671143D02* 252 | X122800000Y-128385429D01* 253 | M02* 254 | -------------------------------------------------------------------------------- /Programs/Noise_Generator/Noise_Generator.ino: -------------------------------------------------------------------------------- 1 | /* 2 | //******************** 3 | //* miniMO Noise * 4 | //* 2016 by enveloop * 5 | //******************** 6 | 7 | Uses the xorshift pseudorandom number generator, 8 | as described Here: 9 | http://www.arklyffe.com/main/2010/08/29/xorshift-pseudorandom-number-generator/ 10 | 11 | // 12 | http://www.minimosynth.com/ 13 | CC BY 4.0 14 | Licensed under a Creative Commons Attribution 4.0 International license: 15 | http://creativecommons.org/licenses/by/4.0/ 16 | // 17 | 18 | I/O 19 | 1&2: Outputs - noise/grains 20 | 3: Input - frequency/grain density modulation 21 | 4: Input - amplitude modulation (if frequency is selected)/amplitude and density modulation (if density is selected) 22 | 23 | OPERATION 24 | Knob: change frequency (default) or grain density 25 | -miniMO waits until you reach the value it has currently stored 26 | Click: toggle between frequency and density control 27 | -The LED blinks once - frequency control 28 | -The LED blinks twice - density control 29 | 30 | BATTERY CHECK 31 | When you switch the module ON, 32 | -If the LED blinks once, the battery is OK 33 | -If the LED blinks fast several times, the battery is running low 34 | 35 | NOTES&TROUBLESHOOTING 36 | Amplitude modulation also affects grain density. This is particularly noticeable when density is set to very low values 37 | If a parameter doesn't respond to the knob when I/O 3 is connected to an external input, disconnect the input, move the knob until the module becomes responsive, and reconnect the input again 38 | */ 39 | 40 | 41 | #include 42 | #include 43 | 44 | //button interrupt 45 | volatile bool inputButtonValue; 46 | bool control = 1; 47 | 48 | //random number generator 49 | static unsigned long y32 = 1; // pattern length: 32 bit 50 | 51 | //freq control reference 52 | bool coarseFreqChange = false; 53 | byte potPosFreqRef = 255; // max 54 | 55 | //grain control reference 56 | bool coarseGrainChange = false; 57 | byte potPosGrainRef = 255; // max 58 | 59 | //volume input smoothing 60 | const int numReadings = 4; 61 | int readings[numReadings]; // readings from the analog input 62 | int readIndex = 0; // index of the current reading 63 | int total = 0; // running total 64 | byte volumeModulation = 255; 65 | 66 | void setup() { 67 | 68 | PRR = (1 << PRUSI); // disable USI to save power as we are not using it 69 | DIDR0 = (1 << ADC1D) | (1 << ADC3D); // PB2,PB3 //disable digital input in pins that do analog conversion 70 | 71 | // set the rest of the pins 72 | pinMode(0, OUTPUT); // LED 73 | pinMode(4, OUTPUT); // timer 1 in digital output 4 - outs 1 and 2 74 | pinMode(3, INPUT); // analog- freq input (knob plus external input 1) 75 | pinMode(2, INPUT); // analog- amplitude input (external input 2) 76 | pinMode(1, INPUT); // digital input (push button) 77 | 78 | checkVoltage(); 79 | ADMUX = 0; // reset multiplexer settings 80 | 81 | //set clock source for PWM -datasheet p94 82 | PLLCSR |= (1 << PLLE); // Enable PLL (64 MHz) 83 | _delay_us(100); // Wait for a steady state 84 | while (!(PLLCSR & (1 << PLOCK))); // Ensure PLL lock 85 | PLLCSR |= (1 << PCKE); // Enable PLL as clock source for timer 1 86 | 87 | cli(); // Interrupts OFF (disable interrupts globally) 88 | 89 | //PWM Generation -timer 1 90 | GTCCR = (1 << PWM1B) | (1 << COM1B1); // PWM, output on pb4, compare with OCR1B (see interrupt below), reset on match with OCR1C 91 | OCR1C = 0xff; // 255 92 | TCCR1 = (1 << CS10); // no prescale 93 | 94 | //Timer Interrupt Generation -timer 0 95 | TCCR0A = (1<> 8 ; 116 | 117 | } 118 | 119 | ISR(PCINT0_vect) { // PIN Interruption - has priority over COMPA; this ensures that the switch will work 120 | inputButtonValue = PINB & 0x02; // Reads button (digital input1, the second bit in register PINB. We check the value with & binary 10, so 0x02) 121 | //digitalWrite(0, !inputButtonValue); // Turn LED off while pressing the button 122 | if (inputButtonValue) { 123 | control = !control; 124 | if (control)flashLEDOnce(); 125 | else flashLEDTwice(); 126 | } 127 | } 128 | 129 | void loop() { 130 | 131 | if (control)setFrequency(3); 132 | else setGrainDensity(3); 133 | readExtInput(1); // read analog input 1 (attiny PB2) 134 | 135 | } 136 | 137 | byte xorshift32(void) { 138 | y32 ^= (y32 << 7); 139 | y32 ^= (y32 >> 5); 140 | return y32 ^= (y32 << 3); //pattern values: 8 bit 141 | } 142 | 143 | //Parameters don't change until we return to the value they had last time we changed them. 144 | //we store the knob's position in a variable and check the current position against it; 145 | //when we reach it, we start controlling the parameter again. 146 | 147 | void setGrainDensity(int pin) { 148 | coarseFreqChange = false; // reset the control condition for frequency 149 | if (coarseGrainChange == false) { 150 | byte coarseGrainRead = analogRead(pin) >> 2; 151 | if (coarseGrainRead == potPosGrainRef) { 152 | coarseGrainChange = true; 153 | } 154 | } 155 | if (coarseGrainChange == true) { 156 | int tempRead = analogRead(pin); 157 | byte densityRead = tempRead >> 2; // right shifting by 2 to get values between 0 and 255 (0-1023/2^2) 158 | potPosGrainRef = densityRead; // save the knob´s position for reference. 159 | OCR1C = densityRead; 160 | } 161 | } 162 | 163 | void setFrequency(int pin) { 164 | coarseGrainChange = false; // reset the control condition for density 165 | if (coarseFreqChange == false) { 166 | byte coarsefreqRead = analogRead(pin) >> 2; 167 | if (coarsefreqRead == potPosFreqRef) { 168 | coarseFreqChange = true; 169 | } 170 | } 171 | if (coarseFreqChange == true) { 172 | int tempRead = analogRead(pin); 173 | byte freqRead = tempRead >> 2; 174 | potPosFreqRef = freqRead; 175 | OCR0A = 255 - freqRead; // reversing values so that the knob affects it in the same way as the other parameters 176 | } 177 | } 178 | 179 | int readExtInput(const byte pin) { // with averaging 180 | total = total - readings[readIndex]; 181 | readings[readIndex] = analogRead(pin) >> 2; // right shifting by 2 to get values between 0 and 255 (0-1023/2^2) 182 | total = total + readings[readIndex]; 183 | readIndex = readIndex + 1; 184 | if (readIndex >= numReadings) readIndex = 0; 185 | volumeModulation = total / numReadings; 186 | } 187 | 188 | void checkVoltage() { // voltage from 255 to 0; 46 is (approx)5v, 94 is 2.8, 104-106 is 2.5 189 | // we measure a fixed value of 1.1 against Vcc, so the lower the measurement, the higher Vcc 190 | ADMUX = (0 << REFS1)|(0 << REFS0); // Vcc as reference 191 | ADMUX |= (1 << ADLAR); // Left adjust result (8 bit conversion stored in ADCH) 192 | ADMUX |= (1 << MUX3) | (1 << MUX2); // 1.1v input 193 | delay(250); // Wait for Vref to settle 194 | ADCSRA |= (1 << ADSC); // Start conversion 195 | while (bit_is_set(ADCSRA, ADSC)); // wait while measuring 196 | if (ADCH > 103) // approx 2.6 197 | flashLED(8, 100); 198 | else 199 | flashLED(1, 250); 200 | } 201 | 202 | void flashLED (int times, int gap) { // for voltage check only (uses regular delay) 203 | for (int i = 0; i < times; i++) 204 | { 205 | digitalWrite(0, HIGH); 206 | delay(gap); 207 | digitalWrite(0, LOW); 208 | delay(gap); 209 | } 210 | } 211 | 212 | void flashLEDOnce () { 213 | digitalWrite(0, LOW); 214 | _delay_ms(100); 215 | digitalWrite(0, HIGH); 216 | } 217 | 218 | void flashLEDTwice () { 219 | digitalWrite(0, LOW); 220 | _delay_ms(80); 221 | digitalWrite(0, HIGH); 222 | _delay_ms(80); 223 | digitalWrite(0, LOW); 224 | _delay_ms(80); 225 | digitalWrite(0, HIGH); 226 | } 227 | 228 | -------------------------------------------------------------------------------- /Programs/Delay/Delay.ino: -------------------------------------------------------------------------------- 1 | /* 2 | //************************ 3 | //* miniMO DELAY * 4 | //* 2017 by enveloop * 5 | //************************ 6 | Based on the Arduino Audio Reverb 7 | by Martin Nawrath, 8 | as described Here: 9 | http://interface.khm.de/index.php/lab/interfaces-advanced/arduino-realtime-audio-processing/ 10 | 11 | // 12 | http://www.minimosynth.com/ 13 | CC BY 4.0 14 | Licensed under a Creative Commons Attribution 4.0 International license: 15 | http://creativecommons.org/licenses/by/4.0/ 16 | // 17 | 18 | WARNING! This effect can self-oscillate, producing very loud tones 19 | 20 | I/O 21 | 1&2 Outputs - delayed signal 22 | 3: Input - parameter modulation 23 | 4: Input - audio signal 24 | 25 | OPERATION 26 | Knob: change feedback (default), buffer size or sample rate 27 | -miniMO waits until you reach the value it has currently stored 28 | Click: toggle between feedback, buffer size and delay time control 29 | -the LED blinks 1 to 3 times depending on the parameter selected (1-Feedback, 2-Buffer, 3-Rate) 30 | 31 | BATTERY CHECK 32 | When you switch the module ON, 33 | -If the LED blinks once, the battery is OK 34 | -If the LED blinks fast several times, the battery is running low 35 | 36 | */ 37 | 38 | #include 39 | #include 40 | 41 | #define F_CPU 8000000 42 | 43 | //interrupt variables accessed globally 44 | volatile boolean gotReadings; 45 | volatile byte controlInput; 46 | volatile byte audioInput; 47 | volatile bool inputButtonValue; 48 | 49 | //button press control 50 | int button_delay; 51 | 52 | int iw1; 53 | int iw2; 54 | 55 | int index = 0; 56 | byte delayBuffer[256]; // Audio Memory Array 8-Bit 57 | byte sample; 58 | 59 | bool parameterChange = false; 60 | int currentParameter = 0; 61 | byte parameters[] = { 62 | 200, //feedback 63 | 255, //buffer length 64 | 0 //loop delay length 65 | }; 66 | 67 | void setup() { 68 | 69 | PRR = (1 << PRUSI); //disable USI to save power as we are not using it 70 | DIDR0 = (1 << ADC1D) | (1 << ADC3D); //PB2,PB3 //disable digital input in pins that do analog conversion 71 | 72 | pinMode(0, OUTPUT); //LED 73 | pinMode(4, OUTPUT); //timer 1 in digital output 4 - outs 1 and 2 74 | pinMode(3, INPUT); //analog- freq input (knob plus external input 1) 75 | pinMode(2, INPUT); //analog- amplitude input (external input 2) 76 | pinMode(1, INPUT); //digital input (push button) 77 | 78 | checkVoltage(); 79 | 80 | ADCSRA = (1 << ADEN); //reset ADC Control (ADC Enable 1, everything else 0) 81 | ADCSRA |= (1 << ADPS2); //set adc prescaler to 16 for 500kHz sampling frequency (8 also works well but is noisier). 500/13 cycles per sample = 38.4 Khz, faster than the timer interrupt -good! 82 | 83 | ADMUX = 0; //reset multiplexer settings 84 | //ADMUX |= (1 << REFS2) | (1 << REFS1); //2.56V internal Voltage Reference disconnected from AREF 85 | ADMUX |= (0 << REFS2) | (0 << REFS1) | (0 << REFS0); //Vcc as voltage reference --not necessary, but a reminder 86 | ADMUX |= (1 << ADLAR); //8-Bit ADC in ADCH Register 87 | ADMUX |= (1 << MUX0); //select ADC1 (audio input) 88 | ADCSRA |= (1 << ADSC); // start conversion 89 | 90 | //set clock source for PWM -datasheet p94 91 | PLLCSR |= (1 << PLLE); // Enable PLL (64 MHz) 92 | _delay_us(100); // Wait for a steady state 93 | while (!(PLLCSR & (1 << PLOCK))); // Ensure PLL lock: do nothing while the bit PLOCK in register PLLCSR is false 94 | PLLCSR |= (1 << PCKE); // Enable PLL as clock source for timer 1 95 | 96 | cli(); // Interrupts OFF (disable interrupts globally) 97 | 98 | //PWM Generation -timer 1 99 | GTCCR = (1 << PWM1B) | (1 << COM1B1); // PWM, output on pb4, compare with OCR1B (see interrupt below), reset on match with OCR1C 100 | OCR1C = 0xff; 101 | TCCR1 = (1 << CS10); // no prescale 102 | 103 | //Timer Interrupt Generation -timer 0 104 | TCCR0A = (1 << WGM01) | (1 << WGM00); // fast PWM 105 | TCCR0B = (1 << CS00); // no prescale (source: internal clock) 106 | TIMSK = (1 << TOIE0); // Enable Interrupt on overflow, triggered at 31.2KHz (8Mhz / 256 steps per overflow) 107 | 108 | //Pin Change Interrupt 109 | GIMSK |= (1 << PCIE); // Enable 110 | PCMSK |= (1 << PCINT1); // on pin 1 111 | 112 | sei(); // Interrupts ON (enable interrupts globally) 113 | 114 | digitalWrite(0, HIGH); //lights on! 115 | } 116 | 117 | ISR(PCINT0_vect) { //PIN Interruption - has priority over Timer 0; this ensures that the switch will work 118 | inputButtonValue = PINB & 0x02; //Reads button (digital input1, the second bit in register PINB. We check the value with & binary 10, so 0x02) 119 | } 120 | 121 | //Timer0 interruption 122 | ISR(TIMER0_OVF_vect) { //alternates between reading audio and control input, so each channel is sampled at 15.6kHz 123 | 124 | if (!(ADMUX & 0x02)){ //if the audio input is selected... (it's ADC1, so MUX1 = 0. MUX1 is the second bit in register ADMUX; then, ADMUX & binary 10 = 0, or !(ADMUX&0x02). That ! is logic, so it's not inverting anything, but checking that the value is false 125 | audioInput = ADCH; // read the value 126 | ADMUX |= (1 << MUX1); //select the control input (ADC3, so MUX1 = 1 and MUX0 = 1. MUX0 was already set to 1 during setup) 127 | } 128 | else 129 | { 130 | controlInput = ADCH; // read the value 131 | gotReadings = true; // readings are ready! this will trigger processing in the main loop, once every two measurings - so aprox 7.8 Khz 132 | ADMUX &= ~(1 << MUX1); //select the audio input (ADC1, so MUX1 = 0 and MUX0=1. MUX0 was already set to 1 during setup) 133 | } 134 | ADCSRA |= (1<> 8; // scale delayed sample with potentiometer (originally iw * badc0 /255) 154 | 155 | iw2 = iw2 + iw1; // add delayed sample and new sample 156 | 157 | if (iw2 < -127) iw2 = -127; // limiter 158 | else if (iw2 > 127) iw2 = 127; // limiter 159 | 160 | sample = 127 + iw2; // add offset to the result 161 | 162 | delayBuffer[index] = sample; // store sample in delay buffer 163 | 164 | index++; 165 | 166 | variableDelay(parameters[2]); //slow down the process with a delay 167 | 168 | if (index > parameters[1]) index = 0; // aprox.30 ms for 256 samples (7.8Khz/256) 169 | } 170 | 171 | void variableDelay(int us) { 172 | while(us--) //http://stackoverflow.com/questions/32649032/what-does-whilex-mean-in-c/32649606 173 | _delay_us(1); 174 | } 175 | 176 | void setParameter() { 177 | if (parameterChange) parameters[currentParameter] = controlInput; 178 | 179 | else if (controlInput == parameters[currentParameter]) { //check control input against stored value. If the value is the same (because we have moved the knob to the last known position for that parameter), 180 | parameterChange = true; //it is ok to change the value :) 181 | } 182 | } 183 | 184 | void checkButton() { 185 | while (inputButtonValue == HIGH) { 186 | button_delay++; 187 | _delay_ms(10); 188 | } 189 | if ((inputButtonValue == LOW) && (button_delay > 0)) { //button released after a while (regular single click) 190 | currentParameter++; 191 | if (currentParameter > 2) currentParameter = 0; //3 parameters, indexes from 0 to 2 192 | flashLEDSlow(currentParameter + 1); //parameter 0 - flash once, etc 193 | parameterChange = false; //reset parameter change condition so that after we press the button, the newly selected parameter won't immediately change (see setParameter) 194 | button_delay = 0; 195 | } 196 | } 197 | 198 | void checkVoltage() { //voltage from 255 to 0; 46 is (approx)5v, 94 is 2.8, 104-106 is 2.5 199 | //we measure a fixed value of 1.1 against Vcc, so the lower the measurement, the higher Vcc 200 | ADMUX = (0 << REFS1) | (0 << REFS0); //Vcc as reference 201 | ADMUX |= (1 << ADLAR); //Left adjust result (8 bit conversion stored in ADCH) 202 | ADMUX |= (1 << MUX3) | (1 << MUX2); //1.1v input 203 | delay(250); //Wait for Vref to settle 204 | ADCSRA |= (1 << ADSC); //Start conversion 205 | while (bit_is_set(ADCSRA, ADSC)); //wait while measuring 206 | if (ADCH > 103) //approx 2.6 207 | flashLED(8, 100); 208 | else 209 | flashLED(1, 250); 210 | } 211 | 212 | void flashLED (int times, int gap) { //for voltage check only (uses regular delay) 213 | for (int i = 0; i < times; i++) 214 | { 215 | digitalWrite(0, HIGH); 216 | delay(gap); 217 | digitalWrite(0, LOW); 218 | delay(gap); 219 | } 220 | } 221 | 222 | void flashLEDSlow(int times) { 223 | for (int i = 0; i < times; i++){ 224 | _delay_ms(100); 225 | digitalWrite(0, LOW); 226 | _delay_ms(100); 227 | digitalWrite(0, HIGH); 228 | } 229 | } 230 | -------------------------------------------------------------------------------- /Programs/Noise_Random_Generator/Noise_Random_Generator.ino: -------------------------------------------------------------------------------- 1 | /* 2 | //************************************* 3 | //* miniMO Noise Random Generator * 4 | //* 2018 by enveloop * 5 | //************************************* 6 | 7 | Uses the xorshift pseudorandom number generator, 8 | as described Here: 9 | http://www.arklyffe.com/main/2010/08/29/xorshift-pseudorandom-number-generator/ 10 | 11 | // 12 | http://www.minimosynth.com/ 13 | CC BY 4.0 14 | Licensed under a Creative Commons Attribution 4.0 International license: 15 | http://creativecommons.org/licenses/by/4.0/ 16 | // 17 | 18 | I/O 19 | 1&2: Outputs - noise/grains 20 | 3: Input - frequency/grain density modulation 21 | 4: unused 22 | 23 | OPERATION 24 | 25 | Knob: change frequency (default) or grain density 26 | -miniMO waits until you reach the value it has currently stored 27 | Click: toggle between frequency and density control 28 | -The LED blinks once - frequency control 29 | -The LED blinks twice - density control 30 | 31 | BATTERY CHECK 32 | When you switch the module ON, 33 | -If the LED blinks once, the battery is OK 34 | -If the LED blinks fast several times, the battery is running low 35 | 36 | NOTES&TROUBLESHOOTING 37 | Extra Mode - Randomize All 38 | -If you select the randomizeMore() function in the main loop, miniMO will randomize all parameters 39 | -In this mode, there's no live user input 40 | -Note that there is also a delay() under OCR1C to play with :D 41 | */ 42 | 43 | 44 | #include 45 | #include 46 | #include 47 | 48 | //button interrupt 49 | volatile bool inputButtonValue; 50 | bool controlFrequency = 1; 51 | 52 | //random number generator 53 | static unsigned long y32 = 1; // pattern length: 32 bit 54 | 55 | //freq control reference 56 | bool coarseFreqChange = false; 57 | byte potPosFreqRef = 255; // max 58 | 59 | //grain control reference 60 | bool coarseGrainChange = false; 61 | byte potPosGrainRef = 255; // max 62 | 63 | 64 | byte noiseParameters[] = { 65 | 7, 66 | 5, 67 | 3 68 | }; 69 | 70 | void setup() { 71 | 72 | PRR = (1 << PRUSI); // disable USI to save power as we are not using it 73 | DIDR0 = (1 << ADC1D) | (1 << ADC3D); // PB2,PB3 //disable digital input in pins that do analog conversion 74 | 75 | // set the rest of the pins 76 | pinMode(0, OUTPUT); // LED 77 | pinMode(4, OUTPUT); // timer 1 in digital output 4 - outs 1 and 2 78 | pinMode(3, INPUT); // analog- freq input (knob plus external input 1) 79 | pinMode(2, INPUT); // analog- amplitude input (external input 2) 80 | pinMode(1, INPUT); // digital input (push button) 81 | 82 | checkVoltage(); 83 | ADMUX = 0; // reset multiplexer settings 84 | 85 | //set clock source for PWM -datasheet p94 86 | PLLCSR |= (1 << PLLE); // Enable PLL (64 MHz) 87 | _delay_us(100); // Wait for a steady state 88 | while (!(PLLCSR & (1 << PLOCK))); // Ensure PLL lock 89 | PLLCSR |= (1 << PCKE); // Enable PLL as clock source for timer 1 90 | 91 | cli(); // Interrupts OFF (disable interrupts globally) 92 | 93 | //PWM Generation -timer 1 94 | GTCCR = (1 << PWM1B) | (1 << COM1B1); // PWM, output on pb4, compare with OCR1B (see interrupt below), reset on match with OCR1C 95 | OCR1C = 0xff; // 255 96 | TCCR1 = (1 << CS10); // no prescale 97 | 98 | //Timer Interrupt Generation -timer 0 99 | TCCR0A = (1<> noiseParameters[1]); 141 | return y32 ^= (y32 << noiseParameters[2]); //pattern values: 8 bit 142 | } 143 | 144 | void randomizeMore() { 145 | 146 | randomizeNoiseParams(); 147 | 148 | OCR0A = (rand() >> 7); //frequency - rand (max value 32767) >> 7 to give max 255 149 | OCR1C = (rand() >> 7); //density - if used together with the delay below, it freezes the sound 150 | //delay(100); //may freeze the sound depending on the value (and/or chance!) :P 151 | } 152 | 153 | void randomizeNoise() { 154 | if (controlFrequency)setFrequency(3); 155 | else setGrainDensity(3); 156 | randomizeNoiseParams(); 157 | } 158 | 159 | void randomizeNoiseParams() { 160 | noiseParameters[0] = (rand() >> 10) + 1; //rand (max value 32767) >> 10 to give max 32 161 | noiseParameters[1] = (rand() >> 10) + 1; // +1 to avoid 0, which might "extiguish" the noise 162 | noiseParameters[2] = (rand() >> 10) + 1; 163 | } 164 | 165 | //Parameters don't change until we return to the value they had last time we changed them. 166 | //we store the knob's position in a variable and check the current position against it; 167 | //when we reach it, we start controlling the parameter again. 168 | 169 | void setGrainDensity(int pin) { 170 | coarseFreqChange = false; // reset the control condition for frequency 171 | if (coarseGrainChange == false) { 172 | byte coarseGrainRead = analogRead(pin) >> 2; 173 | if (coarseGrainRead == potPosGrainRef) { 174 | coarseGrainChange = true; 175 | } 176 | } 177 | if (coarseGrainChange == true) { 178 | int tempRead = analogRead(pin); 179 | byte densityRead = tempRead >> 2; // right shifting by 2 to get values between 0 and 255 (0-1023/2^2) 180 | potPosGrainRef = densityRead; // save the knob´s position for reference. 181 | OCR1C = densityRead; 182 | } 183 | } 184 | 185 | void setFrequency(int pin) { 186 | coarseGrainChange = false; // reset the control condition for density 187 | if (coarseFreqChange == false) { 188 | byte coarsefreqRead = analogRead(pin) >> 2; 189 | if (coarsefreqRead == potPosFreqRef) { 190 | coarseFreqChange = true; 191 | } 192 | } 193 | if (coarseFreqChange == true) { 194 | int tempRead = analogRead(pin); 195 | byte freqRead = tempRead >> 2; 196 | potPosFreqRef = freqRead; 197 | OCR0A = 255 - freqRead; // reversing values so that the knob affects it in the same way as the other parameters 198 | } 199 | } 200 | 201 | 202 | void checkVoltage() { // voltage from 255 to 0; 46 is (approx)5v, 94 is 2.8, 104-106 is 2.5 203 | // we measure a fixed value of 1.1 against Vcc, so the lower the measurement, the higher Vcc 204 | ADMUX = (0 << REFS1)|(0 << REFS0); // Vcc as reference 205 | ADMUX |= (1 << ADLAR); // Left adjust result (8 bit conversion stored in ADCH) 206 | ADMUX |= (1 << MUX3) | (1 << MUX2); // 1.1v input 207 | delay(250); // Wait for Vref to settle 208 | ADCSRA |= (1 << ADSC); // Start conversion 209 | while (bit_is_set(ADCSRA, ADSC)); // wait while measuring 210 | if (ADCH > 103) // approx 2.6 211 | flashLED(8, 100); 212 | else 213 | flashLED(1, 250); 214 | } 215 | 216 | void flashLED (int times, int gap) { // for voltage check only (uses regular delay) 217 | for (int i = 0; i < times; i++) 218 | { 219 | digitalWrite(0, HIGH); 220 | delay(gap); 221 | digitalWrite(0, LOW); 222 | delay(gap); 223 | } 224 | } 225 | 226 | void flashLEDOnce () { 227 | digitalWrite(0, LOW); 228 | _delay_ms(100); 229 | digitalWrite(0, HIGH); 230 | } 231 | 232 | void flashLEDTwice () { 233 | digitalWrite(0, LOW); 234 | _delay_ms(80); 235 | digitalWrite(0, HIGH); 236 | _delay_ms(80); 237 | digitalWrite(0, LOW); 238 | _delay_ms(80); 239 | digitalWrite(0, HIGH); 240 | } 241 | 242 | 243 | void initSeed(int address){ //initialize steps' info to random notes 244 | unsigned int rSeed = eeprom_read_word((uint16_t*)address); //read the last seed we used, from memory 245 | rSeed++; //add one -now we have a new seed 246 | srand(rSeed); //assign the new seed to the random generator (this way we'll have a new sequence of random values) 247 | eeprom_update_word((uint16_t*)address, rSeed); //save the seed we used 248 | } 249 | 250 | -------------------------------------------------------------------------------- /Programs/Low_Power_Beacon/Low_Power_Beacon.ino: -------------------------------------------------------------------------------- 1 | /* 2 | //********************************* 3 | //* miniMO LOW POWER BEACON * 4 | //* 2017 by enveloop * 5 | //********************************* 6 | Inspired by The Annoy-O-Bug by Alex Wulff: https://www.hackster.io/AlexWulff/the-annoy-o-bug-a-chirping-light-up-throwie-37e58a 7 | Watchdog setup described by Martin Nawrath: http://interface.khm.de/index.php/lab/interfaces-advanced/sleep_watchdog_battery/ 8 | Square wave generation described here: https://playground.arduino.cc/Main/PbSynthCode 9 | Also uses the Xorshift pseudorandom number generator, described here: http://www.arklyffe.com/main/2010/08/29/xorshift-pseudorandom-number-generator/ 10 | 11 | // 12 | http://www.minimosynth.com/ 13 | CC BY 4.0 14 | Licensed under a Creative Commons Attribution 4.0 International license: 15 | http://creativecommons.org/licenses/by/4.0/ 16 | // 17 | 18 | CONCEPT 19 | 20 | This program puts miniMO in a low power sleep condition for an adjustable interval of time. 21 | When miniMO wakes up, it plays one out of several preprogrammed sequences, then goes to sleep again. 22 | 23 | I/O 24 | 1&2: Outputs - signal 25 | 3: Input - frequency or note length modulation / set sleep interval (when pressing button) 26 | 4: Input - sequence change 27 | 28 | OPERATION 29 | 30 | Knob: 31 | -If the button is not pressed: change frequency (sequences 00 to 02), note length (sequence 03), or initial note frequency (sequence 04) 32 | -All the tones are square waves 33 | -If the button is pressed: change sleep interval 34 | -The LED toggles ON/OFF with every note played 35 | Button Press: set the sleep interval 36 | -To register the change, you must have the button pressed by the end of the current sequence 37 | -miniMO checks for a button press right before going to sleep 38 | -Depending on the knob's position, the interval can take values from 64ms to 8s 39 | Finger Tap on both terminals of I/O 4: cycle through the available sequences 40 | -To register the change, you must have the terminals pressed by the end of the current sequence 41 | -Available Sequences (in order): 42 | -sequence 00: single beep 43 | -sequence 01: double beep 44 | -sequence 02: SOS in Morse code 45 | -sequence 03: single random tone 46 | -sequence 04: portamento SFX 47 | 48 | BATTERY CHECK 49 | When you switch the module ON, 50 | -If the LED blinks once, the battery is OK 51 | -If the LED blinks fast several times, the battery is running low 52 | 53 | NOTES: 54 | 55 | ON CHANGING THE SEQUENCE 56 | This program uses I/O 4 as a makeshift extra button 57 | The best way to try this feature is to turn miniMO on, wait for a couple beeps, then gently place a finger over BOTH pins of I/O 4, until the sequence changes 58 | This is an experimental feature! if for whatever reason it doesn't work for you, please let me know 59 | To disable this feature, 60 | comment the line that has the following code: if (analogRead(1) < 700) advanceSeq(); 61 | modify playSeq(value from 0 to 4) to set the initial sequence 62 | */ 63 | 64 | #include 65 | 66 | static byte watchdogInterval = 6; //intial watchdog sleep interval (1 sec) 67 | 68 | int currentSeq = 0; 69 | int lastSeqIndex = 4; //index of the last sequence available 70 | 71 | //random number generator 72 | static unsigned long y32 = 1; //pattern length: 32 bit 73 | 74 | void setup() { 75 | 76 | pinMode(0, OUTPUT); //LED 77 | pinMode(4, OUTPUT); //outs 1 and 2 78 | pinMode(3, INPUT); //analog- freq input (knob plus external input 1) 79 | pinMode(1, INPUT); //digital input (push button) 80 | 81 | checkVoltage(); 82 | ADMUX = 0; //reset multiplexer settings 83 | 84 | setup_watchdog(watchdogInterval); //0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms, 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec 85 | set_sleep_mode(SLEEP_MODE_PWR_DOWN); 86 | } 87 | 88 | ISR(WDT_vect) { //the watchdog ISR must be present even if it's empty. Otherwise, the system resets every time it wakes up 89 | } 90 | 91 | void loop() { 92 | 93 | playSeq(currentSeq); 94 | checkButtons(); 95 | sleep(); 96 | 97 | } 98 | 99 | void checkButtons() { 100 | if (analogRead(1) < 700) advanceSeq(); //detect finger tap in I/O 4 -experimental! if doesn't work for you, try different values or comment the line 101 | if(digitalRead(1) == 1){ 102 | watchdogInterval = (analogRead(3) >> 7) + 2; //values between 2 and 9 (64ms to 8s) 103 | setup_watchdog(watchdogInterval); 104 | } 105 | } 106 | 107 | void playSeq(int seq) { 108 | switch (seq) { 109 | case 0: 110 | sequence00(); 111 | break; 112 | case 1: 113 | sequence01(); 114 | break; 115 | case 2: 116 | sequence02(); 117 | break; 118 | case 3: 119 | sequence03(); 120 | break; 121 | case 4: 122 | sequence04(); 123 | break; 124 | } 125 | } 126 | 127 | void advanceSeq() 128 | { 129 | currentSeq++; 130 | if (currentSeq >= lastSeqIndex + 1) currentSeq = 0; 131 | } 132 | 133 | //***********************SEQUENCES************************ 134 | 135 | void sequence00() { //single beep, frequency set by knob's position, length 30ms 136 | freqout((analogRead(3) << 2), 30); 137 | } 138 | 139 | void sequence01() { //double beep 140 | freqout((analogRead(3) << 2), 30); 141 | delay(30); 142 | freqout((analogRead(3) << 2), 30); 143 | } 144 | 145 | void sequence02() { //SOS in Morse Code 146 | dot(); dot(); dot(); 147 | delay(100); //pause between characters is 50. Between words is 150, but we already have 50 from the last character 148 | dash(); dash(); dash(); 149 | delay(100); 150 | dot(); dot(); dot(); 151 | } 152 | 153 | void sequence03() { 154 | freqout(xorshift32(), (analogRead(3) >> 3)); //random frequencies, note legnth set by knob's position 155 | } 156 | 157 | void sequence04() { //descending portamento, initial frequency set by knob's position 158 | int readOut = analogRead(3); 159 | if (readOut < 70) readOut = 70; //lower readouts crash the program 160 | int initial = readOut << 5; //readout * 2^5 (just makes the initial frequency fairly high) 161 | 162 | for (int i = 0; i < 10; i++) { 163 | freqout((initial >> i), 30); //initial / 2^i 164 | delay(initial / (initial >> i)); 165 | } 166 | } 167 | 168 | //******************************************************* 169 | 170 | byte xorshift32(void) { 171 | y32 ^= (y32 << 7); 172 | y32 ^= (y32 >> 5); 173 | return y32 ^= (y32 << 3); //pattern values: 8 bit 174 | } 175 | 176 | //Morse****************************** 177 | void dot() { 178 | freqout((analogRead(3) << 2), 50); 179 | delay(50); 180 | } 181 | 182 | void dash() { 183 | freqout((analogRead(3) << 2), 150); 184 | delay(50); 185 | } 186 | //************************************ 187 | 188 | void freqout(int freq, int t) { 189 | int hperiod; 190 | long cycles, i; 191 | 192 | hperiod = 500000 / (freq - 7); // subtract 7 us to make up for digitalWrite overhead - determined empirically 193 | cycles = ((long)freq * (long)t) / 1000; 194 | 195 | digitalWrite(0, HIGH); //turn LED ON 196 | for (i=0; i<= cycles; i++) { //square wave generation 197 | digitalWrite(4, HIGH); 198 | delayMicroseconds(hperiod); 199 | digitalWrite(4, LOW); 200 | delayMicroseconds(hperiod - 1); 201 | } 202 | digitalWrite(0, LOW); //turn LED OFF 203 | } 204 | 205 | void sleep() { 206 | 207 | ADCSRA &= ~(1 << ADEN); //switch ADC OFF 208 | 209 | sleep_mode(); //nap time! sleep_mode() takes care of enabling and disabling sleep 210 | 211 | ADCSRA |= (1 << ADEN); //switch ADC ON 212 | } 213 | 214 | void setup_watchdog(int ii) { 215 | 216 | byte bb; 217 | bb = ii & 7; //for inputs from 0 to 7, nothing changes. If the inputs are 8 or 9, this sets the fourth bit in bb to 0 218 | if (ii > 7) bb |= (1 << 5); //if the inputs are 8 or 9, sets bit 6 in bb to 1 219 | //why is this? see below 220 | 221 | MCUSR &= ~(1 << WDRF); //clear watchdog reset flag 222 | WDTCR |= (1 << WDCE) | (1 << WDE); //timed sequence to change the wathdog configuration (datasheet p.43) 223 | 224 | WDTCR = bb; //set watchdog prescaler (also clears WDCE: note the equals sign) 225 | //the bits that set the prescaler are not contiguous in the register: from right to left, they take positions 1,2,3, and 6 226 | //the code above took care of that, because if the input is 7 or 8, it sets bit 6 to 1, instead of setting bit 4 to 1 227 | 228 | WDTCR |= (1 << WDIE); //trigger interrupt on time out 229 | } 230 | 231 | void checkVoltage() { //voltage from 255 to 0; 46 is (approx)5v, 94 is 2.8, 104-106 is 2.5 232 | //we measure a fixed value of 1.1 against Vcc, so the lower the measurement, the higher Vcc 233 | ADMUX = (0 << REFS1)|(0 << REFS0); //Vcc as reference 234 | ADMUX |= (1 << ADLAR); //Left adjust result (8 bit conversion stored in ADCH) 235 | ADMUX |= (1 << MUX3) | (1 << MUX2); //1.1v input 236 | delay(250); // Wait for Vref to settle 237 | ADCSRA |= (1 << ADSC); // Start conversion 238 | while (bit_is_set(ADCSRA, ADSC)); // wait while measuring 239 | if (ADCH > 103) //approx 2.6 240 | flashLED(8, 100); 241 | else 242 | flashLED(1, 250); 243 | } 244 | 245 | void flashLED (int times, int gap) { 246 | for (int i = 0; i < times; i++) 247 | { 248 | digitalWrite(0, HIGH); 249 | delay(gap); 250 | digitalWrite(0, LOW); 251 | delay(gap); 252 | } 253 | } 254 | -------------------------------------------------------------------------------- /Programs/DCO/DCO.cpp.hex: -------------------------------------------------------------------------------- 1 | :1000000056C070C070C06EC05AC47EC06BC06AC09B 2 | :1000100069C068C067C066C065C064C063C00000D6 3 | :1000200000000101010202030405050607090A0B8D 4 | :100030000C0E0F1112141517191B1D1F2123252833 5 | :100040002A2C2F313436393B3E414346494C4F52DE 6 | :1000500055585A5D6164676A6D707376797C8083E8 7 | :1000600086898C8F9295989B9EA2A5A7AAADB0B3C6 8 | :10007000B6B9BCBEC1C4C6C9CBCED0D3D5D7DADCE5 9 | :10008000DEE0E2E4E6E8EAEBEDEEF0F1F3F4F5F6BB 10 | :10009000F8F9FAFAFBFCFDFDFEFEFEFFFFFF010290 11 | :1000A000040810200101010101010038003711246A 12 | :1000B0001FBECFE5D2E0DEBFCDBF10E0A0E6B0E0CE 13 | :1000C000E8EAFDE002C005900D92A836B107D9F725 14 | :1000D00021E0A8E6B0E001C01D92AD39B207E1F71A 15 | :1000E0001FD560C68DCF1F920F920FB60F921124AD 16 | :1000F0008F9386B386958170809392018F910F9034 17 | :100100000FBE0F901F9018951F920F920FB60F926F 18 | :1001100011242F933F935F936F937F938F939F93BC 19 | :10012000EF93FF9380916A008BBD2091680030911E 20 | :100130006900E32FFF27E559FF4F808160917A0125 21 | :1001400070E090E033D590936A00809178019091AF 22 | :100150007901820F931F9093690080936800FF914B 23 | :10016000EF919F918F917F916F915F913F912F912F 24 | :100170000F900FBE0F901F901895CF93DF9381E0E3 25 | :1001800080937F0119BE83E046D4EC011092830175 26 | :10019000109282018FEF93E0909381018093800110 27 | :1001A00083E039D48C1B9D0B97FF03C091958195FB 28 | :1001B00091090597ACF3C0E0D0E083E02CD4209106 29 | :1001C000820130918301281739072CF49093830121 30 | :1001D000809382010DC020918001309181018217AE 31 | :1001E00093072CF4909381018093800101C02196A4 32 | :1001F0008FE19EE40197F1F700C00000C83CD105F3 33 | :10020000E4F2609180017091810181E090E0A4D5D9 34 | :10021000609182017091830183E090E09DD51092FE 35 | :100220007F0182E089BFDF91CF910895CF93C82FDE 36 | :100230001092660080917E0181110EC08C2FEBD34D 37 | :100240009C01220F232F221F330B80916400821305 38 | :1002500003C081E080937E0180917E018823B1F00C 39 | :100260008C2FD9D39C0195958795959587958093EB 40 | :100270007B0160916B0170E090E098D490937A01DB 41 | :10028000220F232F221F330B20936400CF91089558 42 | :100290004F925F926F927F92AF92BF92CF92DF9216 43 | :1002A000EF92FF920F931F93182F10927E0180916F 44 | :1002B000660081110EC0812FAED39C013595279524 45 | :1002C0003595279580916500821303C081E0809366 46 | :1002D0006600809166008823E9F1812F9CD39C0100 47 | :1002E000359527953595279520936500A090860133 48 | :1002F000B0908701CC24B7FCC094DC2CE090820144 49 | :10030000F09083010027F7FC0095102F40908001AA 50 | :10031000509081019201442737FD4095542FBC0134 51 | :10032000882777FD8095982FE0918401F0918501D1 52 | :100330002F01662457FC6094762C7F926F925F9217 53 | :100340004F92F2D370937901609378010F900F90E0 54 | :100350000F900F901F910F91FF90EF90DF90CF9033 55 | :10036000BF90AF907F906F905F904F900895EEE1B7 56 | :10037000F0E0ABE6B0E084918D93319680E0EE3909 57 | :10038000F807C9F78FEF8093EB00EBEEF0E0ACEEEF 58 | :10039000B0E082918D9380E0EC36F807D1F70895B4 59 | :1003A0008BE690E0FC012E2F281B219321E0EB36F9 60 | :1003B000F207C9F70895EBE6F0E080E090E0282F1F 61 | :1003C000220F2193019680389105C9F7EBEEF0E0FA 62 | :1003D0008FEF90E0819302978F3F2FEF9207D1F735 63 | :1003E0000895EBE6F0E08FEF819390E0EB3EF907A4 64 | :1003F000D9F7EBEEF0E081E0819391E0EB36F9077D 65 | :10040000D9F70895EBE6F0E081E0819391E0EB36D7 66 | :10041000F907D9F708958230910571F02CF400970F 67 | :1004200049F0019741F008958330910531F0049728 68 | :1004300029F008959CCFBFCFD4CFB2CF60E080E049 69 | :1004400040D3E0CFCF93DF93C0916E01D0916F0185 70 | :10045000CC0FDD1FC059DE4F20916C0130916D0132 71 | :1004600048815981241B350B30936D0120936C0119 72 | :10047000D2D2959587959595879599838883209174 73 | :100480006E0130916F01F901EE0FFF1FE059FE4F31 74 | :1004900080916C0190916D0140815181840F951F75 75 | :1004A00090936D0180936C012F5F3F4F2430310595 76 | :1004B0002CF430936F0120936E0104C010926F01F1 77 | :1004C00010926E0197FD0396959587959595879562 78 | :1004D00080936B01DF91CF9108958130910571F088 79 | :1004E00082309105A1F0892BF1F481E090E09093A6 80 | :1004F00087018093860182E790E011C082E790E057 81 | :10050000909387018093860186E297E008C086E297 82 | :1005100097E090938701809386018CE49EE090930E 83 | :10052000850180938401089560E080E0CAD28FE362 84 | :100530009CE90197F1F700C0000061E080E0C1C2D2 85 | :1005400060E080E0BED28FE39CE90197F1F700C044 86 | :10055000000061E080E0B5D28FE39CE90197F1F7FC 87 | :1005600000C0000060E080E0ACD28FE39CE901971E 88 | :10057000F1F700C0000061E080E0A3C2CF93DF93F9 89 | :10058000C1E0D1E080919201882301F18091900136 90 | :1005900090919101019690939101809390018FE148 91 | :1005A0009EE40197F1F700C0000080918D018C1747 92 | :1005B00049F380919001909191010B971CF3D09396 93 | :1005C0008C01B2DF83E090E031DEDCCF80919201DC 94 | :1005D0008111A5C010928D0180919001909191019F 95 | :1005E000181619060CF09BC0209192018FEC97E031 96 | :1005F0000197F1F700C0000080918E0190918F016A 97 | :10060000019690938F0180938E0130919201332354 98 | :1006100019F0222309F478C08436910529F78091D6 99 | :100620008A0190918B01009759F580918C01882364 100 | :1006300019F010928C0117C077DF80917C019091A6 101 | :100640007D010196853091052CF490937D01809376 102 | :100650007C0104C010927D0110927C0180917C018C 103 | :1006600090917D01D8DE109291011092900110922C 104 | :100670008F0110928E0110928B0110928A014FC04F 105 | :100680008130910539F55CDF809188019091890175 106 | :100690000196833091052CF4909389018093880111 107 | :1006A00004C0109289011092880180918801909174 108 | :1006B000890113DF81E0809366001092910110920E 109 | :1006C000900110928F0110928E0110928B01109266 110 | :1006D0008A0117C002970CF487CF60E080E0F1D167 111 | :1006E0004CDD61E080E0EDD110929101109290011B 112 | :1006F00010928F0110928E0110928B0110928A013C 113 | :1007000081E080938D010BC020918A0130918B0193 114 | :100710002F5F3F4F30938B0120938A017DCFDF9174 115 | :10072000CF9108952BDF80917F0181110EC083E06E 116 | :1007300090E0AEDD81E086DE80917B0160916B010F 117 | :1007400070E090E033D290937A010895CF92DF92D7 118 | :10075000EF92FF920F931F93CF93DF938C01C0E032 119 | :10076000D0E06B01EE24D7FCE094FE2CC017D1073B 120 | :1007700074F461E080E0A5D1C701B6010ED160E05C 121 | :1007800080E09FD1C701B60108D12196EFCFDF915C 122 | :10079000CF911F910F91FF90EF90DF90CF90089530 123 | :1007A00017B83D9A87B18C6087B96AEF70E080E036 124 | :1007B00090E0F3D0369A3699FECF85B1883628F08E 125 | :1007C00064E670E088E090E004C06AEF70E081E0E9 126 | :1007D00090E0BCCF82E080BD8CE084BB61E080E033 127 | :1007E00038D161E084E035D160E083E032D160E06F 128 | :1007F00082E02FD160E081E02CD1D2DF17B881E018 129 | :1008000090E0A5D2909381018093800183E090E0F5 130 | :100810009ED2009711F48FEF93E090938301809321 131 | :10082000820187B5826087BD87EC90E00197F1F780 132 | :1008300000C0000007B400FEFDCF87B5846087BD0F 133 | :10084000F89480E68CBD8FEF8DBD81E080BF93E092 134 | :100850009ABD83BF82E089BF8BB780628BBFA99AA4 135 | :10086000789481E090E0909389018093880182E7F9 136 | :1008700090E0909387018093860186E297E09093C1 137 | :1008800085018093840190937901809378018FEFA3 138 | :1008900080937B0180936B0161E080E012D167CD92 139 | :1008A00083B7887F83BF8AB58C7F81608ABD83B719 140 | :1008B000877F83BF83B7887F836083BF08951F923C 141 | :1008C0000F920FB60F9211242F933F938F939F9304 142 | :1008D000AF93BF938091940190919501A09196015F 143 | :1008E000B09197013091930126E0230F2D3730F01E 144 | :1008F00029E8230F0396A11DB11D03C00296A11D77 145 | :10090000B11D209393018093940190939501A0933E 146 | :100910009601B09397018091980190919901A091CF 147 | :100920009A01B0919B010196A11DB11D8093980180 148 | :1009300090939901A0939A01B0939B01BF91AF91BD 149 | :100940009F918F913F912F910F900FBE0F901F900D 150 | :1009500018953FB7F8948091980190919901A091D2 151 | :100960009A01B0919B012FB508B602FE05C02F3F3A 152 | :1009700019F00196A11DB11D3FBF6627782F892F61 153 | :100980009A2F620F711D811D911D43E0660F771F25 154 | :10099000881F991F4A95D1F70895CF92DF92EF9261 155 | :1009A000FF92CF93DF936B017C01D3DFEB01C11486 156 | :1009B000D104E104F10471F0CCDF6C1B7D0B683EC7 157 | :1009C0007340A8F381E0C81AD108E108F108C851C2 158 | :1009D000DC4FEDCFDF91CF91FF90EF90DF90CF9084 159 | :1009E0000895789480B7806880BF80B7806480BFA6 160 | :1009F0008CB580648CBD8FEF8DBD80B7807F8760A4 161 | :100A000080BF89B7846089BF4BDF86B1887F8660ED 162 | :100A100086B9379A0895863008F0865030919C0147 163 | :100A200027B1932F9295990F990F907C2F72922B4B 164 | :100A300032FB332730F93295307F932B97B997B13A 165 | :100A4000907F982B97B9369A3699FECF84B195B19D 166 | :100A50000895CF93DF93C82FD0E0FE01E256FF4FF9 167 | :100A60008491FE01EC55FF4FC491CC2339F1D0E0C5 168 | :100A7000FE01E455FF4FA491B0E0FE01E655FF4FA3 169 | :100A8000C491D0E02FB7611108C0F8949C91809573 170 | :100A900098239C93988198230AC0623051F4F8946B 171 | :100AA0009C91382F309593239C939881982B988311 172 | :100AB00004C0F8949C91982B9C932FBFDF91CF9109 173 | :100AC0000895A82FB0E0FD01E256FF4F9491FD017B 174 | :100AD000EC55FF4FE491EE2311F1811103C08AB56B 175 | :100AE0008F7304C0813021F48AB58F7C8ABD05C024 176 | :100AF000843019F48CB58F7C8CBDF0E0E655FF4F47 177 | :100B0000A491B0E02FB7611105C0F8948C91909535 178 | :100B1000892303C0F8948C91892B8C932FBF08955F 179 | :100B200060DF58DEFFDDFECF4F925F926F927F92C3 180 | :100B3000AF92BF92CF92DF92EF92FF920F931F93EB 181 | :100B4000CF93DF93CDB7DEB729013A0129893A89DE 182 | :100B50004B895C8964197509860997092A193B092B 183 | :100B60004C095D0950D0A32FF42FE52FE418F508A8 184 | :100B700006091709622F7A2F8F2F9E2FA801970140 185 | :100B800026D02A0D3B1D4C1D5D1DCA01B901DF9108 186 | :100B9000CF911F910F91FF90EF90DF90CF90BF907A 187 | :100BA000AF907F906F905F904F90089500245527ED 188 | :100BB00004C0080E591F880F991F009729F07695D9 189 | :100BC0006795B8F37105B9F7802D952F0895052E17 190 | :100BD00097FB16F400940FD057FD05D068D007FCA2 191 | :100BE00002D046F408C050954095309521953F4F6E 192 | :100BF0004F4F5F4F089590958095709561957F4F09 193 | :100C00008F4F9F4F089568940013E894A0E0B0E0E0 194 | :100C1000EBE0F6E01DC0EFEFE7F959016A015E2352 195 | :100C2000550FEE08FE2C87019B01AC019E23990F06 196 | :100C3000660B762FCB015DD0CDB7DEB7EAE024C0DE 197 | :100C40002F923F924F925F926F927F928F929F92DC 198 | :100C5000AF92BF92CF92DF92EF92FF920F931F93CA 199 | :100C6000CF93DF93CDB7DEB7CA1BDB0B0FB6F8947B 200 | :100C7000DEBF0FBECDBF09942A88398848885F84BB 201 | :100C80006E847D848C849B84AA84B984C884DF802C 202 | :100C9000EE80FD800C811B81AA81B981CE0FD11D10 203 | :100CA0000FB6F894DEBF0FBECDBFED010895A1E2EF 204 | :100CB0001A2EAA1BBB1BFD010DC0AA1FBB1FEE1FD6 205 | :100CC000FF1FA217B307E407F50720F0A21BB30B21 206 | :100CD000E40BF50B661F771F881F991F1A9469F79D 207 | :100CE00060957095809590959B01AC01BD01CF01F9 208 | :100CF0000895DF93CF939F92A0E49A2E0024D00111 209 | :100D0000E001F00116950795F794E794D794C794FE 210 | :100D1000B794A79448F41068A20FB31FC41FD51F3F 211 | :100D2000E61FF71F081E191E220F331F441F551FF1 212 | :100D3000661F771F881F991F9A9421F79D01AE01A6 213 | :100D4000BF01C00111249F90CF91DF910895A8E1C8 214 | :100D5000B0E042E050E006C00196272F12D010C04C 215 | :100D6000DC01CB01FC01E199FECF06C0FFBBEEBB6D 216 | :100D7000E09A31960DB20D9241505040B8F7089567 217 | :100D8000262FE199FECF9FBB8EBBE09A01970DB253 218 | :100D9000021639F01CBA2DBB0FB6F894E29AE19A0C 219 | :080DA0000FBE0895F894FFCF87 220 | :080DA8000100000007FF01003B 221 | :00000001FF 222 | -------------------------------------------------------------------------------- /Programs/LunaMod_Generator/LunaMod_Generator.ino: -------------------------------------------------------------------------------- 1 | /* 2 | //********************** 3 | //* miniMO LUNAMOD * 4 | //* 2017 by enveloop * 5 | //********************** 6 | Based on a Remix by Rob Miles, shown here, http://hosted.hackaday.com/lunaMod45remix.pde 7 | of the original project by Brian McNamara: http://makezine.com/projects/make-26/the-luna-mod-looper/ 8 | 9 | // 10 | http://www.minimosynth.com/ 11 | CC BY 4.0 12 | Licensed under a Creative Commons Attribution 4.0 International license: 13 | http://creativecommons.org/licenses/by/4.0/ 14 | // 15 | 16 | CONCEPT 17 | 18 | This program plays a series of 64 notes in a loop. 19 | While you keep the button pressed, it records the knob's positions as notes in the loop. 20 | Depending of the tempo and the time you keep the button pressed, you can modify individual notes, or the entire loop at once. 21 | 22 | I/O 23 | 1&2: Outputs - signal 24 | 3: Input - frequency/tempo modulation 25 | 4: Input - wave change 26 | 27 | OPERATION 28 | 29 | Knob: change tempo (default) or frequency 30 | -If you change tempo, miniMO waits until you reach the value it has currently stored 31 | -The LED toggles ON/OFF every 8 notes to give an indication of the tempo 32 | Button Press: record the knob's position 33 | -Recording continues for as long as the button is pressed 34 | -After the button is depressed, the knob controls tempo once more 35 | Finger Tap on both terminals of I/O 4: cycle through the available wave shapes 36 | -Shapes (in order): triangle, square, and saw 37 | -You can also use an external source to change waves automatically 38 | 39 | BATTERY CHECK 40 | When you switch the module ON, 41 | -If the LED blinks once, the battery is OK 42 | -If the LED blinks fast several times, the battery is running low 43 | 44 | NOTES: 45 | 46 | ON CHANGING THE WAVE 47 | This program uses I/O 4 as a makeshift extra button. 48 | The best way to try this feature is to set the tempo to a low value, then gently place a finger over BOTH pins of I/O 4, until the wave changes. 49 | Usually it takes pressing for about a "LED interval" for the wave to change. 50 | This is an experimental feature! if for whatever reason it doesn't work for you, please let me know 51 | To disable this feature, 52 | comment the line that has the following code: if (analogRead(1) < 700) advanceWave(); 53 | modify writeWave(value from 0 to 2) to set the initial wave shape. 54 | */ 55 | 56 | #include 57 | 58 | //tone sequence 59 | int currentStep = 0; 60 | int steps[] = {500, 500, 100, 100, 100, 100, 100, 100, //Initial array of tones. The values are translated to frequencies (warning: "100" is not 100 HZ!) 61 | 100, 100, 100, 100, 100, 100, 100, 100, 62 | 500, 500, 100, 100, 100, 100, 100, 100, //The values here determine the melody that plays when you turn the unit ON 63 | 100, 100, 100, 100, 100, 100, 100, 100, 64 | 500, 500, 100, 100, 100, 100, 100, 100, 65 | 100, 100, 100, 100, 100, 100, 100, 100, 66 | 500, 500, 100, 100, 100, 100, 100, 100, 67 | 100, 100, 100, 100, 100, 100, 100, 100 68 | }; 69 | 70 | //sound generation 71 | volatile unsigned int frequency; 72 | unsigned char wavetable[256]; //the table that stores the shape of the waves for PWM sound generation 73 | int currentWave; 74 | 75 | //tempo control 76 | int tempoReading; 77 | byte tempoCoarse; 78 | int tempo = 2000; //max value for tempo = 1023 << 2 (see setTempo below) 79 | bool tempoChange = false; 80 | 81 | void setup() 82 | { 83 | PRR = (1 << PRUSI); //disable USI to save power as we are not using it 84 | DIDR0 = (1 << ADC1D) | (1 << ADC3D); //PB2,PB3 //disable digital input in pins that do analog conversion 85 | 86 | pinMode(0, OUTPUT); //LED 87 | pinMode(4, OUTPUT); //timer 1 in digital output 4 - outs 1 and 2 88 | pinMode(3, INPUT); //analog- tempo/freq input (knob plus external input 1) 89 | pinMode(2, INPUT); //analog- tap input (experimental) 90 | pinMode(1, INPUT); //digital input (push button) 91 | 92 | checkVoltage(); 93 | ADMUX = 0; //reset multiplexer settings 94 | 95 | //set clock source for PWM -datasheet p94 96 | PLLCSR |= (1 << PLLE); // Enable PLL (64 MHz) 97 | _delay_us(100); // Wait for a steady state 98 | while (!(PLLCSR & (1 << PLOCK))); // Ensure PLL lock 99 | PLLCSR |= (1 << PCKE); // Enable PLL as clock source for timer 1 100 | 101 | cli(); // Interrupts OFF (disable interrupts globally) 102 | 103 | //PWM Generation -timer 1 104 | GTCCR = (1 << PWM1B) | (1 << COM1B1); // PWM, output on pb4, compare with OCR1B (see interrupt below), reset on match with OCR1C 105 | OCR1C = 0xff; // 255 106 | TCCR1 = (1 << CS10); // no prescale 107 | 108 | //Timer Interrupt Generation -timer 0 109 | TCCR0A = (1 << WGM01) | (1 << WGM00); // fast PWM 110 | TCCR0B = (1 << CS00); // no prescale 111 | TIMSK = (1 << TOIE0); // Enable Interrupt on overflow 112 | 113 | sei(); // Interrupts ON (enable interrupts globally) 114 | 115 | writeWave(0); 116 | 117 | delay(40000); // delay to help tell when the LED blinking from battery reading stops 118 | } 119 | 120 | ISR(TIMER0_OVF_vect) { //Timer 0 interruption - changes the width of timer 1's pulse to generate waves 121 | static byte sample; 122 | static unsigned int phase; 123 | OCR1B = sample; 124 | sample = wavetable[phase >> 8]; 125 | phase += frequency; //phase accumulator 126 | } 127 | 128 | void loop() { 129 | for (int i = 0; i < 64; i++) { //reads through the note array 130 | currentStep = i; 131 | if (i == 0 || i == 15 || i == 31 || i == 47) { 132 | digitalWrite(0, HIGH); //turn the LED ON every 16 notes 133 | } 134 | else if (i == 7 || i == 23 || i == 39 || i == 55) { 135 | digitalWrite(0, LOW); //turn the LED OFF every 16 notes, with an offset of 8 (combined with the code above, toggles the LED every 8 notes) 136 | if (analogRead(1) < 700) advanceWave(); //detect finger tap in I/O 4 -experimental! if doesn't work for you, try different values or comment the line 137 | } 138 | if (digitalRead(1) == HIGH) { //if the button is being pressed 139 | tempoChange = false; //reset the tempo change condition 140 | steps[currentStep] = (analogRead(3) << 4); //write the knob's position in the note array 141 | frequency = steps[currentStep]; 142 | } 143 | else { //if the button is not pressed 144 | setTempo(); //change the tempo (see below) 145 | frequency = steps[currentStep]; //change the frequency according to the current step 146 | } 147 | delay(4092-tempo); //wait a bit. 4092 is the maximum value the delay can take (see setTempo). The expression 4092-tempo nakes the positions that give the lowest notes also give the lowest tempos 148 | } 149 | } 150 | 151 | //We want the tempo to change only if we return to the vaue where we left it after controlling something else 152 | //so we store the knob's position in a variable and check the current position against it; 153 | //when we reach it, we start controlling the parameter again. 154 | 155 | void setTempo() { 156 | if (tempoChange) { 157 | tempoReading = analogRead(3); 158 | tempoCoarse = tempoReading >> 4; //right shifting by 4 to get values between 0 and 63 (0-1023/2^4). Less resolution makes it easier to track 159 | tempo = tempoReading << 2; //Here we decide what's the actual tempo.The max value is 1023 << 2 160 | } 161 | else if ((analogRead(3) >> 4) == tempoCoarse) { //check control input against stored value. If the value is the same (because we have moved the knob to the last known position for that parameter), 162 | tempoChange = true; //it is ok to change the value :) 163 | } 164 | } 165 | 166 | void advanceWave() 167 | { 168 | currentWave++; //change the wave 169 | if (currentWave >= 3) currentWave = 0; 170 | writeWave(currentWave); 171 | } 172 | 173 | void writeWave(int wave) { 174 | switch (wave) { 175 | case 0: 176 | triangleWave(); 177 | break; 178 | case 1: 179 | squareWave(); 180 | break; 181 | case 2: 182 | sawtoothWave(); 183 | break; 184 | } 185 | } 186 | 187 | //functions to populate the wavetable 188 | void sawtoothWave() { 189 | for (int i = 0; i < 256; ++i) { 190 | wavetable[i] = i; // sawtooth 191 | } 192 | } 193 | void triangleWave() { 194 | for (int i = 0; i < 128; ++i) { 195 | wavetable[i] = i * 2; 196 | } 197 | int value = 255; 198 | for (int i = 128; i < 256; ++i) { 199 | wavetable[i] = value; 200 | value -= 2; 201 | } 202 | } 203 | void squareWave() { 204 | for (int i = 0; i < 128; ++i) { 205 | wavetable[i] = 255; 206 | } 207 | for (int i = 128; i < 256; ++i) { 208 | wavetable[i] = 1; //0 gives problems (offset and different freq), related to sample = ((wavetable[phase >> 8]*amplitude)>>8); 209 | } 210 | } 211 | 212 | void checkVoltage() { //voltage from 255 to 0; 46 is (approx)5v, 94 is 2.8, 104-106 is 2.5 213 | //we measure a fixed value of 1.1 against Vcc, so the lower the measurement, the higher Vcc 214 | ADMUX = (0 << REFS1)|(0 << REFS0); //Vcc as reference 215 | ADMUX |= (1 << ADLAR); //Left adjust result (8 bit conversion stored in ADCH) 216 | ADMUX |= (1 << MUX3) | (1 << MUX2); //1.1v input 217 | delay(250); // Wait for Vref to settle 218 | ADCSRA |= (1 << ADSC); // Start conversion 219 | while (bit_is_set(ADCSRA, ADSC)); // wait while measuring 220 | if (ADCH > 103) //approx 2.6 221 | flashLED(8, 100); 222 | else 223 | flashLED(1, 250); 224 | } 225 | 226 | void flashLED (int times, int gap) { //for voltage check only (uses regular delay) 227 | for (int i = 0; i < times; i++) 228 | { 229 | digitalWrite(0, HIGH); 230 | delay(gap); 231 | digitalWrite(0, LOW); 232 | delay(gap); 233 | } 234 | } 235 | -------------------------------------------------------------------------------- /Programs/LPF/LPF.ino: -------------------------------------------------------------------------------- 1 | /* 2 | //****************************** 3 | //* miniMO Low Pass Filter * 4 | //* 2017 by enveloop * 5 | //****************************** 6 | Based on the Filter Algorithm 7 | by Rohan Hill, 8 | as described Here: 9 | https://beammyselfintothefuture.wordpress.com/2015/02/16/simple-c-code-for-resonant-lpf-hpf-filters-and-high-low-shelving-eqs/ 10 | 11 | // 12 | http://www.minimosynth.com/ 13 | CC BY 4.0 14 | Licensed under a Creative Commons Attribution 4.0 International license: 15 | http://creativecommons.org/licenses/by/4.0/ 16 | // 17 | 18 | WARNING! This filter can self-oscillate, producing very loud tones 19 | 20 | I/O 21 | 1&2 Outputs - filtered signal 22 | 3: Input - frequency/resonance modulation 23 | 4: Input - audio signal 24 | 25 | OPERATION 26 | Knob: change frequency (default) or resonance 27 | -miniMO waits until you reach the value it has currently stored 28 | Click: toggle between frequency and resonance control 29 | -The LED blinks once - frequency control 30 | -The LED blinks twice - resonance control 31 | 32 | BATTERY CHECK 33 | When you switch the module ON, 34 | -If the LED blinks once, the battery is OK 35 | -If the LED blinks fast several times, the battery is running low 36 | 37 | */ 38 | 39 | #include 40 | 41 | //button input interrupt 42 | bool inputButtonValue; 43 | 44 | //audio and control signal interrupt 45 | byte audioInput, controlInput; 46 | int count; 47 | byte sensorMinDefault = 63; 48 | byte sensorMin; 49 | 50 | //control parameters 51 | bool parameterChange = true; //behaviour after turning on: change cutoff frequency 52 | int currentParameter = 0; 53 | byte parameters[] = { 54 | 255, //frequency (255: filteropen) 55 | 0 //resonance 56 | }; 57 | 58 | //button press control 59 | int button_delay; 60 | 61 | //LPF parameters 62 | int lastOutput, output; 63 | int momentum; 64 | 65 | void setup() { 66 | 67 | PRR = (1 << PRUSI); //disable USI to save power as we are not using it 68 | DIDR0 = (1 << ADC1D) | (1 << ADC3D); //PB2,PB3 //disable digital input in pins that do analog conversion 69 | 70 | pinMode(0, OUTPUT); //LED 71 | pinMode(4, OUTPUT); //audio output - outs 1 and 2 72 | pinMode(3, INPUT); //analog- control input (knob plus external input 1) 73 | pinMode(2, INPUT); //analog- audio input (external input 2) 74 | pinMode(1, INPUT); //digital input (push button) 75 | 76 | checkVoltage(); 77 | 78 | ADCSRA = (1< 200) { //if the threshold is not reached after a while, 133 | sensorMin = sensorMinDefault; //reset 134 | count = 0; 135 | } 136 | else count++; 137 | } 138 | } 139 | else { //if the control input is selected 140 | controlInput = ADCH; //read the value 141 | sensorMin = sensorMinDefault; //reset sensorMin 142 | ADMUX &= ~(1 << MUX1); //select the audio input (ADC1, so MUX1 = 0 and MUX0=1. MUX0 was already set to 1 during setup) 143 | } 144 | 145 | ADCSRA |= (1< 0)) { //button released after a while (regular single click) 170 | currentParameter++; 171 | if (currentParameter > 1) currentParameter = 0; //2 parameters, indexes 0 and 1 172 | flashLEDSlow(currentParameter + 1); //parameter 0 - flash once, etc 173 | parameterChange = false; 174 | button_delay = 0; 175 | } 176 | } 177 | 178 | int doResonantLPF(int input) { 179 | 180 | input = input << 3; 181 | int distanceToGo = input - lastOutput; 182 | momentum = momentum + distanceToGo; 183 | lastOutput = lastOutput + scale(momentum, parameters[1]) + scale(distanceToGo, parameters[0]); 184 | 185 | output = ((lastOutput) >> 3) + (parameters[1] >> 2); 186 | 187 | if (output < 0) { output = 0; momentum = momentum >> 1;} 188 | if (output > 255) {output = 255; momentum = momentum >> 1;} 189 | 190 | return output; 191 | } 192 | 193 | int scale(int input, byte factor) { 194 | 195 | int output = //every line adds precision - and output noise 196 | ( (input>>1) & (-((128&factor)>>7)) ) 197 | + ( (input>>2) & (-((64&factor)>>6)) ) 198 | + ( (input>>3) & (-((32&factor)>>5)) ) 199 | + ( (input>>4) & (-((16&factor)>>4)) ) 200 | + ( (input>>5) & (-((8&factor)>>3)) ) ; 201 | /* + ( (input>>6) & (-((4&factor)>>2)) ) 202 | + ( (input>>7) & (-((2&factor)>>1)) ) 203 | + ( (input>>8) & (- (1&factor) ) ); */ 204 | 205 | return output; 206 | } 207 | 208 | void checkVoltage() { //voltage from 255 to 0; 46 is (approx)5v, 94 is 2.8, 104-106 is 2.5 209 | //we measure a fixed value of 1.1 against Vcc, so the lower the measurement, the higher Vcc 210 | ADMUX = (0 << REFS1) | (0 << REFS0); //Vcc as reference 211 | ADMUX |= (1 << ADLAR); //Left adjust result (8 bit conversion stored in ADCH) 212 | ADMUX |= (1 << MUX3) | (1 << MUX2); //1.1v input 213 | delay(250); //Wait for Vref to settle 214 | ADCSRA |= (1 << ADSC); //Start conversion 215 | while (bit_is_set(ADCSRA, ADSC)); //wait while measuring 216 | if (ADCH > 103) //approx 2.6 217 | flashLED(8, 100); 218 | else 219 | flashLED(1, 250); 220 | } 221 | 222 | void flashLED (int times, int gap) { //for voltage check only (uses regular delay) 223 | for (int i = 0; i < times; i++) 224 | { 225 | digitalWrite(0, HIGH); 226 | delay(gap); 227 | digitalWrite(0, LOW); 228 | delay(gap); 229 | } 230 | } 231 | 232 | void flashLEDSlow(int times) { 233 | for (int i = 0; i < times; i++){ 234 | _delay_ms(100); 235 | digitalWrite(0, LOW); 236 | _delay_ms(100); 237 | digitalWrite(0, HIGH); 238 | } 239 | } 240 | -------------------------------------------------------------------------------- /BOM_and_schematic/Gerber_panel_2x2/combined.gbs: -------------------------------------------------------------------------------- 1 | %MOIN*% 2 | %OFA0B0*% 3 | %FSLAX46Y46*% 4 | %IPPOS*% 5 | %LPD*% 6 | %ADD10C,0.0039370078740157488*% 7 | %ADD11R,0.066929133858267723X0.066929133858267723*% 8 | %ADD12C,0.066929133858267723*% 9 | %ADD13R,0.094488188976377951X0.094488188976377951*% 10 | %ADD14C,0.094488188976377951*% 11 | %ADD15O,0.07874015748031496X0.07874015748031496*% 12 | %ADD16R,0.095748031496063X0.095748031496063*% 13 | %ADD17O,0.095748031496063X0.095748031496063*% 14 | %ADD18C,0.094448031496063*% 15 | %ADD19R,0.095748031496063X0.083748031496063011*% 16 | %ADD20O,0.095748031496063X0.083748031496063011*% 17 | %ADD21R,0.083748031496063011X0.095748031496063*% 18 | %ADD22O,0.083748031496063011X0.095748031496063*% 19 | %ADD33C,0.0039370078740157488*% 20 | %ADD34R,0.066929133858267723X0.066929133858267723*% 21 | %ADD35C,0.066929133858267723*% 22 | %ADD36R,0.094488188976377951X0.094488188976377951*% 23 | %ADD37C,0.094488188976377951*% 24 | %ADD38O,0.07874015748031496X0.07874015748031496*% 25 | %ADD39R,0.095748031496063X0.095748031496063*% 26 | %ADD40O,0.095748031496063X0.095748031496063*% 27 | %ADD41C,0.094448031496063*% 28 | %ADD42R,0.095748031496063X0.083748031496063011*% 29 | %ADD43O,0.095748031496063X0.083748031496063011*% 30 | %ADD44R,0.083748031496063011X0.095748031496063*% 31 | %ADD45O,0.083748031496063011X0.095748031496063*% 32 | %ADD46C,0.0039370078740157488*% 33 | %ADD47R,0.066929133858267723X0.066929133858267723*% 34 | %ADD48C,0.066929133858267723*% 35 | %ADD49R,0.094488188976377951X0.094488188976377951*% 36 | %ADD50C,0.094488188976377951*% 37 | %ADD51O,0.07874015748031496X0.07874015748031496*% 38 | %ADD52R,0.095748031496063X0.095748031496063*% 39 | %ADD53O,0.095748031496063X0.095748031496063*% 40 | %ADD54C,0.094448031496063*% 41 | %ADD55R,0.095748031496063X0.083748031496063011*% 42 | %ADD56O,0.095748031496063X0.083748031496063011*% 43 | %ADD57R,0.083748031496063011X0.095748031496063*% 44 | %ADD58O,0.083748031496063011X0.095748031496063*% 45 | %ADD59C,0.0039370078740157488*% 46 | %ADD60R,0.066929133858267723X0.066929133858267723*% 47 | %ADD61C,0.066929133858267723*% 48 | %ADD62R,0.094488188976377951X0.094488188976377951*% 49 | %ADD63C,0.094488188976377951*% 50 | %ADD64O,0.07874015748031496X0.07874015748031496*% 51 | %ADD65R,0.095748031496063X0.095748031496063*% 52 | %ADD66O,0.095748031496063X0.095748031496063*% 53 | %ADD67C,0.094448031496063*% 54 | %ADD68R,0.095748031496063X0.083748031496063011*% 55 | %ADD69O,0.095748031496063X0.083748031496063011*% 56 | %ADD70R,0.083748031496063011X0.095748031496063*% 57 | %ADD71O,0.083748031496063011X0.095748031496063*% 58 | G01* 59 | D10* 60 | D11* 61 | X0005787401Y-0004055118D02* 62 | X0001067401Y0000894881D03* 63 | D12* 64 | X0001165826Y0000894881D03* 65 | D11* 66 | X0001337401Y0001014881D03* 67 | D12* 68 | X0001337401Y0000916456D03* 69 | D11* 70 | X0001067401Y0001024881D03* 71 | D12* 72 | X0001165826Y0001024881D03* 73 | D13* 74 | X0000271653Y0000372598D03* 75 | D14* 76 | X0000371653Y0000372598D03* 77 | D15* 78 | X0001367401Y0000424881D03* 79 | X0001367401Y0000524881D03* 80 | X0001367401Y0000624881D03* 81 | X0001367401Y0000724881D03* 82 | X0001067401Y0000724881D03* 83 | X0001067401Y0000624881D03* 84 | X0001067401Y0000524881D03* 85 | X0001067401Y0000424881D03* 86 | D16* 87 | X0001087401Y0000204881D03* 88 | D17* 89 | X0001187401Y0000204881D03* 90 | D16* 91 | X0000687401Y0000204881D03* 92 | D17* 93 | X0000787401Y0000204881D03* 94 | D16* 95 | X0001497401Y0000894881D03* 96 | D17* 97 | X0001497401Y0000994881D03* 98 | D16* 99 | X0001497401Y0000494881D03* 100 | D17* 101 | X0001497401Y0000594881D03* 102 | D18* 103 | X0000921653Y0001089133D03* 104 | X0000621653Y0001089133D03* 105 | X0001118503Y0001408031D03* 106 | X0000818503Y0001408031D03* 107 | X0000818503Y0001522204D03* 108 | X0001118503Y0001522204D03* 109 | X0000913779Y0000348976D03* 110 | X0000613779Y0000348976D03* 111 | X0000621653Y0000978897D03* 112 | X0000921653Y0000978897D03* 113 | X0000613779Y0000549763D03* 114 | X0000913779Y0000549763D03* 115 | X0001163338Y0001142266D03* 116 | X0001419338Y0001319466D03* 117 | X0001163338Y0001319466D03* 118 | X0001419338Y0001142266D03* 119 | D19* 120 | X0000417322Y0001034015D03* 121 | D20* 122 | X0000417322Y0000934015D03* 123 | X0000417322Y0000834015D03* 124 | X0000417322Y0000734015D03* 125 | X0000417322Y0000634015D03* 126 | X0000417322Y0000534015D03* 127 | D14* 128 | X0000952755Y0001230866D03* 129 | X0000952755Y0000443464D03* 130 | D18* 131 | X0000714517Y0000864699D03* 132 | X0000901574Y0000766299D03* 133 | X0000714517Y0000667899D03* 134 | D21* 135 | X0000448818Y0001224409D03* 136 | D22* 137 | X0000548818Y0001224409D03* 138 | X0000648818Y0001224409D03* 139 | G04 next file* 140 | G04 #@! TF.FileFunction,Soldermask,Bot* 141 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 142 | G04 Created by KiCad (PCBNEW 4.0.1-stable) date 10/18/2017 12:48:17 AM* 143 | G01* 144 | G04 APERTURE LIST* 145 | G04 APERTURE END LIST* 146 | D33* 147 | D34* 148 | X0005787401Y-0002476377D02* 149 | X0001067401Y0002473621D03* 150 | D35* 151 | X0001165826Y0002473621D03* 152 | D34* 153 | X0001337401Y0002593621D03* 154 | D35* 155 | X0001337401Y0002495196D03* 156 | D34* 157 | X0001067401Y0002603621D03* 158 | D35* 159 | X0001165826Y0002603621D03* 160 | D36* 161 | X0000271653Y0001951338D03* 162 | D37* 163 | X0000371653Y0001951338D03* 164 | D38* 165 | X0001367401Y0002003621D03* 166 | X0001367401Y0002103621D03* 167 | X0001367401Y0002203621D03* 168 | X0001367401Y0002303621D03* 169 | X0001067401Y0002303621D03* 170 | X0001067401Y0002203621D03* 171 | X0001067401Y0002103621D03* 172 | X0001067401Y0002003621D03* 173 | D39* 174 | X0001087401Y0001783621D03* 175 | D40* 176 | X0001187401Y0001783621D03* 177 | D39* 178 | X0000687401Y0001783621D03* 179 | D40* 180 | X0000787401Y0001783621D03* 181 | D39* 182 | X0001497401Y0002473621D03* 183 | D40* 184 | X0001497401Y0002573621D03* 185 | D39* 186 | X0001497401Y0002073621D03* 187 | D40* 188 | X0001497401Y0002173621D03* 189 | D41* 190 | X0000921653Y0002667873D03* 191 | X0000621653Y0002667873D03* 192 | X0001118503Y0002986771D03* 193 | X0000818503Y0002986771D03* 194 | X0000818503Y0003100944D03* 195 | X0001118503Y0003100944D03* 196 | X0000913779Y0001927716D03* 197 | X0000613779Y0001927716D03* 198 | X0000621653Y0002557637D03* 199 | X0000921653Y0002557637D03* 200 | X0000613779Y0002128503D03* 201 | X0000913779Y0002128503D03* 202 | X0001163338Y0002721006D03* 203 | X0001419338Y0002898206D03* 204 | X0001163338Y0002898206D03* 205 | X0001419338Y0002721006D03* 206 | D42* 207 | X0000417322Y0002612755D03* 208 | D43* 209 | X0000417322Y0002512755D03* 210 | X0000417322Y0002412755D03* 211 | X0000417322Y0002312755D03* 212 | X0000417322Y0002212755D03* 213 | X0000417322Y0002112755D03* 214 | D37* 215 | X0000952755Y0002809606D03* 216 | X0000952755Y0002022204D03* 217 | D41* 218 | X0000714517Y0002443439D03* 219 | X0000901574Y0002345039D03* 220 | X0000714517Y0002246639D03* 221 | D44* 222 | X0000448818Y0002803149D03* 223 | D45* 224 | X0000548818Y0002803149D03* 225 | X0000648818Y0002803149D03* 226 | G04 next file* 227 | G04 #@! TF.FileFunction,Soldermask,Bot* 228 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 229 | G04 Created by KiCad (PCBNEW 4.0.1-stable) date 10/18/2017 12:48:17 AM* 230 | G01* 231 | G04 APERTURE LIST* 232 | G04 APERTURE END LIST* 233 | D46* 234 | D47* 235 | X-0002500000Y0005728346D02* 236 | X0002220000Y0000778346D03* 237 | D48* 238 | X0002121574Y0000778346D03* 239 | D47* 240 | X0001950000Y0000658346D03* 241 | D48* 242 | X0001950000Y0000756771D03* 243 | D47* 244 | X0002220000Y0000648346D03* 245 | D48* 246 | X0002121574Y0000648346D03* 247 | D49* 248 | X0003015748Y0001300629D03* 249 | D50* 250 | X0002915748Y0001300629D03* 251 | D51* 252 | X0001920000Y0001248346D03* 253 | X0001920000Y0001148346D03* 254 | X0001920000Y0001048346D03* 255 | X0001920000Y0000948346D03* 256 | X0002220000Y0000948346D03* 257 | X0002220000Y0001048346D03* 258 | X0002220000Y0001148346D03* 259 | X0002220000Y0001248346D03* 260 | D52* 261 | X0002199999Y0001468346D03* 262 | D53* 263 | X0002100000Y0001468346D03* 264 | D52* 265 | X0002599999Y0001468346D03* 266 | D53* 267 | X0002500000Y0001468346D03* 268 | D52* 269 | X0001789999Y0000778346D03* 270 | D53* 271 | X0001789999Y0000678346D03* 272 | D52* 273 | X0001789999Y0001178346D03* 274 | D53* 275 | X0001789999Y0001078346D03* 276 | D54* 277 | X0002365748Y0000584094D03* 278 | X0002665748Y0000584094D03* 279 | X0002168897Y0000265196D03* 280 | X0002468897Y0000265196D03* 281 | X0002468897Y0000151023D03* 282 | X0002168897Y0000151023D03* 283 | X0002373622Y0001324251D03* 284 | X0002673622Y0001324251D03* 285 | X0002665748Y0000694330D03* 286 | X0002365748Y0000694330D03* 287 | X0002673622Y0001123464D03* 288 | X0002373622Y0001123464D03* 289 | X0002124062Y0000530962D03* 290 | X0001868062Y0000353762D03* 291 | X0002124062Y0000353762D03* 292 | X0001868062Y0000530962D03* 293 | D55* 294 | X0002870078Y0000639212D03* 295 | D56* 296 | X0002870078Y0000739212D03* 297 | X0002870078Y0000839212D03* 298 | X0002870078Y0000939212D03* 299 | X0002870078Y0001039212D03* 300 | X0002870078Y0001139212D03* 301 | D50* 302 | X0002334645Y0000442362D03* 303 | X0002334645Y0001229763D03* 304 | D54* 305 | X0002572884Y0000808529D03* 306 | X0002385826Y0000906929D03* 307 | X0002572884Y0001005329D03* 308 | D57* 309 | X0002838582Y0000448818D03* 310 | D58* 311 | X0002738582Y0000448818D03* 312 | X0002638582Y0000448818D03* 313 | G04 next file* 314 | G04 #@! TF.FileFunction,Soldermask,Bot* 315 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 316 | G04 Created by KiCad (PCBNEW 4.0.1-stable) date 10/18/2017 12:48:17 AM* 317 | G01* 318 | G04 APERTURE LIST* 319 | G04 APERTURE END LIST* 320 | D59* 321 | D60* 322 | X-0002503936Y0007311024D02* 323 | X0002216063Y0002361024D03* 324 | D61* 325 | X0002117637Y0002361024D03* 326 | D60* 327 | X0001946063Y0002241024D03* 328 | D61* 329 | X0001946063Y0002339449D03* 330 | D60* 331 | X0002216063Y0002231024D03* 332 | D61* 333 | X0002117637Y0002231024D03* 334 | D62* 335 | X0003011811Y0002883307D03* 336 | D63* 337 | X0002911811Y0002883307D03* 338 | D64* 339 | X0001916063Y0002831024D03* 340 | X0001916063Y0002731024D03* 341 | X0001916063Y0002631024D03* 342 | X0001916063Y0002531024D03* 343 | X0002216063Y0002531024D03* 344 | X0002216063Y0002631024D03* 345 | X0002216063Y0002731024D03* 346 | X0002216063Y0002831024D03* 347 | D65* 348 | X0002196063Y0003051024D03* 349 | D66* 350 | X0002096063Y0003051024D03* 351 | D65* 352 | X0002596063Y0003051024D03* 353 | D66* 354 | X0002496063Y0003051024D03* 355 | D65* 356 | X0001786063Y0002361024D03* 357 | D66* 358 | X0001786063Y0002261024D03* 359 | D65* 360 | X0001786063Y0002761024D03* 361 | D66* 362 | X0001786063Y0002661024D03* 363 | D67* 364 | X0002361811Y0002166772D03* 365 | X0002661811Y0002166772D03* 366 | X0002164960Y0001847874D03* 367 | X0002464960Y0001847874D03* 368 | X0002464960Y0001733701D03* 369 | X0002164960Y0001733701D03* 370 | X0002369685Y0002906929D03* 371 | X0002669685Y0002906929D03* 372 | X0002661811Y0002277008D03* 373 | X0002361811Y0002277008D03* 374 | X0002669685Y0002706142D03* 375 | X0002369685Y0002706142D03* 376 | X0002120126Y0002113639D03* 377 | X0001864126Y0001936439D03* 378 | X0002120126Y0001936439D03* 379 | X0001864126Y0002113639D03* 380 | D68* 381 | X0002866141Y0002221890D03* 382 | D69* 383 | X0002866141Y0002321890D03* 384 | X0002866141Y0002421890D03* 385 | X0002866141Y0002521890D03* 386 | X0002866141Y0002621890D03* 387 | X0002866141Y0002721890D03* 388 | D63* 389 | X0002330708Y0002025039D03* 390 | X0002330708Y0002812441D03* 391 | D67* 392 | X0002568947Y0002391206D03* 393 | X0002381889Y0002489606D03* 394 | X0002568947Y0002588006D03* 395 | D70* 396 | X0002834645Y0002031496D03* 397 | D71* 398 | X0002734645Y0002031496D03* 399 | X0002634645Y0002031496D03* 400 | M02* -------------------------------------------------------------------------------- /BOM_and_schematic/Gerber_panel_2x2/combined.gts: -------------------------------------------------------------------------------- 1 | %MOIN*% 2 | %OFA0B0*% 3 | %FSLAX46Y46*% 4 | %IPPOS*% 5 | %LPD*% 6 | %ADD10C,0.0039370078740157488*% 7 | %ADD11R,0.066929133858267723X0.066929133858267723*% 8 | %ADD12C,0.066929133858267723*% 9 | %ADD13R,0.094488188976377951X0.094488188976377951*% 10 | %ADD14C,0.094488188976377951*% 11 | %ADD15O,0.07874015748031496X0.07874015748031496*% 12 | %ADD16R,0.095748031496063X0.095748031496063*% 13 | %ADD17O,0.095748031496063X0.095748031496063*% 14 | %ADD18C,0.094448031496063*% 15 | %ADD19R,0.095748031496063X0.083748031496063011*% 16 | %ADD20O,0.095748031496063X0.083748031496063011*% 17 | %ADD21R,0.083748031496063011X0.095748031496063*% 18 | %ADD22O,0.083748031496063011X0.095748031496063*% 19 | %ADD33C,0.0039370078740157488*% 20 | %ADD34R,0.066929133858267723X0.066929133858267723*% 21 | %ADD35C,0.066929133858267723*% 22 | %ADD36R,0.094488188976377951X0.094488188976377951*% 23 | %ADD37C,0.094488188976377951*% 24 | %ADD38O,0.07874015748031496X0.07874015748031496*% 25 | %ADD39R,0.095748031496063X0.095748031496063*% 26 | %ADD40O,0.095748031496063X0.095748031496063*% 27 | %ADD41C,0.094448031496063*% 28 | %ADD42R,0.095748031496063X0.083748031496063011*% 29 | %ADD43O,0.095748031496063X0.083748031496063011*% 30 | %ADD44R,0.083748031496063011X0.095748031496063*% 31 | %ADD45O,0.083748031496063011X0.095748031496063*% 32 | %ADD46C,0.0039370078740157488*% 33 | %ADD47R,0.066929133858267723X0.066929133858267723*% 34 | %ADD48C,0.066929133858267723*% 35 | %ADD49R,0.094488188976377951X0.094488188976377951*% 36 | %ADD50C,0.094488188976377951*% 37 | %ADD51O,0.07874015748031496X0.07874015748031496*% 38 | %ADD52R,0.095748031496063X0.095748031496063*% 39 | %ADD53O,0.095748031496063X0.095748031496063*% 40 | %ADD54C,0.094448031496063*% 41 | %ADD55R,0.095748031496063X0.083748031496063011*% 42 | %ADD56O,0.095748031496063X0.083748031496063011*% 43 | %ADD57R,0.083748031496063011X0.095748031496063*% 44 | %ADD58O,0.083748031496063011X0.095748031496063*% 45 | %ADD59C,0.0039370078740157488*% 46 | %ADD60R,0.066929133858267723X0.066929133858267723*% 47 | %ADD61C,0.066929133858267723*% 48 | %ADD62R,0.094488188976377951X0.094488188976377951*% 49 | %ADD63C,0.094488188976377951*% 50 | %ADD64O,0.07874015748031496X0.07874015748031496*% 51 | %ADD65R,0.095748031496063X0.095748031496063*% 52 | %ADD66O,0.095748031496063X0.095748031496063*% 53 | %ADD67C,0.094448031496063*% 54 | %ADD68R,0.095748031496063X0.083748031496063011*% 55 | %ADD69O,0.095748031496063X0.083748031496063011*% 56 | %ADD70R,0.083748031496063011X0.095748031496063*% 57 | %ADD71O,0.083748031496063011X0.095748031496063*% 58 | G01* 59 | D10* 60 | D11* 61 | X0005787401Y-0004055118D02* 62 | X0001067401Y0000894881D03* 63 | D12* 64 | X0001165826Y0000894881D03* 65 | D11* 66 | X0001337401Y0001014881D03* 67 | D12* 68 | X0001337401Y0000916456D03* 69 | D11* 70 | X0001067401Y0001024881D03* 71 | D12* 72 | X0001165826Y0001024881D03* 73 | D13* 74 | X0000271653Y0000372598D03* 75 | D14* 76 | X0000371653Y0000372598D03* 77 | D15* 78 | X0001367401Y0000424881D03* 79 | X0001367401Y0000524881D03* 80 | X0001367401Y0000624881D03* 81 | X0001367401Y0000724881D03* 82 | X0001067401Y0000724881D03* 83 | X0001067401Y0000624881D03* 84 | X0001067401Y0000524881D03* 85 | X0001067401Y0000424881D03* 86 | D16* 87 | X0001087401Y0000204881D03* 88 | D17* 89 | X0001187401Y0000204881D03* 90 | D16* 91 | X0000687401Y0000204881D03* 92 | D17* 93 | X0000787401Y0000204881D03* 94 | D16* 95 | X0001497401Y0000894881D03* 96 | D17* 97 | X0001497401Y0000994881D03* 98 | D16* 99 | X0001497401Y0000494881D03* 100 | D17* 101 | X0001497401Y0000594881D03* 102 | D18* 103 | X0000921653Y0001089133D03* 104 | X0000621653Y0001089133D03* 105 | X0001118503Y0001408031D03* 106 | X0000818503Y0001408031D03* 107 | X0000818503Y0001522204D03* 108 | X0001118503Y0001522204D03* 109 | X0000913779Y0000348976D03* 110 | X0000613779Y0000348976D03* 111 | X0000621653Y0000978897D03* 112 | X0000921653Y0000978897D03* 113 | X0000613779Y0000549763D03* 114 | X0000913779Y0000549763D03* 115 | X0001163338Y0001142266D03* 116 | X0001419338Y0001319466D03* 117 | X0001163338Y0001319466D03* 118 | X0001419338Y0001142266D03* 119 | D19* 120 | X0000417322Y0001034015D03* 121 | D20* 122 | X0000417322Y0000934015D03* 123 | X0000417322Y0000834015D03* 124 | X0000417322Y0000734015D03* 125 | X0000417322Y0000634015D03* 126 | X0000417322Y0000534015D03* 127 | D14* 128 | X0000952755Y0001230866D03* 129 | X0000952755Y0000443464D03* 130 | D18* 131 | X0000714517Y0000864699D03* 132 | X0000901574Y0000766299D03* 133 | X0000714517Y0000667899D03* 134 | D21* 135 | X0000448818Y0001224409D03* 136 | D22* 137 | X0000548818Y0001224409D03* 138 | X0000648818Y0001224409D03* 139 | G04 next file* 140 | G04 #@! TF.FileFunction,Soldermask,Top* 141 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 142 | G04 Created by KiCad (PCBNEW 4.0.1-stable) date 10/18/2017 12:48:17 AM* 143 | G01* 144 | G04 APERTURE LIST* 145 | G04 APERTURE END LIST* 146 | D33* 147 | D34* 148 | X0005787401Y-0002476377D02* 149 | X0001067401Y0002473621D03* 150 | D35* 151 | X0001165826Y0002473621D03* 152 | D34* 153 | X0001337401Y0002593621D03* 154 | D35* 155 | X0001337401Y0002495196D03* 156 | D34* 157 | X0001067401Y0002603621D03* 158 | D35* 159 | X0001165826Y0002603621D03* 160 | D36* 161 | X0000271653Y0001951338D03* 162 | D37* 163 | X0000371653Y0001951338D03* 164 | D38* 165 | X0001367401Y0002003621D03* 166 | X0001367401Y0002103621D03* 167 | X0001367401Y0002203621D03* 168 | X0001367401Y0002303621D03* 169 | X0001067401Y0002303621D03* 170 | X0001067401Y0002203621D03* 171 | X0001067401Y0002103621D03* 172 | X0001067401Y0002003621D03* 173 | D39* 174 | X0001087401Y0001783621D03* 175 | D40* 176 | X0001187401Y0001783621D03* 177 | D39* 178 | X0000687401Y0001783621D03* 179 | D40* 180 | X0000787401Y0001783621D03* 181 | D39* 182 | X0001497401Y0002473621D03* 183 | D40* 184 | X0001497401Y0002573621D03* 185 | D39* 186 | X0001497401Y0002073621D03* 187 | D40* 188 | X0001497401Y0002173621D03* 189 | D41* 190 | X0000921653Y0002667873D03* 191 | X0000621653Y0002667873D03* 192 | X0001118503Y0002986771D03* 193 | X0000818503Y0002986771D03* 194 | X0000818503Y0003100944D03* 195 | X0001118503Y0003100944D03* 196 | X0000913779Y0001927716D03* 197 | X0000613779Y0001927716D03* 198 | X0000621653Y0002557637D03* 199 | X0000921653Y0002557637D03* 200 | X0000613779Y0002128503D03* 201 | X0000913779Y0002128503D03* 202 | X0001163338Y0002721006D03* 203 | X0001419338Y0002898206D03* 204 | X0001163338Y0002898206D03* 205 | X0001419338Y0002721006D03* 206 | D42* 207 | X0000417322Y0002612755D03* 208 | D43* 209 | X0000417322Y0002512755D03* 210 | X0000417322Y0002412755D03* 211 | X0000417322Y0002312755D03* 212 | X0000417322Y0002212755D03* 213 | X0000417322Y0002112755D03* 214 | D37* 215 | X0000952755Y0002809606D03* 216 | X0000952755Y0002022204D03* 217 | D41* 218 | X0000714517Y0002443439D03* 219 | X0000901574Y0002345039D03* 220 | X0000714517Y0002246639D03* 221 | D44* 222 | X0000448818Y0002803149D03* 223 | D45* 224 | X0000548818Y0002803149D03* 225 | X0000648818Y0002803149D03* 226 | G04 next file* 227 | G04 #@! TF.FileFunction,Soldermask,Top* 228 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 229 | G04 Created by KiCad (PCBNEW 4.0.1-stable) date 10/18/2017 12:48:17 AM* 230 | G01* 231 | G04 APERTURE LIST* 232 | G04 APERTURE END LIST* 233 | D46* 234 | D47* 235 | X-0002500000Y0005728346D02* 236 | X0002220000Y0000778346D03* 237 | D48* 238 | X0002121574Y0000778346D03* 239 | D47* 240 | X0001950000Y0000658346D03* 241 | D48* 242 | X0001950000Y0000756771D03* 243 | D47* 244 | X0002220000Y0000648346D03* 245 | D48* 246 | X0002121574Y0000648346D03* 247 | D49* 248 | X0003015748Y0001300629D03* 249 | D50* 250 | X0002915748Y0001300629D03* 251 | D51* 252 | X0001920000Y0001248346D03* 253 | X0001920000Y0001148346D03* 254 | X0001920000Y0001048346D03* 255 | X0001920000Y0000948346D03* 256 | X0002220000Y0000948346D03* 257 | X0002220000Y0001048346D03* 258 | X0002220000Y0001148346D03* 259 | X0002220000Y0001248346D03* 260 | D52* 261 | X0002199999Y0001468346D03* 262 | D53* 263 | X0002100000Y0001468346D03* 264 | D52* 265 | X0002599999Y0001468346D03* 266 | D53* 267 | X0002500000Y0001468346D03* 268 | D52* 269 | X0001789999Y0000778346D03* 270 | D53* 271 | X0001789999Y0000678346D03* 272 | D52* 273 | X0001789999Y0001178346D03* 274 | D53* 275 | X0001789999Y0001078346D03* 276 | D54* 277 | X0002365748Y0000584094D03* 278 | X0002665748Y0000584094D03* 279 | X0002168897Y0000265196D03* 280 | X0002468897Y0000265196D03* 281 | X0002468897Y0000151023D03* 282 | X0002168897Y0000151023D03* 283 | X0002373622Y0001324251D03* 284 | X0002673622Y0001324251D03* 285 | X0002665748Y0000694330D03* 286 | X0002365748Y0000694330D03* 287 | X0002673622Y0001123464D03* 288 | X0002373622Y0001123464D03* 289 | X0002124062Y0000530962D03* 290 | X0001868062Y0000353762D03* 291 | X0002124062Y0000353762D03* 292 | X0001868062Y0000530962D03* 293 | D55* 294 | X0002870078Y0000639212D03* 295 | D56* 296 | X0002870078Y0000739212D03* 297 | X0002870078Y0000839212D03* 298 | X0002870078Y0000939212D03* 299 | X0002870078Y0001039212D03* 300 | X0002870078Y0001139212D03* 301 | D50* 302 | X0002334645Y0000442362D03* 303 | X0002334645Y0001229763D03* 304 | D54* 305 | X0002572884Y0000808529D03* 306 | X0002385826Y0000906929D03* 307 | X0002572884Y0001005329D03* 308 | D57* 309 | X0002838582Y0000448818D03* 310 | D58* 311 | X0002738582Y0000448818D03* 312 | X0002638582Y0000448818D03* 313 | G04 next file* 314 | G04 #@! TF.FileFunction,Soldermask,Top* 315 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 316 | G04 Created by KiCad (PCBNEW 4.0.1-stable) date 10/18/2017 12:48:17 AM* 317 | G01* 318 | G04 APERTURE LIST* 319 | G04 APERTURE END LIST* 320 | D59* 321 | D60* 322 | X-0002503936Y0007311024D02* 323 | X0002216063Y0002361024D03* 324 | D61* 325 | X0002117637Y0002361024D03* 326 | D60* 327 | X0001946063Y0002241024D03* 328 | D61* 329 | X0001946063Y0002339449D03* 330 | D60* 331 | X0002216063Y0002231024D03* 332 | D61* 333 | X0002117637Y0002231024D03* 334 | D62* 335 | X0003011811Y0002883307D03* 336 | D63* 337 | X0002911811Y0002883307D03* 338 | D64* 339 | X0001916063Y0002831024D03* 340 | X0001916063Y0002731024D03* 341 | X0001916063Y0002631024D03* 342 | X0001916063Y0002531024D03* 343 | X0002216063Y0002531024D03* 344 | X0002216063Y0002631024D03* 345 | X0002216063Y0002731024D03* 346 | X0002216063Y0002831024D03* 347 | D65* 348 | X0002196063Y0003051024D03* 349 | D66* 350 | X0002096063Y0003051024D03* 351 | D65* 352 | X0002596063Y0003051024D03* 353 | D66* 354 | X0002496063Y0003051024D03* 355 | D65* 356 | X0001786063Y0002361024D03* 357 | D66* 358 | X0001786063Y0002261024D03* 359 | D65* 360 | X0001786063Y0002761024D03* 361 | D66* 362 | X0001786063Y0002661024D03* 363 | D67* 364 | X0002361811Y0002166772D03* 365 | X0002661811Y0002166772D03* 366 | X0002164960Y0001847874D03* 367 | X0002464960Y0001847874D03* 368 | X0002464960Y0001733701D03* 369 | X0002164960Y0001733701D03* 370 | X0002369685Y0002906929D03* 371 | X0002669685Y0002906929D03* 372 | X0002661811Y0002277008D03* 373 | X0002361811Y0002277008D03* 374 | X0002669685Y0002706142D03* 375 | X0002369685Y0002706142D03* 376 | X0002120126Y0002113639D03* 377 | X0001864126Y0001936439D03* 378 | X0002120126Y0001936439D03* 379 | X0001864126Y0002113639D03* 380 | D68* 381 | X0002866141Y0002221890D03* 382 | D69* 383 | X0002866141Y0002321890D03* 384 | X0002866141Y0002421890D03* 385 | X0002866141Y0002521890D03* 386 | X0002866141Y0002621890D03* 387 | X0002866141Y0002721890D03* 388 | D63* 389 | X0002330708Y0002025039D03* 390 | X0002330708Y0002812441D03* 391 | D67* 392 | X0002568947Y0002391206D03* 393 | X0002381889Y0002489606D03* 394 | X0002568947Y0002588006D03* 395 | D70* 396 | X0002834645Y0002031496D03* 397 | D71* 398 | X0002734645Y0002031496D03* 399 | X0002634645Y0002031496D03* 400 | M02* -------------------------------------------------------------------------------- /Programs/Algorithmic_Generator/Algorithmic_Generator.ino: -------------------------------------------------------------------------------- 1 | /* 2 | //********************************** 3 | //* miniMO Algorithmic Generator * 4 | //* 2018 by enveloop * 5 | //********************************** 6 | 7 | Based on the RCArduino Algorithmic Music code by Duane Banks, 8 | as described Here: 9 | http://rcarduino.blogspot.com.es/2012/09/algorithmic-music-on-arduino.html 10 | 11 | , and the Algorithmic Noise Machine, by Madshobye: 12 | https://www.instructables.com/id/Algorithmic-noise-machine/ 13 | 14 | Also uses the xorshift pseudorandom number generator, 15 | as described Here: 16 | http://www.arklyffe.com/main/2010/08/29/xorshift-pseudorandom-number-generator/ 17 | 18 | I/O 19 | 1&2: Outputs 20 | 3: Input - parameter modulation 21 | 4: Input - unused 22 | 23 | OPERATION 24 | Knob: change the value of the parameter currently selected 25 | -miniMO waits until you reach the value it has currently stored 26 | Click: toggle between parameters 27 | -There are three parameters available per algorithm 28 | -The LED blinks once, twice, or thrice, according to the parameter selected 29 | Double Click: toggle between algorithms 30 | -The LED blinks once 31 | 32 | BATTERY CHECK 33 | When you switch the module ON, 34 | -If the LED blinks once, the battery is OK 35 | -If the LED blinks fast several times, the battery is running low 36 | 37 | NOTES&TROUBLESHOOTING 38 | Sometimes the sound changes when moving between parameters 39 | 40 | 41 | // 42 | http://www.minimosynth.com/ 43 | CC BY 4.0 44 | Licensed under a Creative Commons Attribution 4.0 International license: 45 | http://creativecommons.org/licenses/by/4.0/ 46 | // 47 | 48 | */ 49 | 50 | #include 51 | #include 52 | 53 | char sample; 54 | long t; 55 | byte controlInput; 56 | bool parameterChange = false; 57 | int currentParameter = 0; 58 | int currentAlgo = 0; 59 | byte parameters[] = { 60 | 1, 61 | 1, 62 | 1 63 | }; 64 | 65 | //button press control 66 | int button_delay; 67 | int button_delay_b; 68 | int additionalClicks = 0; 69 | 70 | //button interrupt 71 | bool inputButtonValue; 72 | 73 | void setup() { 74 | 75 | PRR = (1 << PRUSI); //disable USI to save power as we are not using it 76 | DIDR0 = (1 << ADC1D) | (1 << ADC3D); //PB2,PB3 //disable digital input in pins that do analog conversion 77 | 78 | //set the rest of the pins 79 | pinMode(0, OUTPUT); //LED 80 | pinMode(4, OUTPUT); // 81 | pinMode(3, INPUT); //analog- parameter input (knob plus external input 1) 82 | pinMode(2, INPUT); //analog- 83 | pinMode(1, INPUT); //digital input (push button) 84 | 85 | checkVoltage(); 86 | ADMUX = 0; //reset multiplexer settings 87 | ADCSRA = (1 << ADEN); //reset ADC Control (ADC Enable 1, everything else 0) 88 | ADMUX |= (0 << REFS2) | (0 << REFS1) | (0 << REFS0); //Vcc as voltage reference --not necessary, but a reminder 89 | ADMUX |= (1 << ADLAR); //8-Bit ADC in ADCH Register 90 | ADMUX |= (1 << MUX1) | (1 << MUX0); //select ADC3 (control input) 91 | ADCSRA |= (1 << ADSC); // start conversion 92 | 93 | //set clock source for PWM -datasheet p94 94 | PLLCSR |= (1 << PLLE); // Enable PLL (64 MHz) 95 | _delay_us(100); // Wait for a steady state 96 | while (!(PLLCSR & (1 << PLOCK))); // Ensure PLL lock 97 | PLLCSR |= (1 << PCKE); // Enable PLL as clock source for timer 1 98 | 99 | cli(); // Interrupts OFF (disable interrupts globally) 100 | 101 | //PWM Generation -timer 1 102 | GTCCR = (1 << PWM1B) | (1 << COM1B1); // PWM, output on pb4, compare with OCR1B (see interrupt below), reset on match with OCR1C 103 | OCR1C = 0xff; // 255 104 | TCCR1 = (1 << CS10); // no prescale 105 | 106 | //Timer Interrupt Generation -timer 0 107 | TCCR0A = (1 << WGM01) | (1 << WGM00); // fast PWM 108 | TCCR0B = (1 << CS00); // no prescale 109 | TIMSK = (1 << TOIE0); // Enable Interrupt on overflow 110 | 111 | //Pin interrupt Generation 112 | GIMSK |= (1 << PCIE); // Enable Pin Change Interrupt 113 | PCMSK |= (1 << PCINT1); // on pin 1 114 | 115 | sei(); // Interrupts ON (enable interrupts globally) 116 | 117 | //go for it! 118 | initializeAlgoParameters(currentAlgo); 119 | digitalWrite(0, HIGH); // turn LED ON 120 | 121 | } 122 | 123 | ISR(TIMER0_OVF_vect) { // Timer 0 interruption - changes the width of timer 1's pulse to generate waves 124 | 125 | algo(currentAlgo); 126 | } 127 | 128 | ISR(PCINT0_vect) { // PIN Interruption - has priority over COMPA; this ensures that the switch will work 129 | TIMSK = (0 << TOIE0); // Disable sound generation Interrupt 130 | inputButtonValue = PINB & 0x02; // Reads button (digital input1, the second bit in register PINB. We check the value with & binary 10, so 0x02) 131 | } 132 | 133 | void loop() { 134 | OCR1B = sample; 135 | checkButton(); 136 | setParameter(); 137 | } 138 | 139 | void algo(int currentAlgo) { // 0 - 3: Algorithms by enveloop, based on previous work by Viznut, Tejeez & al (see sources below) 140 | switch (currentAlgo) { 141 | case 0: 142 | sample = t*(t>>parameters[0]) ^ (t<>parameters[0]) ^ (t<>parameters[0]))&t)>>7|t)¶meters[1]); // 151 | t = t + parameters[2]; 152 | break; 153 | case 3: 154 | sample = t&(t>>parameters[0])>>parameters[1]; // 155 | t = t + parameters[2]; 156 | break; 157 | case 4: // xorshift noise 158 | t ^= (t << parameters[0]); 159 | t ^= (t >> parameters[1]); 160 | sample ^= (t << parameters[2]); // 2-5-3 161 | if (t == 0) t = 1; // avoids "extinguishing the noise" 162 | break; 163 | } 164 | } 165 | 166 | void initializeAlgoParameters(int currentAlgo) { 167 | t = 1; // for case 4, noise, with needs it initialized to 1 168 | currentParameter = 0; 169 | switch (currentAlgo) { 170 | case 0: 171 | parameters[0] = 14; 172 | parameters[1] = 8; 173 | parameters[2] = 1; 174 | break; 175 | case 1: 176 | parameters[0] = 10; //1 10 1 177 | parameters[1] = 2; 178 | parameters[2] = 1; 179 | break; 180 | case 2: 181 | parameters[0] = 7; 182 | parameters[1] = 9; 183 | parameters[2] = 2; 184 | break; 185 | case 3: 186 | parameters[0] = 2; 187 | parameters[1] = 8; 188 | parameters[2] = 1; 189 | break; 190 | case 4: 191 | parameters[0] = 2; 192 | parameters[1] = 5; 193 | parameters[2] = 3; 194 | break; 195 | } 196 | } 197 | 198 | 199 | void setParameter() { 200 | controlInput = ADCH >> 4; //0 to 15 201 | if (parameterChange == true) parameters[currentParameter] = controlInput; 202 | 203 | else if (controlInput == parameters[currentParameter]) { //check control input against stored value. If the value is the same (because we have moved the knob to the last known position for that parameter), 204 | parameterChange = true; //it is ok to change the value :) 205 | } 206 | 207 | ADCSRA |= (1< 0)) { //button released after a while 217 | bool hold = true; 218 | while (hold) { 219 | bool previousButtonState = inputButtonValue; //see if the button is pressed or not 220 | 221 | _delay_ms(1); 222 | 223 | button_delay_b++; //fast counter to check if there are more presses 224 | if ((inputButtonValue == HIGH) && (previousButtonState == 0)) { 225 | additionalClicks++; //if we press the button and we were not pressing it before, that counts as a click 226 | } 227 | 228 | if (button_delay_b == 300) { 229 | if (additionalClicks == 0) { //single click 230 | currentParameter++; 231 | if (currentParameter == 3) currentParameter = 0; //3 parameters, indexes from 0 to 2 232 | flashLEDSlow(currentParameter + 1); //parameter 0 - flash once, etc 233 | } 234 | else { // more than one click 235 | currentAlgo++; 236 | if (currentAlgo == 5) currentAlgo = 0; 237 | initializeAlgoParameters(currentAlgo); 238 | flashLEDSlow(1); 239 | additionalClicks = 0; 240 | } 241 | button_delay = 0; 242 | button_delay_b = 0; 243 | hold = false; 244 | parameterChange = false; //reset parameter change condition so that after we press the button, the newly selected parameter won't immediately change (see setParameter) 245 | TIMSK = (1 << TOIE0); // Enable Interrupt 246 | } 247 | } 248 | } 249 | } 250 | 251 | void checkVoltage() { //voltage from 255 to 0; 46 is (approx)5v, 94 is 2.8, 104-106 is 2.5 252 | //we measure a fixed value of 1.1 against Vcc, so the lower the measurement, the higher Vcc 253 | ADMUX = (0 << REFS1)|(0 << REFS0); //Vcc as reference 254 | ADMUX |= (1 << ADLAR); //Left adjust result (8 bit conversion stored in ADCH) 255 | ADMUX |= (1 << MUX3) | (1 << MUX2); //1.1v input 256 | delay(250); // Wait for Vref to settle 257 | ADCSRA |= (1 << ADSC); // Start conversion 258 | while (bit_is_set(ADCSRA, ADSC)); // wait while measuring 259 | if (ADCH > 103) //approx 2.6 260 | flashLED(8, 100); 261 | else 262 | flashLED(1, 250); 263 | } 264 | 265 | void flashLED (int times, int gap) { //for voltage check only (uses regular delay) 266 | for (int i = 0; i < times; i++) 267 | { 268 | digitalWrite(0, HIGH); 269 | delay(gap); 270 | digitalWrite(0, LOW); 271 | delay(gap); 272 | } 273 | } 274 | 275 | void flashLEDOnce () { 276 | digitalWrite(0, LOW); 277 | _delay_ms(100); 278 | digitalWrite(0, HIGH); 279 | } 280 | 281 | void flashLEDTwice () { 282 | digitalWrite(0, LOW); 283 | _delay_ms(80); 284 | digitalWrite(0, HIGH); 285 | _delay_ms(80); 286 | digitalWrite(0, LOW); 287 | _delay_ms(80); 288 | digitalWrite(0, HIGH); 289 | } 290 | 291 | void flashLEDSlow(int times) { 292 | for (int i = 0; i < times; i++){ 293 | _delay_ms(100); 294 | digitalWrite(0, LOW); 295 | _delay_ms(100); 296 | digitalWrite(0, HIGH); 297 | } 298 | } 299 | 300 | 301 | /*Algorithm Sources for reference 302 | 303 | https://gist.github.com/mvasilkov/352f863e38989aa89127 304 | 305 | http://www.windows93.net/ (within the Byte Beat program) 306 | 307 | Try them here: http://wurstcaptures.untergrund.net/music/ , or here: 308 | 309 | https://greggman.com/downloads/examples/html5bytebeat/html5bytebeat.html ) 310 | 311 | 312 | */ 313 | 314 | 315 | -------------------------------------------------------------------------------- /Programs/Phaser/Phaser.ino: -------------------------------------------------------------------------------- 1 | /* 2 | //************************ 3 | //* miniMO PHASER * 4 | //* 2017 by enveloop * 5 | //************************ 6 | Based on the Arduino Audio Phasor 7 | by Martin Nawrath, 8 | as described Here: 9 | http://interface.khm.de/index.php/lab/interfaces-advanced/arduino-realtime-audio-processing/ 10 | 11 | // 12 | http://www.minimosynth.com/ 13 | CC BY 4.0 14 | Licensed under a Creative Commons Attribution 4.0 International license: 15 | http://creativecommons.org/licenses/by/4.0/ 16 | // 17 | 18 | I/O 19 | 1&2 Outputs - phased signal 20 | 3: Input - parameter modulation 21 | 4: Input - audio signal 22 | 23 | OPERATION 24 | Knob: change phase (default), phased buffer size or sample rate 25 | -miniMO waits until you reach the value it has currently stored 26 | Click: toggle between phase, phased buffer size and delay time control 27 | -the LED blinks 1 to 3 times depending on the parameter selected (1-Phase, 2-Buffer, 3-Rate) 28 | Double Click: toggle between normal and high sensitivity modes 29 | 30 | BATTERY CHECK 31 | When you switch the module ON, 32 | -If the LED blinks once, the battery is OK 33 | -If the LED blinks fast several times, the battery is running low 34 | 35 | */ 36 | 37 | #include 38 | #include 39 | 40 | #define F_CPU 8000000 41 | 42 | //audio and control signal interrupt 43 | int count; 44 | byte sensorMinDefault = 63; 45 | byte sensorMin; 46 | 47 | //interrupt variables accessed globally 48 | volatile boolean gotReadings; 49 | volatile byte controlInput; 50 | volatile byte audioInput; 51 | volatile bool inputButtonValue; 52 | 53 | //button press control 54 | int button_delay; 55 | int button_delay_b; 56 | int additionalClicks = 0; 57 | 58 | int test; 59 | int iw1, iw2; 60 | int phaseSample; 61 | int index, phaseIndex; 62 | byte sampleBuffer[256]; // Audio Memory Array 8-Bit 63 | 64 | bool highSensitivity = false; 65 | 66 | bool parameterChange = false; 67 | int currentParameter = 0; 68 | byte parameters[] = { 69 | 127, //phase 70 | 255, //buffer length 71 | 0 //loop delay length 72 | }; 73 | 74 | void setup() { 75 | 76 | PRR = (1 << PRUSI); //disable USI to save power as we are not using it 77 | DIDR0 = (1 << ADC1D) | (1 << ADC3D); //PB2,PB3 //disable digital input in pins that do analog conversion 78 | 79 | pinMode(0, OUTPUT); //LED 80 | pinMode(4, OUTPUT); //timer 1 in digital output 4 - outs 1 and 2 81 | pinMode(3, INPUT); //analog- freq input (knob plus external input 1) 82 | pinMode(2, INPUT); //analog- amplitude input (external input 2) 83 | pinMode(1, INPUT); //digital input (push button) 84 | 85 | checkVoltage(); 86 | 87 | ADCSRA = (1 << ADEN); //reset ADC Control (ADC Enable 1, everything else 0) 88 | ADCSRA |= (1 << ADPS2); //set adc prescaler to 16 for 500kHz sampling frequency (8 also works well but is noisier). 500/13 cycles per sample = 38.4 Khz, faster than the timer interrupt -good! 89 | 90 | ADMUX = 0; //reset multiplexer settings 91 | //ADMUX |= (1 << REFS2) | (1 << REFS1); //2.56V internal Voltage Reference disconnected from AREF 92 | ADMUX |= (0 << REFS2) | (0 << REFS1) | (0 << REFS0); //Vcc as voltage reference --not necessary, but a reminder 93 | ADMUX |= (1 << ADLAR); //8-Bit ADC in ADCH Register 94 | ADMUX |= (1 << MUX0); //select ADC1 (audio input) 95 | ADCSRA |= (1 << ADSC); // start conversion 96 | 97 | //set clock source for PWM -datasheet p94 98 | PLLCSR |= (1 << PLLE); // Enable PLL (64 MHz) 99 | _delay_us(100); // Wait for a steady state 100 | while (!(PLLCSR & (1 << PLOCK))); // Ensure PLL lock: do nothing while the bit PLOCK in register PLLCSR is false 101 | PLLCSR |= (1 << PCKE); // Enable PLL as clock source for timer 1 102 | 103 | cli(); // Interrupts OFF (disable interrupts globally) 104 | 105 | //PWM Generation -timer 1 106 | GTCCR = (1 << PWM1B) | (1 << COM1B1); // PWM, output on pb4, compare with OCR1B (see interrupt below), reset on match with OCR1C 107 | OCR1C = 0xff; 108 | TCCR1 = (1 << CS10); // no prescale 109 | 110 | //Timer Interrupt Generation -timer 0 111 | TCCR0A = (1 << WGM01) | (1 << WGM00); // fast PWM 112 | TCCR0B = (1 << CS00); // no prescale (source: internal clock) 113 | TIMSK = (1 << TOIE0); // Enable Interrupt on overflow, triggered at 31.2KHz (8Mhz / 256 steps per overflow) 114 | 115 | //Pin Change Interrupt 116 | GIMSK |= (1 << PCIE); // Enable 117 | PCMSK |= (1 << PCINT1); // on pin 1 118 | 119 | sei(); // Interrupts ON (enable interrupts globally) 120 | 121 | digitalWrite(0, HIGH); //lights on! 122 | 123 | } 124 | 125 | ISR(PCINT0_vect) { // PIN Interruption - has priority over Timer 0; this ensures that the switch will work 126 | inputButtonValue = PINB & 0x02; // Reads button (digital input1, the second bit in register PINB. We check the value with & binary 10, so 0x02) 127 | } 128 | 129 | //Timer0 interruption 130 | ISR(TIMER0_OVF_vect) { //Alternates between reading the audio (most of the time) and control input. 131 | 132 | if (!(ADMUX & 0x02)){ //if the audio input is selected... (it's ADC1, so MUX1 = 0. Then, ADMUX & binary 10 = 0, or !(ADMUX&0x02) 133 | 134 | audioInput = ADCH; //read the value 135 | 136 | if (count < 100){ //until count is 100, 137 | if (audioInput < sensorMin) sensorMin = audioInput; //if the audio input is low, adjust the threshold 138 | count++; //advance the counter 139 | } 140 | else { //from 101 onwards 141 | if (audioInput == sensorMin){ //the moment the threshold is reached (makes the readings periodical), 142 | ADMUX |= (1 << MUX1); //select the control input (ADC3, so MUX1 = 1 and MUX0=1. MUX0 was already set to 1 during setup) 143 | ADMUX &= ~(1 << REFS1); //the control input always needs Vcc for reference to read the potentiometer's full range, so REFS1 is 0 144 | } 145 | else if (count > 200) { //if the threshold is not reached after a while, 146 | sensorMin = sensorMinDefault; //reset 147 | count = 0; 148 | } 149 | else count++; 150 | } 151 | } 152 | else { //if the control input is selected 153 | controlInput = ADCH; //read the value 154 | gotReadings = true; 155 | sensorMin = sensorMinDefault; //reset sensorMin 156 | ADMUX &= ~(1 << MUX1); //select the audio input (ADC1, so MUX1 = 0 and MUX0=1. MUX0 was already set to 1 during setup) 157 | if (highSensitivity) ADMUX |= (1 << REFS1); //if highSensitivity is selected, we toggle REFS1 to use 1.1v as voltage reference 158 | } 159 | 160 | ADCSRA |= (1<> 1; // average newly acquired sample with phased sample, and send the result to the PWM output 178 | 179 | //store newly acquired sample to use in the next cycle 180 | sampleBuffer[index] = audioInput; 181 | index++; 182 | index = index & 255; // limit index 183 | 184 | variableDelay(parameters[2]); 185 | } 186 | 187 | void variableDelay(int us) { 188 | while(us--) //http://stackoverflow.com/questions/32649032/what-does-whilex-mean-in-c/32649606 189 | _delay_us(1); 190 | } 191 | 192 | void setParameter() { 193 | if (parameterChange) parameters[currentParameter] = controlInput; 194 | 195 | else if ((controlInput & 0xF0) == (parameters[currentParameter] & 0xF0) ) { //checks the control input against stored value. & 0xF0 is a mask to ignore the 4 lower bits and use less resolution (works better) 196 | parameterChange = true; //If the value is the same (because we have moved the knob to the last known position for that parameter),it is ok to change the value :) 197 | } 198 | } 199 | 200 | void checkButton() { 201 | while (inputButtonValue == HIGH) { 202 | button_delay++; 203 | _delay_ms(10); 204 | } 205 | 206 | if ((inputButtonValue == LOW) && (button_delay > 0)) { //button released after a while 207 | bool hold = true; 208 | while (hold) { 209 | bool previousButtonState = inputButtonValue; //see if the button is pressed or not 210 | 211 | _delay_ms(1); 212 | 213 | button_delay_b++; //fast counter to check if there are more presses 214 | if ((inputButtonValue == HIGH) && (previousButtonState == 0)) { 215 | additionalClicks++; //if we press the button and we were not pressing it before, that counts as a click 216 | } 217 | 218 | if (button_delay_b == 300) { 219 | 220 | if (additionalClicks == 0) { //single click 221 | currentParameter++; 222 | if (currentParameter > 2) currentParameter = 0; //3 parameters, indexes from 0 to 2 223 | flashLEDSlow(currentParameter + 1); //parameter 0 - flash once, etc 224 | parameterChange = false; //reset parameter change condition so that after we press the button, the newly selected parameter won't immediately change (see setParameter) 225 | button_delay = 0; 226 | button_delay_b = 0; 227 | additionalClicks = 0; 228 | hold = false; 229 | } 230 | else { // more than one click 231 | highSensitivity = !highSensitivity; 232 | //ADMUX ^= (1 << REFS1); // toggles REFS1 from 0 to 1 or 1 to 0. When it is 0, reference voltage is Vcc. When it is 1, reference voltage is 1.1v, so the ADC is more sensitive. 233 | flashLEDSlow(1); 234 | button_delay = 0; 235 | button_delay_b = 0; 236 | additionalClicks = 0; 237 | hold = false; 238 | } 239 | } 240 | } 241 | } 242 | } 243 | 244 | void checkVoltage() { //voltage from 255 to 0; 46 is (approx)5v, 94 is 2.8, 104-106 is 2.5 245 | //we measure a fixed value of 1.1 against Vcc, so the lower the measurement, the higher Vcc 246 | ADMUX = (0 << REFS1) | (0 << REFS0); //Vcc as reference 247 | ADMUX |= (1 << ADLAR); //Left adjust result (8 bit conversion stored in ADCH) 248 | ADMUX |= (1 << MUX3) | (1 << MUX2); //1.1v input 249 | delay(250); //Wait for Vref to settle 250 | ADCSRA |= (1 << ADSC); //Start conversion 251 | while (bit_is_set(ADCSRA, ADSC)); //wait while measuring 252 | if (ADCH > 103) //approx 2.6 253 | flashLED(8, 100); 254 | else 255 | flashLED(1, 250); 256 | } 257 | 258 | void flashLED (int times, int gap) { //for voltage check only (uses regular delay) 259 | for (int i = 0; i < times; i++) 260 | { 261 | digitalWrite(0, HIGH); 262 | delay(gap); 263 | digitalWrite(0, LOW); 264 | delay(gap); 265 | } 266 | } 267 | 268 | void flashLEDSlow(int times) { 269 | for (int i = 0; i < times; i++){ 270 | _delay_ms(100); 271 | digitalWrite(0, LOW); 272 | _delay_ms(100); 273 | digitalWrite(0, HIGH); 274 | } 275 | } 276 | 277 | -------------------------------------------------------------------------------- /Programs/Tuned_Controller/Tuned_Controller.ino: -------------------------------------------------------------------------------- 1 | /* 2 | //******************************* 3 | //* miniMO Tuned Controller * 4 | //* 2016 by enveloop * 5 | //******************************* 6 | // 7 | http://www.minimosynth.com/ 8 | CC BY 4.0 9 | Licensed under a Creative Commons Attribution 4.0 International license: 10 | http://creativecommons.org/licenses/by/4.0/ 11 | // 12 | 13 | I/O 14 | 1&2: Outputs - control voltage for frequency 15 | 3: Input - frequency (during calibration) 16 | 4: Output - gate (note ON/OFF) 17 | 18 | MODES OF OPERATION 19 | PLAY (default) 20 | -Knob: change frequency 21 | -Single click: toggle between note ON and OFF 22 | -If the note is ON, the LED is also ON (and the other way round) 23 | -Double click: frequency calibration with OSC module(see below) 24 | -Triple click: frequency calibration with OSC module(see below) 25 | 26 | FREQUENCY CALIBRATION (With an Oscillator Module) 27 | When you enter this mode, miniMO starts an automatic procedure and calibrates its output to send values that result in the target frequencies defined in the program 28 | -Before calibration, 29 | -Connect the controller's I/O 1 or 2 to the oscillator's I/O 3 (controller note output to oscillator frequency input) 30 | -Connect the controller's I/O 3 to the oscillator's I/O 1 or 2 (controller calibration input to oscillator frequency output) 31 | -Connect the controller's I/O 4 to the oscillator's I/O 4 (controller gate output to oscillator volume output) 32 | -Turn the controller's knob all the way counter-clockwise and make sure the arrow points at the button 33 | -Turn the controller's knob halfway (arrow pointing at I/O 4) 34 | -Click the controller module's button two or three times to start the calibration procedure in the controller 35 | -Start the oscillator calibration procedure (refer to oscillator manual on how to set it up) 36 | -A series of high and low beeps are heard; this calibrates the oscillator module 37 | -A rising pitch is heard; this calibrates the controller module 38 | -When the pitch stops rising, calibration is finished 39 | -Disconnect the cable from I/O 3 in the controller module 40 | -Turn the controller OFF and ON again. A sequence starts playing ^_^ 41 | 42 | miniMO automatically saves the calibrated values to memory and recalls them if you turn it OFF and ON again 43 | 44 | 45 | CALIBRATION TROUBLESHOOTING 46 | Problem: Calibration gets stuck in an endless loop from the lowest note up 47 | -Solution: Recheck cable connections and knob positions, then repeat calibration 48 | Problem: Calibration gets stuck in an endless loop towards the highest pitches 49 | -Solution: Move the knob in the controller clockwise by a small amount and repeat calibration 50 | Problem: After calibration, moving the knob in the controller gives strange sounds 51 | -Solution: Disconnect the cable between the oscillator output and the controller input 52 | Problem: Calibration is lost after turning the oscillator OFF and ON again 53 | -Solution: Disconnect the cable connected to the oscillator's input 2 before turning it OFF 54 | Alternatively, turn OFF the Controller before the oscillator, 55 | or make sure that the controller is not sending a note before turning OFF the oscillator 56 | 57 | BATTERY CHECK 58 | When you switch the module ON, 59 | -If the LED blinks once, the battery is OK 60 | -If the LED blinks fast several times, the battery is running low 61 | */ 62 | 63 | #include 64 | #include 65 | #include 66 | 67 | volatile unsigned int globalTicks = 0; 68 | volatile unsigned long Count; 69 | bool found = false; 70 | bool tested = false; 71 | 72 | //button interrupt 73 | volatile bool inputButtonValue; 74 | 75 | //button press control 76 | int button_delay; 77 | int button_delay_b; 78 | bool beenDoubleClicked = false; 79 | bool beenLongPressed = false; 80 | int additionalClicks = 0; //variable to see how many times we click after the first 81 | 82 | //calibration data 83 | 84 | const int PROGMEM arrayLength = 37; 85 | const int PROGMEM targetFrequencies[arrayLength] = { //int array, so we read it with pgm_read_word_near(targetFrequencies + j) later on 86 | 110, 117, 123, 131, 139, 147, 156, 165, 175, 87 | 185, 196, 208, 220, 233, 247, 262, 277, 294, 88 | 311, 330, 349, 370, 392, 415, 440, 466, 494, 89 | 523, 554, 587, 622, 659, 698, 740, 784, 831, 880 //A2 to A5 90 | }; 91 | /* 92 | const int PROGMEM arrayLength = 13; 93 | const int PROGMEM targetFrequencies[arrayLength] = { 94 | 110, 147, 165, 196, 95 | 220, 294, 330, 392, 96 | 440, 587, 659, 784, 880 //tetratonic A2 to A5 97 | }; 98 | */ 99 | 100 | int calibratedFrequencies[arrayLength]; 101 | bool calibrating = false; 102 | 103 | void setup() { 104 | 105 | PRR = (1 << PRUSI); //disable USI to save power as we are not using it 106 | DIDR0 = (1 << ADC1D) | (1 << ADC3D); //PB2,PB3 //disable digital input in pins that do analog conversion 107 | 108 | //osc calibration 109 | OSCCAL = 161; 110 | 111 | pinMode(0, OUTPUT); //LED 112 | pinMode(4, OUTPUT); //Note pitch 113 | pinMode(2, OUTPUT); //Note trigger 114 | pinMode(3, INPUT); //Analog- freq Input 115 | pinMode(1, INPUT); //Digital input (push button) 116 | 117 | checkVoltage(); 118 | ADMUX = 0; //reset multiplexer settings 119 | 120 | cli(); // Interrupts OFF (disable interrupts globally) 121 | 122 | GTCCR = (1 << PWM1B) | (1 << COM1B1); // PWM, output on pb1, compare with OCR1B, reset on match with OCR1C 123 | OCR1C = 0xff; // 255 124 | TCCR1 = (1 << CS10); // no prescale 125 | 126 | //Pin Change Interrupt 127 | GIMSK |= (1 << PCIE); // Enable 128 | PCMSK |= (1 << PCINT1); // on pin 1 129 | 130 | //Timer Interrupt Generation -timer 0 131 | TCCR0A = (1 << WGM01); //Clear Timer on Compare (CTC) with OCR0A 132 | TCCR0B = (1 << CS01) | (1 << CS00); // prescaled by 64 133 | OCR0A = 0x7d; //0x7d = 125 //1000hz - 1000 ticks per second https://www.easycalculation.com/engineering/electrical/avr-timer-calculator.php 134 | TIMSK = (1 << OCIE0A); // Enable Interrupt on compare with OCR0A 135 | 136 | memoryToArray(calibratedFrequencies, arrayLength); //reads the last calibration values from memory and places them in the calibration array 137 | 138 | sei(); // Interrupts ON (enable interrupts globally) 139 | 140 | //go for it! 141 | digitalWrite(0, HIGH); // turn LED ON 142 | digitalWrite(2, HIGH); // turn note ON 143 | 144 | 145 | } 146 | 147 | ISR(PCINT0_vect) { //PIN Interruption - has priority over Timer 0; this ensures that the switch will work 148 | inputButtonValue = PINB & 0x02; //Reads button (digital input1, the second bit in register PINB. We check the value with & binary 10, so 0x02) 149 | Count++; //This interruption happens both on rising and falling. When calibrating, we use the analog input as source for the interrupt, and freq = interruptions (Count) in a second/2 150 | } 151 | 152 | ISR(TIMER0_COMPA_vect) { //1000 ticks per second 153 | globalTicks++; 154 | } 155 | 156 | void loop () { 157 | setNote(3); 158 | checkButton(); 159 | } 160 | 161 | void setNote(int pin) { 162 | if (!calibrating){ 163 | int noteRead = analogRead(pin) >> 2; //0-255 164 | OCR1B = noteMap(noteRead); 165 | } 166 | } 167 | 168 | void toggleNote(){ 169 | if (digitalRead(2) == HIGH){ 170 | digitalWrite(2, LOW); 171 | digitalWrite(0, LOW); 172 | } 173 | else { 174 | digitalWrite(2, HIGH); 175 | digitalWrite(0, HIGH); 176 | } 177 | } 178 | 179 | int noteMap(int note){ 180 | int result; 181 | for (int i = 0; i < arrayLength; i++) 182 | { 183 | if (abs(note - calibratedFrequencies[i]) < abs(note - result)) 184 | result = calibratedFrequencies[i]; 185 | } 186 | return result; 187 | } 188 | 189 | void calibrate() { 190 | sendCalibration(); //sends the max and min values (this is to calibrate the oscillator) 191 | PCMSK = (1 << PCINT3); //source for PIN interruption: input 3 (frequency) 192 | calibrating = true; 193 | int nextI = 0; 194 | for (int j = 0; j < arrayLength; j++) { //for every target frequency in the array 195 | for (int i = nextI; i < 256; i++) { //tests voltages, starting with the last voltage that gave a valid frequency 196 | found = false; 197 | tested = false; 198 | OCR1B = i; //sends the voltage 199 | while (tested == false) { 200 | testFrequency(pgm_read_word_near(targetFrequencies + j)); 201 | } 202 | if (found) { 203 | calibratedFrequencies[j] = i; //puts the calibration value for this note in the array 204 | nextI = i; 205 | break; 206 | } 207 | } 208 | } 209 | //once all the notes are calibrated 210 | arrayToMemory(calibratedFrequencies, arrayLength); //save the calibration array to memory 211 | PCMSK = (1 << PCINT1); //interrupt source back to button 212 | calibrating = false; 213 | } 214 | 215 | void arrayToMemory(int array[], int arraySize){ 216 | int j = 1; 217 | int offset = 2; //two bytes for each int 218 | for (int i = 0; i < arraySize; i++) { 219 | eeprom_update_word((uint16_t*)j, array[i]); 220 | j = j + offset; 221 | } 222 | } 223 | 224 | void memoryToArray(int array[], int arraySize){ 225 | int j = 1; 226 | int offset = 2; //two bytes for each int 227 | for (int i = 0; i < arraySize; i++) { 228 | array[i] = eeprom_read_word((uint16_t*)j); 229 | j = j + offset; 230 | } 231 | } 232 | 233 | void testFrequency(int target) { //in 1 second, count = freq * 2 234 | globalTicks = 0; 235 | Count = 0; 236 | while (globalTicks < 125); //eigth of a second 237 | if (Count > (target >> 2)) found = true; 238 | tested = true; 239 | } 240 | 241 | void sendCalibration() { //sends the max and min values (this is to calibrate the oscillator) 242 | digitalWrite(2, HIGH); 243 | int i = 0; 244 | for (int j = 0; j < 5; ++j){ //alternates 5 times between max and min 245 | i = 0; 246 | for (i = 0; i < 256; ++i) { 247 | OCR1B = 0xff; //255 248 | _delay_ms(2); 249 | } 250 | i = 0; 251 | for (i = 0; i < 256; ++i) { 252 | OCR1B = 0; 253 | _delay_ms(2); 254 | } 255 | } 256 | } 257 | 258 | void checkButton() { 259 | while (inputButtonValue == HIGH) { 260 | button_delay++; 261 | _delay_ms(10); 262 | if (button_delay > 50 &! beenDoubleClicked) { 263 | beenLongPressed = true; //press and hold 264 | 265 | } 266 | } 267 | if (inputButtonValue == LOW) { 268 | beenDoubleClicked = false; 269 | if (button_delay > 0) { 270 | bool hold = true; 271 | while (hold) { 272 | bool previousButtonState = inputButtonValue; //see if the button is pressed or not 273 | 274 | _delay_ms(1); 275 | 276 | button_delay_b++; //fast counter to check if there are more presses 277 | if ((inputButtonValue == HIGH)&& (previousButtonState == 0)) { 278 | additionalClicks++; //if we press the button and we were not pressing it before, that counts as a click 279 | } 280 | 281 | if (button_delay_b == 500) { 282 | if (additionalClicks == 0){ 283 | if (beenLongPressed) { //button released after being pressed for a while (most likely because we were changing the volume) 284 | beenLongPressed = false; 285 | button_delay = 0; 286 | button_delay_b = 0; 287 | additionalClicks = 0; 288 | hold = false; 289 | } 290 | else { //button released (regular single click) 291 | 292 | toggleNote(); 293 | 294 | button_delay = 0; 295 | button_delay_b = 0; 296 | additionalClicks = 0; 297 | hold = false; 298 | } 299 | } 300 | else if (additionalClicks == 1) { //button pressed again (double click), 301 | 302 | calibrate(); 303 | 304 | button_delay = 0; 305 | button_delay_b = 0; 306 | additionalClicks = 0; 307 | beenDoubleClicked = true; 308 | hold = false; 309 | } 310 | else if (additionalClicks > 1 ) { //button pressed at least twice (triple click or more) 311 | 312 | calibrate(); 313 | 314 | button_delay = 0; 315 | button_delay_b = 0; 316 | additionalClicks = 0; 317 | beenDoubleClicked = true; 318 | hold = false; 319 | } 320 | } 321 | } 322 | } 323 | } 324 | } 325 | void checkVoltage() { //voltage from 255 to 0; 46 is (approx)5v, 94 is 2.8, 104-106 is 2.5 326 | //we measure a fixed value of 1.1 against Vcc, so the lower the measurement, the higher Vcc 327 | ADMUX = (0< 103) //approx 2.6 334 | flashLED(8,100); 335 | else 336 | flashLED(1,250); 337 | } 338 | 339 | void flashLED (int times, int gap) { //for voltage check only (uses regular delay) 340 | //delay(250); 341 | for (int i=0; i 46 | //#include 47 | #include 48 | 49 | volatile unsigned int globalTicks; 50 | 51 | //calibration (use with sequencer) 52 | bool calibrating = false; 53 | 54 | //mode 55 | bool autoTrigger = false; 56 | 57 | //output 58 | int envelopeValue; 59 | 60 | //button interrupt 61 | volatile bool inputButtonValue; 62 | 63 | //envelope stage control; 64 | bool readyToAttack = true; 65 | bool readyToRelease = false; 66 | 67 | //button press control 68 | int button_delay; 69 | int button_delay_b; 70 | bool beenDoubleClicked = false; 71 | bool beenLongPressed = false; 72 | int additionalClicks = 0; //variable to see how many times we click after the first 73 | 74 | bool parameterChange = false; 75 | byte controlInput; 76 | 77 | int currentStep = 0; 78 | 79 | const int attackLevel = 255; 80 | 81 | int ADSR[] = { 82 | 127, //attackLength 83 | 127, //decayLength 84 | 127, //sustainLevel 85 | 127 //releaseLength 86 | }; 87 | 88 | //////////USER EDITING ENCOURAGED 89 | const byte lengthFactor = 4; //length values are eight bits; we right shift them by this value to make them shorter (for instance, with value 4 the legnths' range is 0 to 15) 90 | ///////////////////////////////// 91 | 92 | void setup() { 93 | //disable USI to save power as we are not using it 94 | PRR = 1<> lengthFactor; 227 | int decayLength = ADSR[1] >> lengthFactor; 228 | int sustainLevel = ADSR[2]; 229 | 230 | //ATTACK 231 | if (attackLength == 0) OCR1B = attackLevel; 232 | else { 233 | globalTicks = 0; 234 | for (envelopeValue = 0; envelopeValue <= 255; ){ 235 | OCR1B = envelopeValue; 236 | if (globalTicks == attackLength) { 237 | envelopeValue++; 238 | globalTicks = 0; 239 | } 240 | } 241 | } 242 | //DECAY 243 | globalTicks = 0; 244 | if ((decayLength == 0) || (sustainLevel == attackLevel)) OCR1B = sustainLevel; 245 | else{ 246 | if (sustainLevel < attackLevel){ 247 | for (envelopeValue = attackLevel; envelopeValue >= sustainLevel; ){ 248 | OCR1B = envelopeValue; 249 | if (globalTicks == decayLength) { 250 | envelopeValue--; 251 | globalTicks = 0; 252 | } 253 | } 254 | } 255 | } 256 | //SUSTAIN --nothing to do, we keep the last value until the "note off" trigger 257 | } 258 | 259 | void readR() { 260 | int sustainLevel = ADSR[2]; 261 | int releaseLength = ADSR [3] >> lengthFactor; 262 | 263 | //RELEASE 264 | if (releaseLength == 0) OCR1B = 0; 265 | else { 266 | OCR1B = sustainLevel; 267 | globalTicks = 0; 268 | for (envelopeValue = sustainLevel; envelopeValue >= 0;){ 269 | if (!autoTrigger) { //NORMAL ADSR ONLY 270 | if (PINB & 1 << 2){ //if during R stage there's a new trigger, silence and exit 271 | OCR1B = 0; 272 | return; 273 | } 274 | } 275 | OCR1B = envelopeValue; 276 | if (globalTicks == releaseLength) { 277 | envelopeValue--; 278 | globalTicks = 0; 279 | } 280 | } 281 | } 282 | } 283 | 284 | void checkButton() { 285 | while (inputButtonValue == HIGH) { 286 | button_delay++; 287 | _delay_ms(10); 288 | } 289 | if (inputButtonValue == LOW) { 290 | beenDoubleClicked = false; 291 | if (button_delay > 0) { 292 | bool hold = true; 293 | while (hold) { 294 | bool previousButtonState = inputButtonValue; //see if the button is pressed or not 295 | 296 | _delay_ms(1); 297 | 298 | button_delay_b++; //fast counter to check if there are more presses 299 | if ((inputButtonValue == HIGH)&& (previousButtonState == 0)) { 300 | additionalClicks++; //if we press the button and we were not pressing it before, that counts as a click 301 | } 302 | 303 | if (button_delay_b == 300) { 304 | if (additionalClicks == 0){ //button released (regular single click) 305 | 306 | parameterChange = false; 307 | 308 | currentStep++; //cycles through the steps 309 | if (currentStep >= 4) currentStep = 0; 310 | flashLEDSlow(currentStep + 1); 311 | 312 | button_delay = 0; 313 | button_delay_b = 0; 314 | additionalClicks = 0; 315 | hold = false; 316 | } 317 | else if (additionalClicks == 1) { //button pressed again (double click), 318 | 319 | manualTrigger(); 320 | 321 | button_delay = 0; 322 | button_delay_b = 0; 323 | additionalClicks = 0; 324 | beenDoubleClicked = true; 325 | hold = false; 326 | } 327 | else if (additionalClicks > 1 ) { //button pressed at least twice (triple click or more) 328 | 329 | if (calibrating == true){ 330 | digitalWrite (0, HIGH); 331 | OCR1B = 0; 332 | calibrating = false; 333 | } 334 | else { 335 | digitalWrite (0, LOW); 336 | OCR1B = 255; 337 | calibrating = true; 338 | } 339 | 340 | button_delay = 0; 341 | button_delay_b = 0; 342 | additionalClicks = 0; 343 | beenDoubleClicked = true; 344 | hold = false; 345 | } 346 | } 347 | } 348 | } 349 | } 350 | } 351 | 352 | void checkVoltage() { //voltage from 255 to 0; 46 is (approx)5v, 94 is 2.8, 104-106 is 2.5 353 | //we measure a fixed value of 1.1 against Vcc, so the lower the measurement, the higher Vcc 354 | ADMUX = (0 << REFS1) | (0 << REFS0); //Vcc as reference 355 | ADMUX |= (1 << ADLAR); //Left adjust result (8 bit conversion stored in ADCH) 356 | ADMUX |= (1 << MUX3) | (1 << MUX2); //1.1v input 357 | delay(250); // Wait for Vref to settle 358 | ADCSRA |= (1 << ADSC); // Start conversion 359 | while (bit_is_set(ADCSRA, ADSC)); // wait while measuring 360 | if (ADCH > 103) //approx 2.6 361 | flashLED(8, 100); 362 | else 363 | flashLED(1, 250); 364 | } 365 | 366 | void flashLEDSlow(int times) { 367 | for (int i = 0; i < times; i++){ 368 | _delay_ms(70); 369 | digitalWrite(0, LOW); 370 | _delay_ms(70); 371 | digitalWrite(0, HIGH); 372 | } 373 | } 374 | 375 | void flashLED (int times, int gap) { //for voltage check only (uses regular delay) 376 | for (int i = 0; i < times; i++) 377 | { 378 | digitalWrite(0, HIGH); 379 | delay(gap); 380 | digitalWrite(0, LOW); 381 | delay(gap); 382 | } 383 | } 384 | --------------------------------------------------------------------------------