Project tutorial
Arduino Atari Punk Synth

Arduino Atari Punk Synth © GPL3+

A DIY version of Atari Punk Synth with minimal stuff.

  • 2 respects

Components and supplies

09939 01
Rotary potentiometer (generic)
Ard nano
Arduino Nano R3
Logo jycgurodtz
UTSOURCE Electronic Parts
everything above can be found here for a low price

Necessary tools and machines

3D Printer (generic)

Apps and online services

About this project

Watch the video first.

I wanted to make a Synth that resembles the great "Atari Punk Synth" from the 1980s. APS usually was based on 556 dual timer IC but in this version, I have used an ATmega328PU on a minimal config and some pots in order to replicate the so-called "Sound Synthesizer."

First, I designed the base body in Fusion360 and 3D printed it on my Ender 3.

Then I just put everything together like a jigsaw puzzle.

Thanks to offer electronic components for this project!

you can check, they deal in all kinds of electronic components, for example, Arduino board, Atmega328PU, and many more.

The main part of the heart of this project is the Mozzi Library here's the link for downloading it.

After installing it, I uploaded the sketch based on this library to my minimal Arduino Uno PCB which is basically a breakout board for ATmega328PU (originally I made the circuit for a different thing but I end up using it instead of using a dot circuit board.

Results were good but the sound is not loud because I have connected the speaker directly with digital pin 9.

(Will be adding an OPAMP circuit in this in future.)


#include <MozziGuts.h>
#include <Oscil.h> // oscillator 
#include <tables/cos2048_int8.h> // table for Oscils to play
#include <Smooth.h>
#include <AutoMap.h> // maps unpredictable inputs to a range
// int freqVal;
// desired carrier frequency max and min, for AutoMap
const int MIN_CARRIER_FREQ = 22;
const int MAX_CARRIER_FREQ = 440;

const int MIN = 1;
const int MAX = 10;

const int MIN_2 = 1;
const int MAX_2 = 15;

// desired intensity max and min, for AutoMap, note they're inverted for reverse dynamics
const int MIN_INTENSITY = 700;
const int MAX_INTENSITY = 10;

// desired mod speed max and min, for AutoMap, note they're inverted for reverse dynamics
const int MIN_MOD_SPEED = 10000;
const int MAX_MOD_SPEED = 1;

AutoMap kMapCarrierFreq(0,1023,MIN_CARRIER_FREQ,MAX_CARRIER_FREQ);
AutoMap kMapIntensity(0,1023,MIN_INTENSITY,MAX_INTENSITY);
AutoMap kMapModSpeed(0,1023,MIN_MOD_SPEED,MAX_MOD_SPEED);
AutoMap mapThis(0,1023,MIN,MAX);
AutoMap mapThisToo(0,1023,MIN_2,MAX_2);

const int KNOB_PIN = 0; // set the input for the knob to analog pin 0
const int LDR1_PIN=1; // set the analog input for fm_intensity to pin 1
const int LDR2_PIN=2; // set the analog input for mod rate to pin 2
const int LDR3_PIN=4;
const int LDR4_PIN=3;

Oscil<COS2048_NUM_CELLS, AUDIO_RATE> aCarrier(COS2048_DATA);
Oscil<COS2048_NUM_CELLS, AUDIO_RATE> aModulator(COS2048_DATA);
Oscil<COS2048_NUM_CELLS, CONTROL_RATE> kIntensityMod(COS2048_DATA);

int mod_ratio = 5; // brightness (harmonics)
long fm_intensity; // carries control info from updateControl to updateAudio

// smoothing for intensity to remove clicks on transitions
float smoothness = 0.95f;
Smooth <long> aSmoothIntensity(smoothness);

void setup(){
//  Serial.begin(115200); // set up the Serial output so we can look at the light level
  startMozzi(); // :))

void updateControl(){
//  freqVal = map(LDR3_PIN, 0, 1023, 1, 100);
   int freqVal = mozziAnalogRead(LDR3_PIN); // value is 0-1023
   int FRQ = mapThis(freqVal);
   int knob2 = mozziAnalogRead(LDR4_PIN); // value is 0-1023
   int knob2Val = mapThis(knob2);
  // read the knob
  int knob_value = mozziAnalogRead(KNOB_PIN); // value is 0-1023
  // map the knob to carrier frequency
  int carrier_freq = kMapCarrierFreq(knob_value);
  //calculate the modulation frequency to stay in ratio
  int mod_freq = carrier_freq * mod_ratio * FRQ;
  // set the FM oscillator frequencies
  // read the light dependent resistor on the width Analog input pin
  int LDR1_value= mozziAnalogRead(LDR1_PIN); // value is 0-1023
  // print the value to the Serial monitor for debugging
  //Serial.print("LDR1 = "); 
 // Serial.print(LDR1_value);
 // Serial.print("\t"); // prints a tab

  int LDR1_calibrated = kMapIntensity(LDR1_value);
 // Serial.print("LDR1_calibrated = ");
 // Serial.print(LDR1_calibrated);
//  Serial.print("\t"); // prints a tab
 // calculate the fm_intensity
  fm_intensity = ((long)LDR1_calibrated * knob2Val * (>>8; // shift back to range after 8 bit multiply
//  Serial.print("fm_intensity = ");
 // Serial.print(fm_intensity);
//  Serial.print("\t"); // prints a tab
  // read the light dependent resistor on the speed Analog input pin
  int LDR2_value= mozziAnalogRead(LDR2_PIN); // value is 0-1023
//  Serial.print("LDR2 = "); 
//  Serial.print(LDR2_value);
//  Serial.print("\t"); // prints a tab
  // use a float here for low frequencies
  float mod_speed = (float)kMapModSpeed(LDR2_value)/1000;
  //Serial.print("   mod_speed = ");
 // Serial.print(mod_speed);
 // Serial.println(); // finally, print a carraige return for the next line of debugging info

int updateAudio(){
  long modulation = *;
  return aCarrier.phMod(modulation);

void loop(){

Custom parts and enclosures

base body

Sketchfab still processing.


sch for pcb


Similar projects you might like

Arduino MIDI Stepper Synth

Project tutorial by Jonathan Kayne

  • 67 respects

Simple Arduino Piano

Project tutorial by Arnov Sharma

  • 1 comment
  • 15 respects


Project tutorial by bzqp

  • 4 respects

Let's Build an SN76489 USB MIDI Synth With Arduino Nano

Project tutorial by tyrkelko

  • 1 comment
  • 5 respects

Arduino MIDI Arpeggiator

Project tutorial by Dmitry

  • 117 respects
Add projectSign up / Login