Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <MIDI.h>
- #include <FastLED.h>
- #define MIDI_VELOCITY 123 //El CC midi 123 es la intensidad, la reduciremos a cero cuando queramos silencio
- #define NUM_LEDS 16
- #define STEPS 16
- #define PIN 2// Led Ring
- //BOTONERA:
- #define PREV A0
- #define NEXT A1
- #define NOTEADD A6
- #define NOTEDEC A7
- #define OFFSETADD A5
- #define OFFSETDEC A4
- #define NUMBERADD A2
- #define NUMBERDEC A3
- //ENCODER
- #define ENC_SW 13 //
- #include "EncoderStepCounter.h"
- #define NUMPIXELS 16 // Popular NeoPixel ring size
- #define DELAYVAL 200 // Time (in milliseconds) to pause between pixels
- #define BPM 120
- int Delay = 15000 / BPM;
- //ENCODER
- #define ENCODER_PIN1 21
- #define ENCODER_INT1 digitalPinToInterrupt(ENCODER_PIN1)
- #define ENCODER_PIN2 3
- #define ENCODER_INT2 digitalPinToInterrupt(ENCODER_PIN2)
- EncoderStepCounter encoder(ENCODER_PIN1, ENCODER_PIN2, HALF_STEP);
- //ENCODER
- unsigned int rotateBitShiftRight(unsigned int chunk, byte rotation) {
- chunk = (chunk >> rotation) | (chunk << (16 - rotation)); //Suma lógica (OR) del valor con bitshift desde LSB y complementaria desde MSB
- return chunk;
- }
- unsigned int rotateBitShiftLeft(unsigned int chunk, byte rotation) {
- chunk = (chunk << rotation) | (chunk >> (16 - rotation)); //Suma lógica (OR) del valor con bitshift desde LSB y complementaria desde MSB
- return chunk;
- }
- class Track {
- private:
- byte Note;
- byte Offset;
- byte Number;
- unsigned int Euclidean;
- public:
- void setTrack() {
- Note = 78; //C3
- Offset = 0;
- Number = 0;
- Euclidean = 0b0000000000000000;
- }
- void populateEuclidean() {
- unsigned int euclideanPatterns[17] = { //Precalculated Euclid patterns
- 0b0000000000000000,
- 0b1000000000000000,
- 0b1000000010000000,
- 0b1000010000100000,
- 0b1000100010001000,
- 0b1001001001001000,
- 0b1001010010010100,
- 0b1001010100101010,
- 0b1010101010101010,
- 0b1011010101101010,
- 0b1011010110110101,
- 0b1011011011011011,
- 0b1011101110111011,
- 0b1011110111101111,
- 0b1011111110111111,
- 0b1111111111111110,
- 0b1111111111111111
- };
- Euclidean = rotateBitShiftRight(euclideanPatterns[Number], Offset); //Rotated to Offset value
- }
- void addOffset() {
- if ( Offset > 15 ) {
- Offset = 0;
- } else {
- Offset++;
- }
- Euclidean = rotateBitShiftRight( Euclidean , 1 );
- }
- void decOffset() {
- if (Offset > 0) {
- Offset--;
- } else {
- Offset = 15;
- }
- Euclidean = rotateBitShiftLeft( Euclidean , 1 );
- }
- void addNumber() {
- if (Number < 16) {
- Number++;
- }
- else {
- Number = 0;
- }
- populateEuclidean();
- }
- void decNumber() {
- if ( Number > 0) {
- Number--;
- }
- else {
- Number = 16;
- }
- populateEuclidean();
- }
- void addNote() {
- Note++;
- }
- void decNote() {
- Note--;
- }
- byte getNote() {
- return Note;
- }
- unsigned int getEuclidean() {
- return Euclidean;
- }
- };
- MIDI_CREATE_DEFAULT_INSTANCE();
- byte Pista = 0;
- byte Paso = 0;
- Track track[4];
- CRGBArray<NUM_LEDS> leds;
- class Anillo {
- private:
- byte Output[16];//array 16 colores
- byte Posicion;//posición del puntero
- byte ColorActual;//color puntero
- byte Anterior;
- public:
- void setAnillo() {
- for (int i = 0; i < 16; i++) {
- Output[i] = 0;
- }
- Posicion = 0;
- ColorActual = 0;
- }
- void setAnillo(byte pos, byte col) {
- Posicion = pos;
- ColorActual = col;
- }
- voidSetPosicion(byte val) {
- Posicion = val;
- }
- void crearFondo() {
- for (int i = 15; i >= 0; i--) {
- byte posibilidades[4] = {0, 0, 0, 0,};
- byte contador = 0;
- for (int j = 0; j < 4; j++) {
- if (bitRead(track[j].getEuclidean(), i)) {
- //Serial.print("1-");
- posibilidades[contador] = track[j].getNote();
- contador++;
- }
- }
- if (contador > 0) {
- Output[i] = posibilidades[random(contador)];
- leds[i] = CHSV(map(Output[i], 60, 106, 0, 255), 200, 150); //CRGB::Blue;
- }
- else {
- leds[i] = CRGB::Black;
- Output[i] = 0;
- //Serial.print("0-");
- }
- }
- }
- void crearPuntero() {
- leds[Posicion] = CRGB::Orange;
- }
- //borrar
- void borrar() {
- FastLED.clear();
- }
- //mostrar
- void mostrar() {
- FastLED.show();
- }
- void actualiza(byte val) {
- borrar();
- crearFondo();
- setAnillo(val, CRGB::Green);
- crearPuntero();
- mostrar();
- }
- void silencio() {
- MIDI.sendNoteOff(Anterior, 0, 1);
- MIDI.sendControlChange(123, 0, 1);
- }
- void toca(byte val) {
- if (Output[val] != 0) {
- MIDI.sendNoteOn(Output[val], 100, 1);
- Anterior = Output[val];
- }
- }
- };
- Anillo seq;
- void botones() {
- static byte boton = 0;
- static byte i = A0;
- static byte contador = 0;
- const int Theshold = 900;
- const byte Debounce = 5;
- static unsigned long int ultimaComprobacion = 0;
- if (boton == 0) {
- if (contador > Debounce) {
- //Serial.println();
- contador = 0;
- boton = i;
- return;
- }
- else if (analogRead(i) > Theshold) {
- if ((millis() - ultimaComprobacion) > 1)
- {
- //Serial.print(analogRead(i));
- contador ++;
- //Serial.print(contador);
- //Serial.print(" ");
- ultimaComprobacion = millis();
- }
- }
- else {
- contador = 0;
- i++;
- if (i > A7) {
- i = A0;
- }
- }
- } else if (analogRead(boton) > Theshold) {
- return; //No realiza la acción hasta soltar el boton.
- }
- else {
- switch (boton) {
- case PREV: (Pista == 0) ? Pista = 3 : Pista++; break;
- case NEXT: (Pista == 3) ? Pista = 0 : Pista++; break;
- case OFFSETADD: track[Pista].addOffset(); break;
- case OFFSETDEC: track[Pista].decOffset(); break;
- case NUMBERADD: track[Pista].addNumber(); break;
- case NUMBERDEC: track[Pista].decNumber(); break;
- case NOTEADD: track[Pista].addNote(); break;
- case NOTEDEC: track[Pista].decNote(); break;
- //Serial.println();
- //Serial.print("Botón pulsado: ");
- //Serial.print(boton);
- }
- boton = 0;
- seq.actualiza(Paso); //Si hay cambios actualiza el display.
- }
- }
- bool encoderSW() {
- if ( digitalRead(ENC_SW) == 1) {
- return 0;
- }
- while ( digitalRead(ENC_SW) == 0) {} //return 1;
- while ( digitalRead(ENC_SW) == 1) {}
- while ( digitalRead(ENC_SW) == 0) {}
- }
- void setup() {
- MIDI.begin(MIDI_CHANNEL_OMNI);
- //Serial.begin(115200);
- FastLED.addLeds<NEOPIXEL, 2>(leds, NUM_LEDS);
- FastLED.setBrightness(25);
- pinMode(A1, INPUT);
- pinMode(A2, INPUT);
- pinMode(A3, INPUT);
- pinMode(A4, INPUT);
- pinMode(A5, INPUT);
- pinMode(A6, INPUT);
- pinMode(A7, INPUT);
- //ENCODER
- encoder.begin();
- pinMode (ENC_SW, INPUT_PULLUP);
- attachInterrupt(ENCODER_INT1, interrupt, CHANGE);
- attachInterrupt(ENCODER_INT2, interrupt, CHANGE);
- randomSeed(analogRead(A0));
- for (int i = 0; i < 4; i++) {
- track[i].setTrack();
- }
- }
- void interrupt() {
- encoder.tick();
- }
- void loop() {
- EVERY_N_MILLISECONDS_I(bpm, Delay) {
- static byte cont = 0;
- seq.silencio();
- Paso = cont;
- seq.actualiza(cont);
- seq.toca(cont);
- cont++;
- bpm.setPeriod(Delay);
- if (cont >= STEPS) {
- cont = 0;
- }
- }
- botones();
- ////Serial.println(myEnc.read());
- encoderSW();
- static unsigned int position = BPM;
- signed char pos = encoder.getPosition();
- if (pos != 0) {
- position += pos;
- if (position == 0) {
- position = 1;
- }
- encoder.reset();
- //Serial.println(position);
- Delay = 15000 / position;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement