507 lines
11 KiB
C++
507 lines
11 KiB
C++
|
|
#include <SPI.h>
|
|
#include <SD.h>
|
|
#include <Adafruit_VS1053.h>
|
|
|
|
#include <Wire.h>
|
|
#include "PCA9634.h"
|
|
|
|
#include <Adafruit_LIS3DH.h>
|
|
#include <Adafruit_Sensor.h>
|
|
|
|
#include "nRF24L01MOD.h"
|
|
#include "RF24MOD.h"
|
|
#include "printfMOD.h"
|
|
|
|
#define DEBUG 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 120
|
|
|
|
|
|
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 selectedEffect = 0;
|
|
unsigned char data;
|
|
|
|
void resetBoard()
|
|
{
|
|
//Serial.println("reset");
|
|
NVIC_SystemReset(); // esta funcion en teoria si funciona en SAMD
|
|
}
|
|
|
|
|
|
int channel(int ch)
|
|
{
|
|
int value;
|
|
switch (ch)
|
|
{
|
|
case 0:
|
|
value = 0x10; //
|
|
break;
|
|
case 1:
|
|
value = 0x4C; //
|
|
break;
|
|
case 3:
|
|
value = 0x64; //
|
|
break;
|
|
case 4:
|
|
value = 0x7F; //
|
|
break;
|
|
default:
|
|
value = 0; //
|
|
break;
|
|
}
|
|
return value;
|
|
}
|
|
|
|
|
|
void sceneRF( int num ) // Disparo DE ESCENA via Radio
|
|
{
|
|
digitalWrite(LED_BUILTIN, HIGH);
|
|
|
|
Serial.print("Scene RF received");
|
|
Serial.println(num);
|
|
|
|
if( num == 0 )
|
|
selectedEffect = 0; // CMD 0 = off
|
|
else if( num == 1)
|
|
{
|
|
selectedEffect = 1;
|
|
ledFlag = 0;
|
|
}
|
|
else if( num == 2)
|
|
{
|
|
selectedEffect = 2;
|
|
ledFlag = 0;
|
|
}
|
|
else if( num == 3)
|
|
{
|
|
selectedEffect = 3;
|
|
ledFlag = 0;
|
|
}
|
|
|
|
digitalWrite(LED_BUILTIN, LOW);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// 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(i, globalWhite);
|
|
//delay(2);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void test_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");
|
|
ledValue(255);
|
|
}
|
|
else if (click & 0x20)
|
|
{
|
|
Serial.println("Double click");
|
|
test_pwm();
|
|
}
|
|
|
|
//Serial.println();
|
|
|
|
radio.stopListening();
|
|
Serial.println("stop listening");
|
|
radio.openWritingPipe(pipes[1]); // modo TRANSMITTER
|
|
radio.openReadingPipe(1, pipes[0]); // modo TRANSMITTER
|
|
|
|
data++;
|
|
if(data>3)
|
|
data = 0;
|
|
|
|
Serial.print("Data TX: ");
|
|
|
|
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(10,10);
|
|
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();
|
|
//printf_begin();
|
|
|
|
Wire.begin();
|
|
Wire.setClock(400000);
|
|
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");
|
|
|
|
if (DEBUG)
|
|
{
|
|
Serial.println(F("Playing Brian Eno"));
|
|
musicPlayer.startPlayingFile("/brian.mp3");
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void loop()
|
|
{
|
|
|
|
///////////////////////////// SERIAL /////////////////////////////
|
|
|
|
if (Serial.available()) {
|
|
char c = Serial.read();
|
|
|
|
///////////// AUDIO //////////////////
|
|
// if we get an 's' on the serial console, stop!
|
|
if (c == 's') {
|
|
musicPlayer.stopPlaying();
|
|
}
|
|
// if we get an 'p' on the serial console, pause/unpause!
|
|
if (c == 'p') {
|
|
if (! musicPlayer.paused()) {
|
|
Serial.println("Paused");
|
|
musicPlayer.pausePlaying(true);
|
|
} else {
|
|
Serial.println("Resumed");
|
|
musicPlayer.pausePlaying(false);
|
|
}
|
|
}
|
|
|
|
///////////// EFFECT //////////////////
|
|
if( c == '0')
|
|
selectedEffect = 0; // CMD 0 = off
|
|
else if( c == '1')
|
|
{
|
|
selectedEffect = 1;
|
|
ledFlag = 0;
|
|
}
|
|
else if( c == '2')
|
|
{
|
|
selectedEffect = 2;
|
|
ledFlag = 0;
|
|
}
|
|
else if( c == '3')
|
|
{
|
|
selectedEffect = 3;
|
|
ledFlag = 0;
|
|
}
|
|
else if( c == '4')
|
|
{
|
|
selectedEffect = 4;
|
|
ledFlag = 0;
|
|
}
|
|
|
|
}
|
|
|
|
///////////////////////////// EFFECTS /////////////////////////////
|
|
|
|
switch (selectedEffect)
|
|
{
|
|
|
|
case 0 : { // OFF - no parameters
|
|
ledValue(0);
|
|
delay(10);
|
|
break;
|
|
}
|
|
case 1 : {
|
|
ledFade( 255, 2000, 16);
|
|
//AUDIO PLAY?
|
|
break;
|
|
}
|
|
case 2 : {
|
|
ledFade( 0, 2000, 16); // 14 es el cero en este led con el pwm
|
|
//AUDIO PLAY?
|
|
break;
|
|
}
|
|
case 3 : {
|
|
ledValue(255);
|
|
delay(10);
|
|
break;
|
|
}
|
|
case 4 : {
|
|
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();
|
|
}
|
|
}
|
|
}
|
|
|
|
///////////////////////////// LOOP /////////////////////////////
|
|
|
|
test_acel_click(); // cheuque el acelerometro continuamente
|
|
|
|
|
|
|
|
}
|