{"id":19150014,"url":"https://github.com/smashingboxes/moogfest-2017","last_synced_at":"2026-02-13T09:58:04.175Z","repository":{"id":140669083,"uuid":"91712386","full_name":"smashingboxes/moogfest-2017","owner":"smashingboxes","description":"Code and instructions for building a $20 synthesizer using our Moogfest-2017 kit","archived":false,"fork":false,"pushed_at":"2017-05-24T15:45:27.000Z","size":3463,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-19T18:33:19.658Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/smashingboxes.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-18T15:56:33.000Z","updated_at":"2025-01-12T21:02:09.000Z","dependencies_parsed_at":null,"dependency_job_id":"93c5a804-0601-4828-a165-3a6322bebf38","html_url":"https://github.com/smashingboxes/moogfest-2017","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smashingboxes%2Fmoogfest-2017","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smashingboxes%2Fmoogfest-2017/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smashingboxes%2Fmoogfest-2017/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smashingboxes%2Fmoogfest-2017/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/smashingboxes","download_url":"https://codeload.github.com/smashingboxes/moogfest-2017/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252816937,"owners_count":21808704,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T08:10:23.217Z","updated_at":"2025-10-05T20:57:17.414Z","avatar_url":"https://github.com/smashingboxes.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Building a Programmable Synth for $20\n\nFor [Moogfest](http://www.moogfest.com/) this year, Smashing Boxes will be hosting a VIP reception\nfeaturing some innovative projects we have done in the areas of digital art, machine learning, and\ndata visualization. We want to do more than just show however; we wanted to give participants\nsomething that they could go home and hack on as well. Our goal was to put together a small kit of\nelectronics that would allow festival-goers to build their own programmable synthesizer. We are\nnot associated with any of the products discussed in this post; we simply wanted to put together\na kit that could be functional for around $20, including prototyping materials like a breadboard\nand wires.\n\nThis guide will walk through all the parts needed, the theory behind how this project works, how to\nassemble the parts, and how to write software that controls it.\n\n\n## The Parts\n\n- We picked the [Nucleo-L432KC](https://developer.mbed.org/platforms/ST-Nucleo-L432KC/) as the\n  centerpiece of our synthesizer because it delivers tons of potential at a great price. This article\n  will detail a simple square wave synth, but this little kit has 9 analog inputs and 2 analog\n  outputs that could be used to do all kinds of things. Some other nice features are the expansive\n  memory (256kB Flash, 64k RAM) and the True Random Number Generator, which could be particularly\n  fun when working with music. Price: $11.\n- We picked [a simple 0.5W speaker from Adafruit](https://www.adafruit.com/product/1890) as the\n  output for our synthesizer. In order to use this with the 5V power that USB supplies, we also\n  added in a\n  [resistor](https://www.digikey.com/product-detail/en/vishay-bc-components/SFR2500002439FR500/PPC24.3YCT-ND/596973)\n  in order to limit the power being sent into the speaker. Price: $1.50\n- In order to deliver power to the speaker, we are using a\n  [simple N-channel MOSFET (2N7000)](https://www.onsemi.com/pub/Collateral/2N7000-D.PDF)\n  to switch on and off the full power to the speaker. This is a simple and cheap circuit, but only\n  allows two states: on and off. This means that we can only use square waves to drive our speaker.\n  Price: $0.38\n- We also need a way to power and connect all this stuff. For prototyping, we bought a simple\n  [400 connection breadboard](https://www.digikey.com/product-detail/en/bud-industries/BB-32621/377-2094-ND/4156445)\n  and a\n  [40-wire cable with male/male connectors](https://www.digikey.com/product-detail/en/adafruit-industries-llc/758/1528-1154-ND/5353614).\n  If you don't have a USB B-micro connector, you will\n  [also need to buy one](https://www.digikey.com/product-detail/en/qualtek/3025010-03/Q853-ND/4341883)\n  since the Nucleo kits do not include one.\n- The complete parts list with links to Digikey for ordering can be found in our\n  [moogfest-2017](https://github.com/smashingboxes/moogfest-2017/blob/master/assets/parts.csv)\n  repository on Github. Total cost for one kit: **$21.26**\n\n\n## Circuit Theory\n\nFirst we'll take a look at a few of the circuits that make this synthesizer work. If theory isn't\nyour thing, you can skip this section and jump right into the build.\n\n\n### Transistor Switched Speaker\n\nIn order for a speaker to produce sound, it needs to be fed a signal that causes the cone to move\nback and forth. This is typically done by producing a very weak signal, like one coming from a\nmicrophone or guitar, and putting it through an amplifier.\n\nFor our cheap version, we will be using a transistor to simply switch the speaker all-on and\nall-off. A transistor is a voltage controlled switch; it allows us to turn on and off a high current\ncircuit (like a speaker) using a low current circuit (like a microcontroller pin).\n\n![Transistor Circuit](assets/transistor.png)\n\nWhen the microcontroller pin goes high, the speaker circuit turns on, sending current through the\nspeaker and causing the cone to move. When the pin goes low, the circuit is shut off and the cone\nmoves back. These movements produce sound! The big limitation of this circuit, however, is that the\nsignal is either all-on or all-off (digital), meaning it will only create a square wave.\n\nYou may also notice that there is a resistor in the picture. The speaker that we chose is rated at\n0.5W, and has an impedance of 8 ohms. Power is calculated as:\n\n`P = IV = V^2 / R`\n\nFor `V = 5V; R = 8 Ohm`, the power calculates out to 3.125W! In order to make sure that the speaker\ndoesn't burn out, we need to add a current limiting resistor. Since we cannot change the impedance\nof the speaker, we need to change the input voltage by using a simple voltage divider. If we instead\nsolve for `V` in the formula above by fixing `R = 8 Ohm, P = 0.5W`, we find that the max voltage for\nthe speaker is `2V`. We can finally calculate the resistance needed using:\n\n`2V = 5V * 8 Ohm / (R1 + 8 Ohm)`\n\nSolving this, we find that we need at least a 12 Ohm resistor to not burn out our speaker. For this\nkit, we chose 24 Ohm just to be safe.\n\nIf you are interested in making a circuit that can do more than just square waves, check out the\n`Using Analog Outputs` section in `Where to Go From Here` below!\n\n\n### Potentiometer Dial\n\nThe potentiometer circuit we will be using is much simpler. A potentiometer is simply a resistor\nwith a third connection (the wiper) that can be moved around using a physical dial. We will be using\nthe potentiometer to create a signal between 3.3V and GND that the user can control using the dial.\n\n![Transistor Circuit](assets/potentiometer.png)\n\nWhen the dial is turned all the way in one direction, the wiper will be connected to the 3.3V line.\nWhen you turn is all the way in the other direction, the wiper will be connected to ground. Anywhere\nin between it will be at some voltage in between 3.3V and ground. By connecting the wiper to an\nanalog input on your microcontroller, you can get a reading of where the dial is currently at.\n\n\n## Building your Synthesizer\n\nIf you haven't used a breadboard before, check out\n[this tutorial](https://computers.tutsplus.com/tutorials/how-to-use-a-breadboard-and-build-a-led-circuit--mac-54746)\nwhich goes through the basics of how the breadboard is internally connected. Our guide will\nuse the notation `letter:number` to denote the row and column that the wires or parts should be\nplaced in. These letters and numbers are marked on the board suggested in the parts above.\n\n\n### Lay out the Parts\n\nLet's start by laying out where all the components will go. Start by connecting the Nucleo board to\nthe top of the breadboard so that pin `D1/TX` is connected to `d:1` and `VIN` is connected to `h:1`.\nConnect the resistor to the very bottom of the board: `e:30` and `f:30`. The potentiometer will be\nconnected to `g:20,21,22` with its side legs set in the groove in the middle of the breadboard. The\ntransistor should be connected to `j:22,23,24`. The transistor should have its flat side facing the\ncenter of the breadboard.\n\n![Assembly Picture 1](assets/assembly-1.jpg)\n\n\n### Wire The Potentiometer\n\nTo wire the potentiometer, connect the following pins:\n- Potentiometer Pin 1 `i:20` to the microcontroller's 3.3V line, `j:14`.\n- Potentiometer Pin 2 `i:21` to the microcontroller's A0 input, `j:12`.\n- Potentiometer Pin 3 `i:22` to the microcontroller's GND pin, `j:2`.\n\n![Assembly Picture 2](assets/assembly-2.jpg)\n\n\n### Wire The Transistor\n\nFinally, lets wire the speaker and transistor up.\n- The PWM audio signal `a:6` to the gate of the transistor `i:23`.\n- One `speaker cable` to the source of the MOSFET, `i:24`.\n- One `speaker cable` to one side of the resistor, `j:30`.\n- The 5V line `i:4` to the other side of the resistor, `a:30`.\n\n![Assembly Picture 3](assets/assembly-3.jpg)\n\nNote: there is an error in this picture. Instead of `a:30` being tied to the 5V line, it is tied to\n`Vin`. Please connect `a:30` to `j:4`, not `j:1` as depicted in the picture.\n\n\n### Ready To Program\n\nThe final wiring diagram should look like the following:\n\n![Full Schematic](assets/schematic.png)\n\nOnce these are all connected, your breadboard is ready to be programmed. Check out the sections\nbelow to start programming your board, or alternatively, check out our\n[moogfest-2017](https://github.com/smashingboxes/moogfest-2017) repo for some stock programs to test\nthat your board is working!\n\n\n## Programming Your Synthesizer\n\nIn addition to the hardware specs and costs, we also chose the Nucleo board because it can be easily\nprogrammed using [mbed.org](https://developer.mbed.org/). Mbed is an online IDE that allows you to\ncompile your code remotely, download it, and then drag and drop it into the microcontroller's\nmemory. If you want more information about the platform, we recommend mbed's\n[getting started guide](https://developer.mbed.org/getting-started/).\n\nAs was mentioned in the beginning, we need to be able to do two things: output a square wave, and\nread the position of the potentiometer. The mbed platform makes both of these tasks easy. The code\nto create a square wave is simply:\n\n```\n// Create an instance of a PWM object\nPwmOut my_pwm(pin_number);\n\n// Set the period, or time between cycles, to (1.0 / FREQ).\nmy_pwm.period(1.0/440);\n\n// Set the duty cycle, or amount of time at the top of the\n// square versus the bottom of the square, to 0.5 (50%).\n// This will start the note.\nmy_pwm.write(0.5);\n```\n\nLikewise, the code to read an analog input is:\n\n```\n// Create an instance of an Analog input\nAnalogIn potentiometer(A0);\n\n// To read the input, simply call the read() function.\nfloat reading_1 = potentiometer.read();\n\n// This does the same thing, but has a shorter notation.\nfloat reading_2 = potentiometer;       \n```\n\nThat is pretty much all you need! We can use these primitives in a bunch of different ways to create\nsound. Creating a basic synthesizer that lets you use the potentiometer to sweep through 3 octaves\nis as simple as:\n\n```\nmy_pwm.write(0.5);\nwhile(1) my_pwm.period(1 / (220 + 1540 * potentiometer));\n```\n\nWe wanted to make something a little more complex though, so we made a demo that lets the user\nshift the pitch dynamically for the [Giorgio Morodor](https://www.youtube.com/watch?v=zhl-Cs1-sG4)\nrhythm from Daft Punk's Random Access Memories. There are a couple of helper functions that allow\nyou to call notes by name instead of frequency and to keep basic tempo.\n\nThe code for this demo can be found\n[here](https://github.com/smashingboxes/moogfest-2017/blob/master/giorgio/main.cpp).\nIf you just want to program your controller and go, you can download the compiled version:\n[giorgio.bin](https://github.com/smashingboxes/moogfest-2017/blob/master/assets/giorgio.bin). To\nprogram the Nucleo, plug it into a computer and it will enumerate it as a flash drive. You can then\ndrag-and-drop the `.bin` file onto the Nucleo and it will reprogram itself and start running this\nprogram.\n\n\n## Where To Go From Here\n\n\n### Adding Buttons, Switches, and Dials\n\n- **Buttons** can be read using `DigitalIn`, and are read into the chip as `0` or `1`. If you wanted\n  a simple keyboard, you could achieve this by connecting one button per note that you want to\n  control. Buttons only change their state while they are pressed; once they are released they\n  reset.\n- **Switches** work the same as buttons, except that they stay in the position that they are set to.\n  They are read using the same mechanisms, and for synths are useful for settings that will not\n  change. If you want to switch between a major and minor arpeggiator without having to hold a\n  button, a switch is likely the right move.\n- **Potentiometers** have already been covered above, but can be used for so much more! Remember\n  that potentiometers are good for creating signals between some min and max value.\n- **Rotary Encoders** are dials like a potentiometer, but instead of having a min and max value,\n  they output a signal only when they are turned. These are good for selecting one item in a list\n  of discrete items.\n\n\n### Using Analog Inputs\n\nIn this example, we used one of the 9 analog inputs to read in the signal from a potentiometer.\nAnalog inputs can be used for so much more, from reading temperature sensors and light sensors to\nreading inputs from your other synthesizer components. We recommend checking out\n[sparkfun.com](https://www.sparkfun.com) or [adafruit.com](https://www.adafruit.com) for more easy\nto use, well-documented components.\n\n\n### Using Analog Outputs\n\nSquare waves are great, but there are so many other waves that can completely change the sound of\nthe synth. As mentioned before, there are 2 digital-to-analog outputs, or DACs, that allow us to\nsend an analog signal out of our chip. This opens the door to all kinds of other waves that are\ncommon in synths, such as [sine waves and sawtooth waves](https://www.youtube.com/watch?v=j2uB4nKzGlg).\nSince the transistor driver circuit is on-off only, we will have to use one of the following two\nways to output our sound into the world:\n\n1. Output the signal at line-level and use headphones or other speakers. This is the more modular\n   and simple approach since it just requires some passive components and can connect to far more.\n   This can be achieved with a couple of passive components, or by using a pre-driver meant for this\n   application (like the one seen in the\n   [STM32F4 Discovery board](http://www.st.com/resource/en/schematic_pack/stm32f4discovery_sch.zip)).\n\n1. Use a signal amplifier to drive our speaker. This allows us to use a chip to amplify any signal,\n   not just a square wave. It will require more than just passive components, but you can use the\n   speaker above or another, larger speaker. A good example of a chip that lets you do this is the\n   [LM386](http://www.ti.com/lit/ds/symlink/lm386.pdf), but there are countless others to choose\n   from.\n\n---\n\nHopefully this covers everything you need to know in order to build your own programmable synth.\nIf you have any problems with setting things up, we've set up an email that you can use to ask\nquestions: [synth-help@smashingboxes.com](mailto:synth-help@smashingboxes.com). If you use this kit\nto build a cool new type of synth, we would also love to hear about it.\n\nThe reason we are hosting this event is to highlight the projects that have spun out of Smashing\nLabs, including this synth kit. We hope that if you are at Moogfest, you have the chance to check\nout some of the other fun projects that we have been working on this year.\n\nGood luck, and happy hacking.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmashingboxes%2Fmoogfest-2017","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmashingboxes%2Fmoogfest-2017","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmashingboxes%2Fmoogfest-2017/lists"}