EXAMPLE Arduino Template for Terrarium PCB

TGargasz

New member
C++:
/*
    Name:       TerrariumTemplate.ino - An Arduino template for PedalPCB Terrarium
    Created:    11/15/2020 10:30:38 AM
    Copyright (C) 2020  By: Tony Gargasz

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation version 3.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see https://www.gnu.org/licenses
*/

// Includes
#include <DaisyDSP.h>
#include <DaisyDuino.h>

// Instantiate Daisy Seed hardware
DaisyHardware hw;
size_t num_channels;
float sample_rate;

// Indetify Switch pins
const int footSw1 = D25;
const int footSw2 = D26;
const int toglSw1 = D8;
const int toglSw2 = D9;
const int toglSw3 = D10;
const int toglSw4 = D11;

// Identify Led pins
const int led1 = D22;
const int led2 = D23;

// Identify Knob pins
const int knob1 = A1;
const int knob2 = A2;
const int knob3 = A3;
const int knob4 = A4;
const int knob5 = A5;
const int knob6 = A6;

// Create vars for Knobs
float knob1val;
float knob2val;
float knob3val;
float knob4val;
float knob5val;
float knob6val;

// Create vars for non-blocking timer in loop()
unsigned long currentMillis;        // To set period to poll knobs and switches
unsigned long previousMillis = 0;   // Last time knobs and switches were polled
const long interval = 100;          // Interval at which to poll (milliseconds)

// Create vars for Examples
boolean footSw1_Enabled = true;
boolean footSw1_On = false;

void setup()
{
    // Setup Switches
    pinMode(footSw1, INPUT_PULLUP);
    pinMode(footSw2, INPUT_PULLUP);
    pinMode(toglSw1, INPUT_PULLUP);
    pinMode(toglSw2, INPUT_PULLUP);
    pinMode(toglSw3, INPUT_PULLUP);
    pinMode(toglSw4, INPUT_PULLUP);

    // Setup Leds
    pinMode(led1, OUTPUT);
    pinMode(led2, OUTPUT);

    // Initialize Daisy Seed audio at 48kHz
    hw = DAISY.init(DAISY_SEED, AUDIO_SR_48K);
    num_channels = hw.num_channels;
    sample_rate = DAISY.get_samplerate();
}

void loop()
{
    // Poll the hardware. Poll period is 100 ms and can be adjusted with var: interval
    currentMillis = millis();
    if (currentMillis - previousMillis >= interval)
    {
        // save the last poll time
        previousMillis = currentMillis;

        // ================== EXAMPLE - Footswitch and Led =====================
        // Footswitch is momentary so simulate a S/R latch
        if (digitalRead(footSw1))
        {
            if (footSw1_Enabled == true)
            {
                digitalWrite(led1, !(digitalRead(led1)));
                footSw1_Enabled = false;
            }
        }
        else
        {
            if (footSw1_Enabled == false)
            {
                footSw1_Enabled = true;
            }
        }
        if (digitalRead(led1) == HIGH)
        {
            footSw1_On = false;
        }
        else
        {
            footSw1_On = true;
        }

        // ================= EXAMPLE - Read Knobs (return range is 0 to 1023) =====================
        knob1val = analogRead(knob1);
        knob2val = analogRead(knob2);
    }
}
 
Last edited:
Finally built my Terrarium this past weekend.

This AM, I've got your template above built and running without a hassle, TGargasz. Thank you for putting this together!
 
Last edited:
Do you happen to have an example for a simple audio passthrough?

I've modified DaisyDuino.h and added a daisy_terrarium.h pin definitions file to make things easier to work with ... all seems well, but my attempt at a simple passthrough suggests I've got hardware/soldering problems that I need to debug.

I can share my modifications as well if you're up for sanity checking 'em.
 
Last edited:
I'm not sure if modifying DaisyDuino.h is a good idea since Electro-Smith is likely to update it if a future release and that will break your code. There's an example for bypass in the DaisyDuino library that works except it has a bug in that it swaps the 2 audio channels. E-S is aware of it and is working on a fix. All of my projects are mono so I created a solder bridge across physical pins 16 & 17 (Audio In 1 & Audio In 2), hence problem solved.

Bypass.jpg

// Title: bypass
// Description: Passes left and right in to left and right out
// Hardware: Daisy Seed
// Author: Stephen Hensley

#include "DaisyDuino.h"

DaisyHardware hw;

size_t num_channels;

void MyCallback(float **in, float **out, size_t size)
{
for (size_t i = 0; i < size; i++)
{
for (size_t chn = 0; chn < num_channels; chn++)
{
out[chn] = in[chn];
}
}
}

void setup() {
float samplerate;
// Initialize for Daisy pod at 48kHz
hw = DAISY.init(DAISY_SEED, AUDIO_SR_48K);
num_channels = hw.num_channels;
samplerate = DAISY.get_samplerate();

DAISY.begin(MyCallback);
}

void loop() {
}

 
Here's a Terrarium example that demonstrates a bypass function and an echo effect. You may find that one of the Footswitches or Leds works backwards and I programmed it that way to encourage experimentation with the code. I wish this sort of program was around when I was Noob with the Daisy Seed.

/*
Name: TerrariumBypassEcho.ino - An Arduino example for PedalPCB Terrarium
Created: 11/27/2020 05:30:00 AM
Copyright (C) 2020 By: Tony Gargasz

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see https://www.gnu.org/licenses
*/

// Includes
#include <DaisyDSP.h>
#include <DaisyDuino.h>

// Instantiate Daisy Seed hardware
DaisyHardware hw;
size_t num_channels;
float sample_rate;

// Indetify Switch pins
const int footSw1 = D25;
const int footSw2 = D26;
const int toglSw1 = D8;
const int toglSw2 = D9;
const int toglSw3 = D10;
const int toglSw4 = D11;

// Identify Led pins
const int led1 = D22;
const int led2 = D23;

// Idenify Knob pins
const int knob1 = A1;
const int knob2 = A2;
const int knob3 = A3;
const int knob4 = A4;
const int knob5 = A5;
const int knob6 = A6;

// Create vars for Knobs
float knob1val, prev_knob1val;
float knob2val, prev_knob2val;
float knob3val;
float knob4val;
float knob5val;
float knob6val;

// Create vars for non-blocking timer in loop()
unsigned long currentMillis; // To set period to poll knobs and switches
unsigned long previousMillis = 0; // Last time knobs and switches were polled
const long interval = 100; // Interval at which to poll (milliseconds)

// Create vars for Footswitches
boolean footSw1_Enabled = true;
boolean footSw1_On = false;
boolean footSw2_Enabled = true;
boolean footSw2_On = false;

float wet, out_buf, delay_adj, feedback_adj; // Various audio vars

#define MAX_DELAY static_cast<size_t>(48000) // Set Echo max delay time to 100% of samplerate (1 second)

// Instantiate Daisy Seed Effects
static DelayLine<float, MAX_DELAY> del; // Echo delay line

// Callback to process audio
void MyCallback(float** in, float** out, size_t size)
{
// Process the effects
for (size_t i = 0; i < size; i++)
{
// Read from I/O
out_buf = in[0];

// Bypass footswitch
if (footSw1_On != true)
{
// Echo footswitch
if (footSw2_On)
{ // ====================== Echo ===========================

// Read Wet from Delay Line
wet = del.Read();

// Write to Delay
del.Write((wet * feedback_adj) + out_buf);

// Send to I/O
out_buf = wet + out_buf;
}
}
// Note: Line level audio is mono and tied to both audio inputs
// Only Audio Out 2 is being used and Audio Out 1 is not connected
for (size_t chn = 0; chn < num_channels; chn++)
{
out[chn] = out_buf;
}
}
}

void setup()
{
// Setup Switches
pinMode(footSw1, INPUT_PULLUP);
pinMode(footSw2, INPUT_PULLUP);
pinMode(toglSw1, INPUT_PULLUP);
pinMode(toglSw2, INPUT_PULLUP);
pinMode(toglSw3, INPUT_PULLUP);
pinMode(toglSw4, INPUT_PULLUP);

// Setup Leds
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);

// Initialize Daisy Seed audio at 48kHz
hw = DAISY.init(DAISY_SEED, AUDIO_SR_48K);
num_channels = hw.num_channels;
sample_rate = DAISY.get_samplerate();

// Start Audio
DAISY.begin(MyCallback);
}

void loop()
{
// Poll the hardware. Poll period is 100 ms and can be adjusted with var: interval
currentMillis = millis();
if (currentMillis - previousMillis >= interval)
{
// save the last poll time
previousMillis = currentMillis;

// ========================== Footswitches and Leds ============================
// Footswitches are momentary so simulate a S/R latch
if (digitalRead(footSw1)) // Bypass Footswitch
{
if (footSw1_Enabled == true)
{
digitalWrite(led1, !(digitalRead(led1)));
footSw1_Enabled = false;
}
}
else
{
if (footSw1_Enabled == false)
{
footSw1_Enabled = true;
}
}
if (digitalRead(led1) == HIGH)
{
footSw1_On = false;
}
else
{
footSw1_On = true;
}

if (digitalRead(footSw2)) // Echo Footswitch
{
if (footSw2_Enabled == true)
{
digitalWrite(led2, !(digitalRead(led2)));
footSw2_Enabled = false;
}
}
else
{
if (footSw2_Enabled == false)
{
footSw2_Enabled = true;
}
}
if (digitalRead(led2) == HIGH)
{
footSw2_On = false;
}
else
{
footSw2_On = true;
}

// ================= Read Knobs (return range is 0 to 1023) ====================
knob1val = analogRead(knob1);
knob2val = analogRead(knob2);

// ========== Set only when knob 1 (Rate) position has changed ==============
if (abs(prev_knob1val - knob1val) > 5)
{
prev_knob1val = knob1val;

// Echo Delay time (in number of samples) 48 to 48000
delay_adj = map(knob1val, 0, 1023, (sample_rate / 1000), sample_rate);
del.Reset();
del.SetDelay(delay_adj);
}

// ========== Set only when knob 2 (Depth) position has changed =============
if (abs(prev_knob2val - knob2val) > 5)
{
prev_knob2val = knob2val;

// Number of Echo Feedback repeats multiplier Knob Scale: 0.00 to 0.95
feedback_adj = knob2val / 1075.00f;
}
}
}
 
Ok, thanks for these examples. Just wanted to be extra sure I'm using the audio callback as intended, and I am.
I've got output from the Terrarium from my code, just no input.
Guess I know what I'm doing this weekend now!
 
There's an example for bypass in the DaisyDuino library that works except it has a bug in that it swaps the 2 audio channels. E-S is aware of it and is working on a fix.

This was my problem. Thanks for pointing this out, not sure how I breezed by this key bit of info ( trying to do 10 things at once, perhaps... ).
All is well, and thank you again!
 
This was my problem. Thanks for pointing this out, not sure how I breezed by this key bit of info ( trying to do 10 things at once, perhaps... ).
All is well, and thank you again!
I'm glad that you found it. I can't tell you how many times I've spent hours overlooking the obvious!
 
Back
Top