Arnov Sharma
Published © LGPL

Atari Punk Synth V2

Version 2 of my previous Atari Punk Synth project powered by a Minimal ATmega328-PU config and Mozzi library.

BeginnerFull instructions provided2 hours1,388

Things used in this project

Hardware components

JLCPCB Customized PCB
JLCPCB Customized PCB
Arduino Nano R3
Arduino Nano R3
for Flashing the Atmega328PU
ATmega328PB microcontroller
Microchip ATmega328PB microcontroller
Atmega328PU DIP28
22pf Cap SMD
16MHz Crystal
Rotary potentiometer (generic)
Rotary potentiometer (generic)

Software apps and online services

Arduino IDE
Arduino IDE
OrCad Cadance


Read more

Custom parts and enclosures

Gerber data for PCB


Circuit Diagram


main sketch

  Example using 2 light dependent resistors (LDRs) to change 
  FM synthesis parameters, and a knob for fundamental frequency,
  using Mozzi sonification library.

  Demonstrates analog input, audio and control oscillators, phase modulation
  and smoothing a control signal at audio rate to avoid clicks.
  Also demonstrates AutoMap, which maps unpredictable inputs to a set range.
  This example goes with a tutorial on the Mozzi site:
  The circuit:
     Audio output on digital pin 9 (on a Uno or similar), or 
     check the README or

     Potentiometer connected to analog pin 0.
       Center pin of the potentiometer goes to the analog pin.
       Side pins of the potentiometer go to +5V and ground
     Light dependent resistor (LDR) and 5.1k resistor on analog pin 1:
       LDR from analog pin to +5V
       5.1k resistor from analog pin to ground
     Light dependent resistor (LDR) and 5.1k resistor on analog pin 2:
       LDR from analog pin to +5V
       5.1k resistor from analog pin to ground
  Mozzi help/discussion/announcements:!forum/mozzi-users

  Tim Barrass 2013.
  This example code is in the public domain.

#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(){

Fade Sketch

For testing the board
int led = 9;           // the PWM pin the LED is attached to
int brightness = 0;    // how bright the LED is
int fadeAmount = 5;    // how many points to fade the LED by

// the setup routine runs once when you press reset:
void setup() {
  // declare pin 9 to be an output:
  pinMode(led, OUTPUT);

// the loop routine runs over and over again forever:
void loop() {
  // set the brightness of pin 9:
  analogWrite(led, brightness);

  // change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;

  // reverse the direction of the fading at the ends of the fade:
  if (brightness <= 0 || brightness >= 255) {
    fadeAmount = -fadeAmount;
  // wait for 30 milliseconds to see the dimming effect


Arnov Sharma

Arnov Sharma

162 projects • 212 followers
Just your average MAKER