This Arduino-based 4 step sequencer uses the popular Auduino code as synthesiser, with some simple additions to add a sequencer to the code (see below). When i was experimenting with the Atari Punk Console 8-step sequencer described here, i was not too impressed with the sound and remembered the Auduino. So i went back to the Auduino to build my sequencer. Here’s how it sounds:

The original Auduino has 5 potentiometers to modify its sound. One of them is SYNC_CONTROL which controls the base pitch of the sound. I started with a standard Arduino UNO, which only has 6 analog inputs. So i could only use 1 potentiometer per step, for the pitch, and keep the other 4 Auduino parameters constant for the 4 steps. I also needed one potentiometer for the tempo, so only 1 left for extra Auduino effects, which i decided to connect to GAIN_FREQ_CONTROL. For the other 3 parameters that are controlled by a potentiometer on the original Auduino, i used a constant.

So my first prototype on a breadboard had 6 potentiometers (pitch for 4 steps, effect, tempo), and 4 LEDs, connected to an Arduino UNO. I connected the output to a simple speaker.

Next step was to put the pots in a nice laser cut panel with soldered connections, and i also added a small mono amplifier to drive a larger speaker, with a volume pot. This speaker is a little damaged so the Auduino sounds is not as pure as usual, but it adds character.

img_20160906_090337828_hdr

I switched to an Arduino Nano that easily fits onto a breadboard. By now i was hooked to this little instrument so i decided to put it in a nice permanent laser cut box. I swapped the breadboard for a perf board and soldered female headers to it for the Arduino Nano. The (mono) output pin goes over a 150Ω resistor to a 3.5mm jack connection to plug it into any type of external speaker. It also goes through a 10KΩ volume pot and a capacitor to filter out the DC, as input for the small mono amplifier. This amplifier, connected to the internal speaker, can be powered on/off with a switch on the panel.

img_20160908_111445026

Then i fixed the LEDs, amplifier, and connectors with hot glue and put the box together. The Arduino and amplifier are powered by a mini USB cable connected to the Arduino, so it works with any USB power supply, such as a powerbank. The tabs have a very close fit so it looks like i won’t need any glue to hold the box together.

img_20160908_112309941

And with some colourful knobs i had laying around:

img_20160916_125753362_hdr

And i made a custom PCB for this project, and got some of my kid students to make their own box at DSL.

image1

And i made a PCB for this project, based on below schematics.

IMG_20180101_164454 - Edited

4stepseq

note: R2 should not be 10K as on the schematics; i found 220Ω works well with above amplifier

IMG_20180301_095104

IMG_20180214_083026

/*
 Auduino, the Lo-Fi granular synthesiser https://code.google.com/archive/p/tinkerit/downloads
 added a 4 step sequencer inspired by https://learn.sparkfun.com/tutorials/build-an-auduino-step-sequencer
 Tom Tobback Sep 2016
 BuffaloLabs www.cassiopeia.hk/kids

 LICENSE:
 Copyright (c) 2016 Tom Tobback 

 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

/* analog inputs:
 * A0 pitch step 1 (syncPhaseInc)
 * A1 pitch step 2
 * A2 pitch step 3
 * A3 pitch step 4
 * A4 tempo
 * A5 effect (grainPhaseInc)
 * plus volume potentiometer
 *
 * audio out via 220 ohm resistor to 3.5mm jack
 * audio out via 10K/10K voltage divider and 10K volume pot and 10uF cap to internal mono amp with speaker
 * power switch on amp
 * built with Arduino Nano on perf board powered by USB cable
 */

#include <avr/io.h>
 #include <avr/interrupt.h>

uint16_t syncPhaseAcc;
 uint16_t syncPhaseInc;
 uint16_t grainPhaseAcc;
 uint16_t grainPhaseInc;
 uint16_t grainAmp;
 uint8_t grainDecay;
 uint16_t grain2PhaseAcc;
 uint16_t grain2PhaseInc;
 uint16_t grain2Amp;
 uint8_t grain2Decay;

// Changing these will also requires rewriting audioOn()

#if defined(__AVR_ATmega8__)
 //
 // On old ATmega8 boards.
 // Output is on pin 11
 //
 #define LED_PIN 13
 #define LED_PORT PORTB
 #define LED_BIT 5
 #define PWM_PIN 11
 #define PWM_VALUE OCR2
 #define PWM_INTERRUPT TIMER2_OVF_vect
 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
 //
 // On the Arduino Mega
 // Output is on pin 3
 //
 #define LED_PIN 13
 #define LED_PORT PORTB
 #define LED_BIT 7
 #define PWM_PIN 3
 #define PWM_VALUE OCR3C
 #define PWM_INTERRUPT TIMER3_OVF_vect
 #else
 //
 // For modern ATmega168 and ATmega328 boards
 // Output is on pin 3
 //
 #define PWM_PIN 3
 #define PWM_VALUE OCR2B
 #define LED_PIN 13
 #define LED_PORT PORTB
 #define LED_BIT 5
 #define PWM_INTERRUPT TIMER2_OVF_vect
 #endif

// Smooth logarithmic mapping
 //
 uint16_t antilogTable[] = {
 64830, 64132, 63441, 62757, 62081, 61413, 60751, 60097, 59449, 58809, 58176, 57549, 56929, 56316, 55709, 55109,
 54515, 53928, 53347, 52773, 52204, 51642, 51085, 50535, 49991, 49452, 48920, 48393, 47871, 47356, 46846, 46341,
 45842, 45348, 44859, 44376, 43898, 43425, 42958, 42495, 42037, 41584, 41136, 40693, 40255, 39821, 39392, 38968,
 38548, 38133, 37722, 37316, 36914, 36516, 36123, 35734, 35349, 34968, 34591, 34219, 33850, 33486, 33125, 32768
 };
 uint16_t mapPhaseInc(uint16_t input) {
 return (antilogTable[input & 0x3f]) >> (input >> 6);
 }

// Stepped chromatic mapping
 //
 uint16_t midiTable[] = {
 17, 18, 19, 20, 22, 23, 24, 26, 27, 29, 31, 32, 34, 36, 38, 41, 43, 46, 48, 51, 54, 58, 61, 65, 69, 73,
 77, 82, 86, 92, 97, 103, 109, 115, 122, 129, 137, 145, 154, 163, 173, 183, 194, 206, 218, 231,
 244, 259, 274, 291, 308, 326, 346, 366, 388, 411, 435, 461, 489, 518, 549, 581, 616, 652, 691,
 732, 776, 822, 871, 923, 978, 1036, 1097, 1163, 1232, 1305, 1383, 1465, 1552, 1644, 1742,
 1845, 1955, 2071, 2195, 2325, 2463, 2610, 2765, 2930, 3104, 3288, 3484, 3691, 3910, 4143,
 4389, 4650, 4927, 5220, 5530, 5859, 6207, 6577, 6968, 7382, 7821, 8286, 8779, 9301, 9854,
 10440, 11060, 11718, 12415, 13153, 13935, 14764, 15642, 16572, 17557, 18601, 19708, 20879,
 22121, 23436, 24830, 26306
 };
 uint16_t mapMidi(uint16_t input) {
 return (midiTable[(1023 - input) >> 3]);
 }

// Stepped Pentatonic mapping
 //
 uint16_t pentatonicTable[54] = {
 0, 19, 22, 26, 29, 32, 38, 43, 51, 58, 65, 77, 86, 103, 115, 129, 154, 173, 206, 231, 259, 308, 346,
 411, 461, 518, 616, 691, 822, 923, 1036, 1232, 1383, 1644, 1845, 2071, 2463, 2765, 3288,
 3691, 4143, 4927, 5530, 6577, 7382, 8286, 9854, 11060, 13153, 14764, 16572, 19708, 22121, 26306
 };

uint16_t mapPentatonic(uint16_t input) {
 uint8_t value = (1023 - input) / (1024 / 53);
 return (pentatonicTable[value]);
 }

void audioOn() {
 #if defined(__AVR_ATmega8__)
 // ATmega8 has different registers
 TCCR2 = _BV(WGM20) | _BV(COM21) | _BV(CS20);
 TIMSK = _BV(TOIE2);
 #elif defined(__AVR_ATmega1280__)
 TCCR3A = _BV(COM3C1) | _BV(WGM30);
 TCCR3B = _BV(CS30);
 TIMSK3 = _BV(TOIE3);
 #else
 // Set up PWM to 31.25kHz, phase accurate
 TCCR2A = _BV(COM2B1) | _BV(WGM20);
 TCCR2B = _BV(CS20);
 TIMSK2 = _BV(TOIE2);
 #endif
 }

long counter = 0;
 long tempo;
 int pattern = 0;

const byte pat0 = 4;
 const byte pat1 = 5;
 const byte pat2 = 6;
 const byte pat3 = 7;

void setup() {
 pinMode(PWM_PIN, OUTPUT);
 audioOn();
 pinMode(LED_PIN, OUTPUT);

pinMode(pat0, OUTPUT);
 pinMode(pat1, OUTPUT);
 pinMode(pat2, OUTPUT);
 pinMode(pat3, OUTPUT);
 digitalWrite(pat0, LOW);
 digitalWrite(pat1, LOW);
 digitalWrite(pat2, LOW);
 digitalWrite(pat3, LOW);

// presets for 3 less important pots
 grainDecay = 200 / 8;
 grain2PhaseInc = mapPhaseInc(200) / 2;
 grain2Decay = 200 / 4;
 }

void loop() {

tempo = map(analogRead(A4), 0, 1023, 100, 4000);
 counter++;
 if (counter > tempo) {
 counter = 0;
 if (pattern == 4) {
 pattern = 0;
 }
 switch (pattern) {
 case 0:
 syncPhaseInc = mapPentatonic(analogRead(A0));
 digitalWrite(pat3, LOW);
 digitalWrite(pat0, HIGH);
 break;
 case 1:
 syncPhaseInc = mapPentatonic(analogRead(A1));
 digitalWrite(pat0, LOW);
 digitalWrite(pat1, HIGH);
 break;
 case 2:
 syncPhaseInc = mapPentatonic(analogRead(A2));
 digitalWrite(pat1, LOW);
 digitalWrite(pat2, HIGH);
 break;
 case 3:
 syncPhaseInc = mapPentatonic(analogRead(A3));
 digitalWrite(pat2, LOW);
 digitalWrite(pat3, HIGH);
 break;
 }

grainPhaseInc = mapPhaseInc(analogRead(A5)) / 2;
 pattern++;
 }
 }

SIGNAL(PWM_INTERRUPT)
 {
 uint8_t value;
 uint16_t output;

syncPhaseAcc += syncPhaseInc;
 if (syncPhaseAcc < syncPhaseInc) {
 // Time to start the next grain
 grainPhaseAcc = 0;
 grainAmp = 0x7fff;
 grain2PhaseAcc = 0;
 grain2Amp = 0x7fff;
 LED_PORT ^= 1 << LED_BIT; // Faster than using digitalWrite } // Increment the phase of the grain oscillators grainPhaseAcc += grainPhaseInc; grain2PhaseAcc += grain2PhaseInc; // Convert phase into a triangle wave value = (grainPhaseAcc >> 7) & 0xff;
 if (grainPhaseAcc & 0x8000) value = ~value;
 // Multiply by current grain amplitude to get sample
 output = value * (grainAmp >> 8);

// Repeat for second grain
 value = (grain2PhaseAcc >> 7) & 0xff;
 if (grain2PhaseAcc & 0x8000) value = ~value;
 output += value * (grain2Amp >> 8);

// Make the grain amplitudes decay by a factor every sample (exponential decay)
 grainAmp -= (grainAmp >> 8) * grainDecay;
 grain2Amp -= (grain2Amp >> 8) * grain2Decay;

// Scale output to the available range, clipping if necessary
 output >>= 9;
 if (output > 255) output = 255;

// Output to PWM (this is faster than using analogWrite)
 PWM_VALUE = output;
 }

Auduino 4-step sequencer

19 thoughts on “Auduino 4-step sequencer

  • Pingback:Made at DSL: Auduino 4-step sequencer | Dim Sum Labs

  • Pingback:ESP8266 portable Internet radio – Cassiopeia Ltd

  • 27/12/2017 at 10:10
    Permalink

    Please, send some kind of schematics.

    Reply
    • 01/01/2018 at 17:06
      Permalink

      hi, i have added the schematics

      Reply
  • 07/10/2018 at 06:45
    Permalink

    that youre doing these projects with the kids is awesome, keep up the good job, also killer module

    Reply
  • 23/01/2019 at 04:20
    Permalink

    Hey! I have built the awesome synthesizer you made, but somehow the effect potentio meter does not seem to work.. Also the sound of the speaker without amplifier is VERY low on PWM pin 3. Do you maybe have an idea how this can happen?

    Reply
    • 23/03/2019 at 14:20
      Permalink

      it depends on what kind of speaker you are using; with a piezo buzzer, or 8ohm 0.5W speaker it will have a decent sound
      for the effect pot, have a look at the original auduino, it has 4 effect parameters and i chose 1 of them, maybe you can get a better effect using another one

      Reply
      • 02/11/2019 at 08:49
        Permalink

        hi i have tried to replicate your project on arduino uno r3 clone. it works really well your work is amazing. i notice that on my arduino the pmw pin is 13 and the led on digital pin4,5,6,7. the only problem i have is that the 10k potentiometer on A5 has no effect on the sound. what can i do? thanks 🙂

        Reply
        • 04/11/2019 at 07:39
          Permalink

          hi, the output on D13 is intended for an LED; you may get some sound out of it, but better use pin D3 which has the Auduino-style audio signal, that will bring out the effect on A5

          Reply
  • Pingback:Best Arduino Project – DIY 4 Step Sequencer – DIY COMMUNITY

  • 24/12/2019 at 00:43
    Permalink

    Is it possible to replace the 4 potentiometers with 4 sensors that send an analog signal through a DAC?

    Reply
    • 03/02/2020 at 11:00
      Permalink

      hi, i think that could work, anything that generates a 0-5V signal on the analog inputs will work. i’m a bit confused with the DAC, do you want to use digital sensors? or you mean 4 digital sensors to create a 4-bit analog signal for 1 analog input channel?

      Reply
  • 23/09/2020 at 22:30
    Permalink

    Could you post Arduino circuit diagram of the project? Thank’s in advances.

    Reply
    • 09/11/2020 at 09:33
      Permalink

      Hi! Would also really appreciate a schematic for the Arduino version. Thanks so much for this tutorial! 🙂

      Reply
  • 24/06/2021 at 04:39
    Permalink

    Hello friend, thanks for the project.
    REALLY the sound is coming out through pin 13 and not through 3 as it should. I’ve tested some codes from the links you posted for other users and the sound ALWAYS comes out on pin 13, there’s something wrong! Didn’t you use a different version of the IDE from the current ones? What could be happening?
    sorry for my bad english, I’m Brazilian.
    thanks!

    Reply
    • 28/06/2021 at 16:36
      Permalink

      Hi, it’s possible that the pins are different; i think i started with an Arduino UNO, then used a NANO, and eventually a barebones Atmega328p on my PCB that i think i programmed as an Arduino Duemilanove, sorry for the confusion.

      Reply

Leave a Reply to Tom Cancel reply

Your email address will not be published. Required fields are marked *