The Alpha Geek – Geeking Out

SparkFun

SparkFun

Project #22: Synthesizer – Wave – Mk13

——

DonLucElectronics #DonLuc #Synthesizer #Mozzi #Keyboard #ADSREnvelope #Oscillators #Arduino #SparkFunRedBoard #Project #Fritzing #Programming #Electronics #Microcontrollers #Consultant

——

Wave

——

Wave

——

Wave

——

Sine Wave and Cosine Wave

A sine wave is a mathematical curve defined in terms of the sine trigonometric function. It is a type of continuous wave and also a smooth periodic function. It occurs often in mathematics, as well as in physics, engineering, signal processing and many other fields.

The term sinusoid describes any wave with characteristics of a sine wave. Thus, a cosine wave is also said to be sinusoidal, which is also a sine wave with a phase-shift. Because of this head start, it is often said that the cosine function leads the sine function or the sine lags the cosine. The term sinusoidal thereby collectively refers to both sine waves and cosine waves with any phase offset.

Sawtooth Wave

The sawtooth wave is a kind of non-sinusoidal waveform. It is so named based on its resemblance to the teeth of a plain toothed saw with a zero rake angle. A single sawtooth, or an intermittently triggered sawtooth, is called a ramp waveform.

Triangle Wave

A triangle wave is a non-sinusoidal waveform named for its triangular shape. It is a periodic, piecewise linear, continuous real function.

Square Wave

A square wave is a non-sinusoidal periodic waveform in which the amplitude alternates at a steady frequency between fixed minimum and maximum values, with the same duration at minimum and maximum. In an ideal square wave, the transitions between minimum and maximum are instantaneous.

DL2208Mk06

1 x SparkFun RedBoard
1 x 10k Ohm Rotary Potentiometer
1 x Potentiometer Knob – Blue
7 x Momentary Button – Panel Mount (Blue)
5 x Momentary Button – Panel Mount (Black)
12 x 10K Ohm Resistor
5 x 10k Ohm Slide Linear Taper Pot – X-Large
5 x Slide Potentiometer Knob – X-Large
1 x Perfboard 13.5 cm x 11 cm
1 x SparkFun Solderable Breadboard
1 x Audio Jack 3.5mm
1 x SparkFun Audio Jack Breakout
1 x SparkFun ProtoShield
1 x Insignia Speakers
1 x SparkFun Cerberus USB Cable

SparkFun RedBoard

LP0 – Analog A0 – Blue
LP1 – Analog A1 – Green
LP2 – Analog A2 – Grey
LP3 – Analog A3 – Yellow
LP4 – Analog A4 – Purple
PO5 – Analog A5
KY1 – 1
KY2 – 2
KY3 – 3
KY4 – 4
KY5 – 5
KY6 – 6
KY7 – 7
KY8 – 8
SPK – 9
KY10 – 10
KY11 – 11
KY12 – 12
KY13 – 13
VIN – +5V
GND – GND

——

DL2208Mk06p.ino

/* ***** Don Luc Electronics © *****
Software Version Information
Project #22: Synthesizer - Wave - Mk13
22-13
DL2208Mk06p.ino
1 x SparkFun RedBoard
1 x 10k Ohm Rotary Potentiometer
1 x Potentiometer Knob - Blue
7 x Momentary Button - Panel Mount (Blue)
5 x Momentary Button - Panel Mount (Black)
12 x 1K Ohm Resistor
5 x 10k Ohm Slide Linear Taper Pot - X-Large
5 x Slide Potentiometer Knob - X-Large
1 x Perfboard 13.5 cm x 11 cm
1 x SparkFun Solderable Breadboard
1 x Audio Jack 3.5mm
1 x SparkFun Audio Jack Breakout
1 x SparkFun ProtoShield
1 x Insignia Speakers
1 x SparkFun Cerberus USB Cable
*/

// Include the Library Code
// Pitches
#include "pitches.h"
// Mozzi
#include <MozziGuts.h>
// Oscillator
#include <Oscil.h>
// Sine Wave Table For Oscillator
#include <tables/sin2048_int8.h>
// Cosine Wave Table For Oscillator
#include <tables/cos2048_int8.h>
// Sawtooth Wave Table For Oscillator
#include <tables/saw2048_int8.h>
// Triangle Wave Table For Oscillator
#include <tables/triangle2048_int8.h>
// Square Wave Table For Oscillator
#include <tables/square_no_alias_2048_int8.h>
// ADSR envelope generator
#include <ADSR.h>

// Simple Keyboard
// Minimum reading of the button that generates a note
const int iKeyboard1 = 1;
const int iKeyboard2 = 2;
const int iKeyboard3 = 3;
const int iKeyboard4 = 4;
const int iKeyboard5 = 5;
const int iKeyboard6 = 6;
const int iKeyboard7 = 7;
const int iKeyboard8 = 8;
const int iKeyboard10 = 10;
const int iKeyboard11 = 11;
const int iKeyboard12 = 12;
const int iKeyboard13 = 13;
// Button is pressed
int iB1 = 1;
int iB2 = 1;
int iB3 = 1;
int iB4 = 1;
int iB5 = 1;
int iB6 = 1;
int iB7 = 1;
int iB8 = 1;
int iB10 = 1;
int iB11 = 1;
int iB12 = 1;
int iB13 = 1;

// Set the input for the potentiometer for Frequency to analog pin 2
const int potFreq = A2;
int iFreg = 1;
int iNoteA = 0;
int iNoteAS = 0;
int iNoteB = 0;
int iNoteC = 0;
int iNoteCS = 0;
int iNoteD = 0;
int iNoteDS = 0;
int iNoteE = 0;
int iNoteF = 0;
int iNoteFS = 0;
int iNoteG = 0;
int iNoteGS = 0;

// Potentiometer
int iPot4 = A4;

//Oscillator Functions declared for output envelope 1
// Carrier
Oscil<COS2048_NUM_CELLS, AUDIO_RATE> aCarrier;
// Set the input for the potentiometer for Oscillator to analog pin 4
const int potWave = A5;
// Wave
int iWave;
int iWaveLevel;

// ADSR declaration/definition
// Comment out to use control rate of 128
#define CONTROL_RATE 128
ADSR <CONTROL_RATE, CONTROL_RATE> envelope1;

// Set the input for the potentiometer Attack to analog pin 1
const int potAttack = A0;
// Attack
int attack_level = 0;
int iAttack = 0;

// Set the input for the potentiometer for Decay to analog pin 2
const int potDecay = A1;
// Decay
int decay_level = 0;
int iDecay = 0;

// Set the input for the potentiometer Attack Time to analog pin 3
const int potAttackTime = A3;
// Attack Time
int AttackTime_level = 0;
int iAttackTime = 0;

// Software Version Information
String sver = "22-13";

void loop() {

  // Audio Hook
  audioHook();
  
}

getKeyboard.ino

// getKeyboard
// setupKeyboard
void setupKeyboard() {

  // Initialize the button pin as an input
  pinMode(iKeyboard1, INPUT_PULLUP);
  pinMode(iKeyboard2, INPUT_PULLUP);
  pinMode(iKeyboard3, INPUT_PULLUP);
  pinMode(iKeyboard4, INPUT_PULLUP);
  pinMode(iKeyboard5, INPUT_PULLUP);
  pinMode(iKeyboard6, INPUT_PULLUP);
  pinMode(iKeyboard7, INPUT_PULLUP);
  pinMode(iKeyboard8, INPUT_PULLUP);
  pinMode(iKeyboard10, INPUT_PULLUP);
  pinMode(iKeyboard11, INPUT_PULLUP);
  pinMode(iKeyboard12, INPUT_PULLUP);
  pinMode(iKeyboard13, INPUT_PULLUP);
 
}
// isKeyboard
void isKeyboard() {

  // Oscillators
  isOscil();
  // Choose envelope levels
  // attack_level
  iAttack = mozziAnalogRead( potAttack );
  attack_level = map( iAttack, 0, 1023, 100, 400);
  // Attack Level
  envelope1.setAttackLevel( attack_level );
  // decay_level
  iDecay = mozziAnalogRead( potDecay );
  decay_level = map( iDecay, 0, 1023, 50, 255);
  // Decay Level
  envelope1.setDecayLevel( decay_level );
  // AttackTime_level
  iAttackTime = mozziAnalogRead( potAttackTime );
  AttackTime_level = map( iAttackTime, 0, 1023, 0, 900);
  // Attack Time Level
  envelope1.setAttackTime( AttackTime_level );

  // Read the state of the button value 1
  if ( digitalRead(iKeyboard1) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 1
    iB1 = iB1 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aCarrier.setFreq(iNoteA);

  }
  else
  {
    
    iB1 = iB1 - 1;

  }

  // Read the state of the button value 2
  if ( digitalRead(iKeyboard2) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 2
    iB2 = iB2 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aCarrier.setFreq(iNoteAS);

  }
  else
  {
    
    iB2 = iB2 - 1;
 
  }

  // Read the state of the button value 3
  if ( digitalRead(iKeyboard3) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 3
    iB3 = iB3 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aCarrier.setFreq(iNoteB);

  }
  else
  {
    
    iB3 = iB3 - 1;
 
  }

  // Read the state of the button value 4
  if ( digitalRead(iKeyboard4) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 4
    iB4 = iB4 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aCarrier.setFreq(iNoteC);

  }
  else
  {
    
    iB4 = iB4 - 1;
 
  }

  // Read the state of the button value 5
  if ( digitalRead(iKeyboard5) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 5
    iB5 = iB5 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aCarrier.setFreq(iNoteCS);

  }
  else
  {
    
    iB5 = iB5 - 1;
 
  }

  // Read the state of the button value 6
  if ( digitalRead(iKeyboard6) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 6
    iB6 = iB6 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aCarrier.setFreq(iNoteD);

  }
  else
  {
    
    iB6 = iB6 - 1;

  }

  // Read the state of the button value 7
  if ( digitalRead(iKeyboard7) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 7
    iB7 = iB7 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aCarrier.setFreq(iNoteDS);

  }
  else
  {
    
    iB7 = iB7 - 1;
 
  }

  // Read the state of the button value 8
  if ( digitalRead(iKeyboard8) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 8
    iB8 = iB8 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aCarrier.setFreq(iNoteE);

  }
  else
  {
    
    iB8 = iB8 - 1;

  }

  // Read the state of the button value 10
  if ( digitalRead(iKeyboard10) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 10
    iB10 = iB10 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aCarrier.setFreq(iNoteF);

  }
  else
  {
    
    iB10 = iB10 - 1;

  }

  // Read the state of the button value 11
  if ( digitalRead(iKeyboard11) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 11
    iB11 = iB11 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aCarrier.setFreq(iNoteFS);

  }
  else
  {
    
    iB11 = iB11 - 1;
 
  }

  // Read the state of the button value 12
  if ( digitalRead(iKeyboard12) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 12
    iB12 = iB12 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aCarrier.setFreq(iNoteG);

  }
  else
  {
    
    iB12 = iB12 - 1;
    
  }

  // Read the state of the button value 13
  if ( digitalRead(iKeyboard13) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 13
    iB13 = iB13 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aCarrier.setFreq(iNoteGS);

  }
  else
  {
    
    iB13 = iB13 - 1;

  }

}

getMozzi.ino

// Mozzi
// Update Control
void updateControl(){

  // Frequency
  isPitches();
  
  // Keyboard
  isKeyboard();

}
// Update Audio
int updateAudio()
{

  // Update Audio
  // ADSR declaration/definition
  envelope1.update();
  // >>8 for AUDIO_MODE STANDARD
  return (int) (envelope1.next() * aCarrier.next())>>8;

}

getOscillators.ino

// Oscillators
// isOscil
void isOscil(){
  
  // Oscillators
  // Value is 0-1023
  iWave = mozziAnalogRead(potWave);
  iWaveLevel = map(iWave, 0, 1023, 1, 5);

  switch (iWaveLevel) {
    case 1:
      // Sine Wave
      aCarrier.setTable(SIN2048_DATA);
      break;
    case 2:
      // Cosine Wave
      aCarrier.setTable(COS2048_DATA);
      break;
    case 3:
      // Sawtooth Wave
      aCarrier.setTable(SAW2048_DATA);
      break;
    case 4:
      // Triangle Wave
      aCarrier.setTable(TRIANGLE2048_DATA);
      break;
    case 5:
      // Square Wave
      aCarrier.setTable(SQUARE_NO_ALIAS_2048_DATA);
      break;
    default: // Case 0
      // Sine Wave
      aCarrier.setTable(SIN2048_DATA);
      break;
  }
  
}

getPitches.ino

// Pitches
// isPitches
void isPitches(){
  
  // Frequency
  // Value is 0-1023
  iFreg = mozziAnalogRead(potFreq);
  iFreg = map(iFreg, 0, 1023, 2, 6);

  // Range Frequency Note Low => High
  switch ( iFreg ) {
    case 1:
      // NOTE A1
      iNoteA = NOTE_A1;
      iNoteAS = NOTE_AS1;
      iNoteB = NOTE_B1;
      iNoteC = NOTE_C2;
      iNoteCS = NOTE_CS2;
      iNoteD = NOTE_D2;
      iNoteDS = NOTE_DS2;
      iNoteE = NOTE_E2;
      iNoteF = NOTE_F2;
      iNoteFS = NOTE_FS2;
      iNoteG = NOTE_G2;
      iNoteGS = NOTE_GS2;
      break;
    case 2:
      // NOTE A2
      iNoteA = NOTE_A2;
      iNoteAS = NOTE_AS2;
      iNoteB = NOTE_B2;
      iNoteC = NOTE_C3;
      iNoteCS = NOTE_CS3;
      iNoteD = NOTE_D3;
      iNoteDS = NOTE_DS3;
      iNoteE = NOTE_E3;
      iNoteF = NOTE_F3;
      iNoteFS = NOTE_FS3;
      iNoteG = NOTE_G3;
      iNoteGS = NOTE_GS3;
      break;
    case 3:
      // NOTE A3
      iNoteA = NOTE_A3;
      iNoteAS = NOTE_AS3;
      iNoteB = NOTE_B3;
      iNoteC = NOTE_C4;
      iNoteD = NOTE_D4;
      iNoteDS = NOTE_DS4;
      iNoteE = NOTE_E4;
      iNoteF = NOTE_F4;
      iNoteFS = NOTE_FS4;
      iNoteG = NOTE_G4;
      iNoteGS = NOTE_GS4;
      break;
    case 4:
      // NOTE A4
      iNoteA = NOTE_A4;
      iNoteAS = NOTE_AS4;
      iNoteB = NOTE_B4;
      iNoteC = NOTE_C5;
      iNoteCS = NOTE_CS5;
      iNoteD = NOTE_D5;
      iNoteE = NOTE_E5;
      iNoteF = NOTE_F5;
      iNoteFS = NOTE_FS5;
      iNoteG = NOTE_G5;
      iNoteGS = NOTE_GS5;
      break;
    case 5:
      // NOTE A5
      iNoteA = NOTE_A5;
      iNoteAS = NOTE_AS5;
      iNoteB = NOTE_B5;
      iNoteC = NOTE_C6;
      iNoteCS = NOTE_CS6;
      iNoteD = NOTE_D6;
      iNoteDS = NOTE_DS6;
      iNoteE = NOTE_E6;
      iNoteF = NOTE_F6;
      iNoteFS = NOTE_FS6;
      iNoteG = NOTE_G6;
      iNoteGS = NOTE_GS6;
      break;
    case 6:
      // NOTE A6
      iNoteA = NOTE_A6;
      iNoteAS = NOTE_AS6;
      iNoteB = NOTE_B6;
      iNoteC = NOTE_C7;
      iNoteCS = NOTE_CS7;
      iNoteD = NOTE_D7;
      iNoteDS = NOTE_DS7;
      iNoteE = NOTE_E7;
      iNoteF = NOTE_F7;
      iNoteFS = NOTE_FS7;
      iNoteG = NOTE_G7;
      iNoteGS = NOTE_GS7;
      break;
  }
  
}

pitches.h

/*****************************************************************
 * Pitches NOTE_B0 <=> NOTE_DS8 - NOTE_A4 is "A" measured at 440Hz
 *****************************************************************/

#define NOTE_B0  31
#define NOTE_C1  33
#define NOTE_CS1  35
#define NOTE_D1  37
#define NOTE_DS1  39
#define NOTE_E1  41
#define NOTE_F1  44
#define NOTE_FS1  46
#define NOTE_G1  49
#define NOTE_GS1  52
#define NOTE_A1  55
#define NOTE_AS1  58
#define NOTE_B1  62
#define NOTE_C2  65
#define NOTE_CS2  69
#define NOTE_D2  73
#define NOTE_DS2  78
#define NOTE_E2  82
#define NOTE_F2  87
#define NOTE_FS2  93
#define NOTE_G2  98
#define NOTE_GS2  104
#define NOTE_A2  110
#define NOTE_AS2  117
#define NOTE_B2  123
#define NOTE_C3  131
#define NOTE_CS3  139
#define NOTE_D3  147
#define NOTE_DS3  156
#define NOTE_E3  165
#define NOTE_F3  175
#define NOTE_FS3 185
#define NOTE_G3  196
#define NOTE_GS3  208
#define NOTE_A3  220
#define NOTE_AS3  233
#define NOTE_B3  247
#define NOTE_C4  262
#define NOTE_CS4  277
#define NOTE_D4  294
#define NOTE_DS4 311
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_FS4  370
#define NOTE_G4  392
#define NOTE_GS4  415
#define NOTE_A4  440
#define NOTE_AS4  466
#define NOTE_B4  494
#define NOTE_C5  523
#define NOTE_CS5  554
#define NOTE_D5  587
#define NOTE_DS5  622
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_FS5  740
#define NOTE_G5  784
#define NOTE_GS5  831
#define NOTE_A5  880
#define NOTE_AS5  932
#define NOTE_B5  988
#define NOTE_C6  1047
#define NOTE_CS6  1109
#define NOTE_D6  1175
#define NOTE_DS6  1245
#define NOTE_E6  1319
#define NOTE_F6  1397
#define NOTE_FS6  1480
#define NOTE_G6  1568
#define NOTE_GS6  1661
#define NOTE_A6  1760
#define NOTE_AS6  1865
#define NOTE_B6  1976
#define NOTE_C7  2093
#define NOTE_CS7  2217
#define NOTE_D7  2349
#define NOTE_DS7  2489
#define NOTE_E7  2637
#define NOTE_F7  2794
#define NOTE_FS7  2960
#define NOTE_G7  3136
#define NOTE_GS7  3322
#define NOTE_A7  3520
#define NOTE_AS7  3729
#define NOTE_B7  3951
#define NOTE_C8  4186
#define NOTE_CS8  4435
#define NOTE_D8  4699
#define NOTE_DS8  4978

setup.ino

// Setup
void setup() {

  // Setup Keyboard
  setupKeyboard();

  // Mozzi Start
  startMozzi( CONTROL_RATE );
  // Sets Attack and Decay Levels; assumes Sustain, Decay, and Idle times
  envelope1.setADLevels(200,200);
  // Sets Decay time in milliseconds
  envelope1.setDecayTime(200);
  // Sustain Time setting for envelope1
  envelope1.setSustainTime(52500);

}

——

People can contact us: https://www.donluc.com/?page_id=1927

Technology Experience

  • Single-Board Microcontrollers (PIC, Arduino, Raspberry Pi,Espressif, etc…)
  • IoT
  • Robotics
  • Camera and Video Capture Receiver Stationary, Wheel/Tank and Underwater Vehicle
  • Unmanned Vehicles Terrestrial and Marine
  • Research & Development (R & D)

Instructor and E-Mentor

  • IoT
  • PIC Microcontrollers
  • Arduino
  • Raspberry Pi
  • Espressif
  • Robotics

Follow Us

J. Luc Paquin – Curriculum Vitae – 2022 English & Español
https://www.jlpconsultants.com/luc/

Web: https://www.donluc.com/
Web: https://www.jlpconsultants.com/
Facebook: https://www.facebook.com/neosteam.labs.9/
YouTube: https://www.youtube.com/channel/UC5eRjrGn1CqkkGfZy0jxEdA
Twitter: https://twitter.com/labs_steam
Pinterest: https://www.pinterest.com/NeoSteamLabs/
Instagram: https://www.instagram.com/neosteamlabs/

Don Luc

Project #22: Synthesizer – Attack Time Level – Mk12

——

#DonLucElectronics #DonLuc #Synthesizer #Mozzi #Keyboard #ADSREnvelope #Arduino #SparkFunRedBoard #Project #Fritzing #Programming #Electronics #Microcontrollers #Consultant

——

Attack Time Level

——

Attack Time Level

——

Attack Time Level

——

Attack Time Level

When creating artificial waveforms in a synthesizer, changes in the signal amplitude over time are controlled by an envelope generator which typically has controls to adjust the Attack, Decay, Sustain and Release times, triggered by the pressing and subsequent release of a key on the keyboard. The Attack Time Level determines the time taken for the signal to grow to its maximum amplitude, initiated by the pressing of a key. By lengthening the attack and release times, you can create rich, lush tones. By shortening the time of the attack and release phases, you can create percussive, staccato sounds.

DL2208Mk05

1 x SparkFun RedBoard
7 x Momentary Button – Panel Mount (Blue)
5 x Momentary Button – Panel Mount (Black)
12 x 10K Ohm Resistor
5 x 10k Ohm Slide Linear Taper Pot – X-Large
5 x Slide Potentiometer Knob – X-Large
1 x Perfboard 13.5 cm x 11 cm
1 x SparkFun Solderable Breadboard
1 x Audio Jack 3.5mm
1 x SparkFun Audio Jack Breakout
1 x SparkFun ProtoShield
1 x Insignia Speakers
1 x SparkFun Cerberus USB Cable

SparkFun RedBoard

LP0 – Analog A0 – Blue
LP1 – Analog A1 – Green
LP2 – Analog A2 – Grey
LP3 – Analog A3 – Yellow
LP4 – Analog A4 – Purple
KY1 – 1
KY2 – 2
KY3 – 3
KY4 – 4
KY5 – 5
KY6 – 6
KY7 – 7
KY8 – 8
SPK – 9
KY10 – 10
KY11 – 11
KY12 – 12
KY13 – 13
VIN – +5V
GND – GND

——

DL2208Mk05p.ino

/* ***** Don Luc Electronics © *****
Software Version Information
Project #22: Synthesizer - Attack Time Level - Mk12
22-12
DL2208Mk05p.ino
1 x SparkFun RedBoard
7 x Momentary Button - Panel Mount (Blue)
5 x Momentary Button - Panel Mount (Black)
12 x 1K Ohm Resistor
5 x 10k Ohm Slide Linear Taper Pot - X-Large
5 x Slide Potentiometer Knob - X-Large
1 x Perfboard 13.5 cm x 11 cm
1 x SparkFun Solderable Breadboard
1 x Audio Jack 3.5mm
1 x SparkFun Audio Jack Breakout
1 x SparkFun ProtoShield
1 x Insignia Speakers
1 x SparkFun Cerberus USB Cable
*/

// Include the Library Code
// Pitches
#include "pitches.h"
// Mozzi
#include <MozziGuts.h>
// Oscillator
#include <Oscil.h>
// Sine Wave Table For Oscillator
#include <tables/sin2048_int8.h>
// ADSR envelope generator
#include <ADSR.h>

// Simple Keyboard
// Minimum reading of the button that generates a note
const int iKeyboard1 = 1;
const int iKeyboard2 = 2;
const int iKeyboard3 = 3;
const int iKeyboard4 = 4;
const int iKeyboard5 = 5;
const int iKeyboard6 = 6;
const int iKeyboard7 = 7;
const int iKeyboard8 = 8;
const int iKeyboard10 = 10;
const int iKeyboard11 = 11;
const int iKeyboard12 = 12;
const int iKeyboard13 = 13;
// Button is pressed
int iB1 = 1;
int iB2 = 1;
int iB3 = 1;
int iB4 = 1;
int iB5 = 1;
int iB6 = 1;
int iB7 = 1;
int iB8 = 1;
int iB10 = 1;
int iB11 = 1;
int iB12 = 1;
int iB13 = 1;

// Set the input for the potentiometer for Frequency to analog pin 2
const int potFreq = A2;
int iFreg = 1;
int iNoteA = 0;
int iNoteAS = 0;
int iNoteB = 0;
int iNoteC = 0;
int iNoteCS = 0;
int iNoteD = 0;
int iNoteDS = 0;
int iNoteE = 0;
int iNoteF = 0;
int iNoteFS = 0;
int iNoteG = 0;
int iNoteGS = 0;

// Potentiometer
int iPot4 = A4;

//Oscillator Functions declared for output envelope 1 
// Sine Wave
Oscil <2048, AUDIO_RATE> aSin1(SIN2048_DATA);

// ADSR declaration/definition
// Comment out to use control rate of 128
#define CONTROL_RATE 128
ADSR <CONTROL_RATE, CONTROL_RATE> envelope1;

// Set the input for the potentiometer Attack to analog pin 1
const int potAttack = A0;
// Attack
int attack_level = 0;
int iAttack = 0;

// Set the input for the potentiometer for Decay to analog pin 2
const int potDecay = A1;
// Decay
int decay_level = 0;
int iDecay = 0;

// Set the input for the potentiometer Attack Time to analog pin 3
const int potAttackTime = A3;
// Attack Time
int AttackTime_level = 0;
int iAttackTime = 0;

// Software Version Information
String sver = "22-12";

void loop() {

  // Audio Hook
  audioHook();
  
}

getKeyboard.ino

// getKeyboard
// setupKeyboard
void setupKeyboard() {

  // Initialize the button pin as an input
  pinMode(iKeyboard1, INPUT_PULLUP);
  pinMode(iKeyboard2, INPUT_PULLUP);
  pinMode(iKeyboard3, INPUT_PULLUP);
  pinMode(iKeyboard4, INPUT_PULLUP);
  pinMode(iKeyboard5, INPUT_PULLUP);
  pinMode(iKeyboard6, INPUT_PULLUP);
  pinMode(iKeyboard7, INPUT_PULLUP);
  pinMode(iKeyboard8, INPUT_PULLUP);
  pinMode(iKeyboard10, INPUT_PULLUP);
  pinMode(iKeyboard11, INPUT_PULLUP);
  pinMode(iKeyboard12, INPUT_PULLUP);
  pinMode(iKeyboard13, INPUT_PULLUP);
 
}
// isKeyboard
void isKeyboard() {

  // Choose envelope levels
  // attack_level
  iAttack = mozziAnalogRead( potAttack );
  attack_level = map( iAttack, 0, 1023, 100, 400);
  // Attack Level
  envelope1.setAttackLevel( attack_level );
  // decay_level
  iDecay = mozziAnalogRead( potDecay );
  decay_level = map( iDecay, 0, 1023, 50, 255);
  // Decay Level
  envelope1.setDecayLevel( decay_level );
  // AttackTime_level
  iAttackTime = mozziAnalogRead( potAttackTime );
  AttackTime_level = map( iAttackTime, 0, 1023, 0, 900);
  // Attack Time Level
  envelope1.setAttackTime( AttackTime_level );

  // Read the state of the button value 1
  if ( digitalRead(iKeyboard1) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 1
    iB1 = iB1 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteA);

  }
  else
  {
    
    iB1 = iB1 - 1;

  }

  // Read the state of the button value 2
  if ( digitalRead(iKeyboard2) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 2
    iB2 = iB2 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteAS);

  }
  else
  {
    
    iB2 = iB2 - 1;
 
  }

  // Read the state of the button value 3
  if ( digitalRead(iKeyboard3) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 3
    iB3 = iB3 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteB);

  }
  else
  {
    
    iB3 = iB3 - 1;
 
  }

  // Read the state of the button value 4
  if ( digitalRead(iKeyboard4) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 4
    iB4 = iB4 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteC);

  }
  else
  {
    
    iB4 = iB4 - 1;
 
  }

  // Read the state of the button value 5
  if ( digitalRead(iKeyboard5) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 5
    iB5 = iB5 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteCS);

  }
  else
  {
    
    iB5 = iB5 - 1;
 
  }

  // Read the state of the button value 6
  if ( digitalRead(iKeyboard6) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 6
    iB6 = iB6 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteD);

  }
  else
  {
    
    iB6 = iB6 - 1;

  }

  // Read the state of the button value 7
  if ( digitalRead(iKeyboard7) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 7
    iB7 = iB7 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteDS);

  }
  else
  {
    
    iB7 = iB7 - 1;
 
  }

  // Read the state of the button value 8
  if ( digitalRead(iKeyboard8) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 8
    iB8 = iB8 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteE);

  }
  else
  {
    
    iB8 = iB8 - 1;

  }

  // Read the state of the button value 10
  if ( digitalRead(iKeyboard10) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 10
    iB10 = iB10 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteF);

  }
  else
  {
    
    iB10 = iB10 - 1;

  }

  // Read the state of the button value 11
  if ( digitalRead(iKeyboard11) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 11
    iB11 = iB11 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteFS);

  }
  else
  {
    
    iB11 = iB11 - 1;
 
  }

  // Read the state of the button value 12
  if ( digitalRead(iKeyboard12) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 12
    iB12 = iB12 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteG);

  }
  else
  {
    
    iB12 = iB12 - 1;
    
  }

  // Read the state of the button value 13
  if ( digitalRead(iKeyboard13) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 13
    iB13 = iB13 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteGS);

  }
  else
  {
    
    iB13 = iB13 - 1;

  }

}

getMozzi.ino

// Mozzi
// Update Control
void updateControl(){

  // Frequency
  isPitches();
  
  // Keyboard
  isKeyboard();

}
// Update Audio
int updateAudio()
{

  // Update Audio
  // ADSR declaration/definition
  envelope1.update();
  // >>8 for AUDIO_MODE STANDARD
  return (int) (envelope1.next() * aSin1.next())>>8;

}

getPitches.ino

// Pitches
// isPitches
void isPitches(){
  
  // Frequency
  // Value is 0-1023
  iFreg = mozziAnalogRead(potFreq);
  iFreg = map(iFreg, 0, 1023, 2, 6);

  // Range Frequency Note Low => High
  switch ( iFreg ) {
    case 1:
      // NOTE A1
      iNoteA = NOTE_A1;
      iNoteAS = NOTE_AS1;
      iNoteB = NOTE_B1;
      iNoteC = NOTE_C2;
      iNoteCS = NOTE_CS2;
      iNoteD = NOTE_D2;
      iNoteDS = NOTE_DS2;
      iNoteE = NOTE_E2;
      iNoteF = NOTE_F2;
      iNoteFS = NOTE_FS2;
      iNoteG = NOTE_G2;
      iNoteGS = NOTE_GS2;
      break;
    case 2:
      // NOTE A2
      iNoteA = NOTE_A2;
      iNoteAS = NOTE_AS2;
      iNoteB = NOTE_B2;
      iNoteC = NOTE_C3;
      iNoteCS = NOTE_CS3;
      iNoteD = NOTE_D3;
      iNoteDS = NOTE_DS3;
      iNoteE = NOTE_E3;
      iNoteF = NOTE_F3;
      iNoteFS = NOTE_FS3;
      iNoteG = NOTE_G3;
      iNoteGS = NOTE_GS3;
      break;
    case 3:
      // NOTE A3
      iNoteA = NOTE_A3;
      iNoteAS = NOTE_AS3;
      iNoteB = NOTE_B3;
      iNoteC = NOTE_C4;
      iNoteD = NOTE_D4;
      iNoteDS = NOTE_DS4;
      iNoteE = NOTE_E4;
      iNoteF = NOTE_F4;
      iNoteFS = NOTE_FS4;
      iNoteG = NOTE_G4;
      iNoteGS = NOTE_GS4;
      break;
    case 4:
      // NOTE A4
      iNoteA = NOTE_A4;
      iNoteAS = NOTE_AS4;
      iNoteB = NOTE_B4;
      iNoteC = NOTE_C5;
      iNoteCS = NOTE_CS5;
      iNoteD = NOTE_D5;
      iNoteE = NOTE_E5;
      iNoteF = NOTE_F5;
      iNoteFS = NOTE_FS5;
      iNoteG = NOTE_G5;
      iNoteGS = NOTE_GS5;
      break;
    case 5:
      // NOTE A5
      iNoteA = NOTE_A5;
      iNoteAS = NOTE_AS5;
      iNoteB = NOTE_B5;
      iNoteC = NOTE_C6;
      iNoteCS = NOTE_CS6;
      iNoteD = NOTE_D6;
      iNoteDS = NOTE_DS6;
      iNoteE = NOTE_E6;
      iNoteF = NOTE_F6;
      iNoteFS = NOTE_FS6;
      iNoteG = NOTE_G6;
      iNoteGS = NOTE_GS6;
      break;
    case 6:
      // NOTE A6
      iNoteA = NOTE_A6;
      iNoteAS = NOTE_AS6;
      iNoteB = NOTE_B6;
      iNoteC = NOTE_C7;
      iNoteCS = NOTE_CS7;
      iNoteD = NOTE_D7;
      iNoteDS = NOTE_DS7;
      iNoteE = NOTE_E7;
      iNoteF = NOTE_F7;
      iNoteFS = NOTE_FS7;
      iNoteG = NOTE_G7;
      iNoteGS = NOTE_GS7;
      break;
  }
  
}

pitches.h

/*****************************************************************
 * Pitches NOTE_B0 <=> NOTE_DS8 - NOTE_A4 is "A" measured at 440Hz
 *****************************************************************/

#define NOTE_B0  31
#define NOTE_C1  33
#define NOTE_CS1  35
#define NOTE_D1  37
#define NOTE_DS1  39
#define NOTE_E1  41
#define NOTE_F1  44
#define NOTE_FS1  46
#define NOTE_G1  49
#define NOTE_GS1  52
#define NOTE_A1  55
#define NOTE_AS1  58
#define NOTE_B1  62
#define NOTE_C2  65
#define NOTE_CS2  69
#define NOTE_D2  73
#define NOTE_DS2  78
#define NOTE_E2  82
#define NOTE_F2  87
#define NOTE_FS2  93
#define NOTE_G2  98
#define NOTE_GS2  104
#define NOTE_A2  110
#define NOTE_AS2  117
#define NOTE_B2  123
#define NOTE_C3  131
#define NOTE_CS3  139
#define NOTE_D3  147
#define NOTE_DS3  156
#define NOTE_E3  165
#define NOTE_F3  175
#define NOTE_FS3 185
#define NOTE_G3  196
#define NOTE_GS3  208
#define NOTE_A3  220
#define NOTE_AS3  233
#define NOTE_B3  247
#define NOTE_C4  262
#define NOTE_CS4  277
#define NOTE_D4  294
#define NOTE_DS4 311
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_FS4  370
#define NOTE_G4  392
#define NOTE_GS4  415
#define NOTE_A4  440
#define NOTE_AS4  466
#define NOTE_B4  494
#define NOTE_C5  523
#define NOTE_CS5  554
#define NOTE_D5  587
#define NOTE_DS5  622
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_FS5  740
#define NOTE_G5  784
#define NOTE_GS5  831
#define NOTE_A5  880
#define NOTE_AS5  932
#define NOTE_B5  988
#define NOTE_C6  1047
#define NOTE_CS6  1109
#define NOTE_D6  1175
#define NOTE_DS6  1245
#define NOTE_E6  1319
#define NOTE_F6  1397
#define NOTE_FS6  1480
#define NOTE_G6  1568
#define NOTE_GS6  1661
#define NOTE_A6  1760
#define NOTE_AS6  1865
#define NOTE_B6  1976
#define NOTE_C7  2093
#define NOTE_CS7  2217
#define NOTE_D7  2349
#define NOTE_DS7  2489
#define NOTE_E7  2637
#define NOTE_F7  2794
#define NOTE_FS7  2960
#define NOTE_G7  3136
#define NOTE_GS7  3322
#define NOTE_A7  3520
#define NOTE_AS7  3729
#define NOTE_B7  3951
#define NOTE_C8  4186
#define NOTE_CS8  4435
#define NOTE_D8  4699
#define NOTE_DS8  4978

setup.ino

// Setup
void setup() {

  // Setup Keyboard
  setupKeyboard();

  // Mozzi Start
  startMozzi( CONTROL_RATE );
  // Sets Attack and Decay Levels; assumes Sustain, Decay, and Idle times
  envelope1.setADLevels(200,200);
  // Sets Decay time in milliseconds
  envelope1.setDecayTime(200);
  // Sustain Time setting for envelope1
  envelope1.setSustainTime(52500);

}

——

People can contact us: https://www.donluc.com/?page_id=1927

Technology Experience

  • Single-Board Microcontrollers (PIC, Arduino, Raspberry Pi,Espressif, etc…)
  • IoT
  • Robotics
  • Camera and Video Capture Receiver Stationary, Wheel/Tank and Underwater Vehicle
  • Unmanned Vehicles Terrestrial and Marine
  • Research & Development (R & D)

Instructor and E-Mentor

  • IoT
  • PIC Microcontrollers
  • Arduino
  • Raspberry Pi
  • Espressif
  • Robotics

Follow Us

J. Luc Paquin – Curriculum Vitae – 2022 English & Español
https://www.jlpconsultants.com/luc/

Web: https://www.donluc.com/
Web: https://www.jlpconsultants.com/
Facebook: https://www.facebook.com/neosteam.labs.9/
YouTube: https://www.youtube.com/channel/UC5eRjrGn1CqkkGfZy0jxEdA
Twitter: https://twitter.com/labs_steam
Pinterest: https://www.pinterest.com/NeoSteamLabs/
Instagram: https://www.instagram.com/neosteamlabs/

Don Luc

Project #22: Synthesizer – 4 Stages – Mk11

——

#DonLucElectronics #DonLuc #Synthesizer #Mozzi #Keyboard #ADSREnvelope #Arduino #SparkFunRedBoard #Project #Fritzing #Programming #Electronics #Microcontrollers #Consultant

——

4 Stages

——

4 Stages

——

4 Stages

——

4 Stages of an ADSR Envelope

An ADSR envelope features these four stages.

  • 1 Attack: The attack phase begins the moment a key is pressed. This phase determines how quickly a sound reaches full volume before entering the decay phase. On an analog synthesizer, this phase is typically instantaneous. Some modern synthesizers allow for the attack time to be delayed.
  • 2 Decay: The decay phase determines the length of the drop from the peak level to the sustain level of a sound. The decay time can often be altered to change the overall sound. For instance, a short attack and a long decay will produce a sound that reaches maximum amplitude quickly and falls slowly to the sustain level.
  • 3 Sustain: The sustain phase does not specify a length of time. Instead, it determines the volume of a sound for the entire hold time between the decay and release phases.
  • 4 Release: The final phase determines the speed at which a sound ends from the moment you release the key. Depending on the desired sound, the release time can be short or long.

DL2208Mk04

1 x SparkFun RedBoard
7 x Momentary Button – Panel Mount (Blue)
5 x Momentary Button – Panel Mount (Black)
12 x 10K Ohm Resistor
5 x 10k Ohm Slide Linear Taper Pot – X-Large
5 x Slide Potentiometer Knob – X-Large
1 x Perfboard 13.5 cm x 11 cm
1 x SparkFun Solderable Breadboard
1 x Audio Jack 3.5mm
1 x SparkFun Audio Jack Breakout
1 x SparkFun ProtoShield
1 x Insignia Speakers
1 x SparkFun Cerberus USB Cable

SparkFun RedBoard

LP0 – Analog A0 – Blue
LP1 – Analog A1 – Green
LP2 – Analog A2 – Grey
LP3 – Analog A3 – Yellow
LP4 – Analog A4 – Purple
KY1 – 1
KY2 – 2
KY3 – 3
KY4 – 4
KY5 – 5
KY6 – 6
KY7 – 7
KY8 – 8
SPK – 9
KY10 – 10
KY11 – 11
KY12 – 12
KY13 – 13
VIN – +5V
GND – GND

DL2208Mk04p.ino

/* ***** Don Luc Electronics © *****
Software Version Information
Project #22: Synthesizer - 4 Stages - Mk11
22-11
DL2208Mk04p.ino
1 x SparkFun RedBoard
7 x Momentary Button - Panel Mount (Blue)
5 x Momentary Button - Panel Mount (Black)
12 x 1K Ohm Resistor
5 x 10k Ohm Slide Linear Taper Pot - X-Large
5 x Slide Potentiometer Knob - X-Large
1 x Perfboard 13.5 cm x 11 cm
1 x SparkFun Solderable Breadboard
1 x Audio Jack 3.5mm
1 x SparkFun Audio Jack Breakout
1 x SparkFun ProtoShield
1 x Insignia Speakers
1 x SparkFun Cerberus USB Cable
*/

// Include the Library Code
// Pitches
#include "pitches.h"
// Mozzi
#include <MozziGuts.h>
// Oscillator
#include <Oscil.h>
// Sine Wave Table For Oscillator
#include <tables/sin2048_int8.h>
// ADSR envelope generator
#include <ADSR.h>

// Simple Keyboard
// Minimum reading of the button that generates a note
const int iKeyboard1 = 1;
const int iKeyboard2 = 2;
const int iKeyboard3 = 3;
const int iKeyboard4 = 4;
const int iKeyboard5 = 5;
const int iKeyboard6 = 6;
const int iKeyboard7 = 7;
const int iKeyboard8 = 8;
const int iKeyboard10 = 10;
const int iKeyboard11 = 11;
const int iKeyboard12 = 12;
const int iKeyboard13 = 13;
// Button is pressed
int iB1 = 1;
int iB2 = 1;
int iB3 = 1;
int iB4 = 1;
int iB5 = 1;
int iB6 = 1;
int iB7 = 1;
int iB8 = 1;
int iB10 = 1;
int iB11 = 1;
int iB12 = 1;
int iB13 = 1;

// Set the input for the potentiometer for Frequency to analog pin 2
const int potFreq = A2;
int iFreg = 1;
int iNoteA = 0;
int iNoteAS = 0;
int iNoteB = 0;
int iNoteC = 0;
int iNoteCS = 0;
int iNoteD = 0;
int iNoteDS = 0;
int iNoteE = 0;
int iNoteF = 0;
int iNoteFS = 0;
int iNoteG = 0;
int iNoteGS = 0;

// Potentiometer
int iPot3 = A3;
int iPot4 = A4;

//Oscillator Functions declared for output envelope 1 
// Sine Wave
Oscil <2048, AUDIO_RATE> aSin1(SIN2048_DATA);

// ADSR declaration/definition
// Comment out to use control rate of 128
#define CONTROL_RATE 128
ADSR <CONTROL_RATE, CONTROL_RATE> envelope1;

// Set the input for the potentiometer Attack to analog pin 1
const int potAttack = A0;
// Attack
int attack_level = 0;
int iAttack = 0;

// Set the input for the potentiometer for Decay to analog pin 2
const int potDecay = A1;
// Decay
int decay_level = 0;
int iDecay = 0;

// Software Version Information
String sver = "22-11";

void loop() {

  // Audio Hook
  audioHook();
  
}

getKeyboard.ino

// getKeyboard
// setupKeyboard
void setupKeyboard() {

  // Initialize the button pin as an input
  pinMode(iKeyboard1, INPUT_PULLUP);
  pinMode(iKeyboard2, INPUT_PULLUP);
  pinMode(iKeyboard3, INPUT_PULLUP);
  pinMode(iKeyboard4, INPUT_PULLUP);
  pinMode(iKeyboard5, INPUT_PULLUP);
  pinMode(iKeyboard6, INPUT_PULLUP);
  pinMode(iKeyboard7, INPUT_PULLUP);
  pinMode(iKeyboard8, INPUT_PULLUP);
  pinMode(iKeyboard10, INPUT_PULLUP);
  pinMode(iKeyboard11, INPUT_PULLUP);
  pinMode(iKeyboard12, INPUT_PULLUP);
  pinMode(iKeyboard13, INPUT_PULLUP);
 
}
// isKeyboard
void isKeyboard() {

  // Choose envelope levels
  // attack_level
  iAttack = mozziAnalogRead( potAttack );
  attack_level = map( iAttack, 0, 1023, 100, 400);
  // Attack Level
  envelope1.setAttackLevel( attack_level );
  // decay_level
  iDecay = mozziAnalogRead( potDecay );
  decay_level = map( iDecay, 0, 1023, 50, 255);
  // Decay Level
  envelope1.setDecayLevel( decay_level );

  // Read the state of the button value 1
  if ( digitalRead(iKeyboard1) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 1
    iB1 = iB1 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteA);

  }
  else
  {
    
    iB1 = iB1 - 1;

  }

  // Read the state of the button value 2
  if ( digitalRead(iKeyboard2) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 2
    iB2 = iB2 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteAS);

  }
  else
  {
    
    iB2 = iB2 - 1;
 
  }

  // Read the state of the button value 3
  if ( digitalRead(iKeyboard3) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 3
    iB3 = iB3 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteB);

  }
  else
  {
    
    iB3 = iB3 - 1;
 
  }

  // Read the state of the button value 4
  if ( digitalRead(iKeyboard4) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 4
    iB4 = iB4 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteC);

  }
  else
  {
    
    iB4 = iB4 - 1;
 
  }

  // Read the state of the button value 5
  if ( digitalRead(iKeyboard5) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 5
    iB5 = iB5 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteCS);

  }
  else
  {
    
    iB5 = iB5 - 1;
 
  }

  // Read the state of the button value 6
  if ( digitalRead(iKeyboard6) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 6
    iB6 = iB6 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteD);

  }
  else
  {
    
    iB6 = iB6 - 1;

  }

  // Read the state of the button value 7
  if ( digitalRead(iKeyboard7) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 7
    iB7 = iB7 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteDS);

  }
  else
  {
    
    iB7 = iB7 - 1;
 
  }

  // Read the state of the button value 8
  if ( digitalRead(iKeyboard8) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 8
    iB8 = iB8 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteE);

  }
  else
  {
    
    iB8 = iB8 - 1;

  }

  // Read the state of the button value 10
  if ( digitalRead(iKeyboard10) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 10
    iB10 = iB10 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteF);

  }
  else
  {
    
    iB10 = iB10 - 1;

  }

  // Read the state of the button value 11
  if ( digitalRead(iKeyboard11) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 11
    iB11 = iB11 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteFS);

  }
  else
  {
    
    iB11 = iB11 - 1;
 
  }

  // Read the state of the button value 12
  if ( digitalRead(iKeyboard12) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 12
    iB12 = iB12 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteG);

  }
  else
  {
    
    iB12 = iB12 - 1;
    
  }

  // Read the state of the button value 13
  if ( digitalRead(iKeyboard13) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 13
    iB13 = iB13 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteGS);

  }
  else
  {
    
    iB13 = iB13 - 1;

  }

}

getMozzi.ino

// Mozzi
// Update Control
void updateControl(){

  // Frequency
  isPitches();
  
  // Keyboard
  isKeyboard();

}
// Update Audio
int updateAudio()
{

  // Update Audio
  // ADSR declaration/definition
  envelope1.update();
  // >>8 for AUDIO_MODE STANDARD
  return (int) (envelope1.next() * aSin1.next())>>8;

}

getPitches.ino

// Pitches
// isPitches
void isPitches(){
  
  // Frequency
  // Value is 0-1023
  iFreg = mozziAnalogRead(potFreq);
  iFreg = map(iFreg, 0, 1023, 2, 6);

  // Range Frequency Note Low => High
  switch ( iFreg ) {
    case 1:
      // NOTE A1
      iNoteA = NOTE_A1;
      iNoteAS = NOTE_AS1;
      iNoteB = NOTE_B1;
      iNoteC = NOTE_C2;
      iNoteCS = NOTE_CS2;
      iNoteD = NOTE_D2;
      iNoteDS = NOTE_DS2;
      iNoteE = NOTE_E2;
      iNoteF = NOTE_F2;
      iNoteFS = NOTE_FS2;
      iNoteG = NOTE_G2;
      iNoteGS = NOTE_GS2;
      break;
    case 2:
      // NOTE A2
      iNoteA = NOTE_A2;
      iNoteAS = NOTE_AS2;
      iNoteB = NOTE_B2;
      iNoteC = NOTE_C3;
      iNoteCS = NOTE_CS3;
      iNoteD = NOTE_D3;
      iNoteDS = NOTE_DS3;
      iNoteE = NOTE_E3;
      iNoteF = NOTE_F3;
      iNoteFS = NOTE_FS3;
      iNoteG = NOTE_G3;
      iNoteGS = NOTE_GS3;
      break;
    case 3:
      // NOTE A3
      iNoteA = NOTE_A3;
      iNoteAS = NOTE_AS3;
      iNoteB = NOTE_B3;
      iNoteC = NOTE_C4;
      iNoteD = NOTE_D4;
      iNoteDS = NOTE_DS4;
      iNoteE = NOTE_E4;
      iNoteF = NOTE_F4;
      iNoteFS = NOTE_FS4;
      iNoteG = NOTE_G4;
      iNoteGS = NOTE_GS4;
      break;
    case 4:
      // NOTE A4
      iNoteA = NOTE_A4;
      iNoteAS = NOTE_AS4;
      iNoteB = NOTE_B4;
      iNoteC = NOTE_C5;
      iNoteCS = NOTE_CS5;
      iNoteD = NOTE_D5;
      iNoteE = NOTE_E5;
      iNoteF = NOTE_F5;
      iNoteFS = NOTE_FS5;
      iNoteG = NOTE_G5;
      iNoteGS = NOTE_GS5;
      break;
    case 5:
      // NOTE A5
      iNoteA = NOTE_A5;
      iNoteAS = NOTE_AS5;
      iNoteB = NOTE_B5;
      iNoteC = NOTE_C6;
      iNoteCS = NOTE_CS6;
      iNoteD = NOTE_D6;
      iNoteDS = NOTE_DS6;
      iNoteE = NOTE_E6;
      iNoteF = NOTE_F6;
      iNoteFS = NOTE_FS6;
      iNoteG = NOTE_G6;
      iNoteGS = NOTE_GS6;
      break;
    case 6:
      // NOTE A6
      iNoteA = NOTE_A6;
      iNoteAS = NOTE_AS6;
      iNoteB = NOTE_B6;
      iNoteC = NOTE_C7;
      iNoteCS = NOTE_CS7;
      iNoteD = NOTE_D7;
      iNoteDS = NOTE_DS7;
      iNoteE = NOTE_E7;
      iNoteF = NOTE_F7;
      iNoteFS = NOTE_FS7;
      iNoteG = NOTE_G7;
      iNoteGS = NOTE_GS7;
      break;
  }
  
}

pitches.h

/*****************************************************************
 * Pitches NOTE_B0 <=> NOTE_DS8 - NOTE_A4 is "A" measured at 440Hz
 *****************************************************************/

#define NOTE_B0  31
#define NOTE_C1  33
#define NOTE_CS1  35
#define NOTE_D1  37
#define NOTE_DS1  39
#define NOTE_E1  41
#define NOTE_F1  44
#define NOTE_FS1  46
#define NOTE_G1  49
#define NOTE_GS1  52
#define NOTE_A1  55
#define NOTE_AS1  58
#define NOTE_B1  62
#define NOTE_C2  65
#define NOTE_CS2  69
#define NOTE_D2  73
#define NOTE_DS2  78
#define NOTE_E2  82
#define NOTE_F2  87
#define NOTE_FS2  93
#define NOTE_G2  98
#define NOTE_GS2  104
#define NOTE_A2  110
#define NOTE_AS2  117
#define NOTE_B2  123
#define NOTE_C3  131
#define NOTE_CS3  139
#define NOTE_D3  147
#define NOTE_DS3  156
#define NOTE_E3  165
#define NOTE_F3  175
#define NOTE_FS3 185
#define NOTE_G3  196
#define NOTE_GS3  208
#define NOTE_A3  220
#define NOTE_AS3  233
#define NOTE_B3  247
#define NOTE_C4  262
#define NOTE_CS4  277
#define NOTE_D4  294
#define NOTE_DS4 311
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_FS4  370
#define NOTE_G4  392
#define NOTE_GS4  415
#define NOTE_A4  440
#define NOTE_AS4  466
#define NOTE_B4  494
#define NOTE_C5  523
#define NOTE_CS5  554
#define NOTE_D5  587
#define NOTE_DS5  622
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_FS5  740
#define NOTE_G5  784
#define NOTE_GS5  831
#define NOTE_A5  880
#define NOTE_AS5  932
#define NOTE_B5  988
#define NOTE_C6  1047
#define NOTE_CS6  1109
#define NOTE_D6  1175
#define NOTE_DS6  1245
#define NOTE_E6  1319
#define NOTE_F6  1397
#define NOTE_FS6  1480
#define NOTE_G6  1568
#define NOTE_GS6  1661
#define NOTE_A6  1760
#define NOTE_AS6  1865
#define NOTE_B6  1976
#define NOTE_C7  2093
#define NOTE_CS7  2217
#define NOTE_D7  2349
#define NOTE_DS7  2489
#define NOTE_E7  2637
#define NOTE_F7  2794
#define NOTE_FS7  2960
#define NOTE_G7  3136
#define NOTE_GS7  3322
#define NOTE_A7  3520
#define NOTE_AS7  3729
#define NOTE_B7  3951
#define NOTE_C8  4186
#define NOTE_CS8  4435
#define NOTE_D8  4699
#define NOTE_DS8  4978

setup.ino

// Setup
void setup() {

  // Setup Keyboard
  setupKeyboard();

  // Mozzi Start
  startMozzi( CONTROL_RATE );
  // Sets Attack and Decay Levels; assumes Sustain, Decay, and Idle times
  envelope1.setADLevels(200,200);
  // Sets Decay time in milliseconds
  envelope1.setDecayTime(200);
  // Sustain Time setting for envelope1
  envelope1.setSustainTime(52500);

}

——

People can contact us: https://www.donluc.com/?page_id=1927

Technology Experience

  • Single-Board Microcontrollers (PIC, Arduino, Raspberry Pi,Espressif, etc…)
  • IoT
  • Robotics
  • Camera and Video Capture Receiver Stationary, Wheel/Tank and Underwater Vehicle
  • Unmanned Vehicles Terrestrial and Marine
  • Research & Development (R & D)

Instructor and E-Mentor

  • IoT
  • PIC Microcontrollers
  • Arduino
  • Raspberry Pi
  • Espressif
  • Robotics

Follow Us

J. Luc Paquin – Curriculum Vitae – 2022 English & Español
https://www.jlpconsultants.com/luc/

Web: https://www.donluc.com/
Web: https://www.jlpconsultants.com/
Facebook: https://www.facebook.com/neosteam.labs.9/
YouTube: https://www.youtube.com/channel/UC5eRjrGn1CqkkGfZy0jxEdA
Twitter: https://twitter.com/labs_steam
Pinterest: https://www.pinterest.com/NeoSteamLabs/
Instagram: https://www.instagram.com/neosteamlabs/

Don Luc

Project #22: Synthesizer – ADSR Envelope – Mk10

——

#DonLucElectronics #DonLuc #Synthesizer #Mozzi #Keyboard #ADSREnvelope #Arduino #SparkFunRedBoard #Project #Fritzing #Programming #Electronics #Microcontrollers #Consultant

——

ADSR Envelope

——

ADSR Envelope

——

ADSR Envelope

——

What Is an Envelope in Music?

An envelope is a term used to describe the evolution of a sound in a piece of music. Envelopes are fed through an envelope generator, the component within an analog synthesizer that signals when and how a sound should change. The envelope defines the trajectory and modulation of a sound, while the envelope generator controls the behavior of the envelope.

What Is an ADSR Envelope?

An ADSR envelope is a type of envelope control mechanism commonly found in the synthesizer and samplers used in electronic music. ADSR stands for the envelope’s four stages of modulation: attack, decay, sustain, and release. These stages control the level of the sound from the moment you press a key or advance a music sequencer.

In sound design, ADSR envelopes are typically used to control the loudness of a sound. ADSR envelopes typically produce a sound that takes the shape of a waveform rising in the attack stage, slightly declining during the decay stage, plateauing during the sustain stage, and finally falling at the return stage.

DL2208Mk03

1 x SparkFun RedBoard
7 x Momentary Button – Panel Mount (Blue)
5 x Momentary Button – Panel Mount (Black)
12 x 10K Ohm Resistor
5 x 10k Ohm Slide Linear Taper Pot – X-Large
5 x Slide Potentiometer Knob – X-Large
1 x Perfboard 13.5 cm x 11 cm
1 x SparkFun Solderable Breadboard
1 x Audio Jack 3.5mm
1 x SparkFun Audio Jack Breakout
1 x SparkFun ProtoShield
1 x Insignia Speakers
1 x SparkFun Cerberus USB Cable

SparkFun RedBoard

LP0 – Analog A0 – Blue
LP1 – Analog A1 – Green
LP2 – Analog A2 – Grey
LP3 – Analog A3 – Yellow
LP4 – Analog A4 – Purple
KY1 – 1
KY2 – 2
KY3 – 3
KY4 – 4
KY5 – 5
KY6 – 6
KY7 – 7
KY8 – 8
SPK – 9
KY10 – 10
KY11 – 11
KY12 – 12
KY13 – 13
VIN – +5V
GND – GND

——

DL2208Mk03p.ino

/* ***** Don Luc Electronics © *****
Software Version Information
Project #22: Synthesizer - ADSR Envelope - Mk10
22-10
DL2208Mk03p.ino
1 x SparkFun RedBoard
7 x Momentary Button - Panel Mount (Blue)
5 x Momentary Button - Panel Mount (Black)
12 x 1K Ohm Resistor
5 x 10k Ohm Slide Linear Taper Pot - X-Large
5 x Slide Potentiometer Knob - X-Large
1 x Perfboard 13.5 cm x 11 cm
1 x SparkFun Solderable Breadboard
1 x Audio Jack 3.5mm
1 x SparkFun Audio Jack Breakout
1 x SparkFun ProtoShield
1 x Insignia Speakers
1 x SparkFun Cerberus USB Cable
*/

// Include the Library Code
// Pitches
#include "pitches.h"
// Mozzi
#include <MozziGuts.h>
// Oscillator
#include <Oscil.h>
// Sine Wave Table For Oscillator
#include <tables/sin2048_int8.h>
// ADSR envelope generator
#include <ADSR.h>

// Simple Keyboard
// Minimum reading of the button that generates a note
const int iKeyboard1 = 1;
const int iKeyboard2 = 2;
const int iKeyboard3 = 3;
const int iKeyboard4 = 4;
const int iKeyboard5 = 5;
const int iKeyboard6 = 6;
const int iKeyboard7 = 7;
const int iKeyboard8 = 8;
const int iKeyboard10 = 10;
const int iKeyboard11 = 11;
const int iKeyboard12 = 12;
const int iKeyboard13 = 13;
// Button is pressed
int iB1 = 1;
int iB2 = 1;
int iB3 = 1;
int iB4 = 1;
int iB5 = 1;
int iB6 = 1;
int iB7 = 1;
int iB8 = 1;
int iB10 = 1;
int iB11 = 1;
int iB12 = 1;
int iB13 = 1;

// Set the input for the potentiometer for Frequency to analog pin 3
//const int potFreq = A3;
int iFreg = 1;
int iNoteA = 0;
int iNoteAS = 0;
int iNoteB = 0;
int iNoteC = 0;
int iNoteCS = 0;
int iNoteD = 0;
int iNoteDS = 0;
int iNoteE = 0;
int iNoteF = 0;
int iNoteFS = 0;
int iNoteG = 0;
int iNoteGS = 0;

// Potentiometer
int iPot2 = A2;
int iPot3 = A3;
int iPot4 = A4;

//Oscillator Functions declared for output envelope 1 
// Sine Wave
Oscil <2048, AUDIO_RATE> aSin1(SIN2048_DATA);

// ADSR declaration/definition
// Comment out to use control rate of 128
#define CONTROL_RATE 128
ADSR <CONTROL_RATE, CONTROL_RATE> envelope1;

// Set the input for the potentiometer Attack to analog pin 1
const int potAttack = A0;
// Attack
int attack_level = 0;
int iAttack = 0;

// Set the input for the potentiometer for Decay to analog pin 2
const int potDecay = A1;
// Decay
int decay_level = 0;
int iDecay = 0;

// Software Version Information
String sver = "22-10";

void loop() {

  // Audio Hook
  audioHook();
  
}

getKeyboard.ino

// getKeyboard
// setupKeyboard
void setupKeyboard() {

  // Initialize the button pin as an input
  pinMode(iKeyboard1, INPUT_PULLUP);
  pinMode(iKeyboard2, INPUT_PULLUP);
  pinMode(iKeyboard3, INPUT_PULLUP);
  pinMode(iKeyboard4, INPUT_PULLUP);
  pinMode(iKeyboard5, INPUT_PULLUP);
  pinMode(iKeyboard6, INPUT_PULLUP);
  pinMode(iKeyboard7, INPUT_PULLUP);
  pinMode(iKeyboard8, INPUT_PULLUP);
  pinMode(iKeyboard10, INPUT_PULLUP);
  pinMode(iKeyboard11, INPUT_PULLUP);
  pinMode(iKeyboard12, INPUT_PULLUP);
  pinMode(iKeyboard13, INPUT_PULLUP);
 
}
// isKeyboard
void isKeyboard() {

  // Choose envelope levels
  // attack_level
  iAttack = mozziAnalogRead( potAttack );
  attack_level = map( iAttack, 0, 1023, 0, 255);
  // decay_level
  iDecay = mozziAnalogRead( potDecay );
  decay_level = map( iDecay, 0, 1023, 0, 255);
  // set AD Levels
  envelope1.setADLevels(attack_level,decay_level);

  // Read the state of the button value 1
  if ( digitalRead(iKeyboard1) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 1
    iB1 = iB1 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteA);

  }
  else
  {
    
    iB1 = iB1 - 1;

  }

  // Read the state of the button value 2
  if ( digitalRead(iKeyboard2) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 2
    iB2 = iB2 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteAS);

  }
  else
  {
    
    iB2 = iB2 - 1;
 
  }

  // Read the state of the button value 3
  if ( digitalRead(iKeyboard3) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 3
    iB3 = iB3 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteB);

  }
  else
  {
    
    iB3 = iB3 - 1;
 
  }

  // Read the state of the button value 4
  if ( digitalRead(iKeyboard4) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 4
    iB4 = iB4 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteC);

  }
  else
  {
    
    iB4 = iB4 - 1;
 
  }

  // Read the state of the button value 5
  if ( digitalRead(iKeyboard5) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 5
    iB5 = iB5 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteCS);

  }
  else
  {
    
    iB5 = iB5 - 1;
 
  }

  // Read the state of the button value 6
  if ( digitalRead(iKeyboard6) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 6
    iB6 = iB6 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteD);

  }
  else
  {
    
    iB6 = iB6 - 1;

  }

  // Read the state of the button value 7
  if ( digitalRead(iKeyboard7) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 7
    iB7 = iB7 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteDS);

  }
  else
  {
    
    iB7 = iB7 - 1;
 
  }

  // Read the state of the button value 8
  if ( digitalRead(iKeyboard8) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 8
    iB8 = iB8 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteE);

  }
  else
  {
    
    iB8 = iB8 - 1;

  }

  // Read the state of the button value 10
  if ( digitalRead(iKeyboard10) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 10
    iB10 = iB10 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteF);

  }
  else
  {
    
    iB10 = iB10 - 1;

  }

  // Read the state of the button value 11
  if ( digitalRead(iKeyboard11) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 11
    iB11 = iB11 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteFS);

  }
  else
  {
    
    iB11 = iB11 - 1;
 
  }

  // Read the state of the button value 12
  if ( digitalRead(iKeyboard12) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 12
    iB12 = iB12 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteG);

  }
  else
  {
    
    iB12 = iB12 - 1;
    
  }

  // Read the state of the button value 13
  if ( digitalRead(iKeyboard13) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 13
    iB13 = iB13 + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteGS);

  }
  else
  {
    
    iB13 = iB13 - 1;

  }

}

getMozzi.ino

// Mozzi
// Update Control
void updateControl(){

  // Frequency
  isPitches();
  
  // Keyboard
  isKeyboard();

}
// Update Audio
int updateAudio()
{

  // Update Audio
  // ADSR declaration/definition
  envelope1.update();
  // >>8 for AUDIO_MODE STANDARD
  return (int) (envelope1.next() * aSin1.next())>>8;

}

getPitches.ino

// Pitches
// isPitches
void isPitches(){
  
  // Frequency
  // Value is 0-1023
  //iFreg = mozziAnalogRead(potFreq);
  //iFreg = map(iFreg, 0, 1023, 3, 6);
  iFreg = 5;

  // Range Frequency Note Low => High
  switch ( iFreg ) {
    case 1:
      // NOTE A1
      iNoteA = NOTE_A1;
      iNoteAS = NOTE_AS1;
      iNoteB = NOTE_B1;
      iNoteC = NOTE_C2;
      iNoteCS = NOTE_CS2;
      iNoteD = NOTE_D2;
      iNoteDS = NOTE_DS2;
      iNoteE = NOTE_E2;
      iNoteF = NOTE_F2;
      iNoteFS = NOTE_FS2;
      iNoteG = NOTE_G2;
      iNoteGS = NOTE_GS2;
      break;
    case 2:
      // NOTE A2
      iNoteA = NOTE_A2;
      iNoteAS = NOTE_AS2;
      iNoteB = NOTE_B2;
      iNoteC = NOTE_C3;
      iNoteCS = NOTE_CS3;
      iNoteD = NOTE_D3;
      iNoteDS = NOTE_DS3;
      iNoteE = NOTE_E3;
      iNoteF = NOTE_F3;
      iNoteFS = NOTE_FS3;
      iNoteG = NOTE_G3;
      iNoteGS = NOTE_GS3;
      break;
    case 3:
      // NOTE A3
      iNoteA = NOTE_A3;
      iNoteAS = NOTE_AS3;
      iNoteB = NOTE_B3;
      iNoteC = NOTE_C4;
      iNoteD = NOTE_D4;
      iNoteDS = NOTE_DS4;
      iNoteE = NOTE_E4;
      iNoteF = NOTE_F4;
      iNoteFS = NOTE_FS4;
      iNoteG = NOTE_G4;
      iNoteGS = NOTE_GS4;
      break;
    case 4:
      // NOTE A4
      iNoteA = NOTE_A4;
      iNoteAS = NOTE_AS4;
      iNoteB = NOTE_B4;
      iNoteC = NOTE_C5;
      iNoteCS = NOTE_CS5;
      iNoteD = NOTE_D5;
      iNoteE = NOTE_E5;
      iNoteF = NOTE_F5;
      iNoteFS = NOTE_FS5;
      iNoteG = NOTE_G5;
      iNoteGS = NOTE_GS5;
      break;
    case 5:
      // NOTE A5
      iNoteA = NOTE_A5;
      iNoteAS = NOTE_AS5;
      iNoteB = NOTE_B5;
      iNoteC = NOTE_C6;
      iNoteCS = NOTE_CS6;
      iNoteD = NOTE_D6;
      iNoteDS = NOTE_DS6;
      iNoteE = NOTE_E6;
      iNoteF = NOTE_F6;
      iNoteFS = NOTE_FS6;
      iNoteG = NOTE_G6;
      iNoteGS = NOTE_GS6;
      break;
    case 6:
      // NOTE A6
      iNoteA = NOTE_A6;
      iNoteAS = NOTE_AS6;
      iNoteB = NOTE_B6;
      iNoteC = NOTE_C7;
      iNoteCS = NOTE_CS7;
      iNoteD = NOTE_D7;
      iNoteDS = NOTE_DS7;
      iNoteE = NOTE_E7;
      iNoteF = NOTE_F7;
      iNoteFS = NOTE_FS7;
      iNoteG = NOTE_G7;
      iNoteGS = NOTE_GS7;
      break;
  }
  
}

pitches.h

/*****************************************************************
 * Pitches NOTE_B0 <=> NOTE_DS8 - NOTE_A4 is "A" measured at 440Hz
 *****************************************************************/

#define NOTE_B0  31
#define NOTE_C1  33
#define NOTE_CS1  35
#define NOTE_D1  37
#define NOTE_DS1  39
#define NOTE_E1  41
#define NOTE_F1  44
#define NOTE_FS1  46
#define NOTE_G1  49
#define NOTE_GS1  52
#define NOTE_A1  55
#define NOTE_AS1  58
#define NOTE_B1  62
#define NOTE_C2  65
#define NOTE_CS2  69
#define NOTE_D2  73
#define NOTE_DS2  78
#define NOTE_E2  82
#define NOTE_F2  87
#define NOTE_FS2  93
#define NOTE_G2  98
#define NOTE_GS2  104
#define NOTE_A2  110
#define NOTE_AS2  117
#define NOTE_B2  123
#define NOTE_C3  131
#define NOTE_CS3  139
#define NOTE_D3  147
#define NOTE_DS3  156
#define NOTE_E3  165
#define NOTE_F3  175
#define NOTE_FS3 185
#define NOTE_G3  196
#define NOTE_GS3  208
#define NOTE_A3  220
#define NOTE_AS3  233
#define NOTE_B3  247
#define NOTE_C4  262
#define NOTE_CS4  277
#define NOTE_D4  294
#define NOTE_DS4 311
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_FS4  370
#define NOTE_G4  392
#define NOTE_GS4  415
#define NOTE_A4  440
#define NOTE_AS4  466
#define NOTE_B4  494
#define NOTE_C5  523
#define NOTE_CS5  554
#define NOTE_D5  587
#define NOTE_DS5  622
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_FS5  740
#define NOTE_G5  784
#define NOTE_GS5  831
#define NOTE_A5  880
#define NOTE_AS5  932
#define NOTE_B5  988
#define NOTE_C6  1047
#define NOTE_CS6  1109
#define NOTE_D6  1175
#define NOTE_DS6  1245
#define NOTE_E6  1319
#define NOTE_F6  1397
#define NOTE_FS6  1480
#define NOTE_G6  1568
#define NOTE_GS6  1661
#define NOTE_A6  1760
#define NOTE_AS6  1865
#define NOTE_B6  1976
#define NOTE_C7  2093
#define NOTE_CS7  2217
#define NOTE_D7  2349
#define NOTE_DS7  2489
#define NOTE_E7  2637
#define NOTE_F7  2794
#define NOTE_FS7  2960
#define NOTE_G7  3136
#define NOTE_GS7  3322
#define NOTE_A7  3520
#define NOTE_AS7  3729
#define NOTE_B7  3951
#define NOTE_C8  4186
#define NOTE_CS8  4435
#define NOTE_D8  4699
#define NOTE_DS8  4978

setup.ino

// Setup
void setup() {

  // Setup Keyboard
  setupKeyboard();

  // Mozzi Start
  startMozzi( CONTROL_RATE );
  // Sets Attack and Decay Levels; assumes Sustain, Decay, and Idle times
  envelope1.setADLevels(200,200);
  // Sets Decay time in milliseconds
  envelope1.setDecayTime(100);
  // Sustain Time setting for envelope1
  envelope1.setSustainTime(32500);

}

——

People can contact us: https://www.donluc.com/?page_id=1927

Technology Experience

  • Single-Board Microcontrollers (PIC, Arduino, Raspberry Pi,Espressif, etc…)
  • IoT
  • Robotics
  • Camera and Video Capture Receiver Stationary, Wheel/Tank and Underwater Vehicle
  • Unmanned Vehicles Terrestrial and Marine
  • Research & Development (R & D)

Instructor and E-Mentor

  • IoT
  • PIC Microcontrollers
  • Arduino
  • Raspberry Pi
  • Espressif
  • Robotics

Follow Us

J. Luc Paquin – Curriculum Vitae – 2022 English & Español
https://www.jlpconsultants.com/luc/

Web: https://www.donluc.com/
Web: https://www.jlpconsultants.com/
Facebook: https://www.facebook.com/neosteam.labs.9/
YouTube: https://www.youtube.com/channel/UC5eRjrGn1CqkkGfZy0jxEdA
Twitter: https://twitter.com/labs_steam
Pinterest: https://www.pinterest.com/NeoSteamLabs/
Instagram: https://www.instagram.com/neosteamlabs/

Don Luc

Project #22: Synthesizer – Momentary Button – Mk09

——

#DonLucElectronics #DonLuc #Synthesizer #Mozzi #Keyboard #ADSREnvelope #Arduino #AdafruitMETROM0Express #Project #Fritzing #Programming #Electronics #Microcontrollers #Consultant

——

Momentary Button

——

Momentary Button

——

Momentary Button

——

Momentary Button – Panel Mount

It’s your basic black or blue action button. This is a very useful, small, panel-mount momentary switch. It is a SPST N.O. with the threaded portion being 6.75 mm in diameter. This button is perfect for basic On/Off functions. Overall length including leads and has small solder lugs for connection. These momentary buttons are rated up to 0.5A and 250VAC.

Momentary button connect two points in a circuit when you press them. Turns on and off a light emitting LED. When the button is open there is no connection between the two legs of the button, so the pin is connected to ground, through the pull-down resistor, and we read a LOW. When the button is closed, it makes a connection between its two legs, connecting the pin to 5 volts, so that we read a HIGH.

You can also wire this circuit the opposite way, with a pullup resistor keeping the input HIGH, and going LOW when the button is pressed. If so, the behavior of the sketch will be reversed, with the LED normally on and turning off when you press the button.

DL2208Mk02

1 x Adafruit METRO M0 Express
8 x Momentary Button – Panel Mount (Blue)
5 x Momentary Button – Panel Mount (Black)
13 x 10K Ohm Resistor
1 x LED Red 5mm
1 x SparkFun Cerberus USB Cable

Adafruit METRO M0 Express

KY0 – 0
KY1 – 1
KY2 – 2
KY3 – 3
KY4 – 4
KY5 – 5
KY6 – 6
KY7 – 7
KY8 – 8
LEDR – 9
KY10 – 10
KY11 – 11
KY12 – 12
KY13 – 13
VIN – +5V
GND – GND

——

DL2208Mk02p.ino

/* ***** Don Luc Electronics © *****
Software Version Information
Project #22: Synthesizer - Momentary Button - Mk09
22-09
DL2208Mk02p.ino
1 x Adafruit METRO M0 Express
8 x Momentary Button - Panel Mount (Blue)
5 x Momentary Button - Panel Mount (Black)
13 x 1K Ohm Resistor
1 x LED Red 5mm
1 x SparkFun Cerberus USB Cable
*/

// Include the Library Code


// Simple Keyboard
// Minimum reading of the button that generates a note
//const int iKeyboard0 = 0;
const int iKeyboard1 = 1;
const int iKeyboard2 = 2;
const int iKeyboard3 = 3;
const int iKeyboard4 = 4;
const int iKeyboard5 = 5;
const int iKeyboard6 = 6;
const int iKeyboard7 = 7;
const int iKeyboard8 = 8;
const int iKeyboard10 = 10;
const int iKeyboard11 = 11;
const int iKeyboard12 = 12;
const int iKeyboard13 = 13;
// Button is pressed
int iB0 = 1;
int iB1 = 1;
int iB2 = 1;
int iB3 = 1;
int iB4 = 1;
int iB5 = 1;
int iB6 = 1;
int iB7 = 1;
int iB8 = 1;
int iB10 = 1;
int iB11 = 1;
int iB12 = 1;
int iB13 = 1;

// The number of the LED Red pin 9
const int iLedR =  9;

// Software Version Information
String sver = "22-09";

void loop() {

  // isKeyboard
  isKeyboard();
  
}

getKeyboard.ino

// getKeyboard
// setupKeyboard
void setupKeyboard() {

  // Initialize the button pin as an input
//  pinMode(iKeyboard0, INPUT_PULLUP);
  pinMode(iKeyboard1, INPUT_PULLUP);
  pinMode(iKeyboard2, INPUT_PULLUP);
  pinMode(iKeyboard3, INPUT_PULLUP);
  pinMode(iKeyboard4, INPUT_PULLUP);
  pinMode(iKeyboard5, INPUT_PULLUP);
  pinMode(iKeyboard6, INPUT_PULLUP);
  pinMode(iKeyboard7, INPUT_PULLUP);
  pinMode(iKeyboard8, INPUT_PULLUP);
  pinMode(iKeyboard10, INPUT_PULLUP);
  pinMode(iKeyboard11, INPUT_PULLUP);
  pinMode(iKeyboard12, INPUT_PULLUP);
  pinMode(iKeyboard13, INPUT_PULLUP);
 
}
// isKeyboard
void isKeyboard() {

/*
  // Read the state of the button value 0
  if ( digitalRead(iKeyboard0) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 0
    iB0 = iB0 + 1;
    // Turn LED Red on
    digitalWrite(iLedR, HIGH );

  }
  else
  {
    
    iB0 = iB0 - 1;
    // Turn LED Red off
    digitalWrite(iLedR, LOW );
    
  }
*/
  // Read the state of the button value 1
  if ( digitalRead(iKeyboard1) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 1
    iB1 = iB1 + 1;
    // Turn LED Red on
    digitalWrite(iLedR, HIGH );

  }
  else
  {
    
    iB1 = iB1 - 1;
    // Turn LED Red off
    digitalWrite(iLedR, LOW );
    
  }

  // Read the state of the button value 2
  if ( digitalRead(iKeyboard2) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 2
    iB2 = iB2 + 1;
    // Turn LED Red on
    digitalWrite(iLedR, HIGH );

  }
  else
  {
    
    iB2 = iB2 - 1;
    // Turn LED Red off
    digitalWrite(iLedR, LOW );
    
  }

  // Read the state of the button value 3
  if ( digitalRead(iKeyboard3) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 3
    iB3 = iB3 + 1;
    // Turn LED Red on
    digitalWrite(iLedR, HIGH );

  }
  else
  {
    
    iB3 = iB3 - 1;
    // Turn LED Red off
    digitalWrite(iLedR, LOW );
    
  }

  // Read the state of the button value 4
  if ( digitalRead(iKeyboard4) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 4
    iB4 = iB4 + 1;
    // Turn LED Red on
    digitalWrite(iLedR, HIGH );

  }
  else
  {
    
    iB4 = iB4 - 1;
    // Turn LED Red off
    digitalWrite(iLedR, LOW );
    
  }

  // Read the state of the button value 5
  if ( digitalRead(iKeyboard5) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 5
    iB5 = iB5 + 1;
    // Turn LED Red on
    digitalWrite(iLedR, HIGH );

  }
  else
  {
    
    iB5 = iB5 - 1;
    // Turn LED Red off
    digitalWrite(iLedR, LOW );
    
  }

  // Read the state of the button value 6
  if ( digitalRead(iKeyboard6) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 6
    iB6 = iB6 + 1;
    // Turn LED Red on
    digitalWrite(iLedR, HIGH );

  }
  else
  {
    
    iB6 = iB6 - 1;
    // Turn LED Red off
    digitalWrite(iLedR, LOW );
    
  }

  // Read the state of the button value 7
  if ( digitalRead(iKeyboard7) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 7
    iB7 = iB7 + 1;
    // Turn LED Red on
    digitalWrite(iLedR, HIGH );

  }
  else
  {
    
    iB7 = iB7 - 1;// Turn LED Red off
    digitalWrite(iLedR, LOW );
    
  }

  // Read the state of the button value 8
  if ( digitalRead(iKeyboard8) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 8
    iB8 = iB8 + 1;
    // Turn LED Red on
    digitalWrite(iLedR, HIGH );

  }
  else
  {
    
    iB8 = iB8 - 1;
    // Turn LED Red off
    digitalWrite(iLedR, LOW );
    
  }

  // Read the state of the button value 10
  if ( digitalRead(iKeyboard10) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 10
    iB10 = iB10 + 1;
    // Turn LED Red on
    digitalWrite(iLedR, HIGH );

  }
  else
  {
    
    iB10 = iB10 - 1;
    // Turn LED Red off
    digitalWrite(iLedR, LOW );
    
  }

  // Read the state of the button value 11
  if ( digitalRead(iKeyboard11) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 11
    iB11 = iB11 + 1;
    // Turn LED Red on
    digitalWrite(iLedR, HIGH );

  }
  else
  {
    
    iB11 = iB11 - 1;
    // Turn LED Red off
    digitalWrite(iLedR, LOW );
    
  }

  // Read the state of the button value 12
  if ( digitalRead(iKeyboard12) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 12
    iB12 = iB12 + 1;
    // Turn LED Red on
    digitalWrite(iLedR, HIGH );

  }
  else
  {
    
    iB12 = iB12 - 1;
    // Turn LED Red off
    digitalWrite(iLedR, LOW );
    
  }

  // Read the state of the button value 13
  if ( digitalRead(iKeyboard13) == HIGH ) {

    // Button is pressed - pullup keeps pin high normally 13
    iB13 = iB13 + 1;
    // Turn LED Red on
    digitalWrite(iLedR, HIGH );

  }
  else
  {
    
    iB13 = iB13 - 1;
    // Turn LED Red off
    digitalWrite(iLedR, LOW );
    
  }

}

setup.ino

// Setup
void setup() {

  // Setup Keyboard
  setupKeyboard();

  // Initialize the LED Red pin 9 as an output
  pinMode(iLedR, OUTPUT);
  
}

——

People can contact us: https://www.donluc.com/?page_id=1927

Technology Experience

  • Single-Board Microcontrollers (PIC, Arduino, Raspberry Pi,Espressif, etc…)
  • IoT
  • Robotics
  • Camera and Video Capture Receiver Stationary, Wheel/Tank and Underwater Vehicle
  • Unmanned Vehicles Terrestrial and Marine
  • Research & Development (R & D)

Instructor and E-Mentor

  • IoT
  • PIC Microcontrollers
  • Arduino
  • Raspberry Pi
  • Espressif
  • Robotics

Follow Us

J. Luc Paquin – Curriculum Vitae – 2022 English & Español
https://www.jlpconsultants.com/luc/

Web: https://www.donluc.com/
Web: https://www.jlpconsultants.com/
Facebook: https://www.facebook.com/neosteam.labs.9/
YouTube: https://www.youtube.com/channel/UC5eRjrGn1CqkkGfZy0jxEdA
Twitter: https://twitter.com/labs_steam
Pinterest: https://www.pinterest.com/NeoSteamLabs/
Instagram: https://www.instagram.com/neosteamlabs/

Don Luc

Project #22: Synthesizer – Slide Linear Taper Pot – Mk08

——

#DonLucElectronics #DonLuc #Synthesizer #Mozzi #Keyboard #ADSREnvelope #Arduino #AdafruitMETROM0Express #Project #Fritzing #Programming #Electronics #Microcontrollers #Consultant

——

Slide Linear Taper Pot

——

Slide Linear Taper Pot

——

Slide Linear Taper Pot

——

10k Ohm Slide Linear Taper Pot – X-Large

A simple slide potentiometer can go a long way. Rated at 10k Ohm and 0.5W. Comes with solder tab connections. The taper profile for this slide:

Length: 80 cm
Width: 15 cm
Height: 12 cm

Slide Potentiometer Knob – X-Large

This is a simple knob that connects to the extra large sized linear slide potentiometer. Each knob uses friction to secure itself to fit onto the slide pot. Once attached, this small knob provides you with an easier to use potentiometer for your project.

Adafruit METRO M0 Express

Metro is our series of microcontroller boards for use with the Arduino IDE. This new Metro M0 Express board looks a whole lot like our original Metro 328, but with a huge upgrade. This Metro features a ATSAMD21G18 chip, an ARM Cortex M0+.

At the Metro M0’s heart is an ATSAMD21G18 ARM Cortex M0 processor, clocked at 48 MHz and at 3.3V logic. This chip has a 256K of FLASH and 32K of RAM. This chip comes with built in USB so it has USB-to-Serial program.

DL2208Mk01

1 x Adafruit METRO M0 Express
5 x 10k Ohm Slide Linear Taper Pot – X-Large
5 x Slide Potentiometer Knob – X-Large
1 x SparkFun Cerberus USB Cable

Adafruit METRO M0 Express

LP0 – Analog A0 – Blue
LP1 – Analog A1 – Green
LP2 – Analog A2 – Grey
LP3 – Analog A3 – Yellow
LP4 – Analog A4 – Purple
VIN – +5V
GND – GND

DL2208Mk01p.ino

/* ***** Don Luc Electronics © *****
Software Version Information
Project #22: Synthesizer - Slide Linear Taper Pot - Mk08
22-08
DL2208Mk01p.ino
1 x Adafruit METRO M0 Express
5 x 10k Ohm Slide Linear Taper Pot - X-Large
5 x Slide Potentiometer Knob - X-Large
1 x SparkFun Cerberus USB Cable
*/

// Include the Library Code

// Pot
int iPot0 = A0;
int iPot1 = A1;
int iPot2 = A2;
int iPot3 = A3;
int iPot4 = A4;
int sensorValue0 = 0;
int iValue0 = 0;
int sensorValue1 = 0;
int iValue1 = 0;
int sensorValue2 = 0;
int iValue2 = 0;
int sensorValue3 = 0;
int iValue3 = 0;
int sensorValue4 = 0;
int iValue4 = 0;

// Software Version Information
String sver = "22-08";

void loop() {

  // Pot
  isPot();

  // Delay in between reads
  delay( 1000 );
  
}

getPot.ino

// 10k Slide Linear Taper Pot - X-Large
// Pot
void isPot(){

  // Read the input on analog pin 0
  sensorValue0 = analogRead( iPot0 );
  iValue0 = map(sensorValue0, 0, 1023, 0, 255);
  Serial.print( "P0: " );
  Serial.print( iValue0 );
  // Read the input on analog pin 1
  sensorValue1 = analogRead( iPot1 );
  iValue1 = map(sensorValue1, 0, 1023, 0, 255);
  Serial.print( " P1: " );
  Serial.print( iValue1 );
  // Read the input on analog pin 2
  sensorValue2 = analogRead( iPot2 );
  iValue2 = map(sensorValue2, 0, 1023, 0, 255);
  Serial.print( " P2: " );
  Serial.print( iValue2 );
  // Read the input on analog pin 3
  sensorValue3 = analogRead( iPot3 );
  iValue3 = map(sensorValue3, 0, 1023, 0, 255);
  Serial.print( " P3: " );
  Serial.print( iValue3 );
  // Read the input on analog pin 4
  sensorValue4 = analogRead( iPot4 );
  iValue4 = map(sensorValue4, 0, 1023, 0, 255);
  Serial.print( " P4: " );
  Serial.println( iValue4 );

}

setup.ino

// Setup
void setup() {

  // Initialize serial communication at 9600 bits per second
  Serial.begin(9600);
  
}

——

People can contact us: https://www.donluc.com/?page_id=1927

Technology Experience

  • Single-Board Microcontrollers (PIC, Arduino, Raspberry Pi,Espressif, etc…)
  • IoT
  • Robotics
  • Camera and Video Capture Receiver Stationary, Wheel/Tank and Underwater Vehicle
  • Unmanned Vehicles Terrestrial and Marine
  • Research & Development (R & D)

Instructor and E-Mentor

  • IoT
  • PIC Microcontrollers
  • Arduino
  • Raspberry Pi
  • Espressif
  • Robotics

Follow Us

J. Luc Paquin – Curriculum Vitae – 2022 English & Español
https://www.jlpconsultants.com/luc/

Web: https://www.donluc.com/
Web: https://www.jlpconsultants.com/
Facebook: https://www.facebook.com/neosteam.labs.9/
YouTube: https://www.youtube.com/channel/UC5eRjrGn1CqkkGfZy0jxEdA
Twitter: https://twitter.com/labs_steam
Pinterest: https://www.pinterest.com/NeoSteamLabs/
Instagram: https://www.instagram.com/neosteamlabs/

Don Luc

Project #22: Synthesizer – Volume Sound – Mk07

——

DonLucElectronics #DonLuc #Synthesizer #UltrasonicSynth #Mozzi #Arduino #ArduinoProMini #Project #Fritzing #Programming #Electronics #Microcontrollers #Consultant

——

Volume Sound

——

Volume Sound

——

Volume Sound

——

Volume Sound

Volume the degree of loudness or the intensity of a sound. The volume of a sound is how loud or quiet the sound is. Sounds are vibrations that travel through the air. Volume, or loudness, is related to the strength, intensity, pressure, or power of the sound. Amplified vibrations result in louder sounds. There are a few ways of varying the volume.

I am using the Mozzi audio library to implement a simple synthesizer and using a potentiometer to control the amplitude of a sinewave with Mozzi sonification library. To convey the volume level. Volume it to an 8 bit range for efficient calculations.

DL2207Mk04

1 x Arduino Pro Mini 328 – 5V/16MHz
2 x HC-SR04 Ultrasonic Sensor
3 x 1M Ohm Potentiometer
3 x Knob
1 x Audio Jack 3.5mm
1 x SparkFun Audio Jack Breakout
1 x SparkFun USB Mini-B Breakout
1 x SPDT Slide Switch
1 x JST Jumper 2 Wire Connector
1 x JST Jumper 3 Wire Connector
1 x Insignia Speakers
1 x SparkFun Solderable Breadboard – Large
1 x SparkFun FTDI Basic Breakout – 5V
1 x SparkFun Cerberus USB Cable

Arduino Pro Mini 328 – 5V/16MHz

Ech – Digital 13
Tri – Digital 12
EcR – Digital 11
TrR – Digital 10
SPK – Digital 9
CAP – Analog A0
CAH – Analog A1
CAV – Analog A2
VIN – +5V
GND – GND

——

DL2207Mk04p.ino

/* ***** Don Luc Electronics © *****
Software Version Information
Project #22: Synthesizer - Volume - Mk07
22-07
DL2207Mk04p.ino
1 x Arduino Pro Mini 328 - 5V/16MHz
2 x HC-SR04 Ultrasonic Sensor
3 x 1M Ohm Potentiometer
3 x Knob
1 x Audio Jack 3.5mm
1 x SparkFun Audio Jack Breakout
1 x SparkFun USB Mini-B Breakout
1 x SPDT Slide Switch
1 x JST Jumper 2 Wire Connector
1 x JST Jumper 3 Wire Connector
1 x Insignia Speakers
1 x SparkFun Solderable Breadboard - Large
1 x SparkFun FTDI Basic Breakout - 5V
1 x SparkFun Cerberus USB Cable
*/

// Include the Library Code
// Mozzi
#include <MozziGuts.h>
// Oscillator
#include <Oscil.h>
// Table for Oscils to play
#include <tables/cos2048_int8.h>
// Smoothing Control
#include <Smooth.h>
// Maps unpredictable inputs to a range
#include <AutoMap.h>

// Desired carrier frequency max and min, for AutoMap
const int MIN_CARRIER_FREQ = 22;
const int MAX_CARRIER_FREQ = 440;

// 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;

// Maps unpredictable inputs to a range
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);

// Set the input for the knob to analog pin 0
const int KNOB_PIN = A0;
// Set the analog input for fm_intensity
int LDR1_PIN;
// Set the analog input for mod rate
int LDR2_PIN;

// Table for Oscils to play
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);

// Harmonics (Brightness)
int iModRatio = A1;
int mod_ratio;
// Carries control info from updateControl to updateAudio
long fm_intensity;

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

// Trigger pin 12 to pitch distance sensor
const int iTrigPitch = 12;
// Echo Receive pin 13 to pitch distance sensor
const int iEchoPitch = 13;
// Define the useable range of the pitch sensor
const int pitchLowThreshold = 45;
const int pitchHighThreshold = 2;    
// Stores the distance measured by the distance sensor
float distance = 0;
// Trigger pin 10 to rate distance sensor
const int iTrigRate = 10;
// Echo Receive pin 13 to pitch distance sensor
const int iEchoRate = 11;
// Define the useable range of the pitch sensor
const int rateLowThreshold = 45;
const int rateHighThreshold = 2;    
// Stores the distance measured by the distance sensor
float rate = 0;

// Volume
// Set the input for the knob to analog pin 2
const int iVolKnob = A2;
// To convey the Volume level from updateControl() to updateAudio()
byte bVolume;

// Mini Speaker
int SPK = 9;

// Software Version Information
String sver = "22-07";

void loop() {

  // Audio Hook
  audioHook();
  
}

getHC-SR04.ino

// HC-SR04 Ultrasonic Sensor
// Setup HC-SR04
void setupHCSR04() {

  // The trigger iTrig Pitch will output pulses of electricity
  pinMode(iTrigPitch, OUTPUT);
  // The echo iEcho will measure the duration of pulses coming back from the distance sensor
  pinMode(iEchoPitch, INPUT);

  // The trigger iTrig Rate will output pulses of electricity
  pinMode(iTrigRate, OUTPUT);
  // The echo iEcho will measure the duration of pulses coming back from the distance sensor
  pinMode(iEchoRate, INPUT);
  
}
// Distance
float isDistance() {
  
  // Variable to store the time it takes for a ping to bounce off an object
  float echoTime;
  // Variable to store the distance calculated from the echo time
  float calculatedDistance;

  // Send out an ultrasonic pulse that's 10ms long
  digitalWrite(iTrigPitch, HIGH);
  delayMicroseconds(10);
  digitalWrite(iTrigPitch, LOW);

  // Use the pulseIn command to see how long it takes for the
  // pulse to bounce back to the sensor
  echoTime = pulseIn(iEchoPitch, HIGH);

  // Calculate the distance of the object that reflected the pulse
  // (half the bounce time multiplied by the speed of sound)
  calculatedDistance = echoTime * 0.034 / 2;

  // Send back the distance that was calculated
  return calculatedDistance;
  
}
// Rate
float isRate() {
  
  // Variable to store the time it takes for a ping to bounce off an object
  float echoTime;
  // Variable to store the distance calculated from the echo time
  float calculatedDistance;

  // Send out an ultrasonic pulse that's 10ms long
  digitalWrite(iTrigRate, HIGH);
  delayMicroseconds(10);
  digitalWrite(iTrigRate, LOW);

  // Use the pulseIn command to see how long it takes for the
  // pulse to bounce back to the sensor
  echoTime = pulseIn(iEchoRate, HIGH);

  // Calculate the distance of the object that reflected the pulse
  // (half the bounce time multiplied by the speed of sound)
  // cm = 58.0
  calculatedDistance = echoTime * 0.034 / 2;

  // Send back the distance that was calculated
  return calculatedDistance;
  
}

getMozzi.ino

// Mozzi
// Update Control
void updateControl(){

  // Variable to store the distance measured by the sensor
  distance = isDistance();
  // Low Threshold
  if ( distance >= pitchLowThreshold) {

    // pitchLowThreshold
    distance = pitchLowThreshold;
    
  }
  // High Threshold
  if ( distance < pitchHighThreshold){
    
    // pitchHighThreshold
    distance = pitchHighThreshold;
    
  }

  // Variable to store the distance measured by the sensor
  rate = isRate();
  // Low Threshold
  if ( rate >= rateLowThreshold) {

    // rateLowThreshold
    rate = rateLowThreshold;
    
  }
  // High Threshold
  if ( rate < rateHighThreshold){
    
    // rateHighThreshold
    rate = rateHighThreshold;
    
  }

  // Map
  distance = map(distance, 45, 2, 0, 1023);
  rate = map(rate, 45, 2, 0, 1023);
  
  // Read the knob
  // Value is 0-1023
  int knob_value = mozziAnalogRead(KNOB_PIN);

  // Read the mod_ratio
  // Value is 0-1023
  mod_ratio = mozziAnalogRead(iModRatio);

  // Map
  mod_ratio = map(mod_ratio, 0, 1023, 2, 15);

  // 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;

  // Set the FM oscillator frequencies
  aCarrier.setFreq(carrier_freq);
  aModulator.setFreq(mod_freq);

  // Read the light dependent resistor on the width
  LDR1_PIN = distance;
  int LDR1_value = LDR1_PIN;

  int LDR1_calibrated = kMapIntensity(LDR1_value);

  // Calculate the fm_intensity
  // Shift back to range after 8 bit multiply
  fm_intensity = ((long)LDR1_calibrated * (kIntensityMod.next()+128))>>8;
  
  // Read the light dependent resistor on the speed
  LDR2_PIN = rate;
  int LDR2_value= LDR2_PIN;

  // Use a float here for low frequencies
  float mod_speed = (float)kMapModSpeed(LDR2_value)/1000;

  kIntensityMod.setFreq(mod_speed);

  // Read the variable resistor for volume
  // Value is 0-1023
  int iVolValue = mozziAnalogRead(iVolKnob); 
  // map it to an 8 bit range for efficient calculations in updateAudio
  bVolume = map(iVolValue, 0, 1023, 155, 1);
  
}
// Update Audio
int updateAudio()
{

  // Update Audio
  long modulation = aSmoothIntensity.next(fm_intensity) * aModulator.next() * bVolume;
  return aCarrier.phMod(modulation);

}

setup.ino

// Setup
void setup() {

  // Setup HC-SR04
  setupHCSR04();

  // Delay
  delay( 200 );

  // Mozzi Start
  startMozzi();

}

——

People can contact us: https://www.donluc.com/?page_id=1927

Technology Experience

  • Single-Board Microcontrollers (PIC, Arduino, Raspberry Pi,Espressif, etc…)
  • IoT
  • Robotics
  • Camera and Video Capture Receiver Stationary, Wheel/Tank and Underwater Vehicle
  • Unmanned Vehicles Terrestrial and Marine
  • Research & Development (R & D)

Instructor and E-Mentor

  • IoT
  • PIC Microcontrollers
  • Arduino
  • Raspberry Pi
  • Espressif
  • Robotics

Follow Us

J. Luc Paquin – Curriculum Vitae – 2022 English & Español
https://www.jlpconsultants.com/luc/

Web: https://www.donluc.com/
Web: https://www.jlpconsultants.com/
Facebook: https://www.facebook.com/neosteam.labs.9/
YouTube: https://www.youtube.com/channel/UC5eRjrGn1CqkkGfZy0jxEdA
Twitter: https://twitter.com/labs_steam
Pinterest: https://www.pinterest.com/NeoSteamLabs/
Instagram: https://www.instagram.com/neosteamlabs/

Don Luc

Project #22: Synthesizer – Envelope – Mk06

——

#DonLucElectronics #DonLuc #Synthesizer #Mozzi #Keyboard #ADSREnvelope #Arduino #ArduinoProMini #Project #Fritzing #Programming #Electronics #Microcontrollers #Consultant

——

Envelope

——

Envelope

——

Envelope

——

Envelope (Music)

In sound and music, an envelope describes how a sound changes over time. It may relate to elements such as amplitude (Volume), frequencies (with the use of filters) or pitch. For example, a piano key, when struck and held, creates a near-immediate initial sound which gradually decreases in volume to zero.

Envelope generators, which allow users to control the different stages of a sound, are common features of synthesizers, samplers, and other electronic musical instruments. The most common form of envelope generator is controlled with four parameters: attack, decay, sustain and release (ADSR).

A Simple ADSR Envelope Generator

This implementation has separate update() and next() methods, where next() interpolates values between each update(). The “normal” way to use this would be with update() in updateControl(), where it calculates a new internal state each control step, and then next() is in updateAudio(), called much more often, where it interpolates between the control values. This also allows the ADSR updates to be made even more sparsely if desired, eg. every 3rd control update.

noteOn()

Start the attack phase of the ADSR. This will restart the ADSR no matter what phase it is up to. True, the envelope will start from 0, even if it is still playing, often useful for effect envelopes. If false, the envelope will start rising from the current level, which could be non-zero, if it is still playing, most useful for note envelopes.

DL2207Mk01

1 x Arduino Pro Mini 328 – 5V/16MHz
8 x Tactile Button
3 x 1K Ohm Potentiometer
3 x Knob
1 x JST Jumper 3 Wire Connector
1 x Solderable Breadboard
1 x SparkFun FTDI Basic Breakout – 5V
1 x SparkFun Cerberus USB Cable

Arduino Pro Mini 328 – 5V/16MHz

KY2 – Digital 2
KY3 – Digital 3
KY4 – Digital 4
KY5 – Digital 5
KY6 – Digital 6
KY7 – Digital 7
KY8 – Digital 8
SPK – Digital 9
KY9 – Digital 10
PFR – Analog A3
CDE – Analog A2
CAT – Analog A1
VIN – +5V
GND – GND

DL2207Mk01p.ino

/* ***** Don Luc Electronics © *****
Software Version Information
Project #22: Synthesizer - Envelope - Mk06
22-06
DL2207Mk01p.ino
1 x Arduino Pro Mini 328 - 5V/16MHz
8 x Tactile Button
3 x 1K Ohm Potentiometer
3 x Knob
4 x SPDT Slide Switch
1 x JST Jumper 3 Wire
1 x Insignia Speakers
1 x Solderable Breadboard
1 x SparkFun FTDI Basic Breakout - 5V
1 x SparkFun Cerberus USB Cable
*/

// Include the Library Code
// Pitches
#include "pitches.h"
// Mozzi
#include <MozziGuts.h>
// Oscillator
#include <Oscil.h>
// Table for Oscils to play
#include <tables/sin2048_int8.h>
// ADSR envelope generator
#include <ADSR.h>

// Simple Keyboard
// Minimum reading of the button that generates a note
const int iKeyboard2 = 2;
const int iKeyboard3 = 3;
const int iKeyboard4 = 4;
const int iKeyboard5 = 5;
const int iKeyboard6 = 6;
const int iKeyboard7 = 7;
const int iKeyboard8 = 8;
const int iKeyboard9 = 10; 
// Button is pressed
int aa = 1;
int bb = 1;
int cc = 1;
int dd = 1;
int ee = 1;
int ff = 1;
int gg = 1;
int hh = 1;

//Oscillator Functions declared for output envelope 1 
// Sine Wave
Oscil <2048, AUDIO_RATE> aSin1(SIN2048_DATA);

// ADSR declaration/definition
// Comment out to use control rate of 128
#define CONTROL_RATE 128
ADSR <CONTROL_RATE, CONTROL_RATE> envelope1;

// Set the input for the potentiometer Attack to analog pin 1
const int potAttack = A1;
// Attack
int attack_level = 0;
int iAttack = 0;

// Set the input for the potentiometer for Decay to analog pin 2
const int potDecay = A2;
// Decay
int decay_level = 0;
int iDecay = 0;

// Set the input for the potentiometer for Frequency to analog pin 3
const int potFreq = A3;
int iFreg = 1;
int iNoteA = 0;
int iNoteB = 0;
int iNoteC = 0;
int iNoteD = 0;
int iNoteE = 0;
int iNoteF = 0;
int iNoteG = 0;
int iNoteAA = 0;

// Software Version Information
String sver = "22-06";

void loop() {

  // Audio Hook
  audioHook();
  
}

getKeyboard.ino

// getKeyboard
// setupKeyboard
void setupKeyboard() {

  // Initialize the pushbutton pin as an input
  pinMode(iKeyboard2, INPUT_PULLUP);
  pinMode(iKeyboard3, INPUT_PULLUP);
  pinMode(iKeyboard4, INPUT_PULLUP);
  pinMode(iKeyboard5, INPUT_PULLUP);
  pinMode(iKeyboard6, INPUT_PULLUP);
  pinMode(iKeyboard7, INPUT_PULLUP);
  pinMode(iKeyboard8, INPUT_PULLUP);
  pinMode(iKeyboard9, INPUT_PULLUP);
 
}
// isKeyboard
void isKeyboard() {

  // Choose envelope levels
  // attack_level
  iAttack = mozziAnalogRead( potAttack );
  attack_level = map( iAttack, 0, 1023, 0, 255);
  // decay_level
  iDecay = mozziAnalogRead( potDecay );
  decay_level = map( iDecay, 0, 1023, 0, 255);
  // set AD Levels
  envelope1.setADLevels(attack_level,decay_level);

  // Read the state of the pushbutton value
  if ( digitalRead(iKeyboard2) == LOW ) {

    // Button is pressed - pullup keeps pin high normally
    aa = aa + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteA);
    
  }
  else
  {
    
    aa = aa - 1;
    
  }    

  // Read the state of the pushbutton value
  if ( digitalRead(iKeyboard3) == LOW ) {

    // Button is pressed - pullup keeps pin high normally
    bb = bb + 1;
    // Waveform
    envelope1.noteOn();
    aSin1.setFreq(iNoteB);
    
  }
  else
  {
    
    bb = bb - 1;
    
  }

  // Read the state of the pushbutton value
  if ( digitalRead(iKeyboard4) == LOW ) {

    // Button is pressed - pullup keeps pin high normally
    cc = cc + 1;
    // Waveform
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteC);
    
  }
  else
  {
    
    cc = cc - 1;
    
  }

  // Read the state of the pushbutton value
  if ( digitalRead(iKeyboard5) == LOW ) {

    // Button is pressed - pullup keeps pin high normally
    dd = dd + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteD);
      
  }
  else
  {
    
    dd = dd - 1;
    
  }
  
  // Read the state of the pushbutton value
  if ( digitalRead(iKeyboard6) == LOW ) {

    // Button is pressed - pullup keeps pin high normally
    ee = ee + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteE);    
  }
  else
  {
    
    ee = ee - 1;
    
  }

  // Read the state of the pushbutton value
  if ( digitalRead(iKeyboard7) == LOW ) {

    // Button is pressed - pullup keeps pin high normally
    ff = ff + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteF);
        
  }
  else
  {
    
    ff = ff - 1;
    
  }

  // Read the state of the pushbutton value
  if ( digitalRead(iKeyboard8) == LOW ) {

    // Button is pressed - pullup keeps pin high normally
    gg = gg + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteG);
        
  }
  else
  {
    
    gg = gg - 1;
    
  }

  // Read the state of the pushbutton value
  if ( digitalRead(iKeyboard9) == LOW ) {

    // Button is pressed - pullup keeps pin high normally
    hh = hh + 1;
    // ADSR declaration/definition
    envelope1.noteOn();
    aSin1.setFreq(iNoteAA);
        
  }
  else
  {
    
    hh = hh - 1;
    
  }

}

getMozzi.ino

// Mozzi
// Update Control
void updateControl(){

  // Frequency
  isPitches();
  
  // Keyboard
  isKeyboard();

}
// Update Audio
int updateAudio()
{

  // Update Audio
  // ADSR declaration/definition
  envelope1.update();
  // >>8 for AUDIO_MODE STANDARD
  return (int) (envelope1.next() * aSin1.next())>>8;

}

getPitches.ino

// Pitches
// isPitches
void isPitches(){
  
  // Frequency
  // Value is 0-1023
  iFreg = mozziAnalogRead(potFreq);
  iFreg = map(iFreg, 0, 1023, 3, 6);

  // Range Frequency Note Low => High
  switch ( iFreg ) {
    case 1:
      // NOTE A1
      iNoteA = NOTE_A1;
      iNoteB = NOTE_B1;
      iNoteC = NOTE_C2;
      iNoteD = NOTE_D2;
      iNoteE = NOTE_E2;
      iNoteF = NOTE_F2;
      iNoteG = NOTE_G2;
      iNoteAA = NOTE_A2;
      break;
    case 2:
      // NOTE A2
      iNoteA = NOTE_A2;
      iNoteB = NOTE_B2;
      iNoteC = NOTE_C3;
      iNoteD = NOTE_D3;
      iNoteE = NOTE_E3;
      iNoteF = NOTE_F3;
      iNoteG = NOTE_G3;
      iNoteAA = NOTE_A3;
      break;
    case 3:
      // NOTE A3
      iNoteA = NOTE_A3;
      iNoteB = NOTE_B3;
      iNoteC = NOTE_C4;
      iNoteD = NOTE_D4;
      iNoteE = NOTE_E4;
      iNoteF = NOTE_F4;
      iNoteG = NOTE_G4;
      iNoteAA = NOTE_A4;
      break;
    case 4:
      // NOTE A4
      iNoteA = NOTE_A4;
      iNoteB = NOTE_B4;
      iNoteC = NOTE_C5;
      iNoteD = NOTE_D5;
      iNoteE = NOTE_E5;
      iNoteF = NOTE_F5;
      iNoteG = NOTE_G5;
      iNoteAA = NOTE_A5;
      break;
    case 5:
      // NOTE A5
      iNoteA = NOTE_A5;
      iNoteB = NOTE_B5;
      iNoteC = NOTE_C6;
      iNoteD = NOTE_D6;
      iNoteE = NOTE_E6;
      iNoteF = NOTE_F6;
      iNoteG = NOTE_G6;
      iNoteAA = NOTE_A6;
      break;
    case 6:
      // NOTE A6
      iNoteA = NOTE_A6;
      iNoteB = NOTE_B6;
      iNoteC = NOTE_C7;
      iNoteD = NOTE_D7;
      iNoteE = NOTE_E7;
      iNoteF = NOTE_F7;
      iNoteG = NOTE_G7;
      iNoteAA = NOTE_A7;
      break;
  }
  
}

pitches.h

/*****************************************************************
 * Pitches NOTE_B0 <=> NOTE_DS8 - NOTE_A4 is "A" measured at 440Hz
 *****************************************************************/

#define NOTE_B0  31
#define NOTE_C1  33
#define NOTE_CS1 35
#define NOTE_D1  37
#define NOTE_DS1 39
#define NOTE_E1  41
#define NOTE_F1  44
#define NOTE_FS1 46
#define NOTE_G1  49
#define NOTE_GS1 52
#define NOTE_A1  55
#define NOTE_AS1 58
#define NOTE_B1  62
#define NOTE_C2  65
#define NOTE_CS2 69
#define NOTE_D2  73
#define NOTE_DS2 78
#define NOTE_E2  82
#define NOTE_F2  87
#define NOTE_FS2 93
#define NOTE_G2  98
#define NOTE_GS2 104
#define NOTE_A2  110
#define NOTE_AS2 117
#define NOTE_B2  123
#define NOTE_C3  131
#define NOTE_CS3 139
#define NOTE_D3  147
#define NOTE_DS3 156
#define NOTE_E3  165
#define NOTE_F3  175
#define NOTE_FS3 185
#define NOTE_G3  196
#define NOTE_GS3 208
#define NOTE_A3  220
#define NOTE_AS3 233
#define NOTE_B3  247
#define NOTE_C4  262
#define NOTE_CS4 277
#define NOTE_D4  294
#define NOTE_DS4 311
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_FS4 370
#define NOTE_G4  392
#define NOTE_GS4 415
#define NOTE_A4  440
#define NOTE_AS4 466
#define NOTE_B4  494
#define NOTE_C5  523
#define NOTE_CS5 554
#define NOTE_D5  587
#define NOTE_DS5 622
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_FS5 740
#define NOTE_G5  784
#define NOTE_GS5 831
#define NOTE_A5  880
#define NOTE_AS5 932
#define NOTE_B5  988
#define NOTE_C6  1047
#define NOTE_CS6 1109
#define NOTE_D6  1175
#define NOTE_DS6 1245
#define NOTE_E6  1319
#define NOTE_F6  1397
#define NOTE_FS6 1480
#define NOTE_G6  1568
#define NOTE_GS6 1661
#define NOTE_A6  1760
#define NOTE_AS6 1865
#define NOTE_B6  1976
#define NOTE_C7  2093
#define NOTE_CS7 2217
#define NOTE_D7  2349
#define NOTE_DS7 2489
#define NOTE_E7  2637
#define NOTE_F7  2794
#define NOTE_FS7 2960
#define NOTE_G7  3136
#define NOTE_GS7 3322
#define NOTE_A7  3520
#define NOTE_AS7 3729
#define NOTE_B7  3951
#define NOTE_C8  4186
#define NOTE_CS8 4435
#define NOTE_D8  4699
#define NOTE_DS8 4978

setup.ino

// Setup
void setup() {

  // Setup Keyboard
  setupKeyboard();

  // Mozzi Start
  startMozzi( CONTROL_RATE );
  // Sets Attack and Decay Levels; assumes Sustain, Decay, and Idle times
  envelope1.setADLevels(200,200);
  // Sets Decay time in milliseconds
  envelope1.setDecayTime(100);
  // Sustain Time setting for envelope1
  envelope1.setSustainTime(32500);
  
}

——

People can contact us: https://www.donluc.com/?page_id=1927

Technology Experience

  • Single-Board Microcontrollers (PIC, Arduino, Raspberry Pi,Espressif, etc…)
  • IoT
  • Robotics
  • Camera and Video Capture Receiver Stationary, Wheel/Tank and Underwater Vehicle
  • Unmanned Vehicles Terrestrial and Marine
  • Research & Development (R & D)

Instructor and E-Mentor

  • IoT
  • PIC Microcontrollers
  • Arduino
  • Raspberry Pi
  • Espressif
  • Robotics

Follow Us

J. Luc Paquin – Curriculum Vitae – 2022 English & Español
https://www.jlpconsultants.com/luc/

Web: https://www.donluc.com/
Web: https://www.jlpconsultants.com/
Facebook: https://www.facebook.com/neosteam.labs.9/
YouTube: https://www.youtube.com/channel/UC5eRjrGn1CqkkGfZy0jxEdA
Twitter: https://twitter.com/labs_steam
Pinterest: https://www.pinterest.com/NeoSteamLabs/
Instagram: https://www.instagram.com/neosteamlabs/

Don Luc

Project #22: Synthesizer – Harmonics – Mk05

——

#DonLucElectronics #DonLuc #Synthesizer #UltrasonicSynth #Mozzi #Arduino #ArduinoProMini #Project #Fritzing #Programming #Electronics #Microcontrollers #Consultant

——

Harmonics

——

Harmonics

——

Harmonics

——

Harmonics – Brightness

Nearly all signals contain energy at harmonic frequencies, in addition to the energy at the fundamental frequency. If it contains all the energy in a signal at the fundamental frequency, then that signal is a perfect sine wave. If the signal is not a perfect sine wave, then some energy is contained in the harmonics. Some waveforms contain large amounts of energy at harmonic frequencies.

Ratio

So in the harmonic series, we have a fundamental (pitch/note) and a succession of harmonics that stem from the fundamental which also hold other pitches within themselves.

Arduino – Map

map(value, fromLow, fromHigh, toLow, toHigh)

Re-maps a number from one range to another. That is, a value of fromLow would get mapped to toLow, a value of fromHigh to toHigh, values in-between to values in-between, etc…

DL2206Mk03

1 x Arduino Pro Mini 328 – 5V/16MHz
2 x HC-SR04 Ultrasonic Sensor
2 x 1M Ohm Potentiometer
2 x Knob
1 x Audio Jack 3.5mm
1 x SparkFun Audio Jack Breakout
1 x SparkFun USB Mini-B Breakout
1 x SPDT Slide Switch
1 x JST Jumper 2 Wire Connector
1 x JST Jumper 3 Wire Connector
1 x Insignia Speakers
1 x SparkFun Solderable Breadboard – Large
1 x SparkFun FTDI Basic Breakout – 5V
1 x SparkFun Cerberus USB Cable

Arduino Pro Mini 328 – 5V/16MHz

Ech – Digital 13
Tri – Digital 12
EcR – Digital 11
TrR – Digital 10
SPK – Digital 9
CAP – Analog A0
CAH – Analog A1
VIN – +5V
GND – GND

——

DL2206Mk03p.ino

/* ***** Don Luc Electronics © *****
Software Version Information
Project #22: Synthesizer - Harmonics - Mk05
22-05
DL2206Mk03p.ino
1 x Arduino Pro Mini 328 - 5V/16MHz
2 x HC-SR04 Ultrasonic Sensor
2 x 1M Ohm Potentiometer
2 x Knob
1 x Audio Jack 3.5mm
1 x SparkFun Audio Jack Breakout
1 x SparkFun USB Mini-B Breakout
1 x SPDT Slide Switch
1 x JST Jumper 2 Wire Connector
1 x JST Jumper 3 Wire Connector
1 x Insignia Speakers
1 x SparkFun Solderable Breadboard - Large
1 x SparkFun FTDI Basic Breakout - 5V
1 x SparkFun Cerberus USB Cable
*/

// Include the Library Code
// Mozzi
#include <MozziGuts.h>
// Oscillator
#include <Oscil.h>
// Table for Oscils to play
#include <tables/cos2048_int8.h>
// Smoothing Control
#include <Smooth.h>
// Maps unpredictable inputs to a range
#include <AutoMap.h>

// Desired carrier frequency max and min, for AutoMap
const int MIN_CARRIER_FREQ = 22;
const int MAX_CARRIER_FREQ = 440;

// 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;

// Maps unpredictable inputs to a range
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);

// Set the input for the knob to analog pin 0
const int KNOB_PIN = A0;
// Set the analog input for fm_intensity
int LDR1_PIN;
// Set the analog input for mod rate
int LDR2_PIN;

// Table for Oscils to play
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);

// Harmonics (Brightness)
int iModRatio = A1;
int mod_ratio;
// Carries control info from updateControl to updateAudio
long fm_intensity;

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

// Trigger pin 12 to pitch distance sensor
const int iTrigPitch = 12;
// Echo Receive pin 13 to pitch distance sensor
const int iEchoPitch = 13;
// Define the useable range of the pitch sensor
const int pitchLowThreshold = 45;
const int pitchHighThreshold = 2;    
// Stores the distance measured by the distance sensor
float distance = 0;
// Trigger pin 10 to rate distance sensor
const int iTrigRate = 10;
// Echo Receive pin 13 to pitch distance sensor
const int iEchoRate = 11;
// Define the useable range of the pitch sensor
const int rateLowThreshold = 45;
const int rateHighThreshold = 2;    
// Stores the distance measured by the distance sensor
float rate = 0;

// Mini Speaker
int SPK = 9;

// Software Version Information
String sver = "22-05";

void loop() {

  // Audio Hook
  audioHook();
  
}

getHC-SR04.ino

// HC-SR04 Ultrasonic Sensor
// Setup HC-SR04
void setupHCSR04() {

  // The trigger iTrig Pitch will output pulses of electricity
  pinMode(iTrigPitch, OUTPUT);
  // The echo iEcho will measure the duration of pulses coming back from the distance sensor
  pinMode(iEchoPitch, INPUT);

  // The trigger iTrig Rate will output pulses of electricity
  pinMode(iTrigRate, OUTPUT);
  // The echo iEcho will measure the duration of pulses coming back from the distance sensor
  pinMode(iEchoRate, INPUT);
  
}
// Distance
float isDistance() {
  
  // Variable to store the time it takes for a ping to bounce off an object
  float echoTime;
  // Variable to store the distance calculated from the echo time
  float calculatedDistance;

  // Send out an ultrasonic pulse that's 10ms long
  digitalWrite(iTrigPitch, HIGH);
  delayMicroseconds(10);
  digitalWrite(iTrigPitch, LOW);

  // Use the pulseIn command to see how long it takes for the
  // pulse to bounce back to the sensor
  echoTime = pulseIn(iEchoPitch, HIGH);

  // Calculate the distance of the object that reflected the pulse
  // (half the bounce time multiplied by the speed of sound)
  calculatedDistance = echoTime * 0.034 / 2;

  // Send back the distance that was calculated
  return calculatedDistance;
  
}
// Rate
float isRate() {
  
  // Variable to store the time it takes for a ping to bounce off an object
  float echoTime;
  // Variable to store the distance calculated from the echo time
  float calculatedDistance;

  // Send out an ultrasonic pulse that's 10ms long
  digitalWrite(iTrigRate, HIGH);
  delayMicroseconds(10);
  digitalWrite(iTrigRate, LOW);

  // Use the pulseIn command to see how long it takes for the
  // pulse to bounce back to the sensor
  echoTime = pulseIn(iEchoRate, HIGH);

  // Calculate the distance of the object that reflected the pulse
  // (half the bounce time multiplied by the speed of sound)
  // cm = 58.0
  calculatedDistance = echoTime * 0.034 / 2;

  // Send back the distance that was calculated
  return calculatedDistance;
  
}

getMozzi.ino

// Mozzi
// Update Control
void updateControl(){

  // Variable to store the distance measured by the sensor
  distance = isDistance();
  // Low Threshold
  if ( distance >= pitchLowThreshold) {

    // pitchLowThreshold
    distance = pitchLowThreshold;
    
  }
  // High Threshold
  if ( distance < pitchHighThreshold){
    
    // pitchHighThreshold
    distance = pitchHighThreshold;
    
  }

  // Variable to store the distance measured by the sensor
  rate = isRate();
  // Low Threshold
  if ( rate >= rateLowThreshold) {

    // rateLowThreshold
    rate = rateLowThreshold;
    
  }
  // High Threshold
  if ( rate < rateHighThreshold){
    
    // rateHighThreshold
    rate = rateHighThreshold;
    
  }

  // Map
  distance = map(distance, 45, 2, 0, 1023);
  rate = map(rate, 45, 2, 0, 1023);
  
  // Read the knob
  // Value is 0-1023
  int knob_value = mozziAnalogRead(KNOB_PIN);

  // Read the mod_ratio
  // Value is 0-1023
  mod_ratio = mozziAnalogRead(iModRatio);

  // Map
  mod_ratio = map(mod_ratio, 0, 1023, 2, 15);

  // 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;

  // Set the FM oscillator frequencies
  aCarrier.setFreq(carrier_freq);
  aModulator.setFreq(mod_freq);

  // Read the light dependent resistor on the width
  LDR1_PIN = distance;
  int LDR1_value = LDR1_PIN;

  int LDR1_calibrated = kMapIntensity(LDR1_value);

  // Calculate the fm_intensity
  // Shift back to range after 8 bit multiply
  fm_intensity = ((long)LDR1_calibrated * (kIntensityMod.next()+128))>>8;
  
  // Read the light dependent resistor on the speed
  LDR2_PIN = rate;
  int LDR2_value= LDR2_PIN;

  // Use a float here for low frequencies
  float mod_speed = (float)kMapModSpeed(LDR2_value)/1000;

  kIntensityMod.setFreq(mod_speed);
  
}
// Update Audio
int updateAudio()
{

  // Update Audio
  long modulation = aSmoothIntensity.next(fm_intensity) * aModulator.next();
  return aCarrier.phMod(modulation);

}

setup.ino

// Setup
void setup() {

  // Setup HC-SR04
  setupHCSR04();

  // Delay
  delay( 200 );

  // Mozzi Start
  startMozzi();

}

——

People can contact us: https://www.donluc.com/?page_id=1927

Technology Experience

  • Single-Board Microcontrollers (PIC, Arduino, Raspberry Pi,Espressif, etc…)
  • IoT
  • Robotics
  • Camera and Video Capture Receiver Stationary, Wheel/Tank and Underwater Vehicle
  • Unmanned Vehicles Terrestrial and Marine
  • Research & Development (R & D)

Instructor and E-Mentor

  • IoT
  • PIC Microcontrollers
  • Arduino
  • Raspberry Pi
  • Espressif
  • Robotics

Follow Us

J. Luc Paquin – Curriculum Vitae – 2022 English & Español
https://www.jlpconsultants.com/luc/

Web: https://www.donluc.com/
Web: https://www.jlpconsultants.com/
Facebook: https://www.facebook.com/neosteam.labs.9/
YouTube: https://www.youtube.com/channel/UC5eRjrGn1CqkkGfZy0jxEdA
Twitter: https://twitter.com/labs_steam
Pinterest: https://www.pinterest.com/NeoSteamLabs/
Instagram: https://www.instagram.com/neosteamlabs/

Don Luc

Project #22: Synthesizer – Solderable Breadboard – Large – Mk04

——

#DonLucElectronics #DonLuc #Synthesizer #UltrasonicSynth #Arduino #ArduinoProMini #Project #Fritzing #Programming #Electronics #Microcontrollers #Consultant

——

Solderable Breadboard

——

Solderable Breadboard

——

Solderable Breadboard

——

SparkFun Solderable Breadboard – Large

This is the Large SparkFun Solderable Breadboard. A bare PCB that is the exact size as our full-size breadboard with the same connections to pins and power rails. This board is especially useful for preserving a prototype or experiment you just created on a solderless breadboard by soldering all the pieces in place. The large solderable breadboard also includes real estate for screw terminal connectors and a trace down the center gutter for ground.

DL2206Mk02

1 x Arduino Pro Mini 328 – 5V/16MHz
2 x HC-SR04 Ultrasonic Sensor
1 x 1M Ohm Potentiometer
1 x Knob
1 x Audio Jack 3.5mm
1 x SparkFun Audio Jack Breakout
1 x SparkFun USB Mini-B Breakout
1 x SPDT Slide Switch
1 x JST Jumper 2 Wire Connector
1 x JST Jumper 3 Wire Connector
1 x Insignia Speakers
1 x SparkFun Solderable Breadboard – Large
1 x SparkFun FTDI Basic Breakout – 5V
1 x SparkFun Cerberus USB Cable

Arduino Pro Mini 328 – 5V/16MHz

Ech – Digital 13
Tri – Digital 12
EcR – Digital 11
TrR – Digital 10
SPK – Digital 9
CAP – Analog A0
VIN – +5V
GND – GND

——

DL2206Mk02p.ino

/* ***** Don Luc Electronics © *****
Software Version Information
Project #22: Synthesizer - Solderable Breadboard - Large - Mk04
22-04
DL2206Mk02p.ino
1 x Arduino Pro Mini 328 - 5V/16MHz
2 x HC-SR04 Ultrasonic Sensor
1 x 1M Ohm Potentiometer
1 x Knob
1 x Audio Jack 3.5mm
1 x SparkFun Audio Jack Breakout
1 x SparkFun USB Mini-B Breakout
1 x SPDT Slide Switch
1 x JST Jumper 2 Wire Connector
1 x JST Jumper 3 Wire Connector
1 x Insignia Speakers
1 x SparkFun Solderable Breadboard - Large
1 x SparkFun FTDI Basic Breakout - 5V
1 x SparkFun Cerberus USB Cable
*/

// Include the Library Code
// Mozzi
#include <MozziGuts.h>
// Oscillator
#include <Oscil.h>
// Table for Oscils to play
#include <tables/cos2048_int8.h>
// Smoothing Control
#include <Smooth.h>
// Maps unpredictable inputs to a range
#include <AutoMap.h>

// Desired carrier frequency max and min, for AutoMap
const int MIN_CARRIER_FREQ = 22;
const int MAX_CARRIER_FREQ = 440;

// 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;

// Maps unpredictable inputs to a range
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);

// Set the input for the knob to analog pin 0
const int KNOB_PIN = A0;
// Set the analog input for fm_intensity
int LDR1_PIN;
// Set the analog input for mod rate
int LDR2_PIN;

// Table for Oscils to play
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);

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

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

// Trigger pin 12 to pitch distance sensor
const int iTrigPitch = 12;
// Echo Receive pin 13 to pitch distance sensor
const int iEchoPitch = 13;
// Define the useable range of the pitch sensor
const int pitchLowThreshold = 45;
const int pitchHighThreshold = 2;    
// Stores the distance measured by the distance sensor
float distance = 0;
// Trigger pin 10 to rate distance sensor
const int iTrigRate = 10;
// Echo Receive pin 13 to pitch distance sensor
const int iEchoRate = 11;
// Define the useable range of the pitch sensor
const int rateLowThreshold = 45;
const int rateHighThreshold = 2;    
// Stores the distance measured by the distance sensor
float rate = 0;

// Mini Speaker
int SPK = 9;

// Software Version Information
String sver = "22-04";

void loop() {

  // Audio Hook
  audioHook();
  
}

getHC-SR04.ino

// HC-SR04 Ultrasonic Sensor
// Setup HC-SR04
void setupHCSR04() {

  // The trigger iTrig Pitch will output pulses of electricity
  pinMode(iTrigPitch, OUTPUT);
  // The echo iEcho will measure the duration of pulses coming back from the distance sensor
  pinMode(iEchoPitch, INPUT);

  // The trigger iTrig Rate will output pulses of electricity
  pinMode(iTrigRate, OUTPUT);
  // The echo iEcho will measure the duration of pulses coming back from the distance sensor
  pinMode(iEchoRate, INPUT);
  
}
// Distance
float isDistance() {
  
  // Variable to store the time it takes for a ping to bounce off an object
  float echoTime;
  // Variable to store the distance calculated from the echo time
  float calculatedDistance;

  // Send out an ultrasonic pulse that's 10ms long
  digitalWrite(iTrigPitch, HIGH);
  delayMicroseconds(10);
  digitalWrite(iTrigPitch, LOW);

  // Use the pulseIn command to see how long it takes for the
  // pulse to bounce back to the sensor
  echoTime = pulseIn(iEchoPitch, HIGH);

  // Calculate the distance of the object that reflected the pulse
  // (half the bounce time multiplied by the speed of sound)
  calculatedDistance = echoTime * 0.034 / 2;

  // Send back the distance that was calculated
  return calculatedDistance;
  
}
// Rate
float isRate() {
  
  // Variable to store the time it takes for a ping to bounce off an object
  float echoTime;
  // Variable to store the distance calculated from the echo time
  float calculatedDistance;

  // Send out an ultrasonic pulse that's 10ms long
  digitalWrite(iTrigRate, HIGH);
  delayMicroseconds(10);
  digitalWrite(iTrigRate, LOW);

  // Use the pulseIn command to see how long it takes for the
  // pulse to bounce back to the sensor
  echoTime = pulseIn(iEchoRate, HIGH);

  // Calculate the distance of the object that reflected the pulse
  // (half the bounce time multiplied by the speed of sound)
  // cm = 58.0
  calculatedDistance = echoTime * 0.034 / 2;

  // Send back the distance that was calculated
  return calculatedDistance;
  
}

getMozzi.ino

// Mozzi
// Update Control
void updateControl(){

  // Variable to store the distance measured by the sensor
  distance = isDistance();
  // Low Threshold
  if ( distance >= pitchLowThreshold) {

    // pitchLowThreshold
    distance = pitchLowThreshold;
    
  }
  // High Threshold
  if ( distance < pitchHighThreshold){
    
    // pitchHighThreshold
    distance = pitchHighThreshold;
    
  }

  // Variable to store the distance measured by the sensor
  rate = isRate();
  // Low Threshold
  if ( rate >= rateLowThreshold) {

    // rateLowThreshold
    rate = rateLowThreshold;
    
  }
  // High Threshold
  if ( rate < rateHighThreshold){
    
    // rateHighThreshold
    rate = rateHighThreshold;
    
  }

  // Read the knob
  // Value is 0-1023
  int knob_value = mozziAnalogRead(KNOB_PIN);

  // 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;

  // Set the FM oscillator frequencies
  aCarrier.setFreq(carrier_freq);
  aModulator.setFreq(mod_freq);

  // Read the light dependent resistor on the width
  LDR1_PIN = distance;
  int LDR1_value = LDR1_PIN;

  int LDR1_calibrated = kMapIntensity(LDR1_value);

  // Calculate the fm_intensity
  // Shift back to range after 8 bit multiply
  fm_intensity = ((long)LDR1_calibrated * (kIntensityMod.next()+128))>>8;
  
  // Read the light dependent resistor on the speed
  LDR2_PIN = rate;
  int LDR2_value= LDR2_PIN;

  // Use a float here for low frequencies
  float mod_speed = (float)kMapModSpeed(LDR2_value)/1000;

  kIntensityMod.setFreq(mod_speed);
  
}
// Update Audio
int updateAudio()
{

  // Update Audio
  long modulation = aSmoothIntensity.next(fm_intensity) * aModulator.next();
  return aCarrier.phMod(modulation);

}

setup.ino

// Setup
void setup() {

  // Setup HC-SR04
  setupHCSR04();

  // Delay
  delay( 200 );

  // Mozzi Start
  startMozzi();

}

——

People can contact us: https://www.donluc.com/?page_id=1927

Technology Experience

  • Single-Board Microcontrollers (PIC, Arduino, Raspberry Pi,Espressif, etc…)
  • IoT
  • Robotics
  • Camera and Video Capture Receiver Stationary, Wheel/Tank and Underwater Vehicle
  • Unmanned Vehicles Terrestrial and Marine
  • Research & Development (R & D)

Instructor and E-Mentor

  • IoT
  • PIC Microcontrollers
  • Arduino
  • Raspberry Pi
  • Espressif
  • Robotics

Follow Us

J. Luc Paquin – Curriculum Vitae – 2022 English & Español
https://www.jlpconsultants.com/luc/

Web: https://www.donluc.com/
Web: https://www.jlpconsultants.com/
Facebook: https://www.facebook.com/neosteam.labs.9/
YouTube: https://www.youtube.com/channel/UC5eRjrGn1CqkkGfZy0jxEdA
Twitter: https://twitter.com/labs_steam
Pinterest: https://www.pinterest.com/NeoSteamLabs/
Instagram: https://www.instagram.com/neosteamlabs/

Don Luc

Categories
Archives