electro-music.com   Dedicated to experimental electro-acoustic
and electronic music
 
    Front Page  |  Radio
 |  Media  |  Forum  |  Wiki  |  Links
Forum with support of Syndicator RSS
 FAQFAQ   CalendarCalendar   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   LinksLinks
 RegisterRegister   ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in  Chat RoomChat Room 
 Forum index » DIY Hardware and Software » Microcontrollers and Programmable Logic
Anyone working on an Arduino-based ADSR?
Post new topic   Reply to topic Moderators: State Machine
Page 1 of 1 [24 Posts]
View unread posts
View new posts in the last week
Mark the topic unread :: View previous topic :: View next topic
Author Message
reve



Joined: Feb 23, 2008
Posts: 149
Location: USA

PostPosted: Tue Nov 15, 2011 9:18 pm    Post subject: Anyone working on an Arduino-based ADSR? Reply with quote  Mark this post and the followings unread

EDIT: Now started. Code at https://github.com/rmosquito/PolyEGg

Hey everyone. I'm venturing into modular polyphony, and the Arduino route seems like a cost and labor effective route to achieve the dream of polyphonic envelope generators. That is to say, one set of ADSR knobs but independently triggered envelopes with eight gate ins and eight envelope outs.

I've hacked together some crap code that just checks micros() to come up with whether to increment or decrement based on gate and state... that gives me linear envelopes that work, but obviously not worth using with linear VCAs.

I assume I have to implement some sort of DDS routine to make it work well, but I don't really have the foggiest idea as to how to do that. So before... you know, trying to figure out how to do that it seemed wise to see if anyone had done this before me? I know T. Wiltshire used a similar scheme in his PIC-based EGs, but other than the lookup table that doesn't do me a lot of good since it's all in PIC assembly and I'm stupid. Smile

So! Anyone doing something similar?

Cheers!

_________________
- r. mosquito
SynthDIY Synthpop -> http://www.reverbnation.com/photovoltaik

Last edited by reve on Fri Mar 23, 2012 11:07 pm; edited 1 time in total
Back to top
View user's profile Send private message
comrade_zero



Joined: Mar 05, 2009
Posts: 66
Location: arizona
Audio files: 4

PostPosted: Wed Nov 16, 2011 10:40 pm    Post subject: Reply with quote  Mark this post and the followings unread

You are going to run into some issues using Arduino, but that is not to say you can't find a workable solution. Some things to remember: you are limited to positive voltages between 0 and 5. So unless you have a mehtod for scaling this will be what you've got. The Arduino uses Pulse Width Modulation for it's analog out pins, you will need a method of deriving continuous voltage from them (i.e. a passive low-pass filter).
If we assume that your four stage envelope represents three time bases (attack,decay,release) and 1 voltage level (sustain):
1)attack = a ramp from 0 to 5 volts in x amount of time where x is set via an analogRead pot value.
2)decay = a ramp from 5 to 3 (or whatever) volts in y amount of time where y is set via an analogRead pot value.
3)sustain = maintains a constant voltage (set by an analog pot) as long as a pulse is coming into the control pin.
4)release: voltage drops from sustain to zero in z amount of time as set by a pot.
the simplest way to set this up in code is with a switch statment, with the state incrementing as each stage is completed. Use the analogRead function on your pots along with the delayMicroseconds command to increase or decrease your time bases...
If you want to use this for polyphonic use, you can derive one envelope from your pot-reads, and, instead of using the pwm of the arduino you can use a digital pot, such as the AD5206, to generate your outputs. (you will still be limited to 5 volts)...
anyway, I hope some of these ideas help, if you have more questions I'd love to hear them, I've been playing with Arduino for a while now, and want to see more synth use gotten out of them...
cheers
c_z
Back to top
View user's profile Send private message
Pehr



Joined: Aug 14, 2005
Posts: 1307
Location: Björkvik, Sweden
Audio files: 2

PostPosted: Thu Nov 17, 2011 4:21 am    Post subject: Reply with quote  Mark this post and the followings unread

If you're using the PWM outputs you will not get as snappy envelopes as analog envelopes due to the low PWM frequency (~500 Hz).

For longer envelopes you will prob hear stepping due to that the PWM outputs is 8-bit.

Other than that, I think it's possible Very Happy

_________________
YouTube channel
flickr photostream
http://loxodrom.blogspot.com
http://www.garageband.com/artist/loxodrom
http://soundcloud.com/loxodrom
Back to top
View user's profile Send private message
Mongo1



Joined: Aug 11, 2011
Posts: 411
Location: Raleigh NC

PostPosted: Thu Nov 17, 2011 5:06 am    Post subject: Reply with quote  Mark this post and the followings unread

If the Neutron Shield becomes available. that would do most of what you want. It does all of the level translations and such.

Gary
Back to top
View user's profile Send private message Send e-mail
YashN



Joined: Jun 27, 2011
Posts: 104
Location: Canada

PostPosted: Fri Nov 18, 2011 1:48 am    Post subject: Reply with quote  Mark this post and the followings unread

Good to see other Arduino fans.

For lookup, you may check some normal Arduino code for oscillators - Adrian Freed for instance.

Additionally, have you checked out ArdCore?

http://20objects.com/ardcore/
Back to top
View user's profile Send private message
reve



Joined: Feb 23, 2008
Posts: 149
Location: USA

PostPosted: Fri Nov 18, 2011 9:51 pm    Post subject: Reply with quote  Mark this post and the followings unread

comrade_zero & pehr:

Yeah, c_z's proposal is pretty much how I have it set up now -- except I'm just checking a clock instead of calling delay() (to allow different envs to be triggered at different times). In production I'd kind of planned on using a discrete octal DAC to be able to do 0-10V without a separate gain stage as well as getting around the PWM limitations pehr noted. I mean, multiplexing the PWM out and then piping it to eight op amps might save me ten bucks but it'd be a bigger pain. But after looking at datasheets it looks like I might have to use a stack of opamps as buffers anyway to get the output impedance where it needs to be. Razz

YashN:

Yeah, I'd been on the waiting list for ArdCore boards -- I guess they went into production without me hearing. But their sketch gives a linear envelope, so it doesn't solve the immediate problem. :/ I have seen the Adrian Freed code (that pretty much every arduino DDS scheme is based off of, it seems) and while I get the gist of it (and could repurpose the exponential Wiltshire wave table), I'm not totally clear on how to translate that lookup routine into a single-shot scheme rather than a continuous loop --- other than pre-calculating the duration of the envelope, which seems rather processor intensive. Dunno how Wiltshire did it because I can't make heads or tails out of assembly. :/

Any suggestions are of course encouraged. Smile

_________________
- r. mosquito
SynthDIY Synthpop -> http://www.reverbnation.com/photovoltaik
Back to top
View user's profile Send private message
corex



Joined: Mar 02, 2010
Posts: 114
Location: Las Vegas

PostPosted: Tue Nov 29, 2011 2:54 pm    Post subject: Reply with quote  Mark this post and the followings unread

Pehr wrote:
If you're using the PWM outputs you will not get as snappy envelopes as analog envelopes due to the low PWM frequency (~500 Hz).

For longer envelopes you will prob hear stepping due to that the PWM outputs is 8-bit.


I've just used bare AVRs so I may be a little bit off-base, but aren't most Arduinos built around the ATmega328P? If so, this chip has a 16-bit PWM counter (Counter1) as well as an 8-bit counter (Counter0).

Additionally, the PWM counters can be clocked at system clock rates, therefore with a 20MHz crystal, shouldn't the 8-bit counter achieve rates of 20MHz / 2^8 ~= 78KHz? How did you derive this 500Hz figure? I think it may not be accurate.
Back to top
View user's profile Send private message
Mongo1



Joined: Aug 11, 2011
Posts: 411
Location: Raleigh NC

PostPosted: Tue Nov 29, 2011 2:58 pm    Post subject: Reply with quote  Mark this post and the followings unread

A basic Arduino uses something like 600 Hz as it's PWM frequency. You can definitely modify it, but you have to be careful about interfering with other timer functions and so on.

Gary
Back to top
View user's profile Send private message Send e-mail
Pehr



Joined: Aug 14, 2005
Posts: 1307
Location: Björkvik, Sweden
Audio files: 2

PostPosted: Tue Nov 29, 2011 3:35 pm    Post subject: Reply with quote  Mark this post and the followings unread

corex wrote:
Pehr wrote:
If you're using the PWM outputs you will not get as snappy envelopes as analog envelopes due to the low PWM frequency (~500 Hz).

For longer envelopes you will prob hear stepping due to that the PWM outputs is 8-bit.


I've just used bare AVRs so I may be a little bit off-base, but aren't most Arduinos built around the ATmega328P? If so, this chip has a 16-bit PWM counter (Counter1) as well as an 8-bit counter (Counter0).

Additionally, the PWM counters can be clocked at system clock rates, therefore with a 20MHz crystal, shouldn't the 8-bit counter achieve rates of 20MHz / 2^8 ~= 78KHz? How did you derive this 500Hz figure? I think it may not be accurate.


http://arduino.cc/en/Reference/AnalogWrite

Quote:
The frequency of the PWM signal is approximately 490 Hz.
[/quote]
_________________
YouTube channel
flickr photostream
http://loxodrom.blogspot.com
http://www.garageband.com/artist/loxodrom
http://soundcloud.com/loxodrom
Back to top
View user's profile Send private message
Pehr



Joined: Aug 14, 2005
Posts: 1307
Location: Björkvik, Sweden
Audio files: 2

PostPosted: Wed Nov 30, 2011 1:04 am    Post subject: Reply with quote  Mark this post and the followings unread

Pehr wrote:
http://arduino.cc/en/Reference/AnalogWrite

Quote:
The frequency of the PWM signal is approximately 490 Hz.


however:
http://www.arduino.cc/playground/Main/TimerPWMCheatsheet

_________________
YouTube channel
flickr photostream
http://loxodrom.blogspot.com
http://www.garageband.com/artist/loxodrom
http://soundcloud.com/loxodrom
Back to top
View user's profile Send private message
Mongo1



Joined: Aug 11, 2011
Posts: 411
Location: Raleigh NC

PostPosted: Wed Nov 30, 2011 6:32 am    Post subject: Reply with quote  Mark this post and the followings unread

Quote:
however:
http://www.arduino.cc/playground/Main/TimerPWMCheatsheet


But it's still 8 bit resolution isn't it?

Thanks
Gary
Back to top
View user's profile Send private message Send e-mail
Pehr



Joined: Aug 14, 2005
Posts: 1307
Location: Björkvik, Sweden
Audio files: 2

PostPosted: Wed Nov 30, 2011 6:57 am    Post subject: Reply with quote  Mark this post and the followings unread

Mongo1 wrote:
Quote:
however:
http://www.arduino.cc/playground/Main/TimerPWMCheatsheet


But it's still 8 bit resolution isn't it?

Thanks
Gary


I guess so...

_________________
YouTube channel
flickr photostream
http://loxodrom.blogspot.com
http://www.garageband.com/artist/loxodrom
http://soundcloud.com/loxodrom
Back to top
View user's profile Send private message
YashN



Joined: Jun 27, 2011
Posts: 104
Location: Canada

PostPosted: Sat Dec 03, 2011 3:48 pm    Post subject: Reply with quote  Mark this post and the followings unread

reve wrote:
I have seen the Adrian Freed code (that pretty much every arduino DDS scheme is based off of, it seems)


Where are these other Arduino DDS schemes?
Back to top
View user's profile Send private message
comrade_zero



Joined: Mar 05, 2009
Posts: 66
Location: arizona
Audio files: 4

PostPosted: Sat Dec 03, 2011 11:57 pm    Post subject: arduino direct synthesis Reply with quote  Mark this post and the followings unread

@YashN
Check a site called Shaduzlabs for the ArduinOSC library. It comes with wavetables for a few waves and has room for user-built arbitrary waves. Check it out, it's fairly easy to use.
Back to top
View user's profile Send private message
YashN



Joined: Jun 27, 2011
Posts: 104
Location: Canada

PostPosted: Sun Dec 04, 2011 8:41 am    Post subject: Reply with quote  Mark this post and the followings unread

Oh I know Shaduzlabs' code all right and it's cool they put it out. I was just wondering why our friend Reve here thinks that other Arduino DDS code appear to be based on Adrian Freed's code, and if they do exist, to point me to them.
Back to top
View user's profile Send private message
dobart



Joined: Feb 20, 2007
Posts: 10
Location: SEATTLE

PostPosted: Wed Feb 29, 2012 11:53 am    Post subject: Reply with quote  Mark this post and the followings unread

Hi! I'm just settling on a simplistic design for a sequencer along the lines of some of the analog stuff I've been working on. It's going to be a 4 voice polyphonic, using the tone library and an arduino mega. I was going to wire it up all nutso and analog-like, but I think instead I'm going for 1 serlcd display, one pot, and one momentary (up/down/middle) toggle to handle selections; per channel. So from that standpoint it'll be more or less totally open.

I have lots of ways to make an arduino tickle an oscillator (5940 and 16 pwm vactrols?), but I like the idea of

tone1.play(NOTE_A4);

in order to get a nice even-tempered note.

So what I'm aiming for is something that takes an analog input and makes that a timebase multiplier for tempo, a routine that decides to play a tone or not (or continuous), and something that sorts the array of available notes with a bitmask for musical key and musical mode (I'd use the info right on the wiki entries to sort this)...

Each voice will feed to an analog bandpass filter, controlled via an spi digital pot. The output of this filter will also be fed thru a pot, for digitally controlled attenuation. I'd like to set up ADSR for those, using the 256-step pots. Finally, all ouputs would mix to an analog onboard amp and speaker, etc.

Interfacewise, you'd be able to toggle the menu on the LCD for a given voice and adjust:

Tempo
Musical Key
Musical Scale
Pause
Voice Range
Voice Scale
Filter ADSR
Output ADSR

Using the analog pot.

Sound fun? Four polyvoices and filters picking from musical modes and keys to assemble a pseudorandom aleatronic chord/arpeggiation experimentation device.

I'll be steadily working on hardware until it's done (probably 6 weeks in this iteration), it'll be a shield with a quad opamp for the filtering and 4 dual ISP pots for the controlling... any input is appreciated, especially if someone is dying to have one who feels comfortable coding the thing with me. The hardware stuff is easy, the bitmasking will be fun to learn.
Back to top
View user's profile Send private message Visit poster's website
Electric Druid



Joined: Mar 13, 2012
Posts: 44
Location: UK

PostPosted: Tue Mar 13, 2012 3:18 am    Post subject: Envelope generators on a PIC/AVR Reply with quote  Mark this post and the followings unread

reve wrote:

Dunno how Wiltshire did it because I can't make heads or tails out of assembly. :/


Hi there,

Perhaps my notes on my code will help a bit:

http://www.electricdruid.net/forums.html?page=projects.envgen7Bnotes

The basic gist of it is that there's main code that runs in a loop reading the ADC channels and storing the values. The raw ADC values are used to look up a frequency increment for the DDS from a table. The lookup table allows me to have an exponential control response (1ms to 10ms covers the same span on the knob as 10ms to 100ms, etc etc).

The rest of the code (the envelope sample generation) runs in an interrupt routine at the 19.5KHz PWM output rate. This runs the DDS and does the conversion from the linear output from the DDS to the exponential curve. This is again done with a lookup table. Essentially you put a linear value from 0-255 in, and you get a exponential output value out. In practice it's a bit more complicated 'cos I added linear interpolation between the table points to smooth the output.

Finally, the PIC can produce a 10-bit PWM output at 19.5KHz with a 20MHz crystal (e.g. at full tilt) and I bet the AVR can do similar. Whether the Arduino gives you easy access to this feature is a different story.

Hope this helps - good luck with your AVR/Arduino version!

Tom
Back to top
View user's profile Send private message
dobart



Joined: Feb 20, 2007
Posts: 10
Location: SEATTLE

PostPosted: Tue Mar 13, 2012 7:40 am    Post subject: Reply with quote  Mark this post and the followings unread

THANK YOU!!!

I have the notepicker working pretty well, and have some kludge code for the ADSR; I'm getting hardware together so I can work it out with the bandpass filter and attenuator in place (as well as the serLCDs); should be another week or so...
Back to top
View user's profile Send private message Visit poster's website
dobart



Joined: Feb 20, 2007
Posts: 10
Location: SEATTLE

PostPosted: Tue Mar 13, 2012 7:50 am    Post subject: Reply with quote  Mark this post and the followings unread

here's a chunk of the ADSR code, I need to work out the variable types before it compiles (this happens within the note picker loop, if noteplayer returns a true (isPlaying()):

Code:
here it is so far; it doesn't compile but I want to get the variable arrays squared away...

void loop()
{

for (currentVoice = 0; currentVoice <= numVoices-1; currentVoice++)
{
if (notePlayer[currentVoice].isPlaying() == true)
//time = millis();
for
(currentADSRfunction = 0; currentADSRfunction <=1; currentADSRfunction++)
{
ADSRTotal[currentADSRfunction] =
(
attack[currentADSRfunction]+
decay[currentADSRfunction]+
sustain[currentADSRfunction]+
release[currentADSRfunction]
);

attackLength[currentADSRfunction] =
((noteLength [currentVoice] * attack[currentADSRfunction])/ADSRTotal[currentADSRfunction]);
decayLength[currentADSRfunction] =
((noteLength [currentVoice] * decay[currentADSRfunction])/ADSRTotal[currentADSRfunction]);
sustainLength[currentADSRfunction] =
((noteLength [currentVoice] * sustain[currentADSRfunction])/ADSRTotal[currentADSRfunction]);
releaseLength[currentADSRfunction] =
((noteLength [currentVoice] * release[currentADSRfunction])/ADSRTotal[currentADSRfunction]);

startTime[0] = lastTime[currentVoice];
//this is screwed up^^^ error: invalid types 'long unsigned int[int]' for array subscript
endTime[0] = startTime[0] + attackLength[currentADSRfunction];
while (millis() =< endTime[0])
{
ENVlevel[currentADSRfunction] = 255 * (millis() - startTime[0]) / (endTime[0] - startTime[0]);
}
startTime[1] = lastTime[currentVoice] + endTime[0];
endTime[1] = startTime[1] + decayLength[currentADSRfunction];
while (millis() =< endTime[1])
{
ENVlevel[currentADSRfunction] = ENVlevel = 255 + (sustainLevel[currentADSRfunction] - 255) * (millis() - startTime[1]) / (endTime[1] - startTime[1]);
}
startTime[2] = lastTime[currentVoice] + endTime[1];
endTime[2] = startTime[2] + decayLength[currentADSRfunction];
while (millis() =< endTime[2])
{
ENVlevel[currentADSRfunction] = sustainLevel[currentADSRfunction];
}
startTime[3] = lastTime[currentVoice] + endTime[2];
endTime[3] = startTime[3] + decayLength[currentADSRfunction];
while (millis() =<endTime> Lasttime + noteLength [currentVoice])
//setup and play a note...
[/quote]
Back to top
View user's profile Send private message Visit poster's website
reve



Joined: Feb 23, 2008
Posts: 149
Location: USA

PostPosted: Fri Mar 23, 2012 11:06 pm    Post subject: Okay I wrote some code. Reply with quote  Mark this post and the followings unread

Electric Druid wrote:

Perhaps my notes on my code will help a bit:

http://www.electricdruid.net/forums.html?page=projects.envgen7Bnotes


Okay, yes. I wound up cribbing judiciously from Mr. Wiltshire's notes and knocked something together last week. I call it... PolyEGg. There's a pre-alpha version up on github that provides a number of ostensibly handy features:

1. It implements the aforementioned DDS method to give nice exponential curves. I reckon I'm going to need to use larger tables and accumulators (currently 8/16) if we want real long smooth envelopes, but the principle appears sound. So it'll ultimately be able to emulate the responses of your favorite ADSRs, do the linear thing, etc.

2. There are 8 independently triggered, independently running envelopes. They all utilize the same increment tables and read the same pots, but obviously run independently. Just like, you know, a polysynth.

3. The envelopes scale correctly. So if you remove the gate signal during the decay stage, the exponential release curve goes from where you let go rather than from sustain or something. Also, if you retrigger attack during the release stage or anything like that, it scales right.

ASIDE: I'm not sure if this is actually a good thing. Like, if you retrigger a long attack close to the maximum, it takes forever and nearly nothing happens. I'll have to bust out the scope and see how the analog ADSRs actually handle this. Razz

GOTCHAs / TODOs:

1. Obviously, things need to happen regularly rather than whenever the code gets around to executing it. So an interrupt callback will be in order. But that may need some sort of buffer, so... before that happens this is pretty useless except to play with.

2. Right now I'm just bit shifting the reads from the ADC. These should probably be scaled using map() or whatever instead.

3. Crap procedural code needs to be abstracted.

4. If anyone can help with capturing curves of vintage ADSRs, that'd be awesome. I have no idea how far they deviate from the exponential "ideal?" Might not even be worth it.

5. I'm going to use a MAX528 DAC unless 8 bit doesn't cut it. The SPI code that's in the sketch now creates words for that particular DAC. It might be worth making it more vague to play nice with other DACs.

Anyway, code's up at https://github.com/rmosquito/PolyEGg ; if you'd like contrib rights just lemme know.

_________________
- r. mosquito
SynthDIY Synthpop -> http://www.reverbnation.com/photovoltaik
Back to top
View user's profile Send private message
Electric Druid



Joined: Mar 13, 2012
Posts: 44
Location: UK

PostPosted: Sat Mar 24, 2012 3:56 am    Post subject: Re: Okay I wrote some code. Reply with quote  Mark this post and the followings unread

reve wrote:

1. It implements the aforementioned DDS method to give nice exponential curves. I reckon I'm going to need to use larger tables and accumulators (currently 8/16) if we want real long smooth envelopes, but the principle appears sound. So it'll ultimately be able to emulate the responses of your favorite ADSRs, do the linear thing, etc.


That's the great thing about that method. You can have any curve shape you want. Guess how the Andromeda did its envelopes. And I expect you will need more resolution in the accumulator. I think I needed a minimum of 20 bits for the x10000 (1ms to 10 secs) range that I used, so finished up with a 24-bit (3 byte) accumulator.

reve wrote:

2. There are 8 independently triggered, independently running envelopes. They all utilize the same increment tables and read the same pots, but obviously run independently. Just like, you know, a polysynth.


Ooh, very nice!

reve wrote:

3. The envelopes scale correctly. So if you remove the gate signal during the decay stage, the exponential release curve goes from where you let go rather than from sustain or something. Also, if you retrigger attack during the release stage or anything like that, it scales right.


This is a pain to do in my experience. It's where the nice clean code you've got until then gets filled up with untidy conditional statements.

reve wrote:

ASIDE: I'm not sure if this is actually a good thing. Like, if you retrigger a long attack close to the maximum, it takes forever and nearly nothing happens. I'll have to bust out the scope and see how the analog ADSRs actually handle this. Razz


From the pictures in the datasheets for SSM2056 and CEM3310 it looks like they only complete the remaining bit of the attack curve. Given how they work, I don't understand how they pull that off, so I'm not entirely sure I trust the diagram - I'm extrapolating a bit.
I did it the simple way (like you've done) and I have to say that no-one has ever complained about it. Maybe it doesn't matter as much as you think.

reve wrote:

4. If anyone can help with capturing curves of vintage ADSRs, that'd be awesome. I have no idea how far they deviate from the exponential "ideal?" Might not even be worth it.


The most significant thing is that they usually charge up to a voltage above the maximum level. The CEM3310 attacks towards 6.5V, but reaches the top at 5V. This cuts off some of the slow top part of the RC where not much happens and makes the attack more linear.

Good luck with the next stage.

Tom
Back to top
View user's profile Send private message
cappy2112



Joined: Dec 24, 2004
Posts: 2465
Location: San Jose, California
Audio files: 2
G2 patch files: 1

PostPosted: Wed Apr 04, 2012 6:53 pm    Post subject: Reply with quote  Mark this post and the followings unread

corex wrote:

I've just used bare AVRs so I may be a little bit off-base, but aren't most Arduinos built around the ATmega328P? If so, this chip has a 16-bit PWM counter (Counter1) as well as an 8-bit counter (Counter0).


Going through the Arduino library you sacrifice some speed for ease of use.
PWM functions are part of the library, to make it easier for the user.

Not all Arduinos are based on the 328P. The most popular one uses a 328P, but 3.3v models have been made, which means the clock needs to run between 8-10Mhz.

The latest Arduino is based on Atmel's ATMega 2560, which has many more I/O lines, timers, serial ports, and interrupts, but still runs from a 16MHZ crystal. It also has 16K of ram and 256K of program memory.

There has been an announcement of a 75MHZ Cortex M3-based Arduino, but it hasn't surfaced yet.

Quote:

Additionally, the PWM counters can be clocked at system clock rates, therefore with a 20MHz crystal,


Most Arduinos come with a 16Mhz crystal. Changing the freq. would require changing the bootloader and possibly some fuses, thus breaking the Arduino functionality. This is not trivial to do and you would need a special programmer to reload the bootloader (assuming that you got the bootloader code right)

The serial I/O (not to mention the timers,PWM) are all based on 16MHZ operation. Changing the freq will make many things not work, without having to recode some of the Arduino library.

Using the digitalWrite() function to toggle an I/O line is much slower than doing direct-port I/O. You have to remember that the Arduino was developed to make an easy to use platform for everyone who may not have the background to bring up a microcontroller from scratch.

Some featured of the 328P are still available but you have to reference avr-libc to find out the constructs, naming conventions etc.

_________________
Free Tibet. Release the Panchen Lama from prison. Let the Dalai Lama return to his home.
Back to top
View user's profile Send private message
jackdamery



Joined: Apr 26, 2010
Posts: 75
Location: UK

PostPosted: Sun Sep 22, 2013 4:05 pm    Post subject: Re: Envelope generators on a PIC/AVR Reply with quote  Mark this post and the followings unread

Electric Druid wrote:
reve wrote:

Dunno how Wiltshire did it because I can't make heads or tails out of assembly. :/


Hi there,

Perhaps my notes on my code will help a bit:

http://www.electricdruid.net/forums.html?page=projects.envgen7Bnotes

The basic gist of it is that there's main code that runs in a loop reading the ADC channels and storing the values. The raw ADC values are used to look up a frequency increment for the DDS from a table. The lookup table allows me to have an exponential control response (1ms to 10ms covers the same span on the knob as 10ms to 100ms, etc etc).

The rest of the code (the envelope sample generation) runs in an interrupt routine at the 19.5KHz PWM output rate. This runs the DDS and does the conversion from the linear output from the DDS to the exponential curve. This is again done with a lookup table. Essentially you put a linear value from 0-255 in, and you get a exponential output value out. In practice it's a bit more complicated 'cos I added linear interpolation between the table points to smooth the output.

Finally, the PIC can produce a 10-bit PWM output at 19.5KHz with a 20MHz crystal (e.g. at full tilt) and I bet the AVR can do similar. Whether the Arduino gives you easy access to this feature is a different story.

Hope this helps - good luck with your AVR/Arduino version!

Tom


Tom, your link is dead. Could you repost?

Thanks,
Jack
Back to top
View user's profile Send private message
Electric Druid



Joined: Mar 13, 2012
Posts: 44
Location: UK

PostPosted: Thu Aug 11, 2022 5:26 am    Post subject: Re: Envelope generators on a PIC/AVR Reply with quote  Mark this post and the followings unread

jackdamery wrote:

Tom, your link is dead. Could you repost?


Sorry to raise a necro-thread, but for anyone who finds this via google or whatever, I've pput the notes back online at:

https://electricdruid.net/env-gen-some-notes/

_________________
Electric Druid Synth and Pedal DIY website
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic Moderators: State Machine
Page 1 of 1 [24 Posts]
View unread posts
View new posts in the last week
Mark the topic unread :: View previous topic :: View next topic
 Forum index » DIY Hardware and Software » Microcontrollers and Programmable Logic
Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Forum with support of Syndicator RSS
Powered by phpBB © 2001, 2005 phpBB Group
Copyright © 2003 through 2009 by electro-music.com - Conditions Of Use