I'm looking to underclock the Uno. I built a Stomp Shield guitar pedal and I love the arpeggiator but i want it to run slower. Is there a way to do this with code or do i have to mod the crystal?
...and I thought maybe there is some kind of assembly code that can add nops if i understand it correctly. at any rate - code would be the best situation. Are there any pcbs that would allow me variable underclocking by means of a potentiometer? I might consider this if i have room for another knob... it's pretty crammed though. :o
You can use prescaler: divide system clock by 2 or 4 or more if it helps. By manipulating fuses you can use some internal oscillator which can give you nearly any frequency less than 10 MHz. Try to look into ATMega datasheet.
animalstyle:
I'm looking to underclock the Uno. I built a Stomp Shield guitar pedal and I love the arpeggiator but i want it to run slower.
Don't quite get what you're asking. Things can happen very slow on a 16Mhz clock.
You can even flash a LED once a year if you want to.
If you want things to happen slower, change the code.
A lower clock frequency is only needed if e.g. you want to save power by running the Arduino on a lower voltage.
If you want proper help, then tell us more about your project, and post the code.
Leo..
/*
stomp_updown.pde
guest openmusiclabs.com 7.15.13
this program plays through a sample buffer, first forward at
double rate, and then backwards at single rate. it changes
direction at the buffer boundary. the rotary encoder does
nothing.
*/
#include "StompShield.h"
#define SIZE 1000 // buffer size, make lower if it clicks
int buffer[SIZE]; // data buffer
unsigned int location = 0; // current buffer location
unsigned int offset = 0; // distance to current location
byte dir = 0; // direction of travel in buffer
int data_buffer = 0x8000;
void setup() {
StompShield_init(); // setup the arduino for the shield
}
void loop() {
}
ISR(TIMER1_OVF_vect) { // all processing happens here
// output the last value calculated
OCR1AL = ((data_buffer + 0x8000) >> 8); // convert to unsigned, send out high byte
OCR1BL = data_buffer; // send out low byte
// get ADC data
byte temp1 = ADCL; // you need to fetch the low byte first
byte temp2 = ADCH; // yes it needs to be done this way
int input = ((temp2 << 8) | temp1) + 0x8000; // make a signed 16b value
buffer[location] = input; // store current sample
location++; // go to next location
if (location >= SIZE) location = 0; // deal with boundary
unsigned int temp = location + offset; // find playback location
if (temp >= SIZE) temp -= SIZE; // boundary wrap
data_buffer = buffer[temp]; // fetch sample
if (dir) { // increment until at buffer boundary
if (offset >= (SIZE - 4)) {
dir = 0;
offset--;
}
else offset++;
}
else { // decrement till reaching boundary from other side
if (offset <= 4) {
dir = 1;
offset--;
}
else offset -= 2;
}
}
This is an example from the stomp shield library. I'm trying to slow it down because the effect is too dramatic on my guitar. I use lots of video game style effects and custom synths in my rig. I tried quite a few things with no results so far.
let me expand then. I tried adding some snippets of code like this:
asm volatile ("nop \n\t "); // a NOP
asm volatile (".rept 10\n\t nop \n\t .endr\n\t"); // 10 NOPs - you can change the 10 for anything reasonably small
#define MNOP(x) asm volatile (" .rept " #x "\n\t nop \n\t .endr \n\t") // A macro I use a lot
MNOP(20); // 20 NOPs
I also tried to increase the buffer size. I think I might have even tried delay commands.
Are you talking about doing something with TCCR1A or TCCR1B in the library? do I need to assign those to different hex values in the data Sheet? guessing here...
I don't know what the program should do but if it generates a sound somehow you cannot reduce frequency easily - it would reduce the frequency of the generated sound too.
You may try to add
byte sregSave = SREG; //saves system register
cli(); //disable interrupts
CLKPR = 0b10000000; //enable prescaler settings change
CLKPR = 0b00000001; //change prescaler
SREG = sregSave; //restores interrupts if they were enabled before
into setup to set system clock prescaler to 2. Arduino should run at 8MHz after the command - and try if it does what you expect.