From c947d73c36262d3e54b14d0510624c6c6d53eb96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Kun?= Date: Fri, 8 Dec 2017 11:56:06 +0100 Subject: [PATCH] Adafruit Pixie support and automatic sleep mode entry, other see description below Buttons.cpp: prepare for COLOR Profiles, added lines for Adafruit Pixies support (ADF_PIXIE_BLADE) Config_HW.h: - added compile directive for ADF_PIXIE_BLADE (Adafruit Pixie) - added dummy NUMPIXELS define for led strings and star led setups to enable compilation wo/errors Config_SW.h: - definition SLEEPYTIME compile define statement - prepare swicth between GRAVITY_COLOR and COLOR_PROFILES to change blade colors in Config Menu Light.cpp/.h: - mainly support code for ADF_PIXIE_BLADE - fixed smooth blade ramp for LED_STAR setup, now ignition and retractions have a very smooth brightness Ramp FX-SaberOS.ino: sleep mode changes: - automatic entry into sleep mode after SLEEPYTIME sent in idle mode - accent led switch off in sleep mode - ADF_PIXIE_BLADE support, needed to make a switch between 2 DFPlayer libraries to enable using SoftwareSerial Known issues: - ADF_PIXIE_BLADE cannot be made to flicker properly, current code simply keeps the blade static --- Buttons.cpp | 14 +- ConfigMenu.h | 4 +- Config_HW.h | 54 +++--- Config_SW.h | 33 +++- FX-SaberOS.ino | 364 +++++++++++++++++++++--------------- Light.cpp | 210 ++++++++++++++++++--- Light.h | 5 + README.md | 498 ++++++++++++++++++++++++++++++++++++++++++++++++- 8 files changed, 963 insertions(+), 219 deletions(-) diff --git a/Buttons.cpp b/Buttons.cpp index 55b415c..e096a82 100644 --- a/Buttons.cpp +++ b/Buttons.cpp @@ -47,7 +47,7 @@ extern uint8_t ledPins[]; extern cRGB currentColor; //extern uint8_t currentColor[4]; //0:Red 1:Green 2:Blue 3:ColorID #endif -#if defined PIXELBLADE +#if defined PIXELBLADE or defined ADF_PIXIE_BLADE extern uint8_t ledPins[]; extern cRGB color; extern cRGB currentColor; @@ -105,10 +105,13 @@ void ConfigMenuButtonEventHandler(bool SaturateColor, ButtonActionEnum ButtonAct //Serial.print("soundfont "); Serial.print(storage.soundFont); Serial.print(" Offset: ");Serial.println(soundFont.getMenu((storage.soundFont)*NR_FILE_SF)); delay(150); } - #if defined(PIXELBLADE) or defined(STAR_LED) + #if defined PIXELBLADE or defined STAR_LED or defined ADF_PIXIE_BLADE else if (ConfigModeSubStates==CS_MAINCOLOR) { - //confParseValue(storage.sndProfile[storage.soundFont].mainColor, 0, 100 - 1, 1); - ColorMixing(storage.sndProfile[storage.soundFont].mainColor,modification,MAX_BRIGHTNESS, SaturateColor); + #ifdef GRAVITY_COLOR + ColorMixing(storage.sndProfile[storage.soundFont].mainColor,modification,MAX_BRIGHTNESS, SaturateColor); + #else if COLOR_PROFILE + + #endif storage.sndProfile[storage.soundFont].mainColor.r=currentColor.r; storage.sndProfile[storage.soundFont].mainColor.g=currentColor.g; storage.sndProfile[storage.soundFont].mainColor.b=currentColor.b; @@ -140,6 +143,9 @@ void ConfigMenuButtonEventHandler(bool SaturateColor, ButtonActionEnum ButtonAct #ifdef STAR_LED confParseValue(storage.sndProfile[storage.soundFont].flickerType, 0, 2, 1*incrementSign); // max number of flicker types for STAR_LED currently 3 #endif + #ifdef ADF_PIXIE_BLADE + confParseValue(storage.sndProfile[storage.soundFont].flickerType, 0, 0, 1*incrementSign); // max number of flicker types for Adafruit Pixie currently 1 + #endif #ifdef PIXELBLADE confParseValue(storage.sndProfile[storage.soundFont].flickerType, 0, 4, 1*incrementSign); // max number of flicker types for PIXELBLADE currently 5 #endif diff --git a/ConfigMenu.h b/ConfigMenu.h index a59bfd2..d731b3e 100644 --- a/ConfigMenu.h +++ b/ConfigMenu.h @@ -21,11 +21,11 @@ enum ActionModeSubStatesEnum {AS_HUM, AS_IGNITION, AS_RETRACTION, AS_BLADELOCKUP #if defined LEDSTRINGS enum ConfigModeSubStatesEnum {CS_SOUNDFONT, CS_FLICKERTYPE, CS_SLEEPINIT, CS_LASTMEMBER, CS_VOLUME, CS_POWERONOFFTYPE, CS_SWINGSENSITIVITY, CS_MAINCOLOR, CS_CLASHCOLOR, CS_BLASTCOLOR, CS_BATTERYLEVEL, CS_STORAGEACCESS, CS_UARTMODE}; // never delete CS_LASTMEMBER!!! Needed to calculate number of elements in the enum type!!! #endif -#if defined STAR_LED +#if defined STAR_LED or defined ADF_PIXIE_BLADE enum ConfigModeSubStatesEnum {CS_SOUNDFONT, CS_SLEEPINIT, CS_FLICKERTYPE, CS_MAINCOLOR, CS_CLASHCOLOR, CS_BLASTCOLOR, CS_SWINGSENSITIVITY, CS_VOLUME, CS_LASTMEMBER, CS_BATTERYLEVEL, CS_POWERONOFFTYPE, CS_STORAGEACCESS, CS_UARTMODE}; // never delete CS_LASTMEMBER!!! Needed to calculate number of elements in the enum type!!! #endif #if defined PIXELBLADE -enum ConfigModeSubStatesEnum {CS_SOUNDFONT, CS_SLEEPINIT, CS_FLICKERTYPE, CS_MAINCOLOR, CS_CLASHCOLOR, CS_BLASTCOLOR, CS_SWINGSENSITIVITY, CS_LASTMEMBER, CS_VOLUME, CS_POWERONOFFTYPE, CS_BATTERYLEVEL, CS_STORAGEACCESS, CS_UARTMODE}; // never delete CS_LASTMEMBER!!! Needed to calculate number of elements in the enum type!!! +enum ConfigModeSubStatesEnum {CS_SOUNDFONT, CS_VOLUME, CS_SLEEPINIT, CS_FLICKERTYPE, CS_MAINCOLOR, CS_CLASHCOLOR, CS_BLASTCOLOR, CS_SWINGSENSITIVITY, CS_LASTMEMBER, CS_POWERONOFFTYPE, CS_BATTERYLEVEL, CS_STORAGEACCESS, CS_UARTMODE}; // never delete CS_LASTMEMBER!!! Needed to calculate number of elements in the enum type!!! #endif // ==================================================================================== diff --git a/Config_HW.h b/Config_HW.h index 96cd77c..1135861 100644 --- a/Config_HW.h +++ b/Config_HW.h @@ -21,8 +21,8 @@ * If you have a home-brew solution using the Arduino Nano, choose DIYINO_PRIME below */ -#define DIYINO_PRIME -//#define DIYINO_STARDUST +//#define DIYINO_PRIME +#define DIYINO_STARDUST /***** BOARD PINOUT DEFINITIONS ******/ @@ -36,7 +36,7 @@ // If your saber has only a single button to interact with the electronics, uncomment the next line // in case you have 2 buttons (referred to as main and aux buttons) leave this line commented out -//#define SINGLEBUTTON +#define SINGLEBUTTON #ifdef DIYINO_PRIME #define MAIN_BUTTON 12 @@ -60,8 +60,9 @@ * blocks from compile *************************************/ //#define LEDSTRINGS -//#define STAR_LED -#define PIXELBLADE +#define STAR_LED +//#define PIXELBLADE +//#define ADF_PIXIE_BLADE /************************************/ /* @@ -111,13 +112,27 @@ #define LED_BLUE 9 #endif - // How many leds in one strip? - #define NUMPIXELS 60 // can go up to 120, could lead to memory overflow if further increased, causing instability +#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE +#include +#endif + #if defined LEDSTRINGS or defined STAR_LED + #define NUMPIXELS 0 + #endif + + #ifdef PIXELBLADE + // How many leds in one strip? + #define NUMPIXELS 115 // can go up to 120, could lead to memory overflow if further increased, causing instability + // For led chips like NEOPIXELs, which have a data line, ground, and power, you just + // need to define DATA_PIN. + #define DATA_PIN 13 // D13 + #endif + #ifdef ADF_PIXIE_BLADE + #define NUMPIXELS 1 + #define PIXIEPIN 13 // Pin number for SoftwareSerial output + #endif - // For led chips like NEOPIXELs, which have a data line, ground, and power, you just - // need to define DATA_PIN. - #define DATA_PIN 13 // D13 + #ifdef CROSSGUARDSABER // define how many pixels are used for the crossguard and how many for the main blade @@ -153,17 +168,14 @@ * Enable/disable management of * a button accent led *************************************/ -#define ACCENT_LED 14 //A0 - -//#define MULTICOLOR_ACCENT_LED -#if defined MULTICOLOR_ACCENT_LED -#define RED_ACCENT_LED 16 //A2 -#define GREEN_ACCENT_LED 17 //A3 -#define BLUE_ACCENT_LED A7 //.... A7 is input only ... +#ifdef DIYINO_PRIME + #define ACCENT_LED 14 //A0 +#else if DIYINO_STARDUST + #define ACCENT_LED 14 //A0 is an auxiliary pin on Stardust v2 #endif - - - +/* + * MP3 chips YX5200 or YX6300 Tx and Rx ins, as well as the ADC pins connected to the SPK terminals for AudioTracker + */ #define DFPLAYER_RX 8 #define DFPLAYER_TX 7 #define SPK1 20 //A6 @@ -172,8 +184,6 @@ -#define BUTTONLEDPIN 16 //A2 - #define BATTERY_CHECK // comment to disable #ifdef BATTERY_CHECK #ifdef DIYINO_PRIME diff --git a/Config_SW.h b/Config_SW.h index 2222587..4ab5521 100644 --- a/Config_SW.h +++ b/Config_SW.h @@ -26,9 +26,6 @@ #define CLASH_THRESHOLD 10 // 10 was the original value in LSOS, Jason's value changed it to 6, but it resulted in false clash trigges at more forceful swings /************************************/ -#if defined STAR_LED -#endif - #if defined LEDSTRINGS #define CONFIG_VERSION "L01" #endif @@ -38,12 +35,22 @@ #endif #if defined PIXELBLADE #define CONFIG_VERSION "L03" - //#define FIREBLADE + static const uint8_t rgbFactor = 255; +#endif +#if defined ADF_PIXIE_BLADE + #define CONFIG_VERSION "L05" static const uint8_t rgbFactor = 255; #endif +/* + * SOFTWARE SWITCHES FOR DFPLAYER CHISET + *************************************/ - +#ifdef ADF_PIXIE_BLADE + #define OLD_DPFPLAYER_LIB + #include "Adafruit_Pixie.h" + #include +#endif /**********END of blade type hardware settings **************************/ /* @@ -108,9 +115,23 @@ *************************************/ #define DEEP_SLEEP #if defined DEEP_SLEEP - #define SLEEP_TIMER 20000 //20 secs, after which the board will automatically go to sleep mode (to be implemented) + #define SLEEPYTIME 60000 //20 secs, after which the board will automatically go to sleep mode (to be implemented) + #include + #include #endif // DEEP_SLEEP + +/* COLOR CHANGE OPTIONS + * If you want to use the advanced Gravity Color method developed for FX-SaberOS + * leave the GRAVITY_COLOR compile directive defined. + * If instead you would like to work with pre-set color profiles (15 different, pre-defined colors) + * comment out the line with GRAVITY_COLOR, which will define COLOR_PROFILE to be used. + *************************************/ +#define GRAVITY_COLOR +#ifndef GRAVITY_COLOR + #define COLOR_PROFILE +#endif + /* * Enable Jukebox, an integrated MP3/WAV player which can play songs/music files * stored in the jukebox folder on your storage media (SD-card or SPI flash). diff --git a/FX-SaberOS.ino b/FX-SaberOS.ino index 8598c81..d85f32b 100644 --- a/FX-SaberOS.ino +++ b/FX-SaberOS.ino @@ -1,4 +1,4 @@ - /* +/* FX-SaberOS V1.0 released on: 7 October 2017 @@ -17,7 +17,7 @@ #include #include #include - + #include "Buttons.h" #include "Config_HW.h" #include "Config_SW.h" @@ -27,24 +27,22 @@ /* * DFPLAYER variables */ -#include -DFPlayer dfplayer; - -#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE -#include -#endif -#if defined PIXELBLADE -#include +#ifdef OLD_DPFPLAYER_LIB + #include "DFPlayer_Mini_Mp3.h" + //SoftwareSerial mp3player(DFPLAYER_TX, DFPLAYER_RX); // TX, RX + SoftwareSerial mp3player(7, 8); // TX, RX +#else + #include + #include + DFPlayer dfplayer; #endif -#ifdef DEEP_SLEEP - #include - #include -#endif // DEEP_SLEEP - SoundFont soundFont; unsigned long sndSuppress = millis(); unsigned long sndSuppress2 = millis(); +#ifdef DEEP_SLEEP + unsigned long sleepTimer = millis(); +#endif bool hum_playing = false; // variable to store whether hum is being played #ifdef JUKEBOX bool jukebox_play = false; // indicate whether a song is being played in JukeBox mode @@ -103,7 +101,7 @@ VectorInt16 prevDeltAccel; uint8_t ledPins[] = {LED_RED, LED_GREEN, LED_BLUE}; #endif extern bool fireblade; -#if defined PIXELBLADE +#if defined PIXELBLADE or defined ADF_PIXIE_BLADE #ifdef DIYINO_PRIME uint8_t ledPins[] = {LS1, LS2, LS3, LS4, LS5, LS6}; #else if #ifdef DIYINO_STARDUST @@ -437,24 +435,7 @@ Serial.println(configAdress); lockupButton.attachLongPressStop(lockupLongPressStop); lockupButton.attachDuringLongPress(lockupLongPress); #endif - /***** BUTTONS INITIALISATION *****/ - - while (digitalRead(MAIN_BUTTON) == LOW ) { - digitalWrite(BUTTONLEDPIN, HIGH); - delay(100); - digitalWrite(BUTTONLEDPIN, LOW); - delay(100); - } - /***** DF PLAYER INITIALISATION *****/ - InitDFPlayer(); - - delay(200); - // according to debug on 3.11.2017, these 2 lines below cause the sporadic disable of sound. For audio tracker they are not strictly needed. - //pinMode(SPK1, INPUT); - //pinMode(SPK2, INPUT); - SinglePlay_Sound(11); - delay(20); #ifdef DEEP_SLEEP /************ DEEP_SLEEP MODE SETTINGS **********/ @@ -463,23 +444,42 @@ Serial.println(configAdress); digitalWrite(MP3_PSWITCH, LOW); // enable MP3 player with A0 digitalWrite(FTDI_PSWITCH, LOW); // enable FTDI player with A1 // pin change interrupt masks (see below list) - //PCMSK2 |= bit (PCINT20); // pin 4 Aux button + PCMSK2 |= bit (PCINT20); // pin 4 Aux button PCMSK0 |= bit (PCINT4); // pin 12 Main button + delay(300); #endif // DEEP_SLEEP + /***** DF PLAYER INITIALISATION *****/ + InitDFPlayer(); + delay(200); + // according to debug on 3.11.2017, these 2 lines below cause the sporadic disable of sound. For audio tracker they are not strictly needed. + //pinMode(SPK1, INPUT); + //pinMode(SPK2, INPUT); + SinglePlay_Sound(11); + delay(20); + +#ifdef ADF_PIXIE_BLADE + InitAdafruitPixie(ledPins); +#endif + + + /***** Quick Mute *****/ if (digitalRead(MAIN_BUTTON) == LOW) { - dfplayer.setVolume(0); + Set_Volume(0); //Serial.println("Muted"); } else { - dfplayer.setVolume(storage.volume); + Set_Volume(storage.volume); //Serial.println("Unmuted"); } /****** INIT SABER STATE VARIABLE *****/ SaberState = S_STANDBY; PrevSaberState = S_SLEEP; ActionModeSubStates = AS_HUM; + #ifdef DEEP_SLEEP + sleepTimer = millis(); + #endif //Disable_MP3(true); // disable the MP3 in Stand-by mode to enable FTDI communication } @@ -522,13 +522,11 @@ void loop() { /* This is the very first loop after Action Mode has been turned on */ - //attachInterrupt(0, dmpDataReady, RISING); - // Reduce lockup trigger time for faster lockup response - //Disable_MP3(false); + #ifndef SINGLEBUTTON lockupButton.setPressTicks(PRESS_ACTION); #endif -#if defined PIXELBLADE +#if defined PIXELBLADE or defined ADF_PIXIE_BLADE pixelblade_KillKey_Disable(); #endif #if defined LS_INFO @@ -562,12 +560,11 @@ void loop() { #endif // Get the initial position of the motion detector - //motionEngine(); + motionEngine(); ActionModeSubStates = AS_HUM; #if defined ACCENT_LED // turns accent LED On accentLEDControl(AL_ON); - //digitalWrite(ACCENT_LED, HIGH); #endif } // ************************* blade movement detection ************************************ @@ -593,13 +590,6 @@ void loop() { ActionModeSubStates = AS_BLADELOCKUP; if (soundFont.getLockup((storage.soundFont)*NR_FILE_SF)) { LoopPlay_Sound(soundFont.getLockup((storage.soundFont)*NR_FILE_SF)); - //sndSuppress = millis(); - //while (millis() - sndSuppress < 50) { - //} - //Set_Loop_Playback(); - //sndSuppress = millis(); - //while (millis() - sndSuppress < 50) { - //} } } else { // ordinary clash @@ -640,19 +630,14 @@ void loop() { #endif //STAR_LED #if defined PIXELBLADE if (fireblade) { // #ifdef FIREBLADE - //getColor(storage.sndProfile[storage.soundFont].blasterboltColor); - //lightOn(ledPins, -1, currentColor); blasterPixel = random(NUMPIXELS / 4, NUMPIXELS - 3); //momentary shut off one led segment - //getColor(storage.sndProfile[storage.soundFont].blasterboltColor); - // lightBlasterEffect(blasterPixel, 3, storage.sndProfile[storage.soundFont].mainColor); - lightBlasterEffect(ledPins, blasterPixel, map(NUMPIXELS, 0, 120, 1, 3), storage.sndProfile[storage.soundFont].blasterboltColor); + lightBlasterEffect(ledPins, blasterPixel, map(NUMPIXELS, 10, NUMPIXELS-10, 1, 2), storage.sndProfile[storage.soundFont].blasterboltColor); } else { // #else lightOn(ledPins, -1, currentColor); blasterPixel = random(NUMPIXELS / 4, NUMPIXELS - 3); //momentary shut off one led segment getColor(storage.sndProfile[storage.soundFont].blasterboltColor); - // lightBlasterEffect(blasterPixel, 3, storage.sndProfile[storage.soundFont].mainColor); - lightBlasterEffect(ledPins, blasterPixel, map(NUMPIXELS, 0, 120, 1, 3), storage.sndProfile[storage.soundFont].blasterboltColor); + lightBlasterEffect(ledPins, blasterPixel, map(NUMPIXELS, 10, NUMPIXELS-10, 1, 2), storage.sndProfile[storage.soundFont].blasterboltColor); } // #endif #endif @@ -669,17 +654,22 @@ void loop() { We detect swings as hilt's orientation change since IMUs sucks at determining relative position in space */ - else if ((not fireblade) and - //else if (true and - (ActionModeSubStates != AS_BLADELOCKUP or lockuponclash)// end lockuponclash event on a swing + else if ( + (not fireblade) and (ActionModeSubStates != AS_BLADELOCKUP + #ifdef SWING_QUATERNION + or lockuponclash// end lockuponclash event on a swing, but only if swings are calculated based on quaternions, otherwise swings will + // interrut the lockup uncontrollably + #endif + ) #ifndef SWING_QUATERNION and (abs(curDeltAccel.y) > storage.sndProfile[storage.soundFont].swingSensitivity // and it has suffisent power on a certain axis or abs(curDeltAccel.z) > storage.sndProfile[storage.soundFont].swingSensitivity - or abs(curDeltAccel.x) > storage.sndProfile[storage.soundFont].swingSensitivity) and (millis() - sndSuppress > SWING_SUPPRESS)) + or abs(curDeltAccel.x) > storage.sndProfile[storage.soundFont].swingSensitivity) + and (millis() - sndSuppress > SWING_SUPPRESS) #else // SWING_QUATERNION is defined and abs(curRotation.w * 1000) < 999 // some rotation movement have been initiated and ( -#if defined BLADE_X + #if defined BLADE_X ( (millis() - sndSuppress > SWING_SUPPRESS) // The movement doesn't follow another to closely @@ -718,8 +708,6 @@ void loop() { ) ) ) - ) - // the movement must not be triggered by pure blade rotation (wrist rotation) and not ( abs(prevRotation.x * 1000 - curRotation.x * 1000) > abs(prevRotation.y * 1000 - curRotation.y * 1000) @@ -727,8 +715,8 @@ void loop() { abs(prevRotation.x * 1000 - curRotation.x * 1000) > abs(prevRotation.z * 1000 - curRotation.z * 1000) ) -#endif // BLADE_X -#if defined BLADE_Y + #endif // BLADE_X + #if defined BLADE_Y ( (millis() - sndSuppress > SWING_SUPPRESS) // The movement doesn't follow another to closely and (abs(curDeltAccel.x) > storage.sndProfile[storage.soundFont].swingSensitivity // and it has suffisent power on a certain axis @@ -766,16 +754,14 @@ void loop() { ) ) ) - ) - // the movement must not be triggered by pure blade rotation (wrist rotation) and not ( abs(prevRotation.y * 1000 - curRotation.y * 1000) > abs(prevRotation.x * 1000 - curRotation.x * 1000) and abs(prevRotation.y * 1000 - curRotation.y * 1000) > abs(prevRotation.z * 1000 - curRotation.z * 1000) ) -#endif // BLADE_Y -#if defined BLADE_Z + #endif // BLADE_Y + #if defined BLADE_Z ( (millis() - sndSuppress > SWING_SUPPRESS) // The movement doesn't follow another to closely and (abs(curDeltAccel.y) > storage.sndProfile[storage.soundFont].swingSensitivity // and it has suffisent power on a certain axis @@ -813,17 +799,16 @@ void loop() { ) ) ) - ) - // the movement must not be triggered by pure blade rotation (wrist rotation) and not ( abs(prevRotation.z * 1000 - curRotation.z * 1000) > abs(prevRotation.y * 1000 - curRotation.y * 1000) and abs(prevRotation.z * 1000 - curRotation.z * 1000) > abs(prevRotation.x * 1000 - curRotation.x * 1000) ) -#endif // BLADE_Z + #endif // BLADE_Z ) -#endif // SWING_QUATERNION +#endif // SWING_QUATERNION + ) { // end of the condition definition for swings @@ -851,20 +836,35 @@ void loop() { Serial.print(F("\tz=")); Serial.println(curDeltAccel.z); #endif - ActionModeSubStates = AS_SWING; - SinglePlay_Sound(soundFont.getSwing((storage.soundFont)*NR_FILE_SF)); - /* NORMAL SWING */ - - - - - if (millis() - sndSuppress > SWING_SUPPRESS) { + motionEngine(); + if (mpuIntStatus > 60 and mpuIntStatus < 70 and ActionModeSubStates != AS_BLADELOCKUP) { + SinglePlay_Sound(soundFont.getClash((storage.soundFont)*NR_FILE_SF)); sndSuppress = millis(); - } - if (millis() - sndSuppress2 > SWING_SUPPRESS) { sndSuppress2 = millis(); + /* + THIS IS A CLASH ! + */ + ActionModeSubStates = AS_CLASH; + lightClashEffect(ledPins, storage.sndProfile[storage.soundFont].clashColor); + if (!fireblade) { + delay(CLASH_FX_DURATION); // clash duration + } } - + else { + ActionModeSubStates = AS_SWING; + SinglePlay_Sound(soundFont.getSwing((storage.soundFont)*NR_FILE_SF)); + /* NORMAL SWING */ + + + + + if (millis() - sndSuppress > SWING_SUPPRESS) { + sndSuppress = millis(); + } + if (millis() - sndSuppress2 > SWING_SUPPRESS) { + sndSuppress2 = millis(); + } + } } } else { // simply flicker @@ -961,7 +961,7 @@ void loop() { SinglePlay_Sound(3); delay(600); -#if defined PIXELBLADE +#if defined PIXELBLADE or defined ADF_PIXIE_BLADE pixelblade_KillKey_Disable(); #endif @@ -980,57 +980,49 @@ void loop() { // delay(500); //#endif } -#if defined(PIXELBLADE) or defined(STAR_LED) +#if defined PIXELBLADE or defined STAR_LED or defined ADF_PIXIE_BLADE if (ConfigModeSubStates == CS_MAINCOLOR or ConfigModeSubStates == CS_CLASHCOLOR or ConfigModeSubStates == CS_BLASTCOLOR) { - modification = GravityVector(); - //Serial.println(modification); - //if (prev_modification != modification) { - switch (modification) { - case (0): // red + - currentColor.r = 100; currentColor.g = 0; currentColor.b = 0; - break; - case (1): // red - - currentColor.r = 20; currentColor.g = 0; currentColor.b = 0; - break; - case (2): // green + - currentColor.r = 0; currentColor.g = 100; currentColor.b = 0; - break; - case (3): // green - - currentColor.r = 0; currentColor.g = 20; currentColor.b = 0; - break; - case (4): // blue + - currentColor.r = 0; currentColor.g = 0; currentColor.b = 100; - break; - case (5): // blue - - currentColor.r = 0; currentColor.g = 0; currentColor.b = 20; - break; - } - #ifdef PIXELBLADE - lightOn(ledPins, -1, currentColor, NUMPIXELS - 5, NUMPIXELS); - #else if STAR_LED - /*lightOn(ledPins,currentColor); - delay(100); - if (ConfigModeSubStates == CS_MAINCOLOR) { - currentColor.r=storage.sndProfile[storage.soundFont].mainColor.r; - currentColor.r=storage.sndProfile[storage.soundFont].mainColor.g; - currentColor.r=storage.sndProfile[storage.soundFont].mainColor.b; - } - else if (ConfigModeSubStates == CS_CLASHCOLOR) { - currentColor.r=storage.sndProfile[storage.soundFont].clashColor.r; - currentColor.r=storage.sndProfile[storage.soundFont].clashColor.g; - currentColor.r=storage.sndProfile[storage.soundFont].clashColor.b; + #ifdef GRAVITY_COLOR + modification = GravityVector(); + switch (modification) { + case (0): // red + + currentColor.r = 100; currentColor.g = 0; currentColor.b = 0; + break; + case (1): // red - + currentColor.r = 20; currentColor.g = 0; currentColor.b = 0; + break; + case (2): // green + + currentColor.r = 0; currentColor.g = 100; currentColor.b = 0; + break; + case (3): // green - + currentColor.r = 0; currentColor.g = 20; currentColor.b = 0; + break; + case (4): // blue + + currentColor.r = 0; currentColor.g = 0; currentColor.b = 100; + break; + case (5): // blue - + currentColor.r = 0; currentColor.g = 0; currentColor.b = 20; + break; } - else if (ConfigModeSubStates == CS_BLASTCOLOR) { - currentColor.r=storage.sndProfile[storage.soundFont].blasterboltColor.r; - currentColor.r=storage.sndProfile[storage.soundFont].blasterboltColor.g; - currentColor.r=storage.sndProfile[storage.soundFont].blasterboltColor.b; - } - lightOn(ledPins,currentColor);*/ - #endif - //} - //prev_modification=modification; + // in case of a neopixel blade, show the gravity color on the last 5 pixel of the blade tip + #ifdef PIXELBLADE + lightOn(ledPins, -1, currentColor, NUMPIXELS - 5, NUMPIXELS); + #else if STAR_LED + #endif + #ifdef ADF_PIXIE_BLADE + if (ConfigModeSubStates == CS_MAINCOLOR) { + lightOn(ledPins, -1, storage.sndProfile[storage.soundFont].mainColor); + } + else if (ConfigModeSubStates == CS_CLASHCOLOR) { + lightOn(ledPins, -1, storage.sndProfile[storage.soundFont].clashColor); + } + else if (ConfigModeSubStates == CS_BLASTCOLOR) { + lightOn(ledPins, -1, storage.sndProfile[storage.soundFont].blasterboltColor); + } + #endif + #endif // GRAVITY_COLOR } -#endif // PIXELBLADE or STAR_LED +#endif // color configuration for PIXELBLADE or STAR_LED or ADF_PIXIE_BLADE if (ConfigModeSubStates == CS_FLICKERTYPE) { lightFlicker(ledPins, storage.sndProfile[storage.soundFont].flickerType, 0, storage.sndProfile[storage.soundFont].mainColor, storage.sndProfile[storage.soundFont].clashColor, ActionModeSubStates); } @@ -1048,15 +1040,12 @@ void loop() { STANDBY MODE *////////////////////////////////////////////////////////////////////////////////////////////////////////// else if (SaberState == S_STANDBY) { - - //Serial.print("Board supply: ");Serial.println (getBandgap ()); - //Serial.print("Battery: ");Serial.println (analogRead(BATTERY_READPIN)); - //delay(1000); - //BatLevel_ConfigEnter(); - + if (ActionModeSubStates == AS_RETRACTION) { // we just leaved Action Mode //detachInterrupt(0); - + #if defined DEEP_SLEEP + sleepTimer=millis(); // reset sleep time counter + #endif SinglePlay_Sound(soundFont.getPowerOff((storage.soundFont)*NR_FILE_SF)); ActionModeSubStates = AS_HUM; changeMenu = false; @@ -1072,13 +1061,17 @@ void loop() { #endif lightRetract(ledPins, soundFont.getPowerOffTime(), storage.sndProfile[storage.soundFont].poweronoffType,storage.sndProfile[storage.soundFont].mainColor); pixelblade_KillKey_Enable(); + #if defined DEEP_SLEEP + sleepTimer=millis(); // reset sleep time counter + #endif } if (PrevSaberState == S_CONFIG) { // we just leaved Config Mode saveConfig(); PrevSaberState = S_STANDBY; - Disable_FTDI(false); - Disable_MP3(false); - delay(300); + // these commands are not used at the moment and make exit from config mode too long + //Disable_FTDI(false); + //Disable_MP3(false); + //delay(300); /* RESET CONFIG @@ -1115,7 +1108,19 @@ void loop() { #endif accentLEDControl(AL_ON); - + #if defined DEEP_SLEEP and (SLEEPYTIME>5000 and SLEEPYTIME<65000) + if (millis() - sleepTimer > SLEEPYTIME) { // after the defined max idle time SLEEPYTIME automatically go to sleep mode + SaberState=S_SLEEP; + PrevSaberState=S_STANDBY; + // play a beep 3 times + SinglePlay_Sound(1); + delay(500); + SinglePlay_Sound(1); + delay(500); + SinglePlay_Sound(1); + delay(500); + } + #endif } // END STANDBY MODE #ifdef JUKEBOX /*////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1127,7 +1132,7 @@ void loop() { PrevSaberState = S_JUKEBOX; SinglePlay_Sound(14); // play intro sound of JukeBox mode delay(2500); -#ifdef PIXELBLADE +#if defined PIXELBLADE or defined ADF_PIXIE_BLADE pixelblade_KillKey_Disable(); #endif #if defined LS_INFO @@ -1155,11 +1160,23 @@ void loop() { #endif // JUKEBOX #ifdef DEEP_SLEEP else if (SaberState == S_SLEEP) { - if (PrevSaberState == S_CONFIG) { // just entered Sleep mode + Serial.println("LoL"); + + //if (PrevSaberState == S_CONFIG or ) { // just entered Sleep mode //byte old_ADCSRA = ADCSRA; // disable ADC to save power // disable ADC + + // repeat the interupt mask again here, it is already done in the setup() function + // but for an unknown reason sometimes the device fails to wake up... + // pin change interrupt masks (see below list) + //PCMSK2 |= bit (PCINT20); // pin 4 Aux button + //PCMSK0 |= bit (PCINT4); // pin 12 Main button + //delay(300); + //Serial.println("LoL"); ADCSRA = 0; // reduces another ~100uA! + // turns accent LED Off + accentLEDControl(AL_OFF); SleepModeEntry(); // .. and the code will continue from here @@ -1171,7 +1188,7 @@ void loop() { // play boot sound SinglePlay_Sound(11); delay(20); - } + //} } #endif // DEEP_SLEEP } //loop @@ -1218,22 +1235,27 @@ inline void motionEngine() { // (this lets us immediately read more without waiting for an interrupt) mpuFifoCount -= packetSize; +#ifdef SWING_QUATERNION //Making the last orientation the reference for next rotation prevOrientation = curOrientation.getConjugate(); +#endif // SWING_QUATERNION prevAccel = curAccel; //retrieve current orientation value +#ifdef SWING_QUATERNION mpu.dmpGetQuaternion(&curOrientation, fifoBuffer); +#endif // SWING_QUATERNION mpu.dmpGetAccel(&curAccel, fifoBuffer); curDeltAccel.x = prevAccel.x - curAccel.x; curDeltAccel.y = prevAccel.y - curAccel.y; curDeltAccel.z = prevAccel.z - curAccel.z; +#ifdef SWING_QUATERNION //We calculate the rotation quaternion since last orientation prevRotation = curRotation; curRotation = prevOrientation.getProduct( curOrientation.getNormalized()); - +#endif // SWING_QUATERNION #if defined LS_MOTION_HEAVY_DEBUG // display quaternion values in easy matrix form: w x y z printQuaternion(curRotation); @@ -1343,28 +1365,47 @@ void HumRelaunch() { } void SinglePlay_Sound(uint8_t track) { +#ifdef OLD_DPFPLAYER_LIB + mp3_play_physical(track); +#else // DFPlayer_LSOS dfplayer.playPhysicalTrack(track); +#endif } void LoopPlay_Sound(uint8_t track) { +#ifdef OLD_DPFPLAYER_LIB + mp3_loop_play(track); +#else // DFPlayer_LSOS dfplayer.playSingleLoop(track); +#endif } void Set_Volume(int8_t volumeSet) { - //if (volumeSet == -1) { // as a default retreive volume setting from config storage - // dfplayer.setVolume(storage.volume); // Too Slow: we'll change volume on - //} - //else { - dfplayer.setVolume(volumeSet); - //} - delay(50); +#ifdef OLD_DPFPLAYER_LIB + mp3_set_volume (volumeSet); +#else + dfplayer.setVolume(volumeSet); // Too Slow: we'll change volume on exit +#endif +delay(50); } void Set_Loop_Playback() { +#ifdef OLD_DPFPLAYER_LIB + mp3_single_loop(true); +#else dfplayer.setSingleLoop(true);; +#endif } void InitDFPlayer() { +#ifdef OLD_DPFPLAYER_LIB + mp3_set_serial (mp3player); //set softwareSerial for DFPlayer-mini mp3 module + mp3player.begin(9600); + delay(50); + mp3_set_device(1); //playback from SD card + //delay(50); + //mp3_set_volume (storage.volume); +#else dfplayer.setSerial(DFPLAYER_TX, DFPLAYER_RX); // AK 7.9.2016: if the storage.volume has no or invalid value, it will cause the // sketch to repeat setup (reset itself) - up till now no idea why? @@ -1374,14 +1415,23 @@ void InitDFPlayer() { //} //dfplayer.setVolume(storage.volume); //setup finished. Boot ready. We notify ! +#endif } void Pause_Sound() { +#ifdef OLD_DPFPLAYER_LIB + mp3_pause(); +#else dfplayer.pause(); +#endif } void Resume_Sound() { +#ifdef OLD_DPFPLAYER_LIB + mp3_play(); +#else dfplayer.play(); +#endif } #ifdef DEEP_SLEEP @@ -1406,6 +1456,10 @@ void sleepNow() // here we put the arduino to sleep PCIFR |= bit (PCIF0) | bit (PCIF1) | bit (PCIF2); // clear any outstanding interrupts PCICR |= bit (PCIE0) | bit (PCIE1) | bit (PCIE2); // enable pin change interrupts + //PCMSK0 |= bit (PCINT4); // enable pin change interrupt pin 12 Main button + //delay(300); + //enableInterrupt(12, SleepModeExit, CHANGE); + sleep_mode(); // here the device is actually put to sleep!! // THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP diff --git a/Light.cpp b/Light.cpp index 78e204e..1c96450 100644 --- a/Light.cpp +++ b/Light.cpp @@ -1,7 +1,7 @@ /* * Light.cpp * - * author: Sebastien CAPOU (neskweek@gmail.com) and Andras Kun (kun.andras@yahoo.de) + * author: Sebastien CAPOU (neskweek@gmail.com) and Andras Kun (kun.andras@yahoo.de)lightClashEffect * Source : https://github.com/neskweek/LightSaberOS */ #include "Light.h" @@ -75,6 +75,7 @@ static byte heat[NUMPIXELS]; #define PIXELSTEP 5// how many pixel to treat as a group to save on processing capability #endif // PIXELBLADE + /* ***************** UNIFIED LIGHT FUNCTIONS *********************/ #define I_BEGINNEXTSEGMENT 50 @@ -91,10 +92,20 @@ static long lastFlicker = millis(); extern WS2812 pixels; #endif -#if defined STAR_LED or defined PIXELBLADE +#if defined STAR_LED or defined PIXELBLADE or defined ADF_PIXIE_BLADE extern cRGB currentColor; #endif +#ifdef ADF_PIXIE_BLADE + SoftwareSerial pixieSerial(-1, PIXIEPIN); + Adafruit_Pixie strip = Adafruit_Pixie(NUMPIXELS, &pixieSerial); +#endif + +#ifdef COLOR_PROFILE +// define an array for the 15 color profiles +cRGB colorProfiles[15]; +//colorProfiles[0].r=255; +#endif // ==================================================================================== // === LED FUNCTIONS === // ==================================================================================== @@ -117,6 +128,13 @@ void lightOn(uint8_t ledPins[], int8_t segment = -1, cRGB color={0,0,0}, int8_t analogWrite(ledPins[1], color.g); // GREEN analogWrite(ledPins[2], color.b); // BLUE #endif + + #ifdef ADF_PIXIE_BLADE + for(uint8_t i=0; i< NUMPIXELS; i++) { + strip.setPixelColor(i, color.r, color.g, color.b); + } + strip.show(); + #endif #ifdef PIXELBLADE // Light On @@ -151,6 +169,13 @@ void lightOff() { digitalWrite(LED_GREEN, LOW); // GREEN digitalWrite(LED_BLUE, LOW); // BLUE #endif + + #ifdef ADF_PIXIE_BLADE + for(uint8_t i=0; i< NUMPIXELS; i++) { + strip.setPixelColor(i, 0, 0, 0); + } + strip.show(); + #endif #ifdef PIXELBLADE // shut Off @@ -177,6 +202,12 @@ void getColor(cRGB color={0,0,0}) { currentColor.b = color.b; #endif + #ifdef ADF_PIXIE_BLADE + currentColor.r = color.r; + currentColor.g = color.g; + currentColor.b = color.b; + #endif + #ifdef PIXELBLADE currentColor.r = color.r; currentColor.g = color.g; @@ -191,6 +222,10 @@ void RampBlade(uint16_t RampDuration, bool DirectionUpDown, int8_t StartPixel=-1 #if defined STAR_LED + #endif + + #ifdef ADF_PIXIE_BLADE + #endif #ifdef PIXELBLADE @@ -305,11 +340,23 @@ void lightIgnition(uint8_t ledPins[], uint16_t time, uint8_t type, cRGB color={0 #if defined STAR_LED // Fade in to Maximum brightness - for (uint8_t fadeIn = MAX_BRIGHTNESS-50; fadeIn > 0; fadeIn--) { - analogWrite(LED_RED, (MAX_BRIGHTNESS / fadeIn) * color.r / rgbFactor); // RED - analogWrite(LED_GREEN, (MAX_BRIGHTNESS / fadeIn) * color.g / rgbFactor); // GREEN - analogWrite(LED_BLUE, (MAX_BRIGHTNESS / fadeIn) * color.b / rgbFactor); // BLUE - delay(time / (MAX_BRIGHTNESS-50)); + for (uint8_t fadeIn = 0; fadeIn < 255; fadeIn++) { + analogWrite(LED_RED, color.r * fadeIn / 255); // RED + analogWrite(LED_GREEN, color.g * fadeIn / 255); // GREEN + analogWrite(LED_BLUE, color.b * fadeIn / 255); // BLUE + delay(time / 255); + } + #endif + + #ifdef ADF_PIXIE_BLADE + + // Fade in to Maximum brightness + for (uint8_t fadeIn = 0; fadeIn < 255; fadeIn++) { + for(uint8_t i=0; i< NUMPIXELS; i++) { + strip.setPixelColor(i, color.r * fadeIn / 255, color.g * fadeIn / 255, color.b * fadeIn / 255); + } + strip.show(); + delay(time / 255); } #endif @@ -374,14 +421,25 @@ void lightRetract(uint8_t ledPins[], uint16_t time, uint8_t type,cRGB color={0,0 #endif #if defined STAR_LED - // Fade out - for (uint8_t fadeOut = 1; fadeOut < MAX_BRIGHTNESS-50; fadeOut++) { - analogWrite(LED_RED, (MAX_BRIGHTNESS / fadeOut) * color.r / rgbFactor); // RED - analogWrite(LED_GREEN, (MAX_BRIGHTNESS / fadeOut) * color.g / rgbFactor); // GREEN - analogWrite(LED_BLUE, (MAX_BRIGHTNESS / fadeOut) * color.b / rgbFactor); // BLUE - delay(time / (MAX_BRIGHTNESS-50)); + // Fade in to Maximum brightness + for (uint8_t fadeIn = 255; fadeIn > 0; fadeIn--) { + analogWrite(LED_RED, color.r * fadeIn / 255); // RED + analogWrite(LED_GREEN, color.g * fadeIn / 255); // GREEN + analogWrite(LED_BLUE, color.b * fadeIn / 255); // BLUE + delay(time / 255); + } + #endif + + #ifdef ADF_PIXIE_BLADE + + // Fade in to Maximum brightness + for (uint8_t fadeIn = 255; fadeIn > 0; fadeIn--) { + for(uint8_t i=0; i< NUMPIXELS; i++) { + strip.setPixelColor(i, color.r * fadeIn / 255, color.g * fadeIn / 255, color.b * fadeIn / 255); + } + strip.show(); + delay(time / 255); } - lightOff(); #endif #ifdef PIXELBLADE @@ -538,6 +596,15 @@ void lightFlicker(uint8_t ledPins[],uint8_t type, uint8_t value = 0,cRGB maincol break; } #endif + + #ifdef ADF_PIXIE_BLADE + for(uint8_t i=0; i< NUMPIXELS; i++) { + Serial.print("\t");Serial.print(brightness);Serial.print("\t");Serial.print(maincolor.g);Serial.print("\t");Serial.println((brightness * maincolor.r) / rgbFactor); + //strip.setPixelColor(i, ((brightness * maincolor.r) / rgbFactor), ((brightness * maincolor.r) / rgbFactor), ((brightness * maincolor.r) / rgbFactor));//maincolor.r, maincolor.g, maincolor.b); + strip.setPixelColor(i, maincolor.r,maincolor.g, maincolor.b);//maincolor.r, maincolor.g, maincolor.b); + } + strip.show(); + #endif #ifdef PIXELBLADE if (StartPixel == -1 or StopPixel==-1 or StopPixelNUMPIXELS or StopPixel>NUMPIXELS) { // if neither start nor stop is defined or invalid range, go through the whole stripe // neopixel ramp code from jbkuma @@ -665,7 +732,7 @@ void ColorMixing(cRGB colorID={0,0,0}, int8_t mod=-1, uint8_t maxBrightness=MAX_ #endif - #if defined(PIXELBLADE) or defined(STAR_LED) + #if defined PIXELBLADE or defined STAR_LED or defined ADF_PIXIE_BLADE cRGB mixedColor; mixedColor.r=colorID.r; mixedColor.g=colorID.g; @@ -737,6 +804,12 @@ void ColorMixing(cRGB colorID={0,0,0}, int8_t mod=-1, uint8_t maxBrightness=MAX_ analogWrite(LED_GREEN, currentColor.g); // GREEN analogWrite(LED_BLUE, currentColor.b); // BLUE #endif + #ifdef ADF_PIXIE_BLADE + for(uint8_t i=0; i< NUMPIXELS; i++) { + strip.setPixelColor(i, currentColor.r, currentColor.g, currentColor.b); + } + strip.show(); + #endif #endif } // ColorMixing @@ -749,6 +822,13 @@ void lightBlasterEffect(uint8_t ledPins[], uint8_t pixel, uint8_t range, cRGB Sn lightOn(ledPins, -1, currentColor); #endif + #ifdef ADF_PIXIE_BLADE + for(uint8_t i=0; i< NUMPIXELS; i++) { + strip.setPixelColor(i, currentColor.r, currentColor.g, currentColor.b); + } + strip.show(); + #endif + #ifdef PIXELBLADE cRGB blastcolor; cRGB fadecolor; @@ -762,6 +842,23 @@ void lightBlasterEffect(uint8_t ledPins[], uint8_t pixel, uint8_t range, cRGB Sn heat[pixel-i] = 0; // white hot fire burst along the whole blade } else { + uint8_t j=i+pixel; + if (j==pixel or j==pixel+2*range) { // 2 pixels at the edges shall be shut down + fadecolor.r = 0; + fadecolor.g = 0; + fadecolor.b = 0; + pixels.set_crgb_at(j, fadecolor); + } + else if (j==pixel+range+1) { // middle pixel full white + fadecolor.r = MAX_BRIGHTNESS; + fadecolor.g = MAX_BRIGHTNESS; + fadecolor.b = MAX_BRIGHTNESS; + pixels.set_crgb_at(j, fadecolor); + } + else { // rest of the pixels between middle and edge + pixels.set_crgb_at(j, blastcolor); + } + /* for (uint8_t j = 0; j <=range; j++) { if (j==i) { pixels.set_crgb_at(pixel-j, blastcolor); @@ -771,7 +868,7 @@ void lightBlasterEffect(uint8_t ledPins[], uint8_t pixel, uint8_t range, cRGB Sn pixels.set_crgb_at(pixel-j, currentColor); pixels.set_crgb_at(pixel+j, currentColor); } - } + }*/ pixels.sync(); if (not fireblade) { delay(BLASTER_FX_DURATION/(2*range)); // blast deflect should last for ~500ms @@ -782,7 +879,7 @@ void lightBlasterEffect(uint8_t ledPins[], uint8_t pixel, uint8_t range, cRGB Sn } // lightBlasterEffect void pixelblade_KillKey_Enable() { - #ifdef PIXELBLADE + #if defined PIXELBLADE or defined ADF_PIXIE_BLADE // cut power to the neopixels stripes by disconnecting their GND signal using the LS pins digitalWrite(3, LOW); digitalWrite(5, LOW); @@ -790,12 +887,16 @@ void pixelblade_KillKey_Enable() { digitalWrite(9, LOW); digitalWrite(10, LOW); digitalWrite(11, LOW); - digitalWrite(DATA_PIN,HIGH); // in order not to back-connect GND over the Data pin to the stripes when the Low-Sides disconnect it + #ifdef PIXELBLADE + digitalWrite(DATA_PIN,HIGH); // in order not to back-connect GND over the Data pin to the stripes when the Low-Sides disconnect it + #else if ADF_PIXIE_BLADE + digitalWrite(PIXIEPIN,HIGH); // in order not to back-connect GND over the Data pin to the stripes when the Low-Sides disconnect it + #endif #endif } void pixelblade_KillKey_Disable() { - #ifdef PIXELBLADE + #if defined PIXELBLADE or defined ADF_PIXIE_BLADE // cut power to the neopixels stripes by disconnecting their GND signal using the LS pins digitalWrite(3, HIGH); digitalWrite(5, HIGH); @@ -818,6 +919,11 @@ void lightClashEffect(uint8_t ledPins[], cRGB color) { getColor(color); lightOn(ledPins, -1, currentColor); #endif + + #ifdef ADF_PIXIE_BLADE + //getColor(storage.sndProfile[storage.soundFont].clashColor); + lightOn(ledPins, -1, color); + #endif #if defined PIXELBLADE if (fireblade) { // #if defined FIREBLADE // simply flash white @@ -907,10 +1013,43 @@ void BladeMeter (uint8_t ledPins[], int meterLevel) { //expects input of 0-100 #endif } - - - - +#ifdef ADF_PIXIE_BLADE +void InitAdafruitPixie(uint8_t ledPins[]) { + //pixieSerial.setSerial(-1, PIXIEPIN); + pixieSerial.begin(115200); // Pixie REQUIRES this baud rate + strip.setBrightness(MAX_BRIGHTNESS); // Adjust as necessary to avoid blinding + /*pixelblade_KillKey_Disable(); + Serial.println("Red!"); + for(uint8_t i=0; i< NUMPIXELS; i++) + strip.setPixelColor(i, 255, 0, 0); + strip.show(); + delay(300); + + Serial.println("Green!"); + for(uint8_t i=0; i< NUMPIXELS; i++) + strip.setPixelColor(i, 0, 255, 0); + strip.show(); + delay(300); + + Serial.println("Blue!"); + for(uint8_t i=0; i< NUMPIXELS; i++) + strip.setPixelColor(i, 0, 0, 255); + strip.show(); + delay(300); + currentColor.r = 0; + currentColor.g = 200; + currentColor.b = 255; + lightOn(ledPins, -1, currentColor); + delay(300); + for(uint8_t i=0; i< NUMPIXELS; i++) + strip.setPixelColor(i, 255, 0, 0); + strip.show(); + delay(1000); + lightOff(); + getColor(storage.sndProfile[storage.soundFont].mainColor); + pixelblade_KillKey_Enable();*/ +} +#endif @@ -1204,7 +1343,30 @@ uint8_t scale8_video( uint8_t i, uint8_t scale) }*/ #endif - +#ifdef COLOR_PROFILE +cRGB setColorProfile(cRGB currentcolor) { +// Red +colorProfiles[0].r=255; +colorProfiles[0].g=0; +colorProfiles[0].b=0; +// Green +colorProfiles[1].r=0; +colorProfiles[1].g=255; +colorProfiles[1].b=0; +// Blue +colorProfiles[2].r=0; +colorProfiles[2].g=0; +colorProfiles[2].b=255; +// Orange +colorProfiles[3].r=255; +colorProfiles[3].g=100; +colorProfiles[3].b=0; +// Cyan +colorProfiles[4].r=0; +colorProfiles[4].g=100; +colorProfiles[4].b=255; +} +#endif #if defined ACCENT_LED void accentLEDControl( AccentLedAction_En AccentLedAction) { diff --git a/Light.h b/Light.h index f315e7b..5b42d2d 100644 --- a/Light.h +++ b/Light.h @@ -28,6 +28,7 @@ struct softPWM { #endif #endif + // ==================================================================================== // === LED FUNCTIONS === // ==================================================================================== @@ -55,6 +56,10 @@ void pixelblade_KillKey_Disable(); void FoCOn (uint8_t pin); void FoCOff (uint8_t pin); +#ifdef ADF_PIXIE_BLADE + void InitAdafruitPixie(uint8_t ledPins[]); +#endif + #ifdef PIXELBLADE //#ifdef FIREBLADE diff --git a/README.md b/README.md index 0ef33b4..23ef562 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,496 @@ -![alt text](https://github.com/Protonerd/FX-SaberOS/blob/master/README/22489987_10214390565742471_6678630774083988688_n.jpg) +# LightSaberOS -# FX-SaberOS -System code for Arduino based Lightsaber replicas for DIYino family boards and Arduino based home brew systems. +________________________________________________________________________________ -This repository is currently in development. The currently posted builds should be fully functional, but are undergoing rapid changes and there will likely be big changes in the versions prior to the official release. Please check back soon! +## VIDEOS -Installation and configuration instructions are available in the Wiki https://github.com/Protonerd/FX-SaberOS/wiki +[![DIYino demo of Neopixel lightsaber blade with LSOS] (http://img.youtube.com/vi/PjXLKvWpA8A/0.jpg)](https://www.youtube.com/watch?v=PjXLKvWpA8A) +_This is a modified version of the neopixel code. LSOS doesn't come with this fire effect out of the box ;)_ +[![DIYino prototype demo with LSOS by neskweek - Swings] (http://img.youtube.com/vi/tU3GZzV9I6E/0.jpg)](http://www.youtube.com/watch?v=tU3GZzV9I6E)[![Motion Detection Demo (made under v1.0 RC5)] (http://img.youtube.com/vi/wY8BSSEyYLY/0.jpg)](http://www.youtube.com/watch?v=wY8BSSEyYLY)[![Quick tour (made under v1.0 RC4)] (http://img.youtube.com/vi/mc8scn_qyFM/0.jpg)](http://www.youtube.com/watch?v=mc8scn_qyFM) -Please share your projects and join the discussion with our Facebook group at https://www.facebook.com/groups/FXSaberOS/ +________________________________________________________________________________ + +### FEATURES : + +* Simple modular systems (you can choose to remove some systems from your final compilation) +* Swing detection +* Blade Clash detection +* Wrist movement detection +* Full gapless sound playing with "Hum Extended" soundfiles (see below) +* Blaster Shot deflect +* Blade Lockup (long press on Aux switch. Plays until release of the button) +* Accent LED +* Flash-on-Clash LEDString +* Multiple ignition/retractation/flickering effects +* Config Menu to modify some features without wiring the device to your PC/Mac +* EEPROM load/save of your config preferences +* Soundfont adding supported (not automatic, you'll have little work to do ;) ) + +________________________________________________________________________________ + +### WHAT YOU WILL NEED : +* [Java Runtime Environment 8](http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html) +Download the right file for your architecture +* [Arduino IDE](https://www.arduino.cc/en/Main/Software) (advised for end user) +OR + [Arduino Eclipse v3.0](http://www.baeyens.it/) (advised for developpers) +Again, download the right files for your architecture +* my new DFPlayer library (Included in zip file) +* [I2Cdev and MPU6050 (Included in zip file)](https://codeload.github.com/jrowberg/i2cdevlib/zip/master) +* [EEPROMex9.1 (Included in zip file)](http://thijs.elenbaas.net/wp-content/uploads/downloads/2013/12/EEPROMEx-9.1.zip) +* [OneButton (Included in zip file)] (https://github.com/mathertel/OneButton) +* [LinkedList (Included in zip file)] (https://github.com/ivanseidel/LinkedList) +* Wire (Included in Arduino Eclipse) + +________________________________________________________________________________ + +### DEVICE CURRENTLY SUPPORTED : + +Designed to be used on [DIYino boards](https://github.com/Protonerd/DIYino) (recommended) +Designed to be used on Arduino Nano, Arduino Pro mini (ATmega328 processors) + +* IMU (accelerometer + gyroscope) modules : + * MPU6050 +* Soundplayer modules: + * DFPlayer Mini +* Blade module: + * homemade LEDstrings + * RGB LEDs (Luxeon/Cree styled) + * Single LED + * Neopixel strings + +I would be glad to see other modules added. If you're interested to make your device compatible, please contact me. + +________________________________________________________________________________ + +## SET UP FOR ARDUINO IDE: + +These instructions should work for IDE version 1.6.0 and greater and may work with 1.5.x also. If compiling hangs with 1.6.4, try again with File > Preferences > Compiler warnings: None. + +0. Download and install Arduino IDE +1. Download https://github.com/neskweek/LightSaberOS/archive/master.zip. +2. Unzip the downloaded file LightSaberOS-master.zip. +3. Rename the unzipped folder from LightSaberOS-master to LightSaberOS. +4. Move all folders inside LightSaberOS/Libraries to {sketchbook folder}/libraries. You can find the location of your sketchbook folder at File > Preferences > Sketchbook location. +5. Open the file LightSaberOS/LightSaberOS.ino. +6. Connect the USB cable to your Arduino. +7. Select the correct board in Tools > Board. +8. Select the correct port in Tools > Port. +9. Follow the Project Setup instructions at https://github.com/neskweek/LightSaberOS. +10. Once all configuration changes have been made to LightSaberOS.ino, do Sketch > Upload. + +________________________________________________________________________________ + +## SET UP YOUR PC FOR ECLIPSE USE (OPTIONAL): + +For people who don't want to use Eclipse Arduino, and prefer use Arduino IDE (which is really simpler if you don't plan to code) you can jump off to project setup section. + +LSOS is now fully compatible with Arduino IDE thanks to [Pert (per1234)] (https://github.com/per1234) + +1. Download and install [Java Runtime Environment 8](http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html) +Download the right file for your OS +2. Download [Arduino Eclipse v3.0](http://www.baeyens.it/) +Again, download the right file for your OS +3. Uncompress this archive inside c:\Program Files +4. Start C:\Program Files\eclipseArduino\eclipseArduinoIDE.exe +On first start up you will be ask where to put your prject workspace. +I advise you to put it there (off course replace "neskw" by your username) : +![Set workspace destination](https://raw.githubusercontent.com/neskweek/LightSaberOS/master/README/eclipse1.PNG) +On first startup it will download a bunch of stuff related to Arduino Libraries. +Wait until it finishes +5. Go to Windows > Preferences +6. Select Arduino and set "Build before upload ?" to "Yes" and press OK +7. Plug in your Arduino device +It would be best that you always use the same USB port for future use +8. Go to File > New > Arduino sketch +![Project Name](https://raw.githubusercontent.com/neskweek/LightSaberOS/master/README/eclipse2.PNG) +Then press next +![Fill in your board Info](https://raw.githubusercontent.com/neskweek/LightSaberOS/master/README/eclipse3.PNG) +COM port may be different on your PC. It depends on USB port you plugged it in. +Then press next +![Optional Check AVaRICE](https://raw.githubusercontent.com/neskweek/LightSaberOS/master/README/eclipse4.PNG) +Here Checking AVaRICE is optional +Then press Finish +9. Delete LightSaberOS.ino file + +________________________________________________________________________________ + +## IMPORT GITHUB FILES INSIDE ECLIPSE PROJECT: + +1. Uncompress LightSaberOS-master.zip archive +2. If not already done create this directory : C:\Users\__[YOUR USERNAME]__\Arduino +3. Copy and Paste LightSaberOS-master\Libraries directory inside C:\Users\__[YOUR USERNAME]__\Arduino +4. Inside Eclipse Right click on LightSaberOS project > Import +![Import source files](https://raw.githubusercontent.com/neskweek/LightSaberOS/master/README/eclipse5.PNG) +Then press Next +![Select source directory](https://raw.githubusercontent.com/neskweek/LightSaberOS/master/README/eclipse6.PNG) +Then press Next +In "Eclipse Project explorer" open the new created LightSaberOS-master and select those files : +![Select source directory](https://raw.githubusercontent.com/neskweek/LightSaberOS/master/README/eclipse7.PNG) +Then drag and drop them to the root structure of the project +5. Inside Eclipse Right click on LightSaberOS project > Import +![Import Libraries](https://raw.githubusercontent.com/neskweek/LightSaberOS/master/README/eclipse8.PNG) +Then press Next +Select those libraries : +![Select Libraries](https://raw.githubusercontent.com/neskweek/LightSaberOS/master/README/eclipse9.PNG) +Then press Finish +6. Delete LightSaberOS-master directory from Eclipse Project explorer + + +You should end up with this Project explorer structure : +![Project structure](https://raw.githubusercontent.com/neskweek/LightSaberOS/master/README/eclipse10.PNG) + +If so, Then you're ready to rock ! + +________________________________________________________________________________ + + + +### PROJECT SETUP + +#### 0. General Warnings + +You are decided to build your lightsaber. Cool ! +Don't think I want to deceive you from your goal but you 'll have to keep those things in mind : + +* ___This project is not plug and play !___ It's tough, time consuming and you'll spend some times in trial and errors. But it's also highly rewarding once completed with success. +* ___This project might be cheap___, but it's highly unlikely. If you don't make mistake it can be. If you do you'll have to go on spare parts,etc... and costs can grew up. +* ___Think twice about your power supply/LED relations ! This is CRUCIAL!___ A power supply that gives to much voltage for your LEDs will result in burned LEDs. We don't recommend the use of power supply that exceed total LED's voltage capacity. While it's still possible, if you do go down this path, calculate, think, ask questions and USE A MULTIMETER ! +Beware of MAX_BRIGHTNESS setting. While this can remove some voltage from your LEDs it's certainly can not remove too much. Each MOSFETs can take a certain amount of voltage but it will heat up. And too much it can ruin your MOSFET or your DIYNO card. +This choice is ___THE MOST IMPORTANT CHOICE___ for your device !!!! +Also mind the intensity (Amps) your setup will require... +I told you it will be tough ! +* ___You will have shorts !!!___ Well I hope you don't, in fact. Keep in mind that solders on your board are not bullet proof, even for experienced people. The more your board will move, the more these solderings will be exposed to breakage and that will lead to short cuts. On a fully completed blade, this mostly results in unresponsivness : the blade will stops flickering, you won't hear anymore swings and you won't be able to retract the blade until you cut the power off (remove battery, or plug a kill key). +Isolate your buttons leads too, contact with metal hull => short cut. You'll want thermoretractable sheath and maybe hot glue. +* ___Consider a kill key !___ They'll preserve your batteries from draining out when you're not using your saber, allows you to recharge your saber, allows you to quickly shut down your saber.... You want to put a kill key ! + +#### 1. IMU calibration + First, you'll need (if not already done) to calibrate your MPU6050. + [I recommend you use the AutoCalibration script you can find here](http://www.i2cdevlib.com/forums/topic/96-arduino-sketch-to-automatically-calculate-mpu6050-offsets/) + Note the offset values it will give you and replace those you'll find inside setup() function in __Lightsaber.ino__ : +```c++ + /* + * Those offsets are specific to each MPU6050 device. + * they are found via calibration process. + * See this script http://www.i2cdevlib.com/forums/index.php?app=core&module=attach§ion=attach&attach_id=27 + */ + mpu.setXAccelOffset(-2645); + mpu.setYAccelOffset(-5491); + mpu.setZAccelOffset(3881); + mpu.setXGyroOffset(27); + mpu.setYGyroOffset(-135); + mpu.setZGyroOffset(-38); +``` + +#### 2. Determine IMU orientation + The way you physically installed the MPU6050 in your hilt will influence how swing detection works. + You'll have to determine which IMU's axis is parallel to blade axis and change it accordingly in __Config.h__ : +```c++ +//#define BLADE_X +#define BLADE_Y +//#define BLADE_Z +``` + + +#### 3. Prepare your SDCard +Then, put the content of _SDCard.7z_ on your SDCard: + +1. Format your SDCard. __I insist !__ (go read __HOW TO MANAGE YOUR SDRCARD__ section for further explanation) +2. Unzip SDCard.7z to a folder +3. Select all the files from this folder and __"Drag and Drop"__ them to your SDCard. __NO COPY AND PASTE !!!__ : +We need to have this file copied in the same order as their filename order. On Microsoft Windows, Copy/paste produce an anarchic copy order, but Drag and Drop produce an ordered copy as long as you select the first file to init the drag... + + +#### 4. Check Wirings +_If you use DIYino board, don't mind that paragraph._[Go there instead and read user manual](https://github.com/Protonerd/DIYino) +_If you use DIYino board, and want flicker effect wire SPK+ to A6 and SPK- to A7._ + +Using **Protonerd's** wirings. +Don't forget to wire those ones which were added : +* DFPLAYER TX to D7 +* DFPLAYER SPK+ to A6 +* DFPLAYER SPK- to A7 +![Schematics](http://i1073.photobucket.com/albums/w385/cest_bastien1/Lightsaber/AS2_LEDstringSaberArduino_NeskweekRevised_zpsu5k0ljck.png) +Wiring of busy pin is optional since LightSaberOS doesn't use it. + + + + + + + + + + + + + + + +#### 5. Select your emitter type + + +###### A.LEDSTRINGS +In __Config.h__ be sure this line is uncommented : +```c++ +#define LEDSTRINGS +``` + +###### B. RGB LEDs +In __Config.h__ comment this line : +```c++ +#define LEDSTRINGS +``` + +###### C. Single LED +* a) Wire your LED on pin D3 + +* b) In __Config.h__ comment this line : + +```c++ +#define LEDSTRINGS +``` +* c) Modify the following lines in __LightSaber.ino__ so all variables are set to 0 : + +```c++ +#ifdef LUXEON + storage.mainColor = 0; + storage.clashColor = 0; + storage.soundFontColorPreset[2][0] = 0; + storage.soundFontColorPreset[2][1] = 0; + storage.soundFontColorPreset[3][0] = 0; + storage.soundFontColorPreset[3][1] = 0; +#endif +``` + +#### 6. Compile and Upload the sketch to your Arduino device + +#### 7. Enjoy + +________________________________________________________________________________ + +## HOW IT WORKS : + +###### _In Standby Mode (idle)_ : +* Short press on Main switch : activate your saber (Action Mode) +* Long press on Aux switch : activate Config Mode +* if idle for more than 5 min : PowerSaving mode. + +###### _In PowerSaving Mode (idle)_ : +* Short press on Main switch or Aux switch : leave PowerSaving Mode (go back to Standby Mode) + + +###### _In Action Mode_ : +* Move your saber around : Swing effect +* Hit the hilt/blade : Clash effect +* Short press Aux switch : Enable/disable Blaster block modes. Move your saber to produce Blaster effects. +* Long press Aux switch : Blade Lockup effect +* Long press Main switch : Shutdown saber + + + + +###### _In Config Mode_ : +* short press Main switch : Up the value +* short press Aux switch : Down the value +* long press Main switch : Change menu : + * Volume + * SoundFont + * [ONLY FOR LEDSTRING USERS] Power On effect: change the type of ignition for the current SoundFont + * [ONLY FOR LEDSTRING USERS] Power Off effect: change the type of retractation for the current SoundFont + * [ONLY FOR LEDSTRING USERS] Flicker effect: change the type of flickering for the current SoundFont + * [ONLY FOR RGB LED USERS] Main color : change the color of your saber + * [ONLY FOR RGB LED USERS] Clash color: change the color displayed during clash effect + * [ONLY FOR RGB LED USERS] Assign colors to current soundfont ? : Allows you to save the colors you just defined to the current SoundFont + * Swing sensitivity : adjust swing sensitivity. + +* Long press Aux switch : update config to EEPROM and leave Config Mode + +________________________________________________________________________________ + +### HOW TO MANAGE YOUR SDCRAD +#### 1. For DFPlayer Mini + +While there are several ways to make DFPlayer Mini plays your sound files from your SDard, only one can provide full gapless sound "enqueuing" : we need to call each sound file by their copy order number. + +Let's say you have a fresh formatted SDcard. +You copy one file on it : its copy order is 1. +You copy another one: its copy order is 2. +You copy another one: its copy order is 3. + +Now the main "problem" to be aware of is : you remove file 2 (because you maybe want to replace it) : file 3 keep is order number. +You copy another one: its copy order is 4. + +In that case the only proper way to manage your SDCard I found is he following : +1. You create a folder called _sdcard_ on your computer +2. Using a batch renamer utility (I personnaly use [Bulk Rename Utility](http://www.bulkrenameutility.co.uk/Main_Intro.php)) you rename and copy your sound files to that folder in the order you planned +3. You format your SDCard +4. You select all your files from _sdcard_ directory and __DRAG AND DROP__ them to your SDCard. + +Drag and drop on windows genereate a ordered copy following file name sorting. +Copy and paste (Crtl+C/Ctrl+V) generate an anarchic ordered copy. Don't use it ! + +Each time you will want to modify one file you'll have to do it that way. Adding files on he other hand can be done without formatting. + +Files MUST be named that way : +_XXXX[-myfileName].wav_ +where : +* XXXX is the order number planned (ex.: 0001, 0002, 2568,...) +* [-myfileName] is OPTIONNAL. But I encourage you to put one to ease up organisation. +__YOU MUST ABSOLUTLY AVOID ALL GAPS IN THE ORDER NUMBER YOU PLANNED !!!__ + +You can put files in different folders if you like. You don't necessarily need to let them on SDCard root. +__BUT STILL BEWARE OF THOSE NUMBERS !!!!__ +Here are different examples of organisation you can use : + +* All in SDCard root (like SDCard.7z example provided) +* 1 folder for each SoundFonts. For example : + * **_CONFIG_** folder containing files numbered 0001 to 0020 + * **_Barlow's_** folder containing files numbered 0021 to 0053 + * **_MySoundfont_** folder containing files numbered 0079 to 0124 + * **_ZZZZZ_** folder containing files numbered 0054 to 0078 +In this example files in ZZZZZ have been copied BEFORE those in MySoundfont +* an other example of organisation : + * **_CONFIG_** folder containing files numbered 0001 to 0020 + * **_Barlow's_** folder containing files 0021-PowerOn.wav, 0022-PowerOff.wav,0023-Hum.wav,0024-Boot.wav + * **_Swing_** folder containing only swing sound files numbered 0025 to 1075 + * **_Clash_** folder containing only clash sound files numbered 1076 to 1078 + * **_Blaster_** folder containing only blaster sound files numbered 1079 to 2001 + * **_Lockup_** folder containing only lockup sound files numbered 2002 to 2024 + * **_MySoundFont_** folder containing files numbered 2025-Hum.wav, 2026-Boot.wav 2027-PowerOff.wav,2028-PowerOn.wav +In that case, the user wants to be able to use all of his swing/clash/blaster/lockup/etc. sounds with every of its soundfont. +He can also configure some soundfont to use just a part like for example Swings 0100 to 0153. + +________________________________________________________________________________ + +### HOW TO PERSONNALIZE CONFIG MENU SOUNDS + +Let's say you want to change the lady voice or ladies users may want their saber with a male voice or you may want her to talk in Dutch or French or Italian or Spanish (name your langage here). + + +I used [this online free Text-To-Speech generator](http://www.fromtexttospeech.com/) to produce those sounds. +You can produce your own sentences with it or use any other Text-To-Speech program. +For example : +"Hello Master! You just entered into Config Mode !" +Then rename the file it produces : 0001-CONFIG-ConfigMode.mp3. Remove old 0001-CONFIG-ConfigMode.wav file. + + +**_N.B.:_** +1. _Only in Config Mode case_, mp3 are OK to use. We don't care in this mode if there's sound gap. +2. Every changes in sounds file will force you to format your SDCard and copy the whole lot again. +________________________________________________________________________________ + +### HOW TO MAKE YOUR OWN SOUNDFONT + +[In this video](https://www.youtube.com/watch?v=Q_6VITJT0-w), you'll learn how to create the differents lightsabers sounds-effects. + +You can experiment with different device to produce some unique sounds. + +Then use Audacity to mix them. + +Final sounds **MUST BE** in WAV format (**_NO MP3 ! NO WMA!_**)! +When encoding a sound to those format (MP3 or WMA) the encoder will automaticly put a silence at start. +________________________________________________________________________________ + +## License: + +This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. +To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/]http://creativecommons.org/licenses/by-nc-sa/4.0/ . + +________________________________________________________________________________ + +## TODO : +By priority : +* Better README.md (Work in progress) +* Try to reduce compiled hex file +* Rewrite to Object Oriented form, using JakeSoft's [USaber Library](https://github.com/JakeS0ft/USaber) +* Find a use to: + * short press Aux switch in standby mode + * double click on Main switch in action/config/standby mode + * double clik on Aux switch in action/config/standby mode. +* Rewrite some function in Assembler +* Pitch shifting on movements (don't know if it's feasable)... + +________________________________________________________________________________ + +## THANK YOU !!! + +Thanks to Andras Kun (__Protonerd__ from Arduino Forum) for initiating this project, providing [DIYino Boards](https://github.com/Protonerd/DIYino) and his big contributions to LSOS Code +Thanks to __Jakesoft__ from Arduino Forum for : +* his initial idea of using Arduino device to build a lightsaber. +* his idea of using Aux Switch as a triger mode for Blaster Blocks. +and many more source of inspirations. You can also use his [USaber lib](https://github.com/JakeS0ft/USaber) to build your own code to operate your saber. + +Thanks to [__Joe Barlow__](https://www.freesound.org/people/joe93barlow/) for his excellent opensource soundfont that I did remix for our needs. +Thanks to __YOU__ for using it ;) + +________________________________________________________________________________ + +## WITH YOUR HELP... +... a real life lightsaber which cut through stuffs, like a pizza, could be made... +But first things first : I need the pizza ! +[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=GX6M3586YU8JL) +;) +________________________________________________________________________________ + +## FINAL THOUGHTS + +I hope you'll like it. + +Don't hesitate to reports bugs (I've made a lot of test but... hey !), or suggest new functionallity. +If you want to contribute to this project, please contact me via mail or on the [thread of this project] (http://forum.arduino.cc/index.php?topic=361566.0) +________________________________________________________________________________ +________________________________________________________________________________ +________________________________________________________________________________ +________________________________________________________________________________ +________________________________________________________________________________ + +________________________________________________________________________________ +________________________________________________________________________________ + + +##12/03/2016 : The following might not be accurate since release of version 1.0 +## Modification of this Readme is a "work in progress" +## More info regarding LSOS will be added +## Thank you for your patience +________________________________________________________________________________ +________________________________________________________________________________ +________________________________________________________________________________ +________________________________________________________________________________ +________________________________________________________________________________ + +________________________________________________________________________________ +________________________________________________________________________________ + +### MODULES + +________________________________________________________________________________ + +### HOW TO ADD A SOUNDFONT + +Edit SoundFont.h + +________________________________________________________________________________ + + +### NOTES : + +1. __Only WAVs file !!!__ _NOOOO MP3, NOOOO WMA !!!_ : +When encoding a sound to those format (MP3 and WMA) the encoder will automaticly put a silence at start. +___WE DON'T WANT GAPS !!!___ +2. With soundfiles with hum extension (you edited a swing file and paste a hum sound repeated for some time), if you put 2 min of hum after your swing sound, if you don't move your saber for 2 min (higly unprobable in real situation) you'll notice a little gap in hum sound at that moment : You've just switch on a pure hum soundfile. +3. Don't put gaps in soundfile numbering ex.:001_Boot.wav,002.wav, 0010_Swing1.wav... +The "folder play" command of the DFPlayer will see them as 001, 002, 003... +That will generate unpredictable behaviour. +4. You can't put more than 255 folders numbered folder on your SDCard, including O1 (which contains config mode sounds) +5. You can't put more than 255 files in a folder on your SDCard. +6. You won't be able to have more than 65535 sound file on the wole SDCard (including config sounds). +7. Don't put names after folder number (ex.: 001_Config or 002_Sith). Your folder won't be detected (tested :( ) +8. Since I've developped it on a breadboard, clash and swings settings may need some more tweaking. +Still hopping that will not be the case :P. I've developped those wanting to obtain "real life" saber feel. +9. Beware the amount of debug settings you uncoment: they add significant amount of data to the compile. +I've made them modular for this reason, so take advantage of it. + +________________________________________________________________________________ + +### LECTURES / SOURCES /INSPIRATIONS