#include #include /* Sequencer: 8 patterns of 16 steps top LEDs display current pattern screen shows current pattern in 2 rows by 8 steps by 4 dots each step can play 1-8 (or 0, off) highlight current step and playing step L/R to pick step U/D to change step value (0-8) A start/stop B + L/R choose pattern -- to start, preset simple delay per step -- later, sync? -- metronome tick per 1/4 note, 1/8 notes? -- while playing, print current playing step to serial port. (1 2 3 4, 0 for silence) (waveshield will play sound based on serial input) */ #define STEPCOLOR Dark #define EDITCOLOR Blue #define PLAYCOLOR Green // LONOTE is for 1-4. HINOTE is for 5-8. Yellow and Violet clash. #define LONOTECOLOR Yellow #define HINOTECOLOR Violet const byte up = 4; const byte down = 8; const byte left = 16; const byte right = 32; const byte B = 1; const byte A = 2; byte Alatch = 0; byte Blatch = 0; byte Llatch = 0; byte Rlatch = 0; byte Ulatch = 0; byte Dlatch = 0; uint8_t Pattern[8][16]; uint8_t CurrentPatt=0; uint8_t EditStep=0; uint8_t PlayStep=0; uint8_t i; uint8_t Running = 0; // are we playing or not? uint8_t Pulse = 0; // 24 pulses per quarter note for later syncing uint8_t NewPatt = 1; // did we just change pattern? uint8_t OldStep = 0; // 120bpm = 2 beats per second // 2 beats per second = 48 pulses per second = 24 pulses per 500ms // 48 pulses per second = roughly 20.8333... ms per pulse // Let's use 20 ms/pulse for the sake of other processing going on. uint8_t PulseDelay = 20; // arbitrary for now void DrawStep(uint8_t Step) { uint8_t bottomX; uint8_t bottomY; uint8_t j; byte color; // bottom left is 0,0 // step 0 displays using: 0,4 5 6 7 // step 7 displays using: 7,4 5 6 7 // step 8 displays using: 0,0 1 2 3 // step 15 displays using: 7,0 1 2 3 bottomX=Step % 8; bottomY=(Step<8)?4:0; color=STEPCOLOR; if (Step==EditStep) { color=EDITCOLOR; } if (Step==PlayStep && Running==1) { color=PLAYCOLOR; } for(j=0;j<=3;j++) { if(Pattern[CurrentPatt][Step]==(j+1)) { // pixel representing what current step is set to DrawPx(bottomX,bottomY+j,LONOTECOLOR); } else if (Pattern[CurrentPatt][Step]==(j+5)) { DrawPx(bottomX,bottomY+j,HINOTECOLOR); } else { // pixel representing background color DrawPx(bottomX,bottomY+j,color); } } } void setup() { MeggyJrSimpleSetup(); Serial.begin(9600); Serial.println("meggyseq"); ClearSlate(); while(CurrentPatt <= 8) { SetAuxLEDs(1< 23) { Pulse=0; } if (Pulse % 6 == 0) { OldStep=PlayStep; PlayStep++; if (PlayStep==16) { PlayStep=0; } DrawStep(OldStep); DrawStep(PlayStep); Serial.println(Pattern[CurrentPatt][PlayStep],DEC); } } // display current step // deal with buttons byte in = Meg.GetButtons(); // code so we can still use == in the if statements below, but still be holding down the A/B buttons // latch logic gratuitously stolen from Darius if (!(in& A)) Alatch = 0; if (!(in& B)) Blatch = 0; if (!(in& up)) Ulatch = 0; if (!(in& down)) Dlatch = 0; if (!(in& left)) Llatch = 0; if (!(in& right)) Rlatch = 0; //if (Alatch == 1) in-=2; //if (Blatch == 1) in-=1; // if (Button_Right && Button_B) { if (in==B+right && Blatch==0 && Rlatch==0) { CurrentPatt++; if (CurrentPatt > 7) { CurrentPatt = 0; } NewPatt=1; Blatch=1; Rlatch=1; } else if (in==B+left && Blatch==0 && Llatch==0) { if (CurrentPatt==0) { CurrentPatt=7; } else { CurrentPatt--; } NewPatt=1; Blatch=1; Llatch=1; } if (in==right && Rlatch==0) { OldStep=EditStep; EditStep++; DrawStep(OldStep); if (EditStep > 15) { EditStep = 0; } DrawStep(EditStep); Rlatch=1; } if (in==left && Llatch==0) { OldStep=EditStep; EditStep--; if (EditStep == 255 ) { EditStep = 15; } DrawStep(OldStep); DrawStep(EditStep); Llatch=1; } if (in==up && Ulatch==0) { Pattern[CurrentPatt][EditStep]++; if (Pattern[CurrentPatt][EditStep] > 8) { Pattern[CurrentPatt][EditStep] = 8; } DrawStep(EditStep); Ulatch=1; } if (in==down && Dlatch==0) { Pattern[CurrentPatt][EditStep]--; if (Pattern[CurrentPatt][EditStep] == 255 ) { Pattern[CurrentPatt][EditStep] = 0; } DrawStep(EditStep); Dlatch=1; } if (in==A && Alatch==0) { if(Running==0) { Running=1; OldStep=PlayStep; DrawStep(PlayStep); Serial.println(Pattern[CurrentPatt][PlayStep],DEC); if (PlayStep==16) { PlayStep=0; } } else { Running=0; DrawStep(PlayStep); PlayStep=0; } Alatch=1; } // update current pattern SetAuxLEDs(1<