#include #include #include #include #include "PCA9634.h" #include #include #include "nRF24L01MOD.h" #include "RF24MOD.h" #include "printfMOD.h" #define DEBUG 0 #define ID 1 #define VS1053_RESET -1 // VS1053 reset pin (not used!) #define VS1053_CS 6 // VS1053 chip select pin (output) #define VS1053_DCS 10 // VS1053 Data/command select pin (output) #define CARDCS 5 // Card chip select pin // DREQ should be an Int pin *if possible* (not possible on 32u4) #define VS1053_DREQ 9 // VS1053 Data request, ideally an Interrupt pin Adafruit_VS1053_FilePlayer musicPlayer = Adafruit_VS1053_FilePlayer(VS1053_RESET, VS1053_CS, VS1053_DCS, VS1053_DREQ, CARDCS); PCA9634 leds( 0x68 ); #define CE_PIN 19 // A5 #define CSN_PIN 18 // A4 int radioId; uint32_t CMD[ 8 ]; // CMD + Ch + 2 RF24 radio(CE_PIN, CSN_PIN); // Create a Radio const uint64_t pipes[2] = {0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL}; //int ch = 0x4C ; // 76 por defecto es el canal 76 (showroom) Adafruit_LIS3DH lis = Adafruit_LIS3DH(); #define CLICKTHRESHHOLD 80 byte neopix_gamma[] = { // adaptada a este LED con el umbral en 13 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 22, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 26, 26, 26, 27, 27, 28, 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 34, 34, 35, 35, 36, 36, 37, 38, 38, 39, 40, 40, 41, 42, 42, 43, 44, 44, 45, 46, 47, 47, 48, 49, 50, 51, 51, 52, 53, 54, 55, 56, 57, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 71, 72, 73, 74, 75, 76, 77, 79, 80, 81, 82, 83, 85, 86, 87, 89, 90, 91, 93, 94, 95, 97, 98, 100, 101, 102, 104, 105, 107, 108, 110, 112, 113, 115, 116, 118, 120, 121, 123, 125, 126, 128, 130, 132, 133, 135, 137, 139, 141, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 171, 173, 175, 177, 179, 181, 184, 186, 188, 191, 193, 195, 198, 200, 202, 205, 207, 210, 212, 215, 217, 220, 222, 225, 228, 230, 233, 236, 238, 241, 244, 247, 249, 252, 255 }; // Globales LED unsigned long delayed = 0; // control de tiempo de funciones de neon unsigned long launchTime = 0; int countFrame = 0; short stroboFlag = 0; short ledFlag = 0; short stroboOn = 0; int globalWhite = 0; int selectedScene = 1; unsigned char data; unsigned long previousMillis; int interval = 1000; int compas; bool fadeFlag = 0; int pases; const char* fx[] = {"fx1.mp3", "fx2.mp3", "fx3.mp3", "fx4.mp3", "fx5.mp3", "fx6.mp3", "fx7.mp3", "fx8.mp3", "fx9.mp3", "fx10.mp3", "fx11.mp3", "fx12.mp3", "fx13.mp3", "fx14.mp3", "fx15.mp3", "fx16.mp3"}; const char* voz[] = {"voz1.mp3", "voz2.mp3", "voz3.mp3", "voz4.mp3", "voz5.mp3", "voz6.mp3", "orc2.mp3", "orc4.mp3" }; const char* piano[] = {"piano1.mp3", "piano2.mp3", "piano3.mp3"}; const char* orc[] = {"orc1.mp3", "orc2.mp3", "orc3.mp3", "orc4.mp3", "orc5.mp3"}; const char* pianomix[] = {"piano1.mp3", "piano2.mp3", "piano3.mp3", "voz1.mp3","voz4.mp3", "voz5.mp3", "voz6.mp3", "orc3.mp3", "orc1.mp3", "orc5.mp3"}; void resetBoard() { //Serial.println("reset"); NVIC_SystemReset(); // esta funcion en teoria si funciona en SAMD } void sceneRF( char num ) // Disparo DE ESCENA via Radio { if(DEBUG) { Serial.print("Scene RF received: "); Serial.println(num); } if ( num == '1' ) { selectedScene = 4; // TORMENTA compas=0; ledFlag = 0; } } /// File listing helper void printDirectory(File dir, int numTabs) { while (true) { File entry = dir.openNextFile(); if (! entry) { // no more files //Serial.println("**nomorefiles**"); break; } for (uint8_t i = 0; i < numTabs; i++) { Serial.print('\t'); } Serial.print(entry.name()); if (entry.isDirectory()) { Serial.println("/"); printDirectory(entry, numTabs + 1); } else { // files have sizes, directories do not Serial.print("\t\t"); Serial.println(entry.size(), DEC); } entry.close(); } } int16_t v = 0; int8_t inc = 1; void test_pwm() { for (int i = 0; i < 8; i++) { leds.set_brightness(i, 255); delay(10); } delay(1000); for (int i = 0; i < 8; i++) { leds.set_brightness(i, 13); // valor a partir del cual empieza a encenderse delay(10); } } void test_pwm_fade() { int i, r; //Serial.print("Set brightness: "); //Serial.println(v); for (i = 1; i < 8; i++) { r = leds.set_brightness(i, v); //delay(2); } v = v + inc; if ( inc > 0 && v >= 255) { inc = -1; } else if (inc < 0 && v <= 0) { inc = 1; } // delay (1); //delayMicroseconds(100); } void ledValue(byte white) { globalWhite = white; int i, r; //for (i = 4; i < 8; i++) { r = leds.set_brightness(7, globalWhite); //delay(2); //} } void acel_click() { uint8_t click = lis.getClick(); if (click == 0) return; if (! (click & 0x30)) return; //Serial.print("Click detected (0x"); Serial.print(click, HEX); Serial.print("): "); if (click & 0x10) { Serial.println("Single click"); selectedScene = 4; ledFlag = 0; compas = 0; } else if (click & 0x20) { Serial.println("Double click"); } //Serial.println(); radio.stopListening(); data = '1'; // puede ser un random de estados agitados (diferentes sonidos) -> 4,5,6 (dejamos 1, 2, 3 para estatico) Serial.println("stop listening"); radio.openWritingPipe(pipes[1]); // modo TRANSMITTER radio.openReadingPipe(1, pipes[0]); // modo TRANSMITTER radio.write( &data, sizeof(char) ); Serial.println(data); radio.openWritingPipe(pipes[0]); // modo RECEIVER radio.openReadingPipe(1, pipes[1]); // modo RECEIVER radio.startListening(); Serial.println("Start listening..."); delay(100); return; } void ledFade(int value, int fadeTime, int frameTime) { if ( millis() > delayed ) { delayed = millis() + frameTime - 4 ; // compensacion de bloqueo de millis y otras latencias float w; float totalFrames = fadeTime / frameTime; static byte startWhite; byte endWhite = value; if (!ledFlag) { launchTime = millis(); if (DEBUG) { Serial.print("fadeTime: "); Serial.println(fadeTime); Serial.print("LaunchTime: "); Serial.println(launchTime); Serial.print("totalFrames: "); Serial.println(totalFrames); } countFrame = 0; // RESET DE VARIABLES ANTES DE ARRANCAR ledFlag = true; startWhite = globalWhite; } if (countFrame < totalFrames) { countFrame++; w = map(countFrame * 255. / totalFrames, 0, 255, startWhite, endWhite); globalWhite = w; //Serial.print("w: "); //Serial.println( w ); //Serial.println( neopix_gamma[(int)globalWhite] ); leds.set_brightness(7, neopix_gamma[(int)globalWhite]); // int i,r; // for (i=4; i<8; i++){ // r = leds.set_brightness(i, globalWhite); // //delay(2); // } } } } void setup() { pinMode(LED_BUILTIN, OUTPUT); Serial.begin(115200); if (DEBUG) { while (!Serial) { delay(1); } } Serial.println("\n\nAdafruit VS1053 Feather Test"); if (! musicPlayer.begin()) { // initialise the music player Serial.println(F("Couldn't find VS1053, do you have the right pins defined?")); //while (1); } Serial.println(F("VS1053 found")); musicPlayer.sineTest(0x44, 500); // Make a tone to indicate VS1053 is working if (!SD.begin(CARDCS)) { Serial.println(F("SD failed, or not present")); //while (1); // don't do anything more } Serial.println("SD OK!"); // list files printDirectory(SD.open("/"), 0); // Set volume for left, right channels. lower numbers == louder volume! musicPlayer.setVolume(1, 1); musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT); // DREQ int Serial.println("\n\nNRF24 Feather Test"); radio.begin(); radio.setDataRate( RF24_250KBPS ); radio.setPALevel( RF24_PA_MAX ); radio.setAutoAck(0); radio.setPayloadSize(8); radio.setChannel(76); radio.openWritingPipe(pipes[0]); // modo RECEIVER radio.openReadingPipe(1, pipes[1]); // modo RECEIVER radio.printDetails(); radio.startListening(); Wire.begin(); Wire.setClock(100000); leds.begin( ); Serial.println("LIS3DH test!"); if (! lis.begin(0x18)) { // change this to 0x19 for alternative i2c address Serial.println("Couldnt start"); //while (1); } Serial.println("LIS3DH found!"); lis.setRange(LIS3DH_RANGE_2_G); // 2, 4, 8 or 16 G! lis.setClick(2, CLICKTHRESHHOLD); Serial.print("Range = "); Serial.print(2 << lis.getRange()); Serial.println("G"); randomSeed(analogRead(0)); if (DEBUG) { Serial.println(F("Playing Brian Eno")); musicPlayer.startPlayingFile("/brian.mp3"); } } void loop() { ///////////////////////////// SERIAL ///////////////////////////// if (Serial.available()) { char c = Serial.read(); ///////////// EFFECT ////////////////// if ( c == '0') selectedScene = 0; // CMD 0 = off else if ( c == '1') { selectedScene = 1; ledFlag = 0; compas = 0; } else if ( c == '2') { selectedScene = 2; ledFlag = 0; compas = 0; } else if ( c == '3') { selectedScene = 3; ledFlag = 0; compas = 0; } else if ( c == '4') { selectedScene = 4; ledFlag = 0; compas = 0; } else if ( c == '5') { selectedScene = 5; ledFlag = 0; compas = 0; } else if ( c == '6') { selectedScene = 6; ledFlag = 0; compas = 0; } else if ( c == '7') { selectedScene = 7; ledFlag = 0; compas = 0; } else if ( c == '8') { selectedScene = 8; ledFlag = 0; compas = 0; } } ///////////////////////////// EFFECTS ///////////////////////////// switch (selectedScene) { case 0 : { // OFF - no parameters break; } case 1 : { // MODO RELAX 1 (voces + orc) if (millis() > previousMillis + interval - 290 ) // 32000 -> 32 compases a 120 bpm + COMPENSACION RETARDO { previousMillis = millis(); if (DEBUG) { Serial.print("compas: "); Serial.println(compas); } if(compas == 0) { ledFade( 255, 1000, 16); if(!musicPlayer.stopped()) musicPlayer.stopPlaying(); int randomAudio = random(8); //Serial.println(voz[randomAudio]); musicPlayer.startPlayingFile(voz[randomAudio]); // play sample aleatorio cada 8 compases } if(!compas % 8 == 0) { fadeFlag = !fadeFlag; ledFlag = 0; } compas++; if (compas > 31) { compas = 0; pases++; } if( pases > 4) { pases = 0; selectedScene = random(3)+1; //Serial.print("random "); //Serial.println(selectedScene); } } if(!musicPlayer.stopped()) { if(fadeFlag) ledFade( 150, (interval-290), 16); else ledFade( 255, (interval-290), 16); } else ledFade( 0, (interval-290)*2, 16); break; } case 2 : { // MODO RELAX 2 pianomix if (millis() > previousMillis + interval - 290 ) // 32000 -> 32 compases a 120 bpm { previousMillis = millis(); if (DEBUG) { Serial.print("compas: "); Serial.println(compas); } if(compas == 0) { ledFade( 255, 1000, 16); if(!musicPlayer.stopped()) musicPlayer.stopPlaying(); int randomAudio = random(10); //Serial.println(pianomix[randomAudio]); musicPlayer.startPlayingFile(pianomix[randomAudio]); // play sample aleatorio cada 8 compases } if(!compas % 8 == 0) { fadeFlag = !fadeFlag; ledFlag = 0; } compas++; if (compas > 31) { compas = 0; pases++; } if( pases > 4) { pases = 0; selectedScene = random(3)+1; //Serial.print("random "); //Serial.println(selectedScene); } } if(!musicPlayer.stopped()) { if(fadeFlag) ledFade( 150, (interval-290)*2, 16); else ledFade( 255, (interval-290)*2, 16); } else ledFade( 0, (interval-290)*2, 16); break; } case 3 : { // MODO RELAX 3 - PIANO SOLO if (millis() > previousMillis + interval - 290 ) // 32000 -> 32 compases a 120 bpm { previousMillis = millis(); if (DEBUG) { Serial.print("compas: "); Serial.println(compas); } if(compas == 0) { ledFade( 255, 1000, 16); if(!musicPlayer.stopped()) musicPlayer.stopPlaying(); int randomAudio = random(3); //Serial.println(pianomix[randomAudio]); musicPlayer.startPlayingFile(pianomix[randomAudio]); // play sample aleatorio cada 8 compases } if(!compas % 8 == 0) { fadeFlag = !fadeFlag; ledFlag = 0; } compas++; if (compas > 31) { compas = 0; pases++; } if( pases > 4) { pases = 0; selectedScene = random(3)+1; //Serial.print("random "); //Serial.println(selectedScene); } } if(!musicPlayer.stopped()) { if(fadeFlag) ledFade( 150, (interval-290)*2, 16); else ledFade( 255, (interval-290)*2, 16); } else ledFade( 150, (interval-290)*2, 16); break; } case 4 : { // MODO TORMENTA 1 //if (millis() > previousMillis + interval - (32-compas)*30 ) // 8000 -> 8 compas a 120 bpm if (millis() > previousMillis + interval - 290 ) // 8000 -> 8 compas a 120 bpm { previousMillis = millis(); if (DEBUG) { Serial.print("compas: "); Serial.println(compas); } //musicPlayer.stopPlaying(); int _random = random(100); //Serial.print("random: "); //Serial.println(_random); if ((_random) > compas*4) // prob decreciente en % { if(!musicPlayer.stopped()) musicPlayer.stopPlaying(); ledValue(255); ledFlag = 0; int randomAudio = random(16); //Serial.println(fx[randomAudio]); musicPlayer.startPlayingFile(fx[randomAudio]); // play sample aleatorio cada 8 compases } compas++; if (compas > 31) { compas = 0; selectedScene = random(3)+1; //Latido OFF no sincroniza bien if (DEBUG) { Serial.print("random "); Serial.println(selectedScene); } break; } } ledFade( 0, interval*4, 16); break; } case 5 : { //MODO PULSACION if (millis() > previousMillis + interval - 290 ) // 8000 -> 8 compas a 120 bpm { previousMillis = millis(); if (DEBUG) { Serial.print("compas: "); Serial.println(compas); Serial.print("compas%4: "); Serial.println(compas%4); } if ( ( compas%2 == 0) && (compas<30)) { if(!musicPlayer.stopped()) musicPlayer.stopPlaying(); ledValue(255); ledFlag = 0; //Serial.println("pulso.mp3"); musicPlayer.startPlayingFile("corazon.mp3"); // play sample aleatorio cada 8 compases } else if(( compas%1 == 0) && (compas<30) ) { ledValue(255); ledFlag = 0; } compas++; if (compas > 31) { compas = 0; selectedScene = random(3)+1; } } ledFade( 0, (interval-290)*2, 16); } break; } ///////////////////////////// RADIO RX ///////////////////////////// if ( radio.available() ) { while (radio.available()) { radio.read( CMD, sizeof(CMD) ); sceneRF(CMD[0]); //musicPlayer.startPlayingFile("/miles.mp3"); //Serial.println("playing miles"); if (DEBUG) { Serial.println("Got command"); for (int i = 0 ; i < 8 ; i++) { Serial.print(CMD[i]); Serial.print(","); } Serial.println(); } } } ///////////////////////////// ACELEROMETRO ///////////////////////////// acel_click(); }