During the lockdown, I made a Synth Box Project "Arduino Punk Synth" to annoy my neighbor with its weird sound. (well the actual goal was just to make an Arduino based Atari punk Synth device which generates cool like synth sound)
That concept was pretty simple as it was using an Atmega328PU setup connected with 5 Pots for modulating sound frequency, pitch, etc, and a 3W Speaker for sound output.
All things were enclosed nicely in a 3D Printed Body, you can check that project out from here- https://www.hackster.io/Oniichan_is_ded/arduino-atari-punk-synth-2934e8
Later I added a PAM8403 Audio AMP Module to increase the sound loudness.
The OLD setup had Wires, lots of wire. So to reduce the wiring and make this setup better, I Prepared its V2 which has PAM8403 onboard and Pots for audio Modulations with other stuff. (MCU is same, Atmega328PU)
I send the new V2 PCB to JLCPCB and received the PCBs after a week.
I have to say, the PCBs that I received was high quality and NICEEEEE like expected. also, thanks JLCPCB for supporting this project! You can check them out from here- http://jlcpcb.com/
Material Required- Custom PCB x1
- Atmega328PU x1
- 22pf CAP 0603 x2
- 16MHz Crystal x1
- POT 10-100K x5
- PAM8403 Audio Module x1
- SMD LED 0603 x1
- Resistor 10K 0603 x1
- Resistor 1K 0603 x1
- Micro USB Socket x1
- Connectors
- Speaker 3W x1
This is the main Schematic of the Circuit, This setup is driven by an Atmega328PU MCU which is connected with a 22pf cap and 16MHz Crystal according to its minimal configuration. Potentiometers are connected from A0 to A4.
Audio Output is then connected with the R and L port of the PAM8403.
For Programming the chip, there's an ISP Header which has VCC, GND, MISO, MOSI, SCK and RESET Pin.
I've also added an LDR and few LEDs on this circuit for a future project.
Assemblythe assembly was pretty simple and straightforward in this project, I first added the SMD Components on the PCB.
for this, I used a DIY SMT Hotplate. I first put the solder paste on pads of Components on PCB and then added them one by one.
after that, I just put the whole setup onto the hotplate and reflow the PCB at 250°C
then I solder the THT Components which were the MCU, Potentiometers, Connectors, and PAM8403 module.
Note- PAM8403 Module is soldered from the bottom side of this PCB.
you can check out this project's video for the assembly tutorial.
Flashing the SetupNow, this setup uses an Atmega328PU. Atmega328PU has a little hex file onboard known as a bootloader which is similar to BIOS. cheap atmega328PU don't usually come with a preinstalled bootloader so I have to burn the bootloader onto the MCU and for that, I used one of my previous project which was an Arduino Based Attiny Programmer.
This Programmer was made for Burning the bootloader and Flash code into the Attiny MCUs by using "Arduino as ISP Sketch" uploaded into a regular Arduino Nano R3 with few tweaks (adding 1uf Cap between reset and GND)
see my previous project for making this programmer and getting started with this flashing method.
I connected the SPI Pins of Atmega328PU with SPI Pins of Arduino Nano together and Burn the bootloader of At, ega328PU and uploaded FADE SKETCH for testing the Atmega chip.
After confirming that the MCU is working properly, now we can just upload the Code and power up the setup.
/*
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:
http://sensorium.github.io/Mozzi/learn/Mozzi_Introductory_Tutorial.pdf
The circuit:
Audio output on digital pin 9 (on a Uno or similar), or
check the README or http://sensorium.github.com/Mozzi/
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:
https://groups.google.com/forum/#!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
aCarrier.setFreq(carrier_freq);
aModulator.setFreq(mod_freq);
// 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 * (kIntensityMod.next()+128))>>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);
kIntensityMod.setFreq(mod_speed);
// Serial.println(); // finally, print a carraige return for the next line of debugging info
}
int updateAudio(){
long modulation = aSmoothIntensity.next(fm_intensity) * aModulator.next();
return aCarrier.phMod(modulation);
}
void loop(){
audioHook();
}
The code is pretty long but basically, it runs on Mozzi Library which generates algorithmic music without the need for additional shields, message passing or external synths. This library is pretty well documented so you can check that out from here and download it. install this library before uploading this sketch.
https://sensorium.github.io/Mozzi/
the original author was Tim Barrass and This example code is in the public domain (Thanks TIM, Very Kewl).
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;
The POTs are connected on A0, A1, A2, A3, A4 and the Audio Out is D9.
RESULThere's the Project Video-
So as you can see or hear, this Setup is loud and cool. That is all thanks to the Mozzi Library for doing like 50% JOB by modulating the sound without adding any extra external ICs for sound modulation.
Also, thanks JLCPCB again for Providing the PCBs for this build. The blue solder mask is just niceeeee so yeah, everything, in the end, works out pretty well.
Leave a comment if you guys have any problem replicating this project! I'll help you out!
Comments