Arduino AD help

From circuitbending to homebrew stompboxes & synths, keep the DIY spirit alive!

Moderators: Kent, luketeaford, lisa, Joe.

Post Reply
User avatar
snaper
Ultra Wiggler
Posts: 992
Joined: Mon Feb 10, 2014 12:29 am
Location: Magyarország

Arduino AD help

Post by snaper » Sat Sep 12, 2020 1:21 am

Hi Guys,

I have a module, it is a kinda mix between the Ardcore, the Euroduino and the Grains modules.
It can run Grains and Euroduino sketches with sligth modifications and I'm fairly happy with it.
But, I do not have an envelope generator...

I am really really n00b to Arduino, could you help me out?

So far, I have this ... yes, basically nothing :

int attack = map(analogRead(2), 0, 1023, 0, 255);
int decay = map(analogRead(3), 0, 1023, 0, 255);
int cv1 = AD envelope calculation, I assume?
analogWrite(cv1out, cv1);

I have the rest of the code up and running, clocking, etc., is OK, also, I have a DA, so I just need to make that calculation :(
Any ideas?

User avatar
guest
Super Deluxe Wiggler
Posts: 4519
Joined: Mon Aug 19, 2013 11:49 am

Re: Arduino AD help

Post by guest » Sat Sep 12, 2020 2:11 am

do you want linear or "exponential" envelopes?

also, what is the bit depth of your DAC? and which arduino platform are you running this on?
openmusiclabs.com

User avatar
guest
Super Deluxe Wiggler
Posts: 4519
Joined: Mon Aug 19, 2013 11:49 am

Re: Arduino AD help

Post by guest » Sat Sep 12, 2020 2:28 am

also, do you grab ADC samples at a fixed rate, and if so, what is that rate? and what range of AD times do you want?
openmusiclabs.com

User avatar
Hutenberger
Learning to Wiggle
Posts: 23
Joined: Tue Apr 28, 2020 1:52 am
Location: Munich, Germany
Contact:

Re: Arduino AD help

Post by Hutenberger » Sat Sep 12, 2020 3:05 am

In general, you need some sort of timer interrupt routine, in which you update the value of your DAC at a fixed sample rate.
An exponential envelope takes the last value of your Env and multiplies it with a "factor" (which is usually very close but a little smaller or bigger than 1.0, depending if it's attack or decay phase).
A linear envelope adds or subtracts a small "diff" value to your last value.
the values of "diff" or the "factor" depend on your samplerate and the positions of Attack and decay knobs.
Starting with a linear env is easier IMO.
Neuzeit Instruments
INSTAGRAM: @neuzeit_instruments

User avatar
Hutenberger
Learning to Wiggle
Posts: 23
Joined: Tue Apr 28, 2020 1:52 am
Location: Munich, Germany
Contact:

Re: Arduino AD help

Post by Hutenberger » Sat Sep 12, 2020 3:06 am

By the way, I see that you are trying to use "analog Write" which is simply Arduino's PWM. This is not going to work for a usable envelope, also with filtering behind it. PWM resolution too low, output signal noisy, etc... You should use a real DAC with at least 12 bits, and convert the signal to 0...8V afterwards with a noninverting op amp.
Neuzeit Instruments
INSTAGRAM: @neuzeit_instruments

User avatar
snaper
Ultra Wiggler
Posts: 992
Joined: Mon Feb 10, 2014 12:29 am
Location: Magyarország

Re: Arduino AD help

Post by snaper » Sat Sep 12, 2020 3:22 am

I'd go with exponentianl, but since I have two outputs, one could exponential and the other linear.
The DAC output is based on the Euroduino output :

The full code, without the AD part is here :

int clockIn = 8;
int clock_code = 0;
int cv1out = 5;

int clockState = LOW;
int lastClock = LOW;

void setup() {
Serial.begin(9600);
pinMode(clockIn, INPUT);
pinMode(cv1out, OUTPUT);
}

void loop() {
clockState = digitalRead(clockIn);
if (clockState != lastClock) {
if (clockState == HIGH) {
clock_code++;
int attack = map(analogRead(2), 0, 1023, 0, 255);
int decay = map(analogRead(3), 0, 1023, 0, 255);
int cv1 = THING;
analogWrite(cv1out, cv1);
{
delay(10);
}
lastClock = clockState;
}
}


It doesn't need to be accurate or perfect, the module s a fun little thing, with the usb port, it is really easy to replace the sketch on it.
Oh, it is an Arduino Nano.
You do not have the required permissions to view the files attached to this post.

User avatar
guest
Super Deluxe Wiggler
Posts: 4519
Joined: Mon Aug 19, 2013 11:49 am

Re: Arduino AD help

Post by guest » Sat Sep 12, 2020 4:09 am

ok, is it externally clocked, or is that just the trigger for the AD?

i wouldnt bother with the map function, that just eats up processing time. if you want to convert a 10b number to an 8b number, just shift it down by 2:

int outnumber = inputnumber >> 2;

you will need something to determine start/stop of the AD, so maybe make a variable that has that state. for example:

byte ADstate = 0; // initialize at beginning

if (ADstate == 0 && trigger == 1) {ADstate = 1;}
else if (ADstate == 1) { do attack code here, set to 2 when done}
else if (ADstate == 2) { do decay code here, set to 0 when done}

for now, you may want to just get something up and running and then make it better as you go. the quickest way to get something usable is to just add the ADC value to your output variable. this has a lot of downsides, but at least you will then see if the rest of your code works. the biggest downside here, is that you dont have much control over the output values. adding 1 gives a smooth and slow increase, but then adding 2 makes it go twice as fast and half as smooth, and by the time you get to just 10, youve lost a lot of resolution and its already 10x as fast, and youre no way near through your possible values. there are some solutions to this. one is to use an interim, higher resolution accumulator, and a lookup table that maps your input variable to a more reasonable set of values. the other option is to use your ADC value as your delay() time and always increment by 1. if you want to do more than just and AD with the chip, the latter option wont really work, or at least its more complicated to make it work as you cant use delay() as it blocks any other processing from happening.

for an RC style AD, you take the distance from where you are to where you are going, and multiply by your ADC value, and then add this to where you are. for example:

int outputvalue = current_value + (ADCvalue*(255 - current value) >> 8);

the shifting down by 8 is done to scale the result so it make sense. for example, if you get an adc value of 10, and you are currently at 100, you dont want to add 10*(255-100) = 1550, as that is bigger than the output (assuming 8b). so the largest values you will ever see is 255*(255-0), which, when down shifted by 8, makes 255.
openmusiclabs.com

User avatar
snaper
Ultra Wiggler
Posts: 992
Joined: Mon Feb 10, 2014 12:29 am
Location: Magyarország

Re: Arduino AD help

Post by snaper » Sat Sep 12, 2020 4:29 am

Externally clocked yes.
Whoah...

Literally chinese :(

User avatar
guest
Super Deluxe Wiggler
Posts: 4519
Joined: Mon Aug 19, 2013 11:49 am

Re: Arduino AD help

Post by guest » Sat Sep 12, 2020 12:20 pm

ok, if it is externally clocked (doesnt advance to the next AD level until a new pulse comes in), is there a second input that tells it when to start (the trigger)?

with any program, id suggest starting with a small bit and get that working first, and then add increasing functionality. so maybe just something that increments and then decrements your output with every clock pulse (basically a clock controlled oscillator). this will use the state code above, but just get rid of the 0 state, as it will never be off.

byte ADstate = 0; // initialize at beginning
int outputvalue = 0;

if (ADstate == 1) {
outputvalue++;
if (outputvalue == 255) ADstate = 2;
}
else if (ADstate == 2) {
outputvalue--;
if (outputvalue == 0) ADstate = 1;
}
openmusiclabs.com

Synthiq
Veteran Wiggler
Posts: 590
Joined: Mon Feb 06, 2017 3:10 pm
Location: California

Re: Arduino AD help

Post by Synthiq » Sat Sep 12, 2020 6:54 pm

The default PWM frequency for the Nano is just 490Hz so it would be a good idea to increase this frequency to reduce the ripple on the output signal. The PWM is normally also dubble-buffered so this is also the maximum frequency with which the output signal can be updated. There is a clock prescaler for the PWM timer set to divide-by-64 but can be set to divide-by-8 or divide-by-1 but will require some low level understanding of how the PWM block works.

The low PWM frequency also limits the bandwidth of the analog lowpass filter and therefore also the fastest attack time possible while keeping the ripple from the PWM frequency low.

User avatar
snaper
Ultra Wiggler
Posts: 992
Joined: Mon Feb 10, 2014 12:29 am
Location: Magyarország

Re: Arduino AD help

Post by snaper » Sun Sep 13, 2020 2:18 am

Unfortunately, this is way beyond me :(
Any of you is willing to help me out in private?
I have the module up and running, also, I have a few great sketches, I was able to convert a few Ardcore sketches, also Euroduino sketches and all of the Grains sketches, yet, I really need an AD and ADSR.
I have 4 CV inputs, so in theory it could be a dual AD or a single full cv ADSR :D

User avatar
guest
Super Deluxe Wiggler
Posts: 4519
Joined: Mon Aug 19, 2013 11:49 am

Re: Arduino AD help

Post by guest » Sun Sep 13, 2020 3:06 am

id reccomend doing a few tutorials first, just to get a hang of the language and how to structure the code.
openmusiclabs.com

Synthiq
Veteran Wiggler
Posts: 590
Joined: Mon Feb 06, 2017 3:10 pm
Location: California

Re: Arduino AD help

Post by Synthiq » Mon Sep 14, 2020 1:10 pm


Post Reply

Return to “Music Tech DIY”