Go Down

Topic: Help with sequencer code (Read 1 time) previous topic - next topic

GoatBoy

Hello, I was wondering if anyone could help me alter this code so that when I use the "AnalogFrequencyIn" pot, I am able to select a pre-defined scale of notes for each of the steps in the sequencer. Should I be looking at using "case" or an "array" in some way to do this? Any help at all appreciated!
   Thanks :)
Code: [Select]
/* ======================================================================
Arduino Punk Console
A simple programmable 8 step tone sequencer
by dano/beavisaudio.com

Revs
-----------------------------------
15 Sept  djh  initial version
======================================================================*/

// Map all the input and output pins
#define AnalogInFrequency 1
#define AnalogInTempo 2
#define AnalogInDuration 0
#define DigitalOutSignal 11
#define DigitalInSwitch0 2
#define DigitalInSwitch1 3
#define DigitalInSwitch2 4
#define DigitalInSwitch3 5
#define DigitalInSwitch4 6
#define DigitalInSwitch5 7
#define DigitalInSwitch6 8
#define DigitalInSwitch7 9
#define DigitalInStartStop 10
#define DigitalOutLED 12

// Set up the array for each step
int steps[] = {100,120,140,160,180,200,220,240};

// misc housekeeping
int duration = 50;
int pitchval = 1;
int fPlayMode = true;
int lastPushedStep = -1;

// Initialize the tempo
int tempo = 100;

void setup()
{
 // setup pin modes (Digital pins are input by default, but
 // I like to set 'em explicitly just so the code is clear.
 pinMode (DigitalInSwitch0, INPUT);
 pinMode (DigitalInSwitch1, INPUT);
 pinMode (DigitalInSwitch2, INPUT);
 pinMode (DigitalInSwitch3, INPUT);
 pinMode (DigitalInSwitch4, INPUT);
 pinMode (DigitalInSwitch5, INPUT);
 pinMode (DigitalInSwitch6, INPUT);
 pinMode (DigitalInSwitch7, INPUT);                
 pinMode (DigitalInStartStop, INPUT);
 pinMode (DigitalOutSignal, OUTPUT);  
 pinMode (DigitalOutLED, OUTPUT);

 // setup comms for the LCD display
 Serial.begin(9600);

 StartupMessage();

}

void StartupMessage()
{
 clearLCD();
 Serial.print ("BEAVIS: Arduino");
 delay(300);
 Serial.print (254, BYTE);
 Serial.print (192, BYTE);
 Serial.print ("Punk Console!");
 delay (2000);
 clearLCD();
 Serial.print ("Beavis: APC");
}

void clearLCD()
{
 Serial.print(254, BYTE);
 Serial.print(1, BYTE);
}

void loop()
{
 // Main sequence loop  
 for (int i=0; i<8; i++)
 {  
   // Are we playing or stopping?
   fPlayMode = digitalRead (DigitalInStartStop);
   digitalWrite (DigitalOutLED, HIGH);

   // Check the Hardware
    readSwitches();
    readPots();

   // update the display
   updateDisplay();

   // Make the noise
   if (fPlayMode)
   {
     freqout (steps[i], duration);
   }
   digitalWrite (DigitalOutLED, LOW);

   // Pause between steps
   delay (tempo);      
 }
}


void updateDisplay()
{
 Serial.print (254, BYTE);
 Serial.print (192, BYTE);
 Serial.print ("T:");
 Serial.print (tempo);
 Serial.print (" d:");
 Serial.print (duration);

if (lastPushedStep != -1)
{
   Serial.print ("*");
   Serial.print (lastPushedStep);
}
}

// Read the current values of the pots, called from the loop.
void readPots ()
{
   tempo = (analogRead (AnalogInTempo) * 1.9);
   duration = (analogRead (AnalogInDuration));      
}

// Read the current values of the switches and
// if pressed, replace the switch's slot frequency
// by reading the frequency pot.
void readSwitches()
{
 // reset last pushed button number
 lastPushedStep = -1;

 // check switch 0, if pressed, get the current freq into step 0, etc. etc.
 if (digitalRead (DigitalInSwitch0) == HIGH)
 {
   steps[0] = analogRead(AnalogInFrequency);
   lastPushedStep = 1;
 }

 else if (digitalRead (DigitalInSwitch1) == HIGH)
 {
   steps[1] = analogRead(AnalogInFrequency);
   lastPushedStep = 2;
 }

 else if (digitalRead (DigitalInSwitch2) == HIGH)
 {
   steps[2] = analogRead(AnalogInFrequency);
   lastPushedStep = 3;
 }
 else if (digitalRead (DigitalInSwitch3) == HIGH)
 {
   steps[3] = analogRead(AnalogInFrequency);
   lastPushedStep = 4;
 }
 else if (digitalRead (DigitalInSwitch4) == HIGH)
 {
   steps[4] = analogRead(AnalogInFrequency);
   lastPushedStep = 5;
 }
 else if (digitalRead (DigitalInSwitch5) == HIGH)
 {
   steps[5] = analogRead(AnalogInFrequency);
   lastPushedStep = 6;
 }
 else if (digitalRead (DigitalInSwitch6) == HIGH)
 {
   steps[6] = analogRead(AnalogInFrequency);
   lastPushedStep = 7;
 }
 else if (digitalRead (DigitalInSwitch7) == HIGH)
 {
   steps[7] = analogRead(AnalogInFrequency);
   lastPushedStep = 8;
 }
}


//freqout code by Paul Badger
// freq - frequency value
// t - time duration of tone
void freqout(int freq, int t)
{
 int hperiod;     //calculate 1/2 period in us
 long cycles, i;

 // subtract 7 us to make up for digitalWrite overhead - determined empirically
 hperiod = (500000 / ((freq - 7) * pitchval));            

 // calculate cycles
 cycles = ((long)freq * (long)t) / 1000;    // calculate cycles

 for (i=0; i<= cycles; i++)
 {              // play note for t ms  
   digitalWrite(DigitalOutSignal, HIGH);  
   delayMicroseconds(hperiod);
   digitalWrite(DigitalOutSignal, LOW);  
   delayMicroseconds(hperiod - 1);     // - 1 to make up for fractional microsecond in digitaWrite overhead
 }
}




Groove

#1
Apr 23, 2010, 12:55 pm Last Edit: Apr 23, 2010, 12:59 pm by GrooveFlotilla Reason: 1
Code: [Select]
if (digitalRead (DigitalInSwitch[glow]2[/glow]) == HIGH)
 {
   steps[[glow]2[/glow]] = analogRead(AnalogInFrequency);


I think you could do it with an array and a "for" loop with a "break" to cope with the "else".
Per Arduino ad Astra

PaulS

To implement Groove's suggestion, the switch pin numbers would need to be in an array, instead of 8 different variables, just in case that is not clear.

AWOL

I'd use eight different constants  ;)
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

PaulS

Quote
I'd use eight different constants


Picky. Picky.

GoatBoy

:)Thanks guys!! Would I be bold in asking if anyone could write me an example to try out? I'm quite stumped as to where to start! Thanks :)

Groove

Code: [Select]
#define N_PINS 2
const byte DigitalInSwitch [N_PINS] = { 2, 3};


for (int i = 0; i < N_PINS; i++) {
 if (digitalRead (DigitalInSwitch [i]) == HIGH)
 {
   steps[i] = analogRead(AnalogInFrequency);
   lastPushedStep = i + 1;
   break;
 }
}
Per Arduino ad Astra

GoatBoy

Thanks Groove :) Just to be clear, if I have 8 switches must I write "#define N_PINS 8" ?
    Also, how does this solve my problem of getting AnalogInFrequency to read from an array of values? I'm afraid I'm very slow with the concept of code! Thanks :)

Groove

Yes, you have to change the value of N_PINS and add six values in the array.

Quote
how does this solve my problem of getting AnalogInFrequency to read from an array of values?

I wasn't aware this was a problem.
Can you clarify?
Per Arduino ad Astra

GoatBoy

I have 8 switches for each step of the 8 step sequence so does my array therefore have {0,1,2,3,4,5,6,7} to represent the 8 switches?
 The way the sequencer works is by pressing a switch and while holding it down, you turn the AnalogInFrequency pot which then sets the pitch for that step and so on until all 8 steps are filled. My trouble is that the pitch it sets is too variable and I wanted the pot to be able to select from a predetermined scale of notes or values.

Groove

Code: [Select]
#define DigitalInSwitch0 2
#define DigitalInSwitch1 3
#define DigitalInSwitch2 4
#define DigitalInSwitch3 5
#define DigitalInSwitch4 6
#define DigitalInSwitch5 7
#define DigitalInSwitch6 8
#define DigitalInSwitch7 9

not 0..7.


I'm really not sure what you mean about the pot, but perhaps you need another array with frequencies, indexed by a mapping of the pot position:

Code: [Select]
index = map (analogueValue, 0, 1023, 0, N_TONES - 1);
Per Arduino ad Astra

GoatBoy

Cheers Groove! I'll get to work on this now. The AnalogInFrequency is controlled by a pot. Here's a link that shows how it works..http://www.beavisaudio.com/projects/digital/ArduinoPunkConsole/
  Thanks again :)

GoatBoy

I didn't have much joy setting an array for the switches. All sorts of errors were popping up while I was tinkering with it. I didn't have a problem with that part of the code as it works fine but I did manage to map the AnalogInFrequency pot :)
Code: [Select]
{
   val = analogRead(AnalogInFrequency);
   val = map(val, 0, 1023, 100, 240);

   steps[0] = val;
   lastPushedStep = 1;
 }

Now that gives me a value between 100 and 240 but what I'm really looking for are particular set values between these two points to be chosen continually by the pot until I release the switch by which time a value has been set. I just don't have a clue as far as how to set up the array for this :'( I'm afraid I don't have the programming skills. Any further help much appreciated  :)

Go Up