diff --git a/examples/IDEC/IDEC1_1_MotSound5Led/IDEC1_1_MotSound5Led.ino b/examples/IDEC/IDEC1_1_MotSound5Led/IDEC1_1_MotSound5Led.ino new file mode 100644 index 0000000..647f704 --- /dev/null +++ b/examples/IDEC/IDEC1_1_MotSound5Led/IDEC1_1_MotSound5Led.ino @@ -0,0 +1,765 @@ +// Interactive Decoder Motor, Pauses, Reversals w/Sound 4 LED IDEC1_1_MotSound4Led.ino +// Version 1.08 Geoff Bunza 2020 +// Works with both short and long DCC Addesses +// This decoder uses switches/sensors to control 2 motors and Five LEDs with Sound +// F0=Master Function OFF = Function ON DISABLES the decoder +// Input Pin for Decoder Disable Pin 16 Active LOW +//Motor speed via DCC speed for one motor, second motor on/off via function +//Speed Over-Ride = CV = Non-Zero Value (1-127) over-rides the DCC speed commands Bit 8 is direction 1=Forward +//Input1 Pin for Throttle Down/Pause/Throttle Up Pin 5 +// CV for Throttle Down Time, CV for Throttle Up Time,, CV for Pause Time +//Input2 Pin for Throttle Down/Pause/Throttle Up Pin 6 +// CV for Throttle Down Time, CV for Throttle Up Time,, CV for Pause Time +//Input Pin1 for Throttle Down/Reverse/Throttle Up Pin 7 +// CV for Throttle Down Time, CV for Throttle Up Time;,CV for Reverse Pause Time +//Input Pin2 for Throttle Down/Reverse/Throttle Up Pin 8 +// CV for Throttle Down Time, CV for Throttle Up Time;,CV for Reverse Pause Time +//Input Pin for immediate Stop Pin 11 +//Input Pin for Immediate Start Pin 12 +//Functions for lights on/off: +// F1-F5 5 Functions LED ON/OFF by default PINS 13,14,17,18,19 +/* Pro Mini D15 A1 (TX) connected to DFPlayer1 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor + * Remember to connect +5V and GND to the DFPlayer too: DFPLAYER PINS 1 & 7 respectively + * This is a “mobile/function” decoder with audio play to dual motor control and + * LED functions. Audio tracks or clips are stored on a micro SD card for playing, + * in a folder labeled mp3, with tracks named 0001.mp3, 0002.mp3, etc. + * MAX 3 Configurations per pin function: + * Config 0=Decoder DISABLE On/Off, 1=LED; 2=Motor2 Control On/Off + F0 == Master Decoder Disable == ON + F1 == LED == D13 + F2 == LED == D14/A0 + F3 == LED == D17/A3 + F4 == LED == D18/A4 + F5 == LED == D19/A5 + F6 == Motor2 On/OFF speed & direction set by CV 80 Normally Base Station will Transmit F5 as initial OFF + If no DCC present Decoder will power up with Motor2 ON at speed specified in CV 72 + Motor1 speed control is via throttle or overridden by non zero value in CV 50 + High Bit=Direction, Lower 7 Bits=Speed == DSSSSSSS + +PRO MINI PIN ASSIGNMENT: +2 - DCC Input +3 - m2h Motor Control +4 - m2l Motor Control +5 - Input1 Pin for Throttle Down/Pause/Throttle Up +6 - Input2 Pin for Throttle Down/Pause/Throttle Up +7 - Input1 Pin for Throttle Down/Reverse/Throttle Up +8 - Input2 Pin for Throttle Down/Reverse/Throttle Up +9 - m0h Motor Control +10 - m0l Motor Control +11 - Input Pin for immediate Stop +12 - Input Pin for Immediate Start +13 - LED F1 +14 A0 - LED F2 +15 A1 - (TX) connected to DFPlayer1 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor +16 A2 - Input Pin for MasterDecoderDisable Active LOW +17 A3 - LED F3 +18 A4 - LED F4 +19 A5 - LED F5 +*/ + +// ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP +// ******** AFTER THE INITIAL DECODER LOAD REMOVE THE "//" IN THE FOOLOWING LINE!! +//#define DECODER_LOADED + +// ******** EMOVE THE "//" IN THE FOOLOWING LINE TO SEND DEBUGGING +// ******** INFO TO THE SERIAL MONITOR +//#define DEBUG + +#include +#include +#include +SoftwareSerial DFSerial1(21,15); // PRO MINI RX, PRO MINI TX serial to DFPlayer +DFRobotDFPlayerMini Player1; + +#define This_Decoder_Address 24 +uint8_t CV_DECODER_MASTER_RESET = 252; + +//Uncomment ONLY ONE of the following: +//#define MasterTimeConstant 10L // 10's of milliseconds Timing +#define MasterTimeConstant 100L // Tenths of a second Timing +//#define MasterTimeConstant 1000L // Seconds Timing +//#define MasterTimeConstant 10000L // 10's of Seconds Timing +//#define MasterTimeConstant 60000L // Minutes Timing +//#define MasterTimeConstant 3600000L // Hours Timing + +#define runAfter(t) for (static unsigned long _dTimer;(unsigned long)(millis()-_dTimer)>=(t);_dTimer=millis()) + +int tctr, tctr2; +uint16_t ttemp, i; +#define First_Track 1 // Play Random Tracks First_Track#=Start_Track >=1 +#define Last_Track 12 // Play Random Tracks Last_Track= Last Playable Track in Range <= Last Numbered Track + +const int audiocmddelay = 34; +boolean Use_DCC_speed = true; // Switch to disable DCC Speed updates +int Motor1Speed = 0; // Variablw for Motor1 Speed +int Starting_Motor1Speed = 0; +int Motor1ForwardDir = 1; // Variable for Motor1 Dir +int ForcedStopSpeedMotor1 = 0; // Holding Variablw for Last Speed when Immediate Stop +int ForcedStopDirMotor1 = 1; // Holding Variablw for Last Direction when Immediate Stop +int Motor2Speed = 0; // Variable for Motor2 Speed +int Motor2ForwardDir = 1; // Variable for Motor2 Dir +int Motor2ON = 0; +int fwdon = 0; +int fwdtime = 1; +int bwdon = 0; +int bwdtime = 1; +int cyclewidth = 2048; +int loopdelay = 0; //14; + +const int m2h = 3; //R H Bridge Motor1 +const int m2l = 4; //B H Bridge Motor1 +const int ThrottlePause1Pin = 5; // Throttle Speed Pause1 Input Pin +const int ThrottlePause2Pin = 6; // Throttle Speed Pause2 Input Pin +const int ThrottleInputReversePin1 = 7; // Throttle Speed Reverse Input Pin +const int ThrottleInputReversePin2 = 8; // Throttle Immediate Speed Reverse Input Pin +const int m0h = 9; //R H Bridge Motor2 +const int m0l = 10; //B H Bridge //Motor2 +const int ImmediateStopPin = 11; // Throttle Immediate Stop Input Pin +const int ImmediateStartPin = 12; // Throttle Immediate Start Input Pin +const int MasterDecoderDisablePin = 16; // D16/A0 Master Decoder Disable Input Pin Active LOW +// arduino pin D 15; // D15/A1 DFPlayer Receive (RX) Pin 2 via 470 Ohm Resistor + +const int numfpins = 10; // Number of Output pins to initialize +const int num_active_functions = 7; // Number of Functions stating with F0 +byte fpins [] = {13,13,14,17,18,19,3,4,9,10}; //These are all the Output Pins (first 13 is placeholder) +const int FunctionPin0 = 20; // D14/A0 DFPlayer Transmit (TX) Pin 3 +const int FunctionPin1 = 13; // A2 LED +const int FunctionPin2 = 14; // A3 LED +const int FunctionPin3 = 17; // A4 LED +const int FunctionPin4 = 18; // A5 LED +const int FunctionPin5 = 19; // A6 LED + +const int FunctionPin6 = 20; // Turns on Motor2 DCC Function Control Only NO Local Input Pin +const int FunctionPin7 = 20; // Place holders ONLY +const int FunctionPin8 = 20; // Place holders ONLY +const int FunctionPin9 = 20; // Place holders ONLY +const int FunctionPin10 = 20; // Place holders ONLY +const int FunctionPin11 = 20; // Place holders ONLY +const int FunctionPin12 = 20; // Place holders ONLY +const int FunctionPin13 = 20; // Place holders ONLY +const int FunctionPin14 = 20; // Place holders ONLY +const int FunctionPin15 = 20; // Place holders ONLY +const int FunctionPin16 = 20; // Place holders ONLY +int MasterDecoderDisable = 0; +int Function0_value = 0; + + +NmraDcc Dcc ; +DCC_MSG Packet ; +int t; // temp +struct QUEUE +{ + int inuse; + int current_position; + int increment; + int stop_value; + int start_value; +}; +QUEUE *ftn_queue = new QUEUE[17]; + +struct CVPair +{ + uint16_t CV; + uint8_t Value; +}; +CVPair FactoryDefaultCVs [] = +{ + {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address&0x7F }, + + // These two CVs define the Long DCC Address + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, ((This_Decoder_Address>>8)&0x7F)+192 }, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address&0xFF }, + + // ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS +// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps + {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps +// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps + {CV_DECODER_MASTER_RESET, 0}, + + {30, 0}, //F0 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + + {31, 1}, //F1 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {32, 1}, //F2 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {33, 1}, //F3 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {34, 1}, //F4 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {35, 1}, //F5 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + + {36, 2}, //F6 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + + {37,4}, //F7 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {38,4}, //F8 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {39,4}, //F9 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {40,4}, //F10 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {41,4}, //F11 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {42,4}, //F12 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {43,4}, //F13 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {44,4}, //F14 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {45,4}, //F15 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {46,4}, //F16 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {47,4}, //F17 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {48,4}, //F18 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {49,4}, //F19 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + + {50, 0}, // Speed Over-Ride = CV = Non-Zero Value (1-127) over-rides the DCC speed commands + // Bit 8 (128 or 0x80) ON=Forward Direction 0=Reverse Direction + + {51, 75}, // ThrottlePause1 Pause Time 0-255 (0.1 secs) + {52, 3}, // ThrottlePause1 Throttle Ramp DOWN Delay 0-255 Larger Delay=Slower Ramp Down + {53, 3}, // ThrottlePause1 Throttle Ramp UP Delay 0-255 Larger Delay=Slower Ramp Up + {54, 1}, // ThrottlePause1 Pause Sound Clip 1-nn 0=No Sound + {55, 20}, // ThrottlePause1 Pause Sound Clip Volume 0-30 + + {56, 22}, // ThrottlePause2 Pause Time 0-255 (0.1 secs) + {57, 5}, // ThrottlePause2 Throttle Ramp DOWN 0-255 Delay + {58, 5}, // ThrottlePause2 Throttle Ramp UP Delay 0-255 + {59, 1}, // ThrottlePause2 Pause Sound Clip 1-nn 0=No Sound + {60, 20}, // ThrottlePause2 Pause Sound Clip Volume 0-30 + + {61, 28}, // ThrottleInputReverse1 Pause Time 0-255 (0.1 secs) + {62, 3}, // ThrottleInputReverse1 Ramp DOWN Delay 0-255 + {63, 3}, // ThrottleInputReverse1 Ramp UP Delay 0-255 + {64, 2}, // ThrottleInputReverse1 Sound Clip 1-nn 0=No Sound + {65, 20}, // ThrottleInputReverse1 Sound Clip Volume 0-30 + + {66, 22}, // ThrottleInputReverse2 Pause Time 0-255 (0.1 secs) + {67, 5}, // ThrottleInputReverse2 Ramp DOWN Delay 0-255 + {68, 5}, // ThrottleInputReverse2 Ramp UP Delay 0-255 + {69, 2}, // ThrottleInputReverse2 Sound Clip 1-nn 0=No Sound + {70, 20}, // ThrottleInputReverse2 Sound Clip Volume 0-30 + + {71, 0}, // ThrottleImmediateStop Sound Clip 1-nn 0=No Sound + {72, 20}, // ThrottleImmediateStop Sound Clip Volume 0-30 + + {73, 0}, // ThrottleImmediateStart Sound Clip 1-nn 0=No Sound + {74, 20}, // ThrottleImmediateStart Sound Clip Volume 0-30 + + {80, 20}, // Motor2 Speed 0-127 Bit 8 (128 or 0x80) ON=Forward Direction 0=Reverse Direction + + //252,252 CV_DECODER_MASTER_RESET + + {253, 0}, // Extra +}; + +uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +void notifyCVResetFactoryDefault() +{ + // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset + // to flag to the loop() function that a reset to Factory Defaults needs to be done + FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +}; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS + +void setup() //****************************************************** +{ +#ifdef DEBUG + Serial.begin(115200); +#endif + DFSerial1.begin (9600); + Player1.begin (DFSerial1); + + pinMode (ThrottlePause1Pin,INPUT_PULLUP); // Throttle Speed Pause1 Input Pin Active LOW + pinMode (ThrottlePause2Pin,INPUT_PULLUP); // Throttle Speed Pause2 Input Pin Active LOW + pinMode (ThrottleInputReversePin1,INPUT_PULLUP); // Throttle Speed Reverse Input Pin 1 Active LOW + pinMode (ThrottleInputReversePin2,INPUT_PULLUP); // Throttle Speed Reverse Input Pin 2 Active LOW + pinMode (ImmediateStopPin,INPUT_PULLUP); // Throttle Immediate Stop Input Pin Active LOW + pinMode (ImmediateStartPin,INPUT_PULLUP); // Throttle Immediate Start Input Pin Active LOW + pinMode (MasterDecoderDisablePin,INPUT_PULLUP); // Master Decoder Disable Input Pin Active LOW + uint8_t cv_value; + // initialize the digital pins as outputs + for (int i=0; i < numfpins; i++) { + pinMode(fpins[i], OUTPUT); + digitalWrite(fpins[i], 0); // All OUPUT pins initialized LOW + } + // Setup which External Interrupt, the Pin it's associated with that we're using + Dcc.pin(0, 2, 0); + // Call the main DCC Init function to enable the DCC Receiver + Dcc.init( MAN_ID_DIY, 61, FLAGS_MY_ADDRESS_ONLY, 0 ); + delay(800); +#if defined(DECODER_LOADED) + if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET ) +#endif + { + for (int j=0; j < FactoryDefaultCVIndex; j++ ) + Dcc.setCV( FactoryDefaultCVs[j].CV, FactoryDefaultCVs[j].Value); + } + + for ( i=0; i < num_active_functions; i++) { + cv_value = Dcc.getCV(30+i) ; + switch ( cv_value ) { + case 0: // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + break; + case 1: // LED On/Off + ftn_queue[i].inuse = 0; + break; + case 2: // Motor2 Control + if ( Dcc.getCV(72) != 0) { + Motor2ON = 1; + Motor2Speed = (Dcc.getCV(72))&0x7f ; + Motor2ForwardDir = (byte)((Dcc.getCV(72))&0x80)>>7 ; + } else Motor2ON = 0; + break; + case 3: // NEXT FEATURE for the Future + break; + default: + break; + } + } + Motor1ForwardDir = 1; // Default start value for direction if throttle controlled + if ( Dcc.getCV(50) != 0) { + Motor1Speed = (Dcc.getCV(50))&0x7f ; + Motor1ForwardDir = (byte)((Dcc.getCV(50))&0x80 )>>7; + } +#ifdef DEBUG + Serial.println("CV Dump:"); + for (i=30; i<51; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + + Serial.println("Throttle Pause 1"); + for (i=51; i<56; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + + Serial.println("Throttle Pause 2"); + for (i=56; i<61; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + + Serial.println("Throttle Reverse 1"); + for (i=61; i<66; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + + Serial.println("Throttle Reverse 2"); + for (i=66; i<71; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + + Serial.println("Immediate Stop"); + for (i=71; i<73; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + + Serial.println("Immediate Start"); + for (i=73; i<75; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + + Serial.println("Motor2 Speed"); + Serial.print(Dcc.getCV(80),DEC); Serial.print("\t"); } + Serial.println(""); +#endif +} +void loop() //********************************************************************** +{ + //MUST call the NmraDcc.process() method frequently + // from the Arduino loop() function for correct library operation + Dcc.process(); + run_at_speed(); + //delay(1); + +// INPUT OVER RIDES + // Check Master Input Over ride + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + else MasterDecoderDisable = Function0_value & 1; + + if (MasterDecoderDisable == 1) { Motor1Speed = 0; Motor2Speed = 0; } + +// ======== Throttle Pause 1 ======================== + if (digitalRead(ThrottlePause1Pin) == LOW) { // Throttle Speed Pause1 Input Pin + Use_DCC_speed = false; // Do not update speed via DCC + Starting_Motor1Speed = Motor1Speed; + while (Motor1Speed >0) { + --Motor1Speed; + run_at_speed(); + delay(Dcc.getCV(52)); //Throttle Ramp DOWN Delay 0-255 + } + Motor1Speed = 0; + ttemp=(Dcc.getCV(54)); + setVolumeOnChannel (Dcc.getCV(55)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip + delay(int(Dcc.getCV(51)*MasterTimeConstant)); //Pause Time 0-255 (0.1 secs) + while (Motor1Speed <= Starting_Motor1Speed) { + ++Motor1Speed; + run_at_speed(); + delay(Dcc.getCV(53)); //Throttle Ramp UP Delay 0-255 + } + Motor1Speed = Starting_Motor1Speed; + run_at_speed(); + while (digitalRead(ThrottlePause1Pin) == LOW) idle(); //Wait for Sensor + Use_DCC_speed = true; // Do not update speed via DCC + } + +// ======== Throttle Pause 2 ======================== + if (digitalRead(ThrottlePause2Pin) == LOW) { // Throttle Speed Pause2 Input Pin + + Use_DCC_speed = false; // Do not update speed via DCC + Starting_Motor1Speed = Motor1Speed; + while (Motor1Speed >0) { + --Motor1Speed; + run_at_speed(); + delay(Dcc.getCV(57)); //Throttle Ramp DOWN Delay 0-255 + } + Motor1Speed = 0; + ttemp=(Dcc.getCV(59)); + setVolumeOnChannel (Dcc.getCV(60)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip + delay(int(Dcc.getCV(56)*MasterTimeConstant)); //Pause Time 0-255 (0.1 secs) + while (Motor1Speed <= Starting_Motor1Speed) { + ++Motor1Speed; + run_at_speed(); + delay(Dcc.getCV(58)); //Throttle Ramp UP Delay 0-255 + } + Motor1Speed = Starting_Motor1Speed; + run_at_speed(); + while (digitalRead(ThrottlePause2Pin) == LOW) idle(); //Wait for Sensor + Use_DCC_speed = true; // Do not update speed via DCC + } + +// ======== Throttle Reverse 1 ======================== + if (digitalRead(ThrottleInputReversePin1)==LOW){ // Throttle Speed Reverse1 Input Pin + Use_DCC_speed = false; // Do not update speed via DCC + Starting_Motor1Speed = Motor1Speed; + Motor1Speed--; + while (Motor1Speed >1) { + run_at_speed(); + --Motor1Speed; + delay(Dcc.getCV(62)); //Throttle Ramp DOWN Delay 0-255 + } + Motor1Speed = 0; + ttemp=(Dcc.getCV(64)); + setVolumeOnChannel (Dcc.getCV(65)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip + Motor1ForwardDir = (Motor1ForwardDir^0x01) & 0x01; + delay(Dcc.getCV(61)*MasterTimeConstant); //Pause Time 0-255 (0.1 secs) + while (Motor1Speed < Starting_Motor1Speed) { + Motor1Speed++;; + run_at_speed(); + delay(Dcc.getCV(63)); //Throttle Ramp UP Delay 0-255 + } + Motor1Speed = Starting_Motor1Speed; + run_at_speed(); + while (digitalRead(ThrottleInputReversePin1) == LOW) idle(); //Wait for Sensor + Use_DCC_speed = true; + } + +// ======== Throttle Reverse 2 ======================== + if (digitalRead(ThrottleInputReversePin2)==LOW){ // Throttle Speed Reverse Input Pin + Use_DCC_speed = false; // Do not update speed via DCC + Starting_Motor1Speed = Motor1Speed; + while (Motor1Speed >0) { + --Motor1Speed; + run_at_speed(); + delay(Dcc.getCV(67)); //Throttle Ramp DOWN Delay 0-255 + } + Motor1Speed = 0; + ttemp=(Dcc.getCV(69)); + setVolumeOnChannel (Dcc.getCV(70)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip + Motor1ForwardDir = (Motor1ForwardDir^0x01) & 0x01; + delay(int(Dcc.getCV(66)*MasterTimeConstant)); //Pause Time 0-255 (0.1 secs) + while (Motor1Speed <= Starting_Motor1Speed) { + ++Motor1Speed; + run_at_speed(); + delay(Dcc.getCV(68)); //Throttle Ramp UP Delay 0-255 + } + Motor1Speed = Starting_Motor1Speed; + run_at_speed(); + while (digitalRead(ThrottleInputReversePin2) == LOW) idle(); //Wait for Sensor + Use_DCC_speed = true; // Do not update speed via DCC + } + +// ======== Throttle Immediate Stop ======================== + if (digitalRead(ImmediateStopPin) == LOW) { // Throttle Immediate Stop Input Pin + ForcedStopSpeedMotor1 = Motor1Speed; + ForcedStopDirMotor1 = Motor1ForwardDir; + Motor1Speed = 0; + ttemp=(Dcc.getCV(71)); + setVolumeOnChannel (Dcc.getCV(72)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip + } + +// ======== Throttle Immediate Start ======================== + if (digitalRead(ImmediateStartPin) == LOW) { // Throttle Immediate Start Input Pin + ttemp=(Dcc.getCV(73)); + setVolumeOnChannel (Dcc.getCV(74)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip + if (ForcedStopSpeedMotor1 != 0) { + Motor1Speed = ForcedStopSpeedMotor1 ; + Motor1ForwardDir = ForcedStopDirMotor1; + } + else + if ( Dcc.getCV(50) != 0) { + Motor1Speed = (Dcc.getCV(50))&0x7f ; + Motor1ForwardDir = (byte)((Dcc.getCV(50))&0x80 )>>7; + } + ForcedStopSpeedMotor1 = 0; // Take us out of forced stop mode + run_at_speed(); + while (digitalRead(ImmediateStartPin) == LOW) idle(); //Wait for Sensor + } + +// ******************************************************************************** + + for (int i=0; i < num_active_functions; i++) { + switch (Dcc.getCV(30+i)) { + case 0: // Master Decoder Disable Ops + break; + case 1: // LED On/Off + if (MasterDecoderDisable == 1) digitalWrite(fpins[i], 0); //decoder disabled so LEDs off + break; + case 2: // Motor2 Control + Motor2Speed = (Dcc.getCV(72))&0x7f ; // Re-read Motor2Speed if the CV was updated + Motor2ForwardDir = (byte)((Dcc.getCV(72))&0x80)>>7 ; // Re-read Motor2ForwardDir if the CV was updated + + if ((MasterDecoderDisable == 0)&&(Motor2ON == 1)) { + if (Motor2ForwardDir == 0) gofwd2 (fwdtime, Motor2Speed<<4); + else gobwd2 (bwdtime, Motor2Speed<<4); + } + if (MasterDecoderDisable == 1) { + digitalWrite(m0h, LOW); //Motor2OFF + digitalWrite(m0l, LOW); //Motor2 OFF + } + break; + + case 3: // NEXT FEATURE for the Future + break; + default: + break; + } + } +#ifdef DEBUG + Serial.print("loop4 Motor1Speed= "); + Serial.print(Motor1Speed, DEC) ; + Serial.print(" Motor2Speed= "); + Serial.println(Motor2Speed, DEC) ; +#endif +} // end loop() + +void idle() { + Dcc.process(); + run_at_speed(); +} // end idle() + +void run_at_speed() { +#ifdef DEBUG + Serial.print("run Motor1Speed= "); + Serial.print(Motor1Speed, DEC) ; + Serial.print(" Motor1ForwardDir= "); + Serial.println(Motor1ForwardDir, DEC) ; +#endif + if (MasterDecoderDisable == 0) { + if (Motor1Speed != 0) { + if (Motor1ForwardDir == 0) gofwd1 (fwdtime, Motor1Speed<<4); + else gobwd1 (bwdtime, Motor1Speed<<4); + } + } + if (MasterDecoderDisable == 1) { + digitalWrite(m2h, LOW); //Motor1 OFF + digitalWrite(m2l, LOW); //Motor1 OFF + digitalWrite(m0h, LOW); //Motor2 OFF + digitalWrite(m0l, LOW); //Motor2 OFF + } + if ((MasterDecoderDisable == 0)&&(Motor2ON == 1)) { + if (Motor2ForwardDir == 0) gofwd2 (fwdtime, Motor2Speed<<4); + else gobwd2 (bwdtime, Motor2Speed<<4); + } +} // end run_at_speed() + +void gofwd1(int fcnt,int fcycle) { + int icnt; + int delta_tp,delta_tm; + delta_tp = fcycle+loopdelay<<2; + delta_tm = cyclewidth-fcycle-loopdelay; + icnt = 0; + while (icnt < fcnt) + { + digitalWrite(m2h, HIGH); //Motor1 + delayMicroseconds(delta_tp); + digitalWrite(m2h, LOW); //Motor1 + delayMicroseconds(delta_tm); + icnt++; + } +} // end gofwd1() + +void gobwd1(int bcnt,int bcycle) { + int icnt; + int delta_tp,delta_tm; + delta_tp = bcycle+loopdelay<<2; + delta_tm = cyclewidth-bcycle-loopdelay; + icnt=0; + while (icnt < bcnt) + { + digitalWrite(m2l, HIGH); //Motor1 + delayMicroseconds(delta_tp); + digitalWrite(m2l, LOW); //Motor1 + delayMicroseconds(delta_tm); + icnt++; + } +} // end gobwd1() + +void gofwd2(int fcnt,int fcycle) { + int icnt; + int delta_tp,delta_tm; + delta_tp = fcycle+loopdelay<<2; + delta_tm = cyclewidth-fcycle-loopdelay; + icnt = 0; + while (icnt < fcnt) + { + digitalWrite(m0h, HIGH); //Motor2 + delayMicroseconds(delta_tp); + digitalWrite(m0h, LOW); //Motor2 + delayMicroseconds(delta_tm); + icnt++; + } +} // end gofwd2() + +void gobwd2(int bcnt,int bcycle) { + int icnt; + int delta_tp,delta_tm; + delta_tp = bcycle+loopdelay<<2; + delta_tm = cyclewidth-bcycle-loopdelay; + icnt=0; + while (icnt < bcnt) + { + digitalWrite(m0l, HIGH); //Motor2 + delayMicroseconds(delta_tp); + digitalWrite(m0l, LOW); //Motor2 + delayMicroseconds(delta_tm); + icnt++; + } +} // end gobwd2() + +void playTrackOnChannel ( byte dtrack) { + if (dtrack!=255) {Player1.play(dtrack); delay(audiocmddelay); } + else {Player1.play(random(First_Track,Last_Track+1)); delay(audiocmddelay); } +} // end playTrackOnChannel() + +void setVolumeOnChannel ( byte dvolume) { + if(dvolume>30) return; // Don't change the volume if out of range + Player1.volume (dvolume); + delay(audiocmddelay); +} // end setVolumeOnChannel() + +void notifyCVChange( uint16_t CV, uint8_t Value) { + if ( CV== 50 ) { + Motor1Speed = (Dcc.getCV(50))&0x7f ; + Motor1ForwardDir = (byte)((Dcc.getCV(50))&0x80 )>>7; + } +} // end notifyCVChange() + +void notifyDccSpeed( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Speed, DCC_DIRECTION ForwardDir, DCC_SPEED_STEPS SpeedSteps ) { + if ( !Use_DCC_speed ) return; + if ( Dcc.getCV(50) == 0) { + Motor1Speed = (Speed & 0x7f ); + } + if (Motor1Speed == 1) Motor1Speed = 0; +} // end notifyDccSpeed() + +void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { +#ifdef DEBUG + Serial.print("Addr= "); + Serial.println(Addr, DEC) ; + Serial.print("FuncState= "); + Serial.println(FuncState, DEC) ; +#endif + switch(FuncGrp) + { + case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1 + exec_function( 0, FunctionPin0, (FuncState & FN_BIT_00)>>4 ); + exec_function( 1, FunctionPin1, (FuncState & FN_BIT_01)); + exec_function( 2, FunctionPin2, (FuncState & FN_BIT_02)>>1); + exec_function( 3, FunctionPin3, (FuncState & FN_BIT_03)>>2 ); + exec_function( 4, FunctionPin4, (FuncState & FN_BIT_04)>>3 ); + break; + case FN_5_8: //Function Group 1 S FFFF == 1 F8 F7 F6 F5 & == 0 F12 F11 F10 F9 F8 + exec_function( 5, FunctionPin5, (FuncState & FN_BIT_05)); + exec_function( 6, FunctionPin6, (FuncState & FN_BIT_06)>>1 ); + //exec_function( 7, FunctionPin7, (FuncState & FN_BIT_07)>>2 ); + //exec_function( 8, FunctionPin8, (FuncState & FN_BIT_08)>>3 ); + break; + + case FN_9_12: + //exec_function( 9, FunctionPin9, (FuncState & FN_BIT_09)); + //exec_function( 10, FunctionPin10, (FuncState & FN_BIT_10)>>1 ); + //exec_function( 11, FunctionPin11, (FuncState & FN_BIT_11)>>2 ); + //exec_function( 12, FunctionPin12, (FuncState & FN_BIT_12)>>3 ); + break; + case FN_13_20: //Function Group 2 FuncState == F20-F13 Function Control + //exec_function( 13, FunctionPin13, (FuncState & FN_BIT_13); + //exec_function( 14, FunctionPin14, (FuncState & FN_BIT_14)>>1; + //exec_function( 15, FunctionPin15, (FuncState & FN_BIT_15)>>2 ); + //exec_function( 16, FunctionPin16, (FuncState & FN_BIT_16)>>3 ); + break; + + case FN_21_28: + break; + } +} // end notifyDccSpeed() + +void exec_function (int function, int pin, int FuncState) { +#ifdef DEBUG + Serial.print("ex function= "); + Serial.println(function, DEC) ; + Serial.print("FuncState= "); + Serial.println(FuncState, DEC) ; +#endif + switch ( Dcc.getCV( 30+function) ) { // Config 0=On/Off,1=Blink + case 0: // Master Disable Function0 Value will transfer to MasterDecoderDisable in loop() + Function0_value = byte(FuncState); + break; + case 1: // On - Off LED + if (MasterDecoderDisable == 0) { + digitalWrite (pin, FuncState); + } + break; + case 2: // Motor2 Control + if (MasterDecoderDisable == 0) Motor2ON= FuncState; + break; + case 3: // NEXT FEATURE for the Future + break; + default: + ftn_queue[function].inuse = 0; + break; + } +} // end exec_function() + +/* DFPlayer Commands +//----Set volume---- + myDFPlayer.volume(10); //Set volume value (0~30). + myDFPlayer.volumeUp(); //Volume Up + myDFPlayer.volumeDown(); //Volume Down + //----Set different EQ---- + myDFPlayer.EQ(DFPLAYER_EQ_NORMAL); +// myDFPlayer.EQ(DFPLAYER_EQ_POP); +// myDFPlayer.EQ(DFPLAYER_EQ_ROCK); +// myDFPlayer.EQ(DFPLAYER_EQ_JAZZ); +// myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC); +// myDFPlayer.EQ(DFPLAYER_EQ_BASS); + //----Set device we use SD as default---- +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_U_DISK); + myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_AUX); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_SLEEP); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_FLASH); + //----Mp3 control---- +// myDFPlayer.sleep(); //sleep +// myDFPlayer.reset(); //Reset the module +// myDFPlayer.enableDAC(); //Enable On-chip DAC +// myDFPlayer.disableDAC(); //Disable On-chip DAC +// myDFPlayer.outputSetting(true, 15); //output setting, enable the output and set the gain to 15 + //----Mp3 play---- + myDFPlayer.next(); //Play next mp3 + myDFPlayer.previous(); //Play previous mp3 + myDFPlayer.play(1); //Play the first mp3 + myDFPlayer.loop(1); //Loop the first mp3 + myDFPlayer.pause(); //pause the mp3 + myDFPlayer.start(); //start the mp3 from the pause + myDFPlayer.playFolder(15, 4); //play specific mp3 in SD:/15/004.mp3; Folder Name(1~99); File Name(1~255) + myDFPlayer.enableLoopAll(); //loop all mp3 files. + myDFPlayer.disableLoopAll(); //stop loop all mp3 files. + myDFPlayer.playMp3Folder(4); //play specific mp3 in SD:/MP3/0004.mp3; File Name(0~65535) + myDFPlayer.advertise(3); //advertise specific mp3 in SD:/ADVERT/0003.mp3; File Name(0~65535) + myDFPlayer.stopAdvertise(); //stop advertise + myDFPlayer.playLargeFolder(2, 999); //play specific mp3 in SD:/02/004.mp3; Folder Name(1~10); File Name(1~1000) + myDFPlayer.loopFolder(5); //loop all mp3 files in folder SD:/05. + myDFPlayer.randomAll(); //Random play all the mp3. + myDFPlayer.enableLoop(); //enable loop. + myDFPlayer.disableLoop(); //disable loop. +*/ diff --git a/examples/IDEC/IDEC2_1_Building/IDEC2_1_Building.ino b/examples/IDEC/IDEC2_1_Building/IDEC2_1_Building.ino new file mode 100644 index 0000000..5654269 --- /dev/null +++ b/examples/IDEC/IDEC2_1_Building/IDEC2_1_Building.ino @@ -0,0 +1,264 @@ +// Interactive Decoder Random Building Lighting DCC Decoder IDEC2_1_Building.ino +// Version 1.08 Geoff Bunza 2020 +// Works with both short and long DCC Addesses +// This decoder will control Random Building Lighting +// F0=Master Function OFF = Function ON DISABLES the decoder +// Input Pin for Decoder Disable Pin 3 Active LOW + +/* + F0 == Master Decoder Disable +PRO MINI PIN ASSIGNMENT: +2 - DCC Input +3 - Input Pin for MasterDecoderDisable Active LOW +4 - LED +5 - LED +6 - LED +7 - LED +8 - LED +9 - LED +10 - LED +11 - LED +12 - LED +13 - LED +14 A0 - LED +15 A1 - LED +16 A2 - LED +17 A3 - LED +18 A4 - LED +19 A5 - LED +*/ + +// ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP +// ******** AFTER THE INITIAL DECODER LOAD REMOVE THE "//" IN THE FOOLOWING LINE!! +//#define DECODER_LOADED + +// ******** EMOVE THE "//" IN THE FOOLOWING LINE TO SEND DEBUGGING +// ******** INFO TO THE SERIAL MONITOR +//#define DEBUG + +#include +#define runEvery(t) for (static typeof(t) _lasttime;\ + (typeof(t))((typeof(t))millis() - _lasttime) > (t);\ + _lasttime += (t)) +int master_tim_delay = 100; +long delta = 0; +int tctr, tctr2, i; + +int numleds = 16; // Number of Output pins to initialize +int num_active_functions = 1; // Number of Functions stating with F0 +byte fpins [] = {4,5,6,7,8,9,10,11,12,13,54,55,56,57,58,59}; //These are all the Output Pins + +const int MasterDecoderDisablePin = 3; // D3 Master Decoder Disable Input Pin Active LOW +const int FunctionPin0 = 20; // Input Master Pin Disable Active LOW {;aceholder +const int FunctionPin1 = 20; // A0 LED +const int FunctionPin2 = 20; // A1 LED +const int FunctionPin3 = 20; // A2 LED +const int FunctionPin4 = 20; //A3 LED +const int FunctionPin5 = 20; //A4 LED +const int FunctionPin6 = 20; //A5 LED +const int FunctionPin7 = 20; // Place holders ONLY +const int FunctionPin8 = 20; // Place holders ONLY +const int FunctionPin9 = 20; // Place holders ONLY +const int FunctionPin10 = 20; // Place holders ONLY +const int FunctionPin11 = 20; // Place holders ONLY +const int FunctionPin12 = 20; // Place holders ONLY +const int FunctionPin13 = 20; // Place holders ONLY +const int FunctionPin14 = 20; // Place holders ONLY +const int FunctionPin15 = 20; // Place holders ONLY +const int FunctionPin16 = 20; // Place holders ONLY +int MasterDecoderDisable = 0; +int Function0_value = 0; + +NmraDcc Dcc ; +DCC_MSG Packet ; +uint8_t CV_DECODER_MASTER_RESET = 120; +int t; // temp +struct QUEUE +{ + int inuse; + int current_position; + int increment; + int stop_value; + int start_value; +}; +QUEUE *ftn_queue = new QUEUE[3]; + +struct CVPair +{ + uint16_t CV; + uint8_t Value; +}; + +#define This_Decoder_Address 24 + +CVPair FactoryDefaultCVs [] = +{ + {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address&0x7F }, + + // These two CVs define the Long DCC Address + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, ((This_Decoder_Address>>8)&0x7F)+192 }, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address&0xFF }, + + // ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS +// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps + {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps +// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps + + {CV_DECODER_MASTER_RESET, 0}, + {30, 0}, //F0 Config 0=DISABLE On/Off + {50, 90}, // Master Building Time Delay 0-255 255=Slowest + {51, 0}, // + {52, 0}, // +}; + +uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +void notifyCVResetFactoryDefault() +{ + // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset + // to flag to the loop() function that a reset to Factory Defaults needs to be done + FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +}; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS + +void setup() +{ +#ifdef DEBUG + Serial.begin(115200); +#endif + pinMode (MasterDecoderDisablePin,INPUT_PULLUP); // Master Decoder Disable Input Pin Active LOW + uint8_t cv_value; + // initialize the digital pins as outputs + for (int i=0; i < numleds; i++) { + pinMode(fpins[i], OUTPUT); + digitalWrite(fpins[i], 0); // All OUPUT pins initialized LOW + } + for (int i=0; i< numleds; i++) { //As a test turn all ON in sequence + digitalWrite(fpins[i], HIGH); + delay (60); + } + delay(400); + for (int i=0; i< numleds; i++) { //Now turn all OFF in sequence + digitalWrite(fpins[i], LOW); + delay (60); + } + // Setup which External Interrupt, the Pin it's associated with that we're using + Dcc.pin(0, 2, 0); + // Call the main DCC Init function to enable the DCC Receiver + Dcc.init( MAN_ID_DIY, 601, FLAGS_MY_ADDRESS_ONLY, 0 ); + delay(800); +#if defined(DECODER_LOADED) + if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET ) +#endif + { + for (int j=0; j < FactoryDefaultCVIndex; j++ ) + Dcc.setCV( FactoryDefaultCVs[j].CV, FactoryDefaultCVs[j].Value); + digitalWrite(fpins[10], 1); + delay (500); + digitalWrite(fpins[10], 0); + } + for ( i=0; i < num_active_functions; i++) { + cv_value = Dcc.getCV(30+i) ; +#ifdef DEBUG + Serial.print(" cv_value: "); + Serial.println(cv_value, DEC) ; +#endif + switch ( cv_value ) { + case 0: // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + break; + case 1: // LED On/Off + ftn_queue[i].inuse = 0; + break; + case 2: + break; + case 3: // NEXT FEATURE for the Future + break; + default: + break; + } + } + master_tim_delay = int(Dcc.getCV(50)) * 11 ; + delta = millis() + master_tim_delay; +} // end setup + +// ================================================================ +void loop() +{ + //MUST call the NmraDcc.process() method frequently + // from the Arduino loop() function for correct library operation + Dcc.process(); + delay(1); +// INPUT OVER RIDE + // Check Master Input Over ride + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + else MasterDecoderDisable = Function0_value & 1; + runEvery(master_tim_delay) digitalWrite(fpins [random (0,numleds)], lightsw() ); +} //end loop + +boolean lightsw() { + if (MasterDecoderDisable == 1) return LOW; //Eventually turn all lights OFF + if (random(0,100)>48) return HIGH; //48 represents a 52% ON time + else return LOW; +} // end lightsw + +void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { +#ifdef DEBUG + Serial.print("Addr= "); + Serial.println(Addr, DEC) ; + Serial.print("FuncState= "); + Serial.println(FuncState, DEC) ; +#endif + switch(FuncGrp) + { + case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1 + exec_function( 0, FunctionPin0, (FuncState & FN_BIT_00)>>4 ); + exec_function( 1, FunctionPin1, (FuncState & FN_BIT_01)); + exec_function( 2, FunctionPin2, (FuncState & FN_BIT_02)>>1); + //exec_function( 3, FunctionPin3, (FuncState & FN_BIT_03)>>2 ); + //exec_function( 4, FunctionPin4, (FuncState & FN_BIT_04)>>3 ); + break; + case FN_5_8: //Function Group 1 S FFFF == 1 F8 F7 F6 F5 & == 0 F12 F11 F10 F9 F8 + //exec_function( 5, FunctionPin5, (FuncState & FN_BIT_05)); + //exec_function( 6, FunctionPin6, (FuncState & FN_BIT_06)>>1 ); + //exec_function( 7, FunctionPin7, (FuncState & FN_BIT_07)>>2 ); + //exec_function( 8, FunctionPin8, (FuncState & FN_BIT_08)>>3 ); + break; + + case FN_9_12: + //exec_function( 9, FunctionPin9, (FuncState & FN_BIT_09)); + //exec_function( 10, FunctionPin10, (FuncState & FN_BIT_10)>>1 ); + //exec_function( 11, FunctionPin11, (FuncState & FN_BIT_11)>>2 ); + //exec_function( 12, FunctionPin12, (FuncState & FN_BIT_12)>>3 ); + break; + case FN_13_20: //Function Group 2 FuncState == F20-F13 Function Control + //exec_function( 13, FunctionPin13, (FuncState & FN_BIT_13); + //exec_function( 14, FunctionPin14, (FuncState & FN_BIT_14)>>1; + //exec_function( 15, FunctionPin15, (FuncState & FN_BIT_15)>>2 ); + //exec_function( 16, FunctionPin16, (FuncState & FN_BIT_16)>>3 ); + break; + + case FN_21_28: + break; + } +} // end notifyDccFunc + +void exec_function (int function, int pin, int FuncState) { +#ifdef DEBUG + Serial.print("function= "); + Serial.println(function, DEC) ; + Serial.print("FuncState= "); + Serial.println(FuncState, DEC) ; +#endif + switch ( Dcc.getCV( 30+function) ) { // Config 0=On/Off,1=Blink + case 0: // Master Disable + Function0_value = byte(FuncState); + break; + case 1: // NEXT FEATURE for the Future + break; + default: + break; + } +} // end exec_function diff --git a/examples/IDEC/IDEC2_2_Building1Wldr/IDEC2_2_Building1Wldr.ino b/examples/IDEC/IDEC2_2_Building1Wldr/IDEC2_2_Building1Wldr.ino new file mode 100644 index 0000000..b24862d --- /dev/null +++ b/examples/IDEC/IDEC2_2_Building1Wldr/IDEC2_2_Building1Wldr.ino @@ -0,0 +1,301 @@ +// Interactive Decoder Random Building Lighting DCC Decoder IDEC2_2_Building1Wldr.ino +// Version 1.08 Geoff Bunza 2020 +// Works with both short and long DCC Addesses +// This decoder will control Random Building Lighting +// F0=Master Function OFF = Function ON DISABLES the decoder +// Input Pin for Decoder Disable Pin 3 Active LOW +/* + F0 == Master Decoder Disable == ON + F1 == Welder 1 Disable == ON + +PRO MINI PIN ASSIGNMENT: +2 - DCC Input +3 - Input Pin for MasterDecoderDisable Active LOW +4 - LED Blue Welder1 +5 - LED White Welder1 +6 - LED +7 - LED +8 - LED +9 - LED +10 - LED +11 - LED +12 - LED +13 - LED +14 A0 - LED +15 A1 - LED +16 A2 - LED +17 A3 - LED +18 A4 - LED +19 A5 - LED +*/ + +// ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP +// ******** AFTER THE INITIAL DECODER LOAD REMOVE THE "//" IN THE FOOLOWING LINE!! +//#define DECODER_LOADED + +// ******** EMOVE THE "//" IN THE FOOLOWING LINE TO SEND DEBUGGING +// ******** INFO TO THE SERIAL MONITOR +//#define DEBUG + +#include +#define runEvery(t) for (static typeof(t) _lasttime;\ + (typeof(t))((typeof(t))millis() - _lasttime) > (t);\ + _lasttime += (t)) +int building_tim_delay; +int welder1_tim_delay; +byte welder1_on = 0; +int welder1_delta; +long delta = 0; +int tctr, tctr2, i; + +int numleds = 16; // Number of Output pins to initialize +int num_active_functions = 2; // Number of Functions stating with F0 +byte fpins [] = {4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; //These are all the Output Pins + +const int MasterDecoderDisablePin = 3; // D3 Master Decoder Disable Input Pin Active LOW +const int Welder1BluePin = 4; // Blue LED simulation Welder 1 +const int Welder1WhitePin = 5; // White LED simulation Welder 1 +const int FunctionPin0 = 20; // Input Master Pin Disable Active LOW {;aceholder +const int FunctionPin1 = 20; // A0 LED +const int FunctionPin2 = 20; // A1 LED +const int FunctionPin3 = 20; // A2 LED +const int FunctionPin4 = 20; //A3 LED +const int FunctionPin5 = 20; //A4 LED +const int FunctionPin6 = 20; //A5 LED +const int FunctionPin7 = 20; // Place holders ONLY +const int FunctionPin8 = 20; // Place holders ONLY +const int FunctionPin9 = 20; // Place holders ONLY +const int FunctionPin10 = 20; // Place holders ONLY +const int FunctionPin11 = 20; // Place holders ONLY +const int FunctionPin12 = 20; // Place holders ONLY +const int FunctionPin13 = 20; // Place holders ONLY +const int FunctionPin14 = 20; // Place holders ONLY +const int FunctionPin15 = 20; // Place holders ONLY +const int FunctionPin16 = 20; // Place holders ONLY +int MasterDecoderDisable = 0; +int MasterDisable_value = 0; +int Disable_welder1 = 0; + +NmraDcc Dcc ; +DCC_MSG Packet ; +uint8_t CV_DECODER_MASTER_RESET = 120; +int t; // temp +struct QUEUE +{ + int inuse; + int current_position; + int increment; + int stop_value; + int start_value; +}; +QUEUE *ftn_queue = new QUEUE[3]; + +struct CVPair +{ + uint16_t CV; + uint8_t Value; +}; + +#define This_Decoder_Address 24 + +CVPair FactoryDefaultCVs [] = +{ + {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address&0x7F }, + + // These two CVs define the Long DCC Address + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, ((This_Decoder_Address>>8)&0x7F)+192 }, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address&0xFF }, + + // ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS +// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps + {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps +// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps + + {CV_DECODER_MASTER_RESET, 0}, + {30, 0}, // F0 Config 0=DISABLE On/Off,1=Disable Welder 1,2=Deisable Welder2 + {31, 1}, // F1 Config 0=DISABLE On/Off,1=Disable Welder 1,2=Deisable Welder2 + {50, 90}, // Master Building Time Delay 0-255 255=Slowest + {51, 127}, // Welder1 Time Constant + {52, 0}, // Extra + {53, 0}, // Extra +}; + +uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +void notifyCVResetFactoryDefault() +{ + // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset + // to flag to the loop() function that a reset to Factory Defaults needs to be done + FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +}; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS + +void setup() +{ +#ifdef DEBUG + Serial.begin(115200); +#endif + pinMode (MasterDecoderDisablePin,INPUT_PULLUP); // Master Decoder Disable Input Pin Active LOW + uint8_t cv_value; + // initialize the digital pins as outputs + for (int i=0; i < numleds; i++) { + pinMode(fpins[i], OUTPUT); + digitalWrite(fpins[i], 0); // All OUPUT pins initialized LOW + } + for (int i=0; i< numleds; i++) { //As a test turn all ON in sequence + digitalWrite(fpins[i], HIGH); + delay (60); + } + delay(400); + for (int i=0; i< numleds; i++) { //Now turn all OFF in sequence + digitalWrite(fpins[i], LOW); + delay (60); + } + // Setup which External Interrupt, the Pin it's associated with that we're using + Dcc.pin(0, 2, 0); + // Call the main DCC Init function to enable the DCC Receiver + Dcc.init( MAN_ID_DIY, 601, FLAGS_MY_ADDRESS_ONLY, 0 ); + delay(800); +#if defined(DECODER_LOADED) + if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET ) +#endif + { + for (int j=0; j < FactoryDefaultCVIndex; j++ ) + Dcc.setCV( FactoryDefaultCVs[j].CV, FactoryDefaultCVs[j].Value); + digitalWrite(fpins[10], 1); + delay (500); + digitalWrite(fpins[10], 0); + } + for ( i=0; i < num_active_functions; i++) { + cv_value = Dcc.getCV(30+i) ; +#ifdef DEBUG + Serial.print(" cv_value: "); + Serial.println(cv_value, DEC) ; +#endif + switch ( cv_value ) { + case 0: // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + break; + case 1: // F1 Disables Welder 1 + Disable_welder1 = 0; // Initialized + break; + case 2: + break; + case 3: // NEXT FEATURE for the Future + break; + default: + break; + } + } + building_tim_delay = int(Dcc.getCV(50)) * 11 ; + + welder1_tim_delay = int(Dcc.getCV(51)) * 21 ; + +} // end setup + +// ================================================================ +void loop() +{ + //MUST call the NmraDcc.process() method frequently + // from the Arduino loop() function for correct library operation + Dcc.process(); + delay(1); + + // INPUT OVER RIDE // Check Master Input Over ride + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + else MasterDecoderDisable = MasterDisable_value & 1; + + // Random Building Lights + runEvery(building_tim_delay) digitalWrite(fpins[random (2,numleds)], lightsw() ); + + // Welder1 + if ((MasterDecoderDisable == 0)&&(Disable_welder1==0)) { + runEvery(welder1_tim_delay) {welder1_on = random(20,50); welder1_delta=random(23,133); } + } + runEvery(welder1_delta) digitalWrite(Welder1WhitePin,run_welder1_wsw() ); + runEvery(welder1_delta) digitalWrite(Welder1BluePin,run_welder1_bsw() ); + +} //end loop + +boolean run_welder1_wsw() { + if ((MasterDecoderDisable == 1)||(welder1_on<=0)) return LOW; //Eventually turn all lights OFF + welder1_on--; + if (random(0,100)>48) return HIGH; //48 represents a 52% ON time + else return LOW; +} // end run_welder1_wsw +boolean run_welder1_bsw() { + if ((MasterDecoderDisable == 1)||(welder1_on<=0)) return LOW; //Eventually turn all lights OFF + welder1_on--; + if (random(0,100)>35) return HIGH; //35 represents a 65% ON time + else return LOW; +} // end run_welder1_bsw + +boolean lightsw() { + if (MasterDecoderDisable == 1) return LOW; //Eventually turn all lights OFF + if (random(0,100)>40) return HIGH; //40 represents a 60% ON time + else return LOW; +} // end lightsw + +void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { +#ifdef DEBUG + Serial.print("Addr= "); + Serial.println(Addr, DEC) ; + Serial.print("FuncState= "); + Serial.println(FuncState, DEC) ; +#endif + switch(FuncGrp) + { + case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1 + exec_function( 0, FunctionPin0, (FuncState & FN_BIT_00)>>4 ); + exec_function( 1, FunctionPin1, (FuncState & FN_BIT_01)); + exec_function( 2, FunctionPin2, (FuncState & FN_BIT_02)>>1); + //exec_function( 3, FunctionPin3, (FuncState & FN_BIT_03)>>2 ); + //exec_function( 4, FunctionPin4, (FuncState & FN_BIT_04)>>3 ); + break; + case FN_5_8: //Function Group 1 S FFFF == 1 F8 F7 F6 F5 & == 0 F12 F11 F10 F9 F8 + //exec_function( 5, FunctionPin5, (FuncState & FN_BIT_05)); + //exec_function( 6, FunctionPin6, (FuncState & FN_BIT_06)>>1 ); + //exec_function( 7, FunctionPin7, (FuncState & FN_BIT_07)>>2 ); + //exec_function( 8, FunctionPin8, (FuncState & FN_BIT_08)>>3 ); + break; + + case FN_9_12: + //exec_function( 9, FunctionPin9, (FuncState & FN_BIT_09)); + //exec_function( 10, FunctionPin10, (FuncState & FN_BIT_10)>>1 ); + //exec_function( 11, FunctionPin11, (FuncState & FN_BIT_11)>>2 ); + //exec_function( 12, FunctionPin12, (FuncState & FN_BIT_12)>>3 ); + break; + case FN_13_20: //Function Group 2 FuncState == F20-F13 Function Control + //exec_function( 13, FunctionPin13, (FuncState & FN_BIT_13); + //exec_function( 14, FunctionPin14, (FuncState & FN_BIT_14)>>1; + //exec_function( 15, FunctionPin15, (FuncState & FN_BIT_15)>>2 ); + //exec_function( 16, FunctionPin16, (FuncState & FN_BIT_16)>>3 ); + break; + + case FN_21_28: + break; + } +} // end notifyDccFunc + +void exec_function (int function, int pin, int FuncState) { +#ifdef DEBUG + Serial.print("function= "); + Serial.println(function, DEC) ; + Serial.print("FuncState= "); + Serial.println(FuncState, DEC) ; +#endif + switch ( Dcc.getCV( 30+function) ) { // Config 0=On/Off,1=Blink + case 0: // Master Disable by Function 0 + MasterDisable_value = byte(FuncState); + break; + case 1: // Master Disable by Function 1 + Disable_welder1 = byte(FuncState); + break; + case 2: // Next Features + break; + default: + break; + } +} // end exec_function diff --git a/examples/IDEC/IDEC2_3_Building2Wldrs/IDEC2_3_Building2Wldrs.ino b/examples/IDEC/IDEC2_3_Building2Wldrs/IDEC2_3_Building2Wldrs.ino new file mode 100644 index 0000000..ccb83ae --- /dev/null +++ b/examples/IDEC/IDEC2_3_Building2Wldrs/IDEC2_3_Building2Wldrs.ino @@ -0,0 +1,344 @@ +// Interactive Decoder Random Building Lighting DCC Decoder IDEC2_3_Building2Wldrs.ino +// Version 1.08 Geoff Bunza 2020 +// Works with both short and long DCC Addesses +// This decoder will control Random Building Lighting +// F0=Master Function OFF = Function ON DISABLES the decoder +// Input Pin for Decoder Disable Pin 3 Active LOW +/* + F0 == Master Decoder Disable == ON + F1 == Welder 1 Disable == ON + F2 == Welder 2 Disable == ON + +PRO MINI PIN ASSIGNMENT: +2 - DCC Input +3 - Input Pin for MasterDecoderDisable Active LOW +4 - LED Blue Welder1 +5 - LED White Welder1 +6 - LED Blue Welder2 +7 - LED White Welder2 +8 - LED +9 - LED +10 - LED +11 - LED +12 - LED +13 - LED +14 A0 - LED +15 A1 - LED +16 A2 - LED +17 A3 - LED +18 A4 - LED +19 A5 - LED +*/ + +// ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP +// ******** AFTER THE INITIAL DECODER LOAD REMOVE THE "//" IN THE FOOLOWING LINE!! +//#define DECODER_LOADED + +// ******** EMOVE THE "//" IN THE FOOLOWING LINE TO SEND DEBUGGING +// ******** INFO TO THE SERIAL MONITOR +//#define DEBUG + +#include +#define runAfter(t) for (static unsigned long _dTimer=millis();\ + (unsigned long)(millis()-_dTimer)>=(t);\ + _dTimer = millis()) +#define runAfterOnce(t) for (static unsigned long _dTimer=millis();\ + (unsigned long)(millis()-_dTimer)*estop>=(t);\ + _dTimer = millis()) +#define runEvery(t) for (static typeof(t) _lasttime;\ + (typeof(t))((typeof(t))millis() - _lasttime) >= (t);\ + _lasttime += (t)) +unsigned long estop = 1; +int building_tim_delay; +int welder1_tim_delay; +int welder2_tim_delay; +byte welder1_on = 0; +byte welder2_on = 0; +int welder1_delta; +int welder2_delta; +long delta = 0; +int tctr, tctr2, i; + +int numleds = 16; // Number of Output pins to initialize +int num_active_functions = 3; // Number of Functions stating with F0 +byte fpins [] = {4,5,6,7,8,9,10,11,12,13,54,55,56,57,58,59}; //These are all the Output Pins + +const int MasterDecoderDisablePin = 3; // D3 Master Decoder Disable Input Pin Active LOW +const int Welder1BluePin = 4; // Blue LED simulation Welder 1 +const int Welder1WhitePin = 5; // White LED simulation Welder 1 +const int Welder2BluePin = 6; // Blue LED simulation Welder 2 +const int Welder2WhitePin = 7; // White LED simulation Welder 2 +const int FunctionPin0 = 20; // Input Master Pin Disable Active LOW {;aceholder +const int FunctionPin1 = 20; // A0 LED +const int FunctionPin2 = 20; // A1 LED +const int FunctionPin3 = 20; // A2 LED +const int FunctionPin4 = 20; //A3 LED +const int FunctionPin5 = 20; //A4 LED +const int FunctionPin6 = 20; //A5 LED +const int FunctionPin7 = 20; // Place holders ONLY +const int FunctionPin8 = 20; // Place holders ONLY +const int FunctionPin9 = 20; // Place holders ONLY +const int FunctionPin10 = 20; // Place holders ONLY +const int FunctionPin11 = 20; // Place holders ONLY +const int FunctionPin12 = 20; // Place holders ONLY +const int FunctionPin13 = 20; // Place holders ONLY +const int FunctionPin14 = 20; // Place holders ONLY +const int FunctionPin15 = 20; // Place holders ONLY +const int FunctionPin16 = 20; // Place holders ONLY +int MasterDecoderDisable = 0; +int MasterDisable_value = 0; +int Disable_welder1 = 0; +int Disable_welder2 = 0; + +NmraDcc Dcc ; +DCC_MSG Packet ; +uint8_t CV_DECODER_MASTER_RESET = 120; +int t; // temp +struct QUEUE +{ + int inuse; + int current_position; + int increment; + int stop_value; + int start_value; +}; +QUEUE *ftn_queue = new QUEUE[3]; + +struct CVPair +{ + uint16_t CV; + uint8_t Value; +}; + +#define This_Decoder_Address 24 + +CVPair FactoryDefaultCVs [] = +{ + {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address&0x7F }, + + // These two CVs define the Long DCC Address + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, ((This_Decoder_Address>>8)&0x7F)+192 }, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address&0xFF }, + + // ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS +// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps + {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps +// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps + + {CV_DECODER_MASTER_RESET, 0}, + {30, 0}, // F0 Config 0=DISABLE On/Off,1=Disable Welder 1,2=Deisable Welder2 + {31, 1}, // F1 Config 0=DISABLE On/Off,1=Disable Welder 1,2=Deisable Welder2 + {32, 2}, // F2 Config 0=DISABLE On/Off,1=Disable Welder 1,2=Deisable Welder2 + {50, 90}, // Master Building Time Delay 0-255 255=Slowest + {51, 127}, // Welder1 Time Constant + {52, 147}, // Welder2 Time Constant + {53, 0}, // Extra +}; + +uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +void notifyCVResetFactoryDefault() +{ + // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset + // to flag to the loop() function that a reset to Factory Defaults needs to be done + FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +}; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS + +void setup() +{ +#ifdef DEBUG + Serial.begin(115200); +#endif + pinMode (MasterDecoderDisablePin,INPUT_PULLUP); // Master Decoder Disable Input Pin Active LOW + uint8_t cv_value; + // initialize the digital pins as outputs + for (int i=0; i < numleds; i++) { + pinMode(fpins[i], OUTPUT); + digitalWrite(fpins[i], 0); // All OUPUT pins initialized LOW + } + for (int i=0; i< numleds; i++) { //As a test turn all ON in sequence + digitalWrite(fpins[i], HIGH); + delay (60); + } + delay(400); + for (int i=0; i< numleds; i++) { //Now turn all OFF in sequence + digitalWrite(fpins[i], LOW); + delay (60); + } + // Setup which External Interrupt, the Pin it's associated with that we're using + Dcc.pin(0, 2, 0); + // Call the main DCC Init function to enable the DCC Receiver + Dcc.init( MAN_ID_DIY, 601, FLAGS_MY_ADDRESS_ONLY, 0 ); + delay(800); +#if defined(DECODER_LOADED) + if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET ) +#endif + { + for (int j=0; j < FactoryDefaultCVIndex; j++ ) + Dcc.setCV( FactoryDefaultCVs[j].CV, FactoryDefaultCVs[j].Value); + digitalWrite(fpins[10], 1); + delay (500); + digitalWrite(fpins[10], 0); + } + for ( i=0; i < num_active_functions; i++) { + cv_value = Dcc.getCV(30+i) ; +#ifdef DEBUG + Serial.print(" cv_value: "); + Serial.println(cv_value, DEC) ; +#endif + switch ( cv_value ) { + case 0: // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + break; + case 1: // F1 Disables Welder 1 + Disable_welder1 = 0; // Initialized + break; + case 2: // F2 Disables Welder 2 + Disable_welder2 = 0; // Initialized + break; + case 3: // NEXT FEATURE for the Future + + break; + default: + break; + } + } + building_tim_delay = int(Dcc.getCV(50)) * 11 ; + + welder1_tim_delay = int(Dcc.getCV(51)) * 21 ; + + welder2_tim_delay = int(Dcc.getCV(52)) * 21 ; + +} // end setup + +// ================================================================ +void loop() +{ + //MUST call the NmraDcc.process() method frequently + // from the Arduino loop() function for correct library operation + Dcc.process(); + delay(1); + + // INPUT OVER RIDE // Check Master Input Over ride + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + else MasterDecoderDisable = MasterDisable_value & 1; + + // Random Building Lights + runEvery(building_tim_delay) digitalWrite(fpins[random (4,numleds)], lightsw() ); + + // Welder1 + if ((MasterDecoderDisable == 0)&&(Disable_welder1==0)) { + runEvery(welder1_tim_delay) {welder1_on = random(20,50); welder1_delta=random(23,133); } + } + runEvery(welder1_delta) digitalWrite(Welder1WhitePin,run_welder1_wsw() ); + runEvery(welder1_delta) digitalWrite(Welder1BluePin,run_welder1_bsw() ); + + // Welder2 + if ((MasterDecoderDisable == 0)&&(Disable_welder2==0)) { + runEvery(welder2_tim_delay) {welder2_on = random(25,47); welder2_delta=random(22,125); } + } + runEvery(welder2_delta) digitalWrite(Welder2WhitePin,run_welder2_wsw() ); + runEvery(welder2_delta) digitalWrite(Welder2BluePin,run_welder2_bsw() ); + +} //end loop + +boolean run_welder1_wsw() { + if ((MasterDecoderDisable == 1)||(welder1_on<=0)) return LOW; //Eventually turn all lights OFF + welder1_on--; + if (random(0,100)>48) return HIGH; //48 represents a 52% ON time + else return LOW; +} // end run_welder1_wsw +boolean run_welder1_bsw() { + if ((MasterDecoderDisable == 1)||(welder1_on<=0)) return LOW; //Eventually turn all lights OFF + welder1_on--; + if (random(0,100)>35) return HIGH; //35 represents a 65% ON time + else return LOW; +} // end run_welder1_bsw + +boolean run_welder2_wsw() { + if ((MasterDecoderDisable == 1)||(welder2_on<=0)) return LOW; //Eventually turn all lights OFF + welder2_on--; + if (random(0,100)>48) return HIGH; //48 represents a 52% ON time + else return LOW; +} // end run_welder2_wsw +boolean run_welder2_bsw() { + if ((MasterDecoderDisable == 1)||(welder2_on<=0)) return LOW; //Eventually turn all lights OFF + welder2_on--; + if (random(0,100)>35) return HIGH; //35 represents a 65% ON time + else return LOW; +} // end run_welder2_bsw + +boolean lightsw() { + if (MasterDecoderDisable == 1) return LOW; //Eventually turn all lights OFF + if (random(0,100)>40) return HIGH; //40 represents a 60% ON time + else return LOW; +} // end lightsw + +void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { +#ifdef DEBUG + Serial.print("Addr= "); + Serial.println(Addr, DEC) ; + Serial.print("FuncState= "); + Serial.println(FuncState, DEC) ; +#endif + switch(FuncGrp) + { + case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1 + exec_function( 0, FunctionPin0, (FuncState & FN_BIT_00)>>4 ); + exec_function( 1, FunctionPin1, (FuncState & FN_BIT_01)); + exec_function( 2, FunctionPin2, (FuncState & FN_BIT_02)>>1); + //exec_function( 3, FunctionPin3, (FuncState & FN_BIT_03)>>2 ); + //exec_function( 4, FunctionPin4, (FuncState & FN_BIT_04)>>3 ); + break; + case FN_5_8: //Function Group 1 S FFFF == 1 F8 F7 F6 F5 & == 0 F12 F11 F10 F9 F8 + //exec_function( 5, FunctionPin5, (FuncState & FN_BIT_05)); + //exec_function( 6, FunctionPin6, (FuncState & FN_BIT_06)>>1 ); + //exec_function( 7, FunctionPin7, (FuncState & FN_BIT_07)>>2 ); + //exec_function( 8, FunctionPin8, (FuncState & FN_BIT_08)>>3 ); + break; + + case FN_9_12: + //exec_function( 9, FunctionPin9, (FuncState & FN_BIT_09)); + //exec_function( 10, FunctionPin10, (FuncState & FN_BIT_10)>>1 ); + //exec_function( 11, FunctionPin11, (FuncState & FN_BIT_11)>>2 ); + //exec_function( 12, FunctionPin12, (FuncState & FN_BIT_12)>>3 ); + break; + case FN_13_20: //Function Group 2 FuncState == F20-F13 Function Control + //exec_function( 13, FunctionPin13, (FuncState & FN_BIT_13); + //exec_function( 14, FunctionPin14, (FuncState & FN_BIT_14)>>1; + //exec_function( 15, FunctionPin15, (FuncState & FN_BIT_15)>>2 ); + //exec_function( 16, FunctionPin16, (FuncState & FN_BIT_16)>>3 ); + break; + + case FN_21_28: + break; + } +} // end notifyDccFunc + +void exec_function (int function, int pin, int FuncState) { +#ifdef DEBUG + Serial.print("function= "); + Serial.println(function, DEC) ; + Serial.print("FuncState= "); + Serial.println(FuncState, DEC) ; +#endif + switch ( Dcc.getCV( 30+function) ) { // Config 0=On/Off,1=Blink + case 0: // Master Disable by Function 0 + MasterDisable_value = byte(FuncState); + break; + case 1: // Master Disable by Function 1 + Disable_welder1 = byte(FuncState); + break; + case 2: // Master Disable by Function 1 + Disable_welder2 = byte(FuncState); + break; + case 3: // Next Features + + break; + default: + break; + } +} // end exec_function diff --git a/examples/IDEC/IDEC2_4_FunctionSets/IDEC2_4_FunctionSets.ino b/examples/IDEC/IDEC2_4_FunctionSets/IDEC2_4_FunctionSets.ino new file mode 100644 index 0000000..9dbfec4 --- /dev/null +++ b/examples/IDEC/IDEC2_4_FunctionSets/IDEC2_4_FunctionSets.ino @@ -0,0 +1,1229 @@ +// Interactive Decoder Random Switches IDEC2_4_FunctionSetsDev.ino +// Version 1.08 Geoff Bunza 2020 +// Works with both short and long DCC Addesses +// This decoder will control Switch Sequences, servos, sounds and LEDs +// F0=Master Function OFF = Function ON DISABLES the decoder +/* F0 is configured as Master Decoder Disable Override ON==Disable Decoder + * Input Pin for Decoder Disable Pin 16/A2 Active LOW +// F1-F8 Eight Switch Sets 1-8 controlled by Input pins 3,4,5,6,7,8,9,10 respectively + * F1-F10 also runs switch sets (1-8) All Switch Sets are defined by groups of 16 CVs + - Either a DCC Function 1-10 on OR an Input Pin (3,4,5,6,7,8,9,10) Switched Low enables a decoder function (ON) + - BOTH the respective DCC Decoder Function 1-8 must be Off AND its respective Input Pin (3,4,5,6,7,8,9,10) + MUST be High for a decoder function to be considered disabled + - A decoder function LEFT ENABLED will repreat the respecpective action as long as it is enabled + * Switch Set CV's are 5 groups of 3 CVs each: + CV1 - A delay (0-255) which will be multiplied by the + MasterTimeConstant setting time increments from milliseconds to minutes + 0 = No Delay + CV2 - A Mode or Command byte Describing what will be executed in this Switch Step, including: + 0 = No Operation / Null /Skip + 1 = Simple pin switch on/off + 2= Random pin switch on/off + 3 = Weighted Random pin switch on/off default is 60% ON time but can be set to anything 1-99% + 4 = Play sound track using fpin value for the track 1-126, 0 = Skip Play, 127 = Select Random Track + from First_Track to Last_Track inclusive; + MSB=0->No Volume Change MSB=1 -> Set Volume to default_volume + 5 = Position Servo to 0-180 full speed of travel + 6 = Dual pin on/off used for alternate blink fpin and fpin+1 (MSB set value for fpin state) + 7 = Start another Switching set based on the fpin argument (Used to chain Switch Sets) + 8 = Start another Switching set based on the fpin argument ONLY if NOT already started + CV3 - An argument representing the Pin number affected in the lower 7 bits and the High bit (0x80 or 128) a value + or a general parameter like a servo position, a Sound track, or a sound set number to jump to + * Switch sets start with CVs: 50,66,82,98,114,130,146,162,178,194 + * MAX one of 11 Configurations per pin function: + * Config 0=DISABLE On/Off,1-10=Switch Control 1-8 + +PRO MINI PIN ASSIGNMENT: +2 - DCC Input +3 - Input Pin Switch 1 +4 - Input Pin Switch 2 +5 - Input Pin Switch 3 +6 - Input Pin Switch 4 +7 - Input Pin Switch 5 +8 - Input Pin Switch 6 +9 - Input Pin Switch 7 +10 - Input Pin Switch 8 +11 - Switch 1 +12 - Switch 2 +13 - Switch 3 +14 A0 - Switch 4 or default_servo_pin +15 A1 - Switch 5 or default sound player pin (TX) connected to DFPlayer1 (RX) Pin 2 via 1K Ohm 1/4W Resistor +16 A2 - Input Pin for MasterDecoderDisable Active LOW +17 A3 - Switch 6 +18 A4 - Switch 7 +19 A5 - Switch 8 +*/ +// ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP +// ******** AFTER THE INITIAL DECODER LOAD REMOVE THE "//" IN THE FOOLOWING LINE!! +//#define DECODER_LOADED + +// ******** REMOVE THE "//" IN THE FOLOWING LINE TO enable sound DFPlayer on Pin 15 +//#define SOUND_PLAYER15 + +// ******** REMOVE THE "//" IN THE FOLOWING LINE TO enable SERVO USE +//#define USE_SERVO14 + +// ******** REMOVE THE "//" IN THE FOLOWING LINE TO SEND DEBUGGING +// ******** INFO TO THE SERIAL MONITOR *****NOTE Turning DEBUG ON changes ALL Timing!! +//#define DEBUG + + +#include + +#ifdef USE_SERVO14 +#include +SoftwareServo servo[2]; +#endif +#define default_servo_pin 14 + +#ifdef SOUND_PLAYER15 +#include +#include +SoftwareSerial DFSerial1(22,15); // PRO MINI RX, PRO MINI TX serial to DFPlayer +DFRobotDFPlayerMini Player1; +#endif +#define default_volume 25 // sets default volume 0-30, 0 == OFF, >30 == Skip Track +#define First_Track 1 // Play Random Tracks First_Track#=Start_Track >=1 +#define Last_Track 12 // Play Random Tracks Last_Track= Last Playable Track in Range <= Last Numbered Track +const int audiocmddelay = 34; + +#define This_Decoder_Address 24 +uint8_t CV_DECODER_MASTER_RESET = 252; + +//Uncomment ONLY ONE of the following: +//#define MasterTimeConstant 10L // 10's of milliseconds Timing +#define MasterTimeConstant 100L // Tenths of a second Timing +//#define MasterTimeConstant 1000L // Seconds Timing +//#define MasterTimeConstant 10000L // 10's of Seconds Timing +//#define MasterTimeConstant 60000L // Minutes Timing +//#define MasterTimeConstant 3600000L // Hours Timing + +int del_tim = 4000; +uint16_t ttemp, i; + +byte ss1[] = {0,0,0,0,0,0}; unsigned long ss1delay=0; +byte ss2[] = {0,0,0,0,0,0}; unsigned long ss2delay=0; +byte ss3[] = {0,0,0,0,0,0}; unsigned long ss3delay=0; +byte ss4[] = {0,0,0,0,0,0}; unsigned long ss4delay=0; +byte ss5[] = {0,0,0,0,0,0}; unsigned long ss5delay=0; +byte ss6[] = {0,0,0,0,0,0}; unsigned long ss6delay=0; +byte ss7[] = {0,0,0,0,0,0}; unsigned long ss7delay=0; +byte ss8[] = {0,0,0,0,0,0}; unsigned long ss8delay=0; +byte ss9[] = {0,0,0,0,0,0}; unsigned long ss9delay=0; +byte ss10[] = {0,0,0,0,0,0}; unsigned long ss10delay=0; +bool run_switch_set [ ] = {false,false,false,false,false,false,false,false,false,false,false}; +byte switchset_channel[ ]={0,0,0,0,0,0,0,0,0,0,0}; +const int MasterDecoderDisablePin = 16; // D16/A0 Master Decoder Disable Input Pin Active LOW + +const int numINpins = 9; // Number of INput pins to initialize +byte inputpins [] = {3,4,5,6,7,8,9,10,16}; //These are all the Input Pins +const int numfpins = 8; // Number of Output pins to initialize +const int num_active_functions = 11; // Number of Functions stating with F0 +byte fpins [] = {11,12,13,14,15,17,18,19}; //These are all the Output Pins (first 15 is placeholder) +const int FunctionPin0 = 20; // D14/A0 DFPlayer Transmit (TX) Pin 3 +const int FunctionPin1 = 20; // A2 LED Place holders ONLY +const int FunctionPin2 = 20; // A3 LED Place holders ONLY +const int FunctionPin3 = 20; // A4 LED Place holders ONLY +const int FunctionPin4 = 20; // A5 LED Place holders ONLY +const int FunctionPin5 = 20; // A6 LED Place holders ONLY +const int FunctionPin6 = 20; // A7 Place holders ONLY +const int FunctionPin7 = 20; // A8 Place holders ONLY +const int FunctionPin8 = 20; // A9 Place holders ONLY +#define switch1 11 +#define switch2 12 +#define switch3 13 +#define switch4 14 +#define switch5 15 +#define switch6 17 +#define switch7 18 +#define switch8 19 +#define on 0x80 +#define off 0 +const int FunctionPin9 = 20; // Place holders ONLY +const int FunctionPin10 = 20; // Place holders ONLY +const int FunctionPin11 = 20; // F13 LED +const int FunctionPin12 = 20; // F12 LED +const int FunctionPin13 = 20; // F13 LED +const int FunctionPin14 = 20; // F14 LED +const int FunctionPin15 = 20; // Place holders ONLY +int MasterDecoderDisable = 0; +int Function0_value = 0; +byte function_value [ ] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +uint8_t cv_value; + +NmraDcc Dcc ; +DCC_MSG Packet ; +int t; // temp +struct QUEUE +{ + int inuse; + int current_position; + int increment; + int stop_value; + int start_value; +}; +QUEUE *ftn_queue = new QUEUE[17]; + +struct CVPair +{ + uint16_t CV; + uint8_t Value; +}; +CVPair FactoryDefaultCVs [] = +{ + {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address&0x7F }, + + // These two CVs define the Long DCC Address + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, ((This_Decoder_Address>>8)&0x7F)+192 }, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address&0xFF }, + + // ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS +// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps + {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps +// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps + {CV_DECODER_MASTER_RESET, 0}, + + {30, 0}, //F0 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + + {31, 1}, //F1 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {32, 2}, //F2 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {33, 3}, //F3 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {34, 4}, //F4 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {35, 5}, //F5 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {36, 6}, //F6 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {37, 7}, //F7 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {38, 8}, //F8 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {39, 9}, //F9 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {40, 10}, //F10 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + + {41, 11}, + {42, 11}, + {43, 11}, + {44, 11}, + {45, 22}, //F15 not used + + {50, 3}, // Wait1 0-254 0.1 Seconds // switch SET 1 + {51, 1}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {52, switch3+on}, // Switch Pin1 + {53, 6}, // Wait2 0-254 0.1 Seconds + {54, 5}, // Switch Mode + {55, 165}, // Switch Pin2 + {56, 10}, // Wait3 0-254 0.1 Seconds + {57, 4}, // Switch Mode + {58, 11+128}, // Switch Pin3 + {59, 10}, // Wait4 0-254 0.1 Seconds + {60, 5}, // Switch Mode + {61, 20}, // Switch Pin4 + {62, 15}, // Wait5 0-254 0.1 Seconds + {63, 1}, // Switch Mode + {64, switch3+off}, // Switch Pin5 + {65, 0}, // switch Set Channel == LSB 0/1 + + {66, 2}, // Wait1 0-254 0.1 Seconds // switch SET 2 + {67, 2}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {68, switch3+on}, // Switch Pin1 + {69, 6}, // Wait2 0-254 0.1 Seconds + {70, 2}, // Switch Mode + {71, switch3+off}, // Switch Pin2 + {72, 6}, // Wait3 0-254 0.1 Seconds + {73, 2}, // Switch Mode + {74, switch3+on}, // Switch Pin3 + {75, 6}, // Wait4 0-254 0.1 Seconds + {76, 2}, // Switch Mode + {77, switch3+off}, // Switch Pin4 + {78, 8}, // Wait5 0-254 0.1 Seconds + {79, 8}, // Switch Mode + {80, 3}, // Switch Pin5 + {81, 0}, // switch Set Channel == LSB 0/1 + + {82, 0}, // Wait1 0-254 0.1 Seconds // switch SET 3 + {83, 1}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {84, switch3+on}, // Switch Pin1 + {85, 8}, // Wait2 0-254 0.1 Seconds + {86, 1}, // Switch Mode + {87, switch3+off}, // Switch Pin2 + {88, 8}, // Wait3 0-254 0.1 Seconds + {89, 1}, // Switch Mode + {90, switch3+on}, // Switch Pin3 + {91, 8}, // Wait4 0-254 0.1 Seconds + {92, 1}, // Switch Mode + {93, switch3+off}, // Switch Pin4 + {94, 8}, // Wait5 0-254 0.1 Seconds + {95, 8}, // Switch Mode + {96, 4}, // Switch Pin5 + {97, 0}, // switch Set Channel == LSB 0/1 + + {98, 0}, // Wait1 0-254 0.1 Seconds // switch SET 4 + {99, 1}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {100, switch3+on}, // Switch Pin1 + {101, 8}, // Wait2 0-254 0.1 Seconds + {102, 1}, // Switch Mode + {103, switch3+off}, // Switch Pin2 + {104, 8}, // Wait3 0-254 0.1 Seconds + {105, 1}, // Switch Mode + {106, switch3+on}, // Switch Pin3 + {107, 8}, // Wait4 0-254 0.1 Seconds + {108, 1}, // Switch Mode + {109, switch3+off}, // Switch Pin4 + {110, 8}, // Wait5 0-254 0.1 Seconds + {111, 8}, // Switch Mode + {112, 5}, // Switch Pin5 + {113, 0}, // switch Set Channel == LSB 0/1 + + {114, 0}, // Wait1 0-254 0.1 Seconds // switch SET 5 + {115, 1}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {116, switch3+on}, // Switch Pin1 + {117, 8}, // Wait2 0-254 0.1 Seconds + {118, 1}, // Switch Mode + {119, switch3+off}, // Switch Pin2 + {120, 8}, // Wait3 0-254 0.1 Seconds + {121, 1}, // Switch Mode + {122, switch3+on}, // Switch Pin3 + {123, 8}, // Wait4 0-254 0.1 Seconds + {124, 1}, // Switch Mode + {125, switch3+off}, // Switch Pin4 + {126, 8}, // Wait5 0-254 0.1 Seconds + {127, 8}, // Switch Mode + {128, 6}, // Switch Pin5 + {129, 0}, // switch Set Channel == LSB 0/1 + + {130, 0}, // Wait1 0-254 0.1 Seconds // switch SET 6 + {131, 6}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {132, switch3+on}, // Switch Pin1 + {133, 9}, // Wait2 0-254 0.1 Seconds + {134, 6}, // Switch Mode + {135, switch3+off}, // Switch Pin2 + {136, 9}, // Wait3 0-254 0.1 Seconds + {137, 6}, // Switch Mode + {138, switch3+on}, // Switch Pin3 + {139, 9}, // Wait4 0-254 0.1 Seconds + {140, 6}, // Switch Mode + {141, switch3+off}, // Switch Pin4 + {142, 9}, // Wait5 0-254 0.1 Seconds + {143, 8}, // Switch Mode + {144, 7}, // Switch Pin5 + {145, 0}, // switch Set Channel == LSB 0/1 + + {146, 0}, // Wait1 0-254 0.1 Seconds // switch SET 7 + {147, 1}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {148, switch3+on}, // Switch Pin1 + {149, 8}, // Wait2 0-254 0.1 Seconds + {150, 1}, // Switch Mode + {151, switch3+off}, // Switch Pin2 + {152, 8}, // Wait3 0-254 0.1 Seconds + {153, 1}, // Switch Mode + {154, switch3+on}, // Switch Pin3 + {155, 8}, // Wait4 0-254 0.1 Seconds + {156, 1}, // Switch Mode + {157, switch3+off}, // Switch Pin4 + {158, 8}, // Wait5 0-254 0.1 Seconds + {159, 8}, // Switch Mode + {160, 8}, // Switch Pin5 + {161, 0}, // switch Set Channel == LSB 0/1 + + {162, 0}, // Wait1 0-254 0.1 Seconds // switch SET 8 + {163, 1}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {164, switch3+on}, // Switch Pin1 + {165, 8}, // Wait2 0-254 0.1 Seconds + {166, 1}, // Switch Mode + {167, switch3+off}, // Switch Pin2 + {168, 8}, // Wait3 0-254 0.1 Seconds + {169, 1}, // Switch Mode + {170, switch3+on}, // Switch Pin3 + {171, 8}, // Wait4 0-254 0.1 Seconds + {172, 8}, // Switch Mode + {173, switch3+off}, // Switch Pin4 + {174, 8}, // Wait5 0-254 0.1 Seconds + {175, 8}, // Switch Mode + {176, 9}, // Switch Pin5 + {177, 0}, // switch Set Channel == LSB 0/1 + + {178, 0}, // Wait1 0-254 0.1 Seconds // switch SET 9 + {179, 1}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {180, switch3+on}, // Switch Pin1 + {181, 9}, // Wait2 0-254 0.1 Seconds + {182, 1}, // Switch Mode + {183, switch3+off}, // Switch Pin2 + {184, 8}, // Wait3 0-254 0.1 Seconds + {185, 1}, // Switch Mode + {186, switch2+on}, // Switch Pin3 + {187, 12}, // Wait4 0-254 0.1 Seconds + {188, 1}, // Switch Mode + {189, switch2+off}, // Switch Pin4 + {190, 0}, // Wait5 0-254 0.1 Seconds + {191, 0}, // Switch Mode + {192, 0}, // Switch Pin5 + {193, 0}, // switch Set Channel == LSB 0/1 + + {194, 4}, // Wait1 0-254 0.1 Seconds // switch SET 10 + {195, 10}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {196, switch3+on}, // Switch Pin1 + {197, 10}, // Wait2 0-254 0.1 Seconds + {198, 10}, // Switch Mode + {199, switch3+on}, // Switch Pin2 + {200, 4}, // Wait3 0-254 0.1 Seconds + {201, 10}, // Switch Mode + {202, switch3+on}, // Switch Pin3 + {203, 4}, // Wait4 0-254 0.1 Seconds + {204, 10}, // Switch Mode + {205, switch3+on}, // Switch Pin4 + {206, 6}, // Wait5 0-254 0.1 Seconds + {207, 10}, // Switch Mode + {208, switch3+off}, // Switch Pin5 + {209, 0}, // switch Set Channel == LSB 0/1 + + //252,252 CV_DECODER_MASTER_RESET + + {253, 0}, // Extra +}; + +uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +void notifyCVResetFactoryDefault() +{ + // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset + // to flag to the loop() function that a reset to Factory Defaults needs to be done + FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +}; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS + +void setup() //****************************************************** +{ +#ifdef DEBUG + Serial.begin(115200); +#endif + +#ifdef SOUND_PLAYER15 + DFSerial1.begin (9600); + Player1.begin (DFSerial1); +#endif + +#ifdef USE_SERVO14 + servo[0].attach(default_servo_pin); // Start Servo on default_servo_pin //Position Servo + delay(50); + SoftwareServo::refresh(); +#endif + + pinMode (MasterDecoderDisablePin,INPUT_PULLUP); // Master Decoder Disable Input Pin Active LOW + + // initialize the digital pins as outputs + for (int i=0; i < numfpins; i++) { + pinMode(fpins[i], OUTPUT); + digitalWrite(fpins[i], 0); // All OUPUT pins initialized LOW + } + // initialize the digital pins as inputs + for (int i=0; i < numINpins; i++) { + pinMode(inputpins[i], INPUT_PULLUP); + } + // Setup which External Interrupt, the Pin it's associated with that we're using + Dcc.pin(0, 2, 0); + // Call the main DCC Init function to enable the DCC Receiver + Dcc.init( MAN_ID_DIY, 61, FLAGS_MY_ADDRESS_ONLY, 0 ); + delay(800); +#if defined(DECODER_LOADED) + if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET ) +#endif + { + for (int j=0; j < FactoryDefaultCVIndex; j++ ) + Dcc.setCV( FactoryDefaultCVs[j].CV, FactoryDefaultCVs[j].Value); + } + // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; +#ifdef DEBUG + Serial.println("CV Dump:"); + for (i=30; i<41; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=30; i<41; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Switch Set 1"); + for (i=50; i<66; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=50; i<66; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Switch Set 2"); + for (i=66; i<82; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=66; i<82; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Switch Set 3"); + for (i=82; i<98; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=82; i<98; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Switch Set 4"); + for (i=98; i<114; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=98; i<114; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Switch Set 5"); + for (i=114; i<130; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=114; i<130; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Switch Set 6"); + for (i=130; i<146; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=130; i<146; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Switch Set 7"); + for (i=146; i<162; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=146; i<162; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Switch Set 8"); + for (i=162; i<178; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=162; i<178; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Switch Set 9"); + for (i=178; i<194; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=178; i<194; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Switch Set 10"); + for (i=194; i<210; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=194; i<210; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } +#endif +} +void loop() //*********************************************************************************** +{ + //MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation + Dcc.process(); +#ifdef USE_SERVO14 + SoftwareServo::refresh(); +#endif + + //delay(1); +// INPUT OVER RIDES + // Check Master Input Over ride + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + else MasterDecoderDisable = Function0_value & 1; + if (MasterDecoderDisable == 1) { + for (i=0; i < numfpins; i++) digitalWrite(fpins[i], 0); // All LEDs set LOW + } +// ******************************************************************************** + if (MasterDecoderDisable == 0) { + for (i=0; i < num_active_functions; i++) { + cv_value = Dcc.getCV(30+i) ; +#ifdef DEBUG + //Serial.print(" cv_value: "); + //Serial.println(cv_value, DEC) ; +#endif + switch ( cv_value ) { + case 0: // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + break; + case 1: // + if (((digitalRead(3)==LOW)||(function_value[cv_value]==1)) && !run_switch_set[cv_value]) { + ss1[0]=1; run_switch_set[cv_value]=true; +#ifdef DEBUG + Serial.print(" cv_value: "); + Serial.println(cv_value, DEC) ; + Serial.print(" function_value[cv_value]: "); + Serial.println(function_value[cv_value], DEC) ; + Serial.print(" ss1[0]: "); + Serial.println(ss1[0], DEC) ; + Serial.print(" run_switch_set[cv_value]: "); + Serial.println(run_switch_set[cv_value], DEC) ; +#endif + } + break; + case 2: // + if (((digitalRead(4)==LOW)||(function_value[cv_value]==1)) && !run_switch_set[cv_value]) { + ss2[0]=1; run_switch_set[cv_value]=true; + } + break; + case 3: // + if (((digitalRead(5)==LOW)||(function_value[cv_value]==1)) && !run_switch_set[cv_value]) { + ss3[0]=1; run_switch_set[cv_value]=true; } + break; + case 4: // + if (((digitalRead(6)==LOW)||(function_value[cv_value]==1)) && !run_switch_set[cv_value]) { + ss4[0]=1; run_switch_set[cv_value]=true; } + break; + case 5: // + if (((digitalRead(7)==LOW)||(function_value[cv_value]==1)) && !run_switch_set[cv_value]) { + ss5[0]=1; run_switch_set[cv_value]=true; } + break; + case 6: // + if (((digitalRead(8)==LOW)||(function_value[cv_value]==1)) && !run_switch_set[cv_value]) { + ss6[0]=1; run_switch_set[cv_value]=true; } + break; + case 7: // + if (((digitalRead(9)==LOW)||(function_value[cv_value]==1)) && !run_switch_set[cv_value]) { + ss7[0]=1; run_switch_set[cv_value]=true; } + break; + case 8: // + if (((digitalRead(10)==LOW)||(function_value[cv_value]==1)) && !run_switch_set[cv_value]) { + ss8[0]=1; run_switch_set[cv_value]=true; } + break; + case 9: // + if ((function_value[cv_value]==1) && !run_switch_set[cv_value]) { + ss9[0]=1; run_switch_set[cv_value]=true; } + break; + case 10: // + if ((function_value[cv_value]==1) && !run_switch_set[cv_value]) { + ss10[0]=1; run_switch_set[cv_value]=true; } + break; + case 11: // Extra + default: + break; + } + } + } + // ========================== switch Set 1 Start Run + if (ss1[0]==1) { + ss1delay=millis()+(long(Dcc.getCV(50)*MasterTimeConstant)); // Wait1 + ss1[0]=0; ss1[1]=1; + } + if ((ss1[1]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(52)); +#ifdef DEBUG + Serial.print(" Here 1: "); + Serial.println(ttemp, DEC) ; +#endif + if (ttemp!=0) exec_switch_function(Dcc.getCV(51),ttemp&0x3f,ttemp>>7); // execute switch function 1 + ss1delay=millis()+(long(Dcc.getCV(53)*MasterTimeConstant)); // Wait2 + ss1[1]=0; ss1[2]=1; + } + if ((ss1[2]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(55)); +#ifdef DEBUG + Serial.print(" Here 2: "); + Serial.println(ttemp, DEC) ; +#endif + if (ttemp!=0) exec_switch_function (Dcc.getCV(54),ttemp&0x3f,ttemp>>7); // execute switch function 2 + ss1delay=millis()+(long(Dcc.getCV(56)*MasterTimeConstant)); // Wait3 + ss1[2]=0; ss1[3]=1; + } + if ((ss1[3]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(58)); +#ifdef DEBUG + Serial.print(" Here 3: "); + Serial.println(ttemp, DEC) ; +#endif + if (ttemp!=0) exec_switch_function(Dcc.getCV(57),ttemp&0x3f,ttemp>>7); // execute switch function 3 + ss1delay=millis()+(long(Dcc.getCV(59)*MasterTimeConstant)); // Wait4 + ss1[3]=0; ss1[4]=1; + } + if ((ss1[4]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(61)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(60),ttemp&0x3f,ttemp>>7); // execute switch function 4 + ss1delay=millis()+(long(Dcc.getCV(62)*MasterTimeConstant)); // Wait5 + ss1[4]=0; ss1[5]=1; + } + if ((ss1[5]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(64)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(63),ttemp&0x3f,ttemp>>7); // execute switch function 5 + ss1[5]=0; run_switch_set[1]=false; + } +// ========================== switch Set 2 Start Run + if (ss2[0]==1) { + ss2delay=millis()+(long(Dcc.getCV(66)*MasterTimeConstant)); // Wait1 + ss2[0]=0; ss2[1]=1; + } + if ((ss2[1]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(68)); +#ifdef DEBUG + Serial.print(" Here 21: "); + Serial.println(ttemp, DEC) ; +#endif + if (ttemp!=0) exec_switch_function(Dcc.getCV(67),ttemp&0x3f&0x3f,ttemp>>7); // execute switch function 1 + ss2delay=millis()+(long(Dcc.getCV(69)*MasterTimeConstant)); // Wait2 + ss2[1]=0; ss2[2]=1; + } + if ((ss2[2]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(71)); +#ifdef DEBUG + Serial.print(" Here 22: "); + Serial.println(ttemp, DEC) ; +#endif + if (ttemp!=0) exec_switch_function(Dcc.getCV(70),ttemp&0x3f,ttemp>>7); // execute switch function 2 + ss2delay=millis()+(long(Dcc.getCV(72)*MasterTimeConstant)); // Wait3 + ss2[2]=0; ss2[3]=1; + } + if ((ss2[3]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(74)); +#ifdef DEBUG + Serial.print(" Here 23: "); + Serial.println(ttemp, DEC) ; +#endif + if (ttemp!=0) exec_switch_function(Dcc.getCV(73),ttemp&0x3f,ttemp>>7); // execute switch function 3 + ss2delay=millis()+(long(Dcc.getCV(75)*MasterTimeConstant)); // Wait4 + ss2[3]=0; ss2[4]=1; + } + if ((ss2[4]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(77)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(76),ttemp&0x3f,ttemp>>7); // execute switch function 4 + ss2delay=millis()+(long(Dcc.getCV(78)*MasterTimeConstant)); // Wait5 + ss2[4]=0; ss2[5]=1; + } + if ((ss2[5]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(80)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(79),ttemp&0x3f,ttemp>>7); // execute switch function 5 + ss2[5]=0; run_switch_set[2]=false; + } +// ========================== switch Set 3 Start Run + if (ss3[0]==1) { + ss3delay=millis()+(long(Dcc.getCV(82)*MasterTimeConstant)); // Wait1 + ss3[0]=0; ss3[1]=1; + } + if ((ss3[1]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(84)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(83),ttemp&0x3f,ttemp>>7); // execute switch function 1 + ss3delay=millis()+(long(Dcc.getCV(85)*MasterTimeConstant)); // Wait2 + ss3[1]=0; ss3[2]=1; + } + if ((ss3[2]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(87)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(86),ttemp&0x3f,ttemp>>7); // execute switch function 2 + ss3delay=millis()+(long(Dcc.getCV(88)*MasterTimeConstant)); // Wait3 + ss3[2]=0; ss3[3]=1; + } + if ((ss3[3]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(90)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(89),ttemp&0x3f,ttemp>>7); // execute switch function 3 + ss3delay=millis()+(long(Dcc.getCV(91)*MasterTimeConstant)); // Wait4 + ss3[3]=0; ss3[4]=1; + } + if ((ss3[4]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(93)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(92),ttemp&0x3f,ttemp>>7); // execute switch function 4 + ss3delay=millis()+(long(Dcc.getCV(94)*MasterTimeConstant)); // Wait5 + ss3[4]=0; ss3[5]=1; + } + if ((ss3[5]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(96)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(95),ttemp&0x3f,ttemp>>7); // execute switch function 5 + ss3[5]=0; run_switch_set[3]=false; + } +// ========================== switch Set 4 Start Run + if (ss4[0]==1) { + ss4delay=millis()+(long(Dcc.getCV(98)*MasterTimeConstant)); // Wait1 + ss4[0]=0; ss4[1]=1; + } + if ((ss4[1]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(100)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(99),ttemp&0x3f,ttemp>>7); // execute switch function 1 + ss4delay=millis()+(long(Dcc.getCV(101)*MasterTimeConstant)); // Wait2 + ss4[1]=0; ss4[2]=1; + } + if ((ss4[2]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(103)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(102),ttemp&0x3f,ttemp>>7); // execute switch function 2 + ss4delay=millis()+(long(Dcc.getCV(104)*MasterTimeConstant)); // Wait3 + ss4[2]=0; ss4[3]=1; + } + if ((ss4[3]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(106)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(105),ttemp&0x3f,ttemp>>7); // execute switch function 3 + ss4delay=millis()+(long(Dcc.getCV(107)*MasterTimeConstant)); // Wait4 + ss4[3]=0; ss4[4]=1; + } + if ((ss4[4]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(109)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(108),ttemp&0x3f,ttemp>>7); // execute switch function 4 + ss4delay=millis()+(long(Dcc.getCV(110)*MasterTimeConstant)); // Wait5 + ss4[4]=0; ss4[5]=1; + } + if ((ss4[5]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(112)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(111),ttemp&0x3f,ttemp>>7); // execute switch function 5 + ss4[5]=0; run_switch_set[4]=false; + } +// ========================== switch Set 5 Start Run + if (ss5[0]==1) { + ss5delay=millis()+(long(Dcc.getCV(114)*MasterTimeConstant)); // Wait1 + ss5[0]=0; ss5[1]=1; + } + if ((ss5[1]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(116)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(115),ttemp&0x3f,ttemp>>7); // execute switch function 1 + ss5delay=millis()+(long(Dcc.getCV(117)*MasterTimeConstant)); // Wait2 + ss5[1]=0; ss5[2]=1; + } + if ((ss5[2]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(119)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(118),ttemp&0x3f,ttemp>>7); // execute switch function 2 + ss5delay=millis()+(long(Dcc.getCV(120)*MasterTimeConstant)); // Wait3 + ss5[2]=0; ss5[3]=1; + } + if ((ss5[3]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(122)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(121),ttemp&0x3f,ttemp>>7); // execute switch function 3 + ss5delay=millis()+(long(Dcc.getCV(123)*MasterTimeConstant)); // Wait4 + ss5[3]=0; ss5[4]=1; + } + if ((ss5[4]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(125)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(124),ttemp&0x3f,ttemp>>7); // execute switch function 4 + ss5delay=millis()+(long(Dcc.getCV(126)*MasterTimeConstant)); // Wait5 + ss5[4]=0; ss5[5]=1; + } + if ((ss5[5]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(128)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(127),ttemp&0x3f,ttemp>>7); // execute switch function 5 + ss5[5]=0; run_switch_set[5]=false; + } + +// ========================== switch Set 6 Start Run + if (ss6[0]==1) { + ss6delay=millis()+(long(Dcc.getCV(130)*MasterTimeConstant)); // Wait1 + ss6[0]=0; ss6[1]=1; + } + if ((ss6[1]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(132)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(131),ttemp&0x3f,ttemp>>7); // execute switch function 1 + ss6delay=millis()+(long(Dcc.getCV(133)*MasterTimeConstant)); // Wait2 + ss6[1]=0; ss6[2]=1; + } + if ((ss6[2]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(135)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(134),ttemp&0x3f,ttemp>>7); // execute switch function 2 + ss6delay=millis()+(long(Dcc.getCV(136)*MasterTimeConstant)); // Wait3 + ss6[2]=0; ss6[3]=1; + } + if ((ss6[3]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(138)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(137),ttemp&0x3f,ttemp>>7); // execute switch function 3 + ss6delay=millis()+(long(Dcc.getCV(139)*MasterTimeConstant)); // Wait4 + ss6[3]=0; ss6[4]=1; + } + if ((ss6[4]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(141)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(140),ttemp&0x3f,ttemp>>7); // execute switch function 4 + ss6delay=millis()+(long(Dcc.getCV(142)*MasterTimeConstant)); // Wait5 + ss6[4]=0; ss6[5]=1; + } + if ((ss6[5]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(144)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(143),ttemp&0x3f,ttemp>>7); // execute switch function 5 + ss6[5]=0; run_switch_set[6]=false; + } + +// ========================== switch Set 7 Start Run + if (ss7[0]==1) { + ss7delay=millis()+(long(Dcc.getCV(146)*MasterTimeConstant)); // Wait1 + ss7[0]=0; ss7[1]=1; + } + if ((ss7[1]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(148)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(147),ttemp&0x3f,ttemp>>7); // execute switch function 1 + ss7delay=millis()+(long(Dcc.getCV(149)*MasterTimeConstant)); // Wait2 + ss7[1]=0; ss7[2]=1; + } + if ((ss7[2]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(151)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(150),ttemp&0x3f,ttemp>>7); // execute switch function 2 + ss7delay=millis()+(long(Dcc.getCV(152)*MasterTimeConstant)); // Wait3 + ss7[2]=0; ss7[3]=1; + } + if ((ss7[3]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(154)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(153),ttemp&0x3f,ttemp>>7); // execute switch function 3 + ss7delay=millis()+(long(Dcc.getCV(155)*MasterTimeConstant)); // Wait4 + ss7[3]=0; ss7[4]=1; + } + if ((ss7[4]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(157)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(156),ttemp&0x3f,ttemp>>7); // execute switch function 4 + ss7delay=millis()+(long(Dcc.getCV(158)*MasterTimeConstant)); // Wait5 + ss7[4]=0; ss7[5]=1; + } + if ((ss7[5]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(160)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(159),ttemp&0x3f,ttemp>>7); // execute switch function 5 + ss7[5]=0; run_switch_set[7]=false; + } +// ========================== switch Set 8 Start Run + if (ss8[0]==1) { + ss8delay=millis()+(long(Dcc.getCV(162)*MasterTimeConstant)); // Wait1 + ss8[0]=0; ss8[1]=1; + } + if ((ss8[1]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(164)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(163),ttemp&0x3f,ttemp>>7); // execute switch function 1 + ss8delay=millis()+(long(Dcc.getCV(165)*MasterTimeConstant)); // Wait2 + ss8[1]=0; ss8[2]=1; + } + if ((ss8[2]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(167)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(166),ttemp&0x3f,ttemp>>7); // execute switch function 2 + ss8delay=millis()+(long(Dcc.getCV(168)*MasterTimeConstant)); // Wait3 + ss8[2]=0; ss8[3]=1; + } + if ((ss8[3]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(170)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(169),ttemp&0x3f,ttemp>>7); // execute switch function 3 + ss8delay=millis()+(long(Dcc.getCV(171)*MasterTimeConstant)); // Wait4 + ss8[3]=0; ss8[4]=1; + } + if ((ss8[4]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(173)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(172),ttemp&0x3f,ttemp>>7); // execute switch function 4 + ss8delay=millis()+(long(Dcc.getCV(174)*MasterTimeConstant)); // Wait5 + ss8[4]=0; ss8[5]=1; + } + if ((ss8[5]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(176)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(175),ttemp&0x3f,ttemp>>7); // execute switch function 5 + ss8[5]=0; run_switch_set[8]=false; + } +// ========================== switch Set 9 Start Run + if (ss9[0]==1) { + ss9delay=millis()+(long(Dcc.getCV(178)*MasterTimeConstant)); // Wait1 + ss9[0]=0; ss9[1]=1; + } + if ((ss9[1]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(180)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(179),ttemp&0x3f,ttemp>>7); // execute switch function 1 + ss9delay=millis()+(long(Dcc.getCV(181)*MasterTimeConstant)); // Wait2 + ss9[1]=0; ss9[2]=1; + } + if ((ss9[2]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(183)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(182),ttemp&0x3f,ttemp>>7); // execute switch function 2 + ss9delay=millis()+(long(Dcc.getCV(184)*MasterTimeConstant)); // Wait3 + ss9[2]=0; ss9[3]=1; + } + if ((ss9[3]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(186)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(185),ttemp&0x3f,ttemp>>7); // execute switch function 3 + ss9delay=millis()+(long(Dcc.getCV(187)*MasterTimeConstant)); // Wait4 + ss9[3]=0; ss9[4]=1; + } + if ((ss9[4]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(189)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(188),ttemp&0x3f,ttemp>>7); // execute switch function 4 + ss9delay=millis()+(long(Dcc.getCV(190)*MasterTimeConstant)); // Wait5 + ss9[4]=0; ss9[5]=1; + } + if ((ss9[5]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(192)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(191),ttemp&0x3f,ttemp>>7); // execute switch function 5 + ss9[5]=0; run_switch_set[9]=false; + } +// ========================== switch Set 10 Start Run + if (ss10[0]==1) { + ss10delay=millis()+(long(Dcc.getCV(194)*MasterTimeConstant)); // Wait1 + ss10[0]=0; ss10[1]=1; + } + if ((ss10[1]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(196)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(195),ttemp&0x3f,ttemp>>7); // execute switch function 1 + ss10delay=millis()+(long(Dcc.getCV(197)*MasterTimeConstant)); // Wait2 + ss10[1]=0; ss10[2]=1; + } + if ((ss10[2]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(199)); + //setVolumeOnChannel (Dcc.getCV(198)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(198),ttemp&0x3f,ttemp>>7); // execute switch function 2 + ss10delay=millis()+(long(Dcc.getCV(200)*MasterTimeConstant)); // Wait3 + ss10[2]=0; ss10[3]=1; + } + if ((ss10[3]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(202)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(201),ttemp&0x3f,ttemp>>7); // execute switch function 3 + ss10delay=millis()+(long(Dcc.getCV(203)*MasterTimeConstant)); // Wait4 + ss10[3]=0; ss10[4]=1; + } + if ((ss10[4]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(205)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(204),ttemp&0x3f,ttemp>>7); // execute switch function 4 + ss10delay=millis()+(long(Dcc.getCV(206)*MasterTimeConstant)); // Wait5 + ss10[4]=0; ss10[5]=1; + } + if ((ss10[5]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(208)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(207),ttemp&0x3f,ttemp>>7); // execute switch function 5 + ss10[5]=0; run_switch_set[10]=false; + } +} // end loop() + +void exec_switch_function (byte switch_function, byte fpin,byte fbit) { + if (MasterDecoderDisable == 1) return; + + // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next + switch ( switch_function ) { // find the switch function to execute + case 0: // 0 == No function + default: + break; + case 1: // + digitalWrite ( fpin,fbit ); // Simple pin switch on/off + break; + case 2: // + if (fbit!=0) digitalWrite ( fpin, random ( 0,2) ); // Random pin switch on/off + else digitalWrite ( fpin, 0 ); // Force the bit OFF + break; + case 3: // + if (fbit!=0) digitalWrite ( fpin, Weighted_ON() ); // Weighted Random pin switch on/off + else digitalWrite ( fpin, 0 ); // Force the bit OFF + break; + case 4: // +#ifdef SOUND_PLAYER15 + setVolumeOnChannel (default_volume * fbit); // set volume level + playTrackOnChannel(fpin); // play sound track fpin 1-127 +#endif + break; + case 5: // +#ifdef USE_SERVO14 + servo[0].write(fpin|(fbit<<7)); // Position Servo +#endif + break; + case 6: // + digitalWrite ( fpin,fbit ); // Dual pin on/off alternate blink + digitalWrite ( fpin+1,(~fbit)&0x01 ); // Dual pin on/off alternate blink + break; + case 7: // Start up another switch set + { + switch ( fpin ) { // Start another Switching set based on the fpin argument + case 0: // + default: + break; + case 1: // Start Switch Set 1 + ss1[0] = 1; run_switch_set[fpin]=true; + break; + case 2: // Start Switch Set 2 + ss2[0] = 1; run_switch_set[fpin]=true; + break; + case 3: // Start Switch Set 3 + ss3[0] = 1; run_switch_set[fpin]=true; + break; + case 4: // Start Switch Set 4 + ss4[0] = 1; run_switch_set[fpin]=true; + break; + case 5: // Start Switch Set 5 + ss5[0] = 1; run_switch_set[fpin]=true; + break; + case 6: // Start Switch Set 6 + ss6[0] = 1; run_switch_set[fpin]=true; + break; + case 7: // Start Switch Set 7 + ss7[0] = 1; run_switch_set[fpin]=true; + break; + case 8: // Start Switch Set 8 + ss8[0] = 1; run_switch_set[fpin]=true; + break; + case 9: // Start Switch Set 9 + ss9[0] = 1; run_switch_set[fpin]=true; + break; + case 10: // Start Switch Set 10 + ss10[0] = 1; run_switch_set[fpin]=true; + break; + } + } + break; + case 8: // Start Switching set if not already started + { + switch ( fpin ) { // Start another Switching set based on the fpin argument + case 0: // + default: + break; + case 1: // Start Switch Set 1 + if( run_switch_set[fpin]==false) {ss1[0] = 1; run_switch_set[fpin]=true;} + break; + case 2: // Start Switch Set 2 + if( run_switch_set[fpin]==false) {ss2[0] = 1; run_switch_set[fpin]=true;} + break; + case 3: // Start Switch Set 3 + if( run_switch_set[fpin]==false) {ss3[0] = 1; run_switch_set[fpin]=true;} + break; + case 4: // Start Switch Set 4 + if( run_switch_set[fpin]==false) {ss4[0] = 1; run_switch_set[fpin]=true;} + break; + case 5: // Start Switch Set 5 + if( run_switch_set[fpin]==false) {ss5[0] = 1; run_switch_set[fpin]=true;} + break; + case 6: // Start Switch Set 6 + if( run_switch_set[fpin]==false) {ss6[0] = 1; run_switch_set[fpin]=true;} + break; + case 7: // Start Switch Set 7 + if( run_switch_set[fpin]==false) {ss7[0] = 1; run_switch_set[fpin]=true;} + break; + case 8: // Start Switch Set 8 + if( run_switch_set[fpin]==false) {ss8[0] = 1; run_switch_set[fpin]=true;} + break; + case 9: // Start Switch Set 9 + if( run_switch_set[fpin]==false) {ss9[0] = 1; run_switch_set[fpin]=true;} + break; + case 10: // Start Switch Set 10 + if( run_switch_set[fpin]==false) {ss10[0] = 1; run_switch_set[fpin]=true;} + break; + } + } + break; + case 9: // TBD + + break; + case 10: // TBD + + break; + case 11: // TBD + + break; + case 12: // TBD + + break; + case 13: // TBD + + break; + case 14: // TBD + + break; + case 15: // TBD + + break; + case 16: // TBD + + break; + case 17: // TBD + + break; + case 18: // TBD + + break; + case 19: // TBD + + break; + case 20: // TBD + + break; + } +} // end exec_switch_function() + +boolean Weighted_ON() { + if (random (0, 100 ) > 40) return true; //This will reyrn ON/true 60% of the time + return false; +} // end Weighted_ON() + +void playTrackOnChannel ( byte dtrack) { +#ifdef SOUND_PLAYER15 + if (dtrack == 0) return; + if (dtrack!=127) {Player1.play(dtrack); delay(audiocmddelay); } + else {Player1.play(random(First_Track,Last_Track+1)); delay(audiocmddelay); } +#endif +} // end playTrackOnChannel() + +void setVolumeOnChannel ( byte dvolume) { +#ifdef SOUND_PLAYER15 + if(dvolume>30) return; // Don't change the volume if out of range + Player1.volume (dvolume); + delay(audiocmddelay); +#endif +} // end setVolumeOnChannel() + +void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { +#ifdef DEBUG + Serial.print("Addr= "); + Serial.println(Addr, DEC) ; + Serial.print("FuncState= "); + Serial.println(FuncState, DEC) ; +#endif + switch(FuncGrp) + { + case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1 + exec_function( 0, FunctionPin0, (FuncState & FN_BIT_00)>>4 ); + exec_function( 1, FunctionPin1, (FuncState & FN_BIT_01)); + exec_function( 2, FunctionPin2, (FuncState & FN_BIT_02)>>1); + exec_function( 3, FunctionPin3, (FuncState & FN_BIT_03)>>2 ); + exec_function( 4, FunctionPin4, (FuncState & FN_BIT_04)>>3 ); + break; + case FN_5_8: //Function Group 1 S FFFF == 1 F8 F7 F6 F5 & == 0 F12 F11 F10 F9 F8 + exec_function( 5, FunctionPin5, (FuncState & FN_BIT_05)); + exec_function( 6, FunctionPin6, (FuncState & FN_BIT_06)>>1 ); + exec_function( 7, FunctionPin7, (FuncState & FN_BIT_07)>>2 ); + exec_function( 8, FunctionPin8, (FuncState & FN_BIT_08)>>3 ); + break; + + case FN_9_12: + exec_function( 9, FunctionPin9, (FuncState & FN_BIT_09)); + exec_function( 10, FunctionPin10, (FuncState & FN_BIT_10)>>1 ); + exec_function( 11, FunctionPin11, (FuncState & FN_BIT_11)>>2 ); + exec_function( 12, FunctionPin12, (FuncState & FN_BIT_12)>>3 ); + break; + case FN_13_20: //Function Group 2 FuncState == F20-F13 Function Control + exec_function( 13, FunctionPin13, (FuncState & FN_BIT_13)); + exec_function( 14, FunctionPin14, (FuncState & FN_BIT_14)>>1 ); + //exec_function( 15, FunctionPin15, (FuncState & FN_BIT_15)>>2 ); + //exec_function( 16, FunctionPin16, (FuncState & FN_BIT_16)>>3 ); + break; + + case FN_21_28: + break; + } +} // end notifyDccFunc +void exec_function (int function, int pin, int FuncState) { +#ifdef DEBUG + //Serial.print("ex function= "); + //Serial.println(function, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch ( Dcc.getCV( 30+function) ) { // Config + case 0: // Master Disable + Function0_value = byte(FuncState); + break; + case 1: // run switch set [ function ] + case 2: // run switch set [ function ] + case 3: // run switch set [ function ] + case 4: // run switch set [ function ] + case 5: // run switch set [ function ] + case 6: // run switch set [ function ] + case 7: // run switch set [ function ] + case 8: // run switch set [ function ] + case 9: // run switch set [ function ] + case 10: // run switch set [ function ] + function_value[function] = byte(FuncState); + break; + default: + break;; + } +} // end exec_function + +/* DFPlayer Commands +//----Set volume---- + myDFPlayer.volume(10); //Set volume value (0~30). + myDFPlayer.volumeUp(); //Volume Up + myDFPlayer.volumeDown(); //Volume Down + //----Set different EQ---- + myDFPlayer.EQ(DFPLAYER_EQ_NORMAL); +// myDFPlayer.EQ(DFPLAYER_EQ_POP); +// myDFPlayer.EQ(DFPLAYER_EQ_ROCK); +// myDFPlayer.EQ(DFPLAYER_EQ_JAZZ); +// myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC); +// myDFPlayer.EQ(DFPLAYER_EQ_BASS); + //----Set device we use SD as default---- +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_U_DISK); + myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_AUX); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_SLEEP); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_FLASH); + //----Mp3 control---- +// myDFPlayer.sleep(); //sleep +// myDFPlayer.reset(); //Reset the module +// myDFPlayer.enableDAC(); //Enable On-chip DAC +// myDFPlayer.disableDAC(); //Disable On-chip DAC +// myDFPlayer.outputSetting(true, 15); //output setting, enable the output and set the gain to 15 + //----Mp3 play---- + myDFPlayer.next(); //Play next mp3 + myDFPlayer.previous(); //Play previous mp3 + myDFPlayer.play(1); //Play the first mp3 + myDFPlayer.loop(1); //Loop the first mp3 + myDFPlayer.pause(); //pause the mp3 + myDFPlayer.start(); //start the mp3 from the pause + myDFPlayer.playFolder(15, 4); //play specific mp3 in SD:/15/004.mp3; Folder Name(1~99); File Name(1~255) + myDFPlayer.enableLoopAll(); //loop all mp3 files. + myDFPlayer.disableLoopAll(); //stop loop all mp3 files. + myDFPlayer.playMp3Folder(4); //play specific mp3 in SD:/MP3/0004.mp3; File Name(0~65535) + myDFPlayer.advertise(3); //advertise specific mp3 in SD:/ADVERT/0003.mp3; File Name(0~65535) + myDFPlayer.stopAdvertise(); //stop advertise + myDFPlayer.playLargeFolder(2, 999); //play specific mp3 in SD:/02/004.mp3; Folder Name(1~10); File Name(1~1000) + myDFPlayer.loopFolder(5); //loop all mp3 files in folder SD:/05. + myDFPlayer.randomAll(); //Random play all the mp3. + myDFPlayer.enableLoop(); //enable loop. + myDFPlayer.disableLoop(); //disable loop. +*/ diff --git a/examples/IDEC/IDEC2_5_LargeFunctionSets/IDEC2_5_LargeFunctionSets.ino b/examples/IDEC/IDEC2_5_LargeFunctionSets/IDEC2_5_LargeFunctionSets.ino new file mode 100644 index 0000000..286f798 --- /dev/null +++ b/examples/IDEC/IDEC2_5_LargeFunctionSets/IDEC2_5_LargeFunctionSets.ino @@ -0,0 +1,1071 @@ +// Interactive Decoder Random Switches IDEC2_5_LargeFunctionSetsDev.ino +// Version 1.08 Geoff Bunza 2020 +// Works with both short and long DCC Addesses +// This decoder will control Switch Sequences, servos, sounds and LEDs +// F0=Master Function OFF = Function ON DISABLES the decoder +/* F0 is configured as Master Decoder Disable Override ON==Disable Decoder + * Input Pin for Decoder Disable Pin 16/A2 Active LOW +// F1-F2 Eight Switch Sets 1-2 controlled by Input pins 3,4 respectively + * All Switch Sets are defined by groups of 80 CVs + - Either a DCC Function 1-2 on OR an Input Pin (3,4,) Switched Low enables a decoder function (ON) + - BOTH the respective DCC Decoder Function 1-2 must be Off AND its respective Input Pin (3,4) + MUST be High for a decoder function to be considered disabled + - A decoder function LEFT ENABLED will repreat the respecpective action as long as it is enabled + * Switch Set CV's are 25 groups of 3 CVs each: + CV1 - A delay (0-255) which will be multiplied by the + MasterTimeConstant setting time increments from milliseconds to minutes + 0 = No Delay + CV2 - A Mode or Command byte Describing what will be executed in this Switch Step, including: + 0 = No Operation / Null /Skip + 1 = Simple pin switch on/off + 2= Random pin switch on/off + 3 = Weighted Random pin switch on/off default is 60% ON time but can be set to anything 1-99% + 4 = Play sound track using fpin value for the track 1-126, 0 = Skip Play, 127 = Select Random Track + from First_Track to Last_Track inclusive; + MSB=0->No Volume Change MSB=1 -> Set Volume to default_volume + 5 = Position Servo to 0-180 full speed of travel + 6 = Dual pin on/off used for alternate blink fpin and fpin+1 (MSB set value for fpin state) + 7 = Start another Switching set based on the fpin argument (Used to chain Switch Sets) + 8 = Start another Switching set based on the fpin argument ONLY if NOT already started + CV3 - An argument representing the Pin number affected in the lower 7 bits and the High bit (0x80 or 128) a value + or a general parameter like a servo position, a Sound track, or a sound set number to jump to + * Switch sets include CVs: 50-129 and 130=209 + * MAX one of 3 Configurations per pin function: + * Config 0=DISABLE On/Off,1-2=Switch Control 1-2 + +PRO MINI PIN ASSIGNMENT: +2 - DCC Input +3 - Input Pin Switch 1 +4 - Input Pin Switch 2 +5 - Switch 9 +6 - Switch 10 +7 - Switch 11 +8 - Switch 12 +9 - Switch 13 +10 - Switch 14 +11 - Switch 1 +12 - Switch 2 +13 - Switch 3 +14 A0 - Switch 4 or default_servo_pin +15 A1 - Switch 5 or default sound player pin (TX) connected to DFPlayer1 (RX) Pin 2 via 1K Ohm 1/4W Resistor +16 A2 - Input Pin for MasterDecoderDisable Active LOW +17 A3 - Switch 6 +18 A4 - Switch 7 +19 A5 - Switch 8 +*/ +// ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP +// ******** AFTER THE INITIAL DECODER LOAD REMOVE THE "//" IN THE FOOLOWING LINE!! +//#define DECODER_LOADED + +// ******** REMOVE THE "//" IN THE FOLOWING LINE TO enable sound DFPlayer on Pin 15 +//#define SOUND_PLAYER15 + +// ******** REMOVE THE "//" IN THE FOLOWING LINE TO enable SERVO USE +//#define USE_SERVO14 + +// ******** REMOVE THE "//" IN THE FOLOWING LINE TO SEND DEBUGGING +// ******** INFO TO THE SERIAL MONITOR *****NOTE Turning DEBUG ON changes ALL Timing!! +//#define DEBUG + + +#include + +#ifdef USE_SERVO14 +#include +SoftwareServo servo[2]; +#endif +#define default_servo_pin 14 + +#ifdef SOUND_PLAYER15 +#include +#include +SoftwareSerial DFSerial1(22,15); // PRO MINI RX, PRO MINI TX serial to DFPlayer +DFRobotDFPlayerMini Player1; +#endif +#define default_volume 25 // sets default volume 0-30, 0 == OFF, >30 == Skip Track +#define First_Track 1 // Play Random Tracks First_Track#=Start_Track >=1 +#define Last_Track 12 // Play Random Tracks Last_Track= Last Playable Track in Range <= Last Numbered Track +const int audiocmddelay = 34; + +#define This_Decoder_Address 24 +uint8_t CV_DECODER_MASTER_RESET = 252; + +//Uncomment ONLY ONE of the following: +//#define MasterTimeConstant 10L // 10's of milliseconds Timing +#define MasterTimeConstant 100L // Tenths of a second Timing +//#define MasterTimeConstant 1000L // Seconds Timing +//#define MasterTimeConstant 10000L // 10's of Seconds Timing +//#define MasterTimeConstant 60000L // Minutes Timing +//#define MasterTimeConstant 3600000L // Hours Timing + +int del_tim = 4000; +uint16_t ttemp, i; + +byte ss1[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +unsigned long ss1delay=0; +byte ss2[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +unsigned long ss2delay=0; +bool run_switch_set [ ] = {false,false,false}; +byte switchset_channel[ ]={0,0,0}; +const int MasterDecoderDisablePin = 16; // D16/A0 Master Decoder Disable Input Pin Active LOW + +const int numINpins = 3; // Number of INput pins to initialize +byte inputpins [] = {3,4,16}; //These are all the Input Pins +const int numfpins = 14; // Number of Output pins to initialize +const int num_active_functions = 3; // Number of Functions stating with F0 +byte fpins [] = {5,6,7,8,9,10,11,12,13,14,15,17,18,19}; //These are all the Output Pins (first 15 is placeholder) +const int FunctionPin0 = 20; // D14/A0 DFPlayer Transmit (TX) Pin 3 +const int FunctionPin1 = 20; // A2 LED Place holders ONLY +const int FunctionPin2 = 20; // A3 LED Place holders ONLY +const int FunctionPin3 = 20; // A4 LED Place holders ONLY +const int FunctionPin4 = 20; // A5 LED Place holders ONLY +const int FunctionPin5 = 20; // A6 LED Place holders ONLY +const int FunctionPin6 = 20; // A7 Place holders ONLY +const int FunctionPin7 = 20; // A8 Place holders ONLY +const int FunctionPin8 = 20; // A9 Place holders ONLY +#define switch1 11 +#define switch2 12 +#define switch3 13 +#define switch4 14 +#define switch5 15 +#define switch6 17 +#define switch7 18 +#define switch8 19 +#define switch9 5 +#define switch10 6 +#define switch11 7 +#define switch12 8 +#define switch13 9 +#define switch14 10 +#define on 0x80 +#define off 0 +const int FunctionPin9 = 20; // Place holders ONLY +const int FunctionPin10 = 20; // Place holders ONLY +const int FunctionPin11 = 20; // F13 LED +const int FunctionPin12 = 20; // F12 LED +const int FunctionPin13 = 20; // F13 LED +const int FunctionPin14 = 20; // F14 LED +const int FunctionPin15 = 20; // Place holders ONLY +int MasterDecoderDisable = 0; +int Function0_value = 0; +byte function_value [ ] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +uint8_t cv_value; + +NmraDcc Dcc ; +DCC_MSG Packet ; +int t; // temp +struct QUEUE +{ + int inuse; + int current_position; + int increment; + int stop_value; + int start_value; +}; +QUEUE *ftn_queue = new QUEUE[17]; + +struct CVPair +{ + uint16_t CV; + uint8_t Value; +}; +CVPair FactoryDefaultCVs [] = +{ + {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address&0x7F }, + + // These two CVs define the Long DCC Address + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, ((This_Decoder_Address>>8)&0x7F)+192 }, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address&0xFF }, + + // ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS +// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps + {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps +// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps + {CV_DECODER_MASTER_RESET, 0}, + + {30, 0}, //F0 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + + {31, 1}, //F1 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {32, 2}, //F2 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {33, 3}, //F3 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {34, 4}, //F4 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {35, 5}, //F5 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {36, 6}, //F6 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {37, 7}, //F7 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {38, 8}, //F8 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {39, 9}, //F9 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {40, 10}, //F10 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + + {41, 11}, + {42, 11}, + {43, 11}, + {44, 11}, + {45, 22}, //F15 not used + + {50, 3}, // Wait1 0-254 0.1 Seconds // switch SET 1-1 + {51, 1}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {52, switch3+on}, // Switch Pin1 + {53, 3}, // Wait2 0-254 0.1 Seconds + {54, 1}, // Switch Mode + {55, switch3+off}, // Switch Pin2 + {56, 3}, // Wait3 0-254 0.1 Seconds + {57, 1}, // Switch Mode + {58, switch3+on}, // Switch Pin3 + {59, 3}, // Wait4 0-254 0.1 Seconds + {60, 1}, // Switch Mode + {61, switch3+off}, // Switch Pin4 + {62, 3}, // Wait5 0-254 0.1 Seconds + {63, 1}, // Switch Mode + {64, switch3+on}, // Switch Pin5 + {65, 0}, // Not Used + + {66, 3}, // Wait1 0-254 0.1 Seconds // switch SET 1-2 + {67, 1}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {68, switch3+off}, // Switch Pin1 + {69, 3}, // Wait2 0-254 0.1 Seconds + {70, 1}, // Switch Mode + {71, switch3+on}, // Switch Pin2 + {72, 3}, // Wait3 0-254 0.1 Seconds + {73, 1}, // Switch Mode + {74, switch3+off}, // Switch Pin3 + {75, 3}, // Wait4 0-254 0.1 Seconds + {76, 1}, // Switch Mode + {77, switch3+on}, // Switch Pin4 + {78, 3}, // Wait5 0-254 0.1 Seconds + {79, 1}, // Switch Mode + {80, switch3+off}, // Switch Pin5 + {81, 0}, // Not Used + + {82, 3}, // Wait1 0-254 0.1 Seconds // switch SET 1-3 + {83, 1}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {84, switch3+on}, // Switch Pin1 + {85, 3}, // Wait2 0-254 0.1 Seconds + {86, 1}, // Switch Mode + {87, switch3+off}, // Switch Pin2 + {88, 3}, // Wait3 0-254 0.1 Seconds + {89, 1}, // Switch Mode + {90, switch3+on}, // Switch Pin3 + {91, 3}, // Wait4 0-254 0.1 Seconds + {92, 1}, // Switch Mode + {93, switch3+off}, // Switch Pin4 + {94, 3}, // Wait5 0-254 0.1 Seconds + {95, 1}, // Switch Mode + {96, switch3+on}, // Switch Pin5 + {97, 0}, // Not Used + + {98, 8}, // Wait1 0-254 0.1 Seconds // switch SET 1-4 + {99, 1}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {100, switch3+off}, // Switch Pin1 + {101, 8}, // Wait2 0-254 0.1 Seconds + {102, 1}, // Switch Mode + {103, switch3+on}, // Switch Pin2 + {104, 8}, // Wait3 0-254 0.1 Seconds + {105, 1}, // Switch Mode + {106, switch3+off}, // Switch Pin3 + {107, 8}, // Wait4 0-254 0.1 Seconds + {108, 1}, // Switch Mode + {109, switch3+on}, // Switch Pin4 + {110, 8}, // Wait5 0-254 0.1 Seconds + {111, 1}, // Switch Mode + {112, switch3+off}, // Switch Pin5 + {113, 0}, // Not Used + + {114, 8}, // Wait1 0-254 0.1 Seconds // switch SET 1-5 + {115, 1}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {116, switch3+on}, // Switch Pin1 + {117, 8}, // Wait2 0-254 0.1 Seconds + {118, 1}, // Switch Mode + {119, switch3+off}, // Switch Pin2 + {120, 8}, // Wait3 0-254 0.1 Seconds + {121, 1}, // Switch Mode + {122, switch3+on}, // Switch Pin3 + {123, 8}, // Wait4 0-254 0.1 Seconds + {124, 1}, // Switch Mode + {125, switch3+off}, // Switch Pin4 + {126, 8}, // Wait5 0-254 0.1 Seconds + {127, 0}, // Switch Mode + {128, 0}, // Switch Pin5 + {129, 0}, // Not Used + + {130, 5}, // Wait1 0-254 0.1 Seconds // switch SET 2-1 + {131, 6}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {132, switch3+on}, // Switch Pin1 + {133, 9}, // Wait2 0-254 0.1 Seconds + {134, 6}, // Switch Mode + {135, switch3+off}, // Switch Pin2 + {136, 9}, // Wait3 0-254 0.1 Seconds + {137, 6}, // Switch Mode + {138, switch3+on}, // Switch Pin3 + {139, 9}, // Wait4 0-254 0.1 Seconds + {140, 6}, // Switch Mode + {141, switch3+off}, // Switch Pin4 + {142, 5}, // Wait5 0-254 0.1 Seconds + {143, 1}, // Switch Mode + {144, switch3+on}, // Switch Pin5 + {145, 0}, // Not Used + + {146, 5}, // Wait1 0-254 0.1 Seconds // switch SET 2-2 + {147, 1}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {148, switch2+on}, // Switch Pin1 + {149, 5}, // Wait2 0-254 0.1 Seconds + {150, 1}, // Switch Mode + {151, switch1+on}, // Switch Pin2 + {152, 9}, // Wait3 0-254 0.1 Seconds + {153, 1}, // Switch Mode + {154, switch1+off}, // Switch Pin3 + {155, 6}, // Wait4 0-254 0.1 Seconds + {156, 1}, // Switch Mode + {157, switch2+off}, // Switch Pin4 + {158, 6}, // Wait5 0-254 0.1 Seconds + {159, 1}, // Switch Mode + {160, switch3+off}, // Switch Pin5 + {161, 0}, // Not Used + + {162, 6}, // Wait1 0-254 0.1 Seconds // switch SET 2-3 + {163, 1}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {164, switch4+off}, // Switch Pin1 + {165, 8}, // Wait2 0-254 0.1 Seconds + {166, 6}, // Switch Mode + {167, switch1+on}, // Switch Pin2 + {168, 0}, // Wait3 0-254 0.1 Seconds + {169, 6}, // Switch Mode + {170, switch3+on}, // Switch Pin3 + {171, 8}, // Wait4 0-254 0.1 Seconds + {172, 6}, // Switch Mode + {173, switch1+off}, // Switch Pin4 + {174, 0}, // Wait5 0-254 0.1 Seconds + {175, 6}, // Switch Mode + {176, switch3+off}, // Switch Pin5 + {177, 0}, // Not Used + + {178, 8}, // Wait1 0-254 0.1 Seconds // switch SET 2-4 + {179, 6}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {180, switch1+on}, // Switch Pin1 + {181, 0}, // Wait2 0-254 0.1 Seconds + {182, 6}, // Switch Mode + {183, switch3+on}, // Switch Pin2 + {184, 8}, // Wait3 0-254 0.1 Seconds + {185, 6}, // Switch Mode + {186, switch1+off}, // Switch Pin3 + {187, 0}, // Wait4 0-254 0.1 Seconds + {188, 6}, // Switch Mode + {189, switch3+off}, // Switch Pin4 + {190, 8}, // Wait5 0-254 0.1 Seconds + {191, 6}, // Switch Mode + {192, switch1+on}, // Switch Pin5 + {193, 0}, // Not Used + + {194, 0}, // Wait1 0-254 0.1 Seconds // switch SET 2-5 + {195, 6}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {196, switch3+on}, // Switch Pin1 + {197, 9}, // Wait2 0-254 0.1 Seconds + {198, 1}, // Switch Mode + {199, switch1+off}, // Switch Pin2 + {200, 4}, // Wait3 0-254 0.1 Seconds + {201, 1}, // Switch Mode + {202, switch3+off}, // Switch Pin3 + {203, 10}, // Wait4 0-254 0.1 Seconds + {204, 1}, // Switch Mode + {205, switch3+on}, // Switch Pin4 + {206, 10}, // Wait5 0-254 0.1 Seconds + {207, 1}, // Switch Mode + {208, switch3+off}, // Switch Pin5 + {209, 0}, // Not Used + + //252,252 CV_DECODER_MASTER_RESET + + {253, 0}, // Extra +}; + +uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +void notifyCVResetFactoryDefault() +{ + // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset + // to flag to the loop() function that a reset to Factory Defaults needs to be done + FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +}; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS + +void setup() //****************************************************** +{ +#ifdef DEBUG + Serial.begin(115200); +#endif + +#ifdef SOUND_PLAYER15 + DFSerial1.begin (9600); + Player1.begin (DFSerial1); +#endif + +#ifdef USE_SERVO14 + servo[0].attach(default_servo_pin); // Start Servo on default_servo_pin //Position Servo + delay(50); + SoftwareServo::refresh(); +#endif + + pinMode (MasterDecoderDisablePin,INPUT_PULLUP); // Master Decoder Disable Input Pin Active LOW + + // initialize the digital pins as outputs + for (int i=0; i < numfpins; i++) { + pinMode(fpins[i], OUTPUT); + digitalWrite(fpins[i], 0); // All OUPUT pins initialized LOW + } + // initialize the digital pins as inputs + for (int i=0; i < numINpins; i++) { + pinMode(inputpins[i], INPUT_PULLUP); + } + // Setup which External Interrupt, the Pin it's associated with that we're using + Dcc.pin(0, 2, 0); + // Call the main DCC Init function to enable the DCC Receiver + Dcc.init( MAN_ID_DIY, 61, FLAGS_MY_ADDRESS_ONLY, 0 ); + delay(800); +#if defined(DECODER_LOADED) + if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET ) +#endif + { + for (int j=0; j < FactoryDefaultCVIndex; j++ ) + Dcc.setCV( FactoryDefaultCVs[j].CV, FactoryDefaultCVs[j].Value); + } + // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; +#ifdef DEBUG + Serial.println("CV Dump:"); + for (i=30; i<41; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=30; i<41; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Large Switch Set 1"); + for (i=50; i<66; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=50; i<66; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=66; i<82; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=66; i<82; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=82; i<98; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=82; i<98; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=98; i<114; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=98; i<114; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=114; i<130; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=114; i<130; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Large Switch Set 2"); + for (i=130; i<146; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=130; i<146; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=146; i<162; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=146; i<162; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=162; i<178; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=162; i<178; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=178; i<194; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=178; i<194; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=194; i<210; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=194; i<210; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); +#endif +} +void loop() //*********************************************************************************** +{ + //MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation + Dcc.process(); +#ifdef USE_SERVO14 + SoftwareServo::refresh(); +#endif + + //delay(1); +// INPUT OVER RIDES + // Check Master Input Over ride + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + else MasterDecoderDisable = Function0_value & 1; + if (MasterDecoderDisable == 1) { + for (i=0; i < numfpins; i++) digitalWrite(fpins[i], 0); // All LEDs set LOW + } +// ******************************************************************************** + if (MasterDecoderDisable == 0) { + for (i=0; i < num_active_functions; i++) { + cv_value = Dcc.getCV(30+i) ; +#ifdef DEBUG + //Serial.print(" cv_value: "); + //Serial.println(cv_value, DEC) ; +#endif + switch ( cv_value ) { + case 0: // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + break; + case 1: // + if (((digitalRead(3)==LOW)||(function_value[cv_value]==1)) && !run_switch_set[cv_value]) { + ss1[0]=1; run_switch_set[cv_value]=true; + } + break; + case 2: // + if (((digitalRead(4)==LOW)||(function_value[cv_value]==1)) && !run_switch_set[cv_value]) { + ss2[0]=1; run_switch_set[cv_value]=true; + } + break; + default: // Extra + break; + } + } + } + // ========================== Large switch Set 1 Start Run + if (ss1[0]==1) { + ss1delay=millis()+(long(Dcc.getCV(50)*MasterTimeConstant)); // Wait1 + ss1[0]=0; ss1[1]=1; + } + if ((ss1[1]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(52)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(51),ttemp&0x3f,ttemp>>7); // execute switch function 1 + ss1delay=millis()+(long(Dcc.getCV(53)*MasterTimeConstant)); // Wait2 + ss1[1]=0; ss1[2]=1; + } + if ((ss1[2]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(55)); + if (ttemp!=0) exec_switch_function (Dcc.getCV(54),ttemp&0x3f,ttemp>>7); // execute switch function 2 + ss1delay=millis()+(long(Dcc.getCV(56)*MasterTimeConstant)); // Wait3 + ss1[2]=0; ss1[3]=1; + } + if ((ss1[3]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(58)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(57),ttemp&0x3f,ttemp>>7); // execute switch function 3 + ss1delay=millis()+(long(Dcc.getCV(59)*MasterTimeConstant)); // Wait4 + ss1[3]=0; ss1[4]=1; + } + if ((ss1[4]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(61)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(60),ttemp&0x3f,ttemp>>7); // execute switch function 4 + ss1delay=millis()+(long(Dcc.getCV(62)*MasterTimeConstant)); // Wait5 + ss1[4]=0; ss1[5]=1; + } + if ((ss1[5]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(64)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(63),ttemp&0x3f,ttemp>>7); // execute switch function 5 + ss1[5]=0; ss1[6]=1; + } +// ========================== Large switch Set 1 continues + if (ss1[6]==1) { + ss1delay=millis()+(long(Dcc.getCV(66)*MasterTimeConstant)); // Wait1 + ss1[6]=0; ss1[7]=1; + } + if ((ss1[7]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(68)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(67),ttemp&0x3f&0x3f,ttemp>>7); // execute switch function 1 + ss1delay=millis()+(long(Dcc.getCV(69)*MasterTimeConstant)); // Wait2 + ss1[7]=0; ss1[8]=1; + } + if ((ss1[8]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(71)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(70),ttemp&0x3f,ttemp>>7); // execute switch function 2 + ss1delay=millis()+(long(Dcc.getCV(72)*MasterTimeConstant)); // Wait3 + ss1[8]=0; ss1[9]=1; + } + if ((ss1[9]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(74)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(73),ttemp&0x3f,ttemp>>7); // execute switch function 3 + ss1delay=millis()+(long(Dcc.getCV(75)*MasterTimeConstant)); // Wait4 + ss1[9]=0; ss1[10]=1; + } + if ((ss1[10]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(77)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(76),ttemp&0x3f,ttemp>>7); // execute switch function 4 + ss1delay=millis()+(long(Dcc.getCV(78)*MasterTimeConstant)); // Wait5 + ss1[10]=0; ss1[11]=1; + } + if ((ss1[11]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(80)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(79),ttemp&0x3f,ttemp>>7); // execute switch function 5 + ss1[11]=0; ss1[12]=1; + } +// ========================== Large switch Set 1 continues + if (ss1[12]==1) { + ss1delay=millis()+(long(Dcc.getCV(82)*MasterTimeConstant)); // Wait1 + ss1[12]=0; ss1[13]=1; + } + if ((ss1[13]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(84)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(83),ttemp&0x3f,ttemp>>7); // execute switch function 1 + ss1delay=millis()+(long(Dcc.getCV(85)*MasterTimeConstant)); // Wait2 + ss1[13]=0; ss1[14]=1; + } + if ((ss1[14]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(87)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(86),ttemp&0x3f,ttemp>>7); // execute switch function 2 + ss1delay=millis()+(long(Dcc.getCV(88)*MasterTimeConstant)); // Wait3 + ss1[14]=0; ss1[15]=1; + } + if ((ss1[15]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(90)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(89),ttemp&0x3f,ttemp>>7); // execute switch function 3 + ss1delay=millis()+(long(Dcc.getCV(91)*MasterTimeConstant)); // Wait4 + ss1[15]=0; ss1[16]=1; + } + if ((ss1[16]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(93)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(92),ttemp&0x3f,ttemp>>7); // execute switch function 4 + ss1delay=millis()+(long(Dcc.getCV(94)*MasterTimeConstant)); // Wait5 + ss1[16]=0; ss1[17]=1; + } + if ((ss1[17]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(96)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(95),ttemp&0x3f,ttemp>>7); // execute switch function 5 + ss1[17]=0; ss1[18]=1; + } +// ========================== Large switch Set 1 continues + if (ss1[18]==1) { + ss1delay=millis()+(long(Dcc.getCV(98)*MasterTimeConstant)); // Wait1 + ss1[18]=0; ss1[19]=1; + } + if ((ss1[19]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(100)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(99),ttemp&0x3f,ttemp>>7); // execute switch function 1 + ss1delay=millis()+(long(Dcc.getCV(101)*MasterTimeConstant)); // Wait2 + ss1[19]=0; ss1[20]=1; + } + if ((ss1[20]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(103)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(102),ttemp&0x3f,ttemp>>7); // execute switch function 2 + ss1delay=millis()+(long(Dcc.getCV(104)*MasterTimeConstant)); // Wait3 + ss1[20]=0; ss1[21]=1; + } + if ((ss1[21]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(106)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(105),ttemp&0x3f,ttemp>>7); // execute switch function 3 + ss1delay=millis()+(long(Dcc.getCV(107)*MasterTimeConstant)); // Wait4 + ss1[21]=0; ss1[22]=1; + } + if ((ss1[22]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(109)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(108),ttemp&0x3f,ttemp>>7); // execute switch function 4 + ss1delay=millis()+(long(Dcc.getCV(110)*MasterTimeConstant)); // Wait5 + ss1[22]=0; ss1[23]=1; + } + if ((ss1[23]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(112)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(111),ttemp&0x3f,ttemp>>7); // execute switch function 5 + ss1[23]=0; ss1[24]=1; + } +// ========================== Large switch Set 1 continues + if (ss1[24]==1) { + ss1delay=millis()+(long(Dcc.getCV(114)*MasterTimeConstant)); // Wait1 + ss1[24]=0; ss1[25]=1; + } + if ((ss1[25]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(116)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(115),ttemp&0x3f,ttemp>>7); // execute switch function 1 + ss1delay=millis()+(long(Dcc.getCV(117)*MasterTimeConstant)); // Wait2 + ss1[25]=0; ss1[26]=1; + } + if ((ss1[26]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(119)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(118),ttemp&0x3f,ttemp>>7); // execute switch function 2 + ss1delay=millis()+(long(Dcc.getCV(120)*MasterTimeConstant)); // Wait3 + ss1[26]=0; ss1[27]=1; + } + if ((ss1[27]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(122)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(121),ttemp&0x3f,ttemp>>7); // execute switch function 3 + ss1delay=millis()+(long(Dcc.getCV(123)*MasterTimeConstant)); // Wait4 + ss1[27]=0; ss1[28]=1; + } + if ((ss1[28]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(125)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(124),ttemp&0x3f,ttemp>>7); // execute switch function 4 + ss1delay=millis()+(long(Dcc.getCV(126)*MasterTimeConstant)); // Wait5 + ss1[28]=0; ss1[29]=1; + } + if ((ss1[29]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(128)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(127),ttemp&0x3f,ttemp>>7); // execute switch function 5 + ss1[29]=0; run_switch_set[1]=false; + } + +// ========================== Large switch Set 2 Start Run + if (ss2[0]==1) { + ss2delay=millis()+(long(Dcc.getCV(130)*MasterTimeConstant)); // Wait1 + ss2[0]=0; ss2[1]=1; + } + if ((ss2[1]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(132)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(131),ttemp&0x3f,ttemp>>7); // execute switch function 1 + ss2delay=millis()+(long(Dcc.getCV(133)*MasterTimeConstant)); // Wait2 + ss2[1]=0; ss2[2]=1; + } + if ((ss2[2]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(135)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(134),ttemp&0x3f,ttemp>>7); // execute switch function 2 + ss2delay=millis()+(long(Dcc.getCV(136)*MasterTimeConstant)); // Wait3 + ss2[2]=0; ss2[3]=1; + } + if ((ss2[3]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(138)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(137),ttemp&0x3f,ttemp>>7); // execute switch function 3 + ss2delay=millis()+(long(Dcc.getCV(139)*MasterTimeConstant)); // Wait4 + ss2[3]=0; ss2[4]=1; + } + if ((ss2[4]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(141)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(140),ttemp&0x3f,ttemp>>7); // execute switch function 4 + ss2delay=millis()+(long(Dcc.getCV(142)*MasterTimeConstant)); // Wait5 + ss2[4]=0; ss2[5]=1; + } + if ((ss2[5]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(144)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(143),ttemp&0x3f,ttemp>>7); // execute switch function 5 + ss2[5]=0; ss2[6]=1; + } + +// ========================== switch Set 7 Start Run + if (ss2[6]==1) { + ss2delay=millis()+(long(Dcc.getCV(146)*MasterTimeConstant)); // Wait1 + ss2[6]=0; ss2[7]=1; + } + if ((ss2[7]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(148)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(147),ttemp&0x3f,ttemp>>7); // execute switch function 1 + ss2delay=millis()+(long(Dcc.getCV(149)*MasterTimeConstant)); // Wait2 + ss2[7]=0; ss2[8]=1; + } + if ((ss2[8]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(151)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(150),ttemp&0x3f,ttemp>>7); // execute switch function 2 + ss2delay=millis()+(long(Dcc.getCV(152)*MasterTimeConstant)); // Wait3 + ss2[8]=0; ss2[9]=1; + } + if ((ss2[9]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(154)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(153),ttemp&0x3f,ttemp>>7); // execute switch function 3 + ss2delay=millis()+(long(Dcc.getCV(155)*MasterTimeConstant)); // Wait4 + ss2[9]=0; ss2[10]=1; + } + if ((ss2[10]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(157)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(156),ttemp&0x3f,ttemp>>7); // execute switch function 4 + ss2delay=millis()+(long(Dcc.getCV(158)*MasterTimeConstant)); // Wait5 + ss2[10]=0; ss2[11]=1; + } + if ((ss2[11]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(160)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(159),ttemp&0x3f,ttemp>>7); // execute switch function 5 + ss2[11]=0; ss2[12]=1; + } +// ========================== switch Set 8 Start Run + if (ss2[12]==1) { + ss2delay=millis()+(long(Dcc.getCV(162)*MasterTimeConstant)); // Wait1 + ss2[12]=0; ss2[13]=1; + } + if ((ss2[13]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(164)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(163),ttemp&0x3f,ttemp>>7); // execute switch function 1 + ss2delay=millis()+(long(Dcc.getCV(165)*MasterTimeConstant)); // Wait2 + ss2[13]=0; ss2[14]=1; + } + if ((ss2[14]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(167)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(166),ttemp&0x3f,ttemp>>7); // execute switch function 2 + ss2delay=millis()+(long(Dcc.getCV(168)*MasterTimeConstant)); // Wait3 + ss2[14]=0; ss2[15]=1; + } + if ((ss2[15]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(170)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(169),ttemp&0x3f,ttemp>>7); // execute switch function 3 + ss2delay=millis()+(long(Dcc.getCV(171)*MasterTimeConstant)); // Wait4 + ss2[15]=0; ss2[16]=1; + } + if ((ss2[16]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(173)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(172),ttemp&0x3f,ttemp>>7); // execute switch function 4 + ss2delay=millis()+(long(Dcc.getCV(174)*MasterTimeConstant)); // Wait5 + ss2[16]=0; ss2[17]=1; + } + if ((ss2[17]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(176)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(175),ttemp&0x3f,ttemp>>7); // execute switch function 5 + ss2[17]=0; ss2[18]=1; + } +// ========================== switch Set 9 Start Run + if (ss2[18]==1) { + ss2delay=millis()+(long(Dcc.getCV(178)*MasterTimeConstant)); // Wait1 + ss2[18]=0; ss2[19]=1; + } + if ((ss2[19]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(180)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(179),ttemp&0x3f,ttemp>>7); // execute switch function 1 + ss2delay=millis()+(long(Dcc.getCV(181)*MasterTimeConstant)); // Wait2 + ss2[19]=0; ss2[20]=1; + } + if ((ss2[20]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(183)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(182),ttemp&0x3f,ttemp>>7); // execute switch function 2 + ss2delay=millis()+(long(Dcc.getCV(184)*MasterTimeConstant)); // Wait3 + ss2[20]=0; ss2[21]=1; + } + if ((ss2[21]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(186)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(185),ttemp&0x3f,ttemp>>7); // execute switch function 3 + ss2delay=millis()+(long(Dcc.getCV(187)*MasterTimeConstant)); // Wait4 + ss2[21]=0; ss2[22]=1; + } + if ((ss2[22]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(189)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(188),ttemp&0x3f,ttemp>>7); // execute switch function 4 + ss2delay=millis()+(long(Dcc.getCV(190)*MasterTimeConstant)); // Wait5 + ss2[22]=0; ss2[23]=1; + } + if ((ss2[23]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(192)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(191),ttemp&0x3f,ttemp>>7); // execute switch function 5 + ss2[23]=0; ss2[24]=1; + } +// ========================== switch Set 10 Start Run + if (ss2[24]==1) { + ss2delay=millis()+(long(Dcc.getCV(194)*MasterTimeConstant)); // Wait1 + ss2[24]=0; ss2[25]=1; + } + if ((ss2[25]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(196)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(195),ttemp&0x3f,ttemp>>7); // execute switch function 1 + ss2delay=millis()+(long(Dcc.getCV(197)*MasterTimeConstant)); // Wait2 + ss2[25]=0; ss2[26]=1; + } + if ((ss2[26]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(199)); + //setVolumeOnChannel (Dcc.getCV(198)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(198),ttemp&0x3f,ttemp>>7); // execute switch function 2 + ss2delay=millis()+(long(Dcc.getCV(200)*MasterTimeConstant)); // Wait3 + ss2[26]=0; ss2[27]=1; + } + if ((ss2[27]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(202)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(201),ttemp&0x3f,ttemp>>7); // execute switch function 3 + ss2delay=millis()+(long(Dcc.getCV(203)*MasterTimeConstant)); // Wait4 + ss2[27]=0; ss2[28]=1; + } + if ((ss2[28]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(205)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(204),ttemp&0x3f,ttemp>>7); // execute switch function 4 + ss2delay=millis()+(long(Dcc.getCV(206)*MasterTimeConstant)); // Wait5 + ss2[28]=0; ss2[29]=1; + } + if ((ss2[29]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(208)); + if (ttemp!=0) exec_switch_function(Dcc.getCV(207),ttemp&0x3f,ttemp>>7); // execute switch function 5 + ss2[29]=0; run_switch_set[2]=false; + } +} // end loop() + +void exec_switch_function (byte switch_function, byte fpin,byte fbit) { + if (MasterDecoderDisable == 1) return; + + // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next + switch ( switch_function ) { // find the switch function to execute + case 0: // 0 == No function + default: + break; + case 1: // + digitalWrite ( fpin,fbit ); // Simple pin switch on/off + break; + case 2: // + if (fbit!=0) digitalWrite ( fpin, random ( 0,2) ); // Random pin switch on/off + else digitalWrite ( fpin, 0 ); // Force the bit OFF + break; + case 3: // + if (fbit!=0) digitalWrite ( fpin, Weighted_ON() ); // Weighted Random pin switch on/off + else digitalWrite ( fpin, 0 ); // Force the bit OFF + break; + case 4: // +#ifdef SOUND_PLAYER15 + setVolumeOnChannel (default_volume * fbit); // set volume level + playTrackOnChannel(fpin); // play sound track fpin 1-127 +#endif + break; + case 5: // +#ifdef USE_SERVO14 + servo[0].write(fpin|(fbit<<7)); // Position Servo +#endif + break; + case 6: // + digitalWrite ( fpin,fbit ); // Dual pin on/off alternate blink + digitalWrite ( fpin+1,(~fbit)&0x01 ); // Dual pin on/off alternate blink + break; + case 7: // Start up another switch set + { + switch ( fpin ) { // Start another Switching set based on the fpin argument + case 0: // + default: + break; + case 1: // Start Switch Set 1 + ss1[0] = 1; run_switch_set[fpin]=true; + break; + case 2: // Start Switch Set 2 + ss2[0] = 1; run_switch_set[fpin]=true; + break; + } + } + break; + case 8: // Start Switching set if not already started + { + switch ( fpin ) { // Start another Switching set based on the fpin argument + case 0: // + default: + break; + case 1: // Start Switch Set 1 + if( run_switch_set[fpin]==false) {ss1[0] = 1; run_switch_set[fpin]=true;} + break; + case 2: // Start Switch Set 2 + if( run_switch_set[fpin]==false) {ss2[0] = 1; run_switch_set[fpin]=true;} + break; + } + } + break; + } +} // end exec_switch_function() + +boolean Weighted_ON() { + if (random (0, 100 ) > 40) return true; //This will reyrn ON/true 60% of the time + return false; +} // end Weighted_ON() + +void playTrackOnChannel ( byte dtrack) { +#ifdef SOUND_PLAYER15 + if (dtrack == 0) return; + if (dtrack!=127) {Player1.play(dtrack); delay(audiocmddelay); } + else {Player1.play(random(First_Track,Last_Track+1)); delay(audiocmddelay); } +#endif +} // end playTrackOnChannel() + +void setVolumeOnChannel ( byte dvolume) { +#ifdef SOUND_PLAYER15 + if(dvolume>30) return; // Don't change the volume if out of range + Player1.volume (dvolume); + delay(audiocmddelay); +#endif +} // end setVolumeOnChannel() + +void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { +#ifdef DEBUG + //Serial.print("Addr= "); + //Serial.println(Addr, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch(FuncGrp) + { + case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1 + exec_function( 0, FunctionPin0, (FuncState & FN_BIT_00)>>4 ); + exec_function( 1, FunctionPin1, (FuncState & FN_BIT_01)); + exec_function( 2, FunctionPin2, (FuncState & FN_BIT_02)>>1); + exec_function( 3, FunctionPin3, (FuncState & FN_BIT_03)>>2 ); + exec_function( 4, FunctionPin4, (FuncState & FN_BIT_04)>>3 ); + break; + case FN_5_8: //Function Group 1 S FFFF == 1 F8 F7 F6 F5 & == 0 F12 F11 F10 F9 F8 + exec_function( 5, FunctionPin5, (FuncState & FN_BIT_05)); + exec_function( 6, FunctionPin6, (FuncState & FN_BIT_06)>>1 ); + exec_function( 7, FunctionPin7, (FuncState & FN_BIT_07)>>2 ); + exec_function( 8, FunctionPin8, (FuncState & FN_BIT_08)>>3 ); + break; + + case FN_9_12: + exec_function( 9, FunctionPin9, (FuncState & FN_BIT_09)); + exec_function( 10, FunctionPin10, (FuncState & FN_BIT_10)>>1 ); + exec_function( 11, FunctionPin11, (FuncState & FN_BIT_11)>>2 ); + exec_function( 12, FunctionPin12, (FuncState & FN_BIT_12)>>3 ); + break; + case FN_13_20: //Function Group 2 FuncState == F20-F13 Function Control + exec_function( 13, FunctionPin13, (FuncState & FN_BIT_13)); + exec_function( 14, FunctionPin14, (FuncState & FN_BIT_14)>>1 ); + //exec_function( 15, FunctionPin15, (FuncState & FN_BIT_15)>>2 ); + //exec_function( 16, FunctionPin16, (FuncState & FN_BIT_16)>>3 ); + break; + + case FN_21_28: + break; + } +} // end notifyDccFunc +void exec_function (int function, int pin, int FuncState) { +#ifdef DEBUG + //Serial.print("ex function= "); + //Serial.println(function, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch ( Dcc.getCV( 30+function) ) { // Config + case 0: // Master Disable + Function0_value = byte(FuncState); + break; + case 1: // run switch set [ function ] + case 2: // run switch set [ function ] + case 3: // run switch set [ function ] + case 4: // run switch set [ function ] + case 5: // run switch set [ function ] + case 6: // run switch set [ function ] + case 7: // run switch set [ function ] + case 8: // run switch set [ function ] + case 9: // run switch set [ function ] + case 10: // run switch set [ function ] + function_value[function] = byte(FuncState); + break; + default: + break;; + } +} // end exec_function + +/* DFPlayer Commands +//----Set volume---- + myDFPlayer.volume(10); //Set volume value (0~30). + myDFPlayer.volumeUp(); //Volume Up + myDFPlayer.volumeDown(); //Volume Down + //----Set different EQ---- + myDFPlayer.EQ(DFPLAYER_EQ_NORMAL); +// myDFPlayer.EQ(DFPLAYER_EQ_POP); +// myDFPlayer.EQ(DFPLAYER_EQ_ROCK); +// myDFPlayer.EQ(DFPLAYER_EQ_JAZZ); +// myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC); +// myDFPlayer.EQ(DFPLAYER_EQ_BASS); + //----Set device we use SD as default---- +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_U_DISK); + myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_AUX); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_SLEEP); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_FLASH); + //----Mp3 control---- +// myDFPlayer.sleep(); //sleep +// myDFPlayer.reset(); //Reset the module +// myDFPlayer.enableDAC(); //Enable On-chip DAC +// myDFPlayer.disableDAC(); //Disable On-chip DAC +// myDFPlayer.outputSetting(true, 15); //output setting, enable the output and set the gain to 15 + //----Mp3 play---- + myDFPlayer.next(); //Play next mp3 + myDFPlayer.previous(); //Play previous mp3 + myDFPlayer.play(1); //Play the first mp3 + myDFPlayer.loop(1); //Loop the first mp3 + myDFPlayer.pause(); //pause the mp3 + myDFPlayer.start(); //start the mp3 from the pause + myDFPlayer.playFolder(15, 4); //play specific mp3 in SD:/15/004.mp3; Folder Name(1~99); File Name(1~255) + myDFPlayer.enableLoopAll(); //loop all mp3 files. + myDFPlayer.disableLoopAll(); //stop loop all mp3 files. + myDFPlayer.playMp3Folder(4); //play specific mp3 in SD:/MP3/0004.mp3; File Name(0~65535) + myDFPlayer.advertise(3); //advertise specific mp3 in SD:/ADVERT/0003.mp3; File Name(0~65535) + myDFPlayer.stopAdvertise(); //stop advertise + myDFPlayer.playLargeFolder(2, 999); //play specific mp3 in SD:/02/004.mp3; Folder Name(1~10); File Name(1~1000) + myDFPlayer.loopFolder(5); //loop all mp3 files in folder SD:/05. + myDFPlayer.randomAll(); //Random play all the mp3. + myDFPlayer.enableLoop(); //enable loop. + myDFPlayer.disableLoop(); //disable loop. +*/ diff --git a/examples/IDEC/IDEC3_1_1SoundPlyr/IDEC3_1_1SoundPlyr.ino b/examples/IDEC/IDEC3_1_1SoundPlyr/IDEC3_1_1SoundPlyr.ino new file mode 100644 index 0000000..3c38f95 --- /dev/null +++ b/examples/IDEC/IDEC3_1_1SoundPlyr/IDEC3_1_1SoundPlyr.ino @@ -0,0 +1,1076 @@ +// Interactive Decoder Sounds and Lights One Sound Players IDEC3_1_1SoundPlyr.ino +// Version 1.08 Geoff Bunza 2020 +// Works with both short and long DCC Addesses +// This decoder will control Sound Sequences and LEDs +// F0=Master Function OFF = Function ON DISABLES the decoder +// Input Pin for Decoder Disable Pin 16/A2 Active LOW +//Functions for lights on/off: +// F11-F14 Four Functions LED ON/OFF by default PINS 13,16,17,18,19 +/* Pro Mini -D7 (TX) connected to DFPlayer1 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor + * Remember to connect +5V and GND to the DFPlayer too: DFPLAYER PINS 1 & 7 respectively + * This is a “mobile/function” decoder with audio play to dual motor control and + * LED functions. Audio tracks or clips are stored on a micro SD card for playing, + * in a folder labeled mp3, with tracks named 0001.mp3, 0002.mp3, etc. + * F0 is configured as Master Decoder Disable Override ON==Disable Decoder + * F1-F10 plays an audio sound set (1-10) defined by CVs + * MAX one of 12 Configurations per pin function: + * Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + * F0 Master Decoder Disable + * F1-F5 5 Functions LED ON/OFF + * F4 Motor2 On/OFF with speed and direction set by CV 62 + * Simple speed control is made via throttle speed setting for two MOTOR1 or overridden by non zero value in CV 50 + +PRO MINI PIN ASSIGNMENT: +2 - DCC Input +3 - Input Pin Play Sound Set1 +4 - Input Pin Play Sound Set2 +5 - Input Pin Play Sound Set3 +6 - Input Pin Play Sound Set4 +7 - Input Pin Play Sound Set5 +8 - Input Pin Play Sound Set6 +9 - Input Pin Play Sound Set7 +10 - Input Pin Play Sound Set8 +11 - Input Pin Play Sound Set9 +12 - Input Pin Play Sound Set10 +13 - LED F1 +14 A0 - LED F2 +15 A1 - DFPlayer1 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor +16 A2 - Input Pin for MasterDecoderDisable Active LOW +17 A3 - LED F3 +18 A4 - LED F4 +19 A5 - LED F5 +*/ +// ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP +// ******** AFTER THE INITIAL DECODER LOAD REMOVE THE "//" IN THE FOOLOWING LINE!! +//#define DECODER_LOADED + +// ******** REMOVE THE "//" IN THE FOOLOWING LINE TO SEND DEBUGGING +// ******** INFO TO THE SERIAL MONITOR +//#define DEBUG + +#include +#include +#include +SoftwareSerial DFSerial1(22,15); // PRO MINI RX, PRO MINI TX serial to DFPlayer +DFRobotDFPlayerMini Player1; + +#define This_Decoder_Address 24 +uint8_t CV_DECODER_MASTER_RESET = 252; + +//Uncomment ONLY ONE of the following: +//#define MasterTimeConstant 10L // 10's of milliseconds Timing +#define MasterTimeConstant 100L // Tenths of a second Timing +//#define MasterTimeConstant 1000L // Seconds Timing +//#define MasterTimeConstant 10000L // 10's of Seconds Timing +//#define MasterTimeConstant 60000L // Minutes Timing +//#define MasterTimeConstant 3600000L // Hours Timing + +int del_tim = 4000; +uint16_t ttemp, i; + +#define First_Track 1 // Play Random Tracks First_Track#=Start_Track >=1 +#define Last_Track 12 // Play Random Tracks Last_Track= Last Playable Track in Range <= Last Numbered Track +const int audiocmddelay = 34; +byte ss1[] = {0,0,0,0,0,0}; unsigned long ss1delay=0; +byte ss2[] = {0,0,0,0,0,0}; unsigned long ss2delay=0; +byte ss3[] = {0,0,0,0,0,0}; unsigned long ss3delay=0; +byte ss4[] = {0,0,0,0,0,0}; unsigned long ss4delay=0; +byte ss5[] = {0,0,0,0,0,0}; unsigned long ss5delay=0; +byte ss6[] = {0,0,0,0,0,0}; unsigned long ss6delay=0; +byte ss7[] = {0,0,0,0,0,0}; unsigned long ss7delay=0; +byte ss8[] = {0,0,0,0,0,0}; unsigned long ss8delay=0; +byte ss9[] = {0,0,0,0,0,0}; unsigned long ss9delay=0; +byte ss10[] = {0,0,0,0,0,0}; unsigned long ss10delay=0; +bool playing_sound_set [ ] = {false,false,false,false,false,false,false,false,false,false,false}; +byte soundset_channel[ ]={0,0,0,0,0,0,0,0,0,0,0}; +const int MasterDecoderDisablePin = 16; // D16/A0 Master Decoder Disable Input Pin Active LOW + +const int numINpins = 11; // Number of INput pins to initialize +byte inputpins [] = {3,4,5,6,7,8,9,10,11,12,16}; //These are all the Input Pins +const int numfpins = 5; // Number of Output pins to initialize +const int num_active_functions = 16; // Number of Functions stating with F0 +byte fpins [] = {13,14,17,18,19}; //These are all the Output Pins (first 15 is placeholder) +const int FunctionPin0 = 20; // D14/A0 DFPlayer Transmit (TX) Pin 3 +const int FunctionPin1 = 20; // A2 LED +const int FunctionPin2 = 20; // A3 LED +const int FunctionPin3 = 20; // A4 LED +const int FunctionPin4 = 20; // A5 LED +const int FunctionPin5 = 20; // Turns on Motor2 DCC Function Control Only NO Local Input Pin +const int FunctionPin6 = 20; // Place holders ONLY +const int FunctionPin7 = 20; // Place holders ONLY +const int FunctionPin8 = 20; // Place holders ONLY +const int FunctionPin9 = 20; // Place holders ONLY +const int FunctionPin10 = 20; // Place holders ONLY +const int FunctionPin11 = 13; // F13 LED +const int FunctionPin12 = 17; // F12 LED +const int FunctionPin13 = 18; // F13 LED +const int FunctionPin14 = 19; // F14 LED +const int FunctionPin15 = 20; // Place holders ONLY +int MasterDecoderDisable = 0; +int Function0_value = 0; +byte function_value [ ] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +uint8_t cv_value; + +NmraDcc Dcc ; +DCC_MSG Packet ; +int t; // temp +struct QUEUE +{ + int inuse; + int current_position; + int increment; + int stop_value; + int start_value; +}; +QUEUE *ftn_queue = new QUEUE[17]; + +struct CVPair +{ + uint16_t CV; + uint8_t Value; +}; +CVPair FactoryDefaultCVs [] = +{ + {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address&0x7F }, + + // These two CVs define the Long DCC Address + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, ((This_Decoder_Address>>8)&0x7F)+192 }, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address&0xFF }, + + // ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS +// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps + {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps +// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps + {CV_DECODER_MASTER_RESET, 0}, + + {30, 0}, //F0 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + + {31, 1}, //F1 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {32, 2}, //F2 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {33, 3}, //F3 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {34, 4}, //F4 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {35, 5}, //F5 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {36, 6}, //F6 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {37, 7}, //F7 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {38, 8}, //F8 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {39, 9}, //F9 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {40, 10}, //F10 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + + {41, 11}, //F11 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {42, 11}, //F12 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {43, 11}, //F13 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {44, 11}, //F14Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {45, 22}, //F15 not used + + {50, 3}, // Wait1 0-254 0.1 Seconds // SOUND SET 1 + {51, 22}, // Volume1 0-30 >30 == no volume change + {52, 1}, // Sound Clip1 + {53, 6}, // Wait2 0-254 0.1 Seconds + {54, 22}, // Volume2 0-30 >30 == no volume change + {55, 2}, // Sound Clip2 + {56, 6}, // Wait3 0-254 0.1 Seconds + {57, 20}, // Volume3 0-30 >30 == no volume change + {58, 3}, // Sound Clip3 + {59, 6}, // Wait4 0-254 0.1 Seconds + {60, 15}, // Volume4 0-30 >30 == no volume change + {61, 11}, // Sound Clip4 + {62, 11}, // Wait5 0-254 0.1 Seconds + {63, 11}, // Volume5 0-30 >30 == no volume change + {64, 12}, // Sound Clip5 + {65, 0}, // Sound Set Channel == LSB 0/1 + + {66, 2}, // Wait1 0-254 0.1 Seconds // SOUND SET 2 + {67, 20}, // Volume1 0-30 >30 == no volume change + {68, 4}, // Sound Clip1 + {69, 6}, // Wait2 0-254 0.1 Seconds + {70, 20}, // Volume2 0-30 >30 == no volume change + {71, 5}, // Sound Clip2 + {72, 6}, // Wait3 0-254 0.1 Seconds + {73, 20}, // Volume3 0-30 >30 == no volume change + {74, 6}, // Sound Clip3 + {75, 6}, // Wait4 0-254 0.1 Seconds + {76, 20}, // Volume4 0-30 >30 == no volume change + {77, 7}, // Sound Clip4 + {78, 6}, // Wait5 0-254 0.1 Seconds + {79, 20}, // Volume5 0-30 >30 == no volume change + {80, 8}, // Sound Clip5 + {81, 1}, // Sound Set Channel == LSB 0/1 + + {82, 1}, // Wait1 0-254 0.1 Seconds // SOUND SET 3 + {83, 20}, // Volume1 0-30 >30 == no volume change + {84, 5}, // Sound Clip1 + {85, 6}, // Wait2 0-254 0.1 Seconds + {86, 20}, // Volume2 0-30 >30 == no volume change + {87, 6}, // Sound Clip2 + {88, 6}, // Wait3 0-254 0.1 Seconds + {89, 20}, // Volume3 0-30 >30 == no volume change + {90, 7}, // Sound Clip3 + {91, 6}, // Wait4 0-254 0.1 Seconds + {92, 20}, // Volume4 0-30 >30 == no volume change + {93, 8}, // Sound Clip4 + {94, 6}, // Wait5 0-254 0.1 Seconds + {95, 20}, // Volume5 0-30 >30 == no volume change + {96, 8}, // Sound Clip5 + {97, 0}, // Sound Set Channel == LSB 0/1 + + {98, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 4 + {99, 23}, // Volume1 0-30 >30 == no volume change + {100, 9}, // Sound Clip1 + {101,110}, // Wait2 0-254 0.1 Seconds + {102, 99}, // Volume2 0-30 >30 == no volume change + {103, 0}, // Sound Clip2 + {104, 0}, // Wait3 0-254 0.1 Seconds + {105, 20}, // Volume3 0-30 >30 == no volume change + {106, 0}, // Sound Clip3 + {107, 0}, // Wait4 0-254 0.1 Seconds + {108, 99}, // Volume4 0-30 >30 == no volume change + {109, 0}, // Sound Clip4 + {110, 0}, // Wait5 0-254 0.1 Seconds + {111, 99}, // Volume5 0-30 >30 == no volume change + {112, 0}, // Sound Clip5 + {113, 0}, // Sound Set Channel == LSB 0/1 + + {114, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 5 + {115, 20}, // Volume1 0-30 >30 == no volume change + {116, 1}, // Sound Clip1 + {117, 20}, // Wait2 0-254 0.1 Seconds + {118, 20}, // Volume2 0-30 >30 == no volume change + {119, 2}, // Sound Clip2 + {120, 30}, // Wait3 0-254 0.1 Seconds + {121, 20}, // Volume3 0-30 >30 == no volume change + {122, 3}, // Sound Clip3 + {123, 50}, // Wait4 0-254 0.1 Seconds + {124, 20}, // Volume4 0-30 >30 == no volume change + {125, 4}, // Sound Clip4 + {126, 100}, // Wait5 0-254 0.1 Seconds + {127, 20}, // Volume5 0-30 >30 == no volume change + {128, 5}, // Sound Clip5 + {129, 0}, // Sound Set Channel == LSB 0/1 + + {130, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 6 + {131, 20}, // Volume1 0-30 >30 == no volume change + {132, 1}, // Sound Clip1 + {133, 20}, // Wait2 0-254 0.1 Seconds + {134, 20}, // Volume2 0-30 >30 == no volume change + {135, 2}, // Sound Clip2 + {136, 30}, // Wait3 0-254 0.1 Seconds + {137, 20}, // Volume3 0-30 >30 == no volume change + {138, 3}, // Sound Clip3 + {139, 50}, // Wait4 0-254 0.1 Seconds + {140, 20}, // Volume4 0-30 >30 == no volume change + {141, 4}, // Sound Clip4 + {142, 100}, // Wait5 0-254 0.1 Seconds + {143, 20}, // Volume5 0-30 >30 == no volume change + {144, 5}, // Sound Clip5 + {145, 1}, // Sound Set Channel == LSB 0/1 + + {146, 10}, // Wait1 0-254 0.1 Seconds // SOUND SET 7 + {147, 29}, // Volume1 0-30 >30 == no volume change + {148, 1}, // Sound Clip1 + {149, 10}, // Wait2 0-254 0.1 Seconds + {150, 24}, // Volume2 0-30 >30 == no volume change + {151, 2}, // Sound Clip2 + {152, 10}, // Wait3 0-254 0.1 Seconds + {153, 18}, // Volume3 0-30 >30 == no volume change + {154, 3}, // Sound Clip3 + {155, 10}, // Wait4 0-254 0.1 Seconds + {156, 12}, // Volume4 0-30 >30 == no volume change + {157, 4}, // Sound Clip4 + {158, 10}, // Wait5 0-254 0.1 Seconds + {159, 6}, // Volume5 0-30 >30 == no volume change + {160, 5}, // Sound Clip5 + {161, 0}, // Sound Set Channel == LSB 0/1 + + {162, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 8 + {163, 20}, // Volume1 0-30 >30 == no volume change + {164, 1}, // Sound Clip1 + {165, 20}, // Wait2 0-254 0.1 Seconds + {166, 20}, // Volume2 0-30 >30 == no volume change + {167, 2}, // Sound Clip2 + {168, 30}, // Wait3 0-254 0.1 Seconds + {169, 20}, // Volume3 0-30 >30 == no volume change + {170, 3}, // Sound Clip3 + {171, 50}, // Wait4 0-254 0.1 Seconds + {172, 20}, // Volume4 0-30 >30 == no volume change + {173, 4}, // Sound Clip4 + {174, 100}, // Wait5 0-254 0.1 Seconds + {175, 20}, // Volume5 0-30 >30 == no volume change + {176, 5}, // Sound Clip5 + {177, 1}, // Sound Set Channel == LSB 0/1 + + {178, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 9 + {179, 20}, // Volume1 0-30 >30 == no volume change + {180, 255}, // Sound Clip1 + {181, 11}, // Wait2 0-254 0.1 Seconds + {182, 20}, // Volume2 0-30 >30 == no volume change + {183, 255}, // Sound Clip2 + {184, 11}, // Wait3 0-254 0.1 Seconds + {185, 20}, // Volume3 0-30 >30 == no volume change + {186, 255}, // Sound Clip3 + {187, 14}, // Wait4 0-254 0.1 Seconds + {188, 20}, // Volume4 0-30 >30 == no volume change + {189, 255}, // Sound Clip4 + {190, 14}, // Wait5 0-254 0.1 Seconds + {191, 20}, // Volume5 0-30 >30 == no volume change + {192, 255}, // Sound Clip5 + {193, 0}, // Sound Set Channel == LSB 0/1 + + {194, 4}, // Wait1 0-254 0.1 Seconds // SOUND SET 10 + {195, 20}, // Volume1 0-30 >30 == no volume change + {196, 10}, // Sound Clip1 + {197, 110}, // Wait2 0-254 0.1 Seconds + {198, 99}, // Volume2 0-30 >30 == no volume change + {199, 0}, // Sound Clip2 + {200, 4}, // Wait3 0-254 0.1 Seconds + {201, 99}, // Volume3 0-30 >30 == no volume change + {202, 0}, // Sound Clip3 + {203, 4}, // Wait4 0-254 0.1 Seconds + {204, 12}, // Volume4 0-30 >30 == no volume change + {205, 9}, // Sound Clip4 + {206, 100}, // Wait5 0-254 0.1 Seconds + {207, 99}, // Volume5 0-30 >30 == no volume change + {208, 0}, // Sound Clip5 + {209, 1}, // Sound Set Channel == LSB 0/1 + + //252,252 CV_DECODER_MASTER_RESET + + {253, 0}, // Extra +}; + +uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +void notifyCVResetFactoryDefault() +{ + // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset + // to flag to the loop() function that a reset to Factory Defaults needs to be done + FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +}; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS + +void setup() //****************************************************** +{ +#ifdef DEBUG + Serial.begin(115200); +#endif + DFSerial1.begin (9600); + Player1.begin (DFSerial1); + + pinMode (MasterDecoderDisablePin,INPUT_PULLUP); // Master Decoder Disable Input Pin Active LOW + + // initialize the digital pins as outputs + for (int i=0; i < numfpins; i++) { + pinMode(fpins[i], OUTPUT); + digitalWrite(fpins[i], 0); // All OUPUT pins initialized LOW + } + // initialize the digital pins as inputs + for (int i=0; i < numINpins; i++) { + pinMode(inputpins[i], INPUT_PULLUP); + } + // Setup which External Interrupt, the Pin it's associated with that we're using + Dcc.pin(0, 2, 0); + // Call the main DCC Init function to enable the DCC Receiver + Dcc.init( MAN_ID_DIY, 61, FLAGS_MY_ADDRESS_ONLY, 0 ); + delay(800); +#if defined(DECODER_LOADED) + if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET ) +#endif + { + for (int j=0; j < FactoryDefaultCVIndex; j++ ) + Dcc.setCV( FactoryDefaultCVs[j].CV, FactoryDefaultCVs[j].Value); + } + // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; +#ifdef DEBUG + Serial.println("CV Dump:"); + for (i=30; i<45; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=30; i<45; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 1"); + for (i=50; i<66; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=50; i<66; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 2"); + for (i=66; i<82; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=66; i<82; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 3"); + for (i=82; i<98; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=82; i<98; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 4"); + for (i=98; i<114; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=98; i<114; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 5"); + for (i=114; i<130; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=114; i<130; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 6"); + for (i=130; i<146; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=130; i<146; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 7"); + for (i=146; i<162; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=146; i<162; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 8"); + for (i=162; i<178; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=162; i<178; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 9"); + for (i=178; i<194; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=178; i<194; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 10"); + for (i=194; i<210; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=194; i<210; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } +#endif +} +void loop() //*********************************************************************************** +{ + //MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation + Dcc.process(); + delay(1); +// INPUT OVER RIDES + // Check Master Input Over ride + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + else MasterDecoderDisable = Function0_value & 1; + if (MasterDecoderDisable == 1) { + for (i=0; i < numfpins; i++) digitalWrite(fpins[i], 0); // All LEDs set LOW + } +// ******************************************************************************** + if (MasterDecoderDisable == 0) { + for (i=0; i < num_active_functions; i++) { + cv_value = Dcc.getCV(30+i) ; +#ifdef DEBUG + //Serial.print(" cv_value: "); + //Serial.println(cv_value, DEC) ; +#endif + switch ( cv_value ) { + case 0: // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + break; + case 1: // + if (((digitalRead(3)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss1[0]=1; playing_sound_set[cv_value]=true; +#ifdef DEBUG + Serial.print(" cv_value: "); + Serial.println(cv_value, DEC) ; + Serial.print(" function_value[cv_value]: "); + Serial.println(function_value[cv_value], DEC) ; + Serial.print(" ss1[0]: "); + Serial.println(ss1[0], DEC) ; + Serial.print(" playing_sound_set[cv_value]: "); + Serial.println(playing_sound_set[cv_value], DEC) ; +#endif + } + break; + case 2: // + if (((digitalRead(4)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss2[0]=1; playing_sound_set[cv_value]=true; +#ifdef DEBUG + Serial.print(" cv_value: "); + Serial.println(cv_value, DEC) ; + Serial.print(" function_value[cv_value]: "); + Serial.println(function_value[cv_value], DEC) ; + Serial.print(" ss2[0]: "); + Serial.println(ss2[0], DEC) ; + Serial.print(" playing_sound_set[cv_value]: "); + Serial.println(playing_sound_set[cv_value], DEC) ; +#endif + } + + break; + case 3: // + if (((digitalRead(5)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss3[0]=1; playing_sound_set[cv_value]=true; } + break; + case 4: // + if (((digitalRead(6)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss4[0]=1; playing_sound_set[cv_value]=true; } + break; + case 5: // + if (((digitalRead(7)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss5[0]=1; playing_sound_set[cv_value]=true; } + break; + case 6: // + if (((digitalRead(8)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss6[0]=1; playing_sound_set[cv_value]=true; } + break; + case 7: // + if (((digitalRead(9)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss7[0]=1; playing_sound_set[cv_value]=true; } + break; + case 8: // + if (((digitalRead(10)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss8[0]=1; playing_sound_set[cv_value]=true; } + break; + case 9: // + if (((digitalRead(11)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss9[0]=1; playing_sound_set[cv_value]=true; } + break; + case 10: // + if (((digitalRead(12)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss10[0]=1; playing_sound_set[cv_value]=true; } + break; + case 11: // LEDs + break; + default: + break; + } + } + } + // ========================== Sound Set 1 Begin Play + if (ss1[0]==1) { + ss1delay=millis()+(long(Dcc.getCV(50)*MasterTimeConstant)); // Wait1 + ss1[0]=0; ss1[1]=1; + } + if ((ss1[1]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(52)); +#ifdef DEBUG + Serial.print(" Here 1: "); + Serial.println(ttemp, DEC) ; +#endif + setVolumeOnChannel (Dcc.getCV(51)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss1delay=millis()+(long(Dcc.getCV(53)*MasterTimeConstant)); // Wait2 + ss1[1]=0; ss1[2]=1; + } + if ((ss1[2]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(55)); +#ifdef DEBUG + Serial.print(" Here 2: "); + Serial.println(ttemp, DEC) ; +#endif + setVolumeOnChannel (Dcc.getCV(54)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss1delay=millis()+(long(Dcc.getCV(56)*MasterTimeConstant)); // Wait3 + ss1[2]=0; ss1[3]=1; + } + if ((ss1[3]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(58)); +#ifdef DEBUG + Serial.print(" Here 3: "); + Serial.println(ttemp, DEC) ; +#endif + setVolumeOnChannel (Dcc.getCV(57)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss1delay=millis()+(long(Dcc.getCV(59)*MasterTimeConstant)); // Wait4 + ss1[3]=0; ss1[4]=1; + } + if ((ss1[4]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(61)); + setVolumeOnChannel (Dcc.getCV(60)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss1delay=millis()+(long(Dcc.getCV(62)*MasterTimeConstant)); // Wait5 + ss1[4]=0; ss1[5]=1; + } + if ((ss1[5]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(64)); + setVolumeOnChannel (Dcc.getCV(63)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss1[5]=0; playing_sound_set[1]=false; + } +// ========================== Sound Set 2 Begin Play + if (ss2[0]==1) { + ss2delay=millis()+(long(Dcc.getCV(66)*MasterTimeConstant)); // Wait1 + ss2[0]=0; ss2[1]=1; + } + if ((ss2[1]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(68)); + setVolumeOnChannel (Dcc.getCV(67)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss2delay=millis()+(long(Dcc.getCV(69)*MasterTimeConstant)); // Wait2 + ss2[1]=0; ss2[2]=1; + } + if ((ss2[2]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(71)); + setVolumeOnChannel (Dcc.getCV(70)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss2delay=millis()+(long(Dcc.getCV(72)*MasterTimeConstant)); // Wait3 + ss2[2]=0; ss2[3]=1; + } + if ((ss2[3]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(74)); + setVolumeOnChannel (Dcc.getCV(73)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss2delay=millis()+(long(Dcc.getCV(75)*MasterTimeConstant)); // Wait4 + ss2[3]=0; ss2[4]=1; + } + if ((ss2[4]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(77)); + setVolumeOnChannel (Dcc.getCV(76)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss2delay=millis()+(long(Dcc.getCV(78)*MasterTimeConstant)); // Wait5 + ss2[4]=0; ss2[5]=1; + } + if ((ss2[5]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(80)); + setVolumeOnChannel (Dcc.getCV(79)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss2[5]=0; playing_sound_set[2]=false; + } +// ========================== Sound Set 3 Begin Play + if (ss3[0]==1) { + ss3delay=millis()+(long(Dcc.getCV(82)*MasterTimeConstant)); // Wait1 + ss3[0]=0; ss3[1]=1; + } + if ((ss3[1]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(84)); + setVolumeOnChannel (Dcc.getCV(83)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss3delay=millis()+(long(Dcc.getCV(85)*MasterTimeConstant)); // Wait2 + ss3[1]=0; ss3[2]=1; + } + if ((ss3[2]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(87)); + setVolumeOnChannel (Dcc.getCV(86)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss3delay=millis()+(long(Dcc.getCV(88)*MasterTimeConstant)); // Wait3 + ss3[2]=0; ss3[3]=1; + } + if ((ss3[3]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(90)); + setVolumeOnChannel (Dcc.getCV(89)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss3delay=millis()+(long(Dcc.getCV(91)*MasterTimeConstant)); // Wait4 + ss3[3]=0; ss3[4]=1; + } + if ((ss3[4]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(93)); + setVolumeOnChannel (Dcc.getCV(92)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss3delay=millis()+(long(Dcc.getCV(94)*MasterTimeConstant)); // Wait5 + ss3[4]=0; ss3[5]=1; + } + if ((ss3[5]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(96)); + setVolumeOnChannel (Dcc.getCV(95)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss3[5]=0; playing_sound_set[3]=false; + } +// ========================== Sound Set 4 Begin Play + if (ss4[0]==1) { + ss4delay=millis()+(long(Dcc.getCV(98)*MasterTimeConstant)); // Wait1 + ss4[0]=0; ss4[1]=1; + } + if ((ss4[1]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(100)); + setVolumeOnChannel (Dcc.getCV(99)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss4delay=millis()+(long(Dcc.getCV(101)*MasterTimeConstant)); // Wait2 + ss4[1]=0; ss4[2]=1; + } + if ((ss4[2]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(103)); + setVolumeOnChannel (Dcc.getCV(102)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss4delay=millis()+(long(Dcc.getCV(104)*MasterTimeConstant)); // Wait3 + ss4[2]=0; ss4[3]=1; + } + if ((ss4[3]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(106)); + setVolumeOnChannel (Dcc.getCV(105)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss4delay=millis()+(long(Dcc.getCV(107)*MasterTimeConstant)); // Wait4 + ss4[3]=0; ss4[4]=1; + } + if ((ss4[4]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(109)); + setVolumeOnChannel (Dcc.getCV(108)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss4delay=millis()+(long(Dcc.getCV(110)*MasterTimeConstant)); // Wait5 + ss4[4]=0; ss4[5]=1; + } + if ((ss4[5]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(112)); + setVolumeOnChannel (Dcc.getCV(111)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss4[5]=0; playing_sound_set[4]=false; + } +// ========================== Sound Set 5 Begin Play + if (ss5[0]==1) { + ss5delay=millis()+(long(Dcc.getCV(114)*MasterTimeConstant)); // Wait1 + ss5[0]=0; ss5[1]=1; + } + if ((ss5[1]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(116)); + setVolumeOnChannel (Dcc.getCV(115)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss5delay=millis()+(long(Dcc.getCV(117)*MasterTimeConstant)); // Wait2 + ss5[1]=0; ss5[2]=1; + } + if ((ss5[2]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(119)); + setVolumeOnChannel (Dcc.getCV(118)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss5delay=millis()+(long(Dcc.getCV(120)*MasterTimeConstant)); // Wait3 + ss5[2]=0; ss5[3]=1; + } + if ((ss5[3]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(122)); + setVolumeOnChannel (Dcc.getCV(121)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss5delay=millis()+(long(Dcc.getCV(123)*MasterTimeConstant)); // Wait4 + ss5[3]=0; ss5[4]=1; + } + if ((ss5[4]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(125)); + setVolumeOnChannel (Dcc.getCV(124)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss5delay=millis()+(long(Dcc.getCV(126)*MasterTimeConstant)); // Wait5 + ss5[4]=0; ss5[5]=1; + } + if ((ss5[5]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(128)); + setVolumeOnChannel (Dcc.getCV(127)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss5[5]=0; playing_sound_set[5]=false; + } + +// ========================== Sound Set 6 Begin Play + if (ss6[0]==1) { + ss6delay=millis()+(long(Dcc.getCV(130)*MasterTimeConstant)); // Wait1 + ss6[0]=0; ss6[1]=1; + } + if ((ss6[1]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(132)); + setVolumeOnChannel (Dcc.getCV(131)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss6delay=millis()+(long(Dcc.getCV(133)*MasterTimeConstant)); // Wait2 + ss6[1]=0; ss6[2]=1; + } + if ((ss6[2]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(135)); + setVolumeOnChannel (Dcc.getCV(134)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss6delay=millis()+(long(Dcc.getCV(136)*MasterTimeConstant)); // Wait3 + ss6[2]=0; ss6[3]=1; + } + if ((ss6[3]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(138)); + setVolumeOnChannel (Dcc.getCV(137)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss6delay=millis()+(long(Dcc.getCV(139)*MasterTimeConstant)); // Wait4 + ss6[3]=0; ss6[4]=1; + } + if ((ss6[4]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(141)); + setVolumeOnChannel (Dcc.getCV(140)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss6delay=millis()+(long(Dcc.getCV(142)*MasterTimeConstant)); // Wait5 + ss6[4]=0; ss6[5]=1; + } + if ((ss6[5]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(144)); + setVolumeOnChannel (Dcc.getCV(143)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss6[5]=0; playing_sound_set[6]=false; + } + +// ========================== Sound Set 7 Begin Play + if (ss7[0]==1) { + ss7delay=millis()+(long(Dcc.getCV(146)*MasterTimeConstant)); // Wait1 + ss7[0]=0; ss7[1]=1; + } + if ((ss7[1]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(148)); + setVolumeOnChannel (Dcc.getCV(147)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss7delay=millis()+(long(Dcc.getCV(149)*MasterTimeConstant)); // Wait2 + ss7[1]=0; ss7[2]=1; + } + if ((ss7[2]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(151)); + setVolumeOnChannel (Dcc.getCV(150)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss7delay=millis()+(long(Dcc.getCV(152)*MasterTimeConstant)); // Wait3 + ss7[2]=0; ss7[3]=1; + } + if ((ss7[3]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(154)); + setVolumeOnChannel (Dcc.getCV(153)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss7delay=millis()+(long(Dcc.getCV(155)*MasterTimeConstant)); // Wait4 + ss7[3]=0; ss7[4]=1; + } + if ((ss7[4]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(157)); + setVolumeOnChannel (Dcc.getCV(156)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss7delay=millis()+(long(Dcc.getCV(158)*MasterTimeConstant)); // Wait5 + ss7[4]=0; ss7[5]=1; + } + if ((ss7[5]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(160)); + setVolumeOnChannel (Dcc.getCV(159)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss7[5]=0; playing_sound_set[7]=false; + } +// ========================== Sound Set 8 Begin Play + if (ss8[0]==1) { + ss8delay=millis()+(long(Dcc.getCV(162)*MasterTimeConstant)); // Wait1 + ss8[0]=0; ss8[1]=1; + } + if ((ss8[1]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(164)); + setVolumeOnChannel (Dcc.getCV(163)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss8delay=millis()+(long(Dcc.getCV(165)*MasterTimeConstant)); // Wait2 + ss8[1]=0; ss8[2]=1; + } + if ((ss8[2]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(167)); + setVolumeOnChannel (Dcc.getCV(166)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss8delay=millis()+(long(Dcc.getCV(168)*MasterTimeConstant)); // Wait3 + ss8[2]=0; ss8[3]=1; + } + if ((ss8[3]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(170)); + setVolumeOnChannel (Dcc.getCV(169)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss8delay=millis()+(long(Dcc.getCV(171)*MasterTimeConstant)); // Wait4 + ss8[3]=0; ss8[4]=1; + } + if ((ss8[4]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(173)); + setVolumeOnChannel (Dcc.getCV(172)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss8delay=millis()+(long(Dcc.getCV(174)*MasterTimeConstant)); // Wait5 + ss8[4]=0; ss8[5]=1; + } + if ((ss8[5]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(176)); + setVolumeOnChannel (Dcc.getCV(175)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss8[5]=0; playing_sound_set[8]=false; + } +// ========================== Sound Set 9 Begin Play + if (ss9[0]==1) { + ss9delay=millis()+(long(Dcc.getCV(178)*MasterTimeConstant)); // Wait1 + ss9[0]=0; ss9[1]=1; + } + if ((ss9[1]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(180)); + setVolumeOnChannel (Dcc.getCV(179)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss9delay=millis()+(long(Dcc.getCV(181)*MasterTimeConstant)); // Wait2 + ss9[1]=0; ss9[2]=1; + } + if ((ss9[2]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(183)); + setVolumeOnChannel (Dcc.getCV(182)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss9delay=millis()+(long(Dcc.getCV(184)*MasterTimeConstant)); // Wait3 + ss9[2]=0; ss9[3]=1; + } + if ((ss9[3]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(186)); + setVolumeOnChannel (Dcc.getCV(185)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss9delay=millis()+(long(Dcc.getCV(187)*MasterTimeConstant)); // Wait4 + ss9[3]=0; ss9[4]=1; + } + if ((ss9[4]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(189)); + setVolumeOnChannel (Dcc.getCV(188)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss9delay=millis()+(long(Dcc.getCV(190)*MasterTimeConstant)); // Wait5 + ss9[4]=0; ss9[5]=1; + } + if ((ss9[5]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(192)); + setVolumeOnChannel (Dcc.getCV(191)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss9[5]=0; playing_sound_set[9]=false; + } +// ========================== Sound Set 10 Begin Play + if (ss10[0]==1) { + ss10delay=millis()+(long(Dcc.getCV(194)*MasterTimeConstant)); // Wait1 + ss10[0]=0; ss10[1]=1; + } + if ((ss10[1]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(196)); + setVolumeOnChannel (Dcc.getCV(195)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss10delay=millis()+(long(Dcc.getCV(197)*MasterTimeConstant)); // Wait2 + ss10[1]=0; ss10[2]=1; + } + if ((ss10[2]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(199)); + setVolumeOnChannel (Dcc.getCV(198)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss10delay=millis()+(long(Dcc.getCV(200)*MasterTimeConstant)); // Wait3 + ss10[2]=0; ss10[3]=1; + } + if ((ss10[3]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(202)); + setVolumeOnChannel (Dcc.getCV(201)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss10delay=millis()+(long(Dcc.getCV(203)*MasterTimeConstant)); // Wait4 + ss10[3]=0; ss10[4]=1; + } + if ((ss10[4]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(205)); + setVolumeOnChannel (Dcc.getCV(204)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss10delay=millis()+(long(Dcc.getCV(206)*MasterTimeConstant)); // Wait5 + ss10[4]=0; ss10[5]=1; + } + if ((ss10[5]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(208)); + setVolumeOnChannel (Dcc.getCV(207)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss10[5]=0; playing_sound_set[10]=false; + } +} // end loop() + +void playTrackOnChannel ( byte dtrack) { + if (dtrack!=255) {Player1.play(dtrack); delay(audiocmddelay); } + else {Player1.play(random(First_Track,Last_Track+1)); delay(audiocmddelay); } +} +void setVolumeOnChannel ( byte dvolume) { + if(dvolume>30) return; // Don't change the volume if out of range + Player1.volume (dvolume); + delay(audiocmddelay); +} + +void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { +#ifdef DEBUG + Serial.print("Addr= "); + Serial.println(Addr, DEC) ; + Serial.print("FuncState= "); + Serial.println(FuncState, DEC) ; +#endif + switch(FuncGrp) + { + case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1 + exec_function( 0, FunctionPin0, (FuncState & FN_BIT_00)>>4 ); + exec_function( 1, FunctionPin1, (FuncState & FN_BIT_01)); + exec_function( 2, FunctionPin2, (FuncState & FN_BIT_02)>>1); + exec_function( 3, FunctionPin3, (FuncState & FN_BIT_03)>>2 ); + exec_function( 4, FunctionPin4, (FuncState & FN_BIT_04)>>3 ); + break; + case FN_5_8: //Function Group 1 S FFFF == 1 F8 F7 F6 F5 & == 0 F12 F11 F10 F9 F8 + exec_function( 5, FunctionPin5, (FuncState & FN_BIT_05)); + exec_function( 6, FunctionPin6, (FuncState & FN_BIT_06)>>1 ); + exec_function( 7, FunctionPin7, (FuncState & FN_BIT_07)>>2 ); + exec_function( 8, FunctionPin8, (FuncState & FN_BIT_08)>>3 ); + break; + + case FN_9_12: + exec_function( 9, FunctionPin9, (FuncState & FN_BIT_09)); + exec_function( 10, FunctionPin10, (FuncState & FN_BIT_10)>>1 ); + exec_function( 11, FunctionPin11, (FuncState & FN_BIT_11)>>2 ); + exec_function( 12, FunctionPin12, (FuncState & FN_BIT_12)>>3 ); + break; + case FN_13_20: //Function Group 2 FuncState == F20-F13 Function Control + exec_function( 13, FunctionPin13, (FuncState & FN_BIT_13)); + exec_function( 14, FunctionPin14, (FuncState & FN_BIT_14)>>1 ); + //exec_function( 15, FunctionPin15, (FuncState & FN_BIT_15)>>2 ); + //exec_function( 16, FunctionPin16, (FuncState & FN_BIT_16)>>3 ); + break; + + case FN_21_28: + break; + } +} // end notifyDccFunc +void exec_function (int function, int pin, int FuncState) { +#ifdef DEBUG + //Serial.print("ex function= "); + //Serial.println(function, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch ( Dcc.getCV( 30+function) ) { // Config + case 0: // Master Disable + Function0_value = byte(FuncState); + break; + case 1: // play sound set [ function ] + + case 2: // play sound set [ function ] + + case 3: // play sound set [ function ] + + case 4: // play sound set [ function ] + + case 5: // play sound set [ function ] + + case 6: // play sound set [ function ] + + case 7: // play sound set [ function ] + + case 8: // play sound set [ function ] + + case 9: // play sound set [ function ] + + case 10: // play sound set [ function ] + function_value[function] = byte(FuncState); + break; + case 11: // On - Off LED + if (MasterDecoderDisable == 0) digitalWrite (pin, FuncState); + else digitalWrite (pin, 0); // Master Disable is ON so force LEDs off + break; + default: + break;; + } +} // end exec_function + +/* DFPlayer Commands +//----Set volume---- + myDFPlayer.volume(10); //Set volume value (0~30). + myDFPlayer.volumeUp(); //Volume Up + myDFPlayer.volumeDown(); //Volume Down + //----Set different EQ---- + myDFPlayer.EQ(DFPLAYER_EQ_NORMAL); +// myDFPlayer.EQ(DFPLAYER_EQ_POP); +// myDFPlayer.EQ(DFPLAYER_EQ_ROCK); +// myDFPlayer.EQ(DFPLAYER_EQ_JAZZ); +// myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC); +// myDFPlayer.EQ(DFPLAYER_EQ_BASS); + //----Set device we use SD as default---- +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_U_DISK); + myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_AUX); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_SLEEP); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_FLASH); + //----Mp3 control---- +// myDFPlayer.sleep(); //sleep +// myDFPlayer.reset(); //Reset the module +// myDFPlayer.enableDAC(); //Enable On-chip DAC +// myDFPlayer.disableDAC(); //Disable On-chip DAC +// myDFPlayer.outputSetting(true, 15); //output setting, enable the output and set the gain to 15 + //----Mp3 play---- + myDFPlayer.next(); //Play next mp3 + myDFPlayer.previous(); //Play previous mp3 + myDFPlayer.play(1); //Play the first mp3 + myDFPlayer.loop(1); //Loop the first mp3 + myDFPlayer.pause(); //pause the mp3 + myDFPlayer.start(); //start the mp3 from the pause + myDFPlayer.playFolder(15, 4); //play specific mp3 in SD:/15/004.mp3; Folder Name(1~99); File Name(1~255) + myDFPlayer.enableLoopAll(); //loop all mp3 files. + myDFPlayer.disableLoopAll(); //stop loop all mp3 files. + myDFPlayer.playMp3Folder(4); //play specific mp3 in SD:/MP3/0004.mp3; File Name(0~65535) + myDFPlayer.advertise(3); //advertise specific mp3 in SD:/ADVERT/0003.mp3; File Name(0~65535) + myDFPlayer.stopAdvertise(); //stop advertise + myDFPlayer.playLargeFolder(2, 999); //play specific mp3 in SD:/02/004.mp3; Folder Name(1~10); File Name(1~1000) + myDFPlayer.loopFolder(5); //loop all mp3 files in folder SD:/05. + myDFPlayer.randomAll(); //Random play all the mp3. + myDFPlayer.enableLoop(); //enable loop. + myDFPlayer.disableLoop(); //disable loop. +*/ diff --git a/examples/IDEC/IDEC3_2_2SoundPlyrs/IDEC3_2_2SoundPlyrs.ino b/examples/IDEC/IDEC3_2_2SoundPlyrs/IDEC3_2_2SoundPlyrs.ino new file mode 100644 index 0000000..acd36ff --- /dev/null +++ b/examples/IDEC/IDEC3_2_2SoundPlyrs/IDEC3_2_2SoundPlyrs.ino @@ -0,0 +1,1122 @@ +// Interactive Decoder Sounds and Lights Two Sound Players IDEC3_2_2SoundPlyrs.ino +// Version 1.08 Geoff Bunza 2020 +// Works with both short and long DCC Addesses +// This decoder will control Sound Sequences and LEDs +// F0=Master Function OFF = Function ON DISABLES the decoder +// Input Pin for Decoder Disable Pin 16/A2 Active LOW +//Functions for lights on/off: +// F11-F14 Four Functions LED ON/OFF by default PINS 13,16,17,18,19 +/* + * Pro Mini D14 A0 (TX) connected to DFPlayer2 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor + * Pro Mini D15 A1 (TX) connected to DFPlayer1 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor + * Remember to connect +5V and GND to the DFPlayer too: DFPLAYER PINS 1 & 7 respectively + * This is a “mobile/function” decoder with audio play to dual motor control and + * LED functions. Audio tracks or clips are stored on a micro SD card for playing, + in a folder labeled mp3, with tracks named 0001.mp3, 0002.mp3, etc. + * Up to 10 Sound Sets can be defined (and programmed via CVs) each sound set consists of: + delay1,volume1,sound clip1,delay2,volume2,sound clip2,delay3,volume3,sound clip3,delay4,volume4,sound clip4,delay5,volume5,sound clip5,PlayerCnannel (0-1) -- Timing of playing the sound set is completely independent of other sound sets and can occur simultaneously + If a sound clip/track is started while another clp/track is playing on the same player channel, the newly starting clip/track + * Delay set to zero will offer NO delay time + * Volume set to >30 will not change current volume setting + * Track set to 0 will skip playing a track -- delay and volume set can be set to 0 and >30 to ignore operation too, + otherwise delay and volume are executed normally + * Track set to 255 will select a random track to play from number First_Track to Last_Track INCLUSIVE + * F0 is configured as Master Decoder Disable Override ON==Disable Decoder + * F1-F10 plays an audio set (1-10) defined by CVs + * MAX one of 12 Configurations per pin function: + * Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + * F0 Master Decoder Disable + * F1-F10 Play Sound Set 1-10 + * F11-F14 Functions LED ON/OFF + * Both F1-F10 set ON or the appropriate Input Pin 3-12 held LOW will repeat play the associated sound set + until BOTH the respective DCC function goes OFF AND the respective Input Pin goes HIGH + +PRO MINI PIN ASSIGNMENT: +2 - DCC Input +3 - Input Pin Play Sound Set1 +4 - Input Pin Play Sound Set2 +5 - Input Pin Play Sound Set3 +6 - Input Pin Play Sound Set4 +7 - Input Pin Play Sound Set5 +8 - Input Pin Play Sound Set6 +9 - Input Pin Play Sound Set7 +10 - Input Pin Play Sound Set8 +11 - Input Pin Play Sound Set9 +12 - Input Pin Play Sound Set10 +13 - LED F1 +14 A0 - DFPlayer2 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor +15 A1 - DFPlayer1 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor +16 A2 - Input Pin for MasterDecoderDisable Active LOW +17 A3 - LED F2 +18 A4 - LED F3 +19 A5 - LED F4 +*/ +// ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP +// ******** AFTER THE INITIAL DECODER LOAD REMOVE THE "//" IN THE FOOLOWING LINE!! +//#define DECODER_LOADED + +// ******** EMOVE THE "//" IN THE FOOLOWING LINE TO SEND DEBUGGING +// ******** INFO TO THE SERIAL MONITOR +//#define DEBUG + +#include +#include +#include +SoftwareSerial DFSerial2(21,14); // PRO MINI RX, PRO MINI TX serial to DFPlayer +SoftwareSerial DFSerial1(22,15); // PRO MINI RX, PRO MINI TX serial to DFPlayer +DFRobotDFPlayerMini Player1; +DFRobotDFPlayerMini Player2; + +#define This_Decoder_Address 24 +uint8_t CV_DECODER_MASTER_RESET = 252; + +//Uncomment ONLY ONE of the following: +//#define MasterTimeConstant 10L // 10's of milliseconds Timing +#define MasterTimeConstant 100L // Tenths of a second Timing +//#define MasterTimeConstant 1000L // Seconds Timing +//#define MasterTimeConstant 10000L // 10's of Seconds Timing +//#define MasterTimeConstant 60000L // Minutes Timing +//#define MasterTimeConstant 3600000L // Hours Timing + +unsigned long estop = 1; +int del_tim = 4000; +uint16_t ttemp, i; +#define First_Track 1 // Play Random Tracks First_Track#=Start_Track >=1 +#define Last_Track 12 // Play Random Tracks Last_Track= Last Playable Track in Range <= Last Numbered Track +const int audiocmddelay = 34; +byte ss1[] = {0,0,0,0,0,0}; unsigned long ss1delay=0; +byte ss2[] = {0,0,0,0,0,0}; unsigned long ss2delay=0; +byte ss3[] = {0,0,0,0,0,0}; unsigned long ss3delay=0; +byte ss4[] = {0,0,0,0,0,0}; unsigned long ss4delay=0; +byte ss5[] = {0,0,0,0,0,0}; unsigned long ss5delay=0; +byte ss6[] = {0,0,0,0,0,0}; unsigned long ss6delay=0; +byte ss7[] = {0,0,0,0,0,0}; unsigned long ss7delay=0; +byte ss8[] = {0,0,0,0,0,0}; unsigned long ss8delay=0; +byte ss9[] = {0,0,0,0,0,0}; unsigned long ss9delay=0; +byte ss10[] = {0,0,0,0,0,0}; unsigned long ss10delay=0; +bool playing_sound_set [ ] = {false,false,false,false,false,false,false,false,false,false,false}; +byte soundset_channel[ ]={0,0,0,0,0,0,0,0,0,0,0}; +const int MasterDecoderDisablePin = 16; // D16/A0 Master Decoder Disable Input Pin Active LOW + +const int numINpins = 11; // Number of INput pins to initialize +byte inputpins [] = {3,4,5,6,7,8,9,10,11,12,16}; //These are all the Input Pins +const int numfpins = 4; // Number of Output pins to initialize +const int num_active_functions = 12; // Number of Functions stating with F0 +byte fpins [] = {13,17,18,19}; //These are all the Output Pins (first 15 is placeholder) +const int FunctionPin0 = 20; // D14/A0 DFPlayer Transmit (TX) Pin 3 +const int FunctionPin1 = 20; // A2 LED +const int FunctionPin2 = 20; // A3 LED +const int FunctionPin3 = 20; // A4 LED +const int FunctionPin4 = 20; // A5 LED +const int FunctionPin5 = 20; // Turns on Motor2 DCC Function Control Only NO Local Input Pin +const int FunctionPin6 = 20; // Place holders ONLY +const int FunctionPin7 = 20; // Place holders ONLY +const int FunctionPin8 = 20; // Place holders ONLY +const int FunctionPin9 = 20; // Place holders ONLY +const int FunctionPin10 = 20; // Place holders ONLY +const int FunctionPin11 = 13; // Place holders ONLY +const int FunctionPin12 = 17; // Place holders ONLY +const int FunctionPin13 = 18; // Place holders ONLY +const int FunctionPin14 = 19; // Place holders ONLY +const int FunctionPin15 = 20; // Place holders ONLY +const int FunctionPin16 = 20; // Place holders ONLY +int MasterDecoderDisable = 0; +int Function0_value = 0; +byte function_value [ ] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +uint8_t cv_value; + +NmraDcc Dcc ; +DCC_MSG Packet ; +int t; // temp +struct QUEUE +{ + int inuse; + int current_position; + int increment; + int stop_value; + int start_value; +}; +QUEUE *ftn_queue = new QUEUE[17]; + +struct CVPair +{ + uint16_t CV; + uint8_t Value; +}; +CVPair FactoryDefaultCVs [] = +{ + {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address&0x7F }, + + // These two CVs define the Long DCC Address + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, ((This_Decoder_Address>>8)&0x7F)+192 }, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address&0xFF }, + + // ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS +// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps + {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps +// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps + {CV_DECODER_MASTER_RESET, 0}, + + {30, 0}, //F0 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + + {31, 1}, //F1 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {32, 2}, //F2 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {33, 3}, //F3 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {34, 4}, //F4 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {35, 5}, //F5 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {36, 6}, //F6 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {37, 7}, //F7 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {38, 8}, //F8 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {39, 9}, //F9 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {40, 10}, //F10 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + + {41, 11}, //F11 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {42, 11}, //F12 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {43, 11}, //F13 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {44, 11}, //F14Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {45, 22}, //F15 not used + + {50, 3}, // Wait1 0-254 0.1 Seconds // SOUND SET 1 + {51, 22}, // Volume1 0-30 >30 == no volume change + {52, 1}, // Sound Clip1 + {53, 6}, // Wait2 0-254 0.1 Seconds + {54, 22}, // Volume2 0-30 >30 == no volume change + {55, 2}, // Sound Clip2 + {56, 6}, // Wait3 0-254 0.1 Seconds + {57, 20}, // Volume3 0-30 >30 == no volume change + {58, 3}, // Sound Clip3 + {59, 6}, // Wait4 0-254 0.1 Seconds + {60, 15}, // Volume4 0-30 >30 == no volume change + {61, 11}, // Sound Clip4 + {62, 11}, // Wait5 0-254 0.1 Seconds + {63, 11}, // Volume5 0-30 >30 == no volume change + {64, 12}, // Sound Clip5 + {65, 0}, // Sound Set Channel == LSB 0/1 + + {66, 2}, // Wait1 0-254 0.1 Seconds // SOUND SET 2 + {67, 20}, // Volume1 0-30 >30 == no volume change + {68, 4}, // Sound Clip1 + {69, 6}, // Wait2 0-254 0.1 Seconds + {70, 20}, // Volume2 0-30 >30 == no volume change + {71, 5}, // Sound Clip2 + {72, 6}, // Wait3 0-254 0.1 Seconds + {73, 20}, // Volume3 0-30 >30 == no volume change + {74, 6}, // Sound Clip3 + {75, 6}, // Wait4 0-254 0.1 Seconds + {76, 20}, // Volume4 0-30 >30 == no volume change + {77, 7}, // Sound Clip4 + {78, 6}, // Wait5 0-254 0.1 Seconds + {79, 20}, // Volume5 0-30 >30 == no volume change + {80, 8}, // Sound Clip5 + {81, 1}, // Sound Set Channel == LSB 0/1 + + {82, 1}, // Wait1 0-254 0.1 Seconds // SOUND SET 3 + {83, 20}, // Volume1 0-30 >30 == no volume change + {84, 5}, // Sound Clip1 + {85, 6}, // Wait2 0-254 0.1 Seconds + {86, 20}, // Volume2 0-30 >30 == no volume change + {87, 6}, // Sound Clip2 + {88, 6}, // Wait3 0-254 0.1 Seconds + {89, 20}, // Volume3 0-30 >30 == no volume change + {90, 7}, // Sound Clip3 + {91, 6}, // Wait4 0-254 0.1 Seconds + {92, 20}, // Volume4 0-30 >30 == no volume change + {93, 8}, // Sound Clip4 + {94, 6}, // Wait5 0-254 0.1 Seconds + {95, 20}, // Volume5 0-30 >30 == no volume change + {96, 8}, // Sound Clip5 + {97, 0}, // Sound Set Channel == LSB 0/1 + + {98, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 4 + {99, 23}, // Volume1 0-30 >30 == no volume change + {100, 9}, // Sound Clip1 + {101,110}, // Wait2 0-254 0.1 Seconds + {102, 99}, // Volume2 0-30 >30 == no volume change + {103, 0}, // Sound Clip2 + {104, 0}, // Wait3 0-254 0.1 Seconds + {105, 20}, // Volume3 0-30 >30 == no volume change + {106, 0}, // Sound Clip3 + {107, 0}, // Wait4 0-254 0.1 Seconds + {108, 99}, // Volume4 0-30 >30 == no volume change + {109, 0}, // Sound Clip4 + {110, 0}, // Wait5 0-254 0.1 Seconds + {111, 99}, // Volume5 0-30 >30 == no volume change + {112, 0}, // Sound Clip5 + {113, 0}, // Sound Set Channel == LSB 0/1 + + {114, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 5 + {115, 20}, // Volume1 0-30 >30 == no volume change + {116, 1}, // Sound Clip1 + {117, 20}, // Wait2 0-254 0.1 Seconds + {118, 20}, // Volume2 0-30 >30 == no volume change + {119, 2}, // Sound Clip2 + {120, 30}, // Wait3 0-254 0.1 Seconds + {121, 20}, // Volume3 0-30 >30 == no volume change + {122, 3}, // Sound Clip3 + {123, 50}, // Wait4 0-254 0.1 Seconds + {124, 20}, // Volume4 0-30 >30 == no volume change + {125, 4}, // Sound Clip4 + {126, 100}, // Wait5 0-254 0.1 Seconds + {127, 20}, // Volume5 0-30 >30 == no volume change + {128, 5}, // Sound Clip5 + {129, 0}, // Sound Set Channel == LSB 0/1 + + {130, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 6 + {131, 20}, // Volume1 0-30 >30 == no volume change + {132, 1}, // Sound Clip1 + {133, 20}, // Wait2 0-254 0.1 Seconds + {134, 20}, // Volume2 0-30 >30 == no volume change + {135, 2}, // Sound Clip2 + {136, 30}, // Wait3 0-254 0.1 Seconds + {137, 20}, // Volume3 0-30 >30 == no volume change + {138, 3}, // Sound Clip3 + {139, 50}, // Wait4 0-254 0.1 Seconds + {140, 20}, // Volume4 0-30 >30 == no volume change + {141, 4}, // Sound Clip4 + {142, 100}, // Wait5 0-254 0.1 Seconds + {143, 20}, // Volume5 0-30 >30 == no volume change + {144, 5}, // Sound Clip5 + {145, 1}, // Sound Set Channel == LSB 0/1 + + {146, 10}, // Wait1 0-254 0.1 Seconds // SOUND SET 7 + {147, 29}, // Volume1 0-30 >30 == no volume change + {148, 1}, // Sound Clip1 + {149, 10}, // Wait2 0-254 0.1 Seconds + {150, 24}, // Volume2 0-30 >30 == no volume change + {151, 2}, // Sound Clip2 + {152, 10}, // Wait3 0-254 0.1 Seconds + {153, 18}, // Volume3 0-30 >30 == no volume change + {154, 3}, // Sound Clip3 + {155, 10}, // Wait4 0-254 0.1 Seconds + {156, 12}, // Volume4 0-30 >30 == no volume change + {157, 4}, // Sound Clip4 + {158, 10}, // Wait5 0-254 0.1 Seconds + {159, 6}, // Volume5 0-30 >30 == no volume change + {160, 5}, // Sound Clip5 + {161, 0}, // Sound Set Channel == LSB 0/1 + + {162, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 8 + {163, 20}, // Volume1 0-30 >30 == no volume change + {164, 1}, // Sound Clip1 + {165, 20}, // Wait2 0-254 0.1 Seconds + {166, 20}, // Volume2 0-30 >30 == no volume change + {167, 2}, // Sound Clip2 + {168, 30}, // Wait3 0-254 0.1 Seconds + {169, 20}, // Volume3 0-30 >30 == no volume change + {170, 3}, // Sound Clip3 + {171, 50}, // Wait4 0-254 0.1 Seconds + {172, 20}, // Volume4 0-30 >30 == no volume change + {173, 4}, // Sound Clip4 + {174, 100}, // Wait5 0-254 0.1 Seconds + {175, 20}, // Volume5 0-30 >30 == no volume change + {176, 5}, // Sound Clip5 + {177, 1}, // Sound Set Channel == LSB 0/1 + + {178, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 9 + {179, 20}, // Volume1 0-30 >30 == no volume change + {180, 255}, // Sound Clip1 + {181, 11}, // Wait2 0-254 0.1 Seconds + {182, 20}, // Volume2 0-30 >30 == no volume change + {183, 255}, // Sound Clip2 + {184, 11}, // Wait3 0-254 0.1 Seconds + {185, 20}, // Volume3 0-30 >30 == no volume change + {186, 255}, // Sound Clip3 + {187, 14}, // Wait4 0-254 0.1 Seconds + {188, 20}, // Volume4 0-30 >30 == no volume change + {189, 255}, // Sound Clip4 + {190, 14}, // Wait5 0-254 0.1 Seconds + {191, 20}, // Volume5 0-30 >30 == no volume change + {192, 255}, // Sound Clip5 + {193, 0}, // Sound Set Channel == LSB 0/1 + + {194, 4}, // Wait1 0-254 0.1 Seconds // SOUND SET 10 + {195, 20}, // Volume1 0-30 >30 == no volume change + {196, 10}, // Sound Clip1 + {197, 110}, // Wait2 0-254 0.1 Seconds + {198, 99}, // Volume2 0-30 >30 == no volume change + {199, 0}, // Sound Clip2 + {200, 4}, // Wait3 0-254 0.1 Seconds + {201, 99}, // Volume3 0-30 >30 == no volume change + {202, 0}, // Sound Clip3 + {203, 4}, // Wait4 0-254 0.1 Seconds + {204, 12}, // Volume4 0-30 >30 == no volume change + {205, 9}, // Sound Clip4 + {206, 100}, // Wait5 0-254 0.1 Seconds + {207, 99}, // Volume5 0-30 >30 == no volume change + {208, 0}, // Sound Clip5 + {209, 1}, // Sound Set Channel == LSB 0/1 + + //252,252 CV_DECODER_MASTER_RESET + + {253, 0}, // Extra +}; + +uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +void notifyCVResetFactoryDefault() +{ + // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset + // to flag to the loop() function that a reset to Factory Defaults needs to be done + FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +}; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS + +void setup() //****************************************************** +{ +#ifdef DEBUG + Serial.begin(115200); +#endif + DFSerial1.begin (9600); + DFSerial2.begin (9600); + Player1.begin (DFSerial1); + Player2.begin (DFSerial2); + + pinMode (MasterDecoderDisablePin,INPUT_PULLUP); // Master Decoder Disable Input Pin Active LOW + + // initialize the digital pins as outputs + for (int i=0; i < numfpins; i++) { + pinMode(fpins[i], OUTPUT); + digitalWrite(fpins[i], 0); // All OUPUT pins initialized LOW + } + // initialize the digital pins as inputs + for (int i=0; i < numINpins; i++) { + pinMode(inputpins[i], INPUT_PULLUP); + } + // Setup which External Interrupt, the Pin it's associated with that we're using + Dcc.pin(0, 2, 0); + // Call the main DCC Init function to enable the DCC Receiver + Dcc.init( MAN_ID_DIY, 61, FLAGS_MY_ADDRESS_ONLY, 0 ); + delay(800); +#if defined(DECODER_LOADED) + if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET ) +#endif + { + for (int j=0; j < FactoryDefaultCVIndex; j++ ) + Dcc.setCV( FactoryDefaultCVs[j].CV, FactoryDefaultCVs[j].Value); + } + // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; +#ifdef DEBUG + Serial.println("CV Dump:"); + for (i=30; i<45; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=30; i<45; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 1"); + for (i=50; i<66; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=50; i<66; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 2"); + for (i=66; i<82; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=66; i<82; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 3"); + for (i=82; i<98; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=82; i<98; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 4"); + for (i=98; i<114; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=98; i<114; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 5"); + for (i=114; i<130; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=114; i<130; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 6"); + for (i=130; i<146; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=130; i<146; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 7"); + for (i=146; i<162; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=146; i<162; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 8"); + for (i=162; i<178; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=162; i<178; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 9"); + for (i=178; i<194; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=178; i<194; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 10"); + for (i=194; i<210; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=194; i<210; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } +#endif +} // End setup +void loop() //*********************************************************************************** +{ + //MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation + Dcc.process(); + delay(1); +// INPUT OVER RIDES + // Check Master Input Over ride + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + else MasterDecoderDisable = Function0_value & 1; + if (MasterDecoderDisable == 1) { + for (i=0; i < numfpins; i++) digitalWrite(fpins[i], 0); // All LEDs set LOW + } +// ******************************************************************************** + if (MasterDecoderDisable == 0) { + for (i=0; i < num_active_functions; i++) { + cv_value = Dcc.getCV(30+i) ; +#ifdef DEBUG + //Serial.print(" cv_value: "); + //Serial.println(cv_value, DEC) ; +#endif + switch ( cv_value ) { + case 0: // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + break; + case 1: // + if (((digitalRead(3)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss1[0]=1; playing_sound_set[cv_value]=true; +#ifdef DEBUG + Serial.print(" cv_value: "); + Serial.println(cv_value, DEC) ; + Serial.print(" function_value[cv_value]: "); + Serial.println(function_value[cv_value], DEC) ; + Serial.print(" ss1[0]: "); + Serial.println(ss1[0], DEC) ; + Serial.print(" playing_sound_set[cv_value]: "); + Serial.println(playing_sound_set[cv_value], DEC) ; +#endif + } + break; + case 2: // + if (((digitalRead(4)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss2[0]=1; playing_sound_set[cv_value]=true; +#ifdef DEBUG + Serial.print(" cv_value: "); + Serial.println(cv_value, DEC) ; + Serial.print(" function_value[cv_value]: "); + Serial.println(function_value[cv_value], DEC) ; + Serial.print(" ss2[0]: "); + Serial.println(ss2[0], DEC) ; + Serial.print(" playing_sound_set[cv_value]: "); + Serial.println(playing_sound_set[cv_value], DEC) ; +#endif + } + + break; + case 3: // + if (((digitalRead(5)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss3[0]=1; playing_sound_set[cv_value]=true; } + break; + case 4: // + if (((digitalRead(6)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss4[0]=1; playing_sound_set[cv_value]=true; } + break; + case 5: // + if (((digitalRead(7)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss5[0]=1; playing_sound_set[cv_value]=true; } + break; + case 6: // + if (((digitalRead(8)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss6[0]=1; playing_sound_set[cv_value]=true; } + break; + case 7: // + if (((digitalRead(9)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss7[0]=1; playing_sound_set[cv_value]=true; } + break; + case 8: // + if (((digitalRead(10)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss8[0]=1; playing_sound_set[cv_value]=true; } + break; + case 9: // + if (((digitalRead(11)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss9[0]=1; playing_sound_set[cv_value]=true; } + break; + case 10: // + if (((digitalRead(12)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss10[0]=1; playing_sound_set[cv_value]=true; } + break; + case 11: // LEDs + break; + default: + break; + } + } + } + + // ========================== Sound Set 1 Begin Play + if (ss1[0]==1) { + ss1delay=millis()+(long(Dcc.getCV(50)*MasterTimeConstant)); // Wait1 + ss1[0]=0; ss1[1]=1; + soundset_channel[1]=Dcc.getCV(65); //load the channel in case it updated + } + if ((ss1[1]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(52)); +#ifdef DEBUG + Serial.print(" Here 1: "); + Serial.println(ttemp, DEC) ; +#endif + setVolumeOnChannel (Dcc.getCV(51),soundset_channel[1]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[1]); // play clip 1 + ss1delay=millis()+(long(Dcc.getCV(53)*MasterTimeConstant)); // Wait2 + ss1[1]=0; ss1[2]=1; + } + if ((ss1[2]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(55)); +#ifdef DEBUG + Serial.print(" Here 2: "); + Serial.println(ttemp, DEC) ; +#endif + setVolumeOnChannel (Dcc.getCV(54),soundset_channel[1]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[1]); // play clip 2 + ss1delay=millis()+(long(Dcc.getCV(56)*MasterTimeConstant)); // Wait3 + ss1[2]=0; ss1[3]=1; + } + if ((ss1[3]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(58)); +#ifdef DEBUG + Serial.print(" Here 3: "); + Serial.println(ttemp, DEC) ; +#endif + setVolumeOnChannel (Dcc.getCV(57),soundset_channel[1]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[1]); // play clip 3 + ss1delay=millis()+(long(Dcc.getCV(59)*MasterTimeConstant)); // Wait4 + ss1[3]=0; ss1[4]=1; + } + if ((ss1[4]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(61)); + setVolumeOnChannel (Dcc.getCV(60),soundset_channel[1]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[1]); // play clip 4 + ss1delay=millis()+(long(Dcc.getCV(62)*MasterTimeConstant)); // Wait5 + ss1[4]=0; ss1[5]=1; + } + if ((ss1[5]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(64)); + setVolumeOnChannel (Dcc.getCV(63),soundset_channel[1]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[1]); // play clip 5 + ss1[5]=0; playing_sound_set[1]=false; + } +// ========================== Sound Set 2 Begin Play + if (ss2[0]==1) { + ss2delay=millis()+(long(Dcc.getCV(66)*MasterTimeConstant)); // Wait1 + ss2[0]=0; ss2[1]=1; + soundset_channel[2]=Dcc.getCV(81); //load the channel in case it updated + } + if ((ss2[1]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(68)); + setVolumeOnChannel (Dcc.getCV(67),soundset_channel[2]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[2]); // play clip 1 + ss2delay=millis()+(long(Dcc.getCV(69)*MasterTimeConstant)); // Wait2 + ss2[1]=0; ss2[2]=1; + } + if ((ss2[2]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(71)); + setVolumeOnChannel (Dcc.getCV(70),soundset_channel[2]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[2]); // play clip 2 + ss2delay=millis()+(long(Dcc.getCV(72)*MasterTimeConstant)); // Wait3 + ss2[2]=0; ss2[3]=1; + } + if ((ss2[3]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(74)); + setVolumeOnChannel (Dcc.getCV(73),soundset_channel[2]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[2]); // play clip 3 + ss2delay=millis()+(long(Dcc.getCV(75)*MasterTimeConstant)); // Wait4 + ss2[3]=0; ss2[4]=1; + } + if ((ss2[4]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(77)); + setVolumeOnChannel (Dcc.getCV(76),soundset_channel[2]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[2]); // play clip 4 + ss2delay=millis()+(long(Dcc.getCV(78)*MasterTimeConstant)); // Wait5 + ss2[4]=0; ss2[5]=1; + } + if ((ss2[5]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(80)); + setVolumeOnChannel (Dcc.getCV(79),soundset_channel[2]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[2]); // play clip 5 + ss2[5]=0; playing_sound_set[2]=false; + } +// ========================== Sound Set 3 Begin Play + if (ss3[0]==1) { + ss3delay=millis()+(long(Dcc.getCV(82)*MasterTimeConstant)); // Wait1 + ss3[0]=0; ss3[1]=1; + soundset_channel[3]=Dcc.getCV(97); //load the channel in case it updated + } + if ((ss3[1]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(84)); + setVolumeOnChannel (Dcc.getCV(83),soundset_channel[3]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[3]); // play clip 1 + ss3delay=millis()+(long(Dcc.getCV(85)*MasterTimeConstant)); // Wait2 + ss3[1]=0; ss3[2]=1; + } + if ((ss3[2]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(87)); + setVolumeOnChannel (Dcc.getCV(86),soundset_channel[3]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[3]); // play clip 2 + ss3delay=millis()+(long(Dcc.getCV(88)*MasterTimeConstant)); // Wait3 + ss3[2]=0; ss3[3]=1; + } + if ((ss3[3]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(90)); + setVolumeOnChannel (Dcc.getCV(89),soundset_channel[3]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[3]); // play clip 3 + ss3delay=millis()+(long(Dcc.getCV(91)*MasterTimeConstant)); // Wait4 + ss3[3]=0; ss3[4]=1; + } + if ((ss3[4]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(93)); + setVolumeOnChannel (Dcc.getCV(92),soundset_channel[3]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[3]); // play clip 4 + ss3delay=millis()+(long(Dcc.getCV(94)*MasterTimeConstant)); // Wait5 + ss3[4]=0; ss3[5]=1; + } + if ((ss3[5]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(96)); + setVolumeOnChannel (Dcc.getCV(95),soundset_channel[3]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[3]); // play clip 5 + ss3[5]=0; playing_sound_set[3]=false; + } +// ========================== Sound Set 4 Begin Play + if (ss4[0]==1) { + ss4delay=millis()+(long(Dcc.getCV(98)*MasterTimeConstant)); // Wait1 + ss4[0]=0; ss4[1]=1; + soundset_channel[4]=Dcc.getCV(113); //load the channel in case it updated + } + if ((ss4[1]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(100)); + setVolumeOnChannel (Dcc.getCV(99),soundset_channel[4]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[4]); // play clip 1 + ss4delay=millis()+(long(Dcc.getCV(101)*MasterTimeConstant)); // Wait2 + ss4[1]=0; ss4[2]=1; + } + if ((ss4[2]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(103)); + setVolumeOnChannel (Dcc.getCV(102),soundset_channel[4]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[4]); // play clip 2 + ss4delay=millis()+(long(Dcc.getCV(104)*MasterTimeConstant)); // Wait3 + ss4[2]=0; ss4[3]=1; + } + if ((ss4[3]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(106)); + setVolumeOnChannel (Dcc.getCV(105),soundset_channel[4]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[4]); // play clip 3 + ss4delay=millis()+(long(Dcc.getCV(107)*MasterTimeConstant)); // Wait4 + ss4[3]=0; ss4[4]=1; + } + if ((ss4[4]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(109)); + setVolumeOnChannel (Dcc.getCV(108),soundset_channel[4]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[4]); // play clip 4 + ss4delay=millis()+(long(Dcc.getCV(110)*MasterTimeConstant)); // Wait5 + ss4[4]=0; ss4[5]=1; + } + if ((ss4[5]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(112)); + setVolumeOnChannel (Dcc.getCV(111),soundset_channel[4]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[4]); // play clip 5 + ss4[5]=0; playing_sound_set[4]=false; + } +// ========================== Sound Set 5 Begin Play + if (ss5[0]==1) { + ss5delay=millis()+(long(Dcc.getCV(114)*MasterTimeConstant)); // Wait1 + ss5[0]=0; ss5[1]=1; + soundset_channel[5]=Dcc.getCV(129); //load the channel in case it updated + } + if ((ss5[1]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(116)); + setVolumeOnChannel (Dcc.getCV(115),soundset_channel[5]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[5]); // play clip 1 + ss5delay=millis()+(long(Dcc.getCV(117)*MasterTimeConstant)); // Wait2 + ss5[1]=0; ss5[2]=1; + } + if ((ss5[2]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(119)); + setVolumeOnChannel (Dcc.getCV(118),soundset_channel[5]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[5]); // play clip 2 + ss5delay=millis()+(long(Dcc.getCV(120)*MasterTimeConstant)); // Wait3 + ss5[2]=0; ss5[3]=1; + } + if ((ss5[3]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(122)); + setVolumeOnChannel (Dcc.getCV(121),soundset_channel[5]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[5]); // play clip 3 + ss5delay=millis()+(long(Dcc.getCV(123)*MasterTimeConstant)); // Wait4 + ss5[3]=0; ss5[4]=1; + } + if ((ss5[4]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(125)); + setVolumeOnChannel (Dcc.getCV(124),soundset_channel[5]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[5]); // play clip 4 + ss5delay=millis()+(long(Dcc.getCV(126)*MasterTimeConstant)); // Wait5 + ss5[4]=0; ss5[5]=1; + } + if ((ss5[5]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(128)); + setVolumeOnChannel (Dcc.getCV(127),soundset_channel[5]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[5]); // play clip 5 + ss5[5]=0; playing_sound_set[5]=false; + } + +// ========================== Sound Set 6 Begin Play + if (ss6[0]==1) { + ss6delay=millis()+(long(Dcc.getCV(130)*MasterTimeConstant)); // Wait1 + ss6[0]=0; ss6[1]=1; + soundset_channel[6]=Dcc.getCV(145); //load the channel in case it updated + } + if ((ss6[1]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(132)); + setVolumeOnChannel (Dcc.getCV(131),soundset_channel[6]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[6]); // play clip 1 + ss6delay=millis()+(long(Dcc.getCV(133)*MasterTimeConstant)); // Wait2 + ss6[1]=0; ss6[2]=1; + } + if ((ss6[2]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(135)); + setVolumeOnChannel (Dcc.getCV(134),soundset_channel[6]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[6]); // play clip 2 + ss6delay=millis()+(long(Dcc.getCV(136)*MasterTimeConstant)); // Wait3 + ss6[2]=0; ss6[3]=1; + } + if ((ss6[3]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(138)); + setVolumeOnChannel (Dcc.getCV(137),soundset_channel[6]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[6]); // play clip 3 + ss6delay=millis()+(long(Dcc.getCV(139)*MasterTimeConstant)); // Wait4 + ss6[3]=0; ss6[4]=1; + } + if ((ss6[4]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(141)); + setVolumeOnChannel (Dcc.getCV(140),soundset_channel[6]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[6]); // play clip 4 + ss6delay=millis()+(long(Dcc.getCV(142)*MasterTimeConstant)); // Wait5 + ss6[4]=0; ss6[5]=1; + } + if ((ss6[5]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(144)); + setVolumeOnChannel (Dcc.getCV(143),soundset_channel[6]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[6]); // play clip 5 + ss6[5]=0; playing_sound_set[6]=false; + } + +// ========================== Sound Set 7 Begin Play + if (ss7[0]==1) { + ss7delay=millis()+(long(Dcc.getCV(146)*MasterTimeConstant)); // Wait1 + ss7[0]=0; ss7[1]=1; + soundset_channel[7]=Dcc.getCV(161); //load the channel in case it updated + } + if ((ss7[1]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(148)); + setVolumeOnChannel (Dcc.getCV(147),soundset_channel[7]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[7]); // play clip 1 + ss7delay=millis()+(long(Dcc.getCV(149)*MasterTimeConstant)); // Wait2 + ss7[1]=0; ss7[2]=1; + } + if ((ss7[2]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(151)); + setVolumeOnChannel (Dcc.getCV(150),soundset_channel[7]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[7]); // play clip 2 + ss7delay=millis()+(long(Dcc.getCV(152)*MasterTimeConstant)); // Wait3 + ss7[2]=0; ss7[3]=1; + } + if ((ss7[3]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(154)); + setVolumeOnChannel (Dcc.getCV(153),soundset_channel[7]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[7]); // play clip 3 + ss7delay=millis()+(long(Dcc.getCV(155)*MasterTimeConstant)); // Wait4 + ss7[3]=0; ss7[4]=1; + } + if ((ss7[4]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(157)); + setVolumeOnChannel (Dcc.getCV(156),soundset_channel[7]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[7]); // play clip 4 + ss7delay=millis()+(long(Dcc.getCV(158)*MasterTimeConstant)); // Wait5 + ss7[4]=0; ss7[5]=1; + } + if ((ss7[5]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(160)); + setVolumeOnChannel (Dcc.getCV(159),soundset_channel[7]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[7]); // play clip 5 + ss7[5]=0; playing_sound_set[7]=false; + } +// ========================== Sound Set 8 Begin Play + if (ss8[0]==1) { + ss8delay=millis()+(long(Dcc.getCV(162)*MasterTimeConstant)); // Wait1 + ss8[0]=0; ss8[1]=1; + soundset_channel[8]=Dcc.getCV(177); //load the channel in case it updated + } + if ((ss8[1]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(164)); + setVolumeOnChannel (Dcc.getCV(163),soundset_channel[8]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[8]); // play clip 1 + ss8delay=millis()+(long(Dcc.getCV(165)*MasterTimeConstant)); // Wait2 + ss8[1]=0; ss8[2]=1; + } + if ((ss8[2]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(167)); + setVolumeOnChannel (Dcc.getCV(166),soundset_channel[8]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[8]); // play clip 2 + ss8delay=millis()+(long(Dcc.getCV(168)*MasterTimeConstant)); // Wait3 + ss8[2]=0; ss8[3]=1; + } + if ((ss8[3]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(170)); + setVolumeOnChannel (Dcc.getCV(169),soundset_channel[8]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[8]); // play clip 3 + ss8delay=millis()+(long(Dcc.getCV(171)*MasterTimeConstant)); // Wait4 + ss8[3]=0; ss8[4]=1; + } + if ((ss8[4]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(173)); + setVolumeOnChannel (Dcc.getCV(172),soundset_channel[8]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[8]); // play clip 4 + ss8delay=millis()+(long(Dcc.getCV(174)*MasterTimeConstant)); // Wait5 + ss8[4]=0; ss8[5]=1; + } + if ((ss8[5]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(176)); + setVolumeOnChannel (Dcc.getCV(175),soundset_channel[8]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[8]); // play clip 5 + ss8[5]=0; playing_sound_set[8]=false; + } +// ========================== Sound Set 9 Begin Play + if (ss9[0]==1) { + ss9delay=millis()+(long(Dcc.getCV(178)*MasterTimeConstant)); // Wait1 + ss9[0]=0; ss9[1]=1; + soundset_channel[9]=Dcc.getCV(193); //load the channel in case it updated + } + if ((ss9[1]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(180)); + setVolumeOnChannel (Dcc.getCV(179),soundset_channel[9]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[9]); // play clip 1 + ss9delay=millis()+(long(Dcc.getCV(181)*MasterTimeConstant)); // Wait2 + ss9[1]=0; ss9[2]=1; + } + if ((ss9[2]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(183)); + setVolumeOnChannel (Dcc.getCV(182),soundset_channel[9]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[9]); // play clip 2 + ss9delay=millis()+(long(Dcc.getCV(184)*MasterTimeConstant)); // Wait3 + ss9[2]=0; ss9[3]=1; + } + if ((ss9[3]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(186)); + setVolumeOnChannel (Dcc.getCV(185),soundset_channel[9]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[9]); // play clip 3 + ss9delay=millis()+(long(Dcc.getCV(187)*MasterTimeConstant)); // Wait4 + ss9[3]=0; ss9[4]=1; + } + if ((ss9[4]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(189)); + setVolumeOnChannel (Dcc.getCV(188),soundset_channel[9]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[9]); // play clip 4 + ss9delay=millis()+(long(Dcc.getCV(190)*MasterTimeConstant)); // Wait5 + ss9[4]=0; ss9[5]=1; + } + if ((ss9[5]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(192)); + setVolumeOnChannel (Dcc.getCV(191),soundset_channel[9]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[9]); // play clip 5 + ss9[5]=0; playing_sound_set[9]=false; + } +// ========================== Sound Set 10 Begin Play + if (ss10[0]==1) { + ss10delay=millis()+(long(Dcc.getCV(194)*MasterTimeConstant)); // Wait1 + ss10[0]=0; ss10[1]=1; + soundset_channel[10]=Dcc.getCV(209); //load the channel in case it updated + } + if ((ss10[1]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(196)); + setVolumeOnChannel (Dcc.getCV(195),soundset_channel[10]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[10]); // play clip 1 + ss10delay=millis()+(long(Dcc.getCV(197)*MasterTimeConstant)); // Wait2 + ss10[1]=0; ss10[2]=1; + } + if ((ss10[2]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(199)); + setVolumeOnChannel (Dcc.getCV(198),soundset_channel[10]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[10]); // play clip 2 + ss10delay=millis()+(long(Dcc.getCV(200)*MasterTimeConstant)); // Wait3 + ss10[2]=0; ss10[3]=1; + } + if ((ss10[3]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(202)); + setVolumeOnChannel (Dcc.getCV(201),soundset_channel[10]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[10]); // play clip 3 + ss10delay=millis()+(long(Dcc.getCV(203)*MasterTimeConstant)); // Wait4 + ss10[3]=0; ss10[4]=1; + } + if ((ss10[4]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(205)); + setVolumeOnChannel (Dcc.getCV(204),soundset_channel[10]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[10]); // play clip 4 + ss10delay=millis()+(long(Dcc.getCV(206)*MasterTimeConstant)); // Wait5 + ss10[4]=0; ss10[5]=1; + } + if ((ss10[5]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(208)); + setVolumeOnChannel (Dcc.getCV(207),soundset_channel[10]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[10]); // play clip 5 + ss10[5]=0; playing_sound_set[10]=false; + } +} // end loop() + +void playTrackOnChannel ( byte dtrack, byte dchannel) { + switch ( dchannel ) { + case 0: + //DFSerial1.listen(); + if (dtrack!=255) {Player1.play(dtrack); delay(audiocmddelay); } + else {Player1.play(random(First_Track,Last_Track+1)); delay(audiocmddelay); } + break; + case 1: + default: + //DFSerial2.listen(); + if (dtrack!=255) {Player2.play(dtrack); delay(audiocmddelay); } + else {Player2.play(random(First_Track,Last_Track+1)); delay(audiocmddelay); } + break; + } +} +void setVolumeOnChannel ( byte dvolume, byte dchannel) { + if(dvolume>30) return; // Don't change the volume if out of range + switch ( dchannel ) { + case 0: + Player1.volume (dvolume); + delay(audiocmddelay); + break; + case 1: + default: + Player2.volume (dvolume); + delay(audiocmddelay); + break; + } +} +void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { +#ifdef DEBUG + //Serial.print("Addr= "); + //Serial.println(Addr, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch(FuncGrp) + { + case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1 + exec_function( 0, FunctionPin0, (FuncState & FN_BIT_00)>>4 ); + exec_function( 1, FunctionPin1, (FuncState & FN_BIT_01)); + exec_function( 2, FunctionPin2, (FuncState & FN_BIT_02)>>1); + exec_function( 3, FunctionPin3, (FuncState & FN_BIT_03)>>2 ); + exec_function( 4, FunctionPin4, (FuncState & FN_BIT_04)>>3 ); + break; + case FN_5_8: //Function Group 1 S FFFF == 1 F8 F7 F6 F5 & == 0 F12 F11 F10 F9 F8 + exec_function( 5, FunctionPin5, (FuncState & FN_BIT_05)); + exec_function( 6, FunctionPin6, (FuncState & FN_BIT_06)>>1 ); + exec_function( 7, FunctionPin7, (FuncState & FN_BIT_07)>>2 ); + exec_function( 8, FunctionPin8, (FuncState & FN_BIT_08)>>3 ); + break; + + case FN_9_12: + exec_function( 9, FunctionPin9, (FuncState & FN_BIT_09)); + exec_function( 10, FunctionPin10, (FuncState & FN_BIT_10)>>1 ); + exec_function( 11, FunctionPin11, (FuncState & FN_BIT_11)>>2 ); + exec_function( 12, FunctionPin12, (FuncState & FN_BIT_12)>>3 ); + break; + case FN_13_20: //Function Group 2 FuncState == F20-F13 Function Control + exec_function( 13, FunctionPin13, (FuncState & FN_BIT_13)); + exec_function( 14, FunctionPin14, (FuncState & FN_BIT_14)>>1 ); + //exec_function( 15, FunctionPin15, (FuncState & FN_BIT_15)>>2 ); + //exec_function( 16, FunctionPin16, (FuncState & FN_BIT_16)>>3 ); + break; + + case FN_21_28: + break; + } +} // end notifyDccFunc +void exec_function (int function, int pin, int FuncState) { +#ifdef DEBUG + //Serial.print("ex function= "); + //Serial.println(function, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch ( Dcc.getCV( 30+function) ) { // Config + case 0: // Master Disable + Function0_value = byte(FuncState); + break; + case 1: // play sound set [ function ] + + case 2: // play sound set [ function ] + + case 3: // play sound set [ function ] + + case 4: // play sound set [ function ] + + case 5: // play sound set [ function ] + + case 6: // play sound set [ function ] + + case 7: // play sound set [ function ] + + case 8: // play sound set [ function ] + + case 9: // play sound set [ function ] + + case 10: // play sound set [ function ] + function_value[function] = byte(FuncState); + break; + case 11: // On - Off LED + if (MasterDecoderDisable == 0) digitalWrite (pin, FuncState); + else digitalWrite (pin, 0); // Master Disable is ON so force LEDs off + break; + default: + break;; + } +} // end exec_function + +/* DFPlayer Commands +//----Set volume---- + myDFPlayer.volume(10); //Set volume value (0~30). + myDFPlayer.volumeUp(); //Volume Up + myDFPlayer.volumeDown(); //Volume Down + //----Set different EQ---- + myDFPlayer.EQ(DFPLAYER_EQ_NORMAL); +// myDFPlayer.EQ(DFPLAYER_EQ_POP); +// myDFPlayer.EQ(DFPLAYER_EQ_ROCK); +// myDFPlayer.EQ(DFPLAYER_EQ_JAZZ); +// myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC); +// myDFPlayer.EQ(DFPLAYER_EQ_BASS); + //----Set device we use SD as default---- +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_U_DISK); + myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_AUX); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_SLEEP); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_FLASH); + //----Mp3 control---- +// myDFPlayer.sleep(); //sleep +// myDFPlayer.reset(); //Reset the module +// myDFPlayer.enableDAC(); //Enable On-chip DAC +// myDFPlayer.disableDAC(); //Disable On-chip DAC +// myDFPlayer.outputSetting(true, 15); //output setting, enable the output and set the gain to 15 + //----Mp3 play---- + myDFPlayer.next(); //Play next mp3 + myDFPlayer.previous(); //Play previous mp3 + myDFPlayer.play(1); //Play the first mp3 + myDFPlayer.loop(1); //Loop the first mp3 + myDFPlayer.pause(); //pause the mp3 + myDFPlayer.start(); //start the mp3 from the pause + myDFPlayer.playFolder(15, 4); //play specific mp3 in SD:/15/004.mp3; Folder Name(1~99); File Name(1~255) + myDFPlayer.enableLoopAll(); //loop all mp3 files. + myDFPlayer.disableLoopAll(); //stop loop all mp3 files. + myDFPlayer.playMp3Folder(4); //play specific mp3 in SD:/MP3/0004.mp3; File Name(0~65535) + myDFPlayer.advertise(3); //advertise specific mp3 in SD:/ADVERT/0003.mp3; File Name(0~65535) + myDFPlayer.stopAdvertise(); //stop advertise + myDFPlayer.playLargeFolder(2, 999); //play specific mp3 in SD:/02/004.mp3; Folder Name(1~10); File Name(1~1000) + myDFPlayer.loopFolder(5); //loop all mp3 files in folder SD:/05. + myDFPlayer.randomAll(); //Random play all the mp3. + myDFPlayer.enableLoop(); //enable loop. + myDFPlayer.disableLoop(); //disable loop. +*/ diff --git a/examples/IDEC/IDEC3_3_4SoundPlyrs/IDEC3_3_4SoundPlyrs.ino b/examples/IDEC/IDEC3_3_4SoundPlyrs/IDEC3_3_4SoundPlyrs.ino new file mode 100644 index 0000000..13c7cee --- /dev/null +++ b/examples/IDEC/IDEC3_3_4SoundPlyrs/IDEC3_3_4SoundPlyrs.ino @@ -0,0 +1,1148 @@ +// Interactive Decoder Sounds and Lights 4 Sound Players IDEC3_3_4SoundPlyrs.ino +// Version 1.08 Geoff Bunza 2020 +// Works with both short and long DCC Addesses +// This decoder will control Sound Sequences and LEDs +// F0=Master Function OFF = Function ON DISABLES the decoder +// Input Pin for Decoder Disable Pin 16/A2 Active LOW +//Functions for lights on/off: +// F11-F14 Four Functions LED ON/OFF by default PINS 13,16,17,18,19 +/* + * Pro Mini D11 A0 (TX) connected to DFPlayer4 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor + * Pro Mini D12 A1 (TX) connected to DFPlayer3 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor + * Pro Mini D14 A0 (TX) connected to DFPlayer2 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor + * Pro Mini D15 A1 (TX) connected to DFPlayer1 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor + * Remember to connect +5V and GND to the DFPlayer too: DFPLAYER PINS 1 & 7 respectively + * This is a “mobile/function” decoder with audio play to dual motor control and + * LED functions. Audio tracks or clips are stored on a micro SD card for playing, + in a folder labeled mp3, with tracks named 0001.mp3, 0002.mp3, etc. + * Up to 10 Sound Sets can be defined (and programmed via CVs) each sound set consists of: + delay1,volume1,sound clip1,delay2,volume2,sound clip2,delay3,volume3,sound clip3,delay4,volume4,sound clip4,delay5,volume5,sound clip5,PlayerCnannel (0-3) -- Timing of playing the sound set is completely independent of other sound sets and can occur simultaneously + If a sound clip/track is started while another clp/track is playing on the same player channel, the newly starting clip/track + will take precedence, with its associated volume setting + * Delay set to zero will offer NO delay time + * Volume set to >30 will not change current volume setting + * Track set to 0 will skip playing a track -- delay and volume set can be set to 0 and >30 to ignore operation too, + otherwise delay and volume are executed normally + * Track set to 255 will select a random track to play from number First_Track to Last_Track INCLUSIVE + * F0 is configured as Master Decoder Disable Override ON==Disable Decoder + * F1-F10 plays an audio set (1-10) defined by CVs + * MAX one of 12 Configurations per pin function: + * Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + * F0 Master Decoder Disable + * F1-F10 Play Sound Set 1-10 + * F11-F14 Functions LED ON/OFF + * Both F1-F10 set ON or the appropriate Input Pin 3-10 held LOW will repeat play the associated sound set + until BOTH the respective DCC function goes OFF AND the respective Input Pin goes HIGH + * ONLY F9 and F10 can activate Sound sets 9 and 10 respectively + +PRO MINI PIN ASSIGNMENT: +2 - DCC Input +3 - Input Pin Play Sound Set1 +4 - Input Pin Play Sound Set2 +5 - Input Pin Play Sound Set3 +6 - Input Pin Play Sound Set4 +7 - Input Pin Play Sound Set5 +8 - Input Pin Play Sound Set6 +9 - Input Pin Play Sound Set7 +10 - Input Pin Play Sound Set8 +11 - DFPlayer4 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor +12 - DFPlayer3 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor +13 - LED F1 +14 A0 - DFPlayer2 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor +15 A1 - DFPlayer1 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor +16 A2 - Input Pin for MasterDecoderDisable Active LOW +17 A3 - LED F2 +18 A4 - LED F3 +19 A5 - LED F4 +*/ +// ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP +// ******** AFTER THE INITIAL DECODER LOAD REMOVE THE "//" IN THE FOOLOWING LINE!! +//#define DECODER_LOADED + +// ******** EMOVE THE "//" IN THE FOOLOWING LINE TO SEND DEBUGGING +// ******** INFO TO THE SERIAL MONITOR +//#define DEBUG + +#include +#include +#include +SoftwareSerial DFSerial1(21,15); // PRO MINI RX, PRO MINI TX serial to DFPlayer +SoftwareSerial DFSerial2(22,14); // PRO MINI RX, PRO MINI TX serial to DFPlayer +SoftwareSerial DFSerial3(22,12); // PRO MINI RX, PRO MINI TX serial to DFPlayer +SoftwareSerial DFSerial4(22,11); // PRO MINI RX, PRO MINI TX serial to DFPlayer +DFRobotDFPlayerMini Player1; +DFRobotDFPlayerMini Player2; +DFRobotDFPlayerMini Player3; +DFRobotDFPlayerMini Player4; + +#define This_Decoder_Address 24 +uint8_t CV_DECODER_MASTER_RESET = 252; + +//Uncomment ONLY ONE of the following: +//#define MasterTimeConstant 10L // 10's of milliseconds Timing +#define MasterTimeConstant 100L // Tenths of a second Timing +//#define MasterTimeConstant 1000L // Seconds Timing +//#define MasterTimeConstant 10000L // 10's of Seconds Timing +//#define MasterTimeConstant 60000L // Minutes Timing +//#define MasterTimeConstant 3600000L // Hours Timing + +unsigned long estop = 1; +int del_tim = 4000; +uint16_t ttemp, i; +#define First_Track 1 // Play Random Tracks First_Track#=Start_Track >=1 +#define Last_Track 12 // Play Random Tracks Last_Track= Last Playable Track in Range <= Last Numbered Track +const int audiocmddelay = 34; +byte ss1[] = {0,0,0,0,0,0}; unsigned long ss1delay=0; +byte ss2[] = {0,0,0,0,0,0}; unsigned long ss2delay=0; +byte ss3[] = {0,0,0,0,0,0}; unsigned long ss3delay=0; +byte ss4[] = {0,0,0,0,0,0}; unsigned long ss4delay=0; +byte ss5[] = {0,0,0,0,0,0}; unsigned long ss5delay=0; +byte ss6[] = {0,0,0,0,0,0}; unsigned long ss6delay=0; +byte ss7[] = {0,0,0,0,0,0}; unsigned long ss7delay=0; +byte ss8[] = {0,0,0,0,0,0}; unsigned long ss8delay=0; +byte ss9[] = {0,0,0,0,0,0}; unsigned long ss9delay=0; +byte ss10[] = {0,0,0,0,0,0}; unsigned long ss10delay=0; +bool playing_sound_set [ ] = {false,false,false,false,false,false,false,false,false,false,false}; +byte soundset_channel[ ]={0,0,0,0,0,0,0,0,0,0,0}; +const int MasterDecoderDisablePin = 16; // D16/A0 Master Decoder Disable Input Pin Active LOW + +const int numINpins = 9; // Number of INput pins to initialize +byte inputpins [] = {3,4,5,6,7,8,9,10,16}; //These are all the Input Pins +const int numfpins = 4; // Number of Output pins to initialize +const int num_active_functions = 13; // Number of Functions stating with F0 +byte fpins [] = {13,17,18,19}; //These are all the Output Pins (first 15 is placeholder) +const int FunctionPin0 = 20; // D14/A0 DFPlayer Transmit (TX) Pin 3 +const int FunctionPin1 = 20; // A2 LED +const int FunctionPin2 = 20; // A3 LED +const int FunctionPin3 = 20; // A4 LED +const int FunctionPin4 = 20; // A5 LED +const int FunctionPin5 = 20; // Turns on Motor2 DCC Function Control Only NO Local Input Pin +const int FunctionPin6 = 20; // Place holders ONLY +const int FunctionPin7 = 20; // Place holders ONLY +const int FunctionPin8 = 20; // Place holders ONLY +const int FunctionPin9 = 20; // Place holders ONLY +const int FunctionPin10 = 20; // Place holders ONLY +const int FunctionPin11 = 13; // Place holders ONLY +const int FunctionPin12 = 17; // Place holders ONLY +const int FunctionPin13 = 18; // Place holders ONLY +const int FunctionPin14 = 19; // Place holders ONLY +const int FunctionPin15 = 20; // Place holders ONLY +const int FunctionPin16 = 20; // Place holders ONLY +int MasterDecoderDisable = 0; +int Function0_value = 0; +byte function_value [ ] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +uint8_t cv_value; + +NmraDcc Dcc ; +DCC_MSG Packet ; +int t; // temp +struct QUEUE +{ + int inuse; + int current_position; + int increment; + int stop_value; + int start_value; +}; +QUEUE *ftn_queue = new QUEUE[17]; + +struct CVPair +{ + uint16_t CV; + uint8_t Value; +}; +CVPair FactoryDefaultCVs [] = +{ + {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address&0x7F }, + + // These two CVs define the Long DCC Address + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, ((This_Decoder_Address>>8)&0x7F)+192 }, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address&0xFF }, + + // ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS +// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps + {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps +// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps + {CV_DECODER_MASTER_RESET, 0}, + + {30, 0}, //F0 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + + {31, 1}, //F1 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {32, 2}, //F2 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {33, 3}, //F3 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {34, 4}, //F4 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {35, 5}, //F5 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {36, 6}, //F6 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {37, 7}, //F7 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {38, 8}, //F8 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {39, 9}, //F9 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {40, 10}, //F10 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + + {41, 11}, //F11 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {42, 11}, //F12 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {43, 11}, //F13 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {44, 11}, //F14Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {45, 22}, //F15 not used + + {50, 3}, // Wait1 0-254 0.1 Seconds // SOUND SET 1 + {51, 22}, // Volume1 0-30 >30 == no volume change + {52, 1}, // Sound Clip1 + {53, 6}, // Wait2 0-254 0.1 Seconds + {54, 22}, // Volume2 0-30 >30 == no volume change + {55, 2}, // Sound Clip2 + {56, 6}, // Wait3 0-254 0.1 Seconds + {57, 20}, // Volume3 0-30 >30 == no volume change + {58, 3}, // Sound Clip3 + {59, 6}, // Wait4 0-254 0.1 Seconds + {60, 15}, // Volume4 0-30 >30 == no volume change + {61, 11}, // Sound Clip4 + {62, 11}, // Wait5 0-254 0.1 Seconds + {63, 11}, // Volume5 0-30 >30 == no volume change + {64, 12}, // Sound Clip5 + {65, 0}, // Sound Set Channel == LSB 0/1 + + {66, 2}, // Wait1 0-254 0.1 Seconds // SOUND SET 2 + {67, 20}, // Volume1 0-30 >30 == no volume change + {68, 4}, // Sound Clip1 + {69, 6}, // Wait2 0-254 0.1 Seconds + {70, 20}, // Volume2 0-30 >30 == no volume change + {71, 5}, // Sound Clip2 + {72, 6}, // Wait3 0-254 0.1 Seconds + {73, 20}, // Volume3 0-30 >30 == no volume change + {74, 6}, // Sound Clip3 + {75, 6}, // Wait4 0-254 0.1 Seconds + {76, 20}, // Volume4 0-30 >30 == no volume change + {77, 7}, // Sound Clip4 + {78, 6}, // Wait5 0-254 0.1 Seconds + {79, 20}, // Volume5 0-30 >30 == no volume change + {80, 8}, // Sound Clip5 + {81, 1}, // Sound Set Channel == LSB 0/1 + + {82, 1}, // Wait1 0-254 0.1 Seconds // SOUND SET 3 + {83, 20}, // Volume1 0-30 >30 == no volume change + {84, 5}, // Sound Clip1 + {85, 6}, // Wait2 0-254 0.1 Seconds + {86, 20}, // Volume2 0-30 >30 == no volume change + {87, 6}, // Sound Clip2 + {88, 6}, // Wait3 0-254 0.1 Seconds + {89, 20}, // Volume3 0-30 >30 == no volume change + {90, 7}, // Sound Clip3 + {91, 6}, // Wait4 0-254 0.1 Seconds + {92, 20}, // Volume4 0-30 >30 == no volume change + {93, 8}, // Sound Clip4 + {94, 6}, // Wait5 0-254 0.1 Seconds + {95, 20}, // Volume5 0-30 >30 == no volume change + {96, 8}, // Sound Clip5 + {97, 2}, // Sound Set Channel == LSB 0/1 + + {98, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 4 + {99, 23}, // Volume1 0-30 >30 == no volume change + {100, 9}, // Sound Clip1 + {101,110}, // Wait2 0-254 0.1 Seconds + {102, 99}, // Volume2 0-30 >30 == no volume change + {103, 0}, // Sound Clip2 + {104, 0}, // Wait3 0-254 0.1 Seconds + {105, 20}, // Volume3 0-30 >30 == no volume change + {106, 0}, // Sound Clip3 + {107, 0}, // Wait4 0-254 0.1 Seconds + {108, 99}, // Volume4 0-30 >30 == no volume change + {109, 0}, // Sound Clip4 + {110, 0}, // Wait5 0-254 0.1 Seconds + {111, 99}, // Volume5 0-30 >30 == no volume change + {112, 0}, // Sound Clip5 + {113, 3}, // Sound Set Channel == LSB 0/1 + + {114, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 5 + {115, 20}, // Volume1 0-30 >30 == no volume change + {116, 1}, // Sound Clip1 + {117, 20}, // Wait2 0-254 0.1 Seconds + {118, 20}, // Volume2 0-30 >30 == no volume change + {119, 2}, // Sound Clip2 + {120, 30}, // Wait3 0-254 0.1 Seconds + {121, 20}, // Volume3 0-30 >30 == no volume change + {122, 3}, // Sound Clip3 + {123, 50}, // Wait4 0-254 0.1 Seconds + {124, 20}, // Volume4 0-30 >30 == no volume change + {125, 4}, // Sound Clip4 + {126, 100}, // Wait5 0-254 0.1 Seconds + {127, 20}, // Volume5 0-30 >30 == no volume change + {128, 5}, // Sound Clip5 + {129, 0}, // Sound Set Channel == LSB 0/1 + + {130, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 6 + {131, 20}, // Volume1 0-30 >30 == no volume change + {132, 1}, // Sound Clip1 + {133, 20}, // Wait2 0-254 0.1 Seconds + {134, 20}, // Volume2 0-30 >30 == no volume change + {135, 2}, // Sound Clip2 + {136, 30}, // Wait3 0-254 0.1 Seconds + {137, 20}, // Volume3 0-30 >30 == no volume change + {138, 3}, // Sound Clip3 + {139, 50}, // Wait4 0-254 0.1 Seconds + {140, 20}, // Volume4 0-30 >30 == no volume change + {141, 4}, // Sound Clip4 + {142, 100}, // Wait5 0-254 0.1 Seconds + {143, 20}, // Volume5 0-30 >30 == no volume change + {144, 5}, // Sound Clip5 + {145, 1}, // Sound Set Channel == LSB 0/1 + + {146, 10}, // Wait1 0-254 0.1 Seconds // SOUND SET 7 + {147, 29}, // Volume1 0-30 >30 == no volume change + {148, 1}, // Sound Clip1 + {149, 10}, // Wait2 0-254 0.1 Seconds + {150, 24}, // Volume2 0-30 >30 == no volume change + {151, 2}, // Sound Clip2 + {152, 10}, // Wait3 0-254 0.1 Seconds + {153, 18}, // Volume3 0-30 >30 == no volume change + {154, 3}, // Sound Clip3 + {155, 10}, // Wait4 0-254 0.1 Seconds + {156, 12}, // Volume4 0-30 >30 == no volume change + {157, 4}, // Sound Clip4 + {158, 10}, // Wait5 0-254 0.1 Seconds + {159, 6}, // Volume5 0-30 >30 == no volume change + {160, 5}, // Sound Clip5 + {161, 2}, // Sound Set Channel == LSB 0/1 + + {162, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 8 + {163, 20}, // Volume1 0-30 >30 == no volume change + {164, 1}, // Sound Clip1 + {165, 20}, // Wait2 0-254 0.1 Seconds + {166, 20}, // Volume2 0-30 >30 == no volume change + {167, 2}, // Sound Clip2 + {168, 30}, // Wait3 0-254 0.1 Seconds + {169, 20}, // Volume3 0-30 >30 == no volume change + {170, 3}, // Sound Clip3 + {171, 50}, // Wait4 0-254 0.1 Seconds + {172, 20}, // Volume4 0-30 >30 == no volume change + {173, 4}, // Sound Clip4 + {174, 100}, // Wait5 0-254 0.1 Seconds + {175, 20}, // Volume5 0-30 >30 == no volume change + {176, 5}, // Sound Clip5 + {177, 3}, // Sound Set Channel == LSB 0/1 + + {178, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 9 + {179, 20}, // Volume1 0-30 >30 == no volume change + {180, 255}, // Sound Clip1 + {181, 11}, // Wait2 0-254 0.1 Seconds + {182, 20}, // Volume2 0-30 >30 == no volume change + {183, 255}, // Sound Clip2 + {184, 11}, // Wait3 0-254 0.1 Seconds + {185, 20}, // Volume3 0-30 >30 == no volume change + {186, 255}, // Sound Clip3 + {187, 14}, // Wait4 0-254 0.1 Seconds + {188, 20}, // Volume4 0-30 >30 == no volume change + {189, 255}, // Sound Clip4 + {190, 14}, // Wait5 0-254 0.1 Seconds + {191, 20}, // Volume5 0-30 >30 == no volume change + {192, 255}, // Sound Clip5 + {193, 0}, // Sound Set Channel == LSB 0/1 + + {194, 4}, // Wait1 0-254 0.1 Seconds // SOUND SET 10 + {195, 20}, // Volume1 0-30 >30 == no volume change + {196, 10}, // Sound Clip1 + {197, 110}, // Wait2 0-254 0.1 Seconds + {198, 99}, // Volume2 0-30 >30 == no volume change + {199, 0}, // Sound Clip2 + {200, 4}, // Wait3 0-254 0.1 Seconds + {201, 99}, // Volume3 0-30 >30 == no volume change + {202, 0}, // Sound Clip3 + {203, 4}, // Wait4 0-254 0.1 Seconds + {204, 12}, // Volume4 0-30 >30 == no volume change + {205, 9}, // Sound Clip4 + {206, 100}, // Wait5 0-254 0.1 Seconds + {207, 99}, // Volume5 0-30 >30 == no volume change + {208, 0}, // Sound Clip5 + {209, 3}, // Sound Set Channel == LSB 0/1 + + //252,252 CV_DECODER_MASTER_RESET + + {253, 0}, // Extra +}; + +uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +void notifyCVResetFactoryDefault() +{ + // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset + // to flag to the loop() function that a reset to Factory Defaults needs to be done + FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +}; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS + +void setup() //****************************************************** +{ +#ifdef DEBUG + Serial.begin(115200); +#endif + DFSerial1.begin (9600); + DFSerial2.begin (9600); + DFSerial3.begin (9600); + DFSerial4.begin (9600); + Player1.begin (DFSerial1); + Player2.begin (DFSerial2); + Player3.begin (DFSerial3); + Player4.begin (DFSerial4); + + pinMode (MasterDecoderDisablePin,INPUT_PULLUP); // Master Decoder Disable Input Pin Active LOW + + // initialize the digital pins as outputs + for (int i=0; i < numfpins; i++) { + pinMode(fpins[i], OUTPUT); + digitalWrite(fpins[i], 0); // All OUPUT pins initialized LOW + } + // initialize the digital pins as inputs + for (int i=0; i < numINpins; i++) { + pinMode(inputpins[i], INPUT_PULLUP); + } + // Setup which External Interrupt, the Pin it's associated with that we're using + Dcc.pin(0, 2, 0); + // Call the main DCC Init function to enable the DCC Receiver + Dcc.init( MAN_ID_DIY, 61, FLAGS_MY_ADDRESS_ONLY, 0 ); + delay(800); +#if defined(DECODER_LOADED) + if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET ) +#endif + { + for (int j=0; j < FactoryDefaultCVIndex; j++ ) + Dcc.setCV( FactoryDefaultCVs[j].CV, FactoryDefaultCVs[j].Value); + } + // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; +#ifdef DEBUG + Serial.println("CV Dump:"); + for (i=30; i<45; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=30; i<45; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 1"); + for (i=50; i<66; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=50; i<66; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 2"); + for (i=66; i<82; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=66; i<82; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 3"); + for (i=82; i<98; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=82; i<98; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 4"); + for (i=98; i<114; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=98; i<114; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 5"); + for (i=114; i<130; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=114; i<130; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 6"); + for (i=130; i<146; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=130; i<146; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 7"); + for (i=146; i<162; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=146; i<162; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 8"); + for (i=162; i<178; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=162; i<178; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 9"); + for (i=178; i<194; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=178; i<194; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 10"); + for (i=194; i<210; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=194; i<210; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } +#endif +} // End setup +void loop() //*********************************************************************************** +{ + //MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation + Dcc.process(); + delay(1); +// INPUT OVER RIDES + // Check Master Input Over ride + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + else MasterDecoderDisable = Function0_value & 1; + if (MasterDecoderDisable == 1) { + for (i=0; i < numfpins; i++) digitalWrite(fpins[i], 0); // All LEDs set LOW + } +// ******************************************************************************** + if (MasterDecoderDisable == 0) { + for (i=0; i < num_active_functions; i++) { + cv_value = Dcc.getCV(30+i) ; +#ifdef DEBUG + //Serial.print(" cv_value: "); + //Serial.println(cv_value, DEC) ; +#endif + switch ( cv_value ) { + case 0: // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + break; + case 1: // + if (((digitalRead(3)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss1[0]=1; playing_sound_set[cv_value]=true; +#ifdef DEBUG + Serial.print(" cv_value: "); + Serial.println(cv_value, DEC) ; + Serial.print(" function_value[cv_value]: "); + Serial.println(function_value[cv_value], DEC) ; + Serial.print(" ss1[0]: "); + Serial.println(ss1[0], DEC) ; + Serial.print(" playing_sound_set[cv_value]: "); + Serial.println(playing_sound_set[cv_value], DEC) ; +#endif + } + break; + case 2: // + if (((digitalRead(4)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss2[0]=1; playing_sound_set[cv_value]=true; +#ifdef DEBUG + Serial.print(" cv_value: "); + Serial.println(cv_value, DEC) ; + Serial.print(" function_value[cv_value]: "); + Serial.println(function_value[cv_value], DEC) ; + Serial.print(" ss2[0]: "); + Serial.println(ss2[0], DEC) ; + Serial.print(" playing_sound_set[cv_value]: "); + Serial.println(playing_sound_set[cv_value], DEC) ; +#endif + } + + break; + case 3: // + if (((digitalRead(5)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss3[0]=1; playing_sound_set[cv_value]=true; } + break; + case 4: // + if (((digitalRead(6)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss4[0]=1; playing_sound_set[cv_value]=true; } + break; + case 5: // + if (((digitalRead(7)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss5[0]=1; playing_sound_set[cv_value]=true; } + break; + case 6: // + if (((digitalRead(8)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss6[0]=1; playing_sound_set[cv_value]=true; } + break; + case 7: // + if (((digitalRead(9)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss7[0]=1; playing_sound_set[cv_value]=true; } + break; + case 8: // + if (((digitalRead(10)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss8[0]=1; playing_sound_set[cv_value]=true; } + break; + case 9: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss9[0]=1; playing_sound_set[cv_value]=true; } + break; + case 10: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss10[0]=1; playing_sound_set[cv_value]=true; } + break; + case 11: // LEDs + break; + default: + break; + } + } + } + + // ========================== Sound Set 1 Begin Play + if (ss1[0]==1) { + ss1delay=millis()+(long(Dcc.getCV(50)*MasterTimeConstant)); // Wait1 + ss1[0]=0; ss1[1]=1; + soundset_channel[1]=Dcc.getCV(65); //load the channel in case it updated + } + if ((ss1[1]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(52)); +#ifdef DEBUG + Serial.print(" Here 1: "); + Serial.println(ttemp, DEC) ; +#endif + setVolumeOnChannel (Dcc.getCV(51),soundset_channel[1]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[1]); // play clip 1 + ss1delay=millis()+(long(Dcc.getCV(53)*MasterTimeConstant)); // Wait2 + ss1[1]=0; ss1[2]=1; + } + if ((ss1[2]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(55)); +#ifdef DEBUG + Serial.print(" Here 2: "); + Serial.println(ttemp, DEC) ; +#endif + setVolumeOnChannel (Dcc.getCV(54),soundset_channel[1]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[1]); // play clip 2 + ss1delay=millis()+(long(Dcc.getCV(56)*MasterTimeConstant)); // Wait3 + ss1[2]=0; ss1[3]=1; + } + if ((ss1[3]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(58)); +#ifdef DEBUG + Serial.print(" Here 3: "); + Serial.println(ttemp, DEC) ; +#endif + setVolumeOnChannel (Dcc.getCV(57),soundset_channel[1]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[1]); // play clip 3 + ss1delay=millis()+(long(Dcc.getCV(59)*MasterTimeConstant)); // Wait4 + ss1[3]=0; ss1[4]=1; + } + if ((ss1[4]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(61)); + setVolumeOnChannel (Dcc.getCV(60),soundset_channel[1]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[1]); // play clip 4 + ss1delay=millis()+(long(Dcc.getCV(62)*MasterTimeConstant)); // Wait5 + ss1[4]=0; ss1[5]=1; + } + if ((ss1[5]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(64)); + setVolumeOnChannel (Dcc.getCV(63),soundset_channel[1]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[1]); // play clip 5 + ss1[5]=0; playing_sound_set[1]=false; + } +// ========================== Sound Set 2 Begin Play + if (ss2[0]==1) { + ss2delay=millis()+(long(Dcc.getCV(66)*MasterTimeConstant)); // Wait1 + ss2[0]=0; ss2[1]=1; + soundset_channel[2]=Dcc.getCV(81); //load the channel in case it updated + } + if ((ss2[1]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(68)); + setVolumeOnChannel (Dcc.getCV(67),soundset_channel[2]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[2]); // play clip 1 + ss2delay=millis()+(long(Dcc.getCV(69)*MasterTimeConstant)); // Wait2 + ss2[1]=0; ss2[2]=1; + } + if ((ss2[2]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(71)); + setVolumeOnChannel (Dcc.getCV(70),soundset_channel[2]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[2]); // play clip 2 + ss2delay=millis()+(long(Dcc.getCV(72)*MasterTimeConstant)); // Wait3 + ss2[2]=0; ss2[3]=1; + } + if ((ss2[3]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(74)); + setVolumeOnChannel (Dcc.getCV(73),soundset_channel[2]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[2]); // play clip 3 + ss2delay=millis()+(long(Dcc.getCV(75)*MasterTimeConstant)); // Wait4 + ss2[3]=0; ss2[4]=1; + } + if ((ss2[4]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(77)); + setVolumeOnChannel (Dcc.getCV(76),soundset_channel[2]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[2]); // play clip 4 + ss2delay=millis()+(long(Dcc.getCV(78)*MasterTimeConstant)); // Wait5 + ss2[4]=0; ss2[5]=1; + } + if ((ss2[5]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(80)); + setVolumeOnChannel (Dcc.getCV(79),soundset_channel[2]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[2]); // play clip 5 + ss2[5]=0; playing_sound_set[2]=false; + } +// ========================== Sound Set 3 Begin Play + if (ss3[0]==1) { + ss3delay=millis()+(long(Dcc.getCV(82)*MasterTimeConstant)); // Wait1 + ss3[0]=0; ss3[1]=1; + soundset_channel[3]=Dcc.getCV(97); //load the channel in case it updated + } + if ((ss3[1]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(84)); + setVolumeOnChannel (Dcc.getCV(83),soundset_channel[3]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[3]); // play clip 1 + ss3delay=millis()+(long(Dcc.getCV(85)*MasterTimeConstant)); // Wait2 + ss3[1]=0; ss3[2]=1; + } + if ((ss3[2]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(87)); + setVolumeOnChannel (Dcc.getCV(86),soundset_channel[3]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[3]); // play clip 2 + ss3delay=millis()+(long(Dcc.getCV(88)*MasterTimeConstant)); // Wait3 + ss3[2]=0; ss3[3]=1; + } + if ((ss3[3]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(90)); + setVolumeOnChannel (Dcc.getCV(89),soundset_channel[3]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[3]); // play clip 3 + ss3delay=millis()+(long(Dcc.getCV(91)*MasterTimeConstant)); // Wait4 + ss3[3]=0; ss3[4]=1; + } + if ((ss3[4]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(93)); + setVolumeOnChannel (Dcc.getCV(92),soundset_channel[3]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[3]); // play clip 4 + ss3delay=millis()+(long(Dcc.getCV(94)*MasterTimeConstant)); // Wait5 + ss3[4]=0; ss3[5]=1; + } + if ((ss3[5]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(96)); + setVolumeOnChannel (Dcc.getCV(95),soundset_channel[3]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[3]); // play clip 5 + ss3[5]=0; playing_sound_set[3]=false; + } +// ========================== Sound Set 4 Begin Play + if (ss4[0]==1) { + ss4delay=millis()+(long(Dcc.getCV(98)*MasterTimeConstant)); // Wait1 + ss4[0]=0; ss4[1]=1; + soundset_channel[4]=Dcc.getCV(113); //load the channel in case it updated + } + if ((ss4[1]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(100)); + setVolumeOnChannel (Dcc.getCV(99),soundset_channel[4]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[4]); // play clip 1 + ss4delay=millis()+(long(Dcc.getCV(101)*MasterTimeConstant)); // Wait2 + ss4[1]=0; ss4[2]=1; + } + if ((ss4[2]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(103)); + setVolumeOnChannel (Dcc.getCV(102),soundset_channel[4]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[4]); // play clip 2 + ss4delay=millis()+(long(Dcc.getCV(104)*MasterTimeConstant)); // Wait3 + ss4[2]=0; ss4[3]=1; + } + if ((ss4[3]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(106)); + setVolumeOnChannel (Dcc.getCV(105),soundset_channel[4]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[4]); // play clip 3 + ss4delay=millis()+(long(Dcc.getCV(107)*MasterTimeConstant)); // Wait4 + ss4[3]=0; ss4[4]=1; + } + if ((ss4[4]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(109)); + setVolumeOnChannel (Dcc.getCV(108),soundset_channel[4]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[4]); // play clip 4 + ss4delay=millis()+(long(Dcc.getCV(110)*MasterTimeConstant)); // Wait5 + ss4[4]=0; ss4[5]=1; + } + if ((ss4[5]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(112)); + setVolumeOnChannel (Dcc.getCV(111),soundset_channel[4]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[4]); // play clip 5 + ss4[5]=0; playing_sound_set[4]=false; + } +// ========================== Sound Set 5 Begin Play + if (ss5[0]==1) { + ss5delay=millis()+(long(Dcc.getCV(114)*MasterTimeConstant)); // Wait1 + ss5[0]=0; ss5[1]=1; + soundset_channel[5]=Dcc.getCV(129); //load the channel in case it updated + } + if ((ss5[1]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(116)); + setVolumeOnChannel (Dcc.getCV(115),soundset_channel[5]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[5]); // play clip 1 + ss5delay=millis()+(long(Dcc.getCV(117)*MasterTimeConstant)); // Wait2 + ss5[1]=0; ss5[2]=1; + } + if ((ss5[2]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(119)); + setVolumeOnChannel (Dcc.getCV(118),soundset_channel[5]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[5]); // play clip 2 + ss5delay=millis()+(long(Dcc.getCV(120)*MasterTimeConstant)); // Wait3 + ss5[2]=0; ss5[3]=1; + } + if ((ss5[3]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(122)); + setVolumeOnChannel (Dcc.getCV(121),soundset_channel[5]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[5]); // play clip 3 + ss5delay=millis()+(long(Dcc.getCV(123)*MasterTimeConstant)); // Wait4 + ss5[3]=0; ss5[4]=1; + } + if ((ss5[4]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(125)); + setVolumeOnChannel (Dcc.getCV(124),soundset_channel[5]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[5]); // play clip 4 + ss5delay=millis()+(long(Dcc.getCV(126)*MasterTimeConstant)); // Wait5 + ss5[4]=0; ss5[5]=1; + } + if ((ss5[5]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(128)); + setVolumeOnChannel (Dcc.getCV(127),soundset_channel[5]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[5]); // play clip 5 + ss5[5]=0; playing_sound_set[5]=false; + } + +// ========================== Sound Set 6 Begin Play + if (ss6[0]==1) { + ss6delay=millis()+(long(Dcc.getCV(130)*MasterTimeConstant)); // Wait1 + ss6[0]=0; ss6[1]=1; + soundset_channel[6]=Dcc.getCV(145); //load the channel in case it updated + } + if ((ss6[1]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(132)); + setVolumeOnChannel (Dcc.getCV(131),soundset_channel[6]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[6]); // play clip 1 + ss6delay=millis()+(long(Dcc.getCV(133)*MasterTimeConstant)); // Wait2 + ss6[1]=0; ss6[2]=1; + } + if ((ss6[2]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(135)); + setVolumeOnChannel (Dcc.getCV(134),soundset_channel[6]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[6]); // play clip 2 + ss6delay=millis()+(long(Dcc.getCV(136)*MasterTimeConstant)); // Wait3 + ss6[2]=0; ss6[3]=1; + } + if ((ss6[3]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(138)); + setVolumeOnChannel (Dcc.getCV(137),soundset_channel[6]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[6]); // play clip 3 + ss6delay=millis()+(long(Dcc.getCV(139)*MasterTimeConstant)); // Wait4 + ss6[3]=0; ss6[4]=1; + } + if ((ss6[4]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(141)); + setVolumeOnChannel (Dcc.getCV(140),soundset_channel[6]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[6]); // play clip 4 + ss6delay=millis()+(long(Dcc.getCV(142)*MasterTimeConstant)); // Wait5 + ss6[4]=0; ss6[5]=1; + } + if ((ss6[5]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(144)); + setVolumeOnChannel (Dcc.getCV(143),soundset_channel[6]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[6]); // play clip 5 + ss6[5]=0; playing_sound_set[6]=false; + } + +// ========================== Sound Set 7 Begin Play + if (ss7[0]==1) { + ss7delay=millis()+(long(Dcc.getCV(146)*MasterTimeConstant)); // Wait1 + ss7[0]=0; ss7[1]=1; + soundset_channel[7]=Dcc.getCV(161); //load the channel in case it updated + } + if ((ss7[1]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(148)); + setVolumeOnChannel (Dcc.getCV(147),soundset_channel[7]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[7]); // play clip 1 + ss7delay=millis()+(long(Dcc.getCV(149)*MasterTimeConstant)); // Wait2 + ss7[1]=0; ss7[2]=1; + } + if ((ss7[2]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(151)); + setVolumeOnChannel (Dcc.getCV(150),soundset_channel[7]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[7]); // play clip 2 + ss7delay=millis()+(long(Dcc.getCV(152)*MasterTimeConstant)); // Wait3 + ss7[2]=0; ss7[3]=1; + } + if ((ss7[3]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(154)); + setVolumeOnChannel (Dcc.getCV(153),soundset_channel[7]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[7]); // play clip 3 + ss7delay=millis()+(long(Dcc.getCV(155)*MasterTimeConstant)); // Wait4 + ss7[3]=0; ss7[4]=1; + } + if ((ss7[4]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(157)); + setVolumeOnChannel (Dcc.getCV(156),soundset_channel[7]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[7]); // play clip 4 + ss7delay=millis()+(long(Dcc.getCV(158)*MasterTimeConstant)); // Wait5 + ss7[4]=0; ss7[5]=1; + } + if ((ss7[5]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(160)); + setVolumeOnChannel (Dcc.getCV(159),soundset_channel[7]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[7]); // play clip 5 + ss7[5]=0; playing_sound_set[7]=false; + } +// ========================== Sound Set 8 Begin Play + if (ss8[0]==1) { + ss8delay=millis()+(long(Dcc.getCV(162)*MasterTimeConstant)); // Wait1 + ss8[0]=0; ss8[1]=1; + soundset_channel[8]=Dcc.getCV(177); //load the channel in case it updated + } + if ((ss8[1]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(164)); + setVolumeOnChannel (Dcc.getCV(163),soundset_channel[8]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[8]); // play clip 1 + ss8delay=millis()+(long(Dcc.getCV(165)*MasterTimeConstant)); // Wait2 + ss8[1]=0; ss8[2]=1; + } + if ((ss8[2]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(167)); + setVolumeOnChannel (Dcc.getCV(166),soundset_channel[8]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[8]); // play clip 2 + ss8delay=millis()+(long(Dcc.getCV(168)*MasterTimeConstant)); // Wait3 + ss8[2]=0; ss8[3]=1; + } + if ((ss8[3]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(170)); + setVolumeOnChannel (Dcc.getCV(169),soundset_channel[8]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[8]); // play clip 3 + ss8delay=millis()+(long(Dcc.getCV(171)*MasterTimeConstant)); // Wait4 + ss8[3]=0; ss8[4]=1; + } + if ((ss8[4]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(173)); + setVolumeOnChannel (Dcc.getCV(172),soundset_channel[8]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[8]); // play clip 4 + ss8delay=millis()+(long(Dcc.getCV(174)*MasterTimeConstant)); // Wait5 + ss8[4]=0; ss8[5]=1; + } + if ((ss8[5]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(176)); + setVolumeOnChannel (Dcc.getCV(175),soundset_channel[8]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[8]); // play clip 5 + ss8[5]=0; playing_sound_set[8]=false; + } +// ========================== Sound Set 9 Begin Play + if (ss9[0]==1) { + ss9delay=millis()+(long(Dcc.getCV(178)*MasterTimeConstant)); // Wait1 + ss9[0]=0; ss9[1]=1; + soundset_channel[9]=Dcc.getCV(193); //load the channel in case it updated + } + if ((ss9[1]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(180)); + setVolumeOnChannel (Dcc.getCV(179),soundset_channel[9]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[9]); // play clip 1 + ss9delay=millis()+(long(Dcc.getCV(181)*MasterTimeConstant)); // Wait2 + ss9[1]=0; ss9[2]=1; + } + if ((ss9[2]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(183)); + setVolumeOnChannel (Dcc.getCV(182),soundset_channel[9]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[9]); // play clip 2 + ss9delay=millis()+(long(Dcc.getCV(184)*MasterTimeConstant)); // Wait3 + ss9[2]=0; ss9[3]=1; + } + if ((ss9[3]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(186)); + setVolumeOnChannel (Dcc.getCV(185),soundset_channel[9]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[9]); // play clip 3 + ss9delay=millis()+(long(Dcc.getCV(187)*MasterTimeConstant)); // Wait4 + ss9[3]=0; ss9[4]=1; + } + if ((ss9[4]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(189)); + setVolumeOnChannel (Dcc.getCV(188),soundset_channel[9]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[9]); // play clip 4 + ss9delay=millis()+(long(Dcc.getCV(190)*MasterTimeConstant)); // Wait5 + ss9[4]=0; ss9[5]=1; + } + if ((ss9[5]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(192)); + setVolumeOnChannel (Dcc.getCV(191),soundset_channel[9]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[9]); // play clip 5 + ss9[5]=0; playing_sound_set[9]=false; + } +// ========================== Sound Set 10 Begin Play + if (ss10[0]==1) { + ss10delay=millis()+(long(Dcc.getCV(194)*MasterTimeConstant)); // Wait1 + ss10[0]=0; ss10[1]=1; + soundset_channel[10]=Dcc.getCV(209); //load the channel in case it updated + } + if ((ss10[1]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(196)); + setVolumeOnChannel (Dcc.getCV(195),soundset_channel[10]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[10]); // play clip 1 + ss10delay=millis()+(long(Dcc.getCV(197)*MasterTimeConstant)); // Wait2 + ss10[1]=0; ss10[2]=1; + } + if ((ss10[2]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(199)); + setVolumeOnChannel (Dcc.getCV(198),soundset_channel[10]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[10]); // play clip 2 + ss10delay=millis()+(long(Dcc.getCV(200)*MasterTimeConstant)); // Wait3 + ss10[2]=0; ss10[3]=1; + } + if ((ss10[3]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(202)); + setVolumeOnChannel (Dcc.getCV(201),soundset_channel[10]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[10]); // play clip 3 + ss10delay=millis()+(long(Dcc.getCV(203)*MasterTimeConstant)); // Wait4 + ss10[3]=0; ss10[4]=1; + } + if ((ss10[4]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(205)); + setVolumeOnChannel (Dcc.getCV(204),soundset_channel[10]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[10]); // play clip 4 + ss10delay=millis()+(long(Dcc.getCV(206)*MasterTimeConstant)); // Wait5 + ss10[4]=0; ss10[5]=1; + } + if ((ss10[5]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(208)); + setVolumeOnChannel (Dcc.getCV(207),soundset_channel[10]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[10]); // play clip 5 + ss10[5]=0; playing_sound_set[10]=false; + } +} // end loop() + +void playTrackOnChannel ( byte dtrack, byte dchannel) { + switch ( dchannel ) { + case 0: + if (dtrack!=255) {Player1.play(dtrack); delay(audiocmddelay); } + else {Player1.play(random(First_Track,Last_Track+1)); delay(audiocmddelay); } + break; + case 1: + if (dtrack!=255) {Player2.play(dtrack); delay(audiocmddelay); } + else {Player2.play(random(First_Track,Last_Track+1)); delay(audiocmddelay); } + break; + case 2: + if (dtrack!=255) {Player3.play(dtrack); delay(audiocmddelay); } + else {Player3.play(random(First_Track,Last_Track+1)); delay(audiocmddelay); } + break; + case 3: + default: + if (dtrack!=255) {Player4.play(dtrack); delay(audiocmddelay); } + else {Player4.play(random(First_Track,Last_Track+1)); delay(audiocmddelay); } + break; + } +} +void setVolumeOnChannel ( byte dvolume, byte dchannel) { + if(dvolume>30) return; // Don't change the volume if out of range + switch ( dchannel ) { + case 0: + Player1.volume (dvolume); + delay(audiocmddelay); + break; + case 1: + Player2.volume (dvolume); + delay(audiocmddelay); + break; + case 2: + Player3.volume (dvolume); + delay(audiocmddelay); + break; + case 3: + default: + Player4.volume (dvolume); + delay(audiocmddelay); + break; + } +} +void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { +#ifdef DEBUG + //Serial.print("Addr= "); + //Serial.println(Addr, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch(FuncGrp) + { + case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1 + exec_function( 0, FunctionPin0, (FuncState & FN_BIT_00)>>4 ); + exec_function( 1, FunctionPin1, (FuncState & FN_BIT_01)); + exec_function( 2, FunctionPin2, (FuncState & FN_BIT_02)>>1); + exec_function( 3, FunctionPin3, (FuncState & FN_BIT_03)>>2 ); + exec_function( 4, FunctionPin4, (FuncState & FN_BIT_04)>>3 ); + break; + case FN_5_8: //Function Group 1 S FFFF == 1 F8 F7 F6 F5 & == 0 F12 F11 F10 F9 F8 + exec_function( 5, FunctionPin5, (FuncState & FN_BIT_05)); + exec_function( 6, FunctionPin6, (FuncState & FN_BIT_06)>>1 ); + exec_function( 7, FunctionPin7, (FuncState & FN_BIT_07)>>2 ); + exec_function( 8, FunctionPin8, (FuncState & FN_BIT_08)>>3 ); + break; + + case FN_9_12: + exec_function( 9, FunctionPin9, (FuncState & FN_BIT_09)); + exec_function( 10, FunctionPin10, (FuncState & FN_BIT_10)>>1 ); + exec_function( 11, FunctionPin11, (FuncState & FN_BIT_11)>>2 ); + exec_function( 12, FunctionPin12, (FuncState & FN_BIT_12)>>3 ); + break; + case FN_13_20: //Function Group 2 FuncState == F20-F13 Function Control + exec_function( 13, FunctionPin13, (FuncState & FN_BIT_13)); + exec_function( 14, FunctionPin14, (FuncState & FN_BIT_14)>>1 ); + //exec_function( 15, FunctionPin15, (FuncState & FN_BIT_15)>>2 ); + //exec_function( 16, FunctionPin16, (FuncState & FN_BIT_16)>>3 ); + break; + + case FN_21_28: + break; + } +} // end notifyDccFunc +void exec_function (int function, int pin, int FuncState) { +#ifdef DEBUG + //Serial.print("ex function= "); + //Serial.println(function, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch ( Dcc.getCV( 30+function) ) { // Config + case 0: // Master Disable + Function0_value = byte(FuncState); + break; + case 1: // play sound set [ function ] + + case 2: // play sound set [ function ] + + case 3: // play sound set [ function ] + + case 4: // play sound set [ function ] + + case 5: // play sound set [ function ] + + case 6: // play sound set [ function ] + + case 7: // play sound set [ function ] + + case 8: // play sound set [ function ] + + case 9: // play sound set [ function ] + + case 10: // play sound set [ function ] + function_value[function] = byte(FuncState); + break; + case 11: // On - Off LED + if (MasterDecoderDisable == 0) digitalWrite (pin, FuncState); + else digitalWrite (pin, 0); // Master Disable is ON so force LEDs off + break; + default: + break;; + } +} // end exec_function + +/* DFPlayer Commands +//----Set volume---- + myDFPlayer.volume(10); //Set volume value (0~30). + myDFPlayer.volumeUp(); //Volume Up + myDFPlayer.volumeDown(); //Volume Down + //----Set different EQ---- + myDFPlayer.EQ(DFPLAYER_EQ_NORMAL); +// myDFPlayer.EQ(DFPLAYER_EQ_POP); +// myDFPlayer.EQ(DFPLAYER_EQ_ROCK); +// myDFPlayer.EQ(DFPLAYER_EQ_JAZZ); +// myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC); +// myDFPlayer.EQ(DFPLAYER_EQ_BASS); + //----Set device we use SD as default---- +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_U_DISK); + myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_AUX); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_SLEEP); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_FLASH); + //----Mp3 control---- +// myDFPlayer.sleep(); //sleep +// myDFPlayer.reset(); //Reset the module +// myDFPlayer.enableDAC(); //Enable On-chip DAC +// myDFPlayer.disableDAC(); //Disable On-chip DAC +// myDFPlayer.outputSetting(true, 15); //output setting, enable the output and set the gain to 15 + //----Mp3 play---- + myDFPlayer.next(); //Play next mp3 + myDFPlayer.previous(); //Play previous mp3 + myDFPlayer.play(1); //Play the first mp3 + myDFPlayer.loop(1); //Loop the first mp3 + myDFPlayer.pause(); //pause the mp3 + myDFPlayer.start(); //start the mp3 from the pause + myDFPlayer.playFolder(15, 4); //play specific mp3 in SD:/15/004.mp3; Folder Name(1~99); File Name(1~255) + myDFPlayer.enableLoopAll(); //loop all mp3 files. + myDFPlayer.disableLoopAll(); //stop loop all mp3 files. + myDFPlayer.playMp3Folder(4); //play specific mp3 in SD:/MP3/0004.mp3; File Name(0~65535) + myDFPlayer.advertise(3); //advertise specific mp3 in SD:/ADVERT/0003.mp3; File Name(0~65535) + myDFPlayer.stopAdvertise(); //stop advertise + myDFPlayer.playLargeFolder(2, 999); //play specific mp3 in SD:/02/004.mp3; Folder Name(1~10); File Name(1~1000) + myDFPlayer.loopFolder(5); //loop all mp3 files in folder SD:/05. + myDFPlayer.randomAll(); //Random play all the mp3. + myDFPlayer.enableLoop(); //enable loop. + myDFPlayer.disableLoop(); //disable loop. +*/ diff --git a/examples/IDEC/IDEC4_1_ServosFastLEDsSounds/IDEC4_1_ServosFastLEDsSounds.ino b/examples/IDEC/IDEC4_1_ServosFastLEDsSounds/IDEC4_1_ServosFastLEDsSounds.ino new file mode 100644 index 0000000..d956bd9 --- /dev/null +++ b/examples/IDEC/IDEC4_1_ServosFastLEDsSounds/IDEC4_1_ServosFastLEDsSounds.ino @@ -0,0 +1,1112 @@ +// Switched Pins Servos, LEDs and Sounds Quick Servvo Travel IDEC4_1_ServosFastLEDsSounds.ino +// Version 1.08 Geoff Bunza 2020 +// 5 Functions and Switched Inputs Plays Sound Sets 1-5 stepped with Leds 1-5 and Servos 1-5 +// F0 Master Decoder Disable Function Turn Function ON to disable the decoder +// F1-F5 and Switched Inputs Plays Sound Sets 1-5 stepped with Leds 1-5 and Servos 1-5 +// F6-F10 Plays Sound Sets 6-10 +// Master Disable Function Turn Function ON to disable the decoder +// Works with both short and long DCC Addesses +// Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10 + +/* +PRO MINI PIN ASSIGNMENT: +2 - DCC Input +3 - Input Pin Channel Switch1 & Function1 +4 - Input Pin Channel Switch2 & Function2 +5 - Input Pin Channel Switch3 & Function3 +6 - Input Pin Channel Switch4 & Function4 +7 - Input Pin Channel Switch5 & Function5 +8 - Servo Pin Channel 1 +9 - LED Pin Channel 1 +10 - Servo Pin Channel 2 +11 - LED Pin Channel 2 +12 - Servo Pin Channel 3 +13 - LED Pin Channel 3 +14 A0 - Servo Pin Channel 4 +15 A1 - (TX) connected to DFPlayer1 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor +16 A2 - Input Pin for MasterDecoderDisable Active LOW & F0 +17 A3 - LED Pin Channel 4 +18 A4 - Servo Pin Channel 5 +19 A5 - LED Pin Channel 5 +*/ +// ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP +// ******** AFTER THE INITIAL DECODER LOAD REMOVE THE "//" IN THE FOOLOWING LINE!! +//#define DECODER_LOADED + +// ******** REMOVE THE "//" IN THE FOOLOWING LINE TO SEND DEBUGGING +// ******** INFO TO THE SERIAL MONITOR +//#define DEBUG + +#include +#include +#include +#include +SoftwareSerial DFSerial1(22,15); // PRO MINI RX, PRO MINI TX serial to DFPlayer +DFRobotDFPlayerMini Player1; + +SoftwareServo servo1; +SoftwareServo servo2; +SoftwareServo servo3; +SoftwareServo servo4; +SoftwareServo servo5; + +#define This_Decoder_Address 24 +uint8_t CV_DECODER_MASTER_RESET = 252; + +//Uncomment ONLY ONE of the following: +//#define MasterTimeConstant 10L // 10's of milliseconds Timing +#define MasterTimeConstant 100L // Tenths of a second Timing +//#define MasterTimeConstant 1000L // Seconds Timing +//#define MasterTimeConstant 10000L // 10's of Seconds Timing +//#define MasterTimeConstant 60000L // Minutes Timing +//#define MasterTimeConstant 3600000L // Hours Timing + +int del_tim = 4000; +uint16_t ttemp, i; +#define First_Track 1 // Play Random Tracks First_Track#=Start_Track >=1 +#define Last_Track 12 // Play Random Tracks Last_Track= Last Playable Track in Range <= Last Numbered Track +const int audiocmddelay = 34; +byte ss1[] = {0,0,0,0,0,0}; unsigned long ss1delay=0; +byte Ls1[] = {1,0,1,0,1,0}; +byte Vs1[] = {30,60,90,120,150,30}; +byte ss2[] = {0,0,0,0,0,0}; unsigned long ss2delay=0; +byte Ls2[] = {1,1,1,1,1,0}; +byte Vs2[] = {30,60,90,120,150,30}; +byte ss3[] = {0,0,0,0,0,0}; unsigned long ss3delay=0; +byte Ls3[] = {0,0,1,1,1,0}; +byte Vs3[] = {30,60,90,120,150,30}; +byte ss4[] = {0,0,0,0,0,0}; unsigned long ss4delay=0; +byte Ls4[] = {1,0,0,0,0,1}; +byte Vs4[] = {30,60,90,120,150,30}; +byte ss5[] = {0,0,0,0,0,0}; unsigned long ss5delay=0; +byte Ls5[] = {0,1,1,1,1,0}; +byte Vs5[] = {30,60,90,120,150,30}; +byte ss6[] = {0,0,0,0,0,0}; unsigned long ss6delay=0; +byte Ls6[] = {0,0,0,0,0,0}; +byte Vs6[] = {0,0,0,0,0,0}; +byte ss7[] = {0,0,0,0,0,0}; unsigned long ss7delay=0; +byte Ls7[] = {0,0,0,0,0,0}; +byte Vs7[] = {0,0,0,0,0,0}; +byte ss8[] = {0,0,0,0,0,0}; unsigned long ss8delay=0; +byte Ls8[] = {0,0,0,0,0,0}; +byte Vs8[] = {0,0,0,0,0,0}; +byte ss9[] = {0,0,0,0,0,0}; unsigned long ss9delay=0; +byte Ls9[] = {0,0,0,0,0,0}; +byte Vs9[] = {0,0,0,0,0,0}; +byte ss10[] = {0,0,0,0,0,0}; unsigned long ss10delay=0; +byte Ls10[] = {0,0,0,0,0,0}; +byte Vs10[] = {0,0,0,0,0,0}; +bool playing_sound_set [ ] = {false,false,false,false,false,false,false,false,false,false,false}; +byte soundset_channel[ ]={0,0,0,0,0,0,0,0,0,0,0}; +byte Vs_pins[] = {0,8,10,12,14,18}; //Servo pins per channel starting with 1 +byte Ls_pins[] = {0,9,11,13,17,19}; // LED pins per channel starting with 1 +const int MasterDecoderDisablePin = 16; // D16/A0 Master Decoder Disable Input Pin Active LOW + +const int numINpins = 6; // Number of INput pins to initialize +byte inputpins [] = {3,4,5,6,7,16}; //These are all the Input Pins +const int numfpins = 10; // Number of Output pins to initialize +const int num_active_functions = 11; // Number of Functions stating with F0 +byte fpins [] = {8,9,10,11,12,13,14,17,18,19}; //These are all the Output Pins (first 15 is placeholder) +const int FunctionPin0 = 20; // Place holders ONLY +const int FunctionPin1 = 20; // Channel 1 +const int FunctionPin2 = 20; // Channel 2 +const int FunctionPin3 = 20; // Channel 3 +const int FunctionPin4 = 20; // Channel 4 +const int FunctionPin5 = 20; // Channel 5 +const int FunctionPin6 = 20; // Channel 6 +const int FunctionPin7 = 20; // Channel 7 +const int FunctionPin8 = 20; // Channel 8 +const int FunctionPin9 = 20; // Place holders ONLY +const int FunctionPin10 = 20; // Place holders ONLY +const int FunctionPin11 = 20; // Place holders ONLY +const int FunctionPin12 = 20; // Place holders ONLY +const int FunctionPin13 = 20; // Place holders ONLY +const int FunctionPin14 = 20; // Place holders ONLY +const int FunctionPin15 = 20; // Place holders ONLY +int MasterDecoderDisable = 0; +int Function0_value = 0; +byte function_value [ ] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +uint8_t cv_value; + +NmraDcc Dcc ; +DCC_MSG Packet ; +int t; // temp +struct QUEUE +{ + int inuse; + int current_position; + int increment; + int stop_value; + int start_value; +}; +QUEUE *ftn_queue = new QUEUE[17]; + +struct CVPair +{ + uint16_t CV; + uint8_t Value; +}; +CVPair FactoryDefaultCVs [] = +{ + {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address&0x7F }, + + // These two CVs define the Long DCC Address + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, ((This_Decoder_Address>>8)&0x7F)+192 }, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address&0xFF }, + + // ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS +// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps + {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps +// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps + {CV_DECODER_MASTER_RESET, 0}, + + {30, 0}, //F0 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + + {31, 1}, //F1 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {32, 2}, //F2 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {33, 3}, //F3 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {34, 4}, //F4 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {35, 5}, //F5 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {36, 6}, //F6 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {37, 7}, //F7 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {38, 8}, //F8 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {39, 9}, //F9 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {40, 10}, //F10 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + + {41, 22}, //F11 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {42, 22}, //F12 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {43, 22}, //F13 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {44, 22}, //F14Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {45, 22}, //F15 not used + + {50, 3}, // Wait1 0-254 0.1 Seconds // SOUND SET 1 + {51, 22}, // Volume1 0-30 >30 == no volume change + {52, 1}, // Sound Clip1 + {53, 6}, // Wait2 0-254 0.1 Seconds + {54, 22}, // Volume2 0-30 >30 == no volume change + {55, 2}, // Sound Clip2 + {56, 6}, // Wait3 0-254 0.1 Seconds + {57, 20}, // Volume3 0-30 >30 == no volume change + {58, 3}, // Sound Clip3 + {59, 6}, // Wait4 0-254 0.1 Seconds + {60, 15}, // Volume4 0-30 >30 == no volume change + {61, 11}, // Sound Clip4 + {62, 11}, // Wait5 0-254 0.1 Seconds + {63, 11}, // Volume5 0-30 >30 == no volume change + {64, 12}, // Sound Clip5 + {65, 0}, // Sound Set Channel == LSB 0/1 + + {66, 2}, // Wait1 0-254 0.1 Seconds // SOUND SET 2 + {67, 20}, // Volume1 0-30 >30 == no volume change + {68, 4}, // Sound Clip1 + {69, 6}, // Wait2 0-254 0.1 Seconds + {70, 20}, // Volume2 0-30 >30 == no volume change + {71, 5}, // Sound Clip2 + {72, 6}, // Wait3 0-254 0.1 Seconds + {73, 20}, // Volume3 0-30 >30 == no volume change + {74, 6}, // Sound Clip3 + {75, 6}, // Wait4 0-254 0.1 Seconds + {76, 20}, // Volume4 0-30 >30 == no volume change + {77, 7}, // Sound Clip4 + {78, 6}, // Wait5 0-254 0.1 Seconds + {79, 20}, // Volume5 0-30 >30 == no volume change + {80, 8}, // Sound Clip5 + {81, 1}, // Sound Set Channel == LSB 0/1 + + {82, 1}, // Wait1 0-254 0.1 Seconds // SOUND SET 3 + {83, 20}, // Volume1 0-30 >30 == no volume change + {84, 5}, // Sound Clip1 + {85, 6}, // Wait2 0-254 0.1 Seconds + {86, 20}, // Volume2 0-30 >30 == no volume change + {87, 6}, // Sound Clip2 + {88, 6}, // Wait3 0-254 0.1 Seconds + {89, 20}, // Volume3 0-30 >30 == no volume change + {90, 7}, // Sound Clip3 + {91, 6}, // Wait4 0-254 0.1 Seconds + {92, 20}, // Volume4 0-30 >30 == no volume change + {93, 8}, // Sound Clip4 + {94, 6}, // Wait5 0-254 0.1 Seconds + {95, 20}, // Volume5 0-30 >30 == no volume change + {96, 8}, // Sound Clip5 + {97, 0}, // Sound Set Channel == LSB 0/1 + + {98, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 4 + {99, 23}, // Volume1 0-30 >30 == no volume change + {100, 9}, // Sound Clip1 + {101,110}, // Wait2 0-254 0.1 Seconds + {102, 99}, // Volume2 0-30 >30 == no volume change + {103, 0}, // Sound Clip2 + {104, 0}, // Wait3 0-254 0.1 Seconds + {105, 20}, // Volume3 0-30 >30 == no volume change + {106, 0}, // Sound Clip3 + {107, 0}, // Wait4 0-254 0.1 Seconds + {108, 99}, // Volume4 0-30 >30 == no volume change + {109, 0}, // Sound Clip4 + {110, 0}, // Wait5 0-254 0.1 Seconds + {111, 99}, // Volume5 0-30 >30 == no volume change + {112, 0}, // Sound Clip5 + {113, 0}, // Sound Set Channel == LSB 0/1 + + {114, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 5 + {115, 20}, // Volume1 0-30 >30 == no volume change + {116, 1}, // Sound Clip1 + {117, 20}, // Wait2 0-254 0.1 Seconds + {118, 20}, // Volume2 0-30 >30 == no volume change + {119, 2}, // Sound Clip2 + {120, 30}, // Wait3 0-254 0.1 Seconds + {121, 20}, // Volume3 0-30 >30 == no volume change + {122, 3}, // Sound Clip3 + {123, 50}, // Wait4 0-254 0.1 Seconds + {124, 20}, // Volume4 0-30 >30 == no volume change + {125, 4}, // Sound Clip4 + {126, 100}, // Wait5 0-254 0.1 Seconds + {127, 20}, // Volume5 0-30 >30 == no volume change + {128, 5}, // Sound Clip5 + {129, 0}, // Sound Set Channel == LSB 0/1 + + {130, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 6 + {131, 20}, // Volume1 0-30 >30 == no volume change + {132, 1}, // Sound Clip1 + {133, 20}, // Wait2 0-254 0.1 Seconds + {134, 20}, // Volume2 0-30 >30 == no volume change + {135, 2}, // Sound Clip2 + {136, 30}, // Wait3 0-254 0.1 Seconds + {137, 20}, // Volume3 0-30 >30 == no volume change + {138, 3}, // Sound Clip3 + {139, 50}, // Wait4 0-254 0.1 Seconds + {140, 20}, // Volume4 0-30 >30 == no volume change + {141, 4}, // Sound Clip4 + {142, 100}, // Wait5 0-254 0.1 Seconds + {143, 20}, // Volume5 0-30 >30 == no volume change + {144, 5}, // Sound Clip5 + {145, 1}, // Sound Set Channel == LSB 0/1 + + {146, 10}, // Wait1 0-254 0.1 Seconds // SOUND SET 7 + {147, 29}, // Volume1 0-30 >30 == no volume change + {148, 1}, // Sound Clip1 + {149, 10}, // Wait2 0-254 0.1 Seconds + {150, 24}, // Volume2 0-30 >30 == no volume change + {151, 2}, // Sound Clip2 + {152, 10}, // Wait3 0-254 0.1 Seconds + {153, 18}, // Volume3 0-30 >30 == no volume change + {154, 3}, // Sound Clip3 + {155, 10}, // Wait4 0-254 0.1 Seconds + {156, 12}, // Volume4 0-30 >30 == no volume change + {157, 4}, // Sound Clip4 + {158, 10}, // Wait5 0-254 0.1 Seconds + {159, 6}, // Volume5 0-30 >30 == no volume change + {160, 5}, // Sound Clip5 + {161, 0}, // Sound Set Channel == LSB 0/1 + + {162, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 8 + {163, 20}, // Volume1 0-30 >30 == no volume change + {164, 1}, // Sound Clip1 + {165, 20}, // Wait2 0-254 0.1 Seconds + {166, 20}, // Volume2 0-30 >30 == no volume change + {167, 2}, // Sound Clip2 + {168, 30}, // Wait3 0-254 0.1 Seconds + {169, 20}, // Volume3 0-30 >30 == no volume change + {170, 3}, // Sound Clip3 + {171, 50}, // Wait4 0-254 0.1 Seconds + {172, 20}, // Volume4 0-30 >30 == no volume change + {173, 4}, // Sound Clip4 + {174, 100}, // Wait5 0-254 0.1 Seconds + {175, 20}, // Volume5 0-30 >30 == no volume change + {176, 5}, // Sound Clip5 + {177, 1}, // Sound Set Channel == LSB 0/1 + + {178, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 9 + {179, 20}, // Volume1 0-30 >30 == no volume change + {180, 255}, // Sound Clip1 + {181, 11}, // Wait2 0-254 0.1 Seconds + {182, 20}, // Volume2 0-30 >30 == no volume change + {183, 255}, // Sound Clip2 + {184, 11}, // Wait3 0-254 0.1 Seconds + {185, 20}, // Volume3 0-30 >30 == no volume change + {186, 255}, // Sound Clip3 + {187, 14}, // Wait4 0-254 0.1 Seconds + {188, 20}, // Volume4 0-30 >30 == no volume change + {189, 255}, // Sound Clip4 + {190, 14}, // Wait5 0-254 0.1 Seconds + {191, 20}, // Volume5 0-30 >30 == no volume change + {192, 255}, // Sound Clip5 + {193, 0}, // Sound Set Channel == LSB 0/1 + + {194, 4}, // Wait1 0-254 0.1 Seconds // SOUND SET 10 + {195, 20}, // Volume1 0-30 >30 == no volume change + {196, 10}, // Sound Clip1 + {197, 110}, // Wait2 0-254 0.1 Seconds + {198, 99}, // Volume2 0-30 >30 == no volume change + {199, 0}, // Sound Clip2 + {200, 4}, // Wait3 0-254 0.1 Seconds + {201, 99}, // Volume3 0-30 >30 == no volume change + {202, 0}, // Sound Clip3 + {203, 4}, // Wait4 0-254 0.1 Seconds + {204, 12}, // Volume4 0-30 >30 == no volume change + {205, 9}, // Sound Clip4 + {206, 100}, // Wait5 0-254 0.1 Seconds + {207, 99}, // Volume5 0-30 >30 == no volume change + {208, 0}, // Sound Clip5 + {209, 1}, // Sound Set Channel == LSB 0/1 + + //252,252 CV_DECODER_MASTER_RESET + + {253, 0}, // Extra +}; + +uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +void notifyCVResetFactoryDefault() +{ + // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset + // to flag to the loop() function that a reset to Factory Defaults needs to be done + FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +}; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS + +void setup() //****************************************************** +{ +#ifdef DEBUG + Serial.begin(115200); +#endif + DFSerial1.begin (9600); + Player1.begin (DFSerial1); + + //Set up servos + servo1.attach(Vs_pins[1]); + servo2.attach(Vs_pins[2]); + servo3.attach(Vs_pins[3]); + servo4.attach(Vs_pins[4]); + servo5.attach(Vs_pins[5]); + + pinMode (MasterDecoderDisablePin,INPUT_PULLUP); // Master Decoder Disable Input Pin Active LOW + + // initialize the digital pins as outputs + for (int i=0; i < numfpins; i++) { + pinMode(fpins[i], OUTPUT); + digitalWrite(fpins[i], 0); // All OUPUT pins initialized LOW + } + // initialize the digital pins as inputs + for (int i=0; i < numINpins; i++) { + pinMode ( inputpins[i], INPUT_PULLUP ); + } + + // Setup which External Interrupt, the Pin it's associated with that we're using + Dcc.pin(0, 2, 0); + // Call the main DCC Init function to enable the DCC Receiver + Dcc.init( MAN_ID_DIY, 61, FLAGS_MY_ADDRESS_ONLY, 0 ); + delay(800); +#if defined(DECODER_LOADED) + if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET ) +#endif + { + for (int j=0; j < FactoryDefaultCVIndex; j++ ) + Dcc.setCV( FactoryDefaultCVs[j].CV, FactoryDefaultCVs[j].Value); + } + // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; +#ifdef DEBUG + Serial.println("CV Dump:"); + for (i=30; i<45; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=30; i<45; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 1"); + for (i=50; i<66; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=50; i<66; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 2"); + for (i=66; i<82; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=66; i<82; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 3"); + for (i=82; i<98; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=82; i<98; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 4"); + for (i=98; i<114; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=98; i<114; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 5"); + for (i=114; i<130; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=114; i<130; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 6"); + for (i=130; i<146; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=130; i<146; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 7"); + for (i=146; i<162; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=146; i<162; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 8"); + for (i=162; i<178; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=162; i<178; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 9"); + for (i=178; i<194; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=178; i<194; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 10"); + for (i=194; i<210; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=194; i<210; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } +#endif +} +void loop() //*********************************************************************************** +{ + //MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation + Dcc.process(); + SoftwareServo::refresh(); + delay(1); +// INPUT OVER RIDES + // Check Master Input Over ride + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + else MasterDecoderDisable = Function0_value & 1; + if (MasterDecoderDisable == 1) { + for (i=0; i < numfpins; i++) digitalWrite(fpins[i], 0); // All LEDs set LOW + } +// ******************************************************************************** + if (MasterDecoderDisable == 0) { + for (i=0; i < num_active_functions; i++) { + cv_value = Dcc.getCV(30+i) ; +#ifdef DEBUG + //Serial.print(" cv_value: "); + //Serial.println(cv_value, DEC) ; +#endif + switch ( cv_value ) { + case 0: // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + break; + case 1: // + if (((digitalRead(3)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss1[0]=1; + digitalWrite( Ls_pins[1],Ls1[0]); + servo1.write(Vs1[0]); + playing_sound_set[cv_value]=true; + } + break; + case 2: // + if (((digitalRead(4)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss2[0]=1; + digitalWrite( Ls_pins[2],Ls2[0]); + servo2.write(Vs2[0]); + playing_sound_set[cv_value]=true; + } + break; + case 3: // + if (((digitalRead(5)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss3[0]=1; + digitalWrite( Ls_pins[3],Ls3[0]); + servo3.write(Vs3[0]); + playing_sound_set[cv_value]=true; } + break; + case 4: // + if (((digitalRead(6)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss4[0]=1; + digitalWrite( Ls_pins[4],Ls4[0]); + servo4.write(Vs4[0]); + playing_sound_set[cv_value]=true; } + break; + case 5: // + if (((digitalRead(7)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss5[0]=1; + digitalWrite( Ls_pins[5],Ls5[0]); + servo5.write(Vs5[0]); + playing_sound_set[cv_value]=true; } + break; + case 6: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss6[0]=1; playing_sound_set[cv_value]=true; } + break; + case 7: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss7[0]=1; playing_sound_set[cv_value]=true; } + break; + case 8: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss8[0]=1; playing_sound_set[cv_value]=true; } + break; + case 9: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss9[0]=1; playing_sound_set[cv_value]=true; } + break; + case 10: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss10[0]=1; playing_sound_set[cv_value]=true; } + break; + default: + break; + } + } + } + // ========================== Sound Set 1 Begin Play + if (ss1[0]==1) { + ss1delay=millis()+(long(Dcc.getCV(50)*MasterTimeConstant)); // Wait1 + ss1[0]=0; ss1[1]=1; + } + if ((ss1[1]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(52)); + setVolumeOnChannel (Dcc.getCV(51)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss1delay=millis()+(long(Dcc.getCV(53)*MasterTimeConstant)); // Wait2 + ss1[1]=0; ss1[2]=1; digitalWrite( Ls_pins[1],Ls1[1]); + servo1.write(Vs1[1]); + } + if ((ss1[2]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(55)); + setVolumeOnChannel (Dcc.getCV(54)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss1delay=millis()+(long(Dcc.getCV(56)*MasterTimeConstant)); // Wait3 + ss1[2]=0; ss1[3]=1; digitalWrite( Ls_pins[1],Ls1[2]); + servo1.write(Vs1[2]); + } + if ((ss1[3]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(58)); + setVolumeOnChannel (Dcc.getCV(57)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss1delay=millis()+(long(Dcc.getCV(59)*MasterTimeConstant)); // Wait4 + ss1[3]=0; ss1[4]=1; digitalWrite( Ls_pins[1],Ls1[3]); + servo1.write(Vs1[3]); + } + if ((ss1[4]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(61)); + setVolumeOnChannel (Dcc.getCV(60)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss1delay=millis()+(long(Dcc.getCV(62)*MasterTimeConstant)); // Wait5 + ss1[4]=0; ss1[5]=1; digitalWrite( Ls_pins[1],Ls1[4]); + servo1.write(Vs1[4]); + } + if ((ss1[5]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(64)); + setVolumeOnChannel (Dcc.getCV(63)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss1[5]=0; digitalWrite( Ls_pins[1],Ls1[5]); + servo1.write(Vs1[5]); + playing_sound_set[1]=false; + } +// ========================== Sound Set 2 Begin Play + if (ss2[0]==1) { + ss2delay=millis()+(long(Dcc.getCV(66)*MasterTimeConstant)); // Wait1 + ss2[0]=0; ss2[1]=1; + } + if ((ss2[1]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(68)); + setVolumeOnChannel (Dcc.getCV(67)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss2delay=millis()+(long(Dcc.getCV(69)*MasterTimeConstant)); // Wait2 + ss2[1]=0; ss2[2]=1; digitalWrite( Ls_pins[2],Ls2[1]); + servo2.write(Vs2[1]); + } + if ((ss2[2]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(71)); + setVolumeOnChannel (Dcc.getCV(70)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss2delay=millis()+(long(Dcc.getCV(72)*MasterTimeConstant)); // Wait3 + ss2[2]=0; ss2[3]=1; digitalWrite( Ls_pins[2],Ls2[2]); + servo2.write(Vs2[2]); + } + if ((ss2[3]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(74)); + setVolumeOnChannel (Dcc.getCV(73)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss2delay=millis()+(long(Dcc.getCV(75)*MasterTimeConstant)); // Wait4 + ss2[3]=0; ss2[4]=1; digitalWrite( Ls_pins[2],Ls2[3]); + servo2.write(Vs2[3]); + } + if ((ss2[4]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(77)); + setVolumeOnChannel (Dcc.getCV(76)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss2delay=millis()+(long(Dcc.getCV(78)*MasterTimeConstant)); // Wait5 + ss2[4]=0; ss2[5]=1; digitalWrite( Ls_pins[2],Ls2[4]); + servo2.write(Vs2[4]); + } + if ((ss2[5]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(80)); + setVolumeOnChannel (Dcc.getCV(79)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss2[5]=0; digitalWrite( Ls_pins[2],Ls2[5]); + servo2.write(Vs2[5]); + playing_sound_set[2]=false; + } +// ========================== Sound Set 3 Begin Play + if (ss3[0]==1) { + ss3delay=millis()+(long(Dcc.getCV(82)*MasterTimeConstant)); // Wait1 + ss3[0]=0; ss3[1]=1; + } + if ((ss3[1]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(84)); + setVolumeOnChannel (Dcc.getCV(83)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss3delay=millis()+(long(Dcc.getCV(85)*MasterTimeConstant)); // Wait2 + ss3[1]=0; ss3[2]=1; digitalWrite( Ls_pins[3],Ls3[1]); + servo3.write(Vs3[1]); + } + if ((ss3[2]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(87)); + setVolumeOnChannel (Dcc.getCV(86)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss3delay=millis()+(long(Dcc.getCV(88)*MasterTimeConstant)); // Wait3 + ss3[2]=0; ss3[3]=1; digitalWrite( Ls_pins[3],Ls3[2]); + servo3.write(Vs3[2]); + } + if ((ss3[3]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(90)); + setVolumeOnChannel (Dcc.getCV(89)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss3delay=millis()+(long(Dcc.getCV(91)*MasterTimeConstant)); // Wait4 + ss3[3]=0; ss3[4]=1; digitalWrite( Ls_pins[3],Ls3[3]); + servo3.write(Vs3[3]); + } + if ((ss3[4]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(93)); + setVolumeOnChannel (Dcc.getCV(92)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss3delay=millis()+(long(Dcc.getCV(94)*MasterTimeConstant)); // Wait5 + ss3[4]=0; ss3[5]=1; digitalWrite( Ls_pins[3],Ls3[4]); + servo3.write(Vs3[4]); + } + if ((ss3[5]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(96)); + setVolumeOnChannel (Dcc.getCV(95)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss3[5]=0; digitalWrite( Ls_pins[3],Ls3[5]); + servo3.write(Vs3[5]); + playing_sound_set[3]=false; + } +// ========================== Sound Set 4 Begin Play + if (ss4[0]==1) { + ss4delay=millis()+(long(Dcc.getCV(98)*MasterTimeConstant)); // Wait1 + ss4[0]=0; ss4[1]=1; + } + if ((ss4[1]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(100)); + setVolumeOnChannel (Dcc.getCV(99)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss4delay=millis()+(long(Dcc.getCV(101)*MasterTimeConstant)); // Wait2 + ss4[1]=0; ss4[2]=1; digitalWrite( Ls_pins[4],Ls4[1]); + servo4.write(Vs4[1]); + } + if ((ss4[2]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(103)); + setVolumeOnChannel (Dcc.getCV(102)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss4delay=millis()+(long(Dcc.getCV(104)*MasterTimeConstant)); // Wait3 + ss4[2]=0; ss4[3]=1; digitalWrite( Ls_pins[4],Ls4[2]); + servo4.write(Vs4[2]); + } + if ((ss4[3]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(106)); + setVolumeOnChannel (Dcc.getCV(105)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss4delay=millis()+(long(Dcc.getCV(107)*MasterTimeConstant)); // Wait4 + ss4[3]=0; ss4[4]=1; digitalWrite( Ls_pins[4],Ls4[3]); + servo4.write(Vs4[3]); + } + if ((ss4[4]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(109)); + setVolumeOnChannel (Dcc.getCV(108)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss4delay=millis()+(long(Dcc.getCV(110)*MasterTimeConstant)); // Wait5 + ss4[4]=0; ss4[5]=1; digitalWrite( Ls_pins[4],Ls4[4]); + servo4.write(Vs4[4]); + } + if ((ss4[5]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(112)); + setVolumeOnChannel (Dcc.getCV(111)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss4[5]=0; digitalWrite( Ls_pins[4],Ls4[5]); + servo4.write(Vs4[5]); + playing_sound_set[4]=false; + } +// ========================== Sound Set 5 Begin Play + if (ss5[0]==1) { + ss5delay=millis()+(long(Dcc.getCV(114)*MasterTimeConstant)); // Wait1 + ss5[0]=0; ss5[1]=1; + } + if ((ss5[1]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(116)); + setVolumeOnChannel (Dcc.getCV(115)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss5delay=millis()+(long(Dcc.getCV(117)*MasterTimeConstant)); // Wait2 + ss5[1]=0; ss5[2]=1; digitalWrite( Ls_pins[5],Ls5[1]); + servo5.write(Vs5[1]); + } + if ((ss5[2]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(119)); + setVolumeOnChannel (Dcc.getCV(118)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss5delay=millis()+(long(Dcc.getCV(120)*MasterTimeConstant)); // Wait3 + ss5[2]=0; ss5[3]=1; digitalWrite( Ls_pins[5],Ls5[2]); + servo5.write(Vs5[2]); + } + if ((ss5[3]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(122)); + setVolumeOnChannel (Dcc.getCV(121)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss5delay=millis()+(long(Dcc.getCV(123)*MasterTimeConstant)); // Wait4 + ss5[3]=0; ss5[4]=1; digitalWrite( Ls_pins[5],Ls5[3]); + servo5.write(Vs5[3]); + } + if ((ss5[4]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(125)); + setVolumeOnChannel (Dcc.getCV(124)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss5delay=millis()+(long(Dcc.getCV(126)*MasterTimeConstant)); // Wait5 + ss5[4]=0; ss5[5]=1; digitalWrite( Ls_pins[5],Ls5[4]); + servo5.write(Vs5[4]); + } + if ((ss5[5]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(128)); + setVolumeOnChannel (Dcc.getCV(127)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss5[5]=0; digitalWrite( Ls_pins[5],Ls5[5]); + servo5.write(Vs5[5]); + playing_sound_set[5]=false; + } + +// ========================== Sound Set 6 Begin Play + if (ss6[0]==1) { + ss6delay=millis()+(long(Dcc.getCV(130)*MasterTimeConstant)); // Wait1 + ss6[0]=0; ss6[1]=1; + } + if ((ss6[1]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(132)); + setVolumeOnChannel (Dcc.getCV(131)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss6delay=millis()+(long(Dcc.getCV(133)*MasterTimeConstant)); // Wait2 + ss6[1]=0; ss6[2]=1; + } + if ((ss6[2]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(135)); + setVolumeOnChannel (Dcc.getCV(134)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss6delay=millis()+(long(Dcc.getCV(136)*MasterTimeConstant)); // Wait3 + ss6[2]=0; ss6[3]=1; + } + if ((ss6[3]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(138)); + setVolumeOnChannel (Dcc.getCV(137)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss6delay=millis()+(long(Dcc.getCV(139)*MasterTimeConstant)); // Wait4 + ss6[3]=0; ss6[4]=1; + } + if ((ss6[4]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(141)); + setVolumeOnChannel (Dcc.getCV(140)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss6delay=millis()+(long(Dcc.getCV(142)*MasterTimeConstant)); // Wait5 + ss6[4]=0; ss6[5]=1; + } + if ((ss6[5]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(144)); + setVolumeOnChannel (Dcc.getCV(143)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss6[5]=0; playing_sound_set[6]=false; + } + +// ========================== Sound Set 7 Begin Play + if (ss7[0]==1) { + ss7delay=millis()+(long(Dcc.getCV(146)*MasterTimeConstant)); // Wait1 + ss7[0]=0; ss7[1]=1; + } + if ((ss7[1]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(148)); + setVolumeOnChannel (Dcc.getCV(147)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss7delay=millis()+(long(Dcc.getCV(149)*MasterTimeConstant)); // Wait2 + ss7[1]=0; ss7[2]=1; + } + if ((ss7[2]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(151)); + setVolumeOnChannel (Dcc.getCV(150)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss7delay=millis()+(long(Dcc.getCV(152)*MasterTimeConstant)); // Wait3 + ss7[2]=0; ss7[3]=1; + } + if ((ss7[3]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(154)); + setVolumeOnChannel (Dcc.getCV(153)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss7delay=millis()+(long(Dcc.getCV(155)*MasterTimeConstant)); // Wait4 + ss7[3]=0; ss7[4]=1; + } + if ((ss7[4]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(157)); + setVolumeOnChannel (Dcc.getCV(156)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss7delay=millis()+(long(Dcc.getCV(158)*MasterTimeConstant)); // Wait5 + ss7[4]=0; ss7[5]=1; + } + if ((ss7[5]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(160)); + setVolumeOnChannel (Dcc.getCV(159)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss7[5]=0; playing_sound_set[7]=false; + } +// ========================== Sound Set 8 Begin Play + if (ss8[0]==1) { + ss8delay=millis()+(long(Dcc.getCV(162)*MasterTimeConstant)); // Wait1 + ss8[0]=0; ss8[1]=1; + } + if ((ss8[1]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(164)); + setVolumeOnChannel (Dcc.getCV(163)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss8delay=millis()+(long(Dcc.getCV(165)*MasterTimeConstant)); // Wait2 + ss8[1]=0; ss8[2]=1; + } + if ((ss8[2]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(167)); + setVolumeOnChannel (Dcc.getCV(166)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss8delay=millis()+(long(Dcc.getCV(168)*MasterTimeConstant)); // Wait3 + ss8[2]=0; ss8[3]=1; + } + if ((ss8[3]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(170)); + setVolumeOnChannel (Dcc.getCV(169)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss8delay=millis()+(long(Dcc.getCV(171)*MasterTimeConstant)); // Wait4 + ss8[3]=0; ss8[4]=1; + } + if ((ss8[4]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(173)); + setVolumeOnChannel (Dcc.getCV(172)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss8delay=millis()+(long(Dcc.getCV(174)*MasterTimeConstant)); // Wait5 + ss8[4]=0; ss8[5]=1; + } + if ((ss8[5]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(176)); + setVolumeOnChannel (Dcc.getCV(175)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss8[5]=0; playing_sound_set[8]=false; + } +// ========================== Sound Set 9 Begin Play + if (ss9[0]==1) { + ss9delay=millis()+(long(Dcc.getCV(178)*MasterTimeConstant)); // Wait1 + ss9[0]=0; ss9[1]=1; + } + if ((ss9[1]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(180)); + setVolumeOnChannel (Dcc.getCV(179)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss9delay=millis()+(long(Dcc.getCV(181)*MasterTimeConstant)); // Wait2 + ss9[1]=0; ss9[2]=1; + } + if ((ss9[2]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(183)); + setVolumeOnChannel (Dcc.getCV(182)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss9delay=millis()+(long(Dcc.getCV(184)*MasterTimeConstant)); // Wait3 + ss9[2]=0; ss9[3]=1; + } + if ((ss9[3]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(186)); + setVolumeOnChannel (Dcc.getCV(185)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss9delay=millis()+(long(Dcc.getCV(187)*MasterTimeConstant)); // Wait4 + ss9[3]=0; ss9[4]=1; + } + if ((ss9[4]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(189)); + setVolumeOnChannel (Dcc.getCV(188)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss9delay=millis()+(long(Dcc.getCV(190)*MasterTimeConstant)); // Wait5 + ss9[4]=0; ss9[5]=1; + } + if ((ss9[5]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(192)); + setVolumeOnChannel (Dcc.getCV(191)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss9[5]=0; playing_sound_set[9]=false; + } +// ========================== Sound Set 10 Begin Play + if (ss10[0]==1) { + ss10delay=millis()+(long(Dcc.getCV(194)*MasterTimeConstant)); // Wait1 + ss10[0]=0; ss10[1]=1; + } + if ((ss10[1]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(196)); + setVolumeOnChannel (Dcc.getCV(195)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss10delay=millis()+(long(Dcc.getCV(197)*MasterTimeConstant)); // Wait2 + ss10[1]=0; ss10[2]=1; + } + if ((ss10[2]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(199)); + setVolumeOnChannel (Dcc.getCV(198)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss10delay=millis()+(long(Dcc.getCV(200)*MasterTimeConstant)); // Wait3 + ss10[2]=0; ss10[3]=1; + } + if ((ss10[3]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(202)); + setVolumeOnChannel (Dcc.getCV(201)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss10delay=millis()+(long(Dcc.getCV(203)*MasterTimeConstant)); // Wait4 + ss10[3]=0; ss10[4]=1; + } + if ((ss10[4]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(205)); + setVolumeOnChannel (Dcc.getCV(204)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss10delay=millis()+(long(Dcc.getCV(206)*MasterTimeConstant)); // Wait5 + ss10[4]=0; ss10[5]=1; + } + if ((ss10[5]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(208)); + setVolumeOnChannel (Dcc.getCV(207)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss10[5]=0; playing_sound_set[10]=false; + } +} // end loop() + +void playTrackOnChannel ( byte dtrack) { + if (dtrack!=255) {Player1.play(dtrack); delay(audiocmddelay); } + else {Player1.play(random(First_Track,Last_Track+1)); delay(audiocmddelay); } +} +void setVolumeOnChannel ( byte dvolume) { + if(dvolume>30) return; // Don't change the volume if out of range + Player1.volume (dvolume); + delay(audiocmddelay); +} + +void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { +#ifdef DEBUG + Serial.print("Addr= "); + Serial.println(Addr, DEC) ; + Serial.print("FuncState= "); + Serial.println(FuncState, DEC) ; +#endif + switch(FuncGrp) + { + case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1 + exec_function( 0, FunctionPin0, (FuncState & FN_BIT_00)>>4 ); + exec_function( 1, FunctionPin1, (FuncState & FN_BIT_01)); + exec_function( 2, FunctionPin2, (FuncState & FN_BIT_02)>>1); + exec_function( 3, FunctionPin3, (FuncState & FN_BIT_03)>>2 ); + exec_function( 4, FunctionPin4, (FuncState & FN_BIT_04)>>3 ); + break; + case FN_5_8: //Function Group 1 S FFFF == 1 F8 F7 F6 F5 & == 0 F12 F11 F10 F9 F8 + exec_function( 5, FunctionPin5, (FuncState & FN_BIT_05)); + exec_function( 6, FunctionPin6, (FuncState & FN_BIT_06)>>1 ); + exec_function( 7, FunctionPin7, (FuncState & FN_BIT_07)>>2 ); + exec_function( 8, FunctionPin8, (FuncState & FN_BIT_08)>>3 ); + break; + + case FN_9_12: + exec_function( 9, FunctionPin9, (FuncState & FN_BIT_09)); + exec_function( 10, FunctionPin10, (FuncState & FN_BIT_10)>>1 ); + exec_function( 11, FunctionPin11, (FuncState & FN_BIT_11)>>2 ); + exec_function( 12, FunctionPin12, (FuncState & FN_BIT_12)>>3 ); + break; + case FN_13_20: //Function Group 2 FuncState == F20-F13 Function Control + exec_function( 13, FunctionPin13, (FuncState & FN_BIT_13)); + exec_function( 14, FunctionPin14, (FuncState & FN_BIT_14)>>1 ); + //exec_function( 15, FunctionPin15, (FuncState & FN_BIT_15)>>2 ); + //exec_function( 16, FunctionPin16, (FuncState & FN_BIT_16)>>3 ); + break; + + case FN_21_28: + break; + } +} // end notifyDccFunc +void exec_function (int function, int pin, int FuncState) { +#ifdef DEBUG + //Serial.print("ex function= "); + //Serial.println(function, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch ( Dcc.getCV( 30+function) ) { // Config + case 0: // Master Disable + Function0_value = byte(FuncState); + break; + case 1: // play sound set [ function ] + + case 2: // play sound set [ function ] + + case 3: // play sound set [ function ] + + case 4: // play sound set [ function ] + + case 5: // play sound set [ function ] + + case 6: // play sound set [ function ] + + case 7: // play sound set [ function ] + + case 8: // play sound set [ function ] + + case 9: // play sound set [ function ] + + case 10: // play sound set [ function ] + function_value[function] = byte(FuncState); + break; + case 11: // On - Off LED + if (MasterDecoderDisable == 0) digitalWrite (pin, FuncState); + else digitalWrite (pin, 0); // Master Disable is ON so force LEDs off + break; + default: + break;; + } +} // end exec_function + +/* DFPlayer Commands +//----Set volume---- + myDFPlayer.volume(10); //Set volume value (0~30). + myDFPlayer.volumeUp(); //Volume Up + myDFPlayer.volumeDown(); //Volume Down + //----Set different EQ---- + myDFPlayer.EQ(DFPLAYER_EQ_NORMAL); +// myDFPlayer.EQ(DFPLAYER_EQ_POP); +// myDFPlayer.EQ(DFPLAYER_EQ_ROCK); +// myDFPlayer.EQ(DFPLAYER_EQ_JAZZ); +// myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC); +// myDFPlayer.EQ(DFPLAYER_EQ_BASS); + //----Set device we use SD as default---- +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_U_DISK); + myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_AUX); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_SLEEP); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_FLASH); + //----Mp3 control---- +// myDFPlayer.sleep(); //sleep +// myDFPlayer.reset(); //Reset the module +// myDFPlayer.enableDAC(); //Enable On-chip DAC +// myDFPlayer.disableDAC(); //Disable On-chip DAC +// myDFPlayer.outputSetting(true, 15); //output setting, enable the output and set the gain to 15 + //----Mp3 play---- + myDFPlayer.next(); //Play next mp3 + myDFPlayer.previous(); //Play previous mp3 + myDFPlayer.play(1); //Play the first mp3 + myDFPlayer.loop(1); //Loop the first mp3 + myDFPlayer.pause(); //pause the mp3 + myDFPlayer.start(); //start the mp3 from the pause + myDFPlayer.playFolder(15, 4); //play specific mp3 in SD:/15/004.mp3; Folder Name(1~99); File Name(1~255) + myDFPlayer.enableLoopAll(); //loop all mp3 files. + myDFPlayer.disableLoopAll(); //stop loop all mp3 files. + myDFPlayer.playMp3Folder(4); //play specific mp3 in SD:/MP3/0004.mp3; File Name(0~65535) + myDFPlayer.advertise(3); //advertise specific mp3 in SD:/ADVERT/0003.mp3; File Name(0~65535) + myDFPlayer.stopAdvertise(); //stop advertise + myDFPlayer.playLargeFolder(2, 999); //play specific mp3 in SD:/02/004.mp3; Folder Name(1~10); File Name(1~1000) + myDFPlayer.loopFolder(5); //loop all mp3 files in folder SD:/05. + myDFPlayer.randomAll(); //Random play all the mp3. + myDFPlayer.enableLoop(); //enable loop. + myDFPlayer.disableLoop(); //disable loop. +*/ diff --git a/examples/IDEC/IDEC4_2_ServosLEDsSounds/IDEC4_2_ServosLEDsSounds.ino b/examples/IDEC/IDEC4_2_ServosLEDsSounds/IDEC4_2_ServosLEDsSounds.ino new file mode 100644 index 0000000..0cc4a05 --- /dev/null +++ b/examples/IDEC/IDEC4_2_ServosLEDsSounds/IDEC4_2_ServosLEDsSounds.ino @@ -0,0 +1,1170 @@ +// Switched Pins Servos, LEDs Sounds Variable Slow Servvo Travel IDEC4_2_ServosLEDsSounds.ino +// Version 1.08 Geoff Bunza 2020 +// 5 Functions and Switched Inputs Plays Sound Sets 1-5 stepped with Leds 1-5 and Servos 1-5 +// F0 Master Decoder Disable Function Turn Function ON to disable the decoder +// F1-F5 and Switched Inputs Plays Sound Sets 1-5 stepped with Leds 1-5 and Servos 1-5 +// F6-F10 Plays Sound Sets 6-10 +// Master Disable Function Turn Function ON to disable the decoder +// Works with both short and long DCC Addesses +// Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10 + +/* +PRO MINI PIN ASSIGNMENT: +2 - DCC Input +3 - Input Pin Channel Switch1 & Function1 +4 - Input Pin Channel Switch2 & Function2 +5 - Input Pin Channel Switch3 & Function3 +6 - Input Pin Channel Switch4 & Function4 +7 - Input Pin Channel Switch5 & Function5 +8 - Servo Pin Channel 1 +9 - LED Pin Channel 1 +10 - Servo Pin Channel 2 +11 - LED Pin Channel 2 +12 - Servo Pin Channel 3 +13 - LED Pin Channel 3 +14 A0 - Servo Pin Channel 4 +15 A1 - (TX) connected to DFPlayer1 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor +16 A2 - Input Pin for MasterDecoderDisable Active LOW & F0 +17 A3 - LED Pin Channel 4 +18 A4 - Servo Pin Channel 5 +19 A5 - LED Pin Channel 5 +*/ +// ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP +// ******** AFTER THE INITIAL DECODER LOAD REMOVE THE "//" IN THE FOOLOWING LINE!! +//#define DECODER_LOADED + +// ******** REMOVE THE "//" IN THE FOOLOWING LINE TO SEND DEBUGGING +// ******** INFO TO THE SERIAL MONITOR +//#define DEBUG + +#include +#include +#include +#include +SoftwareSerial DFSerial1(22,15); // PRO MINI RX, PRO MINI TX serial to DFPlayer +DFRobotDFPlayerMini Player1; + +SoftwareServo servo[5]; + +#define This_Decoder_Address 24 +uint8_t CV_DECODER_MASTER_RESET = 252; + +//Uncomment ONLY ONE of the following: +//#define MasterTimeConstant 10L // 10's of milliseconds Timing +#define MasterTimeConstant 100L // Tenths of a second Timing +//#define MasterTimeConstant 1000L // Seconds Timing +//#define MasterTimeConstant 10000L // 10's of Seconds Timing +//#define MasterTimeConstant 60000L // Minutes Timing +//#define MasterTimeConstant 3600000L // Hours Timing + +uint16_t ttemp, i; +#define First_Track 1 // Play Random Tracks First_Track#=Start_Track >=1 +#define Last_Track 12 // Play Random Tracks Last_Track= Last Playable Track in Range <= Last Numbered Track +#define starting_volume 22 // If no volume is set use this at the start +const int audiocmddelay = 34; + +#define servo_master_slowdown 20 //servo loop counter limit +int servo_slow_counter = 1; //servo loop counter to slowdown servo transit +byte servo_unit_faster = 0; + +byte ss1[] = {0,0,0,0,0,0}; unsigned long ss1delay=0; +byte Ls1[] = {1,0,1,0,1,0}; +byte Vs1[] = {40,60,90,120,150,30}; +byte ss2[] = {0,0,0,0,0,0}; unsigned long ss2delay=0; +byte Ls2[] = {1,1,1,1,1,0}; +byte Vs2[] = {40,60,90,120,150,30}; +byte ss3[] = {0,0,0,0,0,0}; unsigned long ss3delay=0; +byte Ls3[] = {0,0,1,1,1,0}; +byte Vs3[] = {30,60,90,120,150,30}; +byte ss4[] = {0,0,0,0,0,0}; unsigned long ss4delay=0; +byte Ls4[] = {1,0,0,0,0,1}; +byte Vs4[] = {30,60,90,120,150,30}; +byte ss5[] = {0,0,0,0,0,0}; unsigned long ss5delay=0; +byte Ls5[] = {0,1,1,1,1,0}; +byte Vs5[] = {30,60,90,120,150,30}; +byte ss6[] = {0,0,0,0,0,0}; unsigned long ss6delay=0; +byte ss7[] = {0,0,0,0,0,0}; unsigned long ss7delay=0; +byte ss8[] = {0,0,0,0,0,0}; unsigned long ss8delay=0; +byte ss9[] = {0,0,0,0,0,0}; unsigned long ss9delay=0; +byte ss10[] = {0,0,0,0,0,0}; unsigned long ss10delay=0; +bool playing_sound_set [ ] = {false,false,false,false,false,false,false,false,false,false,false}; +byte soundset_channel[ ]={0,0,0,0,0,0,0,0,0,0,0}; +byte Vs_pins[] = {8,10,12,14,18}; //Servo pins per channel starting with 1 +byte Ls_pins[] = {0,9,11,13,17,19}; // LED pins per channel starting with 1 + +struct SERVO_TRACKING +{ + byte current_position; + byte target_position; + char delta; +}; +SERVO_TRACKING *servo_pos = new SERVO_TRACKING[5]; + +const int MasterDecoderDisablePin = 16; // D16/A0 Master Decoder Disable Input Pin Active LOW + +const int numINpins = 6; // Number of INput pins to initialize +byte inputpins [] = {3,4,5,6,7,16}; //These are all the Input Pins +const int numfpins = 10; // Number of Output pins to initialize +const int num_active_functions = 11; // Number of Functions stating with F0 +byte fpins [] = {8,9,10,11,12,13,14,17,18,19}; //These are all the Output Pins (first 15 is placeholder) +const int FunctionPin0 = 20; // Place holders ONLY +const int FunctionPin1 = 20; // Channel 1 +const int FunctionPin2 = 20; // Channel 2 +const int FunctionPin3 = 20; // Channel 3 +const int FunctionPin4 = 20; // Channel 4 +const int FunctionPin5 = 20; // Channel 5 +const int FunctionPin6 = 20; // Channel 6 +const int FunctionPin7 = 20; // Channel 7 +const int FunctionPin8 = 20; // Channel 8 +const int FunctionPin9 = 20; // Place holders ONLY +const int FunctionPin10 = 20; // Place holders ONLY +const int FunctionPin11 = 20; // Place holders ONLY +const int FunctionPin12 = 20; // Place holders ONLY +const int FunctionPin13 = 20; // Place holders ONLY +const int FunctionPin14 = 20; // Place holders ONLY +const int FunctionPin15 = 20; // Place holders ONLY +int MasterDecoderDisable = 0; +int Function0_value = 0; +byte function_value [ ] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +uint8_t cv_value; + +NmraDcc Dcc ; +DCC_MSG Packet ; +int t; // temp +struct QUEUE +{ + int inuse; + int current_position; + int increment; + int stop_value; + int start_value; +}; +QUEUE *ftn_queue = new QUEUE[17]; + +struct CVPair +{ + uint16_t CV; + uint8_t Value; +}; +CVPair FactoryDefaultCVs [] = +{ + {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address&0x7F }, + + // These two CVs define the Long DCC Address + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, ((This_Decoder_Address>>8)&0x7F)+192 }, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address&0xFF }, + + // ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS +// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps + {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps +// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps + {CV_DECODER_MASTER_RESET, 0}, + + {30, 0}, //F0 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + + {31, 1}, //F1 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {32, 2}, //F2 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {33, 3}, //F3 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {34, 4}, //F4 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {35, 5}, //F5 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {36, 6}, //F6 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {37, 7}, //F7 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {38, 8}, //F8 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {39, 9}, //F9 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {40, 10}, //F10 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + + {41, 22}, //F11 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {42, 22}, //F12 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {43, 22}, //F13 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {44, 22}, //F14Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {45, 22}, //F15 not used + + {50, 3}, // Wait1 0-254 0.1 Seconds // SOUND SET 1 + {51, 22}, // Volume1 0-30 >30 == no volume change + {52, 1}, // Sound Clip1 + {53, 6}, // Wait2 0-254 0.1 Seconds + {54, 22}, // Volume2 0-30 >30 == no volume change + {55, 2}, // Sound Clip2 + {56, 6}, // Wait3 0-254 0.1 Seconds + {57, 20}, // Volume3 0-30 >30 == no volume change + {58, 3}, // Sound Clip3 + {59, 6}, // Wait4 0-254 0.1 Seconds + {60, 15}, // Volume4 0-30 >30 == no volume change + {61, 11}, // Sound Clip4 + {62, 11}, // Wait5 0-254 0.1 Seconds + {63, 11}, // Volume5 0-30 >30 == no volume change + {64, 12}, // Sound Clip5 + {65, 0}, // Sound Set Channel == LSB 0/1 + + {66, 2}, // Wait1 0-254 0.1 Seconds // SOUND SET 2 + {67, 20}, // Volume1 0-30 >30 == no volume change + {68, 4}, // Sound Clip1 + {69, 6}, // Wait2 0-254 0.1 Seconds + {70, 20}, // Volume2 0-30 >30 == no volume change + {71, 5}, // Sound Clip2 + {72, 6}, // Wait3 0-254 0.1 Seconds + {73, 20}, // Volume3 0-30 >30 == no volume change + {74, 6}, // Sound Clip3 + {75, 6}, // Wait4 0-254 0.1 Seconds + {76, 20}, // Volume4 0-30 >30 == no volume change + {77, 7}, // Sound Clip4 + {78, 6}, // Wait5 0-254 0.1 Seconds + {79, 20}, // Volume5 0-30 >30 == no volume change + {80, 8}, // Sound Clip5 + {81, 1}, // Sound Set Channel == LSB 0/1 + + {82, 1}, // Wait1 0-254 0.1 Seconds // SOUND SET 3 + {83, 20}, // Volume1 0-30 >30 == no volume change + {84, 5}, // Sound Clip1 + {85, 6}, // Wait2 0-254 0.1 Seconds + {86, 20}, // Volume2 0-30 >30 == no volume change + {87, 6}, // Sound Clip2 + {88, 6}, // Wait3 0-254 0.1 Seconds + {89, 20}, // Volume3 0-30 >30 == no volume change + {90, 7}, // Sound Clip3 + {91, 6}, // Wait4 0-254 0.1 Seconds + {92, 20}, // Volume4 0-30 >30 == no volume change + {93, 8}, // Sound Clip4 + {94, 6}, // Wait5 0-254 0.1 Seconds + {95, 20}, // Volume5 0-30 >30 == no volume change + {96, 8}, // Sound Clip5 + {97, 0}, // Sound Set Channel == LSB 0/1 + + {98, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 4 + {99, 23}, // Volume1 0-30 >30 == no volume change + {100, 9}, // Sound Clip1 + {101,110}, // Wait2 0-254 0.1 Seconds + {102, 99}, // Volume2 0-30 >30 == no volume change + {103, 0}, // Sound Clip2 + {104, 0}, // Wait3 0-254 0.1 Seconds + {105, 20}, // Volume3 0-30 >30 == no volume change + {106, 0}, // Sound Clip3 + {107, 0}, // Wait4 0-254 0.1 Seconds + {108, 99}, // Volume4 0-30 >30 == no volume change + {109, 0}, // Sound Clip4 + {110, 0}, // Wait5 0-254 0.1 Seconds + {111, 99}, // Volume5 0-30 >30 == no volume change + {112, 0}, // Sound Clip5 + {113, 0}, // Sound Set Channel == LSB 0/1 + + {114, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 5 + {115, 20}, // Volume1 0-30 >30 == no volume change + {116, 1}, // Sound Clip1 + {117, 20}, // Wait2 0-254 0.1 Seconds + {118, 20}, // Volume2 0-30 >30 == no volume change + {119, 2}, // Sound Clip2 + {120, 30}, // Wait3 0-254 0.1 Seconds + {121, 20}, // Volume3 0-30 >30 == no volume change + {122, 3}, // Sound Clip3 + {123, 50}, // Wait4 0-254 0.1 Seconds + {124, 20}, // Volume4 0-30 >30 == no volume change + {125, 4}, // Sound Clip4 + {126, 100}, // Wait5 0-254 0.1 Seconds + {127, 20}, // Volume5 0-30 >30 == no volume change + {128, 5}, // Sound Clip5 + {129, 0}, // Sound Set Channel == LSB 0/1 + + {130, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 6 + {131, 20}, // Volume1 0-30 >30 == no volume change + {132, 1}, // Sound Clip1 + {133, 20}, // Wait2 0-254 0.1 Seconds + {134, 20}, // Volume2 0-30 >30 == no volume change + {135, 2}, // Sound Clip2 + {136, 30}, // Wait3 0-254 0.1 Seconds + {137, 20}, // Volume3 0-30 >30 == no volume change + {138, 3}, // Sound Clip3 + {139, 50}, // Wait4 0-254 0.1 Seconds + {140, 20}, // Volume4 0-30 >30 == no volume change + {141, 4}, // Sound Clip4 + {142, 100}, // Wait5 0-254 0.1 Seconds + {143, 20}, // Volume5 0-30 >30 == no volume change + {144, 5}, // Sound Clip5 + {145, 1}, // Sound Set Channel == LSB 0/1 + + {146, 10}, // Wait1 0-254 0.1 Seconds // SOUND SET 7 + {147, 29}, // Volume1 0-30 >30 == no volume change + {148, 1}, // Sound Clip1 + {149, 10}, // Wait2 0-254 0.1 Seconds + {150, 24}, // Volume2 0-30 >30 == no volume change + {151, 2}, // Sound Clip2 + {152, 10}, // Wait3 0-254 0.1 Seconds + {153, 18}, // Volume3 0-30 >30 == no volume change + {154, 3}, // Sound Clip3 + {155, 10}, // Wait4 0-254 0.1 Seconds + {156, 12}, // Volume4 0-30 >30 == no volume change + {157, 4}, // Sound Clip4 + {158, 10}, // Wait5 0-254 0.1 Seconds + {159, 6}, // Volume5 0-30 >30 == no volume change + {160, 5}, // Sound Clip5 + {161, 0}, // Sound Set Channel == LSB 0/1 + + {162, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 8 + {163, 20}, // Volume1 0-30 >30 == no volume change + {164, 1}, // Sound Clip1 + {165, 20}, // Wait2 0-254 0.1 Seconds + {166, 20}, // Volume2 0-30 >30 == no volume change + {167, 2}, // Sound Clip2 + {168, 30}, // Wait3 0-254 0.1 Seconds + {169, 20}, // Volume3 0-30 >30 == no volume change + {170, 3}, // Sound Clip3 + {171, 50}, // Wait4 0-254 0.1 Seconds + {172, 20}, // Volume4 0-30 >30 == no volume change + {173, 4}, // Sound Clip4 + {174, 100}, // Wait5 0-254 0.1 Seconds + {175, 20}, // Volume5 0-30 >30 == no volume change + {176, 5}, // Sound Clip5 + {177, 1}, // Sound Set Channel == LSB 0/1 + + {178, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 9 + {179, 20}, // Volume1 0-30 >30 == no volume change + {180, 255}, // Sound Clip1 + {181, 11}, // Wait2 0-254 0.1 Seconds + {182, 20}, // Volume2 0-30 >30 == no volume change + {183, 255}, // Sound Clip2 + {184, 11}, // Wait3 0-254 0.1 Seconds + {185, 20}, // Volume3 0-30 >30 == no volume change + {186, 255}, // Sound Clip3 + {187, 14}, // Wait4 0-254 0.1 Seconds + {188, 20}, // Volume4 0-30 >30 == no volume change + {189, 255}, // Sound Clip4 + {190, 14}, // Wait5 0-254 0.1 Seconds + {191, 20}, // Volume5 0-30 >30 == no volume change + {192, 255}, // Sound Clip5 + {193, 0}, // Sound Set Channel == LSB 0/1 + + {194, 4}, // Wait1 0-254 0.1 Seconds // SOUND SET 10 + {195, 20}, // Volume1 0-30 >30 == no volume change + {196, 10}, // Sound Clip1 + {197, 110}, // Wait2 0-254 0.1 Seconds + {198, 99}, // Volume2 0-30 >30 == no volume change + {199, 0}, // Sound Clip2 + {200, 4}, // Wait3 0-254 0.1 Seconds + {201, 99}, // Volume3 0-30 >30 == no volume change + {202, 0}, // Sound Clip3 + {203, 4}, // Wait4 0-254 0.1 Seconds + {204, 12}, // Volume4 0-30 >30 == no volume change + {205, 9}, // Sound Clip4 + {206, 100}, // Wait5 0-254 0.1 Seconds + {207, 99}, // Volume5 0-30 >30 == no volume change + {208, 0}, // Sound Clip5 + {209, 1}, // Sound Set Channel == LSB 0/1 + + //252,252 CV_DECODER_MASTER_RESET + + {253, 0}, // Extra +}; + +uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +void notifyCVResetFactoryDefault() +{ + // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset + // to flag to the loop() function that a reset to Factory Defaults needs to be done + FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +}; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS + +void setup() //****************************************************** +{ +#ifdef DEBUG + Serial.begin(115200); +#endif + DFSerial1.begin (9600); + Player1.begin (DFSerial1); + + // initialize the digital pins as outputs + for (int i=0; i < numfpins; i++) { + pinMode(fpins[i], OUTPUT); + digitalWrite(fpins[i], 0); // All OUPUT pins initialized LOW + } + + //Set up servos + for (i=0; i<5; i++) { + servo[i].attach(Vs_pins[i]); // Start Servos + for (t=0; t<180; t++) SoftwareServo::refresh(); + } + servo[0].write(Vs1[5]); // Set Servos Initial positions + servo_pos[0].current_position = Vs1[5]; + servo[1].write(Vs2[5]); + servo_pos[1].current_position = Vs2[5]; + servo[2].write(Vs3[5]); + servo_pos[2].current_position = Vs3[5]; + servo[3].write(Vs4[5]); + servo_pos[3].current_position = Vs4[5]; + servo[4].write(Vs5[5]); + servo_pos[4].current_position = Vs5[5]; + + pinMode (MasterDecoderDisablePin,INPUT_PULLUP); // Master Decoder Disable Input Pin Active LOW + + // initialize the digital pins as inputs + for (int i=0; i < numINpins; i++) { + pinMode ( inputpins[i], INPUT_PULLUP ); + } + + // Setup which External Interrupt, the Pin it's associated with that we're using + Dcc.pin(0, 2, 0); + // Call the main DCC Init function to enable the DCC Receiver + Dcc.init( MAN_ID_DIY, 13, FLAGS_MY_ADDRESS_ONLY, 0 ); + delay(800); +#if defined(DECODER_LOADED) + if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET ) +#endif + { + for (int j=0; j < FactoryDefaultCVIndex; j++ ) + Dcc.setCV( FactoryDefaultCVs[j].CV, FactoryDefaultCVs[j].Value); + } + // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + setVolumeOnChannel (starting_volume); +#ifdef DEBUG + Serial.println("CV Dump:"); + for (i=30; i<45; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=30; i<45; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 1"); + for (i=50; i<66; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=50; i<66; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 2"); + for (i=66; i<82; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=66; i<82; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 3"); + for (i=82; i<98; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=82; i<98; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 4"); + for (i=98; i<114; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=98; i<114; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 5"); + for (i=114; i<130; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=114; i<130; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 6"); + for (i=130; i<146; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=130; i<146; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 7"); + for (i=146; i<162; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=146; i<162; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 8"); + for (i=162; i<178; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=162; i<178; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 9"); + for (i=178; i<194; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=178; i<194; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 10"); + for (i=194; i<210; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=194; i<210; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } +#endif +} +void loop() //*********************************************************************************** +{ + //MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation + Dcc.process(); + SoftwareServo::refresh(); + if (servo_slow_counter > servo_master_slowdown) update_servos(); + else servo_slow_counter++; + delay(1); +// INPUT OVER RIDES + // Check Master Input Over ride + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + else MasterDecoderDisable = Function0_value & 1; + if (MasterDecoderDisable == 1) { + for (i=0; i < numfpins; i++) digitalWrite(fpins[i], 0); // All LEDs set LOW + } +// ******************************************************************************** + if (MasterDecoderDisable == 0) { + for (i=0; i < num_active_functions; i++) { + cv_value = Dcc.getCV(30+i) ; +#ifdef DEBUG + //Serial.print(" cv_value: "); + //Serial.println(cv_value, DEC) ; +#endif + switch ( cv_value ) { + case 0: // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + break; + case 1: // + if (((digitalRead(3)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss1[0]=1; + digitalWrite( Ls_pins[1],Ls1[0]); + set_servo (0,Vs1[0]); + playing_sound_set[cv_value]=true; + } + break; + case 2: // + if (((digitalRead(4)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss2[0]=1; + digitalWrite( Ls_pins[2],Ls2[0]); + set_servo (1,Vs2[0]); + playing_sound_set[cv_value]=true; + } + break; + case 3: // + if (((digitalRead(5)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss3[0]=1; + digitalWrite( Ls_pins[3],Ls3[0]); + set_servo (2,Vs3[0]); + playing_sound_set[cv_value]=true; } + break; + case 4: // + if (((digitalRead(6)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss4[0]=1; + digitalWrite( Ls_pins[4],Ls4[0]); + set_servo (3,Vs4[0]); + playing_sound_set[cv_value]=true; } + break; + case 5: // + if (((digitalRead(7)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss5[0]=1; + digitalWrite( Ls_pins[5],Ls5[0]); + set_servo (4,Vs5[0]); + playing_sound_set[cv_value]=true; } + break; + case 6: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss6[0]=1; playing_sound_set[cv_value]=true; } + break; + case 7: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss7[0]=1; playing_sound_set[cv_value]=true; } + break; + case 8: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss8[0]=1; playing_sound_set[cv_value]=true; } + break; + case 9: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss9[0]=1; playing_sound_set[cv_value]=true; } + break; + case 10: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss10[0]=1; playing_sound_set[cv_value]=true; } + break; + default: + break; + } + } + } + // ========================== Sound Set 1 Begin Play + if (ss1[0]==1) { + ss1delay=millis()+(long(Dcc.getCV(50)*MasterTimeConstant)); // Wait1 + ss1[0]=0; ss1[1]=1; + } + if ((ss1[1]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(52)); + setVolumeOnChannel (Dcc.getCV(51)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss1delay=millis()+(long(Dcc.getCV(53)*MasterTimeConstant)); // Wait2 + ss1[1]=0; ss1[2]=1; digitalWrite( Ls_pins[1],Ls1[1]); + set_servo (0,Vs1[1]); + } + if ((ss1[2]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(55)); + setVolumeOnChannel (Dcc.getCV(54)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss1delay=millis()+(long(Dcc.getCV(56)*MasterTimeConstant)); // Wait3 + ss1[2]=0; ss1[3]=1; digitalWrite( Ls_pins[1],Ls1[2]); + set_servo (0,Vs1[2]); + } + if ((ss1[3]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(58)); + setVolumeOnChannel (Dcc.getCV(57)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss1delay=millis()+(long(Dcc.getCV(59)*MasterTimeConstant)); // Wait4 + ss1[3]=0; ss1[4]=1; digitalWrite( Ls_pins[1],Ls1[3]); + set_servo (0,Vs1[3]); + } + if ((ss1[4]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(61)); + setVolumeOnChannel (Dcc.getCV(60)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss1delay=millis()+(long(Dcc.getCV(62)*MasterTimeConstant)); // Wait5 + ss1[4]=0; ss1[5]=1; digitalWrite( Ls_pins[1],Ls1[4]); + set_servo (0,Vs1[4]); + } + if ((ss1[5]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(64)); + setVolumeOnChannel (Dcc.getCV(63)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss1[5]=0; digitalWrite( Ls_pins[1],Ls1[5]); + set_servo (0,Vs1[5]); + playing_sound_set[1]=false; + } +// ========================== Sound Set 2 Begin Play + if (ss2[0]==1) { + ss2delay=millis()+(long(Dcc.getCV(66)*MasterTimeConstant)); // Wait1 + ss2[0]=0; ss2[1]=1; + } + if ((ss2[1]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(68)); + setVolumeOnChannel (Dcc.getCV(67)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss2delay=millis()+(long(Dcc.getCV(69)*MasterTimeConstant)); // Wait2 + ss2[1]=0; ss2[2]=1; digitalWrite( Ls_pins[2],Ls2[1]); + set_servo (1,Vs2[1]); + } + if ((ss2[2]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(71)); + setVolumeOnChannel (Dcc.getCV(70)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss2delay=millis()+(long(Dcc.getCV(72)*MasterTimeConstant)); // Wait3 + ss2[2]=0; ss2[3]=1; digitalWrite( Ls_pins[2],Ls2[2]); + set_servo (1,Vs2[2]); + } + if ((ss2[3]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(74)); + setVolumeOnChannel (Dcc.getCV(73)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss2delay=millis()+(long(Dcc.getCV(75)*MasterTimeConstant)); // Wait4 + ss2[3]=0; ss2[4]=1; digitalWrite( Ls_pins[2],Ls2[3]); + set_servo (1,Vs2[3]); + } + if ((ss2[4]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(77)); + setVolumeOnChannel (Dcc.getCV(76)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss2delay=millis()+(long(Dcc.getCV(78)*MasterTimeConstant)); // Wait5 + ss2[4]=0; ss2[5]=1; digitalWrite( Ls_pins[2],Ls2[4]); + set_servo (1,Vs2[4]); + } + if ((ss2[5]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(80)); + setVolumeOnChannel (Dcc.getCV(79)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss2[5]=0; digitalWrite( Ls_pins[2],Ls2[5]); + set_servo (1,Vs2[5]); + playing_sound_set[2]=false; + } +// ========================== Sound Set 3 Begin Play + if (ss3[0]==1) { + ss3delay=millis()+(long(Dcc.getCV(82)*MasterTimeConstant)); // Wait1 + ss3[0]=0; ss3[1]=1; + } + if ((ss3[1]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(84)); + setVolumeOnChannel (Dcc.getCV(83)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss3delay=millis()+(long(Dcc.getCV(85)*MasterTimeConstant)); // Wait2 + ss3[1]=0; ss3[2]=1; digitalWrite( Ls_pins[3],Ls3[1]); + set_servo (2,Vs3[1]); + } + if ((ss3[2]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(87)); + setVolumeOnChannel (Dcc.getCV(86)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss3delay=millis()+(long(Dcc.getCV(88)*MasterTimeConstant)); // Wait3 + ss3[2]=0; ss3[3]=1; digitalWrite( Ls_pins[3],Ls3[2]); + set_servo (2,Vs3[2]); + } + if ((ss3[3]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(90)); + setVolumeOnChannel (Dcc.getCV(89)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss3delay=millis()+(long(Dcc.getCV(91)*MasterTimeConstant)); // Wait4 + ss3[3]=0; ss3[4]=1; digitalWrite( Ls_pins[3],Ls3[3]); + set_servo (2,Vs3[3]); + } + if ((ss3[4]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(93)); + setVolumeOnChannel (Dcc.getCV(92)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss3delay=millis()+(long(Dcc.getCV(94)*MasterTimeConstant)); // Wait5 + ss3[4]=0; ss3[5]=1; digitalWrite( Ls_pins[3],Ls3[4]); + set_servo (2,Vs3[4]); + } + if ((ss3[5]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(96)); + setVolumeOnChannel (Dcc.getCV(95)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss3[5]=0; digitalWrite( Ls_pins[3],Ls3[5]); + set_servo (2,Vs3[5]); + playing_sound_set[3]=false; + } +// ========================== Sound Set 4 Begin Play + if (ss4[0]==1) { + ss4delay=millis()+(long(Dcc.getCV(98)*MasterTimeConstant)); // Wait1 + ss4[0]=0; ss4[1]=1; + } + if ((ss4[1]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(100)); + setVolumeOnChannel (Dcc.getCV(99)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss4delay=millis()+(long(Dcc.getCV(101)*MasterTimeConstant)); // Wait2 + ss4[1]=0; ss4[2]=1; digitalWrite( Ls_pins[4],Ls4[1]); + set_servo (3,Vs4[1]); + } + if ((ss4[2]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(103)); + setVolumeOnChannel (Dcc.getCV(102)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss4delay=millis()+(long(Dcc.getCV(104)*MasterTimeConstant)); // Wait3 + ss4[2]=0; ss4[3]=1; digitalWrite( Ls_pins[4],Ls4[2]); + set_servo (3,Vs4[2]); + } + if ((ss4[3]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(106)); + setVolumeOnChannel (Dcc.getCV(105)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss4delay=millis()+(long(Dcc.getCV(107)*MasterTimeConstant)); // Wait4 + ss4[3]=0; ss4[4]=1; digitalWrite( Ls_pins[4],Ls4[3]); + set_servo (3,Vs4[3]); + } + if ((ss4[4]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(109)); + setVolumeOnChannel (Dcc.getCV(108)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss4delay=millis()+(long(Dcc.getCV(110)*MasterTimeConstant)); // Wait5 + ss4[4]=0; ss4[5]=1; digitalWrite( Ls_pins[4],Ls4[4]); + set_servo (3,Vs4[4]); + } + if ((ss4[5]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(112)); + setVolumeOnChannel (Dcc.getCV(111)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss4[5]=0; digitalWrite( Ls_pins[4],Ls4[5]); + set_servo (3,Vs4[5]); + playing_sound_set[4]=false; + } +// ========================== Sound Set 5 Begin Play + if (ss5[0]==1) { + ss5delay=millis()+(long(Dcc.getCV(114)*MasterTimeConstant)); // Wait1 + ss5[0]=0; ss5[1]=1; + } + if ((ss5[1]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(116)); + setVolumeOnChannel (Dcc.getCV(115)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss5delay=millis()+(long(Dcc.getCV(117)*MasterTimeConstant)); // Wait2 + ss5[1]=0; ss5[2]=1; digitalWrite( Ls_pins[5],Ls5[1]); + set_servo (4,Vs5[1]); + } + if ((ss5[2]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(119)); + setVolumeOnChannel (Dcc.getCV(118)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss5delay=millis()+(long(Dcc.getCV(120)*MasterTimeConstant)); // Wait3 + ss5[2]=0; ss5[3]=1; digitalWrite( Ls_pins[5],Ls5[2]); + set_servo (4,Vs5[2]); + } + if ((ss5[3]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(122)); + setVolumeOnChannel (Dcc.getCV(121)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss5delay=millis()+(long(Dcc.getCV(123)*MasterTimeConstant)); // Wait4 + ss5[3]=0; ss5[4]=1; digitalWrite( Ls_pins[5],Ls5[3]); + set_servo (4,Vs5[3]); + } + if ((ss5[4]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(125)); + setVolumeOnChannel (Dcc.getCV(124)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss5delay=millis()+(long(Dcc.getCV(126)*MasterTimeConstant)); // Wait5 + ss5[4]=0; ss5[5]=1; digitalWrite( Ls_pins[5],Ls5[4]); + set_servo (4,Vs5[4]); + } + if ((ss5[5]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(128)); + setVolumeOnChannel (Dcc.getCV(127)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss5[5]=0; digitalWrite( Ls_pins[5],Ls5[5]); + set_servo (4,Vs5[5]); + playing_sound_set[5]=false; + } + +// ========================== Sound Set 6 Begin Play + if (ss6[0]==1) { + ss6delay=millis()+(long(Dcc.getCV(130)*MasterTimeConstant)); // Wait1 + ss6[0]=0; ss6[1]=1; + } + if ((ss6[1]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(132)); + setVolumeOnChannel (Dcc.getCV(131)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss6delay=millis()+(long(Dcc.getCV(133)*MasterTimeConstant)); // Wait2 + ss6[1]=0; ss6[2]=1; + } + if ((ss6[2]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(135)); + setVolumeOnChannel (Dcc.getCV(134)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss6delay=millis()+(long(Dcc.getCV(136)*MasterTimeConstant)); // Wait3 + ss6[2]=0; ss6[3]=1; + } + if ((ss6[3]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(138)); + setVolumeOnChannel (Dcc.getCV(137)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss6delay=millis()+(long(Dcc.getCV(139)*MasterTimeConstant)); // Wait4 + ss6[3]=0; ss6[4]=1; + } + if ((ss6[4]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(141)); + setVolumeOnChannel (Dcc.getCV(140)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss6delay=millis()+(long(Dcc.getCV(142)*MasterTimeConstant)); // Wait5 + ss6[4]=0; ss6[5]=1; + } + if ((ss6[5]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(144)); + setVolumeOnChannel (Dcc.getCV(143)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss6[5]=0; playing_sound_set[6]=false; + } + +// ========================== Sound Set 7 Begin Play + if (ss7[0]==1) { + ss7delay=millis()+(long(Dcc.getCV(146)*MasterTimeConstant)); // Wait1 + ss7[0]=0; ss7[1]=1; + } + if ((ss7[1]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(148)); + setVolumeOnChannel (Dcc.getCV(147)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss7delay=millis()+(long(Dcc.getCV(149)*MasterTimeConstant)); // Wait2 + ss7[1]=0; ss7[2]=1; + } + if ((ss7[2]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(151)); + setVolumeOnChannel (Dcc.getCV(150)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss7delay=millis()+(long(Dcc.getCV(152)*MasterTimeConstant)); // Wait3 + ss7[2]=0; ss7[3]=1; + } + if ((ss7[3]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(154)); + setVolumeOnChannel (Dcc.getCV(153)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss7delay=millis()+(long(Dcc.getCV(155)*MasterTimeConstant)); // Wait4 + ss7[3]=0; ss7[4]=1; + } + if ((ss7[4]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(157)); + setVolumeOnChannel (Dcc.getCV(156)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss7delay=millis()+(long(Dcc.getCV(158)*MasterTimeConstant)); // Wait5 + ss7[4]=0; ss7[5]=1; + } + if ((ss7[5]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(160)); + setVolumeOnChannel (Dcc.getCV(159)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss7[5]=0; playing_sound_set[7]=false; + } +// ========================== Sound Set 8 Begin Play + if (ss8[0]==1) { + ss8delay=millis()+(long(Dcc.getCV(162)*MasterTimeConstant)); // Wait1 + ss8[0]=0; ss8[1]=1; + } + if ((ss8[1]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(164)); + setVolumeOnChannel (Dcc.getCV(163)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss8delay=millis()+(long(Dcc.getCV(165)*MasterTimeConstant)); // Wait2 + ss8[1]=0; ss8[2]=1; + } + if ((ss8[2]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(167)); + setVolumeOnChannel (Dcc.getCV(166)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss8delay=millis()+(long(Dcc.getCV(168)*MasterTimeConstant)); // Wait3 + ss8[2]=0; ss8[3]=1; + } + if ((ss8[3]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(170)); + setVolumeOnChannel (Dcc.getCV(169)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss8delay=millis()+(long(Dcc.getCV(171)*MasterTimeConstant)); // Wait4 + ss8[3]=0; ss8[4]=1; + } + if ((ss8[4]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(173)); + setVolumeOnChannel (Dcc.getCV(172)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss8delay=millis()+(long(Dcc.getCV(174)*MasterTimeConstant)); // Wait5 + ss8[4]=0; ss8[5]=1; + } + if ((ss8[5]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(176)); + setVolumeOnChannel (Dcc.getCV(175)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss8[5]=0; playing_sound_set[8]=false; + } +// ========================== Sound Set 9 Begin Play + if (ss9[0]==1) { + ss9delay=millis()+(long(Dcc.getCV(178)*MasterTimeConstant)); // Wait1 + ss9[0]=0; ss9[1]=1; + } + if ((ss9[1]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(180)); + setVolumeOnChannel (Dcc.getCV(179)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss9delay=millis()+(long(Dcc.getCV(181)*MasterTimeConstant)); // Wait2 + ss9[1]=0; ss9[2]=1; + } + if ((ss9[2]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(183)); + setVolumeOnChannel (Dcc.getCV(182)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss9delay=millis()+(long(Dcc.getCV(184)*MasterTimeConstant)); // Wait3 + ss9[2]=0; ss9[3]=1; + } + if ((ss9[3]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(186)); + setVolumeOnChannel (Dcc.getCV(185)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss9delay=millis()+(long(Dcc.getCV(187)*MasterTimeConstant)); // Wait4 + ss9[3]=0; ss9[4]=1; + } + if ((ss9[4]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(189)); + setVolumeOnChannel (Dcc.getCV(188)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss9delay=millis()+(long(Dcc.getCV(190)*MasterTimeConstant)); // Wait5 + ss9[4]=0; ss9[5]=1; + } + if ((ss9[5]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(192)); + setVolumeOnChannel (Dcc.getCV(191)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss9[5]=0; playing_sound_set[9]=false; + } +// ========================== Sound Set 10 Begin Play + if (ss10[0]==1) { + ss10delay=millis()+(long(Dcc.getCV(194)*MasterTimeConstant)); // Wait1 + ss10[0]=0; ss10[1]=1; + } + if ((ss10[1]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(196)); + setVolumeOnChannel (Dcc.getCV(195)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss10delay=millis()+(long(Dcc.getCV(197)*MasterTimeConstant)); // Wait2 + ss10[1]=0; ss10[2]=1; + } + if ((ss10[2]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(199)); + setVolumeOnChannel (Dcc.getCV(198)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss10delay=millis()+(long(Dcc.getCV(200)*MasterTimeConstant)); // Wait3 + ss10[2]=0; ss10[3]=1; + } + if ((ss10[3]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(202)); + setVolumeOnChannel (Dcc.getCV(201)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss10delay=millis()+(long(Dcc.getCV(203)*MasterTimeConstant)); // Wait4 + ss10[3]=0; ss10[4]=1; + } + if ((ss10[4]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(205)); + setVolumeOnChannel (Dcc.getCV(204)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss10delay=millis()+(long(Dcc.getCV(206)*MasterTimeConstant)); // Wait5 + ss10[4]=0; ss10[5]=1; + } + if ((ss10[5]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(208)); + setVolumeOnChannel (Dcc.getCV(207)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss10[5]=0; playing_sound_set[10]=false; + } +} // end loop() + + +void set_servo (byte servonum, byte position) { + if (servo_pos[servonum].current_position == position) { + servo_pos[servonum].delta = 0; + servo_pos[servonum].target_position = position; + return; + } +#ifdef DEBUG + Serial.print(" SET SERVO 1: "); +#endif + if (servo_pos[servonum].current_position < position) servo_pos[servonum].delta = 1+servo_unit_faster; + else servo_pos[servonum].delta = -1-servo_unit_faster; + servo_pos[servonum].target_position = position; +#ifdef DEBUG + Serial.print(" servonum: "); + Serial.println(servonum, DEC) ; + Serial.print(" current_position: "); + Serial.println(servo_pos[servonum].current_position, DEC) ; + Serial.print(" target_position: "); + Serial.println(servo_pos[servonum].target_position, DEC) ; + Serial.print(" delta: "); + Serial.println(servo_pos[servonum].delta, DEC) ; +#endif +} +void update_servos() { + servo_slow_counter = 1; + for (i=0; i<5; i++) { + if (servo_pos[i].delta != 0 ) { + servo_pos[i].current_position=servo_pos[i].current_position+servo_pos[i].delta; + if ((servo_pos[i].delta > 0)&&(servo_pos[i].current_position > servo_pos[i].target_position)) + { + servo_pos[i].current_position = servo_pos[i].target_position; + servo_pos[i].delta = 0; + } + if ((servo_pos[i].delta < 0)&&(servo_pos[i].current_position < servo_pos[i].target_position)) + { + servo_pos[i].current_position = servo_pos[i].target_position; + servo_pos[i].delta = 0; + } + if (servo_pos[i].current_position == servo_pos[i].target_position) servo_pos[i].delta = 0; + } + servo[i].write ( servo_pos[i].current_position ); + } +} + +void playTrackOnChannel ( byte dtrack) { + if (dtrack!=255) {Player1.play(dtrack); delay(audiocmddelay); } + else {Player1.play(random(First_Track,Last_Track+1)); delay(audiocmddelay); } +} +void setVolumeOnChannel ( byte dvolume) { + if(dvolume>30) return; // Don't change the volume if out of range + Player1.volume (dvolume); + delay(audiocmddelay); +} + +void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { +#ifdef DEBUG + Serial.print("Addr= "); + Serial.println(Addr, DEC) ; + Serial.print("FuncState= "); + Serial.println(FuncState, DEC) ; +#endif + switch(FuncGrp) + { + case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1 + exec_function( 0, FunctionPin0, (FuncState & FN_BIT_00)>>4 ); + exec_function( 1, FunctionPin1, (FuncState & FN_BIT_01)); + exec_function( 2, FunctionPin2, (FuncState & FN_BIT_02)>>1); + exec_function( 3, FunctionPin3, (FuncState & FN_BIT_03)>>2 ); + exec_function( 4, FunctionPin4, (FuncState & FN_BIT_04)>>3 ); + break; + case FN_5_8: //Function Group 1 S FFFF == 1 F8 F7 F6 F5 & == 0 F12 F11 F10 F9 F8 + exec_function( 5, FunctionPin5, (FuncState & FN_BIT_05)); + exec_function( 6, FunctionPin6, (FuncState & FN_BIT_06)>>1 ); + exec_function( 7, FunctionPin7, (FuncState & FN_BIT_07)>>2 ); + exec_function( 8, FunctionPin8, (FuncState & FN_BIT_08)>>3 ); + break; + + case FN_9_12: + exec_function( 9, FunctionPin9, (FuncState & FN_BIT_09)); + exec_function( 10, FunctionPin10, (FuncState & FN_BIT_10)>>1 ); + exec_function( 11, FunctionPin11, (FuncState & FN_BIT_11)>>2 ); + exec_function( 12, FunctionPin12, (FuncState & FN_BIT_12)>>3 ); + break; + case FN_13_20: //Function Group 2 FuncState == F20-F13 Function Control + exec_function( 13, FunctionPin13, (FuncState & FN_BIT_13)); + exec_function( 14, FunctionPin14, (FuncState & FN_BIT_14)>>1 ); + //exec_function( 15, FunctionPin15, (FuncState & FN_BIT_15)>>2 ); + //exec_function( 16, FunctionPin16, (FuncState & FN_BIT_16)>>3 ); + break; + + case FN_21_28: + break; + } +} // end notifyDccFunc +void exec_function (int function, int pin, int FuncState) { +#ifdef DEBUG + //Serial.print("ex function= "); + //Serial.println(function, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch ( Dcc.getCV( 30+function) ) { // Config + case 0: // Master Disable + Function0_value = byte(FuncState); + break; + case 1: // play sound set [ function ] + + case 2: // play sound set [ function ] + + case 3: // play sound set [ function ] + + case 4: // play sound set [ function ] + + case 5: // play sound set [ function ] + + case 6: // play sound set [ function ] + + case 7: // play sound set [ function ] + + case 8: // play sound set [ function ] + + case 9: // play sound set [ function ] + + case 10: // play sound set [ function ] + function_value[function] = byte(FuncState); + break; + case 11: // On - Off LED + if (MasterDecoderDisable == 0) digitalWrite (pin, FuncState); + else digitalWrite (pin, 0); // Master Disable is ON so force LEDs off + break; + default: + break;; + } +} // end exec_function + +/* DFPlayer Commands +//----Set volume---- + myDFPlayer.volume(10); //Set volume value (0~30). + myDFPlayer.volumeUp(); //Volume Up + myDFPlayer.volumeDown(); //Volume Down + //----Set different EQ---- + myDFPlayer.EQ(DFPLAYER_EQ_NORMAL); +// myDFPlayer.EQ(DFPLAYER_EQ_POP); +// myDFPlayer.EQ(DFPLAYER_EQ_ROCK); +// myDFPlayer.EQ(DFPLAYER_EQ_JAZZ); +// myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC); +// myDFPlayer.EQ(DFPLAYER_EQ_BASS); + //----Set device we use SD as default---- +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_U_DISK); + myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_AUX); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_SLEEP); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_FLASH); + //----Mp3 control---- +// myDFPlayer.sleep(); //sleep +// myDFPlayer.reset(); //Reset the module +// myDFPlayer.enableDAC(); //Enable On-chip DAC +// myDFPlayer.disableDAC(); //Disable On-chip DAC +// myDFPlayer.outputSetting(true, 15); //output setting, enable the output and set the gain to 15 + //----Mp3 play---- + myDFPlayer.next(); //Play next mp3 + myDFPlayer.previous(); //Play previous mp3 + myDFPlayer.play(1); //Play the first mp3 + myDFPlayer.loop(1); //Loop the first mp3 + myDFPlayer.pause(); //pause the mp3 + myDFPlayer.start(); //start the mp3 from the pause + myDFPlayer.playFolder(15, 4); //play specific mp3 in SD:/15/004.mp3; Folder Name(1~99); File Name(1~255) + myDFPlayer.enableLoopAll(); //loop all mp3 files. + myDFPlayer.disableLoopAll(); //stop loop all mp3 files. + myDFPlayer.playMp3Folder(4); //play specific mp3 in SD:/MP3/0004.mp3; File Name(0~65535) + myDFPlayer.advertise(3); //advertise specific mp3 in SD:/ADVERT/0003.mp3; File Name(0~65535) + myDFPlayer.stopAdvertise(); //stop advertise + myDFPlayer.playLargeFolder(2, 999); //play specific mp3 in SD:/02/004.mp3; Folder Name(1~10); File Name(1~1000) + myDFPlayer.loopFolder(5); //loop all mp3 files in folder SD:/05. + myDFPlayer.randomAll(); //Random play all the mp3. + myDFPlayer.enableLoop(); //enable loop. + myDFPlayer.disableLoop(); //disable loop. +*/ diff --git a/examples/IDEC/IDEC4_3_ServosLEDsSounds3Plyr/IDEC4_3_ServosLEDsSounds3Plyr.ino b/examples/IDEC/IDEC4_3_ServosLEDsSounds3Plyr/IDEC4_3_ServosLEDsSounds3Plyr.ino new file mode 100644 index 0000000..fb56727 --- /dev/null +++ b/examples/IDEC/IDEC4_3_ServosLEDsSounds3Plyr/IDEC4_3_ServosLEDsSounds3Plyr.ino @@ -0,0 +1,1190 @@ +// Switched Servos, LEDs Sounds to 3 Sound Players Variable Slow Servvo Travel IDEC4_3_ServosLEDsSounds3Plyr.ino +// Version 1.08 Geoff Bunza 2020 +// 5 Functions and Switched Inputs Plays Sound Sets 1-5 stepped with Leds 1-5 and Servos 1-5 +// F0 Master Decoder Disable Function Turn Function ON to disable the decoder +// F1-F5 and Switched Inputs Plays Sound Sets 1-5 stepped with Leds 1-5 and Servos 1-5 +// F6-F10 Plays Sound Sets 6-10 +// Master Disable Function Turn Function ON to disable the decoder +// Works with both short and long DCC Addesses +// Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10 + +/* +PRO MINI PIN ASSIGNMENT: +2 - DCC Input +3 - Input Pin Channel Switch1 & Function1 +4 - Input Pin Channel Switch2 & Function2 +5 - Input Pin Channel Switch3 & Function3 +6 - Input Pin Channel Switch4 & Function4 +7 - Input Pin Channel Switch5 & Function5 +8 - Servo Pin Channel 1 +9 - LED Pin Channel 1 +10 - Servo Pin Channel 2 +11 - LED Pin Channel 2 +12 - Servo Pin Channel 3 +13 - LED Pin Channel 3 +14 A0 - (TX) connected to DFPlayer2Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor +15 A1 - (TX) connected to DFPlayer1 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor +16 A2 - Input Pin for MasterDecoderDisable Active LOW & F0 +17 A3 - (TX) connected to DFPlayer3Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor +18 A4 - Servo Pin Channel 5 +19 A5 - LED Pin Channel 5 +*/ +// ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP +// ******** AFTER THE INITIAL DECODER LOAD REMOVE THE "//" IN THE FOOLOWING LINE!! +//#define DECODER_LOADED + +// ******** REMOVE THE "//" IN THE FOOLOWING LINE TO SEND DEBUGGING +// ******** INFO TO THE SERIAL MONITOR +//#define DEBUG + +#include +#include +#include +#include +SoftwareSerial DFSerial1(22,15); // PRO MINI RX, PRO MINI TX serial to DFPlayer +SoftwareSerial DFSerial2(22,14); // PRO MINI RX, PRO MINI TX serial to DFPlayer +SoftwareSerial DFSerial3(22,17); // PRO MINI RX, PRO MINI TX serial to DFPlayer +DFRobotDFPlayerMini Player1; +DFRobotDFPlayerMini Player2; +DFRobotDFPlayerMini Player3; + +SoftwareServo servo[5]; + +#define This_Decoder_Address 24 +uint8_t CV_DECODER_MASTER_RESET = 252; + +//Uncomment ONLY ONE of the following: +//#define MasterTimeConstant 10L // 10's of milliseconds Timing +#define MasterTimeConstant 100L // Tenths of a second Timing +//#define MasterTimeConstant 1000L // Seconds Timing +//#define MasterTimeConstant 10000L // 10's of Seconds Timing +//#define MasterTimeConstant 60000L // Minutes Timing +//#define MasterTimeConstant 3600000L // Hours Timing + +uint16_t ttemp, i; +#define First_Track 1 // Play Random Tracks First_Track#=Start_Track >=1 +#define Last_Track 12 // Play Random Tracks Last_Track= Last Playable Track in Range <= Last Numbered Track +const int audiocmddelay = 34; + +#define servo_master_slowdown 20 //servo loop counter limit +int servo_slow_counter = 1; //servo loop counter to slowdown servo transit +byte servo_unit_faster = 0; + +byte ss1[] = {0,0,0,0,0,0}; unsigned long ss1delay=0; +byte Ls1[] = {1,0,1,0,1,0}; +byte Vs1[] = {40,60,90,120,150,30}; +byte ss2[] = {0,0,0,0,0,0}; unsigned long ss2delay=0; +byte Ls2[] = {1,1,1,1,1,0}; +byte Vs2[] = {40,60,90,120,150,30}; +byte ss3[] = {0,0,0,0,0,0}; unsigned long ss3delay=0; +byte Ls3[] = {0,0,1,1,1,0}; +byte Vs3[] = {30,60,90,120,150,30}; +byte ss4[] = {0,0,0,0,0,0}; unsigned long ss4delay=0; +byte Ls4[] = {1,0,0,0,0,1}; +byte Vs4[] = {30,60,90,120,150,30}; +byte ss5[] = {0,0,0,0,0,0}; unsigned long ss5delay=0; +byte Ls5[] = {0,1,1,1,1,0}; +byte Vs5[] = {30,60,90,120,150,30}; +byte ss6[] = {0,0,0,0,0,0}; unsigned long ss6delay=0; +byte ss7[] = {0,0,0,0,0,0}; unsigned long ss7delay=0; +byte ss8[] = {0,0,0,0,0,0}; unsigned long ss8delay=0; +byte ss9[] = {0,0,0,0,0,0}; unsigned long ss9delay=0; +byte ss10[] = {0,0,0,0,0,0}; unsigned long ss10delay=0; +bool playing_sound_set [ ] = {false,false,false,false,false,false,false,false,false,false,false}; +byte soundset_channel[ ]={0,0,0,0,0,0,0,0,0,0,0}; +byte Vs_pins[] = {8,10,12,14,18}; //Servo pins per channel starting with 1 +byte Ls_pins[] = {0,9,11,13,17,19}; // LED pins per channel starting with 1 + +struct SERVO_TRACKING +{ + byte current_position; + byte target_position; + char delta; +}; +SERVO_TRACKING *servo_pos = new SERVO_TRACKING[5]; + +const int MasterDecoderDisablePin = 16; // D16/A0 Master Decoder Disable Input Pin Active LOW + +const int numINpins = 6; // Number of INput pins to initialize +byte inputpins [] = {3,4,5,6,7,16}; //These are all the Input Pins +const int numfpins = 10; // Number of Output pins to initialize +const int num_active_functions = 11; // Number of Functions stating with F0 +byte fpins [] = {8,9,10,11,12,13,14,17,18,19}; //These are all the Output Pins (first 15 is placeholder) +const int FunctionPin0 = 20; // Place holders ONLY +const int FunctionPin1 = 20; // Channel 1 +const int FunctionPin2 = 20; // Channel 2 +const int FunctionPin3 = 20; // Channel 3 +const int FunctionPin4 = 20; // Channel 4 +const int FunctionPin5 = 20; // Channel 5 +const int FunctionPin6 = 20; // Channel 6 +const int FunctionPin7 = 20; // Channel 7 +const int FunctionPin8 = 20; // Channel 8 +const int FunctionPin9 = 20; // Place holders ONLY +const int FunctionPin10 = 20; // Place holders ONLY +const int FunctionPin11 = 20; // Place holders ONLY +const int FunctionPin12 = 20; // Place holders ONLY +const int FunctionPin13 = 20; // Place holders ONLY +const int FunctionPin14 = 20; // Place holders ONLY +const int FunctionPin15 = 20; // Place holders ONLY +int MasterDecoderDisable = 0; +int Function0_value = 0; +byte function_value [ ] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +uint8_t cv_value; + +NmraDcc Dcc ; +DCC_MSG Packet ; +int t; // temp +struct QUEUE +{ + int inuse; + int current_position; + int increment; + int stop_value; + int start_value; +}; +QUEUE *ftn_queue = new QUEUE[17]; + +struct CVPair +{ + uint16_t CV; + uint8_t Value; +}; +CVPair FactoryDefaultCVs [] = +{ + {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address&0x7F }, + + // These two CVs define the Long DCC Address + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, ((This_Decoder_Address>>8)&0x7F)+192 }, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address&0xFF }, + + // ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS +// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps + {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps +// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps + {CV_DECODER_MASTER_RESET, 0}, + + {30, 0}, //F0 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + + {31, 1}, //F1 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {32, 2}, //F2 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {33, 3}, //F3 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {34, 4}, //F4 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {35, 5}, //F5 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {36, 6}, //F6 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {37, 7}, //F7 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {38, 8}, //F8 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {39, 9}, //F9 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {40, 10}, //F10 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + + {50, 3}, // Wait1 0-254 0.1 Seconds // SOUND SET 1 + {51, 22}, // Volume1 0-30 >30 == no volume change + {52, 1}, // Sound Clip1 + {53, 6}, // Wait2 0-254 0.1 Seconds + {54, 22}, // Volume2 0-30 >30 == no volume change + {55, 2}, // Sound Clip2 + {56, 6}, // Wait3 0-254 0.1 Seconds + {57, 20}, // Volume3 0-30 >30 == no volume change + {58, 3}, // Sound Clip3 + {59, 6}, // Wait4 0-254 0.1 Seconds + {60, 15}, // Volume4 0-30 >30 == no volume change + {61, 11}, // Sound Clip4 + {62, 11}, // Wait5 0-254 0.1 Seconds + {63, 11}, // Volume5 0-30 >30 == no volume change + {64, 12}, // Sound Clip5 + {65, 0}, // Sound Set Channel == LSB 0/1/2 + + {66, 2}, // Wait1 0-254 0.1 Seconds // SOUND SET 2 + {67, 20}, // Volume1 0-30 >30 == no volume change + {68, 4}, // Sound Clip1 + {69, 6}, // Wait2 0-254 0.1 Seconds + {70, 20}, // Volume2 0-30 >30 == no volume change + {71, 5}, // Sound Clip2 + {72, 6}, // Wait3 0-254 0.1 Seconds + {73, 20}, // Volume3 0-30 >30 == no volume change + {74, 6}, // Sound Clip3 + {75, 6}, // Wait4 0-254 0.1 Seconds + {76, 20}, // Volume4 0-30 >30 == no volume change + {77, 7}, // Sound Clip4 + {78, 6}, // Wait5 0-254 0.1 Seconds + {79, 20}, // Volume5 0-30 >30 == no volume change + {80, 8}, // Sound Clip5 + {81, 1}, // Sound Set Channel == LSB 0/1/2 + + {82, 1}, // Wait1 0-254 0.1 Seconds // SOUND SET 3 + {83, 20}, // Volume1 0-30 >30 == no volume change + {84, 5}, // Sound Clip1 + {85, 6}, // Wait2 0-254 0.1 Seconds + {86, 20}, // Volume2 0-30 >30 == no volume change + {87, 6}, // Sound Clip2 + {88, 6}, // Wait3 0-254 0.1 Seconds + {89, 20}, // Volume3 0-30 >30 == no volume change + {90, 7}, // Sound Clip3 + {91, 6}, // Wait4 0-254 0.1 Seconds + {92, 20}, // Volume4 0-30 >30 == no volume change + {93, 8}, // Sound Clip4 + {94, 6}, // Wait5 0-254 0.1 Seconds + {95, 20}, // Volume5 0-30 >30 == no volume change + {96, 8}, // Sound Clip5 + {97, 2}, // Sound Set Channel == LSB 0/1/2 + + {98, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 4 + {99, 23}, // Volume1 0-30 >30 == no volume change + {100, 9}, // Sound Clip1 + {101,110}, // Wait2 0-254 0.1 Seconds + {102, 99}, // Volume2 0-30 >30 == no volume change + {103, 0}, // Sound Clip2 + {104, 0}, // Wait3 0-254 0.1 Seconds + {105, 20}, // Volume3 0-30 >30 == no volume change + {106, 0}, // Sound Clip3 + {107, 0}, // Wait4 0-254 0.1 Seconds + {108, 99}, // Volume4 0-30 >30 == no volume change + {109, 0}, // Sound Clip4 + {110, 0}, // Wait5 0-254 0.1 Seconds + {111, 99}, // Volume5 0-30 >30 == no volume change + {112, 0}, // Sound Clip5 + {113, 0}, // Sound Set Channel == LSB 0/1/2 + + {114, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 5 + {115, 20}, // Volume1 0-30 >30 == no volume change + {116, 1}, // Sound Clip1 + {117, 20}, // Wait2 0-254 0.1 Seconds + {118, 20}, // Volume2 0-30 >30 == no volume change + {119, 2}, // Sound Clip2 + {120, 30}, // Wait3 0-254 0.1 Seconds + {121, 20}, // Volume3 0-30 >30 == no volume change + {122, 3}, // Sound Clip3 + {123, 50}, // Wait4 0-254 0.1 Seconds + {124, 20}, // Volume4 0-30 >30 == no volume change + {125, 4}, // Sound Clip4 + {126, 100}, // Wait5 0-254 0.1 Seconds + {127, 20}, // Volume5 0-30 >30 == no volume change + {128, 5}, // Sound Clip5 + {129, 1}, // Sound Set Channel == LSB 0/1/2 + + {130, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 6 + {131, 20}, // Volume1 0-30 >30 == no volume change + {132, 1}, // Sound Clip1 + {133, 20}, // Wait2 0-254 0.1 Seconds + {134, 20}, // Volume2 0-30 >30 == no volume change + {135, 2}, // Sound Clip2 + {136, 30}, // Wait3 0-254 0.1 Seconds + {137, 20}, // Volume3 0-30 >30 == no volume change + {138, 3}, // Sound Clip3 + {139, 50}, // Wait4 0-254 0.1 Seconds + {140, 20}, // Volume4 0-30 >30 == no volume change + {141, 4}, // Sound Clip4 + {142, 100}, // Wait5 0-254 0.1 Seconds + {143, 20}, // Volume5 0-30 >30 == no volume change + {144, 5}, // Sound Clip5 + {145, 2}, // Sound Set Channel == LSB 0/1/2 + + {146, 10}, // Wait1 0-254 0.1 Seconds // SOUND SET 7 + {147, 29}, // Volume1 0-30 >30 == no volume change + {148, 1}, // Sound Clip1 + {149, 10}, // Wait2 0-254 0.1 Seconds + {150, 24}, // Volume2 0-30 >30 == no volume change + {151, 2}, // Sound Clip2 + {152, 10}, // Wait3 0-254 0.1 Seconds + {153, 18}, // Volume3 0-30 >30 == no volume change + {154, 3}, // Sound Clip3 + {155, 10}, // Wait4 0-254 0.1 Seconds + {156, 12}, // Volume4 0-30 >30 == no volume change + {157, 4}, // Sound Clip4 + {158, 10}, // Wait5 0-254 0.1 Seconds + {159, 6}, // Volume5 0-30 >30 == no volume change + {160, 5}, // Sound Clip5 + {161, 0}, // Sound Set Channel == LSB 0/1/2 + + {162, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 8 + {163, 20}, // Volume1 0-30 >30 == no volume change + {164, 1}, // Sound Clip1 + {165, 20}, // Wait2 0-254 0.1 Seconds + {166, 20}, // Volume2 0-30 >30 == no volume change + {167, 2}, // Sound Clip2 + {168, 30}, // Wait3 0-254 0.1 Seconds + {169, 20}, // Volume3 0-30 >30 == no volume change + {170, 3}, // Sound Clip3 + {171, 50}, // Wait4 0-254 0.1 Seconds + {172, 20}, // Volume4 0-30 >30 == no volume change + {173, 4}, // Sound Clip4 + {174, 100}, // Wait5 0-254 0.1 Seconds + {175, 20}, // Volume5 0-30 >30 == no volume change + {176, 5}, // Sound Clip5 + {177, 1}, // Sound Set Channel == LSB 0/1/2 + + {178, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 9 + {179, 20}, // Volume1 0-30 >30 == no volume change + {180, 255}, // Sound Clip1 + {181, 11}, // Wait2 0-254 0.1 Seconds + {182, 20}, // Volume2 0-30 >30 == no volume change + {183, 255}, // Sound Clip2 + {184, 11}, // Wait3 0-254 0.1 Seconds + {185, 20}, // Volume3 0-30 >30 == no volume change + {186, 255}, // Sound Clip3 + {187, 14}, // Wait4 0-254 0.1 Seconds + {188, 20}, // Volume4 0-30 >30 == no volume change + {189, 255}, // Sound Clip4 + {190, 14}, // Wait5 0-254 0.1 Seconds + {191, 20}, // Volume5 0-30 >30 == no volume change + {192, 255}, // Sound Clip5 + {193, 2}, // Sound Set Channel == LSB 0/1/2 + + {194, 4}, // Wait1 0-254 0.1 Seconds // SOUND SET 10 + {195, 20}, // Volume1 0-30 >30 == no volume change + {196, 10}, // Sound Clip1 + {197, 110}, // Wait2 0-254 0.1 Seconds + {198, 99}, // Volume2 0-30 >30 == no volume change + {199, 0}, // Sound Clip2 + {200, 4}, // Wait3 0-254 0.1 Seconds + {201, 99}, // Volume3 0-30 >30 == no volume change + {202, 0}, // Sound Clip3 + {203, 4}, // Wait4 0-254 0.1 Seconds + {204, 12}, // Volume4 0-30 >30 == no volume change + {205, 9}, // Sound Clip4 + {206, 100}, // Wait5 0-254 0.1 Seconds + {207, 99}, // Volume5 0-30 >30 == no volume change + {208, 0}, // Sound Clip5 + {209, 0}, // Sound Set Channel == LSB 0/1/2 + + //252,252 CV_DECODER_MASTER_RESET +}; + +uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +void notifyCVResetFactoryDefault() +{ + // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset + // to flag to the loop() function that a reset to Factory Defaults needs to be done + FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +}; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS + +void setup() //****************************************************** +{ +#ifdef DEBUG + Serial.begin(115200); +#endif + DFSerial1.begin (9600); + DFSerial2.begin (9600); + DFSerial3.begin (9600); + Player1.begin (DFSerial1); + Player2.begin (DFSerial2); + Player3.begin (DFSerial3); + + // initialize the digital pins as outputs + for (int i=0; i < numfpins; i++) { + pinMode(fpins[i], OUTPUT); + digitalWrite(fpins[i], 0); // All OUPUT pins initialized LOW + } + + //Set up servos + for (i=0; i<5; i++) { + servo[i].attach(Vs_pins[i]); // Start Servos + for (t=0; t<180; t++) SoftwareServo::refresh(); + } + servo[0].write(Vs1[5]); // Set Servos Initial positions + servo_pos[0].current_position = Vs1[5]; + servo[1].write(Vs2[5]); + servo_pos[1].current_position = Vs2[5]; + servo[2].write(Vs3[5]); + servo_pos[2].current_position = Vs3[5]; + servo[3].write(Vs4[5]); + servo_pos[3].current_position = Vs4[5]; + servo[4].write(Vs5[5]); + servo_pos[4].current_position = Vs5[5]; + + pinMode (MasterDecoderDisablePin,INPUT_PULLUP); // Master Decoder Disable Input Pin Active LOW + + // initialize the digital pins as inputs + for (int i=0; i < numINpins; i++) { + pinMode ( inputpins[i], INPUT_PULLUP ); + } + + // Setup which External Interrupt, the Pin it's associated with that we're using + Dcc.pin(0, 2, 0); + // Call the main DCC Init function to enable the DCC Receiver + Dcc.init( MAN_ID_DIY, 13, FLAGS_MY_ADDRESS_ONLY, 0 ); + delay(800); +#if defined(DECODER_LOADED) + if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET ) +#endif + { + for (int j=0; j < FactoryDefaultCVIndex; j++ ) + Dcc.setCV( FactoryDefaultCVs[j].CV, FactoryDefaultCVs[j].Value); + } + // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + setVolumeOnChannel (starting_volume); +#ifdef DEBUG + Serial.println("CV Dump:"); + for (i=30; i<41; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=30; i<41; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 1"); + for (i=50; i<66; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=50; i<66; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 2"); + for (i=66; i<82; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=66; i<82; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 3"); + for (i=82; i<98; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=82; i<98; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 4"); + for (i=98; i<114; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=98; i<114; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 5"); + for (i=114; i<130; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=114; i<130; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 6"); + for (i=130; i<146; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=130; i<146; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 7"); + for (i=146; i<162; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=146; i<162; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 8"); + for (i=162; i<178; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=162; i<178; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 9"); + for (i=178; i<194; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=178; i<194; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 10"); + for (i=194; i<210; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=194; i<210; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } +#endif +} +void loop() //*********************************************************************************** +{ + //MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation + Dcc.process(); + SoftwareServo::refresh(); + if (servo_slow_counter > servo_master_slowdown) update_servos(); + else servo_slow_counter++; + delay(1); +// INPUT OVER RIDES + // Check Master Input Over ride + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + else MasterDecoderDisable = Function0_value & 1; + if (MasterDecoderDisable == 1) { + for (i=0; i < numfpins; i++) digitalWrite(fpins[i], 0); // All LEDs set LOW + } +// ******************************************************************************** + if (MasterDecoderDisable == 0) { + for (i=0; i < num_active_functions; i++) { + cv_value = Dcc.getCV(30+i) ; +#ifdef DEBUG + //Serial.print(" cv_value: "); + //Serial.println(cv_value, DEC) ; +#endif + switch ( cv_value ) { + case 0: // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + break; + case 1: // + if (((digitalRead(3)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss1[0]=1; + digitalWrite( Ls_pins[1],Ls1[0]); + set_servo (0,Vs1[0]); + playing_sound_set[cv_value]=true; + } + break; + case 2: // + if (((digitalRead(4)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss2[0]=1; + digitalWrite( Ls_pins[2],Ls2[0]); + set_servo (1,Vs2[0]); + playing_sound_set[cv_value]=true; + } + break; + case 3: // + if (((digitalRead(5)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss3[0]=1; + digitalWrite( Ls_pins[3],Ls3[0]); + set_servo (2,Vs3[0]); + playing_sound_set[cv_value]=true; } + break; + case 4: // + if (((digitalRead(6)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss4[0]=1; + digitalWrite( Ls_pins[4],Ls4[0]); + set_servo (3,Vs4[0]); + playing_sound_set[cv_value]=true; } + break; + case 5: // + if (((digitalRead(7)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss5[0]=1; + digitalWrite( Ls_pins[5],Ls5[0]); + set_servo (4,Vs5[0]); + playing_sound_set[cv_value]=true; } + break; + case 6: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss6[0]=1; playing_sound_set[cv_value]=true; } + break; + case 7: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss7[0]=1; playing_sound_set[cv_value]=true; } + break; + case 8: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss8[0]=1; playing_sound_set[cv_value]=true; } + break; + case 9: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss9[0]=1; playing_sound_set[cv_value]=true; } + break; + case 10: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss10[0]=1; playing_sound_set[cv_value]=true; } + break; + default: + break; + } + } + } + // ========================== Sound Set 1 Begin Play + if (ss1[0]==1) { + ss1delay=millis()+(long(Dcc.getCV(50)*MasterTimeConstant)); // Wait1 + ss1[0]=0; ss1[1]=1; + soundset_channel[1]=Dcc.getCV(65); //load the channel in case it updated + } + if ((ss1[1]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(52)); + setVolumeOnChannel (Dcc.getCV(51),soundset_channel[1]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[1]); // play clip 1 + ss1delay=millis()+(long(Dcc.getCV(53)*MasterTimeConstant)); // Wait2 + ss1[1]=0; ss1[2]=1; digitalWrite( Ls_pins[1],Ls1[1]); + set_servo (0,Vs1[1]); + } + if ((ss1[2]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(55)); + setVolumeOnChannel (Dcc.getCV(54),soundset_channel[1]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[1]); // play clip 2 + ss1delay=millis()+(long(Dcc.getCV(56)*MasterTimeConstant)); // Wait3 + ss1[2]=0; ss1[3]=1; digitalWrite( Ls_pins[1],Ls1[2]); + set_servo (0,Vs1[2]); + } + if ((ss1[3]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(58)); + setVolumeOnChannel (Dcc.getCV(57),soundset_channel[1]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[1]); // play clip 3 + ss1delay=millis()+(long(Dcc.getCV(59)*MasterTimeConstant)); // Wait4 + ss1[3]=0; ss1[4]=1; digitalWrite( Ls_pins[1],Ls1[3]); + set_servo (0,Vs1[3]); + } + if ((ss1[4]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(61)); + setVolumeOnChannel (Dcc.getCV(60),soundset_channel[1]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[1]); // play clip 4 + ss1delay=millis()+(long(Dcc.getCV(62)*MasterTimeConstant)); // Wait5 + ss1[4]=0; ss1[5]=1; digitalWrite( Ls_pins[1],Ls1[4]); + set_servo (0,Vs1[4]); + } + if ((ss1[5]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(64)); + setVolumeOnChannel (Dcc.getCV(63),soundset_channel[1]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[1]); // play clip 5 + ss1[5]=0; digitalWrite( Ls_pins[1],Ls1[5]); + set_servo (0,Vs1[5]); + playing_sound_set[1]=false; + } +// ========================== Sound Set 2 Begin Play + if (ss2[0]==1) { + ss2delay=millis()+(long(Dcc.getCV(66)*MasterTimeConstant)); // Wait1 + ss2[0]=0; ss2[1]=1; + soundset_channel[2]=Dcc.getCV(81); //load the channel in case it updated + } + if ((ss2[1]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(68)); + setVolumeOnChannel (Dcc.getCV(67),soundset_channel[2]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[2]); // play clip 1 + ss2delay=millis()+(long(Dcc.getCV(69)*MasterTimeConstant)); // Wait2 + ss2[1]=0; ss2[2]=1; digitalWrite( Ls_pins[2],Ls2[1]); + set_servo (1,Vs2[1]); + } + if ((ss2[2]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(71)); + setVolumeOnChannel (Dcc.getCV(70),soundset_channel[2]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[2]); // play clip 2 + ss2delay=millis()+(long(Dcc.getCV(72)*MasterTimeConstant)); // Wait3 + ss2[2]=0; ss2[3]=1; digitalWrite( Ls_pins[2],Ls2[2]); + set_servo (1,Vs2[2]); + } + if ((ss2[3]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(74)); + setVolumeOnChannel (Dcc.getCV(73),soundset_channel[2]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[2]); // play clip 3 + ss2delay=millis()+(long(Dcc.getCV(75)*MasterTimeConstant)); // Wait4 + ss2[3]=0; ss2[4]=1; digitalWrite( Ls_pins[2],Ls2[3]); + set_servo (1,Vs2[3]); + } + if ((ss2[4]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(77)); + setVolumeOnChannel (Dcc.getCV(76),soundset_channel[2]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[2]); // play clip 4 + ss2delay=millis()+(long(Dcc.getCV(78)*MasterTimeConstant)); // Wait5 + ss2[4]=0; ss2[5]=1; digitalWrite( Ls_pins[2],Ls2[4]); + set_servo (1,Vs2[4]); + } + if ((ss2[5]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(80)); + setVolumeOnChannel (Dcc.getCV(79),soundset_channel[2]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[2]); // play clip 5 + ss2[5]=0; digitalWrite( Ls_pins[2],Ls2[5]); + set_servo (1,Vs2[5]); + playing_sound_set[2]=false; + } +// ========================== Sound Set 3 Begin Play + if (ss3[0]==1) { + ss3delay=millis()+(long(Dcc.getCV(82)*MasterTimeConstant)); // Wait1 + ss3[0]=0; ss3[1]=1; + soundset_channel[3]=Dcc.getCV(97); //load the channel in case it updated + } + if ((ss3[1]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(84)); + setVolumeOnChannel (Dcc.getCV(83),soundset_channel[3]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[3]); // play clip 1 + ss3delay=millis()+(long(Dcc.getCV(85)*MasterTimeConstant)); // Wait2 + ss3[1]=0; ss3[2]=1; digitalWrite( Ls_pins[3],Ls3[1]); + set_servo (2,Vs3[1]); + } + if ((ss3[2]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(87)); + setVolumeOnChannel (Dcc.getCV(86),soundset_channel[3]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[3]); // play clip 2 + ss3delay=millis()+(long(Dcc.getCV(88)*MasterTimeConstant)); // Wait3 + ss3[2]=0; ss3[3]=1; digitalWrite( Ls_pins[3],Ls3[2]); + set_servo (2,Vs3[2]); + } + if ((ss3[3]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(90)); + setVolumeOnChannel (Dcc.getCV(89),soundset_channel[3]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[3]); // play clip 3 + ss3delay=millis()+(long(Dcc.getCV(91)*MasterTimeConstant)); // Wait4 + ss3[3]=0; ss3[4]=1; digitalWrite( Ls_pins[3],Ls3[3]); + set_servo (2,Vs3[3]); + } + if ((ss3[4]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(93)); + setVolumeOnChannel (Dcc.getCV(92),soundset_channel[3]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[3]); // play clip 4 + ss3delay=millis()+(long(Dcc.getCV(94)*MasterTimeConstant)); // Wait5 + ss3[4]=0; ss3[5]=1; digitalWrite( Ls_pins[3],Ls3[4]); + set_servo (2,Vs3[4]); + } + if ((ss3[5]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(96)); + setVolumeOnChannel (Dcc.getCV(95),soundset_channel[3]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[3]); // play clip 5 + ss3[5]=0; digitalWrite( Ls_pins[3],Ls3[5]); + set_servo (2,Vs3[5]); + playing_sound_set[3]=false; + } +// ========================== Sound Set 4 Begin Play + if (ss4[0]==1) { + ss4delay=millis()+(long(Dcc.getCV(98)*MasterTimeConstant)); // Wait1 + ss4[0]=0; ss4[1]=1; + soundset_channel[4]=Dcc.getCV(113); //load the channel in case it updated + } + if ((ss4[1]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(100)); + setVolumeOnChannel (Dcc.getCV(99),soundset_channel[4]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[4]); // play clip 1 + ss4delay=millis()+(long(Dcc.getCV(101)*MasterTimeConstant)); // Wait2 + ss4[1]=0; ss4[2]=1; digitalWrite( Ls_pins[4],Ls4[1]); + set_servo (3,Vs4[1]); + } + if ((ss4[2]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(103)); + setVolumeOnChannel (Dcc.getCV(102),soundset_channel[4]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[4]); // play clip 2 + ss4delay=millis()+(long(Dcc.getCV(104)*MasterTimeConstant)); // Wait3 + ss4[2]=0; ss4[3]=1; digitalWrite( Ls_pins[4],Ls4[2]); + set_servo (3,Vs4[2]); + } + if ((ss4[3]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(106)); + setVolumeOnChannel (Dcc.getCV(105),soundset_channel[4]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[4]); // play clip 3 + ss4delay=millis()+(long(Dcc.getCV(107)*MasterTimeConstant)); // Wait4 + ss4[3]=0; ss4[4]=1; digitalWrite( Ls_pins[4],Ls4[3]); + set_servo (3,Vs4[3]); + } + if ((ss4[4]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(109)); + setVolumeOnChannel (Dcc.getCV(108),soundset_channel[4]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[4]); // play clip 4 + ss4delay=millis()+(long(Dcc.getCV(110)*MasterTimeConstant)); // Wait5 + ss4[4]=0; ss4[5]=1; digitalWrite( Ls_pins[4],Ls4[4]); + set_servo (3,Vs4[4]); + } + if ((ss4[5]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(112)); + setVolumeOnChannel (Dcc.getCV(111),soundset_channel[4]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[4]); // play clip 5 + ss4[5]=0; digitalWrite( Ls_pins[4],Ls4[5]); + set_servo (3,Vs4[5]); + playing_sound_set[4]=false; + } +// ========================== Sound Set 5 Begin Play + if (ss5[0]==1) { + ss5delay=millis()+(long(Dcc.getCV(114)*MasterTimeConstant)); // Wait1 + ss5[0]=0; ss5[1]=1; + soundset_channel[5]=Dcc.getCV(129); //load the channel in case it updated + } + if ((ss5[1]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(116)); + setVolumeOnChannel (Dcc.getCV(115),soundset_channel[5]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[5]); // play clip 1 + ss5delay=millis()+(long(Dcc.getCV(117)*MasterTimeConstant)); // Wait2 + ss5[1]=0; ss5[2]=1; digitalWrite( Ls_pins[5],Ls5[1]); + set_servo (4,Vs5[1]); + } + if ((ss5[2]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(119)); + setVolumeOnChannel (Dcc.getCV(118),soundset_channel[5]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[5]); // play clip 2 + ss5delay=millis()+(long(Dcc.getCV(120)*MasterTimeConstant)); // Wait3 + ss5[2]=0; ss5[3]=1; digitalWrite( Ls_pins[5],Ls5[2]); + set_servo (4,Vs5[2]); + } + if ((ss5[3]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(122)); + setVolumeOnChannel (Dcc.getCV(121),soundset_channel[5]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[5]); // play clip 3 + ss5delay=millis()+(long(Dcc.getCV(123)*MasterTimeConstant)); // Wait4 + ss5[3]=0; ss5[4]=1; digitalWrite( Ls_pins[5],Ls5[3]); + set_servo (4,Vs5[3]); + } + if ((ss5[4]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(125)); + setVolumeOnChannel (Dcc.getCV(124),soundset_channel[5]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[5]); // play clip 4 + ss5delay=millis()+(long(Dcc.getCV(126)*MasterTimeConstant)); // Wait5 + ss5[4]=0; ss5[5]=1; digitalWrite( Ls_pins[5],Ls5[4]); + set_servo (4,Vs5[4]); + } + if ((ss5[5]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(128)); + setVolumeOnChannel (Dcc.getCV(127),soundset_channel[5]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[5]); // play clip 5 + ss5[5]=0; digitalWrite( Ls_pins[5],Ls5[5]); + set_servo (4,Vs5[5]); + playing_sound_set[5]=false; + } + +// ========================== Sound Set 6 Begin Play + if (ss6[0]==1) { + ss6delay=millis()+(long(Dcc.getCV(130)*MasterTimeConstant)); // Wait1 + ss6[0]=0; ss6[1]=1; + soundset_channel[6]=Dcc.getCV(145); //load the channel in case it updated + } + if ((ss6[1]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(132)); + setVolumeOnChannel (Dcc.getCV(131),soundset_channel[6]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[6]); // play clip 1 + ss6delay=millis()+(long(Dcc.getCV(133)*MasterTimeConstant)); // Wait2 + ss6[1]=0; ss6[2]=1; + } + if ((ss6[2]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(135)); + setVolumeOnChannel (Dcc.getCV(134),soundset_channel[6]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[6]); // play clip 2 + ss6delay=millis()+(long(Dcc.getCV(136)*MasterTimeConstant)); // Wait3 + ss6[2]=0; ss6[3]=1; + } + if ((ss6[3]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(138)); + setVolumeOnChannel (Dcc.getCV(137),soundset_channel[6]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[6]); // play clip 3 + ss6delay=millis()+(long(Dcc.getCV(139)*MasterTimeConstant)); // Wait4 + ss6[3]=0; ss6[4]=1; + } + if ((ss6[4]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(141)); + setVolumeOnChannel (Dcc.getCV(140),soundset_channel[6]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[6]); // play clip 4 + ss6delay=millis()+(long(Dcc.getCV(142)*MasterTimeConstant)); // Wait5 + ss6[4]=0; ss6[5]=1; + } + if ((ss6[5]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(144)); + setVolumeOnChannel (Dcc.getCV(143),soundset_channel[6]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[6]); // play clip 5 + ss6[5]=0; playing_sound_set[6]=false; + } + +// ========================== Sound Set 7 Begin Play + if (ss7[0]==1) { + ss7delay=millis()+(long(Dcc.getCV(146)*MasterTimeConstant)); // Wait1 + ss7[0]=0; ss7[1]=1; + soundset_channel[7]=Dcc.getCV(161); //load the channel in case it updated + } + if ((ss7[1]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(148)); + setVolumeOnChannel (Dcc.getCV(147),soundset_channel[7]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[7]); // play clip 1 + ss7delay=millis()+(long(Dcc.getCV(149)*MasterTimeConstant)); // Wait2 + ss7[1]=0; ss7[2]=1; + } + if ((ss7[2]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(151)); + setVolumeOnChannel (Dcc.getCV(150),soundset_channel[7]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[7]); // play clip 2 + ss7delay=millis()+(long(Dcc.getCV(152)*MasterTimeConstant)); // Wait3 + ss7[2]=0; ss7[3]=1; + } + if ((ss7[3]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(154)); + setVolumeOnChannel (Dcc.getCV(153),soundset_channel[7]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[7]); // play clip 3 + ss7delay=millis()+(long(Dcc.getCV(155)*MasterTimeConstant)); // Wait4 + ss7[3]=0; ss7[4]=1; + } + if ((ss7[4]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(157)); + setVolumeOnChannel (Dcc.getCV(156),soundset_channel[7]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[7]); // play clip 4 + ss7delay=millis()+(long(Dcc.getCV(158)*MasterTimeConstant)); // Wait5 + ss7[4]=0; ss7[5]=1; + } + if ((ss7[5]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(160)); + setVolumeOnChannel (Dcc.getCV(159),soundset_channel[7]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[7]); // play clip 5 + ss7[5]=0; playing_sound_set[7]=false; + } +// ========================== Sound Set 8 Begin Play + if (ss8[0]==1) { + ss8delay=millis()+(long(Dcc.getCV(162)*MasterTimeConstant)); // Wait1 + ss8[0]=0; ss8[1]=1; + soundset_channel[8]=Dcc.getCV(177); //load the channel in case it updated + } + if ((ss8[1]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(164)); + setVolumeOnChannel (Dcc.getCV(163),soundset_channel[8]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[8]); // play clip 1 + ss8delay=millis()+(long(Dcc.getCV(165)*MasterTimeConstant)); // Wait2 + ss8[1]=0; ss8[2]=1; + } + if ((ss8[2]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(167)); + setVolumeOnChannel (Dcc.getCV(166),soundset_channel[8]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[8]); // play clip 2 + ss8delay=millis()+(long(Dcc.getCV(168)*MasterTimeConstant)); // Wait3 + ss8[2]=0; ss8[3]=1; + } + if ((ss8[3]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(170)); + setVolumeOnChannel (Dcc.getCV(169),soundset_channel[8]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[8]); // play clip 3 + ss8delay=millis()+(long(Dcc.getCV(171)*MasterTimeConstant)); // Wait4 + ss8[3]=0; ss8[4]=1; + } + if ((ss8[4]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(173)); + setVolumeOnChannel (Dcc.getCV(172),soundset_channel[8]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[8]); // play clip 4 + ss8delay=millis()+(long(Dcc.getCV(174)*MasterTimeConstant)); // Wait5 + ss8[4]=0; ss8[5]=1; + } + if ((ss8[5]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(176)); + setVolumeOnChannel (Dcc.getCV(175),soundset_channel[8]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[8]); // play clip 5 + ss8[5]=0; playing_sound_set[8]=false; + } +// ========================== Sound Set 9 Begin Play + if (ss9[0]==1) { + ss9delay=millis()+(long(Dcc.getCV(178)*MasterTimeConstant)); // Wait1 + ss9[0]=0; ss9[1]=1; + soundset_channel[9]=Dcc.getCV(193); //load the channel in case it updated + } + if ((ss9[1]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(180)); + setVolumeOnChannel (Dcc.getCV(179),soundset_channel[9]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[9]); // play clip 1 + ss9delay=millis()+(long(Dcc.getCV(181)*MasterTimeConstant)); // Wait2 + ss9[1]=0; ss9[2]=1; + } + if ((ss9[2]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(183)); + setVolumeOnChannel (Dcc.getCV(182),soundset_channel[9]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[9]); // play clip 2 + ss9delay=millis()+(long(Dcc.getCV(184)*MasterTimeConstant)); // Wait3 + ss9[2]=0; ss9[3]=1; + } + if ((ss9[3]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(186)); + setVolumeOnChannel (Dcc.getCV(185),soundset_channel[9]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[9]); // play clip 3 + ss9delay=millis()+(long(Dcc.getCV(187)*MasterTimeConstant)); // Wait4 + ss9[3]=0; ss9[4]=1; + } + if ((ss9[4]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(189)); + setVolumeOnChannel (Dcc.getCV(188),soundset_channel[9]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[9]); // play clip 4 + ss9delay=millis()+(long(Dcc.getCV(190)*MasterTimeConstant)); // Wait5 + ss9[4]=0; ss9[5]=1; + } + if ((ss9[5]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(192)); + setVolumeOnChannel (Dcc.getCV(191),soundset_channel[9]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[9]); // play clip 5 + ss9[5]=0; playing_sound_set[9]=false; + } +// ========================== Sound Set 10 Begin Play + if (ss10[0]==1) { + ss10delay=millis()+(long(Dcc.getCV(194)*MasterTimeConstant)); // Wait1 + ss10[0]=0; ss10[1]=1; + soundset_channel[10]=Dcc.getCV(209); //load the channel in case it updated + } + if ((ss10[1]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(196)); + setVolumeOnChannel (Dcc.getCV(195),soundset_channel[10]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[10]); // play clip 1 + ss10delay=millis()+(long(Dcc.getCV(197)*MasterTimeConstant)); // Wait2 + ss10[1]=0; ss10[2]=1; + } + if ((ss10[2]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(199)); + setVolumeOnChannel (Dcc.getCV(198),soundset_channel[10]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[10]); // play clip 2 + ss10delay=millis()+(long(Dcc.getCV(200)*MasterTimeConstant)); // Wait3 + ss10[2]=0; ss10[3]=1; + } + if ((ss10[3]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(202)); + setVolumeOnChannel (Dcc.getCV(201),soundset_channel[10]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[10]); // play clip 3 + ss10delay=millis()+(long(Dcc.getCV(203)*MasterTimeConstant)); // Wait4 + ss10[3]=0; ss10[4]=1; + } + if ((ss10[4]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(205)); + setVolumeOnChannel (Dcc.getCV(204),soundset_channel[10]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[10]); // play clip 4 + ss10delay=millis()+(long(Dcc.getCV(206)*MasterTimeConstant)); // Wait5 + ss10[4]=0; ss10[5]=1; + } + if ((ss10[5]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(208)); + setVolumeOnChannel (Dcc.getCV(207),soundset_channel[10]); + if (ttemp!=0) playTrackOnChannel(ttemp,soundset_channel[10]); // play clip 5 + ss10[5]=0; playing_sound_set[10]=false; + } +} // end loop() + +void set_servo (byte servonum, byte position) { + if (servo_pos[servonum].current_position == position) { + servo_pos[servonum].delta = 0; + servo_pos[servonum].target_position = position; + return; + } + if (servo_pos[servonum].current_position < position) servo_pos[servonum].delta = 1+servo_unit_faster; + else servo_pos[servonum].delta = -1-servo_unit_faster; + servo_pos[servonum].target_position = position; +} // end set_servo() + +void update_servos() { + servo_slow_counter = 1; + for (i=0; i<5; i++) { + if (servo_pos[i].delta != 0 ) { + servo_pos[i].current_position=servo_pos[i].current_position+servo_pos[i].delta; + if ((servo_pos[i].delta > 0)&&(servo_pos[i].current_position > servo_pos[i].target_position)) + { + servo_pos[i].current_position = servo_pos[i].target_position; + servo_pos[i].delta = 0; + } + if ((servo_pos[i].delta < 0)&&(servo_pos[i].current_position < servo_pos[i].target_position)) + { + servo_pos[i].current_position = servo_pos[i].target_position; + servo_pos[i].delta = 0; + } + if (servo_pos[i].current_position == servo_pos[i].target_position) servo_pos[i].delta = 0; + } + servo[i].write ( servo_pos[i].current_position ); + } +} // end update_servos() + +void playTrackOnChannel ( byte dtrack, byte dchannel) { + switch ( dchannel ) { + case 0: + if (dtrack!=255) {Player1.play(dtrack); delay(audiocmddelay); } + else {Player1.play(random(First_Track,Last_Track+1)); delay(audiocmddelay); } + break; + case 1: + if (dtrack!=255) {Player2.play(dtrack); delay(audiocmddelay); } + else {Player2.play(random(First_Track,Last_Track+1)); delay(audiocmddelay); } + break; + case 2: + default: + if (dtrack!=255) {Player3.play(dtrack); delay(audiocmddelay); } + else {Player3.play(random(First_Track,Last_Track+1)); delay(audiocmddelay); } + break; + } +} // end playTrackOnChannel() + +void setVolumeOnChannel ( byte dvolume, byte dchannel) { + if(dvolume>30) return; // Don't change the volume if out of range + switch ( dchannel ) { + case 0: + Player1.volume (dvolume); + delay(audiocmddelay); + break; + case 1: + Player2.volume (dvolume); + delay(audiocmddelay); + break; + case 2: + default: + Player3.volume (dvolume); + delay(audiocmddelay); + break; + } +} // end setVolumeOnChannel() + +void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { +#ifdef DEBUG + //Serial.print("Addr= "); + //Serial.println(Addr, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch(FuncGrp) + { + case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1 + exec_function( 0, FunctionPin0, (FuncState & FN_BIT_00)>>4 ); + exec_function( 1, FunctionPin1, (FuncState & FN_BIT_01)); + exec_function( 2, FunctionPin2, (FuncState & FN_BIT_02)>>1); + exec_function( 3, FunctionPin3, (FuncState & FN_BIT_03)>>2 ); + exec_function( 4, FunctionPin4, (FuncState & FN_BIT_04)>>3 ); + break; + case FN_5_8: //Function Group 1 S FFFF == 1 F8 F7 F6 F5 & == 0 F12 F11 F10 F9 F8 + exec_function( 5, FunctionPin5, (FuncState & FN_BIT_05)); + exec_function( 6, FunctionPin6, (FuncState & FN_BIT_06)>>1 ); + exec_function( 7, FunctionPin7, (FuncState & FN_BIT_07)>>2 ); + exec_function( 8, FunctionPin8, (FuncState & FN_BIT_08)>>3 ); + break; + + case FN_9_12: + exec_function( 9, FunctionPin9, (FuncState & FN_BIT_09)); + exec_function( 10, FunctionPin10, (FuncState & FN_BIT_10)>>1 ); + //exec_function( 11, FunctionPin11, (FuncState & FN_BIT_11)>>2 ); + //exec_function( 12, FunctionPin12, (FuncState & FN_BIT_12)>>3 ); + break; + case FN_13_20: //Function Group 2 FuncState == F20-F13 Function Control + //exec_function( 13, FunctionPin13, (FuncState & FN_BIT_13)); + //exec_function( 14, FunctionPin14, (FuncState & FN_BIT_14)>>1 ); + //exec_function( 15, FunctionPin15, (FuncState & FN_BIT_15)>>2 ); + //exec_function( 16, FunctionPin16, (FuncState & FN_BIT_16)>>3 ); + break; + + case FN_21_28: + break; + } +} // end notifyDccFunc +void exec_function (int function, int pin, int FuncState) { +#ifdef DEBUG + //Serial.print("ex function= "); + //Serial.println(function, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch ( Dcc.getCV( 30+function) ) { // Config + case 0: // Master Disable + Function0_value = byte(FuncState); + break; + case 1: // play sound set [ function ] + + case 2: // play sound set [ function ] + + case 3: // play sound set [ function ] + + case 4: // play sound set [ function ] + + case 5: // play sound set [ function ] + + case 6: // play sound set [ function ] + + case 7: // play sound set [ function ] + + case 8: // play sound set [ function ] + + case 9: // play sound set [ function ] + + case 10: // play sound set [ function ] + function_value[function] = byte(FuncState); + break; + case 11: // + default: + break;; + } +} // end exec_function + +/* DFPlayer Commands +//----Set volume---- + myDFPlayer.volume(10); //Set volume value (0~30). + myDFPlayer.volumeUp(); //Volume Up + myDFPlayer.volumeDown(); //Volume Down + //----Set different EQ---- + myDFPlayer.EQ(DFPLAYER_EQ_NORMAL); +// myDFPlayer.EQ(DFPLAYER_EQ_POP); +// myDFPlayer.EQ(DFPLAYER_EQ_ROCK); +// myDFPlayer.EQ(DFPLAYER_EQ_JAZZ); +// myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC); +// myDFPlayer.EQ(DFPLAYER_EQ_BASS); + //----Set device we use SD as default---- +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_U_DISK); + myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_AUX); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_SLEEP); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_FLASH); + //----Mp3 control---- +// myDFPlayer.sleep(); //sleep +// myDFPlayer.reset(); //Reset the module +// myDFPlayer.enableDAC(); //Enable On-chip DAC +// myDFPlayer.disableDAC(); //Disable On-chip DAC +// myDFPlayer.outputSetting(true, 15); //output setting, enable the output and set the gain to 15 + //----Mp3 play---- + myDFPlayer.next(); //Play next mp3 + myDFPlayer.previous(); //Play previous mp3 + myDFPlayer.play(1); //Play the first mp3 + myDFPlayer.loop(1); //Loop the first mp3 + myDFPlayer.pause(); //pause the mp3 + myDFPlayer.start(); //start the mp3 from the pause + myDFPlayer.playFolder(15, 4); //play specific mp3 in SD:/15/004.mp3; Folder Name(1~99); File Name(1~255) + myDFPlayer.enableLoopAll(); //loop all mp3 files. + myDFPlayer.disableLoopAll(); //stop loop all mp3 files. + myDFPlayer.playMp3Folder(4); //play specific mp3 in SD:/MP3/0004.mp3; File Name(0~65535) + myDFPlayer.advertise(3); //advertise specific mp3 in SD:/ADVERT/0003.mp3; File Name(0~65535) + myDFPlayer.stopAdvertise(); //stop advertise + myDFPlayer.playLargeFolder(2, 999); //play specific mp3 in SD:/02/004.mp3; Folder Name(1~10); File Name(1~1000) + myDFPlayer.loopFolder(5); //loop all mp3 files in folder SD:/05. + myDFPlayer.randomAll(); //Random play all the mp3. + myDFPlayer.enableLoop(); //enable loop. + myDFPlayer.disableLoop(); //disable loop. +*/ diff --git a/examples/IDEC/IDEC4_4_ServosLEDsSoundsCV/IDEC4_4_ServosLEDsSoundsCV.ino b/examples/IDEC/IDEC4_4_ServosLEDsSoundsCV/IDEC4_4_ServosLEDsSoundsCV.ino new file mode 100644 index 0000000..c2ed565 --- /dev/null +++ b/examples/IDEC/IDEC4_4_ServosLEDsSoundsCV/IDEC4_4_ServosLEDsSoundsCV.ino @@ -0,0 +1,1213 @@ +// Switched Pins Servos, LEDs Sounds Variable Slow Servvo Travel IDEC4_4_ServosLEDsSoundsCV.ino +// Servo Positions and LED controls set by CV dynamically +// Version 1.08 Geoff Bunza 2020 +// 5 Functions and Switched Inputs Plays Sound Sets 1-5 stepped with Leds 1-5 and Servos 1-5 +// F0 Master Decoder Disable Function Turn Function ON to disable the decoder +// F1-F5 and Switched Inputs Plays Sound Sets 1-5 stepped with Leds 1-5 and Servos 1-5 +// F6 Plays Sound Sets 6 +// Master Disable Function Turn Function ON to disable the decoder +// Works with both short and long DCC Addesses +// Config 0=DISABLE On/Off,1-16=Sound Set Control 1-6 + +/* +PRO MINI PIN ASSIGNMENT: +2 - DCC Input +3 - Input Pin Channel Switch1 & Function1 +4 - Input Pin Channel Switch2 & Function2 +5 - Input Pin Channel Switch3 & Function3 +6 - Input Pin Channel Switch4 & Function4 +7 - Input Pin Channel Switch5 & Function5 +8 - Servo Pin Channel 1 +9 - LED Pin Channel 1 +10 - Servo Pin Channel 2 +11 - LED Pin Channel 2 +12 - Servo Pin Channel 3 +13 - LED Pin Channel 3 +14 A0 - Servo Pin Channel 4 +15 A1 - (TX) connected to DFPlayer1 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor +16 A2 - Input Pin for MasterDecoderDisable Active LOW & F0 +17 A3 - LED Pin Channel 4 +18 A4 - Servo Pin Channel 5 +19 A5 - LED Pin Channel 5 +*/ +// ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP +// ******** AFTER THE INITIAL DECODER LOAD REMOVE THE "//" IN THE FOOLOWING LINE!! +//#define DECODER_LOADED + +// ******** REMOVE THE "//" IN THE FOOLOWING LINE TO SEND DEBUGGING +// ******** INFO TO THE SERIAL MONITOR +//#define DEBUG + +#include +#include +#include +#include +SoftwareSerial DFSerial1(22,15); // PRO MINI RX, PRO MINI TX serial to DFPlayer +DFRobotDFPlayerMini Player1; + +SoftwareServo servo[5]; + +#define This_Decoder_Address 24 +uint8_t CV_DECODER_MASTER_RESET = 252; + +//Uncomment ONLY ONE of the following: +//#define MasterTimeConstant 10L // 10's of milliseconds Timing +#define MasterTimeConstant 100L // Tenths of a second Timing +//#define MasterTimeConstant 1000L // Seconds Timing +//#define MasterTimeConstant 10000L // 10's of Seconds Timing +//#define MasterTimeConstant 60000L // Minutes Timing +//#define MasterTimeConstant 3600000L // Hours Timing + +uint16_t ttemp, i; +#define First_Track 1 // Play Random Tracks First_Track#=Start_Track >=1 +#define Last_Track 12 // Play Random Tracks Last_Track= Last Playable Track in Range <= Last Numbered Track +#define starting_volume 21 // If no volume is set use this at the start +const int audiocmddelay = 34; + +#define servo_master_slowdown 9 //servo loop counter limit +int servo_slow_counter = 1; //servo loop counter to slowdown servo transit +byte servo_unit_faster = 0; + + // Vsx and Lsx are all loaded from CVs +byte ss1[] = {0,0,0,0,0,0}; unsigned long ss1delay=0; // Time state variabler for the set +byte Ls1[] = {1,0,1,0,1,0}; // LED states set by CV_load()at setup() +byte Vs1[] = {0,0,0,0,0,0}; // Servo Positions set by CV_load()at setup() +byte ss2[] = {0,0,0,0,0,0}; unsigned long ss2delay=0; // Time state variabler for the set +byte Ls2[] = {1,1,1,1,1,0}; // LED states set by CV_load()at setup() +byte Vs2[] = {0,0,0,0,0,0}; // Servo Positions set by CV_load()at setup() +byte ss3[] = {0,0,0,0,0,0}; unsigned long ss3delay=0; // Time state variabler for the set +byte Ls3[] = {0,0,1,1,1,0}; // LED states set by CV_load()at setup() +byte Vs3[] = {0,0,0,0,0,0}; // Servo Positions set by CV_load()at setup() +byte ss4[] = {0,0,0,0,0,0}; unsigned long ss4delay=0; // Time state variabler for the set +byte Ls4[] = {1,0,0,0,0,1}; // LED states set by CV_load()at setup() +byte Vs4[] = {0,0,0,0,0,0}; // Servo Positions set by CV_load()at setup() +byte ss5[] = {0,0,0,0,0,0}; unsigned long ss5delay=0; // Time state variabler for the set +byte Ls5[] = {0,1,1,1,1,0}; // LED states set by CV_load()at setup() +byte Vs5[] = {0,0,0,0,0,0}; // Servo Positions set by CV_load()at setup() +byte ss6[] = {0,0,0,0,0,0}; unsigned long ss6delay=0; // Time state variabler for the set +byte ss7[] = {0,0,0,0,0,0}; unsigned long ss7delay=0; // Time state variabler for the set +byte ss8[] = {0,0,0,0,0,0}; unsigned long ss8delay=0; // Time state variabler for the set +byte ss9[] = {0,0,0,0,0,0}; unsigned long ss9delay=0; // Time state variabler for the set +byte ss10[] = {0,0,0,0,0,0}; unsigned long ss10delay=0; // Time state variabler for the set +bool playing_sound_set [ ] = {false,false,false,false,false,false,false,false,false,false,false}; +byte soundset_channel[ ]={0,0,0,0,0,0,0,0,0,0,0}; +byte Vs_pins[] = {8,10,12,14,18}; //Servo pins per channel starting with 1 +byte Ls_pins[] = {0,13,11,9,17,19}; // LED pins per channel starting with 1 + +struct SERVO_TRACKING +{ + byte current_position; + byte target_position; + char delta; +}; +SERVO_TRACKING *servo_pos = new SERVO_TRACKING[5]; + +const int MasterDecoderDisablePin = 16; // D16/A0 Master Decoder Disable Input Pin Active LOW + +const int numINpins = 6; // Number of INput pins to initialize +byte inputpins [] = {3,4,5,6,7,16}; //These are all the Input Pins +const int numfpins = 10; // Number of Output pins to initialize +const int num_active_functions = 11; // Number of Functions stating with F0 +byte fpins [] = {8,9,10,11,12,13,14,17,18,19}; //These are all the Output Pins (first 15 is placeholder) +const int FunctionPin0 = 20; // Place holders ONLY +const int FunctionPin1 = 20; // Channel 1 +const int FunctionPin2 = 20; // Channel 2 +const int FunctionPin3 = 20; // Channel 3 +const int FunctionPin4 = 20; // Channel 4 +const int FunctionPin5 = 20; // Channel 5 +const int FunctionPin6 = 20; // Channel 6 +const int FunctionPin7 = 20; // Channel 7 +const int FunctionPin8 = 20; // Channel 8 +const int FunctionPin9 = 20; // Place holders ONLY +const int FunctionPin10 = 20; // Place holders ONLY +const int FunctionPin11 = 20; // Place holders ONLY +int MasterDecoderDisable = 0; +int Function0_value = 0; +byte function_value [ ] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +uint8_t cv_value; + +NmraDcc Dcc ; +DCC_MSG Packet ; +int t; // temp +struct QUEUE +{ + int inuse; + int current_position; + int increment; + int stop_value; + int start_value; +}; +QUEUE *ftn_queue = new QUEUE[17]; + +struct CVPair +{ + uint16_t CV; + uint8_t Value; +}; +CVPair FactoryDefaultCVs [] = +{ + {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address&0x7F }, + + // These two CVs define the Long DCC Address + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, ((This_Decoder_Address>>8)&0x7F)+192 }, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address&0xFF }, + + // ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS +// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps + {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps +// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps + {CV_DECODER_MASTER_RESET, 0}, + + {30, 0}, //F0 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + + {31, 1}, //F1 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {32, 2}, //F2 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {33, 3}, //F3 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {34, 4}, //F4 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {35, 5}, //F5 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {36, 6}, //F6 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {37, 7}, //F7 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {38, 8}, //F8 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {39, 9}, //F9 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {40, 10}, //F10 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + + {41, 22}, //F11 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {42, 22}, //F12 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {43, 22}, //F13 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {44, 22}, //F14Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {45, 22}, //F15 not used + + {50, 6}, // Wait1 0-254 0.1 Seconds // SOUND SET 1 + {51, 55}, // Volume1 0-30 >30 == no volume change + {52, 4}, // Sound Clip1 + {53, 13}, // Wait2 0-254 0.1 Seconds + {54, 55}, // Volume2 0-30 >30 == no volume change + {55, 4}, // Sound Clip2 + {56, 13}, // Wait3 0-254 0.1 Seconds + {57, 55}, // Volume3 0-30 >30 == no volume change + {58, 4}, // Sound Clip3 + {59, 13}, // Wait4 0-254 0.1 Seconds + {60, 55}, // Volume4 0-30 >30 == no volume change + {61, 4}, // Sound Clip4 + {62, 8}, // Wait5 0-254 0.1 Seconds + {63, 55}, // Volume5 0-30 >30 == no volume change + {64, 0}, // Sound Clip5 + {65, 0}, // Sound Set Channel == LSB 0/1 + + {66, 2}, // Wait1 0-254 0.1 Seconds // SOUND SET 2 + {67, 20}, // Volume1 0-30 >30 == no volume change + {68, 4}, // Sound Clip1 + {69, 6}, // Wait2 0-254 0.1 Seconds + {70, 20}, // Volume2 0-30 >30 == no volume change + {71, 5}, // Sound Clip2 + {72, 6}, // Wait3 0-254 0.1 Seconds + {73, 20}, // Volume3 0-30 >30 == no volume change + {74, 6}, // Sound Clip3 + {75, 6}, // Wait4 0-254 0.1 Seconds + {76, 20}, // Volume4 0-30 >30 == no volume change + {77, 7}, // Sound Clip4 + {78, 6}, // Wait5 0-254 0.1 Seconds + {79, 20}, // Volume5 0-30 >30 == no volume change + {80, 8}, // Sound Clip5 + {81, 1}, // Sound Set Channel == LSB 0/1 + + {82, 1}, // Wait1 0-254 0.1 Seconds // SOUND SET 3 + {83, 20}, // Volume1 0-30 >30 == no volume change + {84, 5}, // Sound Clip1 + {85, 6}, // Wait2 0-254 0.1 Seconds + {86, 20}, // Volume2 0-30 >30 == no volume change + {87, 6}, // Sound Clip2 + {88, 6}, // Wait3 0-254 0.1 Seconds + {89, 20}, // Volume3 0-30 >30 == no volume change + {90, 7}, // Sound Clip3 + {91, 6}, // Wait4 0-254 0.1 Seconds + {92, 20}, // Volume4 0-30 >30 == no volume change + {93, 8}, // Sound Clip4 + {94, 6}, // Wait5 0-254 0.1 Seconds + {95, 20}, // Volume5 0-30 >30 == no volume change + {96, 8}, // Sound Clip5 + {97, 0}, // Sound Set Channel == LSB 0/1 + + {98, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 4 + {99, 23}, // Volume1 0-30 >30 == no volume change + {100, 9}, // Sound Clip1 + {101,110}, // Wait2 0-254 0.1 Seconds + {102, 99}, // Volume2 0-30 >30 == no volume change + {103, 0}, // Sound Clip2 + {104, 0}, // Wait3 0-254 0.1 Seconds + {105, 20}, // Volume3 0-30 >30 == no volume change + {106, 0}, // Sound Clip3 + {107, 0}, // Wait4 0-254 0.1 Seconds + {108, 99}, // Volume4 0-30 >30 == no volume change + {109, 0}, // Sound Clip4 + {110, 0}, // Wait5 0-254 0.1 Seconds + {111, 99}, // Volume5 0-30 >30 == no volume change + {112, 0}, // Sound Clip5 + {113, 0}, // Sound Set Channel == LSB 0/1 + + {114, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 5 + {115, 20}, // Volume1 0-30 >30 == no volume change + {116, 1}, // Sound Clip1 + {117, 20}, // Wait2 0-254 0.1 Seconds + {118, 20}, // Volume2 0-30 >30 == no volume change + {119, 2}, // Sound Clip2 + {120, 30}, // Wait3 0-254 0.1 Seconds + {121, 20}, // Volume3 0-30 >30 == no volume change + {122, 3}, // Sound Clip3 + {123, 50}, // Wait4 0-254 0.1 Seconds + {124, 20}, // Volume4 0-30 >30 == no volume change + {125, 4}, // Sound Clip4 + {126, 100}, // Wait5 0-254 0.1 Seconds + {127, 20}, // Volume5 0-30 >30 == no volume change + {128, 5}, // Sound Clip5 + {129, 0}, // Sound Set Channel == LSB 0/1 + + {130, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 6 + {131, 20}, // Volume1 0-30 >30 == no volume change + {132, 1}, // Sound Clip1 + {133, 20}, // Wait2 0-254 0.1 Seconds + {134, 20}, // Volume2 0-30 >30 == no volume change + {135, 2}, // Sound Clip2 + {136, 30}, // Wait3 0-254 0.1 Seconds + {137, 20}, // Volume3 0-30 >30 == no volume change + {138, 3}, // Sound Clip3 + {139, 50}, // Wait4 0-254 0.1 Seconds + {140, 20}, // Volume4 0-30 >30 == no volume change + {141, 4}, // Sound Clip4 + {142, 100}, // Wait5 0-254 0.1 Seconds + {143, 20}, // Volume5 0-30 >30 == no volume change + {144, 5}, // Sound Clip5 + {145, 1}, // Sound Set Channel == LSB 0/1 + // ================================================ + {146, 140}, // Servo Set 1 140,40,140,40,140,90 + {147, 50}, // + {148, 140}, // + {149, 50}, // + {150, 140}, // + {151, 90}, // + + {152, 40}, // Servo Set 2 40,60,90,120,150,30 + {153, 60}, // + {154, 90}, // + {155, 120}, // + {156, 150}, // + {157, 30}, // + + {158, 30}, // Servo Set 3 30,60,90,120,150,30 + {159, 60}, // + {160, 90}, // + {161, 120}, // + {162, 150}, // + {163, 30}, // + + {164, 30}, // Servo Set 4 30,60,90,120,150,30 + {165, 60}, // + {166, 90}, // + {167, 120}, // + {168, 150}, // + {169, 30}, // + + {170, 30}, // Servo Set 5 30,50,90,120,150,30 + {171, 50}, // + {172, 90}, // + {173, 120}, // + {174, 150}, // + {175, 30}, // + + {176, 1}, // LED Set 1 1,0,1,0,1,0 + {177, 0}, // + {178, 1}, // + {179, 0}, // + {180, 1}, // + {181, 0}, // + + {182, 1}, // LED Set 2 1,1,1,1,1,0 + {183, 1}, // + {184, 1}, // + {185, 1}, // + {186, 1}, // + {187, 0}, // + + {188, 1}, // LED Set 3 0,0,1,1,1,0 + {189, 0}, // + {190, 1}, // + {191, 0}, // + {192, 1}, // + {193, 0}, // + + {194, 1}, // LED Set 4 1,0,0,0,0,1 + {195, 0}, // + {196, 0}, // + {197, 0}, // + {198, 0}, // + {199, 1}, // + + {200, 0}, // LED Set 5 0,1,1,1,1,0 + {201, 1}, // + {202, 1}, // + {203, 1}, // + {204, 1}, // + {205, 0}, // + + {206, 0}, // Extra + //252,252 CV_DECODER_MASTER_RESET +}; + +uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +void notifyCVResetFactoryDefault() +{ + // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset + // to flag to the loop() function that a reset to Factory Defaults needs to be done + FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +}; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS + +void setup() //****************************************************** +{ +#ifdef DEBUG + Serial.begin(115200); +#endif + DFSerial1.begin (9600); + Player1.begin (DFSerial1); + + // initialize the digital pins as outputs + for (int i=0; i < numfpins; i++) { + pinMode(fpins[i], OUTPUT); + digitalWrite(fpins[i], 0); // All OUPUT pins initialized LOW + } + CV_load( ); // Load all relevant CVs + //Set up servos + for (i=0; i<5; i++) { + servo[i].attach(Vs_pins[i]); // Start Servos + //for (t=0; t<180; t++) SoftwareServo::refresh(); + } + servo[0].write(Vs1[5]); // Set Servos Initial positions + SoftwareServo::refresh(); + servo_pos[0].current_position = Vs1[5]; + servo[1].write(Vs2[5]); + SoftwareServo::refresh(); + servo_pos[1].current_position = Vs2[5]; + servo[2].write(Vs3[5]); + SoftwareServo::refresh(); + servo_pos[2].current_position = Vs3[5]; + servo[3].write(Vs4[5]); + SoftwareServo::refresh(); + servo_pos[3].current_position = Vs4[5]; + servo[4].write(Vs5[5]); + SoftwareServo::refresh(); + servo_pos[4].current_position = Vs5[5]; + for (i=0; i<5; i++) servo_pos[i].delta = 0; + + pinMode (MasterDecoderDisablePin,INPUT_PULLUP); // Master Decoder Disable Input Pin Active LOW + + // initialize the digital pins as inputs + for (int i=0; i < numINpins; i++) { + pinMode ( inputpins[i], INPUT_PULLUP ); + } + // Setup which External Interrupt, the Pin it's associated with that we're using + Dcc.pin(0, 2, 0); + // Call the main DCC Init function to enable the DCC Receiver + Dcc.init( MAN_ID_DIY, 61, FLAGS_MY_ADDRESS_ONLY, 0 ); + delay(800); +#if defined(DECODER_LOADED) + if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET ) +#endif + { + for (int j=0; j < FactoryDefaultCVIndex; j++ ) + Dcc.setCV( FactoryDefaultCVs[j].CV, FactoryDefaultCVs[j].Value); + } + // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + setVolumeOnChannel (starting_volume); +#ifdef DEBUG + Serial.println("CV Dump:"); + for (i=30; i<45; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=30; i<45; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 1"); + for (i=50; i<66; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=50; i<66; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 2"); + for (i=66; i<82; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=66; i<82; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 3"); + for (i=82; i<98; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=82; i<98; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 4"); + for (i=98; i<114; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=98; i<114; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 5"); + for (i=114; i<130; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=114; i<130; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 6"); + for (i=130; i<146; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=130; i<146; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Servo Set 1"); + for (i=146; i<152; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=146; i<152; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Servo Set 2"); + for (i=152; i<158; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=152; i<158; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Servo Set 3"); + for (i=158; i<164; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=158; i<164; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Servo Set 4"); + for (i=164; i<170; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=164; i<170; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Servo Set 5"); + for (i=170; i<176; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=170; i<176; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("LED Set 1"); + for (i=176; i<182; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=176; i<182; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("LED Set 2"); + for (i=182; i<188; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=182; i<188; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("LED Set 3"); + for (i=188; i<194; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=188; i<194; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("LED Set 4"); + for (i=194; i<200; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=194; i<200; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("LED Set 5"); + for (i=200; i<206; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=200; i<206; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } +#endif +} +void loop() //*********************************************************************************** +{ + //MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation + Dcc.process(); + SoftwareServo::refresh(); + if (servo_slow_counter > servo_master_slowdown) update_servos(); + else servo_slow_counter++; + delay(1); +// INPUT OVER RIDES + // Check Master Input Over ride + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + else MasterDecoderDisable = Function0_value & 1; + if (MasterDecoderDisable == 1) { + for (i=0; i < numfpins; i++) digitalWrite(fpins[i], 0); // All LEDs set LOW + } +// ******************************************************************************** + if (MasterDecoderDisable == 0) { + for (i=0; i < num_active_functions; i++) { + cv_value = Dcc.getCV(30+i) ; +#ifdef DEBUG + //Serial.print(" cv_value: "); + //Serial.println(cv_value, DEC) ; +#endif + switch ( cv_value ) { + case 0: // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + break; + case 1: // + if (((digitalRead(3)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss1[0]=1; + playing_sound_set[cv_value]=true; + } + break; + case 2: // + if (((digitalRead(4)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss2[0]=1; + digitalWrite( Ls_pins[2],Ls2[0]); + set_servo (1,Vs2[0]); + playing_sound_set[cv_value]=true; + } + break; + case 3: // + if (((digitalRead(5)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss3[0]=1; + digitalWrite( Ls_pins[3],Ls3[0]); + set_servo (2,Vs3[0]); + playing_sound_set[cv_value]=true; } + break; + case 4: // + if (((digitalRead(6)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss4[0]=1; + digitalWrite( Ls_pins[4],Ls4[0]); + set_servo (3,Vs4[0]); + playing_sound_set[cv_value]=true; } + break; + case 5: // + if (((digitalRead(7)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss5[0]=1; + digitalWrite( Ls_pins[5],Ls5[0]); + set_servo (4,Vs5[0]); + playing_sound_set[cv_value]=true; } + break; + case 6: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss6[0]=1; playing_sound_set[cv_value]=true; } + break; + case 7: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss7[0]=1; playing_sound_set[cv_value]=true; } + break; + case 8: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss8[0]=1; playing_sound_set[cv_value]=true; } + break; + case 9: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss9[0]=1; playing_sound_set[cv_value]=true; } + break; + case 10: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss10[0]=1; playing_sound_set[cv_value]=true; } + break; + default: + break; + } + } + } + // ========================== Sound Set 1 Begin Play + if (ss1[0]==1) { + digitalWrite( Ls_pins[1],Ls1[0]); + set_servo (0,Vs1[0]); + ss1delay=millis()+(long(Dcc.getCV(50)*MasterTimeConstant)); // Wait1 + ss1[0]=0; ss1[1]=1; + } + if ((ss1[1]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(52)); + setVolumeOnChannel (Dcc.getCV(51)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss1delay=millis()+(long(Dcc.getCV(53)*MasterTimeConstant)); // Wait2 + ss1[1]=0; ss1[2]=1; digitalWrite( Ls_pins[1],Ls1[1]); + set_servo (0,Vs1[1]); + } + if ((ss1[2]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(55)); + setVolumeOnChannel (Dcc.getCV(54)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss1delay=millis()+(long(Dcc.getCV(56)*MasterTimeConstant)); // Wait3 + ss1[2]=0; ss1[3]=1; digitalWrite( Ls_pins[1],Ls1[2]); + set_servo (0,Vs1[2]); + } + if ((ss1[3]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(58)); + setVolumeOnChannel (Dcc.getCV(57)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss1delay=millis()+(long(Dcc.getCV(59)*MasterTimeConstant)); // Wait4 + ss1[3]=0; ss1[4]=1; digitalWrite( Ls_pins[1],Ls1[3]); + set_servo (0,Vs1[3]); + } + if ((ss1[4]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(61)); + setVolumeOnChannel (Dcc.getCV(60)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss1delay=millis()+(long(Dcc.getCV(62)*MasterTimeConstant)); // Wait5 + ss1[4]=0; ss1[5]=1; digitalWrite( Ls_pins[1],Ls1[4]); + set_servo (0,Vs1[4]); + } + if ((ss1[5]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(64)); + setVolumeOnChannel (Dcc.getCV(63)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss1[5]=0; digitalWrite( Ls_pins[1],Ls1[5]); + set_servo (0,Vs1[5]); + playing_sound_set[1]=false; + } +// ========================== Sound Set 2 Begin Play + if (ss2[0]==1) { + ss2delay=millis()+(long(Dcc.getCV(66)*MasterTimeConstant)); // Wait1 + ss2[0]=0; ss2[1]=1; + } + if ((ss2[1]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(68)); + setVolumeOnChannel (Dcc.getCV(67)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss2delay=millis()+(long(Dcc.getCV(69)*MasterTimeConstant)); // Wait2 + ss2[1]=0; ss2[2]=1; digitalWrite( Ls_pins[2],Ls2[1]); + set_servo (1,Vs2[1]); + } + if ((ss2[2]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(71)); + setVolumeOnChannel (Dcc.getCV(70)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss2delay=millis()+(long(Dcc.getCV(72)*MasterTimeConstant)); // Wait3 + ss2[2]=0; ss2[3]=1; digitalWrite( Ls_pins[2],Ls2[2]); + set_servo (1,Vs2[2]); + } + if ((ss2[3]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(74)); + setVolumeOnChannel (Dcc.getCV(73)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss2delay=millis()+(long(Dcc.getCV(75)*MasterTimeConstant)); // Wait4 + ss2[3]=0; ss2[4]=1; digitalWrite( Ls_pins[2],Ls2[3]); + set_servo (1,Vs2[3]); + } + if ((ss2[4]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(77)); + setVolumeOnChannel (Dcc.getCV(76)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss2delay=millis()+(long(Dcc.getCV(78)*MasterTimeConstant)); // Wait5 + ss2[4]=0; ss2[5]=1; digitalWrite( Ls_pins[2],Ls2[4]); + set_servo (1,Vs2[4]); + } + if ((ss2[5]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(80)); + setVolumeOnChannel (Dcc.getCV(79)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss2[5]=0; digitalWrite( Ls_pins[2],Ls2[5]); + set_servo (1,Vs2[5]); + playing_sound_set[2]=false; + } +// ========================== Sound Set 3 Begin Play + if (ss3[0]==1) { + ss3delay=millis()+(long(Dcc.getCV(82)*MasterTimeConstant)); // Wait1 + ss3[0]=0; ss3[1]=1; + } + if ((ss3[1]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(84)); + setVolumeOnChannel (Dcc.getCV(83)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss3delay=millis()+(long(Dcc.getCV(85)*MasterTimeConstant)); // Wait2 + ss3[1]=0; ss3[2]=1; digitalWrite( Ls_pins[3],Ls3[1]); + set_servo (2,Vs3[1]); + } + if ((ss3[2]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(87)); + setVolumeOnChannel (Dcc.getCV(86)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss3delay=millis()+(long(Dcc.getCV(88)*MasterTimeConstant)); // Wait3 + ss3[2]=0; ss3[3]=1; digitalWrite( Ls_pins[3],Ls3[2]); + set_servo (2,Vs3[2]); + } + if ((ss3[3]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(90)); + setVolumeOnChannel (Dcc.getCV(89)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss3delay=millis()+(long(Dcc.getCV(91)*MasterTimeConstant)); // Wait4 + ss3[3]=0; ss3[4]=1; digitalWrite( Ls_pins[3],Ls3[3]); + set_servo (2,Vs3[3]); + } + if ((ss3[4]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(93)); + setVolumeOnChannel (Dcc.getCV(92)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss3delay=millis()+(long(Dcc.getCV(94)*MasterTimeConstant)); // Wait5 + ss3[4]=0; ss3[5]=1; digitalWrite( Ls_pins[3],Ls3[4]); + set_servo (2,Vs3[4]); + } + if ((ss3[5]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(96)); + setVolumeOnChannel (Dcc.getCV(95)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss3[5]=0; digitalWrite( Ls_pins[3],Ls3[5]); + set_servo (2,Vs3[5]); + playing_sound_set[3]=false; + } +// ========================== Sound Set 4 Begin Play + if (ss4[0]==1) { + ss4delay=millis()+(long(Dcc.getCV(98)*MasterTimeConstant)); // Wait1 + ss4[0]=0; ss4[1]=1; + } + if ((ss4[1]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(100)); + setVolumeOnChannel (Dcc.getCV(99)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss4delay=millis()+(long(Dcc.getCV(101)*MasterTimeConstant)); // Wait2 + ss4[1]=0; ss4[2]=1; digitalWrite( Ls_pins[4],Ls4[1]); + set_servo (3,Vs4[1]); + } + if ((ss4[2]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(103)); + setVolumeOnChannel (Dcc.getCV(102)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss4delay=millis()+(long(Dcc.getCV(104)*MasterTimeConstant)); // Wait3 + ss4[2]=0; ss4[3]=1; digitalWrite( Ls_pins[4],Ls4[2]); + set_servo (3,Vs4[2]); + } + if ((ss4[3]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(106)); + setVolumeOnChannel (Dcc.getCV(105)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss4delay=millis()+(long(Dcc.getCV(107)*MasterTimeConstant)); // Wait4 + ss4[3]=0; ss4[4]=1; digitalWrite( Ls_pins[4],Ls4[3]); + set_servo (3,Vs4[3]); + } + if ((ss4[4]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(109)); + setVolumeOnChannel (Dcc.getCV(108)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss4delay=millis()+(long(Dcc.getCV(110)*MasterTimeConstant)); // Wait5 + ss4[4]=0; ss4[5]=1; digitalWrite( Ls_pins[4],Ls4[4]); + set_servo (3,Vs4[4]); + } + if ((ss4[5]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(112)); + setVolumeOnChannel (Dcc.getCV(111)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss4[5]=0; digitalWrite( Ls_pins[4],Ls4[5]); + set_servo (3,Vs4[5]); + playing_sound_set[4]=false; + } +// ========================== Sound Set 5 Begin Play + if (ss5[0]==1) { + ss5delay=millis()+(long(Dcc.getCV(114)*MasterTimeConstant)); // Wait1 + ss5[0]=0; ss5[1]=1; + } + if ((ss5[1]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(116)); + setVolumeOnChannel (Dcc.getCV(115)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss5delay=millis()+(long(Dcc.getCV(117)*MasterTimeConstant)); // Wait2 + ss5[1]=0; ss5[2]=1; digitalWrite( Ls_pins[5],Ls5[1]); + set_servo (4,Vs5[1]); + } + if ((ss5[2]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(119)); + setVolumeOnChannel (Dcc.getCV(118)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss5delay=millis()+(long(Dcc.getCV(120)*MasterTimeConstant)); // Wait3 + ss5[2]=0; ss5[3]=1; digitalWrite( Ls_pins[5],Ls5[2]); + set_servo (4,Vs5[2]); + } + if ((ss5[3]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(122)); + setVolumeOnChannel (Dcc.getCV(121)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss5delay=millis()+(long(Dcc.getCV(123)*MasterTimeConstant)); // Wait4 + ss5[3]=0; ss5[4]=1; digitalWrite( Ls_pins[5],Ls5[3]); + set_servo (4,Vs5[3]); + } + if ((ss5[4]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(125)); + setVolumeOnChannel (Dcc.getCV(124)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss5delay=millis()+(long(Dcc.getCV(126)*MasterTimeConstant)); // Wait5 + ss5[4]=0; ss5[5]=1; digitalWrite( Ls_pins[5],Ls5[4]); + set_servo (4,Vs5[4]); + } + if ((ss5[5]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(128)); + setVolumeOnChannel (Dcc.getCV(127)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss5[5]=0; digitalWrite( Ls_pins[5],Ls5[5]); + set_servo (4,Vs5[5]); + playing_sound_set[5]=false; + } + +// ========================== Sound Set 6 Begin Play + if (ss6[0]==1) { + ss6delay=millis()+(long(Dcc.getCV(130)*MasterTimeConstant)); // Wait1 + ss6[0]=0; ss6[1]=1; + } + if ((ss6[1]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(132)); + setVolumeOnChannel (Dcc.getCV(131)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss6delay=millis()+(long(Dcc.getCV(133)*MasterTimeConstant)); // Wait2 + ss6[1]=0; ss6[2]=1; + } + if ((ss6[2]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(135)); + setVolumeOnChannel (Dcc.getCV(134)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss6delay=millis()+(long(Dcc.getCV(136)*MasterTimeConstant)); // Wait3 + ss6[2]=0; ss6[3]=1; + } + if ((ss6[3]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(138)); + setVolumeOnChannel (Dcc.getCV(137)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss6delay=millis()+(long(Dcc.getCV(139)*MasterTimeConstant)); // Wait4 + ss6[3]=0; ss6[4]=1; + } + if ((ss6[4]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(141)); + setVolumeOnChannel (Dcc.getCV(140)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss6delay=millis()+(long(Dcc.getCV(142)*MasterTimeConstant)); // Wait5 + ss6[4]=0; ss6[5]=1; + } + if ((ss6[5]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(144)); + setVolumeOnChannel (Dcc.getCV(143)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss6[5]=0; playing_sound_set[6]=false; + } + +// ========================== Sound Set 7 Begin Play + if (ss7[0]==1) { + ss7delay=millis()+(long(Dcc.getCV(146)*MasterTimeConstant)); // Wait1 + ss7[0]=0; ss7[1]=1; + } + if ((ss7[1]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(148)); + setVolumeOnChannel (Dcc.getCV(147)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss7delay=millis()+(long(Dcc.getCV(149)*MasterTimeConstant)); // Wait2 + ss7[1]=0; ss7[2]=1; + } + if ((ss7[2]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(151)); + setVolumeOnChannel (Dcc.getCV(150)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss7delay=millis()+(long(Dcc.getCV(152)*MasterTimeConstant)); // Wait3 + ss7[2]=0; ss7[3]=1; + } + if ((ss7[3]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(154)); + setVolumeOnChannel (Dcc.getCV(153)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss7delay=millis()+(long(Dcc.getCV(155)*MasterTimeConstant)); // Wait4 + ss7[3]=0; ss7[4]=1; + } + if ((ss7[4]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(157)); + setVolumeOnChannel (Dcc.getCV(156)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss7delay=millis()+(long(Dcc.getCV(158)*MasterTimeConstant)); // Wait5 + ss7[4]=0; ss7[5]=1; + } + if ((ss7[5]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(160)); + setVolumeOnChannel (Dcc.getCV(159)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss7[5]=0; playing_sound_set[7]=false; + } +// ========================== Sound Set 8 Begin Play + if (ss8[0]==1) { + ss8delay=millis()+(long(Dcc.getCV(162)*MasterTimeConstant)); // Wait1 + ss8[0]=0; ss8[1]=1; + } + if ((ss8[1]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(164)); + setVolumeOnChannel (Dcc.getCV(163)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss8delay=millis()+(long(Dcc.getCV(165)*MasterTimeConstant)); // Wait2 + ss8[1]=0; ss8[2]=1; + } + if ((ss8[2]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(167)); + setVolumeOnChannel (Dcc.getCV(166)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss8delay=millis()+(long(Dcc.getCV(168)*MasterTimeConstant)); // Wait3 + ss8[2]=0; ss8[3]=1; + } + if ((ss8[3]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(170)); + setVolumeOnChannel (Dcc.getCV(169)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss8delay=millis()+(long(Dcc.getCV(171)*MasterTimeConstant)); // Wait4 + ss8[3]=0; ss8[4]=1; + } + if ((ss8[4]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(173)); + setVolumeOnChannel (Dcc.getCV(172)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss8delay=millis()+(long(Dcc.getCV(174)*MasterTimeConstant)); // Wait5 + ss8[4]=0; ss8[5]=1; + } + if ((ss8[5]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(176)); + setVolumeOnChannel (Dcc.getCV(175)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss8[5]=0; playing_sound_set[8]=false; + } +// ========================== Sound Set 9 Begin Play + if (ss9[0]==1) { + ss9delay=millis()+(long(Dcc.getCV(178)*MasterTimeConstant)); // Wait1 + ss9[0]=0; ss9[1]=1; + } + if ((ss9[1]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(180)); + setVolumeOnChannel (Dcc.getCV(179)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss9delay=millis()+(long(Dcc.getCV(181)*MasterTimeConstant)); // Wait2 + ss9[1]=0; ss9[2]=1; + } + if ((ss9[2]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(183)); + setVolumeOnChannel (Dcc.getCV(182)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss9delay=millis()+(long(Dcc.getCV(184)*MasterTimeConstant)); // Wait3 + ss9[2]=0; ss9[3]=1; + } + if ((ss9[3]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(186)); + setVolumeOnChannel (Dcc.getCV(185)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss9delay=millis()+(long(Dcc.getCV(187)*MasterTimeConstant)); // Wait4 + ss9[3]=0; ss9[4]=1; + } + if ((ss9[4]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(189)); + setVolumeOnChannel (Dcc.getCV(188)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss9delay=millis()+(long(Dcc.getCV(190)*MasterTimeConstant)); // Wait5 + ss9[4]=0; ss9[5]=1; + } + if ((ss9[5]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(192)); + setVolumeOnChannel (Dcc.getCV(191)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss9[5]=0; playing_sound_set[9]=false; + } +// ========================== Sound Set 10 Begin Play + if (ss10[0]==1) { + ss10delay=millis()+(long(Dcc.getCV(194)*MasterTimeConstant)); // Wait1 + ss10[0]=0; ss10[1]=1; + } + if ((ss10[1]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(196)); + setVolumeOnChannel (Dcc.getCV(195)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss10delay=millis()+(long(Dcc.getCV(197)*MasterTimeConstant)); // Wait2 + ss10[1]=0; ss10[2]=1; + } + if ((ss10[2]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(199)); + setVolumeOnChannel (Dcc.getCV(198)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss10delay=millis()+(long(Dcc.getCV(200)*MasterTimeConstant)); // Wait3 + ss10[2]=0; ss10[3]=1; + } + if ((ss10[3]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(202)); + setVolumeOnChannel (Dcc.getCV(201)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss10delay=millis()+(long(Dcc.getCV(203)*MasterTimeConstant)); // Wait4 + ss10[3]=0; ss10[4]=1; + } + if ((ss10[4]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(205)); + setVolumeOnChannel (Dcc.getCV(204)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss10delay=millis()+(long(Dcc.getCV(206)*MasterTimeConstant)); // Wait5 + ss10[4]=0; ss10[5]=1; + } + if ((ss10[5]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(208)); + setVolumeOnChannel (Dcc.getCV(207)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss10[5]=0; playing_sound_set[10]=false; + } +} // end loop() + +void set_servo (byte servonum, byte position) { + if (servo_pos[servonum].current_position == position) { + servo_pos[servonum].delta = 0; + servo_pos[servonum].target_position = position; + return; + } + if (servo_pos[servonum].current_position < position) servo_pos[servonum].delta = 1+servo_unit_faster; + else servo_pos[servonum].delta = -1-servo_unit_faster; + servo_pos[servonum].target_position = position; +} // end set_servo() + +void update_servos() { + servo_slow_counter = 1; + for (i=0; i<5; i++) { + if (servo_pos[i].delta != 0 ) { + servo_pos[i].current_position=servo_pos[i].current_position+servo_pos[i].delta; + if ((servo_pos[i].delta > 0)&&(servo_pos[i].current_position > servo_pos[i].target_position)) + { + servo_pos[i].current_position = servo_pos[i].target_position; + servo_pos[i].delta = 0; + } + if ((servo_pos[i].delta < 0)&&(servo_pos[i].current_position < servo_pos[i].target_position)) + { + servo_pos[i].current_position = servo_pos[i].target_position; + servo_pos[i].delta = 0; + } + if (servo_pos[i].current_position == servo_pos[i].target_position) servo_pos[i].delta = 0; + } + servo[i].write ( servo_pos[i].current_position ); + } +} // end update_servos() + +void playTrackOnChannel ( byte dtrack) { + if (dtrack!=255) {Player1.play(dtrack); delay(audiocmddelay); } + else {Player1.play(random(First_Track,Last_Track+1));} // delay(audiocmddelay); } +} +void setVolumeOnChannel ( byte dvolume) { + if(dvolume>30) return; // Don't change the volume if out of range + Player1.volume (dvolume); + delay(audiocmddelay); +} + +void notifyCVChange( uint16_t CV, uint8_t Value) { +#ifdef DEBUG + //Serial.print("CV= "); + //Serial.println(CV, DEC) ; + //Serial.print("Value= "); + //Serial.println(Value, DEC) ; +#endif + if (( CV > 145 )&&( CV < 176)) CV_load(); +} // end notifyCVChange() + +void CV_load( ) { + for (i=0; i<6; i++) { + Vs1[i]= Dcc.getCV(146+i); // if a CV changes update all the internals + Vs2[i]= Dcc.getCV(152+i); + Vs3[i]= Dcc.getCV(158+i); + Vs4[i]= Dcc.getCV(164+i); + Vs5[i]= Dcc.getCV(170+i); + Ls1[i]= Dcc.getCV(176+i); + Ls2[i]= Dcc.getCV(182+i); + Ls3[i]= Dcc.getCV(188+i); + Ls4[i]= Dcc.getCV(194+i); + Ls5[i]= Dcc.getCV(200+i); + } +} // end CV_load() + +void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { +#ifdef DEBUG + //Serial.print("Addr= "); + //Serial.println(Addr, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch(FuncGrp) + { + case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1 + exec_function( 0, FunctionPin0, (FuncState & FN_BIT_00)>>4 ); + exec_function( 1, FunctionPin1, (FuncState & FN_BIT_01)); + exec_function( 2, FunctionPin2, (FuncState & FN_BIT_02)>>1); + exec_function( 3, FunctionPin3, (FuncState & FN_BIT_03)>>2 ); + exec_function( 4, FunctionPin4, (FuncState & FN_BIT_04)>>3 ); + break; + case FN_5_8: //Function Group 1 S FFFF == 1 F8 F7 F6 F5 & == 0 F12 F11 F10 F9 F8 + exec_function( 5, FunctionPin5, (FuncState & FN_BIT_05)); + exec_function( 6, FunctionPin6, (FuncState & FN_BIT_06)>>1 ); + exec_function( 7, FunctionPin7, (FuncState & FN_BIT_07)>>2 ); + exec_function( 8, FunctionPin8, (FuncState & FN_BIT_08)>>3 ); + break; + + case FN_9_12: + exec_function( 9, FunctionPin9, (FuncState & FN_BIT_09)); + exec_function( 10, FunctionPin10, (FuncState & FN_BIT_10)>>1 ); + //exec_function( 11, FunctionPin11, (FuncState & FN_BIT_11)>>2 ); + //exec_function( 12, FunctionPin12, (FuncState & FN_BIT_12)>>3 ); + break; + case FN_13_20: //Function Group 2 FuncState == F20-F13 Function Control + //exec_function( 13, FunctionPin13, (FuncState & FN_BIT_13)); + //exec_function( 14, FunctionPin14, (FuncState & FN_BIT_14)>>1 ); + //exec_function( 15, FunctionPin15, (FuncState & FN_BIT_15)>>2 ); + //exec_function( 16, FunctionPin16, (FuncState & FN_BIT_16)>>3 ); + break; + + case FN_21_28: + break; + } +} // end notifyDccFunc +void exec_function (int function, int pin, int FuncState) { +#ifdef DEBUG + //Serial.print("ex function= "); + //Serial.println(function, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch ( Dcc.getCV( 30+function) ) { // Config + case 0: // Master Disable + Function0_value = byte(FuncState); + break; + case 1: // play sound set [ function ] + + case 2: // play sound set [ function ] + + case 3: // play sound set [ function ] + + case 4: // play sound set [ function ] + + case 5: // play sound set [ function ] + + case 6: // play sound set [ function ] + + case 7: // play sound set [ function ] + + case 8: // play sound set [ function ] + + case 9: // play sound set [ function ] + + case 10: // play sound set [ function ] + function_value[function] = byte(FuncState); + break; + case 11: // + default: + break;; + } +} // end exec_function + +/* DFPlayer Commands +//----Set volume---- + myDFPlayer.volume(10); //Set volume value (0~30). + myDFPlayer.volumeUp(); //Volume Up + myDFPlayer.volumeDown(); //Volume Down + //----Set different EQ---- + myDFPlayer.EQ(DFPLAYER_EQ_NORMAL); +// myDFPlayer.EQ(DFPLAYER_EQ_POP); +// myDFPlayer.EQ(DFPLAYER_EQ_ROCK); +// myDFPlayer.EQ(DFPLAYER_EQ_JAZZ); +// myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC); +// myDFPlayer.EQ(DFPLAYER_EQ_BASS); + //----Set device we use SD as default---- +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_U_DISK); + myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_AUX); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_SLEEP); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_FLASH); + //----Mp3 control---- +// myDFPlayer.sleep(); //sleep +// myDFPlayer.reset(); //Reset the module +// myDFPlayer.enableDAC(); //Enable On-chip DAC +// myDFPlayer.disableDAC(); //Disable On-chip DAC +// myDFPlayer.outputSetting(true, 15); //output setting, enable the output and set the gain to 15 + //----Mp3 play---- + myDFPlayer.next(); //Play next mp3 + myDFPlayer.previous(); //Play previous mp3 + myDFPlayer.play(1); //Play the first mp3 + myDFPlayer.loop(1); //Loop the first mp3 + myDFPlayer.pause(); //pause the mp3 + myDFPlayer.start(); //start the mp3 from the pause + myDFPlayer.playFolder(15, 4); //play specific mp3 in SD:/15/004.mp3; Folder Name(1~99); File Name(1~255) + myDFPlayer.enableLoopAll(); //loop all mp3 files. + myDFPlayer.disableLoopAll(); //stop loop all mp3 files. + myDFPlayer.playMp3Folder(4); //play specific mp3 in SD:/MP3/0004.mp3; File Name(0~65535) + myDFPlayer.advertise(3); //advertise specific mp3 in SD:/ADVERT/0003.mp3; File Name(0~65535) + myDFPlayer.stopAdvertise(); //stop advertise + myDFPlayer.playLargeFolder(2, 999); //play specific mp3 in SD:/02/004.mp3; Folder Name(1~10); File Name(1~1000) + myDFPlayer.loopFolder(5); //loop all mp3 files in folder SD:/05. + myDFPlayer.randomAll(); //Random play all the mp3. + myDFPlayer.enableLoop(); //enable loop. + myDFPlayer.disableLoop(); //disable loop. +*/ diff --git a/examples/IDEC/IDEC_Decoders_Library.pdf b/examples/IDEC/IDEC_Decoders_Library.pdf new file mode 100644 index 0000000..bac216f Binary files /dev/null and b/examples/IDEC/IDEC_Decoders_Library.pdf differ diff --git a/examples/IDECDemo&Diags/IDEC1_1_MotSoundBell_Demo1_8K/IDEC1_1_MotSoundBell_Demo1_8K.ino b/examples/IDECDemo&Diags/IDEC1_1_MotSoundBell_Demo1_8K/IDEC1_1_MotSoundBell_Demo1_8K.ino new file mode 100644 index 0000000..a232ce5 --- /dev/null +++ b/examples/IDECDemo&Diags/IDEC1_1_MotSoundBell_Demo1_8K/IDEC1_1_MotSoundBell_Demo1_8K.ino @@ -0,0 +1,735 @@ +// Interactive Decoder Motor, Pauses, Reversals w/Sound 4 LED IDEC1_1_MotSound4Led.ino +// Version 1.08 Geoff Bunza 2020 +// Works with both short and long DCC Addesses +// This decoder uses switches/sensors to control 2 motors and Five LEDs with Sound +// F0=Master Function OFF = Function ON DISABLES the decoder +// Input Pin for Decoder Disable Pin 16 Active LOW +//Motor speed via DCC speed for one motor, second motor on/off via function +//Speed Over-Ride = CV = Non-Zero Value (1-127) over-rides the DCC speed commands Bit 8 is direction 1=Forward +//Input1 Pin for Throttle Down/Pause/Throttle Up Pin 5 +// CV for Throttle Down Time, CV for Throttle Up Time,, CV for Pause Time +//Input2 Pin for Throttle Down/Pause/Throttle Up Pin 6 +// CV for Throttle Down Time, CV for Throttle Up Time,, CV for Pause Time +//Input Pin1 for Throttle Down/Reverse/Throttle Up Pin 7 +// CV for Throttle Down Time, CV for Throttle Up Time;,CV for Reverse Pause Time +//Input Pin2 for Throttle Down/Reverse/Throttle Up Pin 8 +// CV for Throttle Down Time, CV for Throttle Up Time;,CV for Reverse Pause Time +//Input Pin for immediate Stop Pin 11 +//Input Pin for Immediate Start Pin 12 +//Functions for lights on/off: +// F1-F5 5 Functions LED ON/OFF by default PINS 13,14,17,18,19 +/* Pro Mini D15 A1 (TX) connected to DFPlayer1 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor + * Remember to connect +5V and GND to the DFPlayer too: DFPLAYER PINS 1 & 7 respectively + * This is a “mobile/function” decoder with audio play to dual motor control and + * LED functions. Audio tracks or clips are stored on a micro SD card for playing, + * in a folder labeled mp3, with tracks named 0001.mp3, 0002.mp3, etc. + * MAX 3 Configurations per pin function: + * Config 0=Decoder DISABLE On/Off, 1=LED; 2=Motor2 Control On/Off + F0 == Master Decoder Disable == ON + F1 == LED == D13 + F2 == LED == D14/A0 + F3 == LED == D17/A3 + F4 == LED == D18/A4 + F5 == LED == D19/A5 + F6 == Motor2 On/OFF speed & direction set by CV 80 Normally Base Station will Transmit F5 as initial OFF + If no DCC present Decoder will power up with Motor2 ON at speed specified in CV 72 + Motor1 speed control is via throttle or overridden by non zero value in CV 50 + High Bit=Direction, Lower 7 Bits=Speed == DSSSSSSS + +PRO MINI PIN ASSIGNMENT: +2 - DCC Input +3 - m2h Motor Control +4 - m2l Motor Control +5 - Input1 Pin for Throttle Down/Pause/Throttle Up +6 - Input2 Pin for Throttle Down/Pause/Throttle Up +7 - Input1 Pin for Throttle Down/Reverse/Throttle Up +8 - Input2 Pin for Throttle Down/Reverse/Throttle Up +9 - m0h Motor Control +10 - m0l Motor Control +11 - Input Pin for immediate Stop +12 - Input Pin for Immediate Start +13 - LED F1 +14 A0 - LED F2 +15 A1 - (TX) connected to DFPlayer1 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor +16 A2 - Input Pin for MasterDecoderDisable Active LOW +17 A3 - LED F3 +18 A4 - LED F4 +19 A5 - LED F5 +*/ + +// ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP +// ******** AFTER THE INITIAL DECODER LOAD REMOVE THE "//" IN THE FOOLOWING LINE!! +#define DECODER_LOADED + +// ******** REMOVE THE "//" IN THE FOLLOWING LINE TO SEND DEBUGGING +// ******** INFO TO THE SERIAL MONITOR +//#define DEBUG + +// ******** REMOVE THE "//" IN THE FOLLOWING LINE TO INCLUDE THE PAUSE 1 SENSOR +//#define Pause1 + +// ******** REMOVE THE "//" IN THE FOLLOWING LINE TO INCLUDE THE PAUSE 2 SENSOR +//#define Pause2 + +// ******** REMOVE THE "//" IN THE FOLLOWING LINE TO INCLUDE THE REVERSE 1 SENSOR +#define Reverse1 + +// ******** REMOVE THE "//" IN THE FOLLOWING LINE TO INCLUDE THE REVERSE 2 SENSOR +//#define Reverse2 + +// ******** REMOVE THE "//" IN THE FOLLOWING LINE TO INCLUDE THE IMMEDIATE STOP SENSOR +//#define ImmediateStop + +// ******** REMOVE THE "//" IN THE FOLLOWING LINE TO INCLUDE THE IMMEDIATE START SENSOR +//#define ImmediateStart + +#include +#include +#include +SoftwareSerial DFSerial1(21,15); // PRO MINI RX, PRO MINI TX serial to DFPlayer +DFRobotDFPlayerMini Player1; + +#define This_Decoder_Address 24 +uint8_t CV_DECODER_MASTER_RESET = 252; + +//Uncomment ONLY ONE of the following: +//#define MasterTimeConstant 10L // 10's of milliseconds Timing +#define MasterTimeConstant 100L // Tenths of a second Timing +//#define MasterTimeConstant 1000L // Seconds Timing +//#define MasterTimeConstant 10000L // 10's of Seconds Timing +//#define MasterTimeConstant 60000L // Minutes Timing +//#define MasterTimeConstant 3600000L // Hours Timing + +uint16_t ttemp, i; +#define First_Track 1 // Play Random Tracks First_Track#=Start_Track >=1 +#define Last_Track 2 // Play Random Tracks Last_Track= Last Playable Track in Range <= Last Numbered Track +#define starting_volume 22 // If no volume is set use this at the start +const int audiocmddelay = 34; + +boolean Use_DCC_speed = true; // Switch to disable DCC Speed updates +int Motor1Speed = 0; // Variablw for Motor1 Speed +int Starting_Motor1Speed = 0; +int Motor1ForwardDir = 1; // Variable for Motor1 Dir +int ForcedStopSpeedMotor1 = 0; // Holding Variablw for Last Speed when Immediate Stop +int ForcedStopDirMotor1 = 1; // Holding Variablw for Last Direction when Immediate Stop +int Motor2Speed = 0; // Variable for Motor2 Speed +int Motor2ForwardDir = 1; // Variable for Motor2 Dir +int Motor2ON = 0; +int cyclewidth = 8192; + +const int m2h = 3; //R H Bridge Motor1 +const int m2l = 4; //B H Bridge Motor1 +const int ThrottlePause1Pin = 5; // Throttle Speed Pause1 Input Pin +const int ThrottlePause2Pin = 6; // Throttle Speed Pause2 Input Pin +const int ThrottleInputReverse1Pin = 7; // Throttle Speed Reverse Input Pin +const int ThrottleInputReverse2Pin = 8; // Throttle Immediate Speed Reverse Input Pin +const int m0h = 9; //R H Bridge Motor2 +const int m0l = 10; //B H Bridge //Motor2 +const int ImmediateStopPin = 11; // Throttle Immediate Stop Input Pin +const int ImmediateStartPin = 12; // Throttle Immediate Start Input Pin +const int MasterDecoderDisablePin = 16; // D16/A0 Master Decoder Disable Input Pin Active LOW +// arduino pin D 15; // D15/A1 DFPlayer Receive (RX) Pin 2 via 470 Ohm Resistor + +const int numfpins = 10; // Number of Output pins to initialize +const int num_active_functions = 7; // Number of Functions stating with F0 +byte fpins [] = {13,13,14,17,18,19,3,4,9,10}; //These are all the Output Pins (first 13 is placeholder) +const int FunctionPin0 = 20; // D14/A0 DFPlayer Transmit (TX) Pin 3 +const int FunctionPin1 = 13; // A2 LED +const int FunctionPin2 = 14; // A3 LED +const int FunctionPin3 = 17; // A4 LED +const int FunctionPin4 = 18; // A5 LED +const int FunctionPin5 = 19; // A6 LED + +const int FunctionPin6 = 20; // Turns on Motor2 DCC Function Control Only NO Local Input Pin +const int FunctionPin7 = 20; // Place holders ONLY +const int FunctionPin8 = 20; // Place holders ONLY +const int FunctionPin9 = 20; // Place holders ONLY +const int FunctionPin10 = 20; // Place holders ONLY +const int FunctionPin11 = 20; // Place holders ONLY +const int FunctionPin12 = 20; // Place holders ONLY +const int FunctionPin13 = 20; // Place holders ONLY +const int FunctionPin14 = 20; // Place holders ONLY +const int FunctionPin15 = 20; // Place holders ONLY +const int FunctionPin16 = 20; // Place holders ONLY +int MasterDecoderDisable = 0; +int Function0_value = 0; + +NmraDcc Dcc ; +DCC_MSG Packet ; +int t; // temp +struct QUEUE +{ + int inuse; + int current_position; + int increment; + int stop_value; + int start_value; +}; +QUEUE *ftn_queue = new QUEUE[17]; + +struct CVPair +{ + uint16_t CV; + uint8_t Value; +}; +CVPair FactoryDefaultCVs [] = +{ + {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address&0x7F }, + + // These two CVs define the Long DCC Address + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, ((This_Decoder_Address>>8)&0x7F)+192 }, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address&0xFF }, + + // ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS +// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps + {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps +// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps + {CV_DECODER_MASTER_RESET, 0}, + + {30, 0}, //F0 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + + {31, 1}, //F1 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {32, 1}, //F2 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {33, 1}, //F3 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {34, 1}, //F4 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {35, 1}, //F5 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + + {36, 2}, //F6 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + + {37,4}, //F7 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {38,4}, //F8 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {39,4}, //F9 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {40,4}, //F10 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {41,4}, //F11 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {42,4}, //F12 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {43,4}, //F13 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {44,4}, //F14 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {45,4}, //F15 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {46,4}, //F16 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {47,4}, //F17 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {48,4}, //F18 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {49,4}, //F19 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + + {50, 0}, // Speed Over-Ride = CV = Non-Zero Value (1-127) over-rides the DCC speed commands + // Bit 8 (128 or 0x80) ON=Forward Direction 0=Reverse Direction + + {51, 0}, // ThrottlePause1 Pause Time 0-255 (0.1 secs) + {52, 0}, // ThrottlePause1 Throttle Ramp DOWN Delay 0-255 Larger Delay=Slower Ramp Down + {53, 0}, // ThrottlePause1 Throttle Ramp UP Delay 0-255 Larger Delay=Slower Ramp Up + {54, 11}, // ThrottlePause1 Pause Sound Clip 1-nn 0=No Sound + {55, 55}, // ThrottlePause1 Pause Sound Clip Volume 0-30 + + {56, 0}, // ThrottlePause2 Pause Time 0-255 (0.1 secs) + {57, 0}, // ThrottlePause2 Throttle Ramp DOWN 0-255 Delay + {58, 0}, // ThrottlePause2 Throttle Ramp UP Delay 0-255 + {59, 11}, // ThrottlePause2 Pause Sound Clip 1-nn 0=No Sound + {60, 55}, // ThrottlePause2 Pause Sound Clip Volume 0-30 + + {61, 0}, // ThrottleInputReverse1 Pause Time 0-255 (0.1 secs) + {62, 0}, // ThrottleInputReverse1 Ramp DOWN Delay 0-255 + {63, 0}, // ThrottleInputReverse1 Ramp UP Delay 0-255 + {64, 11}, // ThrottleInputReverse1 Sound Clip 1-nn 0=No Sound + {65, 55}, // ThrottleInputReverse1 Sound Clip Volume 0-30 + + {66, 0}, // ThrottleInputReverse2 Pause Time 0-255 (0.1 secs) + {67, 0}, // ThrottleInputReverse2 Ramp DOWN Delay 0-255 + {68, 0}, // ThrottleInputReverse2 Ramp UP Delay 0-255 + {69, 11}, // ThrottleInputReverse2 Sound Clip 1-nn 0=No Sound + {70, 55}, // ThrottleInputReverse2 Sound Clip Volume 0-30 + + {71, 0}, // ThrottleImmediateStop Sound Clip 1-nn 0=No Sound + {72, 55}, // ThrottleImmediateStop Sound Clip Volume 0-30 + + {73, 0}, // ThrottleImmediateStart Sound Clip 1-nn 0=No Sound + {74, 55}, // ThrottleImmediateStart Sound Clip Volume 0-30 + + {80, 0}, // Motor2 Speed 0-127 Bit 8 (128 or 0x80) ON=Forward Direction 0=Reverse Direction + + //252,252 CV_DECODER_MASTER_RESET + + {253, 0}, // Extra +}; + +uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +void notifyCVResetFactoryDefault() +{ + // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset + // to flag to the loop() function that a reset to Factory Defaults needs to be done + FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +}; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS + +void setup() //****************************************************** +{ +#ifdef DEBUG + Serial.begin(115200); +#endif + DFSerial1.begin (9600); + Player1.begin (DFSerial1); + + pinMode (ThrottlePause1Pin,INPUT_PULLUP); // Throttle Speed Pause1 Input Pin Active LOW + pinMode (ThrottlePause2Pin,INPUT_PULLUP); // Throttle Speed Pause2 Input Pin Active LOW + pinMode (ThrottleInputReverse1Pin,INPUT_PULLUP); // Throttle Speed Reverse Input Pin 1 Active LOW + pinMode (ThrottleInputReverse2Pin,INPUT_PULLUP); // Throttle Speed Reverse Input Pin 2 Active LOW + pinMode (ImmediateStopPin,INPUT_PULLUP); // Throttle Immediate Stop Input Pin Active LOW + pinMode (ImmediateStartPin,INPUT_PULLUP); // Throttle Immediate Start Input Pin Active LOW + pinMode (MasterDecoderDisablePin,INPUT_PULLUP); // Master Decoder Disable Input Pin Active LOW + uint8_t cv_value; + // initialize the digital pins as outputs + for (int i=0; i < numfpins; i++) { + pinMode(fpins[i], OUTPUT); + digitalWrite(fpins[i], 0); // All OUPUT pins initialized LOW + } + // Setup which External Interrupt, the Pin it's associated with that we're using + Dcc.pin(0, 2, 0); + // Call the main DCC Init function to enable the DCC Receiver + Dcc.init( MAN_ID_DIY, 61, FLAGS_MY_ADDRESS_ONLY, 0 ); + delay(800); +#if defined(DECODER_LOADED) + if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET ) +#endif + { + for (int j=0; j < FactoryDefaultCVIndex; j++ ) + Dcc.setCV( FactoryDefaultCVs[j].CV, FactoryDefaultCVs[j].Value); + } + for ( i=0; i < num_active_functions; i++) { + cv_value = Dcc.getCV(30+i) ; + switch ( cv_value ) { + case 0: // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + break; + case 1: // LED On/Off + ftn_queue[i].inuse = 0; + break; + case 2: // Motor2 Control + if ( Dcc.getCV(72) != 0) { + Motor2ON = 1; + Motor2Speed = (Dcc.getCV(72))&0x7f ; + Motor2ForwardDir = (byte)((Dcc.getCV(72))&0x80)>>7 ; + } else Motor2ON = 0; + break; + case 3: // NEXT FEATURE for the Future + break; + default: + break; + } + } + setVolumeOnChannel (starting_volume); + Motor1ForwardDir = 1; // Default start value for direction if throttle controlled + if ( Dcc.getCV(50) != 0) { + Motor1Speed = (Dcc.getCV(50))&0x7f ; + Motor1ForwardDir = (byte)((Dcc.getCV(50))&0x80 )>>7; + } +#ifdef DEBUG + Serial.println("CV Dump:"); + for (i=30; i<51; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + + Serial.println("Throttle Pause 1"); + for (i=51; i<56; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + + Serial.println("Throttle Pause 2"); + for (i=56; i<61; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + + Serial.println("Throttle Reverse 1"); + for (i=61; i<66; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + + Serial.println("Throttle Reverse 2"); + for (i=66; i<71; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + + Serial.println("Immediate Stop"); + for (i=71; i<73; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + + Serial.println("Immediate Start"); + for (i=73; i<75; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + + Serial.println("Motor2 Speed"); + Serial.print(Dcc.getCV(80),DEC); Serial.print("\t"); } + Serial.println(""); +#endif +} +void loop() //********************************************************************** +{ + //MUST call the NmraDcc.process() method frequently + // from the Arduino loop() function for correct library operation + //Dcc.process(); + run_at_speed(); + //delay(1); + +// INPUT OVER RIDES + // Check Master Input Over ride + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + else MasterDecoderDisable = Function0_value & 1; + if (MasterDecoderDisable == 1) { Motor1Speed = 0; Motor2Speed = 0; } + +#ifdef Pause1 +// ======== Throttle Pause 1 ======================== + if (digitalRead(ThrottlePause1Pin) == LOW) { // Throttle Speed Pause1 Input Pin + Use_DCC_speed = false; // Do not update speed via DCC + Starting_Motor1Speed = Motor1Speed; + while (Motor1Speed >0) { + --Motor1Speed; + run_at_speed(); + delay(Dcc.getCV(52)); //Throttle Ramp DOWN Delay 0-255 + } + Motor1Speed = 0; + ttemp=(Dcc.getCV(54)); + setVolumeOnChannel (Dcc.getCV(55)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip + delay(int(Dcc.getCV(51)*MasterTimeConstant)); //Pause Time 0-255 (0.1 secs) + while (Motor1Speed <= Starting_Motor1Speed) { + ++Motor1Speed; + run_at_speed(); + delay(Dcc.getCV(53)); //Throttle Ramp UP Delay 0-255 + } + Motor1Speed = Starting_Motor1Speed; + for (i=0; i<30; i++) run_at_speed(); // Move away from sensor + while (digitalRead(ThrottlePause1Pin) == LOW) run_at_speed(); //Wait for Sensor + Use_DCC_speed = true; // Do not update speed via DCC + } +#endif + +#ifdef Pause2 +// ======== Throttle Pause 2 ======================== + if (digitalRead(ThrottlePause2Pin) == LOW) { // Throttle Speed Pause2 Input Pin + + Use_DCC_speed = false; // Do not update speed via DCC + Starting_Motor1Speed = Motor1Speed; + while (Motor1Speed >0) { + --Motor1Speed; + run_at_speed(); + delay(Dcc.getCV(57)); //Throttle Ramp DOWN Delay 0-255 + } + Motor1Speed = 0; + ttemp=(Dcc.getCV(59)); + setVolumeOnChannel (Dcc.getCV(60)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip + delay(int(Dcc.getCV(56)*MasterTimeConstant)); //Pause Time 0-255 (0.1 secs) + while (Motor1Speed <= Starting_Motor1Speed) { + ++Motor1Speed; + run_at_speed(); + delay(Dcc.getCV(58)); //Throttle Ramp UP Delay 0-255 + } + Motor1Speed = Starting_Motor1Speed; + for (i=0; i<30; i++) run_at_speed(); // Move away from sensor + while (digitalRead(ThrottlePause2Pin) == LOW) run_at_speed(); //Wait for Sensor + Use_DCC_speed = true; // Do not update speed via DCC + } +#endif + +#ifdef Reverse1 +// ======== Throttle Reverse 1 ======================== + if (digitalRead(ThrottleInputReverse1Pin)==LOW){ // Throttle Speed Reverse1 Input Pin + Use_DCC_speed = false; // Do not update speed via DCC + Starting_Motor1Speed = Motor1Speed; + Motor1Speed--; + while (Motor1Speed >1) { + run_at_speed(); + --Motor1Speed; + if (Dcc.getCV(62)!=0) delay(Dcc.getCV(62)); //Throttle Ramp DOWN Delay 0-255 + else Motor1Speed=0; + } + //Motor1Speed = 0; + ttemp=(Dcc.getCV(64)); + if (ttemp!=0) {setVolumeOnChannel (Dcc.getCV(65)); playTrackOnChannel(ttemp);} // play clip + Motor1ForwardDir = (Motor1ForwardDir^0x01) & 0x01; + delay(Dcc.getCV(61)*MasterTimeConstant); //Pause Time 0-255 (0.1 secs) + while (Motor1Speed < Starting_Motor1Speed) { + Motor1Speed++;; + run_at_speed(); + if (Dcc.getCV(63)!=0) delay(Dcc.getCV(63)); //Throttle Ramp UP Delay 0-255 + else Motor1Speed=Starting_Motor1Speed; + } + //Motor1Speed = Starting_Motor1Speed; + for (i=0; i<10; i++) run_at_speed(); // Move away from sensor + while (digitalRead(ThrottleInputReverse1Pin) == LOW) run_at_speed(); //Wait for Sensor + Use_DCC_speed = true; + } +#endif + +#ifdef Reverse2 +// ======== Throttle Reverse 2 ======================== + if (digitalRead(ThrottleInputReverse2Pin)==LOW){ // Throttle Speed Reverse Input Pin + Use_DCC_speed = false; // Do not update speed via DCC + Starting_Motor1Speed = Motor1Speed; + while (Motor1Speed >0) { + --Motor1Speed; + run_at_speed(); + delay(Dcc.getCV(67)); //Throttle Ramp DOWN Delay 0-255 + } + Motor1Speed = 0; + ttemp=(Dcc.getCV(69)); + setVolumeOnChannel (Dcc.getCV(70)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip + Motor1ForwardDir = (Motor1ForwardDir^0x01) & 0x01; + delay(int(Dcc.getCV(66)*MasterTimeConstant)); //Pause Time 0-255 (0.1 secs) + while (Motor1Speed <= Starting_Motor1Speed) { + ++Motor1Speed; + run_at_speed(); + delay(Dcc.getCV(68)); //Throttle Ramp UP Delay 0-255 + } + Motor1Speed = Starting_Motor1Speed; + for (i=0; i<30; i++) run_at_speed(); // Move away from sensor + while (digitalRead(ThrottleInputReverse2Pin) == LOW) run_at_speed(); //Wait for Sensor + Use_DCC_speed = true; // Do not update speed via DCC + } +#endif + +#ifdef ImmediateStop +// ======== Throttle Immediate Stop ======================== + if (digitalRead(ImmediateStopPin) == LOW) { // Throttle Immediate Stop Input Pin + ForcedStopSpeedMotor1 = Motor1Speed; + ForcedStopDirMotor1 = Motor1ForwardDir; + Motor1Speed = 0; + ttemp=(Dcc.getCV(71)); + setVolumeOnChannel (Dcc.getCV(72)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip + } +#endif + +#ifdef ImmediateStart +// ======== Throttle Immediate Start ======================== + if (digitalRead(ImmediateStartPin) == LOW) { // Throttle Immediate Start Input Pin + ttemp=(Dcc.getCV(73)); + setVolumeOnChannel (Dcc.getCV(74)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip + if (ForcedStopSpeedMotor1 != 0) { + Motor1Speed = ForcedStopSpeedMotor1 ; + Motor1ForwardDir = ForcedStopDirMotor1; + } + else + if ( Dcc.getCV(50) != 0) { + Motor1Speed = (Dcc.getCV(50))&0x7f ; + Motor1ForwardDir = (byte)((Dcc.getCV(50))&0x80 )>>7; + } + ForcedStopSpeedMotor1 = 0; // Take us out of forced stop mode + for (i=0; i<30; i++) run_at_speed(); // Move away from sensor + while (digitalRead(ImmediateStartPin) == LOW) run_at_speed(); //Wait for Sensor + } +#endif +// ******************************************************************************** + + for (int i=1; i < num_active_functions; i++) { + switch (Dcc.getCV(30+i)) { + case 0: // Master Decoder Disable Ops + break; + case 1: // LED On/Off + if (MasterDecoderDisable == 1) digitalWrite(fpins[i], 0); //decoder disabled so LEDs off + break; + case 2: // Motor2 Control + Motor2Speed = (Dcc.getCV(72))&0x7f ; // Re-read Motor2Speed if the CV was updated + Motor2ForwardDir = (byte)((Dcc.getCV(72))&0x80)>>7 ; // Re-read Motor2ForwardDir if the CV was updated + + if ((MasterDecoderDisable == 0)&&(Motor2ON == 1)) { + if (Motor2ForwardDir == 0) gofwd2 (Motor2Speed<<4); + else gobwd2 (Motor2Speed<<4); + } + if (MasterDecoderDisable == 1) { + digitalWrite(m0h, LOW); //Motor2OFF + digitalWrite(m0l, LOW); //Motor2 OFF + } + break; + + case 3: // NEXT FEATURE for the Future + break; + default: + break; + } + run_at_speed(); + } +} // end loop() + +void run_at_speed() { + Dcc.process(); + if (MasterDecoderDisable == 0) { + if (Motor1Speed != 0) { + if (Motor1ForwardDir == 0) gofwd1 (Motor1Speed<<6); + else gobwd1 (Motor1Speed<<6); + } + } + if (MasterDecoderDisable == 1) { + digitalWrite(m2h, LOW); //Motor1 OFF + digitalWrite(m2l, LOW); //Motor1 OFF + digitalWrite(m0h, LOW); //Motor2 OFF + digitalWrite(m0l, LOW); //Motor2 OFF + } + if ((MasterDecoderDisable == 0)&&(Motor2ON == 1)) { + if (Motor2ForwardDir == 0) gofwd2 (Motor2Speed<<6); + else gobwd2 (Motor2Speed<<6); + } +} // end run_at_speed() + +void gofwd1(int fcycle) { + digitalWrite(m2h, HIGH); //Motor1 + delayMicroseconds(fcycle); + digitalWrite(m2h, LOW); //Motor1 + delayMicroseconds(cyclewidth-fcycle); +} // end gofwd1() + +void gobwd1(int bcycle) { + digitalWrite(m2l, HIGH); //Motor1 + delayMicroseconds(bcycle); + digitalWrite(m2l, LOW); //Motor1 + delayMicroseconds(cyclewidth-bcycle); +} // end gobwd1() + +void gofwd2(int fcycle) { + digitalWrite(m0h, HIGH); //Motor2 + delayMicroseconds(fcycle); + digitalWrite(m0h, LOW); //Motor2 + delayMicroseconds(cyclewidth-fcycle); +} // end gofwd2() + +void gobwd2(int bcycle) { + digitalWrite(m0l, HIGH); //Motor2 + delayMicroseconds(bcycle); + digitalWrite(m0l, LOW); //Motor2 + delayMicroseconds(cyclewidth-bcycle); +} // end gobwd2() + +void playTrackOnChannel ( byte dtrack) { + if (dtrack!=255) {Player1.play(dtrack); } //delay(audiocmddelay); } + else {Player1.play(random(First_Track,Last_Track+1));} // delay(audiocmddelay); +} // end playTrackOnChannel() + +void setVolumeOnChannel ( byte dvolume) { + if(dvolume>30) return; // Don't change the volume if out of range + Player1.volume (dvolume); + delay(audiocmddelay); +} // end setVolumeOnChannel() + +void notifyCVChange( uint16_t CV, uint8_t Value) { + if ( CV== 50 ) { + Motor1Speed = (Dcc.getCV(50))&0x7f ; + Motor1ForwardDir = (byte)((Dcc.getCV(50))&0x80 )>>7; + } +} // end notifyCVChange() + +void notifyDccSpeed( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Speed, DCC_DIRECTION ForwardDir, DCC_SPEED_STEPS SpeedSteps ) { + if ( !Use_DCC_speed ) return; + if ( Dcc.getCV(50) == 0) { + Motor1Speed = (Speed & 0x7f ); + } + if (Motor1Speed == 1) Motor1Speed = 0; +} // end notifyDccSpeed() + +void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { +#ifdef DEBUG + Serial.print("Addr= "); + Serial.println(Addr, DEC) ; + Serial.print("FuncState= "); + Serial.println(FuncState, DEC) ; +#endif + switch(FuncGrp) + { + case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1 + exec_function( 0, FunctionPin0, (FuncState & FN_BIT_00)>>4 ); + exec_function( 1, FunctionPin1, (FuncState & FN_BIT_01)); + exec_function( 2, FunctionPin2, (FuncState & FN_BIT_02)>>1); + exec_function( 3, FunctionPin3, (FuncState & FN_BIT_03)>>2 ); + exec_function( 4, FunctionPin4, (FuncState & FN_BIT_04)>>3 ); + break; + case FN_5_8: //Function Group 1 S FFFF == 1 F8 F7 F6 F5 & == 0 F12 F11 F10 F9 F8 + exec_function( 5, FunctionPin5, (FuncState & FN_BIT_05)); + exec_function( 6, FunctionPin6, (FuncState & FN_BIT_06)>>1 ); + //exec_function( 7, FunctionPin7, (FuncState & FN_BIT_07)>>2 ); + //exec_function( 8, FunctionPin8, (FuncState & FN_BIT_08)>>3 ); + break; + + case FN_9_12: + //exec_function( 9, FunctionPin9, (FuncState & FN_BIT_09)); + //exec_function( 10, FunctionPin10, (FuncState & FN_BIT_10)>>1 ); + //exec_function( 11, FunctionPin11, (FuncState & FN_BIT_11)>>2 ); + //exec_function( 12, FunctionPin12, (FuncState & FN_BIT_12)>>3 ); + break; + case FN_13_20: //Function Group 2 FuncState == F20-F13 Function Control + //exec_function( 13, FunctionPin13, (FuncState & FN_BIT_13); + //exec_function( 14, FunctionPin14, (FuncState & FN_BIT_14)>>1; + //exec_function( 15, FunctionPin15, (FuncState & FN_BIT_15)>>2 ); + //exec_function( 16, FunctionPin16, (FuncState & FN_BIT_16)>>3 ); + break; + + case FN_21_28: + break; + } +} // end notifyDccSpeed() + +void exec_function (int function, int pin, int FuncState) { +#ifdef DEBUG + Serial.print("ex function= "); + Serial.println(function, DEC) ; + Serial.print("FuncState= "); + Serial.println(FuncState, DEC) ; +#endif + switch ( Dcc.getCV( 30+function) ) { // Config 0=On/Off,1=Blink + case 0: // Master Disable Function0 Value will transfer to MasterDecoderDisable in loop() + Function0_value = byte(FuncState); + break; + case 1: // On - Off LED + if (MasterDecoderDisable == 0) { + digitalWrite (pin, FuncState); + } + break; + case 2: // Motor2 Control + if (MasterDecoderDisable == 0) Motor2ON= FuncState; + break; + case 3: // NEXT FEATURE for the Future + break; + default: + ftn_queue[function].inuse = 0; + break; + } +} // end exec_function() + +/* DFPlayer Commands +//----Set volume---- + myDFPlayer.volume(10); //Set volume value (0~30). + myDFPlayer.volumeUp(); //Volume Up + myDFPlayer.volumeDown(); //Volume Down + //----Set different EQ---- + myDFPlayer.EQ(DFPLAYER_EQ_NORMAL); +// myDFPlayer.EQ(DFPLAYER_EQ_POP); +// myDFPlayer.EQ(DFPLAYER_EQ_ROCK); +// myDFPlayer.EQ(DFPLAYER_EQ_JAZZ); +// myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC); +// myDFPlayer.EQ(DFPLAYER_EQ_BASS); + //----Set device we use SD as default---- +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_U_DISK); + myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_AUX); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_SLEEP); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_FLASH); + //----Mp3 control---- +// myDFPlayer.sleep(); //sleep +// myDFPlayer.reset(); //Reset the module +// myDFPlayer.enableDAC(); //Enable On-chip DAC +// myDFPlayer.disableDAC(); //Disable On-chip DAC +// myDFPlayer.outputSetting(true, 15); //output setting, enable the output and set the gain to 15 + //----Mp3 play---- + myDFPlayer.next(); //Play next mp3 + myDFPlayer.previous(); //Play previous mp3 + myDFPlayer.play(1); //Play the first mp3 + myDFPlayer.loop(1); //Loop the first mp3 + myDFPlayer.pause(); //pause the mp3 + myDFPlayer.start(); //start the mp3 from the pause + myDFPlayer.playFolder(15, 4); //play specific mp3 in SD:/15/004.mp3; Folder Name(1~99); File Name(1~255) + myDFPlayer.enableLoopAll(); //loop all mp3 files. + myDFPlayer.disableLoopAll(); //stop loop all mp3 files. + myDFPlayer.playMp3Folder(4); //play specific mp3 in SD:/MP3/0004.mp3; File Name(0~65535) + myDFPlayer.advertise(3); //advertise specific mp3 in SD:/ADVERT/0003.mp3; File Name(0~65535) + myDFPlayer.stopAdvertise(); //stop advertise + myDFPlayer.playLargeFolder(2, 999); //play specific mp3 in SD:/02/004.mp3; Folder Name(1~10); File Name(1~1000) + myDFPlayer.loopFolder(5); //loop all mp3 files in folder SD:/05. + myDFPlayer.randomAll(); //Random play all the mp3. + myDFPlayer.enableLoop(); //enable loop. + myDFPlayer.disableLoop(); //disable loop. +*/ diff --git a/examples/IDECDemo&Diags/IDEC1_1_MotSoundBell_Demo2_16K/IDEC1_1_MotSoundBell_Demo2_16K.ino b/examples/IDECDemo&Diags/IDEC1_1_MotSoundBell_Demo2_16K/IDEC1_1_MotSoundBell_Demo2_16K.ino new file mode 100644 index 0000000..1c9e6b5 --- /dev/null +++ b/examples/IDECDemo&Diags/IDEC1_1_MotSoundBell_Demo2_16K/IDEC1_1_MotSoundBell_Demo2_16K.ino @@ -0,0 +1,735 @@ +// Interactive Decoder Motor, Pauses, Reversals w/Sound 4 LED IDEC1_1_MotSound4Led.ino +// Version 1.08 Geoff Bunza 2020 +// Works with both short and long DCC Addesses +// This decoder uses switches/sensors to control 2 motors and Five LEDs with Sound +// F0=Master Function OFF = Function ON DISABLES the decoder +// Input Pin for Decoder Disable Pin 16 Active LOW +//Motor speed via DCC speed for one motor, second motor on/off via function +//Speed Over-Ride = CV = Non-Zero Value (1-127) over-rides the DCC speed commands Bit 8 is direction 1=Forward +//Input1 Pin for Throttle Down/Pause/Throttle Up Pin 5 +// CV for Throttle Down Time, CV for Throttle Up Time,, CV for Pause Time +//Input2 Pin for Throttle Down/Pause/Throttle Up Pin 6 +// CV for Throttle Down Time, CV for Throttle Up Time,, CV for Pause Time +//Input Pin1 for Throttle Down/Reverse/Throttle Up Pin 7 +// CV for Throttle Down Time, CV for Throttle Up Time;,CV for Reverse Pause Time +//Input Pin2 for Throttle Down/Reverse/Throttle Up Pin 8 +// CV for Throttle Down Time, CV for Throttle Up Time;,CV for Reverse Pause Time +//Input Pin for immediate Stop Pin 11 +//Input Pin for Immediate Start Pin 12 +//Functions for lights on/off: +// F1-F5 5 Functions LED ON/OFF by default PINS 13,14,17,18,19 +/* Pro Mini D15 A1 (TX) connected to DFPlayer1 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor + * Remember to connect +5V and GND to the DFPlayer too: DFPLAYER PINS 1 & 7 respectively + * This is a “mobile/function” decoder with audio play to dual motor control and + * LED functions. Audio tracks or clips are stored on a micro SD card for playing, + * in a folder labeled mp3, with tracks named 0001.mp3, 0002.mp3, etc. + * MAX 3 Configurations per pin function: + * Config 0=Decoder DISABLE On/Off, 1=LED; 2=Motor2 Control On/Off + F0 == Master Decoder Disable == ON + F1 == LED == D13 + F2 == LED == D14/A0 + F3 == LED == D17/A3 + F4 == LED == D18/A4 + F5 == LED == D19/A5 + F6 == Motor2 On/OFF speed & direction set by CV 80 Normally Base Station will Transmit F5 as initial OFF + If no DCC present Decoder will power up with Motor2 ON at speed specified in CV 72 + Motor1 speed control is via throttle or overridden by non zero value in CV 50 + High Bit=Direction, Lower 7 Bits=Speed == DSSSSSSS + +PRO MINI PIN ASSIGNMENT: +2 - DCC Input +3 - m2h Motor Control +4 - m2l Motor Control +5 - Input1 Pin for Throttle Down/Pause/Throttle Up +6 - Input2 Pin for Throttle Down/Pause/Throttle Up +7 - Input1 Pin for Throttle Down/Reverse/Throttle Up +8 - Input2 Pin for Throttle Down/Reverse/Throttle Up +9 - m0h Motor Control +10 - m0l Motor Control +11 - Input Pin for immediate Stop +12 - Input Pin for Immediate Start +13 - LED F1 +14 A0 - LED F2 +15 A1 - (TX) connected to DFPlayer1 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor +16 A2 - Input Pin for MasterDecoderDisable Active LOW +17 A3 - LED F3 +18 A4 - LED F4 +19 A5 - LED F5 +*/ + +// ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP +// ******** AFTER THE INITIAL DECODER LOAD REMOVE THE "//" IN THE FOOLOWING LINE!! +//#define DECODER_LOADED + +// ******** REMOVE THE "//" IN THE FOLLOWING LINE TO SEND DEBUGGING +// ******** INFO TO THE SERIAL MONITOR +//#define DEBUG + +// ******** REMOVE THE "//" IN THE FOLLOWING LINE TO INCLUDE THE PAUSE 1 SENSOR +//#define Pause1 + +// ******** REMOVE THE "//" IN THE FOLLOWING LINE TO INCLUDE THE PAUSE 2 SENSOR +//#define Pause2 + +// ******** REMOVE THE "//" IN THE FOLLOWING LINE TO INCLUDE THE REVERSE 1 SENSOR +#define Reverse1 + +// ******** REMOVE THE "//" IN THE FOLLOWING LINE TO INCLUDE THE REVERSE 2 SENSOR +//#define Reverse2 + +// ******** REMOVE THE "//" IN THE FOLLOWING LINE TO INCLUDE THE IMMEDIATE STOP SENSOR +//#define ImmediateStop + +// ******** REMOVE THE "//" IN THE FOLLOWING LINE TO INCLUDE THE IMMEDIATE START SENSOR +//#define ImmediateStart + +#include +#include +#include +SoftwareSerial DFSerial1(21,15); // PRO MINI RX, PRO MINI TX serial to DFPlayer +DFRobotDFPlayerMini Player1; + +#define This_Decoder_Address 24 +uint8_t CV_DECODER_MASTER_RESET = 252; + +//Uncomment ONLY ONE of the following: +//#define MasterTimeConstant 10L // 10's of milliseconds Timing +#define MasterTimeConstant 100L // Tenths of a second Timing +//#define MasterTimeConstant 1000L // Seconds Timing +//#define MasterTimeConstant 10000L // 10's of Seconds Timing +//#define MasterTimeConstant 60000L // Minutes Timing +//#define MasterTimeConstant 3600000L // Hours Timing + +uint16_t ttemp, i; +#define First_Track 1 // Play Random Tracks First_Track#=Start_Track >=1 +#define Last_Track 2 // Play Random Tracks Last_Track= Last Playable Track in Range <= Last Numbered Track +#define starting_volume 22 // If no volume is set use this at the start +const int audiocmddelay = 34; + +boolean Use_DCC_speed = true; // Switch to disable DCC Speed updates +int Motor1Speed = 0; // Variablw for Motor1 Speed +int Starting_Motor1Speed = 0; +int Motor1ForwardDir = 1; // Variable for Motor1 Dir +int ForcedStopSpeedMotor1 = 0; // Holding Variablw for Last Speed when Immediate Stop +int ForcedStopDirMotor1 = 1; // Holding Variablw for Last Direction when Immediate Stop +int Motor2Speed = 0; // Variable for Motor2 Speed +int Motor2ForwardDir = 1; // Variable for Motor2 Dir +int Motor2ON = 0; +int cyclewidth = 16384; + +const int m2h = 3; //R H Bridge Motor1 +const int m2l = 4; //B H Bridge Motor1 +const int ThrottlePause1Pin = 5; // Throttle Speed Pause1 Input Pin +const int ThrottlePause2Pin = 6; // Throttle Speed Pause2 Input Pin +const int ThrottleInputReverse1Pin = 7; // Throttle Speed Reverse Input Pin +const int ThrottleInputReverse2Pin = 8; // Throttle Immediate Speed Reverse Input Pin +const int m0h = 9; //R H Bridge Motor2 +const int m0l = 10; //B H Bridge //Motor2 +const int ImmediateStopPin = 11; // Throttle Immediate Stop Input Pin +const int ImmediateStartPin = 12; // Throttle Immediate Start Input Pin +const int MasterDecoderDisablePin = 16; // D16/A0 Master Decoder Disable Input Pin Active LOW +// arduino pin D 15; // D15/A1 DFPlayer Receive (RX) Pin 2 via 470 Ohm Resistor + +const int numfpins = 10; // Number of Output pins to initialize +const int num_active_functions = 7; // Number of Functions stating with F0 +byte fpins [] = {13,13,14,17,18,19,3,4,9,10}; //These are all the Output Pins (first 13 is placeholder) +const int FunctionPin0 = 20; // D14/A0 DFPlayer Transmit (TX) Pin 3 +const int FunctionPin1 = 13; // A2 LED +const int FunctionPin2 = 14; // A3 LED +const int FunctionPin3 = 17; // A4 LED +const int FunctionPin4 = 18; // A5 LED +const int FunctionPin5 = 19; // A6 LED + +const int FunctionPin6 = 20; // Turns on Motor2 DCC Function Control Only NO Local Input Pin +const int FunctionPin7 = 20; // Place holders ONLY +const int FunctionPin8 = 20; // Place holders ONLY +const int FunctionPin9 = 20; // Place holders ONLY +const int FunctionPin10 = 20; // Place holders ONLY +const int FunctionPin11 = 20; // Place holders ONLY +const int FunctionPin12 = 20; // Place holders ONLY +const int FunctionPin13 = 20; // Place holders ONLY +const int FunctionPin14 = 20; // Place holders ONLY +const int FunctionPin15 = 20; // Place holders ONLY +const int FunctionPin16 = 20; // Place holders ONLY +int MasterDecoderDisable = 0; +int Function0_value = 0; + +NmraDcc Dcc ; +DCC_MSG Packet ; +int t; // temp +struct QUEUE +{ + int inuse; + int current_position; + int increment; + int stop_value; + int start_value; +}; +QUEUE *ftn_queue = new QUEUE[17]; + +struct CVPair +{ + uint16_t CV; + uint8_t Value; +}; +CVPair FactoryDefaultCVs [] = +{ + {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address&0x7F }, + + // These two CVs define the Long DCC Address + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, ((This_Decoder_Address>>8)&0x7F)+192 }, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address&0xFF }, + + // ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS +// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps + {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps +// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps + {CV_DECODER_MASTER_RESET, 0}, + + {30, 0}, //F0 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + + {31, 1}, //F1 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {32, 1}, //F2 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {33, 1}, //F3 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {34, 1}, //F4 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {35, 1}, //F5 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + + {36, 2}, //F6 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + + {37,4}, //F7 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {38,4}, //F8 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {39,4}, //F9 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {40,4}, //F10 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {41,4}, //F11 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {42,4}, //F12 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {43,4}, //F13 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {44,4}, //F14 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {45,4}, //F15 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {46,4}, //F16 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {47,4}, //F17 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {48,4}, //F18 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + {49,4}, //F19 Config 0=DISABLE On/Off,1=LED,2=Motor2 Control On/Off,3=NOT Implemented + + {50, 0}, // Speed Over-Ride = CV = Non-Zero Value (1-127) over-rides the DCC speed commands + // Bit 8 (128 or 0x80) ON=Forward Direction 0=Reverse Direction + + {51, 0}, // ThrottlePause1 Pause Time 0-255 (0.1 secs) + {52, 0}, // ThrottlePause1 Throttle Ramp DOWN Delay 0-255 Larger Delay=Slower Ramp Down + {53, 0}, // ThrottlePause1 Throttle Ramp UP Delay 0-255 Larger Delay=Slower Ramp Up + {54, 11}, // ThrottlePause1 Pause Sound Clip 1-nn 0=No Sound + {55, 55}, // ThrottlePause1 Pause Sound Clip Volume 0-30 + + {56, 0}, // ThrottlePause2 Pause Time 0-255 (0.1 secs) + {57, 0}, // ThrottlePause2 Throttle Ramp DOWN 0-255 Delay + {58, 0}, // ThrottlePause2 Throttle Ramp UP Delay 0-255 + {59, 11}, // ThrottlePause2 Pause Sound Clip 1-nn 0=No Sound + {60, 55}, // ThrottlePause2 Pause Sound Clip Volume 0-30 + + {61, 0}, // ThrottleInputReverse1 Pause Time 0-255 (0.1 secs) + {62, 0}, // ThrottleInputReverse1 Ramp DOWN Delay 0-255 + {63, 0}, // ThrottleInputReverse1 Ramp UP Delay 0-255 + {64, 11}, // ThrottleInputReverse1 Sound Clip 1-nn 0=No Sound + {65, 55}, // ThrottleInputReverse1 Sound Clip Volume 0-30 + + {66, 0}, // ThrottleInputReverse2 Pause Time 0-255 (0.1 secs) + {67, 0}, // ThrottleInputReverse2 Ramp DOWN Delay 0-255 + {68, 0}, // ThrottleInputReverse2 Ramp UP Delay 0-255 + {69, 11}, // ThrottleInputReverse2 Sound Clip 1-nn 0=No Sound + {70, 55}, // ThrottleInputReverse2 Sound Clip Volume 0-30 + + {71, 0}, // ThrottleImmediateStop Sound Clip 1-nn 0=No Sound + {72, 55}, // ThrottleImmediateStop Sound Clip Volume 0-30 + + {73, 0}, // ThrottleImmediateStart Sound Clip 1-nn 0=No Sound + {74, 55}, // ThrottleImmediateStart Sound Clip Volume 0-30 + + {80, 0}, // Motor2 Speed 0-127 Bit 8 (128 or 0x80) ON=Forward Direction 0=Reverse Direction + + //252,252 CV_DECODER_MASTER_RESET + + {253, 0}, // Extra +}; + +uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +void notifyCVResetFactoryDefault() +{ + // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset + // to flag to the loop() function that a reset to Factory Defaults needs to be done + FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +}; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS + +void setup() //****************************************************** +{ +#ifdef DEBUG + Serial.begin(115200); +#endif + DFSerial1.begin (9600); + Player1.begin (DFSerial1); + + pinMode (ThrottlePause1Pin,INPUT_PULLUP); // Throttle Speed Pause1 Input Pin Active LOW + pinMode (ThrottlePause2Pin,INPUT_PULLUP); // Throttle Speed Pause2 Input Pin Active LOW + pinMode (ThrottleInputReverse1Pin,INPUT_PULLUP); // Throttle Speed Reverse Input Pin 1 Active LOW + pinMode (ThrottleInputReverse2Pin,INPUT_PULLUP); // Throttle Speed Reverse Input Pin 2 Active LOW + pinMode (ImmediateStopPin,INPUT_PULLUP); // Throttle Immediate Stop Input Pin Active LOW + pinMode (ImmediateStartPin,INPUT_PULLUP); // Throttle Immediate Start Input Pin Active LOW + pinMode (MasterDecoderDisablePin,INPUT_PULLUP); // Master Decoder Disable Input Pin Active LOW + uint8_t cv_value; + // initialize the digital pins as outputs + for (int i=0; i < numfpins; i++) { + pinMode(fpins[i], OUTPUT); + digitalWrite(fpins[i], 0); // All OUPUT pins initialized LOW + } + // Setup which External Interrupt, the Pin it's associated with that we're using + Dcc.pin(0, 2, 0); + // Call the main DCC Init function to enable the DCC Receiver + Dcc.init( MAN_ID_DIY, 61, FLAGS_MY_ADDRESS_ONLY, 0 ); + delay(800); +#if defined(DECODER_LOADED) + if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET ) +#endif + { + for (int j=0; j < FactoryDefaultCVIndex; j++ ) + Dcc.setCV( FactoryDefaultCVs[j].CV, FactoryDefaultCVs[j].Value); + } + for ( i=0; i < num_active_functions; i++) { + cv_value = Dcc.getCV(30+i) ; + switch ( cv_value ) { + case 0: // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + break; + case 1: // LED On/Off + ftn_queue[i].inuse = 0; + break; + case 2: // Motor2 Control + if ( Dcc.getCV(72) != 0) { + Motor2ON = 1; + Motor2Speed = (Dcc.getCV(72))&0x7f ; + Motor2ForwardDir = (byte)((Dcc.getCV(72))&0x80)>>7 ; + } else Motor2ON = 0; + break; + case 3: // NEXT FEATURE for the Future + break; + default: + break; + } + } + setVolumeOnChannel (starting_volume); + Motor1ForwardDir = 1; // Default start value for direction if throttle controlled + if ( Dcc.getCV(50) != 0) { + Motor1Speed = (Dcc.getCV(50))&0x7f ; + Motor1ForwardDir = (byte)((Dcc.getCV(50))&0x80 )>>7; + } +#ifdef DEBUG + Serial.println("CV Dump:"); + for (i=30; i<51; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + + Serial.println("Throttle Pause 1"); + for (i=51; i<56; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + + Serial.println("Throttle Pause 2"); + for (i=56; i<61; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + + Serial.println("Throttle Reverse 1"); + for (i=61; i<66; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + + Serial.println("Throttle Reverse 2"); + for (i=66; i<71; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + + Serial.println("Immediate Stop"); + for (i=71; i<73; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + + Serial.println("Immediate Start"); + for (i=73; i<75; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + + Serial.println("Motor2 Speed"); + Serial.print(Dcc.getCV(80),DEC); Serial.print("\t"); } + Serial.println(""); +#endif +} +void loop() //********************************************************************** +{ + //MUST call the NmraDcc.process() method frequently + // from the Arduino loop() function for correct library operation + //Dcc.process(); + run_at_speed(); + //delay(1); + +// INPUT OVER RIDES + // Check Master Input Over ride + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + else MasterDecoderDisable = Function0_value & 1; + if (MasterDecoderDisable == 1) { Motor1Speed = 0; Motor2Speed = 0; } + +#ifdef Pause1 +// ======== Throttle Pause 1 ======================== + if (digitalRead(ThrottlePause1Pin) == LOW) { // Throttle Speed Pause1 Input Pin + Use_DCC_speed = false; // Do not update speed via DCC + Starting_Motor1Speed = Motor1Speed; + while (Motor1Speed >0) { + --Motor1Speed; + run_at_speed(); + delay(Dcc.getCV(52)); //Throttle Ramp DOWN Delay 0-255 + } + Motor1Speed = 0; + ttemp=(Dcc.getCV(54)); + setVolumeOnChannel (Dcc.getCV(55)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip + delay(int(Dcc.getCV(51)*MasterTimeConstant)); //Pause Time 0-255 (0.1 secs) + while (Motor1Speed <= Starting_Motor1Speed) { + ++Motor1Speed; + run_at_speed(); + delay(Dcc.getCV(53)); //Throttle Ramp UP Delay 0-255 + } + Motor1Speed = Starting_Motor1Speed; + for (i=0; i<30; i++) run_at_speed(); // Move away from sensor + while (digitalRead(ThrottlePause1Pin) == LOW) run_at_speed(); //Wait for Sensor + Use_DCC_speed = true; // Do not update speed via DCC + } +#endif + +#ifdef Pause2 +// ======== Throttle Pause 2 ======================== + if (digitalRead(ThrottlePause2Pin) == LOW) { // Throttle Speed Pause2 Input Pin + + Use_DCC_speed = false; // Do not update speed via DCC + Starting_Motor1Speed = Motor1Speed; + while (Motor1Speed >0) { + --Motor1Speed; + run_at_speed(); + delay(Dcc.getCV(57)); //Throttle Ramp DOWN Delay 0-255 + } + Motor1Speed = 0; + ttemp=(Dcc.getCV(59)); + setVolumeOnChannel (Dcc.getCV(60)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip + delay(int(Dcc.getCV(56)*MasterTimeConstant)); //Pause Time 0-255 (0.1 secs) + while (Motor1Speed <= Starting_Motor1Speed) { + ++Motor1Speed; + run_at_speed(); + delay(Dcc.getCV(58)); //Throttle Ramp UP Delay 0-255 + } + Motor1Speed = Starting_Motor1Speed; + for (i=0; i<30; i++) run_at_speed(); // Move away from sensor + while (digitalRead(ThrottlePause2Pin) == LOW) run_at_speed(); //Wait for Sensor + Use_DCC_speed = true; // Do not update speed via DCC + } +#endif + +#ifdef Reverse1 +// ======== Throttle Reverse 1 ======================== + if (digitalRead(ThrottleInputReverse1Pin)==LOW){ // Throttle Speed Reverse1 Input Pin + Use_DCC_speed = false; // Do not update speed via DCC + Starting_Motor1Speed = Motor1Speed; + Motor1Speed--; + while (Motor1Speed >1) { + run_at_speed(); + --Motor1Speed; + if (Dcc.getCV(62)!=0) delay(Dcc.getCV(62)); //Throttle Ramp DOWN Delay 0-255 + else Motor1Speed=0; + } + //Motor1Speed = 0; + ttemp=(Dcc.getCV(64)); + if (ttemp!=0) {setVolumeOnChannel (Dcc.getCV(65)); playTrackOnChannel(ttemp);} // play clip + Motor1ForwardDir = (Motor1ForwardDir^0x01) & 0x01; + delay(Dcc.getCV(61)*MasterTimeConstant); //Pause Time 0-255 (0.1 secs) + while (Motor1Speed < Starting_Motor1Speed) { + Motor1Speed++;; + run_at_speed(); + if (Dcc.getCV(63)!=0) delay(Dcc.getCV(63)); //Throttle Ramp UP Delay 0-255 + else Motor1Speed=Starting_Motor1Speed; + } + //Motor1Speed = Starting_Motor1Speed; + for (i=0; i<10; i++) run_at_speed(); // Move away from sensor + while (digitalRead(ThrottleInputReverse1Pin) == LOW) run_at_speed(); //Wait for Sensor + Use_DCC_speed = true; + } +#endif + +#ifdef Reverse2 +// ======== Throttle Reverse 2 ======================== + if (digitalRead(ThrottleInputReverse2Pin)==LOW){ // Throttle Speed Reverse Input Pin + Use_DCC_speed = false; // Do not update speed via DCC + Starting_Motor1Speed = Motor1Speed; + while (Motor1Speed >0) { + --Motor1Speed; + run_at_speed(); + delay(Dcc.getCV(67)); //Throttle Ramp DOWN Delay 0-255 + } + Motor1Speed = 0; + ttemp=(Dcc.getCV(69)); + setVolumeOnChannel (Dcc.getCV(70)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip + Motor1ForwardDir = (Motor1ForwardDir^0x01) & 0x01; + delay(int(Dcc.getCV(66)*MasterTimeConstant)); //Pause Time 0-255 (0.1 secs) + while (Motor1Speed <= Starting_Motor1Speed) { + ++Motor1Speed; + run_at_speed(); + delay(Dcc.getCV(68)); //Throttle Ramp UP Delay 0-255 + } + Motor1Speed = Starting_Motor1Speed; + for (i=0; i<30; i++) run_at_speed(); // Move away from sensor + while (digitalRead(ThrottleInputReverse2Pin) == LOW) run_at_speed(); //Wait for Sensor + Use_DCC_speed = true; // Do not update speed via DCC + } +#endif + +#ifdef ImmediateStop +// ======== Throttle Immediate Stop ======================== + if (digitalRead(ImmediateStopPin) == LOW) { // Throttle Immediate Stop Input Pin + ForcedStopSpeedMotor1 = Motor1Speed; + ForcedStopDirMotor1 = Motor1ForwardDir; + Motor1Speed = 0; + ttemp=(Dcc.getCV(71)); + setVolumeOnChannel (Dcc.getCV(72)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip + } +#endif + +#ifdef ImmediateStart +// ======== Throttle Immediate Start ======================== + if (digitalRead(ImmediateStartPin) == LOW) { // Throttle Immediate Start Input Pin + ttemp=(Dcc.getCV(73)); + setVolumeOnChannel (Dcc.getCV(74)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip + if (ForcedStopSpeedMotor1 != 0) { + Motor1Speed = ForcedStopSpeedMotor1 ; + Motor1ForwardDir = ForcedStopDirMotor1; + } + else + if ( Dcc.getCV(50) != 0) { + Motor1Speed = (Dcc.getCV(50))&0x7f ; + Motor1ForwardDir = (byte)((Dcc.getCV(50))&0x80 )>>7; + } + ForcedStopSpeedMotor1 = 0; // Take us out of forced stop mode + for (i=0; i<30; i++) run_at_speed(); // Move away from sensor + while (digitalRead(ImmediateStartPin) == LOW) run_at_speed(); //Wait for Sensor + } +#endif +// ******************************************************************************** + + for (int i=1; i < num_active_functions; i++) { + switch (Dcc.getCV(30+i)) { + case 0: // Master Decoder Disable Ops + break; + case 1: // LED On/Off + if (MasterDecoderDisable == 1) digitalWrite(fpins[i], 0); //decoder disabled so LEDs off + break; + case 2: // Motor2 Control + Motor2Speed = (Dcc.getCV(72))&0x7f ; // Re-read Motor2Speed if the CV was updated + Motor2ForwardDir = (byte)((Dcc.getCV(72))&0x80)>>7 ; // Re-read Motor2ForwardDir if the CV was updated + + if ((MasterDecoderDisable == 0)&&(Motor2ON == 1)) { + if (Motor2ForwardDir == 0) gofwd2 (Motor2Speed<<4); + else gobwd2 (Motor2Speed<<4); + } + if (MasterDecoderDisable == 1) { + digitalWrite(m0h, LOW); //Motor2OFF + digitalWrite(m0l, LOW); //Motor2 OFF + } + break; + + case 3: // NEXT FEATURE for the Future + break; + default: + break; + } + run_at_speed(); + } +} // end loop() + +void run_at_speed() { + Dcc.process(); + if (MasterDecoderDisable == 0) { + if (Motor1Speed != 0) { + if (Motor1ForwardDir == 0) gofwd1 (Motor1Speed<<7); + else gobwd1 (Motor1Speed<<7); + } + } + if (MasterDecoderDisable == 1) { + digitalWrite(m2h, LOW); //Motor1 OFF + digitalWrite(m2l, LOW); //Motor1 OFF + digitalWrite(m0h, LOW); //Motor2 OFF + digitalWrite(m0l, LOW); //Motor2 OFF + } + if ((MasterDecoderDisable == 0)&&(Motor2ON == 1)) { + if (Motor2ForwardDir == 0) gofwd2 (Motor2Speed<<7); + else gobwd2 (Motor2Speed<<7); + } +} // end run_at_speed() + +void gofwd1(int fcycle) { + digitalWrite(m2h, HIGH); //Motor1 + delayMicroseconds(fcycle); + digitalWrite(m2h, LOW); //Motor1 + delayMicroseconds(cyclewidth-fcycle); +} // end gofwd1() + +void gobwd1(int bcycle) { + digitalWrite(m2l, HIGH); //Motor1 + delayMicroseconds(bcycle); + digitalWrite(m2l, LOW); //Motor1 + delayMicroseconds(cyclewidth-bcycle); +} // end gobwd1() + +void gofwd2(int fcycle) { + digitalWrite(m0h, HIGH); //Motor2 + delayMicroseconds(fcycle); + digitalWrite(m0h, LOW); //Motor2 + delayMicroseconds(cyclewidth-fcycle); +} // end gofwd2() + +void gobwd2(int bcycle) { + digitalWrite(m0l, HIGH); //Motor2 + delayMicroseconds(bcycle); + digitalWrite(m0l, LOW); //Motor2 + delayMicroseconds(cyclewidth-bcycle); +} // end gobwd2() + +void playTrackOnChannel ( byte dtrack) { + if (dtrack!=255) {Player1.play(dtrack); } //delay(audiocmddelay); } + else {Player1.play(random(First_Track,Last_Track+1));} // delay(audiocmddelay); +} // end playTrackOnChannel() + +void setVolumeOnChannel ( byte dvolume) { + if(dvolume>30) return; // Don't change the volume if out of range + Player1.volume (dvolume); + delay(audiocmddelay); +} // end setVolumeOnChannel() + +void notifyCVChange( uint16_t CV, uint8_t Value) { + if ( CV== 50 ) { + Motor1Speed = (Dcc.getCV(50))&0x7f ; + Motor1ForwardDir = (byte)((Dcc.getCV(50))&0x80 )>>7; + } +} // end notifyCVChange() + +void notifyDccSpeed( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Speed, DCC_DIRECTION ForwardDir, DCC_SPEED_STEPS SpeedSteps ) { + if ( !Use_DCC_speed ) return; + if ( Dcc.getCV(50) == 0) { + Motor1Speed = (Speed & 0x7f ); + } + if (Motor1Speed == 1) Motor1Speed = 0; +} // end notifyDccSpeed() + +void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { +#ifdef DEBUG + Serial.print("Addr= "); + Serial.println(Addr, DEC) ; + Serial.print("FuncState= "); + Serial.println(FuncState, DEC) ; +#endif + switch(FuncGrp) + { + case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1 + exec_function( 0, FunctionPin0, (FuncState & FN_BIT_00)>>4 ); + exec_function( 1, FunctionPin1, (FuncState & FN_BIT_01)); + exec_function( 2, FunctionPin2, (FuncState & FN_BIT_02)>>1); + exec_function( 3, FunctionPin3, (FuncState & FN_BIT_03)>>2 ); + exec_function( 4, FunctionPin4, (FuncState & FN_BIT_04)>>3 ); + break; + case FN_5_8: //Function Group 1 S FFFF == 1 F8 F7 F6 F5 & == 0 F12 F11 F10 F9 F8 + exec_function( 5, FunctionPin5, (FuncState & FN_BIT_05)); + exec_function( 6, FunctionPin6, (FuncState & FN_BIT_06)>>1 ); + //exec_function( 7, FunctionPin7, (FuncState & FN_BIT_07)>>2 ); + //exec_function( 8, FunctionPin8, (FuncState & FN_BIT_08)>>3 ); + break; + + case FN_9_12: + //exec_function( 9, FunctionPin9, (FuncState & FN_BIT_09)); + //exec_function( 10, FunctionPin10, (FuncState & FN_BIT_10)>>1 ); + //exec_function( 11, FunctionPin11, (FuncState & FN_BIT_11)>>2 ); + //exec_function( 12, FunctionPin12, (FuncState & FN_BIT_12)>>3 ); + break; + case FN_13_20: //Function Group 2 FuncState == F20-F13 Function Control + //exec_function( 13, FunctionPin13, (FuncState & FN_BIT_13); + //exec_function( 14, FunctionPin14, (FuncState & FN_BIT_14)>>1; + //exec_function( 15, FunctionPin15, (FuncState & FN_BIT_15)>>2 ); + //exec_function( 16, FunctionPin16, (FuncState & FN_BIT_16)>>3 ); + break; + + case FN_21_28: + break; + } +} // end notifyDccSpeed() + +void exec_function (int function, int pin, int FuncState) { +#ifdef DEBUG + Serial.print("ex function= "); + Serial.println(function, DEC) ; + Serial.print("FuncState= "); + Serial.println(FuncState, DEC) ; +#endif + switch ( Dcc.getCV( 30+function) ) { // Config 0=On/Off,1=Blink + case 0: // Master Disable Function0 Value will transfer to MasterDecoderDisable in loop() + Function0_value = byte(FuncState); + break; + case 1: // On - Off LED + if (MasterDecoderDisable == 0) { + digitalWrite (pin, FuncState); + } + break; + case 2: // Motor2 Control + if (MasterDecoderDisable == 0) Motor2ON= FuncState; + break; + case 3: // NEXT FEATURE for the Future + break; + default: + ftn_queue[function].inuse = 0; + break; + } +} // end exec_function() + +/* DFPlayer Commands +//----Set volume---- + myDFPlayer.volume(10); //Set volume value (0~30). + myDFPlayer.volumeUp(); //Volume Up + myDFPlayer.volumeDown(); //Volume Down + //----Set different EQ---- + myDFPlayer.EQ(DFPLAYER_EQ_NORMAL); +// myDFPlayer.EQ(DFPLAYER_EQ_POP); +// myDFPlayer.EQ(DFPLAYER_EQ_ROCK); +// myDFPlayer.EQ(DFPLAYER_EQ_JAZZ); +// myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC); +// myDFPlayer.EQ(DFPLAYER_EQ_BASS); + //----Set device we use SD as default---- +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_U_DISK); + myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_AUX); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_SLEEP); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_FLASH); + //----Mp3 control---- +// myDFPlayer.sleep(); //sleep +// myDFPlayer.reset(); //Reset the module +// myDFPlayer.enableDAC(); //Enable On-chip DAC +// myDFPlayer.disableDAC(); //Disable On-chip DAC +// myDFPlayer.outputSetting(true, 15); //output setting, enable the output and set the gain to 15 + //----Mp3 play---- + myDFPlayer.next(); //Play next mp3 + myDFPlayer.previous(); //Play previous mp3 + myDFPlayer.play(1); //Play the first mp3 + myDFPlayer.loop(1); //Loop the first mp3 + myDFPlayer.pause(); //pause the mp3 + myDFPlayer.start(); //start the mp3 from the pause + myDFPlayer.playFolder(15, 4); //play specific mp3 in SD:/15/004.mp3; Folder Name(1~99); File Name(1~255) + myDFPlayer.enableLoopAll(); //loop all mp3 files. + myDFPlayer.disableLoopAll(); //stop loop all mp3 files. + myDFPlayer.playMp3Folder(4); //play specific mp3 in SD:/MP3/0004.mp3; File Name(0~65535) + myDFPlayer.advertise(3); //advertise specific mp3 in SD:/ADVERT/0003.mp3; File Name(0~65535) + myDFPlayer.stopAdvertise(); //stop advertise + myDFPlayer.playLargeFolder(2, 999); //play specific mp3 in SD:/02/004.mp3; Folder Name(1~10); File Name(1~1000) + myDFPlayer.loopFolder(5); //loop all mp3 files in folder SD:/05. + myDFPlayer.randomAll(); //Random play all the mp3. + myDFPlayer.enableLoop(); //enable loop. + myDFPlayer.disableLoop(); //disable loop. +*/ diff --git a/examples/IDECDemo&Diags/IDEC2_5_LargeFunctionBellDemo4/IDEC2_5_LargeFunctionBellDemo4.ino b/examples/IDECDemo&Diags/IDEC2_5_LargeFunctionBellDemo4/IDEC2_5_LargeFunctionBellDemo4.ino new file mode 100644 index 0000000..e3248f7 --- /dev/null +++ b/examples/IDECDemo&Diags/IDEC2_5_LargeFunctionBellDemo4/IDEC2_5_LargeFunctionBellDemo4.ino @@ -0,0 +1,1149 @@ +// Interactive Decoder Random Switches IDEC2_5_LargeFunctionSetsDev.ino +// Version 1.09 Geoff Bunza 2020 +// Works with both short and long DCC Addesses +// This decoder will control Switch Sequences, servos, sounds and LEDs +// F0=Master Function OFF = Function ON DISABLES the decoder +/* F0 is configured as Master Decoder Disable Override ON==Disable Decoder + * Input Pin for Decoder Disable Pin 16/A2 Active LOW +// F1-F2 Eight Switch Sets 1-2 controlled by Input pins 3,4 respectively + * All Switch Sets are defined by groups of 80 CVs + - Either a DCC Function 1-2 on OR an Input Pin (3,4,) Switched Low enables a decoder function (ON) + - BOTH the respective DCC Decoder Function 1-2 must be Off AND its respective Input Pin (3,4) + MUST be High for a decoder function to be considered disabled + - A decoder function LEFT ENABLED will repreat the respecpective action as long as it is enabled + * Switch Set CV's are 25 groups of 3 CVs each: + CV1 - A delay (0-255) which will be multiplied by the + MasterTimeConstant setting time increments from milliseconds to minutes + 0 = No Delay + CV2 - A Mode or Command byte Describing what will be executed in this Switch Step, including: + 0 = No Operation / Null /Skip + 1 = Simple pin switch on/off + 2= Random pin switch on/off + 3 = Weighted Random pin switch on/off default is 60% ON time but can be set to anything 1-99% + 4 = Play sound track using fpin value for the track 1-126, 0 = Skip Play, 127 = Select Random Track + from First_Track to Last_Track inclusive; + MSB=0->No Volume Change MSB=1 -> Set Volume to default_volume + 5 = Position Servo to 0-180 full speed of travel + 6 = Dual pin on/off used for alternate blink fpin and fpin+1 (MSB set value for fpin state) + 7 = Start another Switching set based on the fpin argument (Used to chain Switch Sets) + 8 = Start another Switching set based on the fpin argument ONLY if NOT already started + CV3 - An argument representing the Pin number affected in the lower 7 bits and the High bit (0x80 or 128) a value + or a general parameter like a servo position, a Sound track, or a sound set number to jump to + * Switch sets include CVs: 50-129 and 130=209 + * MAX one of 3 Configurations per pin function: + * Config 0=DISABLE On/Off,1-2=Switch Control 1-2 + +PRO MINI PIN ASSIGNMENT: +2 - DCC Input +3 - Input Pin Switch 1 +4 - Input Pin Switch 2 +5 - Switch 9 +6 - Switch 10 +7 - Switch 11 +8 - Switch 12 +9 - Switch 13 +10 - Switch 14 +11 - Switch 1 +12 - Switch 2 +13 - Switch 3 +14 A0 - Switch 4 or default_servo_pin +15 A1 - Switch 5 or default sound player pin (TX) connected to DFPlayer1 (RX) Pin 2 via 1K Ohm 1/4W Resistor +16 A2 - Input Pin for MasterDecoderDisable Active LOW +17 A3 - Switch 6 +18 A4 - Switch 7 +19 A5 - Switch 8 +*/ +// ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP +// ******** AFTER THE INITIAL DECODER LOAD REMOVE THE "//" IN THE FOOLOWING LINE!! +//#define DECODER_LOADED + +// ******** REMOVE THE "//" IN THE FOLOWING LINE TO enable sound DFPlayer on Pin 15 +#define SOUND_PLAYER15 + +// ******** REMOVE THE "//" IN THE FOLOWING LINE TO enable SERVO USE +#define USE_SERVO14 + +// ******** REMOVE THE "//" IN THE FOLOWING LINE TO SEND DEBUGGING +// ******** INFO TO THE SERIAL MONITOR *****NOTE Turning DEBUG ON changes ALL Timing!! +//#define DEBUG + + +#include +#include + +#ifdef USE_SERVO14 +SoftwareServo sservo; +#endif +byte default_servo_pin = 14; +byte servo_start_position = 90; +const byte servo_master_slowdown_CV = 48; //servo loop counter limit CV +int servo_slow_counter = 1; //servo loop counter to slowdown servo transit +byte servo_unit_faster = 0; + +#ifdef SOUND_PLAYER15 +#include +#include +SoftwareSerial DFSerial1(22,15); // PRO MINI RX, PRO MINI TX serial to DFPlayer +DFRobotDFPlayerMini Player1; +#endif +#define default_volume 20 // sets default volume 0-30, 0 == OFF, >30 == Skip Track +#define First_Track 1 // Play Random Tracks First_Track#=Start_Track >=1 +#define Last_Track 12 // Play Random Tracks Last_Track= Last Playable Track in Range <= Last Numbered Track +const byte starting_volume_CV = 49; // If no volume is set use this CV at the start +const int audiocmddelay = 40; + +#define This_Decoder_Address 24 +uint8_t CV_DECODER_MASTER_RESET = 252; + +//Uncomment ONLY ONE of the following: +//#define MasterTimeConstant 1L // milliseconds Timing +#define MasterTimeConstant 10L // 10's of milliseconds Timing +//#define MasterTimeConstant 100L // Tenths of a second Timing +//#define MasterTimeConstant 1000L // Seconds Timing +//#define MasterTimeConstant 10000L // 10's of Seconds Timing +//#define MasterTimeConstant 60000L // Minutes Timing +//#define MasterTimeConstant 3600000L // Hours Timing + +int del_tim = 4000; +uint16_t ttemp, i; +byte otemp; + +byte ss1[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +unsigned long ss1delay=0; +byte ss2[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +unsigned long ss2delay=0; +bool run_switch_set [ ] = {false,false,false}; +byte switchset_channel[ ]={0,0,0}; + +struct SERVO_TRACKING +{ + byte current_position; + byte target_position; + char delta; +}; +SERVO_TRACKING servo_pos; + +const int MasterDecoderDisablePin = 16; // D16/A0 Master Decoder Disable Input Pin Active LOW + +const int numINpins = 3; // Number of INput pins to initialize +byte inputpins [] = {3,4,16}; //These are all the Input Pins +const int numfpins = 14; // Number of Output pins to initialize +const int num_active_functions = 3; // Number of Functions stating with F0 +byte fpins [] = {5,6,7,8,9,10,11,12,13,14,15,17,18,19}; //These are all the Output Pins (first 15 is placeholder) +const int FunctionPin0 = 20; // D14/A0 DFPlayer Transmit (TX) Pin 3 +const int FunctionPin1 = 20; // A2 LED Place holders ONLY +const int FunctionPin2 = 20; // A3 LED Place holders ONLY +const int FunctionPin3 = 20; // A4 LED Place holders ONLY +const int FunctionPin4 = 20; // A5 LED Place holders ONLY +const int FunctionPin5 = 20; // A6 LED Place holders ONLY +const int FunctionPin6 = 20; // A7 Place holders ONLY +const int FunctionPin7 = 20; // A8 Place holders ONLY +const int FunctionPin8 = 20; // A9 Place holders ONLY +#define switch1 11 +#define switch2 12 +#define switch3 13 +#define switch4 14 +#define switch5 15 +#define switch6 17 +#define switch7 18 +#define switch8 19 +#define switch9 5 +#define switch10 6 +#define switch11 7 +#define switch12 8 +#define switch13 9 +#define switch14 10 +#define on 0x80 +#define off 0 +const int FunctionPin9 = 20; // Place holders ONLY +const int FunctionPin10 = 20; // Place holders ONLY +const int FunctionPin11 = 20; // F13 LED +const int FunctionPin12 = 20; // F12 LED +const int FunctionPin13 = 20; // F13 LED +const int FunctionPin14 = 20; // F14 LED +const int FunctionPin15 = 20; // Place holders ONLY +int MasterDecoderDisable = 0; +int Function0_value = 0; +byte function_value [ ] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +uint8_t cv_value; + +NmraDcc Dcc ; +DCC_MSG Packet ; +int t; // temp +struct QUEUE +{ + int inuse; + int current_position; + int increment; + int stop_value; + int start_value; +}; +QUEUE *ftn_queue = new QUEUE[17]; + +struct CVPair +{ + uint16_t CV; + uint8_t Value; +}; +CVPair FactoryDefaultCVs [] = +{ + {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address&0x7F }, + + // These two CVs define the Long DCC Address + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, ((This_Decoder_Address>>8)&0x7F)+192 }, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address&0xFF }, + + // ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS +// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps + {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps +// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps + {CV_DECODER_MASTER_RESET, 0}, + + {30, 0}, //F0 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + + {31, 1}, //F1 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {32, 2}, //F2 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {33, 3}, //F3 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {34, 4}, //F4 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {35, 5}, //F5 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {36, 6}, //F6 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {37, 7}, //F7 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {38, 8}, //F8 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {39, 9}, //F9 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {40, 10}, //F10 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + + {41, 11}, + {42, 11}, + {43, 11}, + {44, 11}, + {45, 22}, //F15 not used + + {48, 120}, // servo_master_slowdown_CV Higher number slows servo movment + {49, 22}, // Starting sound volume (starting_volume_CV) + +#define soundM 4 +#define servoM 5 +#define delayM 55 +#define servostartM 140 +#define servoendM 42 + {50, 0}, // Wait1 0-254 0.1 Seconds // switch SET 1-1 + {51, servoM}, // servo Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {52, servostartM}, // servo position + {53, delayM}, // Wait2 0-254 0.1 Seconds + {54, soundM}, // sound Mode + {55, 1}, // sound track + {56, delayM}, // Wait3 0-254 0.1 Seconds + {57, servoM}, // servo Mode + {58, servoendM}, // servo position + {59, delayM}, // Wait4 0-254 0.1 Seconds + {60, soundM}, // sound Mode + {61, 2}, // sound track + {62, delayM}, // Wait5 0-254 0.1 Seconds + {63, servoM}, // servo Mode + {64, servostartM}, // servo position + {65, 0}, // Not Used + + {66, delayM}, // Wait1 0-254 0.1 Seconds // switch SET 1-2 + {67, soundM}, // sound Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {68, 3}, // sound track + {69, delayM}, // Wait2 0-254 0.1 Seconds + {70, servoM}, // servo Mode + {71, servoendM}, // servo position + {72, delayM}, // Wait3 0-254 0.1 Seconds + {73, soundM}, // sound Mode + {74, 4}, // sound track + {75, delayM}, // Wait4 0-254 0.1 Seconds + {76, servoM}, // servo Mode + {77, servostartM}, // servo position + {78, delayM}, // Wait5 0-254 0.1 Seconds + {79, soundM}, // sound Mode + {80, 5}, // sound track + {81, 0}, // Not Used + + {82, delayM}, // Wait1 0-254 0.1 Seconds // switch SET 1-3 + {83, servoM}, // servo Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {84, servoendM}, // servo + {85, delayM}, // Wait2 0-254 0.1 Seconds + {86, soundM}, // sound Mode + {87, 6}, // sound + {88, delayM}, // Wait3 0-254 0.1 Seconds + {89, servoM}, // servo Mode + {90, servostartM}, // servo + {91, delayM}, // Wait4 0-254 0.1 Seconds + {92, soundM}, // sound Mode + {93, 7}, // sound + {94, delayM}, // Wait5 0-254 0.1 Seconds + {95, servoM}, // servo Mode + {96, servoendM}, // servo + {97, 0}, // Not Used + + {98, delayM}, // Wait1 0-254 0.1 Seconds // switch SET 1-4 + {99, soundM}, // sound Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {100, 8}, // sound + {101, delayM}, // Wait2 0-254 0.1 Seconds + {102, servoM}, // servo Mode + {103, servostartM}, // servo + {104, delayM}, // Wait3 0-254 0.1 Seconds + {105, soundM}, // sound Mode + {106, 9}, // sound + {107, delayM}, // Wait4 0-254 0.1 Seconds + {108, servoM}, // servo Mode + {109, servoendM}, // Switch Pin4 + {110, delayM}, // Wait5 0-254 0.1 Seconds + {111, soundM}, // sound Mode + {112, 10}, // sound + {113, 0}, // Not Used + + {114, delayM}, // Wait1 0-254 0.1 Seconds // switch SET 1-5 + {115, servoM}, // servo Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {116, servostartM}, // servo + {117, delayM}, // Wait2 0-254 0.1 Seconds + {118, soundM}, // sound Mode + {119, 11}, // sound + {120, delayM}, // Wait3 0-254 0.1 Seconds + {121, servoM}, // servo Mode + {122, servoendM}, // servo + {123, delayM}, // Wait4 0-254 0.1 Seconds + {124, soundM}, // sound Mode + {125, 12}, // sound + {126, delayM}, // Wait5 0-254 0.1 Seconds + {127, servoM}, // servo Mode + {128, 90}, // servo + {129, 0}, // Not Used + + {130, 0}, // Wait1 0-254 0.1 Seconds // switch SET 2-1 + {131, servoM}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {132, servostartM}, // Switch Pin1 + {133, delayM}, // Wait2 0-254 0.1 Seconds + {134, soundM}, // Switch Mode + {135, 13}, // Switch Pin2 + {136, delayM}, // Wait3 0-254 0.1 Seconds + {137, servoM}, // Switch Mode + {138, servoendM}, // Switch Pin3 + {139, delayM}, // Wait4 0-254 0.1 Seconds + {140, soundM}, // Switch Mode + {141, 14}, // Switch Pin4 + {142, delayM}, // Wait5 0-254 0.1 Seconds + {143, servoM}, // Switch Mode + {144, servostartM}, // Switch Pin5 + {145, 0}, // Not Used + + {146, delayM}, // Wait1 0-254 0.1 Seconds // switch SET 2-2 + {147, soundM}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {148, 15}, // Switch Pin1 + {149, delayM}, // Wait2 0-254 0.1 Seconds + {150, servoM}, // Switch Mode + {151, servoendM}, // Switch Pin2 + {152, delayM}, // Wait3 0-254 0.1 Seconds + {153, soundM}, // Switch Mode + {154, 16}, // Switch Pin3 + {155, delayM}, // Wait4 0-254 0.1 Seconds + {156, servoM}, // Switch Mode + {157, servostartM}, // Switch Pin4 + {158, delayM}, // Wait5 0-254 0.1 Seconds + {159, soundM}, // Switch Mode + {160, 17}, // Switch Pin5 + {161, 0}, // Not Used + + {162, delayM}, // Wait1 0-254 0.1 Seconds // switch SET 2-3 + {163, servoM}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {164, servoendM}, // Switch Pin1 + {165, delayM}, // Wait2 0-254 0.1 Seconds + {166, soundM}, // Switch Mode + {167, 0}, // Switch Pin2 + {168, delayM}, // Wait3 0-254 0.1 Seconds + {169, servoM}, // Switch Mode + {170, servostartM}, // Switch Pin3 + {171, delayM}, // Wait4 0-254 0.1 Seconds + {172, soundM}, // Switch Mode + {173, 0}, // Switch Pin4 + {174, delayM}, // Wait5 0-254 0.1 Seconds + {175, servoM}, // Switch Mode + {176, servoendM}, // Switch Pin5 + {177, 0}, // Not Used + + {178, delayM}, // Wait1 0-254 0.1 Seconds // switch SET 2-4 + {179, soundM}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {180, 0}, // Switch Pin1 + {181, delayM}, // Wait2 0-254 0.1 Seconds + {182, servoM}, // Switch Mode + {183, servostartM}, // Switch Pin2 + {184, delayM}, // Wait3 0-254 0.1 Seconds + {185, soundM}, // Switch Mode + {186, 0}, // Switch Pin3 + {187, delayM}, // Wait4 0-254 0.1 Seconds + {188, servoM}, // Switch Mode + {189, servoendM}, // Switch Pin4 + {190, delayM}, // Wait5 0-254 0.1 Seconds + {191, soundM}, // Switch Mode + {192, 0}, // Switch Pin5 + {193, 0}, // Not Used + + {194, delayM}, // Wait1 0-254 0.1 Seconds // switch SET 2-5 + {195, servoM}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {196, servostartM}, // Switch Pin1 + {197, delayM}, // Wait2 0-254 0.1 Seconds + {198, soundM}, // Switch Mode + {199, 0}, // Switch Pin2 + {200, delayM}, // Wait3 0-254 0.1 Seconds + {201, servoM}, // Switch Mode + {202, servoendM}, // Switch Pin3 + {203, delayM}, // Wait4 0-254 0.1 Seconds + {204, soundM}, // Switch Mode + {205, 0}, // Switch Pin4 + {206, delayM}, // Wait5 0-254 0.1 Seconds + {207, servoM}, // Switch Mode + {208, 90}, // Switch Pin5 + {209, 0}, // Not Used + + //252,252 CV_DECODER_MASTER_RESET + + {253, 0}, // Extra +}; + +uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +void notifyCVResetFactoryDefault() +{ + // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset + // to flag to the loop() function that a reset to Factory Defaults needs to be done + FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +}; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS + +void setup() //****************************************************** +{ + pinMode (MasterDecoderDisablePin,INPUT_PULLUP); //Master Decoder Disable Input Active LOW + // initialize the digital pins as outputs + for (int i=0; i < numfpins; i++) { + pinMode(fpins[i], OUTPUT); + digitalWrite(fpins[i], 0); // All OUPUT pins initialized LOW + } + // initialize the digital pins as inputs + for (int i=0; i < numINpins; i++) { + pinMode(inputpins[i], INPUT_PULLUP); + } +#ifdef DEBUG + Serial.begin(115200); +#endif + +#ifdef SOUND_PLAYER15 + DFSerial1.begin (9600); + delay(40); + Player1.begin (DFSerial1); + delay(80); + setVolumeOnChannel (Dcc.getCV(starting_volume_CV)); +#endif + +#ifdef USE_SERVO14 + sservo.attach(default_servo_pin); // Start Servo on default_servo_pin //Position Servo + delay(50); + sservo.write(servo_start_position); // Set starting position + servo_pos.current_position = servo_start_position; + servo_pos.delta = 0; + servo_pos.target_position = servo_start_position; + delay(500); + SoftwareServo::refresh(); +#endif + + // Setup which External Interrupt, the Pin it's associated with that we're using + Dcc.pin(0, 2, 0); + // Call the main DCC Init function to enable the DCC Receiver + Dcc.init( MAN_ID_DIY, 61, FLAGS_MY_ADDRESS_ONLY, 0 ); + delay(800); +#if defined(DECODER_LOADED) + if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET ) +#endif + { + for (int j=0; j < FactoryDefaultCVIndex; j++ ) + Dcc.setCV( FactoryDefaultCVs[j].CV, FactoryDefaultCVs[j].Value); + } + // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; +#ifdef DEBUG + Serial.println("CV Dump:"); + for (i=30; i<41; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=30; i<41; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Large Switch Set 1"); + for (i=50; i<66; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=50; i<66; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=66; i<82; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=66; i<82; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=82; i<98; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=82; i<98; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=98; i<114; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=98; i<114; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=114; i<130; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=114; i<130; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Large Switch Set 2"); + for (i=130; i<146; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=130; i<146; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=146; i<162; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=146; i<162; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=162; i<178; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=162; i<178; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=178; i<194; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=178; i<194; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=194; i<210; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=194; i<210; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); +#endif +} +void loop() //*********************************************************************************** +{ + //MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation + Dcc.process(); +#ifdef USE_SERVO14 + SoftwareServo::refresh(); + if (servo_slow_counter > Dcc.getCV(servo_master_slowdown_CV) ) update_servos(); + else servo_slow_counter++; +#endif + + //delay(1); +// INPUT OVER RIDES + // Check Master Input Over ride + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + else MasterDecoderDisable = Function0_value & 1; + if (MasterDecoderDisable == 1) { + for (i=0; i < numfpins; i++) digitalWrite(fpins[i], 0); // All LEDs set LOW + } +// ******************************************************************************** + if (MasterDecoderDisable == 0) { + for (i=0; i < num_active_functions; i++) { + cv_value = Dcc.getCV(30+i) ; +#ifdef DEBUG + //Serial.print(" cv_value: "); + //Serial.println(cv_value, DEC) ; +#endif + switch ( cv_value ) { + case 0: // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + break; + case 1: // + if (((digitalRead(3)==LOW)||(function_value[cv_value]==1)) && !run_switch_set[cv_value]) { + ss1[0]=1; run_switch_set[cv_value]=true; + } + break; + case 2: // + if (((digitalRead(4)==LOW)||(function_value[cv_value]==1)) && !run_switch_set[cv_value]) { + ss2[0]=1; run_switch_set[cv_value]=true; + } + break; + default: // Extra + break; + } + } + } + // ========================== Large switch Set 1 Start Run + if (ss1[0]==1) { + ss1delay=millis()+(long(Dcc.getCV(50)*MasterTimeConstant)); // Wait1 + ss1[0]=0; ss1[1]=1; + } + if ((ss1[1]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(52)); + exec_switch_function(Dcc.getCV(51),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss1delay=millis()+(long(Dcc.getCV(53)*MasterTimeConstant)); // Wait2 + ss1[1]=0; ss1[2]=1; + } + if ((ss1[2]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(55)); + exec_switch_function (Dcc.getCV(54),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss1delay=millis()+(long(Dcc.getCV(56)*MasterTimeConstant)); // Wait3 + ss1[2]=0; ss1[3]=1; + } + if ((ss1[3]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(58)); + exec_switch_function(Dcc.getCV(57),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss1delay=millis()+(long(Dcc.getCV(59)*MasterTimeConstant)); // Wait4 + ss1[3]=0; ss1[4]=1; + } + if ((ss1[4]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(61)); + exec_switch_function(Dcc.getCV(60),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss1delay=millis()+(long(Dcc.getCV(62)*MasterTimeConstant)); // Wait5 + ss1[4]=0; ss1[5]=1; + } + if ((ss1[5]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(64)); + exec_switch_function(Dcc.getCV(63),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss1[5]=0; ss1[6]=1; + } +// ========================== Large switch Set 1 continues + if (ss1[6]==1) { + ss1delay=millis()+(long(Dcc.getCV(66)*MasterTimeConstant)); // Wait1 + ss1[6]=0; ss1[7]=1; + } + if ((ss1[7]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(68)); + exec_switch_function(Dcc.getCV(67),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss1delay=millis()+(long(Dcc.getCV(69)*MasterTimeConstant)); // Wait2 + ss1[7]=0; ss1[8]=1; + } + if ((ss1[8]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(71)); + exec_switch_function(Dcc.getCV(70),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss1delay=millis()+(long(Dcc.getCV(72)*MasterTimeConstant)); // Wait3 + ss1[8]=0; ss1[9]=1; + } + if ((ss1[9]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(74)); + exec_switch_function(Dcc.getCV(73),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss1delay=millis()+(long(Dcc.getCV(75)*MasterTimeConstant)); // Wait4 + ss1[9]=0; ss1[10]=1; + } + if ((ss1[10]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(77)); + exec_switch_function(Dcc.getCV(76),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss1delay=millis()+(long(Dcc.getCV(78)*MasterTimeConstant)); // Wait5 + ss1[10]=0; ss1[11]=1; + } + if ((ss1[11]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(80)); + exec_switch_function(Dcc.getCV(79),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss1[11]=0; ss1[12]=1; + } +// ========================== Large switch Set 1 continues + if (ss1[12]==1) { + ss1delay=millis()+(long(Dcc.getCV(82)*MasterTimeConstant)); // Wait1 + ss1[12]=0; ss1[13]=1; + } + if ((ss1[13]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(84)); + exec_switch_function(Dcc.getCV(83),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss1delay=millis()+(long(Dcc.getCV(85)*MasterTimeConstant)); // Wait2 + ss1[13]=0; ss1[14]=1; + } + if ((ss1[14]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(87)); + exec_switch_function(Dcc.getCV(86),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss1delay=millis()+(long(Dcc.getCV(88)*MasterTimeConstant)); // Wait3 + ss1[14]=0; ss1[15]=1; + } + if ((ss1[15]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(90)); + exec_switch_function(Dcc.getCV(89),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss1delay=millis()+(long(Dcc.getCV(91)*MasterTimeConstant)); // Wait4 + ss1[15]=0; ss1[16]=1; + } + if ((ss1[16]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(93)); + exec_switch_function(Dcc.getCV(92),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss1delay=millis()+(long(Dcc.getCV(94)*MasterTimeConstant)); // Wait5 + ss1[16]=0; ss1[17]=1; + } + if ((ss1[17]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(96)); + exec_switch_function(Dcc.getCV(95),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss1[17]=0; ss1[18]=1; + } +// ========================== Large switch Set 1 continues + if (ss1[18]==1) { + ss1delay=millis()+(long(Dcc.getCV(98)*MasterTimeConstant)); // Wait1 + ss1[18]=0; ss1[19]=1; + } + if ((ss1[19]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(100)); + exec_switch_function(Dcc.getCV(99),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss1delay=millis()+(long(Dcc.getCV(101)*MasterTimeConstant)); // Wait2 + ss1[19]=0; ss1[20]=1; + } + if ((ss1[20]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(103)); + exec_switch_function(Dcc.getCV(102),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss1delay=millis()+(long(Dcc.getCV(104)*MasterTimeConstant)); // Wait3 + ss1[20]=0; ss1[21]=1; + } + if ((ss1[21]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(106)); + exec_switch_function(Dcc.getCV(105),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss1delay=millis()+(long(Dcc.getCV(107)*MasterTimeConstant)); // Wait4 + ss1[21]=0; ss1[22]=1; + } + if ((ss1[22]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(109)); + exec_switch_function(Dcc.getCV(108),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss1delay=millis()+(long(Dcc.getCV(110)*MasterTimeConstant)); // Wait5 + ss1[22]=0; ss1[23]=1; + } + if ((ss1[23]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(112)); + exec_switch_function(Dcc.getCV(111),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss1[23]=0; ss1[24]=1; + } +// ========================== Large switch Set 1 continues + if (ss1[24]==1) { + ss1delay=millis()+(long(Dcc.getCV(114)*MasterTimeConstant)); // Wait1 + ss1[24]=0; ss1[25]=1; + } + if ((ss1[25]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(116)); + exec_switch_function(Dcc.getCV(115),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss1delay=millis()+(long(Dcc.getCV(117)*MasterTimeConstant)); // Wait2 + ss1[25]=0; ss1[26]=1; + } + if ((ss1[26]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(119)); + exec_switch_function(Dcc.getCV(118),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss1delay=millis()+(long(Dcc.getCV(120)*MasterTimeConstant)); // Wait3 + ss1[26]=0; ss1[27]=1; + } + if ((ss1[27]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(122)); + exec_switch_function(Dcc.getCV(121),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss1delay=millis()+(long(Dcc.getCV(123)*MasterTimeConstant)); // Wait4 + ss1[27]=0; ss1[28]=1; + } + if ((ss1[28]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(125)); + exec_switch_function(Dcc.getCV(124),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss1delay=millis()+(long(Dcc.getCV(126)*MasterTimeConstant)); // Wait5 + ss1[28]=0; ss1[29]=1; + } + if ((ss1[29]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(128)); + exec_switch_function(Dcc.getCV(127),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss1[29]=0; run_switch_set[1]=false; + } + +// ========================== Large switch Set 2 Start Run + if (ss2[0]==1) { + ss2delay=millis()+(long(Dcc.getCV(130)*MasterTimeConstant)); // Wait1 + ss2[0]=0; ss2[1]=1; + } + if ((ss2[1]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(132)); + exec_switch_function(Dcc.getCV(131),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss2delay=millis()+(long(Dcc.getCV(133)*MasterTimeConstant)); // Wait2 + ss2[1]=0; ss2[2]=1; + } + if ((ss2[2]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(135)); + exec_switch_function(Dcc.getCV(134),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss2delay=millis()+(long(Dcc.getCV(136)*MasterTimeConstant)); // Wait3 + ss2[2]=0; ss2[3]=1; + } + if ((ss2[3]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(138)); + exec_switch_function(Dcc.getCV(137),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss2delay=millis()+(long(Dcc.getCV(139)*MasterTimeConstant)); // Wait4 + ss2[3]=0; ss2[4]=1; + } + if ((ss2[4]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(141)); + exec_switch_function(Dcc.getCV(140),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss2delay=millis()+(long(Dcc.getCV(142)*MasterTimeConstant)); // Wait5 + ss2[4]=0; ss2[5]=1; + } + if ((ss2[5]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(144)); + exec_switch_function(Dcc.getCV(143),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss2[5]=0; ss2[6]=1; + } + +// ========================== switch Set 7 Start Run + if (ss2[6]==1) { + ss2delay=millis()+(long(Dcc.getCV(146)*MasterTimeConstant)); // Wait1 + ss2[6]=0; ss2[7]=1; + } + if ((ss2[7]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(148)); + exec_switch_function(Dcc.getCV(147),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss2delay=millis()+(long(Dcc.getCV(149)*MasterTimeConstant)); // Wait2 + ss2[7]=0; ss2[8]=1; + } + if ((ss2[8]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(151)); + exec_switch_function(Dcc.getCV(150),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss2delay=millis()+(long(Dcc.getCV(152)*MasterTimeConstant)); // Wait3 + ss2[8]=0; ss2[9]=1; + } + if ((ss2[9]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(154)); + exec_switch_function(Dcc.getCV(153),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss2delay=millis()+(long(Dcc.getCV(155)*MasterTimeConstant)); // Wait4 + ss2[9]=0; ss2[10]=1; + } + if ((ss2[10]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(157)); + exec_switch_function(Dcc.getCV(156),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss2delay=millis()+(long(Dcc.getCV(158)*MasterTimeConstant)); // Wait5 + ss2[10]=0; ss2[11]=1; + } + if ((ss2[11]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(160)); + exec_switch_function(Dcc.getCV(159),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss2[11]=0; ss2[12]=1; + } +// ========================== switch Set 8 Start Run + if (ss2[12]==1) { + ss2delay=millis()+(long(Dcc.getCV(162)*MasterTimeConstant)); // Wait1 + ss2[12]=0; ss2[13]=1; + } + if ((ss2[13]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(164)); + exec_switch_function(Dcc.getCV(163),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss2delay=millis()+(long(Dcc.getCV(165)*MasterTimeConstant)); // Wait2 + ss2[13]=0; ss2[14]=1; + } + if ((ss2[14]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(167)); + exec_switch_function(Dcc.getCV(166),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss2delay=millis()+(long(Dcc.getCV(168)*MasterTimeConstant)); // Wait3 + ss2[14]=0; ss2[15]=1; + } + if ((ss2[15]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(170)); + exec_switch_function(Dcc.getCV(169),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss2delay=millis()+(long(Dcc.getCV(171)*MasterTimeConstant)); // Wait4 + ss2[15]=0; ss2[16]=1; + } + if ((ss2[16]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(173)); + exec_switch_function(Dcc.getCV(172),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss2delay=millis()+(long(Dcc.getCV(174)*MasterTimeConstant)); // Wait5 + ss2[16]=0; ss2[17]=1; + } + if ((ss2[17]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(176)); + exec_switch_function(Dcc.getCV(175),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss2[17]=0; ss2[18]=1; + } +// ========================== switch Set 9 Start Run + if (ss2[18]==1) { + ss2delay=millis()+(long(Dcc.getCV(178)*MasterTimeConstant)); // Wait1 + ss2[18]=0; ss2[19]=1; + } + if ((ss2[19]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(180)); + exec_switch_function(Dcc.getCV(179),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss2delay=millis()+(long(Dcc.getCV(181)*MasterTimeConstant)); // Wait2 + ss2[19]=0; ss2[20]=1; + } + if ((ss2[20]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(183)); + exec_switch_function(Dcc.getCV(182),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss2delay=millis()+(long(Dcc.getCV(184)*MasterTimeConstant)); // Wait3 + ss2[20]=0; ss2[21]=1; + } + if ((ss2[21]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(186)); + exec_switch_function(Dcc.getCV(185),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss2delay=millis()+(long(Dcc.getCV(187)*MasterTimeConstant)); // Wait4 + ss2[21]=0; ss2[22]=1; + } + if ((ss2[22]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(189)); + exec_switch_function(Dcc.getCV(188),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss2delay=millis()+(long(Dcc.getCV(190)*MasterTimeConstant)); // Wait5 + ss2[22]=0; ss2[23]=1; + } + if ((ss2[23]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(192)); + exec_switch_function(Dcc.getCV(191),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss2[23]=0; ss2[24]=1; + } +// ========================== switch Set 10 Start Run + if (ss2[24]==1) { + ss2delay=millis()+(long(Dcc.getCV(194)*MasterTimeConstant)); // Wait1 + ss2[24]=0; ss2[25]=1; + } + if ((ss2[25]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(196)); + exec_switch_function(Dcc.getCV(195),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss2delay=millis()+(long(Dcc.getCV(197)*MasterTimeConstant)); // Wait2 + ss2[25]=0; ss2[26]=1; + } + if ((ss2[26]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(199)); + exec_switch_function(Dcc.getCV(198),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss2delay=millis()+(long(Dcc.getCV(200)*MasterTimeConstant)); // Wait3 + ss2[26]=0; ss2[27]=1; + } + if ((ss2[27]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(202)); + exec_switch_function(Dcc.getCV(201),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss2delay=millis()+(long(Dcc.getCV(203)*MasterTimeConstant)); // Wait4 + ss2[27]=0; ss2[28]=1; + } + if ((ss2[28]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(205)); + exec_switch_function(Dcc.getCV(204),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss2delay=millis()+(long(Dcc.getCV(206)*MasterTimeConstant)); // Wait5 + ss2[28]=0; ss2[29]=1; + } + if ((ss2[29]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(208)); + exec_switch_function(Dcc.getCV(207),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss2[29]=0; run_switch_set[2]=false; + } +} // end loop() + +void exec_switch_function (byte switch_function, byte fpin,byte fbit) { + byte arg; + if (MasterDecoderDisable == 1) return; + + arg = fpin|(fbit<<7); // 8 bits of argument passed + + // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next + switch ( switch_function ) { // find the switch function to execute + case 0: // 0 == No function + default: + break; + case 1: // + digitalWrite ( fpin,fbit ); // Simple pin switch on/off + break; + case 2: // + if (fbit!=0) digitalWrite ( fpin, random ( 0,2) ); // Random pin switch on/off + else digitalWrite ( fpin, 0 ); // Force the bit OFF + break; + case 3: // + if (fbit!=0) digitalWrite ( fpin, Weighted_ON() ); // Weighted Random pin switch on/off + else digitalWrite ( fpin, 0 ); // Force the bit OFF + break; + case 4: // +#ifdef SOUND_PLAYER15 + //setVolumeOnChannel (default_volume * fbit); // set volume level + playTrackOnChannel(fpin); // play sound track fpin 1-127 +#endif + break; + case 5: // +#ifdef USE_SERVO14 + set_servo(arg); // Position Servo +#endif + break; + case 6: // + digitalWrite ( fpin,fbit ); // Dual pin on/off alternate blink + digitalWrite ( fpin+1,(~fbit)&0x01 ); // Dual pin on/off alternate blink + break; + case 7: // Start up another switch set + { + switch ( fpin ) { // Start another Switching set based on the fpin argument + case 0: // + default: + break; + case 1: // Start Switch Set 1 + ss1[0] = 1; run_switch_set[fpin]=true; + break; + case 2: // Start Switch Set 2 + ss2[0] = 1; run_switch_set[fpin]=true; + break; + } + } + break; + case 8: // Start Switching set if not already started + { + switch ( fpin ) { // Start another Switching set based on the fpin argument + case 0: // + default: + break; + case 1: // Start Switch Set 1 + if( run_switch_set[fpin]==false) {ss1[0] = 1; run_switch_set[fpin]=true;} + break; + case 2: // Start Switch Set 2 + if( run_switch_set[fpin]==false) {ss2[0] = 1; run_switch_set[fpin]=true;} + break; + } + } + break; + } + SoftwareServo::refresh(); +} // end exec_switch_function() + +boolean Weighted_ON() { + if (random (0, 100 ) > 40) return true; //This will reyrn ON/true 60% of the time + return false; +} // end Weighted_ON() + +#ifdef USE_SERVO14 +void set_servo (byte position) { + if (servo_pos.current_position == position) { + servo_pos.delta = 0; + servo_pos.target_position = position; + return; + } + if (servo_pos.current_position < position) servo_pos.delta = 1+servo_unit_faster; + else servo_pos.delta = -1-servo_unit_faster; + servo_pos.target_position = position; +} // end set_servo() + +void update_servos() { + servo_slow_counter = 1; + if (servo_pos.delta != 0 ) { + servo_pos.current_position=servo_pos.current_position+servo_pos.delta; + if ((servo_pos.delta > 0)&&(servo_pos.current_position > servo_pos.target_position)) + { + servo_pos.current_position = servo_pos.target_position; + servo_pos.delta = 0; + } + if ((servo_pos.delta < 0)&&(servo_pos.current_position < servo_pos.target_position)) + { + servo_pos.current_position = servo_pos.target_position; + servo_pos.delta = 0; + } + if (servo_pos.current_position == servo_pos.target_position) servo_pos.delta = 0; + } + sservo.write ( servo_pos.current_position ); +} // end update_servos() +#endif + +void playTrackOnChannel ( byte dtrack) { +#ifdef SOUND_PLAYER15 + if (dtrack == 0) return; + if (dtrack!=127) {Player1.play(dtrack); } //delay(audiocmddelay); } + else {Player1.play(random(First_Track,Last_Track+1)); } //delay(audiocmddelay); } +#endif +} // end playTrackOnChannel() + +void setVolumeOnChannel ( byte dvolume) { +#ifdef SOUND_PLAYER15 + if(dvolume>30) return; // Don't change the volume if out of range + Player1.volume(dvolume); + delay(audiocmddelay); +#endif +} // end setVolumeOnChannel() + +void notifyCVChange( uint16_t CV, uint8_t Value) { +#ifdef DEBUG + //Serial.print("CV= "); + //Serial.println(CV, DEC) ; + //Serial.print("Value= "); + //Serial.println(Value, DEC) ; +#endif + if ( CV==49 ) setVolumeOnChannel (Value); +} + +void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { +#ifdef DEBUG + //Serial.print("Addr= "); + //Serial.println(Addr, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch(FuncGrp) + { + case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1 + exec_function( 0, FunctionPin0, (FuncState & FN_BIT_00)>>4 ); + exec_function( 1, FunctionPin1, (FuncState & FN_BIT_01)); + exec_function( 2, FunctionPin2, (FuncState & FN_BIT_02)>>1); + exec_function( 3, FunctionPin3, (FuncState & FN_BIT_03)>>2 ); + exec_function( 4, FunctionPin4, (FuncState & FN_BIT_04)>>3 ); + break; + case FN_5_8: //Function Group 1 S FFFF == 1 F8 F7 F6 F5 & == 0 F12 F11 F10 F9 F8 + exec_function( 5, FunctionPin5, (FuncState & FN_BIT_05)); + exec_function( 6, FunctionPin6, (FuncState & FN_BIT_06)>>1 ); + exec_function( 7, FunctionPin7, (FuncState & FN_BIT_07)>>2 ); + exec_function( 8, FunctionPin8, (FuncState & FN_BIT_08)>>3 ); + break; + + case FN_9_12: + exec_function( 9, FunctionPin9, (FuncState & FN_BIT_09)); + exec_function( 10, FunctionPin10, (FuncState & FN_BIT_10)>>1 ); + exec_function( 11, FunctionPin11, (FuncState & FN_BIT_11)>>2 ); + exec_function( 12, FunctionPin12, (FuncState & FN_BIT_12)>>3 ); + break; + case FN_13_20: //Function Group 2 FuncState == F20-F13 Function Control + exec_function( 13, FunctionPin13, (FuncState & FN_BIT_13)); + exec_function( 14, FunctionPin14, (FuncState & FN_BIT_14)>>1 ); + //exec_function( 15, FunctionPin15, (FuncState & FN_BIT_15)>>2 ); + //exec_function( 16, FunctionPin16, (FuncState & FN_BIT_16)>>3 ); + break; + + case FN_21_28: + break; + } +} // end notifyDccFunc +void exec_function (int function, int pin, int FuncState) { +#ifdef DEBUG + //Serial.print("ex function= "); + //Serial.println(function, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch ( Dcc.getCV( 30+function) ) { // Config + case 0: // Master Disable + Function0_value = byte(FuncState); + break; + case 1: // run switch set [ function ] + case 2: // run switch set [ function ] + case 3: // run switch set [ function ] + case 4: // run switch set [ function ] + case 5: // run switch set [ function ] + case 6: // run switch set [ function ] + case 7: // run switch set [ function ] + case 8: // run switch set [ function ] + case 9: // run switch set [ function ] + case 10: // run switch set [ function ] + function_value[function] = byte(FuncState); + break; + default: + break;; + } +} // end exec_function + +/* DFPlayer Commands +//----Set volume---- + myDFPlayer.volume(10); //Set volume value (0~30). + myDFPlayer.volumeUp(); //Volume Up + myDFPlayer.volumeDown(); //Volume Down + //----Set different EQ---- + myDFPlayer.EQ(DFPLAYER_EQ_NORMAL); +// myDFPlayer.EQ(DFPLAYER_EQ_POP); +// myDFPlayer.EQ(DFPLAYER_EQ_ROCK); +// myDFPlayer.EQ(DFPLAYER_EQ_JAZZ); +// myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC); +// myDFPlayer.EQ(DFPLAYER_EQ_BASS); + //----Set device we use SD as default---- +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_U_DISK); + myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_AUX); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_SLEEP); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_FLASH); + //----Mp3 control---- +// myDFPlayer.sleep(); //sleep +// myDFPlayer.reset(); //Reset the module +// myDFPlayer.enableDAC(); //Enable On-chip DAC +// myDFPlayer.disableDAC(); //Disable On-chip DAC +// myDFPlayer.outputSetting(true, 15); //output setting, enable the output and set the gain to 15 + //----Mp3 play---- + myDFPlayer.next(); //Play next mp3 + myDFPlayer.previous(); //Play previous mp3 + myDFPlayer.play(1); //Play the first mp3 + myDFPlayer.loop(1); //Loop the first mp3 + myDFPlayer.pause(); //pause the mp3 + myDFPlayer.start(); //start the mp3 from the pause + myDFPlayer.playFolder(15, 4); //play specific mp3 in SD:/15/004.mp3; Folder Name(1~99); File Name(1~255) + myDFPlayer.enableLoopAll(); //loop all mp3 files. + myDFPlayer.disableLoopAll(); //stop loop all mp3 files. + myDFPlayer.playMp3Folder(4); //play specific mp3 in SD:/MP3/0004.mp3; File Name(0~65535) + myDFPlayer.advertise(3); //advertise specific mp3 in SD:/ADVERT/0003.mp3; File Name(0~65535) + myDFPlayer.stopAdvertise(); //stop advertise + myDFPlayer.playLargeFolder(2, 999); //play specific mp3 in SD:/02/004.mp3; Folder Name(1~10); File Name(1~1000) + myDFPlayer.loopFolder(5); //loop all mp3 files in folder SD:/05. + myDFPlayer.randomAll(); //Random play all the mp3. + myDFPlayer.enableLoop(); //enable loop. + myDFPlayer.disableLoop(); //disable loop. +*/ diff --git a/examples/IDECDemo&Diags/IDEC2_5_LargeFunctionBellDemo5/IDEC2_5_LargeFunctionBellDemo5.ino b/examples/IDECDemo&Diags/IDEC2_5_LargeFunctionBellDemo5/IDEC2_5_LargeFunctionBellDemo5.ino new file mode 100644 index 0000000..966187c --- /dev/null +++ b/examples/IDECDemo&Diags/IDEC2_5_LargeFunctionBellDemo5/IDEC2_5_LargeFunctionBellDemo5.ino @@ -0,0 +1,1149 @@ +// Interactive Decoder Random Switches IDEC2_5_LargeFunctionSetsDev.ino +// Version 1.09 Geoff Bunza 2020 +// Works with both short and long DCC Addesses +// This decoder will control Switch Sequences, servos, sounds and LEDs +// F0=Master Function OFF = Function ON DISABLES the decoder +/* F0 is configured as Master Decoder Disable Override ON==Disable Decoder + * Input Pin for Decoder Disable Pin 16/A2 Active LOW +// F1-F2 Eight Switch Sets 1-2 controlled by Input pins 3,4 respectively + * All Switch Sets are defined by groups of 80 CVs + - Either a DCC Function 1-2 on OR an Input Pin (3,4,) Switched Low enables a decoder function (ON) + - BOTH the respective DCC Decoder Function 1-2 must be Off AND its respective Input Pin (3,4) + MUST be High for a decoder function to be considered disabled + - A decoder function LEFT ENABLED will repreat the respecpective action as long as it is enabled + * Switch Set CV's are 25 groups of 3 CVs each: + CV1 - A delay (0-255) which will be multiplied by the + MasterTimeConstant setting time increments from milliseconds to minutes + 0 = No Delay + CV2 - A Mode or Command byte Describing what will be executed in this Switch Step, including: + 0 = No Operation / Null /Skip + 1 = Simple pin switch on/off + 2= Random pin switch on/off + 3 = Weighted Random pin switch on/off default is 60% ON time but can be set to anything 1-99% + 4 = Play sound track using fpin value for the track 1-126, 0 = Skip Play, 127 = Select Random Track + from First_Track to Last_Track inclusive; + MSB=0->No Volume Change MSB=1 -> Set Volume to default_volume + 5 = Position Servo to 0-180 full speed of travel + 6 = Dual pin on/off used for alternate blink fpin and fpin+1 (MSB set value for fpin state) + 7 = Start another Switching set based on the fpin argument (Used to chain Switch Sets) + 8 = Start another Switching set based on the fpin argument ONLY if NOT already started + CV3 - An argument representing the Pin number affected in the lower 7 bits and the High bit (0x80 or 128) a value + or a general parameter like a servo position, a Sound track, or a sound set number to jump to + * Switch sets include CVs: 50-129 and 130=209 + * MAX one of 3 Configurations per pin function: + * Config 0=DISABLE On/Off,1-2=Switch Control 1-2 + +PRO MINI PIN ASSIGNMENT: +2 - DCC Input +3 - Input Pin Switch 1 +4 - Input Pin Switch 2 +5 - Switch 9 +6 - Switch 10 +7 - Switch 11 +8 - Switch 12 +9 - Switch 13 +10 - Switch 14 +11 - Switch 1 +12 - Switch 2 +13 - Switch 3 +14 A0 - Switch 4 or default_servo_pin +15 A1 - Switch 5 or default sound player pin (TX) connected to DFPlayer1 (RX) Pin 2 via 1K Ohm 1/4W Resistor +16 A2 - Input Pin for MasterDecoderDisable Active LOW +17 A3 - Switch 6 +18 A4 - Switch 7 +19 A5 - Switch 8 +*/ +// ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP +// ******** AFTER THE INITIAL DECODER LOAD REMOVE THE "//" IN THE FOOLOWING LINE!! +//#define DECODER_LOADED + +// ******** REMOVE THE "//" IN THE FOLOWING LINE TO enable sound DFPlayer on Pin 15 +#define SOUND_PLAYER15 + +// ******** REMOVE THE "//" IN THE FOLOWING LINE TO enable SERVO USE +#define USE_SERVO14 + +// ******** REMOVE THE "//" IN THE FOLOWING LINE TO SEND DEBUGGING +// ******** INFO TO THE SERIAL MONITOR *****NOTE Turning DEBUG ON changes ALL Timing!! +//#define DEBUG + + +#include +#include + +#ifdef USE_SERVO14 +SoftwareServo sservo; +#endif +byte default_servo_pin = 14; +byte servo_start_position = 90; +const byte servo_master_slowdown_CV = 48; //servo loop counter limit CV +int servo_slow_counter = 1; //servo loop counter to slowdown servo transit +byte servo_unit_faster = 0; + +#ifdef SOUND_PLAYER15 +#include +#include +SoftwareSerial DFSerial1(22,15); // PRO MINI RX, PRO MINI TX serial to DFPlayer +DFRobotDFPlayerMini Player1; +#endif +#define default_volume 20 // sets default volume 0-30, 0 == OFF, >30 == Skip Track +#define First_Track 1 // Play Random Tracks First_Track#=Start_Track >=1 +#define Last_Track 12 // Play Random Tracks Last_Track= Last Playable Track in Range <= Last Numbered Track +const byte starting_volume_CV = 49; // If no volume is set use this CV at the start +const int audiocmddelay = 40; + +#define This_Decoder_Address 24 +uint8_t CV_DECODER_MASTER_RESET = 252; + +//Uncomment ONLY ONE of the following: +//#define MasterTimeConstant 1L // milliseconds Timing +#define MasterTimeConstant 10L // 10's of milliseconds Timing +//#define MasterTimeConstant 100L // Tenths of a second Timing +//#define MasterTimeConstant 1000L // Seconds Timing +//#define MasterTimeConstant 10000L // 10's of Seconds Timing +//#define MasterTimeConstant 60000L // Minutes Timing +//#define MasterTimeConstant 3600000L // Hours Timing + +int del_tim = 4000; +uint16_t ttemp, i; +byte otemp; + +byte ss1[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +unsigned long ss1delay=0; +byte ss2[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +unsigned long ss2delay=0; +bool run_switch_set [ ] = {false,false,false}; +byte switchset_channel[ ]={0,0,0}; + +struct SERVO_TRACKING +{ + byte current_position; + byte target_position; + char delta; +}; +SERVO_TRACKING servo_pos; + +const int MasterDecoderDisablePin = 16; // D16/A0 Master Decoder Disable Input Pin Active LOW + +const int numINpins = 3; // Number of INput pins to initialize +byte inputpins [] = {3,4,16}; //These are all the Input Pins +const int numfpins = 14; // Number of Output pins to initialize +const int num_active_functions = 3; // Number of Functions stating with F0 +byte fpins [] = {5,6,7,8,9,10,11,12,13,14,15,17,18,19}; //These are all the Output Pins (first 15 is placeholder) +const int FunctionPin0 = 20; // D14/A0 DFPlayer Transmit (TX) Pin 3 +const int FunctionPin1 = 20; // A2 LED Place holders ONLY +const int FunctionPin2 = 20; // A3 LED Place holders ONLY +const int FunctionPin3 = 20; // A4 LED Place holders ONLY +const int FunctionPin4 = 20; // A5 LED Place holders ONLY +const int FunctionPin5 = 20; // A6 LED Place holders ONLY +const int FunctionPin6 = 20; // A7 Place holders ONLY +const int FunctionPin7 = 20; // A8 Place holders ONLY +const int FunctionPin8 = 20; // A9 Place holders ONLY +#define switch1 11 +#define switch2 12 +#define switch3 13 +#define switch4 14 +#define switch5 15 +#define switch6 17 +#define switch7 18 +#define switch8 19 +#define switch9 5 +#define switch10 6 +#define switch11 7 +#define switch12 8 +#define switch13 9 +#define switch14 10 +#define on 0x80 +#define off 0 +const int FunctionPin9 = 20; // Place holders ONLY +const int FunctionPin10 = 20; // Place holders ONLY +const int FunctionPin11 = 20; // F13 LED +const int FunctionPin12 = 20; // F12 LED +const int FunctionPin13 = 20; // F13 LED +const int FunctionPin14 = 20; // F14 LED +const int FunctionPin15 = 20; // Place holders ONLY +int MasterDecoderDisable = 0; +int Function0_value = 0; +byte function_value [ ] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +uint8_t cv_value; + +NmraDcc Dcc ; +DCC_MSG Packet ; +int t; // temp +struct QUEUE +{ + int inuse; + int current_position; + int increment; + int stop_value; + int start_value; +}; +QUEUE *ftn_queue = new QUEUE[17]; + +struct CVPair +{ + uint16_t CV; + uint8_t Value; +}; +CVPair FactoryDefaultCVs [] = +{ + {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address&0x7F }, + + // These two CVs define the Long DCC Address + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, ((This_Decoder_Address>>8)&0x7F)+192 }, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address&0xFF }, + + // ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS +// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps + {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps +// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps + {CV_DECODER_MASTER_RESET, 0}, + + {30, 0}, //F0 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + + {31, 1}, //F1 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {32, 2}, //F2 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {33, 3}, //F3 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {34, 4}, //F4 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {35, 5}, //F5 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {36, 6}, //F6 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {37, 7}, //F7 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {38, 8}, //F8 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {39, 9}, //F9 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {40, 10}, //F10 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + + {41, 11}, + {42, 11}, + {43, 11}, + {44, 11}, + {45, 22}, //F15 not used + + {48, 120}, // servo_master_slowdown_CV Higher number slows servo movment + {49, 22}, // Starting sound volume (starting_volume_CV) + +#define soundM 4 +#define servoM 5 +#define delayM 90 +#define servostartM 140 +#define servoendM 42 + {50, 0}, // Wait1 0-254 0.1 Seconds // switch SET 1-1 + {51, servoM}, // servo Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {52, servostartM}, // servo position + {53, delayM}, // Wait2 0-254 0.1 Seconds + {54, soundM}, // sound Mode + {55, 3}, // sound track + {56, delayM}, // Wait3 0-254 0.1 Seconds + {57, servoM}, // servo Mode + {58, servoendM}, // servo position + {59, delayM}, // Wait4 0-254 0.1 Seconds + {60, soundM}, // sound Mode + {61, 3}, // sound track + {62, delayM}, // Wait5 0-254 0.1 Seconds + {63, servoM}, // servo Mode + {64, servostartM}, // servo position + {65, 0}, // Not Used + + {66, delayM}, // Wait1 0-254 0.1 Seconds // switch SET 1-2 + {67, soundM}, // sound Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {68, 9}, // sound track + {69, delayM}, // Wait2 0-254 0.1 Seconds + {70, servoM}, // servo Mode + {71, servoendM}, // servo position + {72, delayM}, // Wait3 0-254 0.1 Seconds + {73, soundM}, // sound Mode + {74, 9}, // sound track + {75, delayM}, // Wait4 0-254 0.1 Seconds + {76, servoM}, // servo Mode + {77, servostartM}, // servo position + {78, delayM}, // Wait5 0-254 0.1 Seconds + {79, soundM}, // sound Mode + {80, 11}, // sound track + {81, 0}, // Not Used + + {82, delayM}, // Wait1 0-254 0.1 Seconds // switch SET 1-3 + {83, servoM}, // servo Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {84, servoendM}, // servo + {85, delayM}, // Wait2 0-254 0.1 Seconds + {86, soundM}, // sound Mode + {87, 11}, // sound + {88, delayM}, // Wait3 0-254 0.1 Seconds + {89, servoM}, // servo Mode + {90, servostartM}, // servo + {91, delayM}, // Wait4 0-254 0.1 Seconds + {92, soundM}, // sound Mode + {93, 12}, // sound + {94, delayM}, // Wait5 0-254 0.1 Seconds + {95, servoM}, // servo Mode + {96, servoendM}, // servo + {97, 0}, // Not Used + + {98, delayM}, // Wait1 0-254 0.1 Seconds // switch SET 1-4 + {99, soundM}, // sound Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {100, 12}, // sound + {101, delayM}, // Wait2 0-254 0.1 Seconds + {102, servoM}, // servo Mode + {103, servostartM}, // servo + {104, delayM}, // Wait3 0-254 0.1 Seconds + {105, soundM}, // sound Mode + {106, 0}, // sound + {107, delayM}, // Wait4 0-254 0.1 Seconds + {108, servoM}, // servo Mode + {109, servoendM}, // Switch Pin4 + {110, delayM}, // Wait5 0-254 0.1 Seconds + {111, soundM}, // sound Mode + {112, 0}, // sound + {113, 0}, // Not Used + + {114, delayM}, // Wait1 0-254 0.1 Seconds // switch SET 1-5 + {115, servoM}, // servo Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {116, servostartM}, // servo + {117, delayM}, // Wait2 0-254 0.1 Seconds + {118, soundM}, // sound Mode + {119, 0}, // sound + {120, delayM}, // Wait3 0-254 0.1 Seconds + {121, servoM}, // servo Mode + {122, servoendM}, // servo + {123, delayM}, // Wait4 0-254 0.1 Seconds + {124, soundM}, // sound Mode + {125, 0}, // sound + {126, delayM}, // Wait5 0-254 0.1 Seconds + {127, servoM}, // servo Mode + {128, 90}, // servo + {129, 0}, // Not Used + + {130, 0}, // Wait1 0-254 0.1 Seconds // switch SET 2-1 + {131, servoM}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {132, servostartM}, // Switch Pin1 + {133, delayM}, // Wait2 0-254 0.1 Seconds + {134, soundM}, // Switch Mode + {135, 0}, // Switch Pin2 + {136, delayM}, // Wait3 0-254 0.1 Seconds + {137, servoM}, // Switch Mode + {138, servoendM}, // Switch Pin3 + {139, delayM}, // Wait4 0-254 0.1 Seconds + {140, soundM}, // Switch Mode + {141, 0}, // Switch Pin4 + {142, delayM}, // Wait5 0-254 0.1 Seconds + {143, servoM}, // Switch Mode + {144, servostartM}, // Switch Pin5 + {145, 0}, // Not Used + + {146, delayM}, // Wait1 0-254 0.1 Seconds // switch SET 2-2 + {147, soundM}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {148, 0}, // Switch Pin1 + {149, delayM}, // Wait2 0-254 0.1 Seconds + {150, servoM}, // Switch Mode + {151, servoendM}, // Switch Pin2 + {152, delayM}, // Wait3 0-254 0.1 Seconds + {153, soundM}, // Switch Mode + {154, 0}, // Switch Pin3 + {155, delayM}, // Wait4 0-254 0.1 Seconds + {156, servoM}, // Switch Mode + {157, servostartM}, // Switch Pin4 + {158, delayM}, // Wait5 0-254 0.1 Seconds + {159, soundM}, // Switch Mode + {160, 0}, // Switch Pin5 + {161, 0}, // Not Used + + {162, delayM}, // Wait1 0-254 0.1 Seconds // switch SET 2-3 + {163, servoM}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {164, servoendM}, // Switch Pin1 + {165, delayM}, // Wait2 0-254 0.1 Seconds + {166, soundM}, // Switch Mode + {167, 0}, // Switch Pin2 + {168, delayM}, // Wait3 0-254 0.1 Seconds + {169, servoM}, // Switch Mode + {170, servostartM}, // Switch Pin3 + {171, delayM}, // Wait4 0-254 0.1 Seconds + {172, soundM}, // Switch Mode + {173, 0}, // Switch Pin4 + {174, delayM}, // Wait5 0-254 0.1 Seconds + {175, servoM}, // Switch Mode + {176, servoendM}, // Switch Pin5 + {177, 0}, // Not Used + + {178, delayM}, // Wait1 0-254 0.1 Seconds // switch SET 2-4 + {179, soundM}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {180, 0}, // Switch Pin1 + {181, delayM}, // Wait2 0-254 0.1 Seconds + {182, servoM}, // Switch Mode + {183, servostartM}, // Switch Pin2 + {184, delayM}, // Wait3 0-254 0.1 Seconds + {185, soundM}, // Switch Mode + {186, 0}, // Switch Pin3 + {187, delayM}, // Wait4 0-254 0.1 Seconds + {188, servoM}, // Switch Mode + {189, servoendM}, // Switch Pin4 + {190, delayM}, // Wait5 0-254 0.1 Seconds + {191, soundM}, // Switch Mode + {192, 0}, // Switch Pin5 + {193, 0}, // Not Used + + {194, delayM}, // Wait1 0-254 0.1 Seconds // switch SET 2-5 + {195, servoM}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {196, servostartM}, // Switch Pin1 + {197, delayM}, // Wait2 0-254 0.1 Seconds + {198, soundM}, // Switch Mode + {199, 0}, // Switch Pin2 + {200, delayM}, // Wait3 0-254 0.1 Seconds + {201, servoM}, // Switch Mode + {202, servoendM}, // Switch Pin3 + {203, delayM}, // Wait4 0-254 0.1 Seconds + {204, soundM}, // Switch Mode + {205, 0}, // Switch Pin4 + {206, delayM}, // Wait5 0-254 0.1 Seconds + {207, servoM}, // Switch Mode + {208, 90}, // Switch Pin5 + {209, 0}, // Not Used + + //252,252 CV_DECODER_MASTER_RESET + + {253, 0}, // Extra +}; + +uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +void notifyCVResetFactoryDefault() +{ + // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset + // to flag to the loop() function that a reset to Factory Defaults needs to be done + FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +}; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS + +void setup() //****************************************************** +{ + pinMode (MasterDecoderDisablePin,INPUT_PULLUP); //Master Decoder Disable Input Active LOW + // initialize the digital pins as outputs + for (int i=0; i < numfpins; i++) { + pinMode(fpins[i], OUTPUT); + digitalWrite(fpins[i], 0); // All OUPUT pins initialized LOW + } + // initialize the digital pins as inputs + for (int i=0; i < numINpins; i++) { + pinMode(inputpins[i], INPUT_PULLUP); + } +#ifdef DEBUG + Serial.begin(115200); +#endif + +#ifdef SOUND_PLAYER15 + DFSerial1.begin (9600); + delay(40); + Player1.begin (DFSerial1); + delay(80); + setVolumeOnChannel (Dcc.getCV(starting_volume_CV)); +#endif + +#ifdef USE_SERVO14 + sservo.attach(default_servo_pin); // Start Servo on default_servo_pin //Position Servo + delay(50); + sservo.write(servo_start_position); // Set starting position + servo_pos.current_position = servo_start_position; + servo_pos.delta = 0; + servo_pos.target_position = servo_start_position; + delay(500); + SoftwareServo::refresh(); +#endif + + // Setup which External Interrupt, the Pin it's associated with that we're using + Dcc.pin(0, 2, 0); + // Call the main DCC Init function to enable the DCC Receiver + Dcc.init( MAN_ID_DIY, 61, FLAGS_MY_ADDRESS_ONLY, 0 ); + delay(800); +#if defined(DECODER_LOADED) + if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET ) +#endif + { + for (int j=0; j < FactoryDefaultCVIndex; j++ ) + Dcc.setCV( FactoryDefaultCVs[j].CV, FactoryDefaultCVs[j].Value); + } + // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; +#ifdef DEBUG + Serial.println("CV Dump:"); + for (i=30; i<41; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=30; i<41; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Large Switch Set 1"); + for (i=50; i<66; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=50; i<66; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=66; i<82; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=66; i<82; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=82; i<98; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=82; i<98; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=98; i<114; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=98; i<114; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=114; i<130; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=114; i<130; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Large Switch Set 2"); + for (i=130; i<146; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=130; i<146; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=146; i<162; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=146; i<162; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=162; i<178; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=162; i<178; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=178; i<194; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=178; i<194; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=194; i<210; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=194; i<210; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); +#endif +} +void loop() //*********************************************************************************** +{ + //MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation + Dcc.process(); +#ifdef USE_SERVO14 + SoftwareServo::refresh(); + if (servo_slow_counter > Dcc.getCV(servo_master_slowdown_CV) ) update_servos(); + else servo_slow_counter++; +#endif + + //delay(1); +// INPUT OVER RIDES + // Check Master Input Over ride + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + else MasterDecoderDisable = Function0_value & 1; + if (MasterDecoderDisable == 1) { + for (i=0; i < numfpins; i++) digitalWrite(fpins[i], 0); // All LEDs set LOW + } +// ******************************************************************************** + if (MasterDecoderDisable == 0) { + for (i=0; i < num_active_functions; i++) { + cv_value = Dcc.getCV(30+i) ; +#ifdef DEBUG + //Serial.print(" cv_value: "); + //Serial.println(cv_value, DEC) ; +#endif + switch ( cv_value ) { + case 0: // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + break; + case 1: // + if (((digitalRead(3)==LOW)||(function_value[cv_value]==1)) && !run_switch_set[cv_value]) { + ss1[0]=1; run_switch_set[cv_value]=true; + } + break; + case 2: // + if (((digitalRead(4)==LOW)||(function_value[cv_value]==1)) && !run_switch_set[cv_value]) { + ss2[0]=1; run_switch_set[cv_value]=true; + } + break; + default: // Extra + break; + } + } + } + // ========================== Large switch Set 1 Start Run + if (ss1[0]==1) { + ss1delay=millis()+(long(Dcc.getCV(50)*MasterTimeConstant)); // Wait1 + ss1[0]=0; ss1[1]=1; + } + if ((ss1[1]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(52)); + exec_switch_function(Dcc.getCV(51),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss1delay=millis()+(long(Dcc.getCV(53)*MasterTimeConstant)); // Wait2 + ss1[1]=0; ss1[2]=1; + } + if ((ss1[2]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(55)); + exec_switch_function (Dcc.getCV(54),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss1delay=millis()+(long(Dcc.getCV(56)*MasterTimeConstant)); // Wait3 + ss1[2]=0; ss1[3]=1; + } + if ((ss1[3]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(58)); + exec_switch_function(Dcc.getCV(57),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss1delay=millis()+(long(Dcc.getCV(59)*MasterTimeConstant)); // Wait4 + ss1[3]=0; ss1[4]=1; + } + if ((ss1[4]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(61)); + exec_switch_function(Dcc.getCV(60),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss1delay=millis()+(long(Dcc.getCV(62)*MasterTimeConstant)); // Wait5 + ss1[4]=0; ss1[5]=1; + } + if ((ss1[5]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(64)); + exec_switch_function(Dcc.getCV(63),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss1[5]=0; ss1[6]=1; + } +// ========================== Large switch Set 1 continues + if (ss1[6]==1) { + ss1delay=millis()+(long(Dcc.getCV(66)*MasterTimeConstant)); // Wait1 + ss1[6]=0; ss1[7]=1; + } + if ((ss1[7]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(68)); + exec_switch_function(Dcc.getCV(67),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss1delay=millis()+(long(Dcc.getCV(69)*MasterTimeConstant)); // Wait2 + ss1[7]=0; ss1[8]=1; + } + if ((ss1[8]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(71)); + exec_switch_function(Dcc.getCV(70),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss1delay=millis()+(long(Dcc.getCV(72)*MasterTimeConstant)); // Wait3 + ss1[8]=0; ss1[9]=1; + } + if ((ss1[9]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(74)); + exec_switch_function(Dcc.getCV(73),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss1delay=millis()+(long(Dcc.getCV(75)*MasterTimeConstant)); // Wait4 + ss1[9]=0; ss1[10]=1; + } + if ((ss1[10]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(77)); + exec_switch_function(Dcc.getCV(76),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss1delay=millis()+(long(Dcc.getCV(78)*MasterTimeConstant)); // Wait5 + ss1[10]=0; ss1[11]=1; + } + if ((ss1[11]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(80)); + exec_switch_function(Dcc.getCV(79),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss1[11]=0; ss1[12]=1; + } +// ========================== Large switch Set 1 continues + if (ss1[12]==1) { + ss1delay=millis()+(long(Dcc.getCV(82)*MasterTimeConstant)); // Wait1 + ss1[12]=0; ss1[13]=1; + } + if ((ss1[13]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(84)); + exec_switch_function(Dcc.getCV(83),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss1delay=millis()+(long(Dcc.getCV(85)*MasterTimeConstant)); // Wait2 + ss1[13]=0; ss1[14]=1; + } + if ((ss1[14]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(87)); + exec_switch_function(Dcc.getCV(86),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss1delay=millis()+(long(Dcc.getCV(88)*MasterTimeConstant)); // Wait3 + ss1[14]=0; ss1[15]=1; + } + if ((ss1[15]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(90)); + exec_switch_function(Dcc.getCV(89),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss1delay=millis()+(long(Dcc.getCV(91)*MasterTimeConstant)); // Wait4 + ss1[15]=0; ss1[16]=1; + } + if ((ss1[16]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(93)); + exec_switch_function(Dcc.getCV(92),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss1delay=millis()+(long(Dcc.getCV(94)*MasterTimeConstant)); // Wait5 + ss1[16]=0; ss1[17]=1; + } + if ((ss1[17]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(96)); + exec_switch_function(Dcc.getCV(95),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss1[17]=0; ss1[18]=1; + } +// ========================== Large switch Set 1 continues + if (ss1[18]==1) { + ss1delay=millis()+(long(Dcc.getCV(98)*MasterTimeConstant)); // Wait1 + ss1[18]=0; ss1[19]=1; + } + if ((ss1[19]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(100)); + exec_switch_function(Dcc.getCV(99),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss1delay=millis()+(long(Dcc.getCV(101)*MasterTimeConstant)); // Wait2 + ss1[19]=0; ss1[20]=1; + } + if ((ss1[20]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(103)); + exec_switch_function(Dcc.getCV(102),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss1delay=millis()+(long(Dcc.getCV(104)*MasterTimeConstant)); // Wait3 + ss1[20]=0; ss1[21]=1; + } + if ((ss1[21]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(106)); + exec_switch_function(Dcc.getCV(105),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss1delay=millis()+(long(Dcc.getCV(107)*MasterTimeConstant)); // Wait4 + ss1[21]=0; ss1[22]=1; + } + if ((ss1[22]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(109)); + exec_switch_function(Dcc.getCV(108),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss1delay=millis()+(long(Dcc.getCV(110)*MasterTimeConstant)); // Wait5 + ss1[22]=0; ss1[23]=1; + } + if ((ss1[23]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(112)); + exec_switch_function(Dcc.getCV(111),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss1[23]=0; ss1[24]=1; + } +// ========================== Large switch Set 1 continues + if (ss1[24]==1) { + ss1delay=millis()+(long(Dcc.getCV(114)*MasterTimeConstant)); // Wait1 + ss1[24]=0; ss1[25]=1; + } + if ((ss1[25]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(116)); + exec_switch_function(Dcc.getCV(115),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss1delay=millis()+(long(Dcc.getCV(117)*MasterTimeConstant)); // Wait2 + ss1[25]=0; ss1[26]=1; + } + if ((ss1[26]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(119)); + exec_switch_function(Dcc.getCV(118),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss1delay=millis()+(long(Dcc.getCV(120)*MasterTimeConstant)); // Wait3 + ss1[26]=0; ss1[27]=1; + } + if ((ss1[27]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(122)); + exec_switch_function(Dcc.getCV(121),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss1delay=millis()+(long(Dcc.getCV(123)*MasterTimeConstant)); // Wait4 + ss1[27]=0; ss1[28]=1; + } + if ((ss1[28]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(125)); + exec_switch_function(Dcc.getCV(124),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss1delay=millis()+(long(Dcc.getCV(126)*MasterTimeConstant)); // Wait5 + ss1[28]=0; ss1[29]=1; + } + if ((ss1[29]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(128)); + exec_switch_function(Dcc.getCV(127),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss1[29]=0; run_switch_set[1]=false; + } + +// ========================== Large switch Set 2 Start Run + if (ss2[0]==1) { + ss2delay=millis()+(long(Dcc.getCV(130)*MasterTimeConstant)); // Wait1 + ss2[0]=0; ss2[1]=1; + } + if ((ss2[1]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(132)); + exec_switch_function(Dcc.getCV(131),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss2delay=millis()+(long(Dcc.getCV(133)*MasterTimeConstant)); // Wait2 + ss2[1]=0; ss2[2]=1; + } + if ((ss2[2]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(135)); + exec_switch_function(Dcc.getCV(134),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss2delay=millis()+(long(Dcc.getCV(136)*MasterTimeConstant)); // Wait3 + ss2[2]=0; ss2[3]=1; + } + if ((ss2[3]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(138)); + exec_switch_function(Dcc.getCV(137),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss2delay=millis()+(long(Dcc.getCV(139)*MasterTimeConstant)); // Wait4 + ss2[3]=0; ss2[4]=1; + } + if ((ss2[4]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(141)); + exec_switch_function(Dcc.getCV(140),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss2delay=millis()+(long(Dcc.getCV(142)*MasterTimeConstant)); // Wait5 + ss2[4]=0; ss2[5]=1; + } + if ((ss2[5]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(144)); + exec_switch_function(Dcc.getCV(143),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss2[5]=0; ss2[6]=1; + } + +// ========================== switch Set 7 Start Run + if (ss2[6]==1) { + ss2delay=millis()+(long(Dcc.getCV(146)*MasterTimeConstant)); // Wait1 + ss2[6]=0; ss2[7]=1; + } + if ((ss2[7]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(148)); + exec_switch_function(Dcc.getCV(147),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss2delay=millis()+(long(Dcc.getCV(149)*MasterTimeConstant)); // Wait2 + ss2[7]=0; ss2[8]=1; + } + if ((ss2[8]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(151)); + exec_switch_function(Dcc.getCV(150),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss2delay=millis()+(long(Dcc.getCV(152)*MasterTimeConstant)); // Wait3 + ss2[8]=0; ss2[9]=1; + } + if ((ss2[9]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(154)); + exec_switch_function(Dcc.getCV(153),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss2delay=millis()+(long(Dcc.getCV(155)*MasterTimeConstant)); // Wait4 + ss2[9]=0; ss2[10]=1; + } + if ((ss2[10]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(157)); + exec_switch_function(Dcc.getCV(156),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss2delay=millis()+(long(Dcc.getCV(158)*MasterTimeConstant)); // Wait5 + ss2[10]=0; ss2[11]=1; + } + if ((ss2[11]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(160)); + exec_switch_function(Dcc.getCV(159),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss2[11]=0; ss2[12]=1; + } +// ========================== switch Set 8 Start Run + if (ss2[12]==1) { + ss2delay=millis()+(long(Dcc.getCV(162)*MasterTimeConstant)); // Wait1 + ss2[12]=0; ss2[13]=1; + } + if ((ss2[13]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(164)); + exec_switch_function(Dcc.getCV(163),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss2delay=millis()+(long(Dcc.getCV(165)*MasterTimeConstant)); // Wait2 + ss2[13]=0; ss2[14]=1; + } + if ((ss2[14]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(167)); + exec_switch_function(Dcc.getCV(166),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss2delay=millis()+(long(Dcc.getCV(168)*MasterTimeConstant)); // Wait3 + ss2[14]=0; ss2[15]=1; + } + if ((ss2[15]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(170)); + exec_switch_function(Dcc.getCV(169),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss2delay=millis()+(long(Dcc.getCV(171)*MasterTimeConstant)); // Wait4 + ss2[15]=0; ss2[16]=1; + } + if ((ss2[16]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(173)); + exec_switch_function(Dcc.getCV(172),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss2delay=millis()+(long(Dcc.getCV(174)*MasterTimeConstant)); // Wait5 + ss2[16]=0; ss2[17]=1; + } + if ((ss2[17]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(176)); + exec_switch_function(Dcc.getCV(175),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss2[17]=0; ss2[18]=1; + } +// ========================== switch Set 9 Start Run + if (ss2[18]==1) { + ss2delay=millis()+(long(Dcc.getCV(178)*MasterTimeConstant)); // Wait1 + ss2[18]=0; ss2[19]=1; + } + if ((ss2[19]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(180)); + exec_switch_function(Dcc.getCV(179),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss2delay=millis()+(long(Dcc.getCV(181)*MasterTimeConstant)); // Wait2 + ss2[19]=0; ss2[20]=1; + } + if ((ss2[20]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(183)); + exec_switch_function(Dcc.getCV(182),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss2delay=millis()+(long(Dcc.getCV(184)*MasterTimeConstant)); // Wait3 + ss2[20]=0; ss2[21]=1; + } + if ((ss2[21]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(186)); + exec_switch_function(Dcc.getCV(185),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss2delay=millis()+(long(Dcc.getCV(187)*MasterTimeConstant)); // Wait4 + ss2[21]=0; ss2[22]=1; + } + if ((ss2[22]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(189)); + exec_switch_function(Dcc.getCV(188),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss2delay=millis()+(long(Dcc.getCV(190)*MasterTimeConstant)); // Wait5 + ss2[22]=0; ss2[23]=1; + } + if ((ss2[23]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(192)); + exec_switch_function(Dcc.getCV(191),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss2[23]=0; ss2[24]=1; + } +// ========================== switch Set 10 Start Run + if (ss2[24]==1) { + ss2delay=millis()+(long(Dcc.getCV(194)*MasterTimeConstant)); // Wait1 + ss2[24]=0; ss2[25]=1; + } + if ((ss2[25]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(196)); + exec_switch_function(Dcc.getCV(195),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss2delay=millis()+(long(Dcc.getCV(197)*MasterTimeConstant)); // Wait2 + ss2[25]=0; ss2[26]=1; + } + if ((ss2[26]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(199)); + exec_switch_function(Dcc.getCV(198),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss2delay=millis()+(long(Dcc.getCV(200)*MasterTimeConstant)); // Wait3 + ss2[26]=0; ss2[27]=1; + } + if ((ss2[27]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(202)); + exec_switch_function(Dcc.getCV(201),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss2delay=millis()+(long(Dcc.getCV(203)*MasterTimeConstant)); // Wait4 + ss2[27]=0; ss2[28]=1; + } + if ((ss2[28]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(205)); + exec_switch_function(Dcc.getCV(204),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss2delay=millis()+(long(Dcc.getCV(206)*MasterTimeConstant)); // Wait5 + ss2[28]=0; ss2[29]=1; + } + if ((ss2[29]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(208)); + exec_switch_function(Dcc.getCV(207),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss2[29]=0; run_switch_set[2]=false; + } +} // end loop() + +void exec_switch_function (byte switch_function, byte fpin,byte fbit) { + byte arg; + if (MasterDecoderDisable == 1) return; + + arg = fpin|(fbit<<7); // 8 bits of argument passed + + // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next + switch ( switch_function ) { // find the switch function to execute + case 0: // 0 == No function + default: + break; + case 1: // + digitalWrite ( fpin,fbit ); // Simple pin switch on/off + break; + case 2: // + if (fbit!=0) digitalWrite ( fpin, random ( 0,2) ); // Random pin switch on/off + else digitalWrite ( fpin, 0 ); // Force the bit OFF + break; + case 3: // + if (fbit!=0) digitalWrite ( fpin, Weighted_ON() ); // Weighted Random pin switch on/off + else digitalWrite ( fpin, 0 ); // Force the bit OFF + break; + case 4: // +#ifdef SOUND_PLAYER15 + //setVolumeOnChannel (default_volume * fbit); // set volume level + playTrackOnChannel(fpin); // play sound track fpin 1-127 +#endif + break; + case 5: // +#ifdef USE_SERVO14 + set_servo(arg); // Position Servo +#endif + break; + case 6: // + digitalWrite ( fpin,fbit ); // Dual pin on/off alternate blink + digitalWrite ( fpin+1,(~fbit)&0x01 ); // Dual pin on/off alternate blink + break; + case 7: // Start up another switch set + { + switch ( fpin ) { // Start another Switching set based on the fpin argument + case 0: // + default: + break; + case 1: // Start Switch Set 1 + ss1[0] = 1; run_switch_set[fpin]=true; + break; + case 2: // Start Switch Set 2 + ss2[0] = 1; run_switch_set[fpin]=true; + break; + } + } + break; + case 8: // Start Switching set if not already started + { + switch ( fpin ) { // Start another Switching set based on the fpin argument + case 0: // + default: + break; + case 1: // Start Switch Set 1 + if( run_switch_set[fpin]==false) {ss1[0] = 1; run_switch_set[fpin]=true;} + break; + case 2: // Start Switch Set 2 + if( run_switch_set[fpin]==false) {ss2[0] = 1; run_switch_set[fpin]=true;} + break; + } + } + break; + } + SoftwareServo::refresh(); +} // end exec_switch_function() + +boolean Weighted_ON() { + if (random (0, 100 ) > 40) return true; //This will reyrn ON/true 60% of the time + return false; +} // end Weighted_ON() + +#ifdef USE_SERVO14 +void set_servo (byte position) { + if (servo_pos.current_position == position) { + servo_pos.delta = 0; + servo_pos.target_position = position; + return; + } + if (servo_pos.current_position < position) servo_pos.delta = 1+servo_unit_faster; + else servo_pos.delta = -1-servo_unit_faster; + servo_pos.target_position = position; +} // end set_servo() + +void update_servos() { + servo_slow_counter = 1; + if (servo_pos.delta != 0 ) { + servo_pos.current_position=servo_pos.current_position+servo_pos.delta; + if ((servo_pos.delta > 0)&&(servo_pos.current_position > servo_pos.target_position)) + { + servo_pos.current_position = servo_pos.target_position; + servo_pos.delta = 0; + } + if ((servo_pos.delta < 0)&&(servo_pos.current_position < servo_pos.target_position)) + { + servo_pos.current_position = servo_pos.target_position; + servo_pos.delta = 0; + } + if (servo_pos.current_position == servo_pos.target_position) servo_pos.delta = 0; + } + sservo.write ( servo_pos.current_position ); +} // end update_servos() +#endif + +void playTrackOnChannel ( byte dtrack) { +#ifdef SOUND_PLAYER15 + if (dtrack == 0) return; + if (dtrack!=127) {Player1.play(dtrack); } //delay(audiocmddelay); } + else {Player1.play(random(First_Track,Last_Track+1)); } //delay(audiocmddelay); } +#endif +} // end playTrackOnChannel() + +void setVolumeOnChannel ( byte dvolume) { +#ifdef SOUND_PLAYER15 + if(dvolume>30) return; // Don't change the volume if out of range + Player1.volume(dvolume); + delay(audiocmddelay); +#endif +} // end setVolumeOnChannel() + +void notifyCVChange( uint16_t CV, uint8_t Value) { +#ifdef DEBUG + //Serial.print("CV= "); + //Serial.println(CV, DEC) ; + //Serial.print("Value= "); + //Serial.println(Value, DEC) ; +#endif + if ( CV==49 ) setVolumeOnChannel (Value); +} + +void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { +#ifdef DEBUG + //Serial.print("Addr= "); + //Serial.println(Addr, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch(FuncGrp) + { + case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1 + exec_function( 0, FunctionPin0, (FuncState & FN_BIT_00)>>4 ); + exec_function( 1, FunctionPin1, (FuncState & FN_BIT_01)); + exec_function( 2, FunctionPin2, (FuncState & FN_BIT_02)>>1); + exec_function( 3, FunctionPin3, (FuncState & FN_BIT_03)>>2 ); + exec_function( 4, FunctionPin4, (FuncState & FN_BIT_04)>>3 ); + break; + case FN_5_8: //Function Group 1 S FFFF == 1 F8 F7 F6 F5 & == 0 F12 F11 F10 F9 F8 + exec_function( 5, FunctionPin5, (FuncState & FN_BIT_05)); + exec_function( 6, FunctionPin6, (FuncState & FN_BIT_06)>>1 ); + exec_function( 7, FunctionPin7, (FuncState & FN_BIT_07)>>2 ); + exec_function( 8, FunctionPin8, (FuncState & FN_BIT_08)>>3 ); + break; + + case FN_9_12: + exec_function( 9, FunctionPin9, (FuncState & FN_BIT_09)); + exec_function( 10, FunctionPin10, (FuncState & FN_BIT_10)>>1 ); + exec_function( 11, FunctionPin11, (FuncState & FN_BIT_11)>>2 ); + exec_function( 12, FunctionPin12, (FuncState & FN_BIT_12)>>3 ); + break; + case FN_13_20: //Function Group 2 FuncState == F20-F13 Function Control + exec_function( 13, FunctionPin13, (FuncState & FN_BIT_13)); + exec_function( 14, FunctionPin14, (FuncState & FN_BIT_14)>>1 ); + //exec_function( 15, FunctionPin15, (FuncState & FN_BIT_15)>>2 ); + //exec_function( 16, FunctionPin16, (FuncState & FN_BIT_16)>>3 ); + break; + + case FN_21_28: + break; + } +} // end notifyDccFunc +void exec_function (int function, int pin, int FuncState) { +#ifdef DEBUG + //Serial.print("ex function= "); + //Serial.println(function, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch ( Dcc.getCV( 30+function) ) { // Config + case 0: // Master Disable + Function0_value = byte(FuncState); + break; + case 1: // run switch set [ function ] + case 2: // run switch set [ function ] + case 3: // run switch set [ function ] + case 4: // run switch set [ function ] + case 5: // run switch set [ function ] + case 6: // run switch set [ function ] + case 7: // run switch set [ function ] + case 8: // run switch set [ function ] + case 9: // run switch set [ function ] + case 10: // run switch set [ function ] + function_value[function] = byte(FuncState); + break; + default: + break;; + } +} // end exec_function + +/* DFPlayer Commands +//----Set volume---- + myDFPlayer.volume(10); //Set volume value (0~30). + myDFPlayer.volumeUp(); //Volume Up + myDFPlayer.volumeDown(); //Volume Down + //----Set different EQ---- + myDFPlayer.EQ(DFPLAYER_EQ_NORMAL); +// myDFPlayer.EQ(DFPLAYER_EQ_POP); +// myDFPlayer.EQ(DFPLAYER_EQ_ROCK); +// myDFPlayer.EQ(DFPLAYER_EQ_JAZZ); +// myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC); +// myDFPlayer.EQ(DFPLAYER_EQ_BASS); + //----Set device we use SD as default---- +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_U_DISK); + myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_AUX); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_SLEEP); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_FLASH); + //----Mp3 control---- +// myDFPlayer.sleep(); //sleep +// myDFPlayer.reset(); //Reset the module +// myDFPlayer.enableDAC(); //Enable On-chip DAC +// myDFPlayer.disableDAC(); //Disable On-chip DAC +// myDFPlayer.outputSetting(true, 15); //output setting, enable the output and set the gain to 15 + //----Mp3 play---- + myDFPlayer.next(); //Play next mp3 + myDFPlayer.previous(); //Play previous mp3 + myDFPlayer.play(1); //Play the first mp3 + myDFPlayer.loop(1); //Loop the first mp3 + myDFPlayer.pause(); //pause the mp3 + myDFPlayer.start(); //start the mp3 from the pause + myDFPlayer.playFolder(15, 4); //play specific mp3 in SD:/15/004.mp3; Folder Name(1~99); File Name(1~255) + myDFPlayer.enableLoopAll(); //loop all mp3 files. + myDFPlayer.disableLoopAll(); //stop loop all mp3 files. + myDFPlayer.playMp3Folder(4); //play specific mp3 in SD:/MP3/0004.mp3; File Name(0~65535) + myDFPlayer.advertise(3); //advertise specific mp3 in SD:/ADVERT/0003.mp3; File Name(0~65535) + myDFPlayer.stopAdvertise(); //stop advertise + myDFPlayer.playLargeFolder(2, 999); //play specific mp3 in SD:/02/004.mp3; Folder Name(1~10); File Name(1~1000) + myDFPlayer.loopFolder(5); //loop all mp3 files in folder SD:/05. + myDFPlayer.randomAll(); //Random play all the mp3. + myDFPlayer.enableLoop(); //enable loop. + myDFPlayer.disableLoop(); //disable loop. +*/ diff --git a/examples/IDECDemo&Diags/IDEC2_5_LargeFunctionBellDemo6/IDEC2_5_LargeFunctionBellDemo6.ino b/examples/IDECDemo&Diags/IDEC2_5_LargeFunctionBellDemo6/IDEC2_5_LargeFunctionBellDemo6.ino new file mode 100644 index 0000000..423f545 --- /dev/null +++ b/examples/IDECDemo&Diags/IDEC2_5_LargeFunctionBellDemo6/IDEC2_5_LargeFunctionBellDemo6.ino @@ -0,0 +1,1149 @@ +// Interactive Decoder Random Switches IDEC2_5_LargeFunctionSetsDev.ino +// Version 1.09 Geoff Bunza 2020 +// Works with both short and long DCC Addesses +// This decoder will control Switch Sequences, servos, sounds and LEDs +// F0=Master Function OFF = Function ON DISABLES the decoder +/* F0 is configured as Master Decoder Disable Override ON==Disable Decoder + * Input Pin for Decoder Disable Pin 16/A2 Active LOW +// F1-F2 Eight Switch Sets 1-2 controlled by Input pins 3,4 respectively + * All Switch Sets are defined by groups of 80 CVs + - Either a DCC Function 1-2 on OR an Input Pin (3,4,) Switched Low enables a decoder function (ON) + - BOTH the respective DCC Decoder Function 1-2 must be Off AND its respective Input Pin (3,4) + MUST be High for a decoder function to be considered disabled + - A decoder function LEFT ENABLED will repreat the respecpective action as long as it is enabled + * Switch Set CV's are 25 groups of 3 CVs each: + CV1 - A delay (0-255) which will be multiplied by the + MasterTimeConstant setting time increments from milliseconds to minutes + 0 = No Delay + CV2 - A Mode or Command byte Describing what will be executed in this Switch Step, including: + 0 = No Operation / Null /Skip + 1 = Simple pin switch on/off + 2= Random pin switch on/off + 3 = Weighted Random pin switch on/off default is 60% ON time but can be set to anything 1-99% + 4 = Play sound track using fpin value for the track 1-126, 0 = Skip Play, 127 = Select Random Track + from First_Track to Last_Track inclusive; + MSB=0->No Volume Change MSB=1 -> Set Volume to default_volume + 5 = Position Servo to 0-180 full speed of travel + 6 = Dual pin on/off used for alternate blink fpin and fpin+1 (MSB set value for fpin state) + 7 = Start another Switching set based on the fpin argument (Used to chain Switch Sets) + 8 = Start another Switching set based on the fpin argument ONLY if NOT already started + CV3 - An argument representing the Pin number affected in the lower 7 bits and the High bit (0x80 or 128) a value + or a general parameter like a servo position, a Sound track, or a sound set number to jump to + * Switch sets include CVs: 50-129 and 130=209 + * MAX one of 3 Configurations per pin function: + * Config 0=DISABLE On/Off,1-2=Switch Control 1-2 + +PRO MINI PIN ASSIGNMENT: +2 - DCC Input +3 - Input Pin Switch 1 +4 - Input Pin Switch 2 +5 - Switch 9 +6 - Switch 10 +7 - Switch 11 +8 - Switch 12 +9 - Switch 13 +10 - Switch 14 +11 - Switch 1 +12 - Switch 2 +13 - Switch 3 +14 A0 - Switch 4 or default_servo_pin +15 A1 - Switch 5 or default sound player pin (TX) connected to DFPlayer1 (RX) Pin 2 via 1K Ohm 1/4W Resistor +16 A2 - Input Pin for MasterDecoderDisable Active LOW +17 A3 - Switch 6 +18 A4 - Switch 7 +19 A5 - Switch 8 +*/ +// ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP +// ******** AFTER THE INITIAL DECODER LOAD REMOVE THE "//" IN THE FOOLOWING LINE!! +//#define DECODER_LOADED + +// ******** REMOVE THE "//" IN THE FOLOWING LINE TO enable sound DFPlayer on Pin 15 +#define SOUND_PLAYER15 + +// ******** REMOVE THE "//" IN THE FOLOWING LINE TO enable SERVO USE +#define USE_SERVO14 + +// ******** REMOVE THE "//" IN THE FOLOWING LINE TO SEND DEBUGGING +// ******** INFO TO THE SERIAL MONITOR *****NOTE Turning DEBUG ON changes ALL Timing!! +//#define DEBUG + + +#include +#include + +#ifdef USE_SERVO14 +SoftwareServo sservo; +#endif +byte default_servo_pin = 14; +byte servo_start_position = 90; +const byte servo_master_slowdown_CV = 48; //servo loop counter limit CV +int servo_slow_counter = 1; //servo loop counter to slowdown servo transit +byte servo_unit_faster = 0; + +#ifdef SOUND_PLAYER15 +#include +#include +SoftwareSerial DFSerial1(22,15); // PRO MINI RX, PRO MINI TX serial to DFPlayer +DFRobotDFPlayerMini Player1; +#endif +#define default_volume 20 // sets default volume 0-30, 0 == OFF, >30 == Skip Track +#define First_Track 1 // Play Random Tracks First_Track#=Start_Track >=1 +#define Last_Track 12 // Play Random Tracks Last_Track= Last Playable Track in Range <= Last Numbered Track +const byte starting_volume_CV = 49; // If no volume is set use this CV at the start +const int audiocmddelay = 40; + +#define This_Decoder_Address 24 +uint8_t CV_DECODER_MASTER_RESET = 252; + +//Uncomment ONLY ONE of the following: +//#define MasterTimeConstant 1L // milliseconds Timing +#define MasterTimeConstant 10L // 10's of milliseconds Timing +//#define MasterTimeConstant 100L // Tenths of a second Timing +//#define MasterTimeConstant 1000L // Seconds Timing +//#define MasterTimeConstant 10000L // 10's of Seconds Timing +//#define MasterTimeConstant 60000L // Minutes Timing +//#define MasterTimeConstant 3600000L // Hours Timing + +int del_tim = 4000; +uint16_t ttemp, i; +byte otemp; + +byte ss1[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +unsigned long ss1delay=0; +byte ss2[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +unsigned long ss2delay=0; +bool run_switch_set [ ] = {false,false,false}; +byte switchset_channel[ ]={0,0,0}; + +struct SERVO_TRACKING +{ + byte current_position; + byte target_position; + char delta; +}; +SERVO_TRACKING servo_pos; + +const int MasterDecoderDisablePin = 16; // D16/A0 Master Decoder Disable Input Pin Active LOW + +const int numINpins = 3; // Number of INput pins to initialize +byte inputpins [] = {3,4,16}; //These are all the Input Pins +const int numfpins = 14; // Number of Output pins to initialize +const int num_active_functions = 3; // Number of Functions stating with F0 +byte fpins [] = {5,6,7,8,9,10,11,12,13,14,15,17,18,19}; //These are all the Output Pins (first 15 is placeholder) +const int FunctionPin0 = 20; // D14/A0 DFPlayer Transmit (TX) Pin 3 +const int FunctionPin1 = 20; // A2 LED Place holders ONLY +const int FunctionPin2 = 20; // A3 LED Place holders ONLY +const int FunctionPin3 = 20; // A4 LED Place holders ONLY +const int FunctionPin4 = 20; // A5 LED Place holders ONLY +const int FunctionPin5 = 20; // A6 LED Place holders ONLY +const int FunctionPin6 = 20; // A7 Place holders ONLY +const int FunctionPin7 = 20; // A8 Place holders ONLY +const int FunctionPin8 = 20; // A9 Place holders ONLY +#define switch1 11 +#define switch2 12 +#define switch3 13 +#define switch4 14 +#define switch5 15 +#define switch6 17 +#define switch7 18 +#define switch8 19 +#define switch9 5 +#define switch10 6 +#define switch11 7 +#define switch12 8 +#define switch13 9 +#define switch14 10 +#define on 0x80 +#define off 0 +const int FunctionPin9 = 20; // Place holders ONLY +const int FunctionPin10 = 20; // Place holders ONLY +const int FunctionPin11 = 20; // F13 LED +const int FunctionPin12 = 20; // F12 LED +const int FunctionPin13 = 20; // F13 LED +const int FunctionPin14 = 20; // F14 LED +const int FunctionPin15 = 20; // Place holders ONLY +int MasterDecoderDisable = 0; +int Function0_value = 0; +byte function_value [ ] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +uint8_t cv_value; + +NmraDcc Dcc ; +DCC_MSG Packet ; +int t; // temp +struct QUEUE +{ + int inuse; + int current_position; + int increment; + int stop_value; + int start_value; +}; +QUEUE *ftn_queue = new QUEUE[17]; + +struct CVPair +{ + uint16_t CV; + uint8_t Value; +}; +CVPair FactoryDefaultCVs [] = +{ + {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address&0x7F }, + + // These two CVs define the Long DCC Address + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, ((This_Decoder_Address>>8)&0x7F)+192 }, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address&0xFF }, + + // ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS +// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps + {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps +// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps + {CV_DECODER_MASTER_RESET, 0}, + + {30, 0}, //F0 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + + {31, 1}, //F1 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {32, 2}, //F2 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {33, 3}, //F3 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {34, 4}, //F4 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {35, 5}, //F5 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {36, 6}, //F6 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {37, 7}, //F7 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {38, 8}, //F8 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {39, 9}, //F9 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + {40, 10}, //F10 Config 0=DISABLE On/Off,1-8=Switch Control 1-10,11=LED On/Off + + {41, 11}, + {42, 11}, + {43, 11}, + {44, 11}, + {45, 27}, //F15 not used + + {48, 120}, // servo_master_slowdown_CV Higher number slows servo movment + {49, 29}, // Starting sound volume (starting_volume_CV) +#define strack 9 +#define soundM 4 +#define servoM 5 +#define delayM 86 +#define servostartM 140 +#define servoendM 42 + {50, 0}, // Wait1 0-254 0.1 Seconds // switch SET 1-1 + {51, servoM}, // servo Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {52, servostartM}, // servo position + {53, delayM}, // Wait2 0-254 0.1 Seconds + {54, soundM}, // sound Mode + {55, strack}, // sound track + {56, delayM}, // Wait3 0-254 0.1 Seconds + {57, servoM}, // servo Mode + {58, servoendM}, // servo position + {59, delayM}, // Wait4 0-254 0.1 Seconds + {60, soundM}, // sound Mode + {61, strack}, // sound track + {62, delayM}, // Wait5 0-254 0.1 Seconds + {63, servoM}, // servo Mode + {64, servostartM}, // servo position + {65, 0}, // Not Used + + {66, delayM}, // Wait1 0-254 0.1 Seconds // switch SET 1-2 + {67, soundM}, // sound Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {68, strack}, // sound track + {69, delayM}, // Wait2 0-254 0.1 Seconds + {70, servoM}, // servo Mode + {71, servoendM}, // servo position + {72, delayM}, // Wait3 0-254 0.1 Seconds + {73, soundM}, // sound Mode + {74, strack}, // sound track + {75, delayM}, // Wait4 0-254 0.1 Seconds + {76, servoM}, // servo Mode + {77, servostartM}, // servo position + {78, delayM}, // Wait5 0-254 0.1 Seconds + {79, soundM}, // sound Mode + {80, strack}, // sound track + {81, 0}, // Not Used + + {82, delayM}, // Wait1 0-254 0.1 Seconds // switch SET 1-3 + {83, servoM}, // servo Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {84, servoendM}, // servo + {85, delayM}, // Wait2 0-254 0.1 Seconds + {86, soundM}, // sound Mode + {87, strack}, // sound + {88, delayM}, // Wait3 0-254 0.1 Seconds + {89, servoM}, // servo Mode + {90, servostartM}, // servo + {91, delayM}, // Wait4 0-254 0.1 Seconds + {92, soundM}, // sound Mode + {93, strack}, // sound + {94, delayM}, // Wait5 0-254 0.1 Seconds + {95, servoM}, // servo Mode + {96, servoendM}, // servo + {97, 0}, // Not Used + + {98, delayM}, // Wait1 0-254 0.1 Seconds // switch SET 1-4 + {99, soundM}, // sound Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {100, strack}, // sound + {101, delayM}, // Wait2 0-254 0.1 Seconds + {102, servoM}, // servo Mode + {103, servostartM}, // servo + {104, delayM}, // Wait3 0-254 0.1 Seconds + {105, soundM}, // sound Mode + {106, strack}, // sound + {107, delayM}, // Wait4 0-254 0.1 Seconds + {108, servoM}, // servo Mode + {109, servoendM}, // Switch Pin4 + {110, delayM}, // Wait5 0-254 0.1 Seconds + {111, soundM}, // sound Mode + {112, strack}, // sound + {113, 0}, // Not Used + + {114, delayM}, // Wait1 0-254 0.1 Seconds // switch SET 1-5 + {115, servoM}, // servo Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {116, servostartM}, // servo + {117, delayM}, // Wait2 0-254 0.1 Seconds + {118, soundM}, // sound Mode + {119, strack}, // sound + {120, delayM}, // Wait3 0-254 0.1 Seconds + {121, servoM}, // servo Mode + {122, servoendM}, // servo + {123, delayM}, // Wait4 0-254 0.1 Seconds + {124, soundM}, // sound Mode + {125, strack}, // sound + {126, delayM}, // Wait5 0-254 0.1 Seconds + {127, servoM}, // servo Mode + {128, 90}, // servo + {129, 0}, // Not Used + + {130, 0}, // Wait1 0-254 0.1 Seconds // switch SET 2-1 + {131, servoM}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {132, servostartM}, // Switch Pin1 + {133, delayM}, // Wait2 0-254 0.1 Seconds + {134, soundM}, // Switch Mode + {135, 0}, // Switch Pin2 + {136, delayM}, // Wait3 0-254 0.1 Seconds + {137, servoM}, // Switch Mode + {138, servoendM}, // Switch Pin3 + {139, delayM}, // Wait4 0-254 0.1 Seconds + {140, soundM}, // Switch Mode + {141, 0}, // Switch Pin4 + {142, delayM}, // Wait5 0-254 0.1 Seconds + {143, servoM}, // Switch Mode + {144, servostartM}, // Switch Pin5 + {145, 0}, // Not Used + + {146, delayM}, // Wait1 0-254 0.1 Seconds // switch SET 2-2 + {147, soundM}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {148, 0}, // Switch Pin1 + {149, delayM}, // Wait2 0-254 0.1 Seconds + {150, servoM}, // Switch Mode + {151, servoendM}, // Switch Pin2 + {152, delayM}, // Wait3 0-254 0.1 Seconds + {153, soundM}, // Switch Mode + {154, 0}, // Switch Pin3 + {155, delayM}, // Wait4 0-254 0.1 Seconds + {156, servoM}, // Switch Mode + {157, servostartM}, // Switch Pin4 + {158, delayM}, // Wait5 0-254 0.1 Seconds + {159, soundM}, // Switch Mode + {160, 0}, // Switch Pin5 + {161, 0}, // Not Used + + {162, delayM}, // Wait1 0-254 0.1 Seconds // switch SET 2-3 + {163, servoM}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {164, servoendM}, // Switch Pin1 + {165, delayM}, // Wait2 0-254 0.1 Seconds + {166, soundM}, // Switch Mode + {167, 0}, // Switch Pin2 + {168, delayM}, // Wait3 0-254 0.1 Seconds + {169, servoM}, // Switch Mode + {170, servostartM}, // Switch Pin3 + {171, delayM}, // Wait4 0-254 0.1 Seconds + {172, soundM}, // Switch Mode + {173, 0}, // Switch Pin4 + {174, delayM}, // Wait5 0-254 0.1 Seconds + {175, servoM}, // Switch Mode + {176, servoendM}, // Switch Pin5 + {177, 0}, // Not Used + + {178, delayM}, // Wait1 0-254 0.1 Seconds // switch SET 2-4 + {179, soundM}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {180, 0}, // Switch Pin1 + {181, delayM}, // Wait2 0-254 0.1 Seconds + {182, servoM}, // Switch Mode + {183, servostartM}, // Switch Pin2 + {184, delayM}, // Wait3 0-254 0.1 Seconds + {185, soundM}, // Switch Mode + {186, 0}, // Switch Pin3 + {187, delayM}, // Wait4 0-254 0.1 Seconds + {188, servoM}, // Switch Mode + {189, servoendM}, // Switch Pin4 + {190, delayM}, // Wait5 0-254 0.1 Seconds + {191, soundM}, // Switch Mode + {192, 0}, // Switch Pin5 + {193, 0}, // Not Used + + {194, delayM}, // Wait1 0-254 0.1 Seconds // switch SET 2-5 + {195, servoM}, // Switch Mode // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next SS,8=Next SS Conditional + {196, servostartM}, // Switch Pin1 + {197, delayM}, // Wait2 0-254 0.1 Seconds + {198, soundM}, // Switch Mode + {199, 0}, // Switch Pin2 + {200, delayM}, // Wait3 0-254 0.1 Seconds + {201, servoM}, // Switch Mode + {202, servoendM}, // Switch Pin3 + {203, delayM}, // Wait4 0-254 0.1 Seconds + {204, soundM}, // Switch Mode + {205, 0}, // Switch Pin4 + {206, delayM}, // Wait5 0-254 0.1 Seconds + {207, servoM}, // Switch Mode + {208, 90}, // Switch Pin5 + {209, 0}, // Not Used + + //252,252 CV_DECODER_MASTER_RESET + + {253, 0}, // Extra +}; + +uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +void notifyCVResetFactoryDefault() +{ + // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset + // to flag to the loop() function that a reset to Factory Defaults needs to be done + FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +}; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS + +void setup() //****************************************************** +{ + pinMode (MasterDecoderDisablePin,INPUT_PULLUP); //Master Decoder Disable Input Active LOW + // initialize the digital pins as outputs + for (int i=0; i < numfpins; i++) { + pinMode(fpins[i], OUTPUT); + digitalWrite(fpins[i], 0); // All OUPUT pins initialized LOW + } + // initialize the digital pins as inputs + for (int i=0; i < numINpins; i++) { + pinMode(inputpins[i], INPUT_PULLUP); + } +#ifdef DEBUG + Serial.begin(115200); +#endif + +#ifdef SOUND_PLAYER15 + DFSerial1.begin (9600); + delay(40); + Player1.begin (DFSerial1); + delay(80); + setVolumeOnChannel (Dcc.getCV(starting_volume_CV)); +#endif + +#ifdef USE_SERVO14 + sservo.attach(default_servo_pin); // Start Servo on default_servo_pin //Position Servo + delay(50); + sservo.write(servo_start_position); // Set starting position + servo_pos.current_position = servo_start_position; + servo_pos.delta = 0; + servo_pos.target_position = servo_start_position; + delay(500); + SoftwareServo::refresh(); +#endif + + // Setup which External Interrupt, the Pin it's associated with that we're using + Dcc.pin(0, 2, 0); + // Call the main DCC Init function to enable the DCC Receiver + Dcc.init( MAN_ID_DIY, 61, FLAGS_MY_ADDRESS_ONLY, 0 ); + delay(800); +#if defined(DECODER_LOADED) + if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET ) +#endif + { + for (int j=0; j < FactoryDefaultCVIndex; j++ ) + Dcc.setCV( FactoryDefaultCVs[j].CV, FactoryDefaultCVs[j].Value); + } + // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; +#ifdef DEBUG + Serial.println("CV Dump:"); + for (i=30; i<41; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=30; i<41; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Large Switch Set 1"); + for (i=50; i<66; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=50; i<66; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=66; i<82; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=66; i<82; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=82; i<98; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=82; i<98; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=98; i<114; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=98; i<114; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=114; i<130; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=114; i<130; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Large Switch Set 2"); + for (i=130; i<146; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=130; i<146; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=146; i<162; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=146; i<162; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=162; i<178; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=162; i<178; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=178; i<194; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=178; i<194; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + for (i=194; i<210; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=194; i<210; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); +#endif +} +void loop() //*********************************************************************************** +{ + //MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation + Dcc.process(); +#ifdef USE_SERVO14 + SoftwareServo::refresh(); + if (servo_slow_counter > Dcc.getCV(servo_master_slowdown_CV) ) update_servos(); + else servo_slow_counter++; +#endif + + //delay(1); +// INPUT OVER RIDES + // Check Master Input Over ride + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + else MasterDecoderDisable = Function0_value & 1; + if (MasterDecoderDisable == 1) { + for (i=0; i < numfpins; i++) digitalWrite(fpins[i], 0); // All LEDs set LOW + } +// ******************************************************************************** + if (MasterDecoderDisable == 0) { + for (i=0; i < num_active_functions; i++) { + cv_value = Dcc.getCV(30+i) ; +#ifdef DEBUG + //Serial.print(" cv_value: "); + //Serial.println(cv_value, DEC) ; +#endif + switch ( cv_value ) { + case 0: // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + break; + case 1: // + if (((digitalRead(3)==LOW)||(function_value[cv_value]==1)) && !run_switch_set[cv_value]) { + ss1[0]=1; run_switch_set[cv_value]=true; + } + break; + case 2: // + if (((digitalRead(4)==LOW)||(function_value[cv_value]==1)) && !run_switch_set[cv_value]) { + ss2[0]=1; run_switch_set[cv_value]=true; + } + break; + default: // Extra + break; + } + } + } + // ========================== Large switch Set 1 Start Run + if (ss1[0]==1) { + ss1delay=millis()+(long(Dcc.getCV(50)*MasterTimeConstant)); // Wait1 + ss1[0]=0; ss1[1]=1; + } + if ((ss1[1]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(52)); + exec_switch_function(Dcc.getCV(51),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss1delay=millis()+(long(Dcc.getCV(53)*MasterTimeConstant)); // Wait2 + ss1[1]=0; ss1[2]=1; + } + if ((ss1[2]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(55)); + exec_switch_function (Dcc.getCV(54),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss1delay=millis()+(long(Dcc.getCV(56)*MasterTimeConstant)); // Wait3 + ss1[2]=0; ss1[3]=1; + } + if ((ss1[3]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(58)); + exec_switch_function(Dcc.getCV(57),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss1delay=millis()+(long(Dcc.getCV(59)*MasterTimeConstant)); // Wait4 + ss1[3]=0; ss1[4]=1; + } + if ((ss1[4]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(61)); + exec_switch_function(Dcc.getCV(60),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss1delay=millis()+(long(Dcc.getCV(62)*MasterTimeConstant)); // Wait5 + ss1[4]=0; ss1[5]=1; + } + if ((ss1[5]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(64)); + exec_switch_function(Dcc.getCV(63),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss1[5]=0; ss1[6]=1; + } +// ========================== Large switch Set 1 continues + if (ss1[6]==1) { + ss1delay=millis()+(long(Dcc.getCV(66)*MasterTimeConstant)); // Wait1 + ss1[6]=0; ss1[7]=1; + } + if ((ss1[7]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(68)); + exec_switch_function(Dcc.getCV(67),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss1delay=millis()+(long(Dcc.getCV(69)*MasterTimeConstant)); // Wait2 + ss1[7]=0; ss1[8]=1; + } + if ((ss1[8]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(71)); + exec_switch_function(Dcc.getCV(70),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss1delay=millis()+(long(Dcc.getCV(72)*MasterTimeConstant)); // Wait3 + ss1[8]=0; ss1[9]=1; + } + if ((ss1[9]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(74)); + exec_switch_function(Dcc.getCV(73),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss1delay=millis()+(long(Dcc.getCV(75)*MasterTimeConstant)); // Wait4 + ss1[9]=0; ss1[10]=1; + } + if ((ss1[10]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(77)); + exec_switch_function(Dcc.getCV(76),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss1delay=millis()+(long(Dcc.getCV(78)*MasterTimeConstant)); // Wait5 + ss1[10]=0; ss1[11]=1; + } + if ((ss1[11]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(80)); + exec_switch_function(Dcc.getCV(79),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss1[11]=0; ss1[12]=1; + } +// ========================== Large switch Set 1 continues + if (ss1[12]==1) { + ss1delay=millis()+(long(Dcc.getCV(82)*MasterTimeConstant)); // Wait1 + ss1[12]=0; ss1[13]=1; + } + if ((ss1[13]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(84)); + exec_switch_function(Dcc.getCV(83),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss1delay=millis()+(long(Dcc.getCV(85)*MasterTimeConstant)); // Wait2 + ss1[13]=0; ss1[14]=1; + } + if ((ss1[14]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(87)); + exec_switch_function(Dcc.getCV(86),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss1delay=millis()+(long(Dcc.getCV(88)*MasterTimeConstant)); // Wait3 + ss1[14]=0; ss1[15]=1; + } + if ((ss1[15]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(90)); + exec_switch_function(Dcc.getCV(89),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss1delay=millis()+(long(Dcc.getCV(91)*MasterTimeConstant)); // Wait4 + ss1[15]=0; ss1[16]=1; + } + if ((ss1[16]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(93)); + exec_switch_function(Dcc.getCV(92),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss1delay=millis()+(long(Dcc.getCV(94)*MasterTimeConstant)); // Wait5 + ss1[16]=0; ss1[17]=1; + } + if ((ss1[17]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(96)); + exec_switch_function(Dcc.getCV(95),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss1[17]=0; ss1[18]=1; + } +// ========================== Large switch Set 1 continues + if (ss1[18]==1) { + ss1delay=millis()+(long(Dcc.getCV(98)*MasterTimeConstant)); // Wait1 + ss1[18]=0; ss1[19]=1; + } + if ((ss1[19]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(100)); + exec_switch_function(Dcc.getCV(99),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss1delay=millis()+(long(Dcc.getCV(101)*MasterTimeConstant)); // Wait2 + ss1[19]=0; ss1[20]=1; + } + if ((ss1[20]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(103)); + exec_switch_function(Dcc.getCV(102),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss1delay=millis()+(long(Dcc.getCV(104)*MasterTimeConstant)); // Wait3 + ss1[20]=0; ss1[21]=1; + } + if ((ss1[21]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(106)); + exec_switch_function(Dcc.getCV(105),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss1delay=millis()+(long(Dcc.getCV(107)*MasterTimeConstant)); // Wait4 + ss1[21]=0; ss1[22]=1; + } + if ((ss1[22]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(109)); + exec_switch_function(Dcc.getCV(108),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss1delay=millis()+(long(Dcc.getCV(110)*MasterTimeConstant)); // Wait5 + ss1[22]=0; ss1[23]=1; + } + if ((ss1[23]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(112)); + exec_switch_function(Dcc.getCV(111),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss1[23]=0; ss1[24]=1; + } +// ========================== Large switch Set 1 continues + if (ss1[24]==1) { + ss1delay=millis()+(long(Dcc.getCV(114)*MasterTimeConstant)); // Wait1 + ss1[24]=0; ss1[25]=1; + } + if ((ss1[25]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(116)); + exec_switch_function(Dcc.getCV(115),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss1delay=millis()+(long(Dcc.getCV(117)*MasterTimeConstant)); // Wait2 + ss1[25]=0; ss1[26]=1; + } + if ((ss1[26]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(119)); + exec_switch_function(Dcc.getCV(118),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss1delay=millis()+(long(Dcc.getCV(120)*MasterTimeConstant)); // Wait3 + ss1[26]=0; ss1[27]=1; + } + if ((ss1[27]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(122)); + exec_switch_function(Dcc.getCV(121),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss1delay=millis()+(long(Dcc.getCV(123)*MasterTimeConstant)); // Wait4 + ss1[27]=0; ss1[28]=1; + } + if ((ss1[28]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(125)); + exec_switch_function(Dcc.getCV(124),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss1delay=millis()+(long(Dcc.getCV(126)*MasterTimeConstant)); // Wait5 + ss1[28]=0; ss1[29]=1; + } + if ((ss1[29]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(128)); + exec_switch_function(Dcc.getCV(127),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss1[29]=0; run_switch_set[1]=false; + } + +// ========================== Large switch Set 2 Start Run + if (ss2[0]==1) { + ss2delay=millis()+(long(Dcc.getCV(130)*MasterTimeConstant)); // Wait1 + ss2[0]=0; ss2[1]=1; + } + if ((ss2[1]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(132)); + exec_switch_function(Dcc.getCV(131),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss2delay=millis()+(long(Dcc.getCV(133)*MasterTimeConstant)); // Wait2 + ss2[1]=0; ss2[2]=1; + } + if ((ss2[2]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(135)); + exec_switch_function(Dcc.getCV(134),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss2delay=millis()+(long(Dcc.getCV(136)*MasterTimeConstant)); // Wait3 + ss2[2]=0; ss2[3]=1; + } + if ((ss2[3]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(138)); + exec_switch_function(Dcc.getCV(137),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss2delay=millis()+(long(Dcc.getCV(139)*MasterTimeConstant)); // Wait4 + ss2[3]=0; ss2[4]=1; + } + if ((ss2[4]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(141)); + exec_switch_function(Dcc.getCV(140),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss2delay=millis()+(long(Dcc.getCV(142)*MasterTimeConstant)); // Wait5 + ss2[4]=0; ss2[5]=1; + } + if ((ss2[5]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(144)); + exec_switch_function(Dcc.getCV(143),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss2[5]=0; ss2[6]=1; + } + +// ========================== switch Set 7 Start Run + if (ss2[6]==1) { + ss2delay=millis()+(long(Dcc.getCV(146)*MasterTimeConstant)); // Wait1 + ss2[6]=0; ss2[7]=1; + } + if ((ss2[7]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(148)); + exec_switch_function(Dcc.getCV(147),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss2delay=millis()+(long(Dcc.getCV(149)*MasterTimeConstant)); // Wait2 + ss2[7]=0; ss2[8]=1; + } + if ((ss2[8]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(151)); + exec_switch_function(Dcc.getCV(150),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss2delay=millis()+(long(Dcc.getCV(152)*MasterTimeConstant)); // Wait3 + ss2[8]=0; ss2[9]=1; + } + if ((ss2[9]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(154)); + exec_switch_function(Dcc.getCV(153),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss2delay=millis()+(long(Dcc.getCV(155)*MasterTimeConstant)); // Wait4 + ss2[9]=0; ss2[10]=1; + } + if ((ss2[10]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(157)); + exec_switch_function(Dcc.getCV(156),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss2delay=millis()+(long(Dcc.getCV(158)*MasterTimeConstant)); // Wait5 + ss2[10]=0; ss2[11]=1; + } + if ((ss2[11]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(160)); + exec_switch_function(Dcc.getCV(159),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss2[11]=0; ss2[12]=1; + } +// ========================== switch Set 8 Start Run + if (ss2[12]==1) { + ss2delay=millis()+(long(Dcc.getCV(162)*MasterTimeConstant)); // Wait1 + ss2[12]=0; ss2[13]=1; + } + if ((ss2[13]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(164)); + exec_switch_function(Dcc.getCV(163),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss2delay=millis()+(long(Dcc.getCV(165)*MasterTimeConstant)); // Wait2 + ss2[13]=0; ss2[14]=1; + } + if ((ss2[14]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(167)); + exec_switch_function(Dcc.getCV(166),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss2delay=millis()+(long(Dcc.getCV(168)*MasterTimeConstant)); // Wait3 + ss2[14]=0; ss2[15]=1; + } + if ((ss2[15]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(170)); + exec_switch_function(Dcc.getCV(169),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss2delay=millis()+(long(Dcc.getCV(171)*MasterTimeConstant)); // Wait4 + ss2[15]=0; ss2[16]=1; + } + if ((ss2[16]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(173)); + exec_switch_function(Dcc.getCV(172),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss2delay=millis()+(long(Dcc.getCV(174)*MasterTimeConstant)); // Wait5 + ss2[16]=0; ss2[17]=1; + } + if ((ss2[17]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(176)); + exec_switch_function(Dcc.getCV(175),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss2[17]=0; ss2[18]=1; + } +// ========================== switch Set 9 Start Run + if (ss2[18]==1) { + ss2delay=millis()+(long(Dcc.getCV(178)*MasterTimeConstant)); // Wait1 + ss2[18]=0; ss2[19]=1; + } + if ((ss2[19]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(180)); + exec_switch_function(Dcc.getCV(179),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss2delay=millis()+(long(Dcc.getCV(181)*MasterTimeConstant)); // Wait2 + ss2[19]=0; ss2[20]=1; + } + if ((ss2[20]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(183)); + exec_switch_function(Dcc.getCV(182),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss2delay=millis()+(long(Dcc.getCV(184)*MasterTimeConstant)); // Wait3 + ss2[20]=0; ss2[21]=1; + } + if ((ss2[21]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(186)); + exec_switch_function(Dcc.getCV(185),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss2delay=millis()+(long(Dcc.getCV(187)*MasterTimeConstant)); // Wait4 + ss2[21]=0; ss2[22]=1; + } + if ((ss2[22]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(189)); + exec_switch_function(Dcc.getCV(188),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss2delay=millis()+(long(Dcc.getCV(190)*MasterTimeConstant)); // Wait5 + ss2[22]=0; ss2[23]=1; + } + if ((ss2[23]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(192)); + exec_switch_function(Dcc.getCV(191),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss2[23]=0; ss2[24]=1; + } +// ========================== switch Set 10 Start Run + if (ss2[24]==1) { + ss2delay=millis()+(long(Dcc.getCV(194)*MasterTimeConstant)); // Wait1 + ss2[24]=0; ss2[25]=1; + } + if ((ss2[25]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(196)); + exec_switch_function(Dcc.getCV(195),ttemp&0x7f,ttemp>>7); // execute switch function 1 + ss2delay=millis()+(long(Dcc.getCV(197)*MasterTimeConstant)); // Wait2 + ss2[25]=0; ss2[26]=1; + } + if ((ss2[26]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(199)); + exec_switch_function(Dcc.getCV(198),ttemp&0x7f,ttemp>>7); // execute switch function 2 + ss2delay=millis()+(long(Dcc.getCV(200)*MasterTimeConstant)); // Wait3 + ss2[26]=0; ss2[27]=1; + } + if ((ss2[27]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(202)); + exec_switch_function(Dcc.getCV(201),ttemp&0x7f,ttemp>>7); // execute switch function 3 + ss2delay=millis()+(long(Dcc.getCV(203)*MasterTimeConstant)); // Wait4 + ss2[27]=0; ss2[28]=1; + } + if ((ss2[28]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(205)); + exec_switch_function(Dcc.getCV(204),ttemp&0x7f,ttemp>>7); // execute switch function 4 + ss2delay=millis()+(long(Dcc.getCV(206)*MasterTimeConstant)); // Wait5 + ss2[28]=0; ss2[29]=1; + } + if ((ss2[29]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(208)); + exec_switch_function(Dcc.getCV(207),ttemp&0x7f,ttemp>>7); // execute switch function 5 + ss2[29]=0; run_switch_set[2]=false; + } +} // end loop() + +void exec_switch_function (byte switch_function, byte fpin,byte fbit) { + byte arg; + if (MasterDecoderDisable == 1) return; + + arg = fpin|(fbit<<7); // 8 bits of argument passed + + // 0=NOP,1=0/1,2=RND,3=WRND,4=SND,5=SRVO,6=Dual Pin,7=Next + switch ( switch_function ) { // find the switch function to execute + case 0: // 0 == No function + default: + break; + case 1: // + digitalWrite ( fpin,fbit ); // Simple pin switch on/off + break; + case 2: // + if (fbit!=0) digitalWrite ( fpin, random ( 0,2) ); // Random pin switch on/off + else digitalWrite ( fpin, 0 ); // Force the bit OFF + break; + case 3: // + if (fbit!=0) digitalWrite ( fpin, Weighted_ON() ); // Weighted Random pin switch on/off + else digitalWrite ( fpin, 0 ); // Force the bit OFF + break; + case 4: // +#ifdef SOUND_PLAYER15 + //setVolumeOnChannel (default_volume * fbit); // set volume level + playTrackOnChannel(fpin); // play sound track fpin 1-127 +#endif + break; + case 5: // +#ifdef USE_SERVO14 + set_servo(arg); // Position Servo +#endif + break; + case 6: // + digitalWrite ( fpin,fbit ); // Dual pin on/off alternate blink + digitalWrite ( fpin+1,(~fbit)&0x01 ); // Dual pin on/off alternate blink + break; + case 7: // Start up another switch set + { + switch ( fpin ) { // Start another Switching set based on the fpin argument + case 0: // + default: + break; + case 1: // Start Switch Set 1 + ss1[0] = 1; run_switch_set[fpin]=true; + break; + case 2: // Start Switch Set 2 + ss2[0] = 1; run_switch_set[fpin]=true; + break; + } + } + break; + case 8: // Start Switching set if not already started + { + switch ( fpin ) { // Start another Switching set based on the fpin argument + case 0: // + default: + break; + case 1: // Start Switch Set 1 + if( run_switch_set[fpin]==false) {ss1[0] = 1; run_switch_set[fpin]=true;} + break; + case 2: // Start Switch Set 2 + if( run_switch_set[fpin]==false) {ss2[0] = 1; run_switch_set[fpin]=true;} + break; + } + } + break; + } + SoftwareServo::refresh(); +} // end exec_switch_function() + +boolean Weighted_ON() { + if (random (0, 100 ) > 40) return true; //This will reyrn ON/true 60% of the time + return false; +} // end Weighted_ON() + +#ifdef USE_SERVO14 +void set_servo (byte position) { + if (servo_pos.current_position == position) { + servo_pos.delta = 0; + servo_pos.target_position = position; + return; + } + if (servo_pos.current_position < position) servo_pos.delta = 1+servo_unit_faster; + else servo_pos.delta = -1-servo_unit_faster; + servo_pos.target_position = position; +} // end set_servo() + +void update_servos() { + servo_slow_counter = 1; + if (servo_pos.delta != 0 ) { + servo_pos.current_position=servo_pos.current_position+servo_pos.delta; + if ((servo_pos.delta > 0)&&(servo_pos.current_position > servo_pos.target_position)) + { + servo_pos.current_position = servo_pos.target_position; + servo_pos.delta = 0; + } + if ((servo_pos.delta < 0)&&(servo_pos.current_position < servo_pos.target_position)) + { + servo_pos.current_position = servo_pos.target_position; + servo_pos.delta = 0; + } + if (servo_pos.current_position == servo_pos.target_position) servo_pos.delta = 0; + } + sservo.write ( servo_pos.current_position ); +} // end update_servos() +#endif + +void playTrackOnChannel ( byte dtrack) { +#ifdef SOUND_PLAYER15 + if (dtrack == 0) return; + if (dtrack!=127) {Player1.play(dtrack); } //delay(audiocmddelay); } + else {Player1.play(random(First_Track,Last_Track+1)); } //delay(audiocmddelay); } +#endif +} // end playTrackOnChannel() + +void setVolumeOnChannel ( byte dvolume) { +#ifdef SOUND_PLAYER15 + if(dvolume>30) return; // Don't change the volume if out of range + Player1.volume(dvolume); + delay(audiocmddelay); +#endif +} // end setVolumeOnChannel() + +void notifyCVChange( uint16_t CV, uint8_t Value) { +#ifdef DEBUG + //Serial.print("CV= "); + //Serial.println(CV, DEC) ; + //Serial.print("Value= "); + //Serial.println(Value, DEC) ; +#endif + if ( CV==49 ) setVolumeOnChannel (Value); +} + +void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { +#ifdef DEBUG + //Serial.print("Addr= "); + //Serial.println(Addr, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch(FuncGrp) + { + case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1 + exec_function( 0, FunctionPin0, (FuncState & FN_BIT_00)>>4 ); + exec_function( 1, FunctionPin1, (FuncState & FN_BIT_01)); + exec_function( 2, FunctionPin2, (FuncState & FN_BIT_02)>>1); + exec_function( 3, FunctionPin3, (FuncState & FN_BIT_03)>>2 ); + exec_function( 4, FunctionPin4, (FuncState & FN_BIT_04)>>3 ); + break; + case FN_5_8: //Function Group 1 S FFFF == 1 F8 F7 F6 F5 & == 0 F12 F11 F10 F9 F8 + exec_function( 5, FunctionPin5, (FuncState & FN_BIT_05)); + exec_function( 6, FunctionPin6, (FuncState & FN_BIT_06)>>1 ); + exec_function( 7, FunctionPin7, (FuncState & FN_BIT_07)>>2 ); + exec_function( 8, FunctionPin8, (FuncState & FN_BIT_08)>>3 ); + break; + + case FN_9_12: + exec_function( 9, FunctionPin9, (FuncState & FN_BIT_09)); + exec_function( 10, FunctionPin10, (FuncState & FN_BIT_10)>>1 ); + exec_function( 11, FunctionPin11, (FuncState & FN_BIT_11)>>2 ); + exec_function( 12, FunctionPin12, (FuncState & FN_BIT_12)>>3 ); + break; + case FN_13_20: //Function Group 2 FuncState == F20-F13 Function Control + exec_function( 13, FunctionPin13, (FuncState & FN_BIT_13)); + exec_function( 14, FunctionPin14, (FuncState & FN_BIT_14)>>1 ); + //exec_function( 15, FunctionPin15, (FuncState & FN_BIT_15)>>2 ); + //exec_function( 16, FunctionPin16, (FuncState & FN_BIT_16)>>3 ); + break; + + case FN_21_28: + break; + } +} // end notifyDccFunc +void exec_function (int function, int pin, int FuncState) { +#ifdef DEBUG + //Serial.print("ex function= "); + //Serial.println(function, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch ( Dcc.getCV( 30+function) ) { // Config + case 0: // Master Disable + Function0_value = byte(FuncState); + break; + case 1: // run switch set [ function ] + case 2: // run switch set [ function ] + case 3: // run switch set [ function ] + case 4: // run switch set [ function ] + case 5: // run switch set [ function ] + case 6: // run switch set [ function ] + case 7: // run switch set [ function ] + case 8: // run switch set [ function ] + case 9: // run switch set [ function ] + case 10: // run switch set [ function ] + function_value[function] = byte(FuncState); + break; + default: + break;; + } +} // end exec_function + +/* DFPlayer Commands +//----Set volume---- + myDFPlayer.volume(10); //Set volume value (0~30). + myDFPlayer.volumeUp(); //Volume Up + myDFPlayer.volumeDown(); //Volume Down + //----Set different EQ---- + myDFPlayer.EQ(DFPLAYER_EQ_NORMAL); +// myDFPlayer.EQ(DFPLAYER_EQ_POP); +// myDFPlayer.EQ(DFPLAYER_EQ_ROCK); +// myDFPlayer.EQ(DFPLAYER_EQ_JAZZ); +// myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC); +// myDFPlayer.EQ(DFPLAYER_EQ_BASS); + //----Set device we use SD as default---- +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_U_DISK); + myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_AUX); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_SLEEP); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_FLASH); + //----Mp3 control---- +// myDFPlayer.sleep(); //sleep +// myDFPlayer.reset(); //Reset the module +// myDFPlayer.enableDAC(); //Enable On-chip DAC +// myDFPlayer.disableDAC(); //Disable On-chip DAC +// myDFPlayer.outputSetting(true, 15); //output setting, enable the output and set the gain to 15 + //----Mp3 play---- + myDFPlayer.next(); //Play next mp3 + myDFPlayer.previous(); //Play previous mp3 + myDFPlayer.play(1); //Play the first mp3 + myDFPlayer.loop(1); //Loop the first mp3 + myDFPlayer.pause(); //pause the mp3 + myDFPlayer.start(); //start the mp3 from the pause + myDFPlayer.playFolder(15, 4); //play specific mp3 in SD:/15/004.mp3; Folder Name(1~99); File Name(1~255) + myDFPlayer.enableLoopAll(); //loop all mp3 files. + myDFPlayer.disableLoopAll(); //stop loop all mp3 files. + myDFPlayer.playMp3Folder(4); //play specific mp3 in SD:/MP3/0004.mp3; File Name(0~65535) + myDFPlayer.advertise(3); //advertise specific mp3 in SD:/ADVERT/0003.mp3; File Name(0~65535) + myDFPlayer.stopAdvertise(); //stop advertise + myDFPlayer.playLargeFolder(2, 999); //play specific mp3 in SD:/02/004.mp3; Folder Name(1~10); File Name(1~1000) + myDFPlayer.loopFolder(5); //loop all mp3 files in folder SD:/05. + myDFPlayer.randomAll(); //Random play all the mp3. + myDFPlayer.enableLoop(); //enable loop. + myDFPlayer.disableLoop(); //disable loop. +*/ diff --git a/examples/IDECDemo&Diags/IDEC4_4_ServosCVBell_Demo3/IDEC4_4_ServosCVBell_Demo3.ino b/examples/IDECDemo&Diags/IDEC4_4_ServosCVBell_Demo3/IDEC4_4_ServosCVBell_Demo3.ino new file mode 100644 index 0000000..c2ed565 --- /dev/null +++ b/examples/IDECDemo&Diags/IDEC4_4_ServosCVBell_Demo3/IDEC4_4_ServosCVBell_Demo3.ino @@ -0,0 +1,1213 @@ +// Switched Pins Servos, LEDs Sounds Variable Slow Servvo Travel IDEC4_4_ServosLEDsSoundsCV.ino +// Servo Positions and LED controls set by CV dynamically +// Version 1.08 Geoff Bunza 2020 +// 5 Functions and Switched Inputs Plays Sound Sets 1-5 stepped with Leds 1-5 and Servos 1-5 +// F0 Master Decoder Disable Function Turn Function ON to disable the decoder +// F1-F5 and Switched Inputs Plays Sound Sets 1-5 stepped with Leds 1-5 and Servos 1-5 +// F6 Plays Sound Sets 6 +// Master Disable Function Turn Function ON to disable the decoder +// Works with both short and long DCC Addesses +// Config 0=DISABLE On/Off,1-16=Sound Set Control 1-6 + +/* +PRO MINI PIN ASSIGNMENT: +2 - DCC Input +3 - Input Pin Channel Switch1 & Function1 +4 - Input Pin Channel Switch2 & Function2 +5 - Input Pin Channel Switch3 & Function3 +6 - Input Pin Channel Switch4 & Function4 +7 - Input Pin Channel Switch5 & Function5 +8 - Servo Pin Channel 1 +9 - LED Pin Channel 1 +10 - Servo Pin Channel 2 +11 - LED Pin Channel 2 +12 - Servo Pin Channel 3 +13 - LED Pin Channel 3 +14 A0 - Servo Pin Channel 4 +15 A1 - (TX) connected to DFPlayer1 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor +16 A2 - Input Pin for MasterDecoderDisable Active LOW & F0 +17 A3 - LED Pin Channel 4 +18 A4 - Servo Pin Channel 5 +19 A5 - LED Pin Channel 5 +*/ +// ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP +// ******** AFTER THE INITIAL DECODER LOAD REMOVE THE "//" IN THE FOOLOWING LINE!! +//#define DECODER_LOADED + +// ******** REMOVE THE "//" IN THE FOOLOWING LINE TO SEND DEBUGGING +// ******** INFO TO THE SERIAL MONITOR +//#define DEBUG + +#include +#include +#include +#include +SoftwareSerial DFSerial1(22,15); // PRO MINI RX, PRO MINI TX serial to DFPlayer +DFRobotDFPlayerMini Player1; + +SoftwareServo servo[5]; + +#define This_Decoder_Address 24 +uint8_t CV_DECODER_MASTER_RESET = 252; + +//Uncomment ONLY ONE of the following: +//#define MasterTimeConstant 10L // 10's of milliseconds Timing +#define MasterTimeConstant 100L // Tenths of a second Timing +//#define MasterTimeConstant 1000L // Seconds Timing +//#define MasterTimeConstant 10000L // 10's of Seconds Timing +//#define MasterTimeConstant 60000L // Minutes Timing +//#define MasterTimeConstant 3600000L // Hours Timing + +uint16_t ttemp, i; +#define First_Track 1 // Play Random Tracks First_Track#=Start_Track >=1 +#define Last_Track 12 // Play Random Tracks Last_Track= Last Playable Track in Range <= Last Numbered Track +#define starting_volume 21 // If no volume is set use this at the start +const int audiocmddelay = 34; + +#define servo_master_slowdown 9 //servo loop counter limit +int servo_slow_counter = 1; //servo loop counter to slowdown servo transit +byte servo_unit_faster = 0; + + // Vsx and Lsx are all loaded from CVs +byte ss1[] = {0,0,0,0,0,0}; unsigned long ss1delay=0; // Time state variabler for the set +byte Ls1[] = {1,0,1,0,1,0}; // LED states set by CV_load()at setup() +byte Vs1[] = {0,0,0,0,0,0}; // Servo Positions set by CV_load()at setup() +byte ss2[] = {0,0,0,0,0,0}; unsigned long ss2delay=0; // Time state variabler for the set +byte Ls2[] = {1,1,1,1,1,0}; // LED states set by CV_load()at setup() +byte Vs2[] = {0,0,0,0,0,0}; // Servo Positions set by CV_load()at setup() +byte ss3[] = {0,0,0,0,0,0}; unsigned long ss3delay=0; // Time state variabler for the set +byte Ls3[] = {0,0,1,1,1,0}; // LED states set by CV_load()at setup() +byte Vs3[] = {0,0,0,0,0,0}; // Servo Positions set by CV_load()at setup() +byte ss4[] = {0,0,0,0,0,0}; unsigned long ss4delay=0; // Time state variabler for the set +byte Ls4[] = {1,0,0,0,0,1}; // LED states set by CV_load()at setup() +byte Vs4[] = {0,0,0,0,0,0}; // Servo Positions set by CV_load()at setup() +byte ss5[] = {0,0,0,0,0,0}; unsigned long ss5delay=0; // Time state variabler for the set +byte Ls5[] = {0,1,1,1,1,0}; // LED states set by CV_load()at setup() +byte Vs5[] = {0,0,0,0,0,0}; // Servo Positions set by CV_load()at setup() +byte ss6[] = {0,0,0,0,0,0}; unsigned long ss6delay=0; // Time state variabler for the set +byte ss7[] = {0,0,0,0,0,0}; unsigned long ss7delay=0; // Time state variabler for the set +byte ss8[] = {0,0,0,0,0,0}; unsigned long ss8delay=0; // Time state variabler for the set +byte ss9[] = {0,0,0,0,0,0}; unsigned long ss9delay=0; // Time state variabler for the set +byte ss10[] = {0,0,0,0,0,0}; unsigned long ss10delay=0; // Time state variabler for the set +bool playing_sound_set [ ] = {false,false,false,false,false,false,false,false,false,false,false}; +byte soundset_channel[ ]={0,0,0,0,0,0,0,0,0,0,0}; +byte Vs_pins[] = {8,10,12,14,18}; //Servo pins per channel starting with 1 +byte Ls_pins[] = {0,13,11,9,17,19}; // LED pins per channel starting with 1 + +struct SERVO_TRACKING +{ + byte current_position; + byte target_position; + char delta; +}; +SERVO_TRACKING *servo_pos = new SERVO_TRACKING[5]; + +const int MasterDecoderDisablePin = 16; // D16/A0 Master Decoder Disable Input Pin Active LOW + +const int numINpins = 6; // Number of INput pins to initialize +byte inputpins [] = {3,4,5,6,7,16}; //These are all the Input Pins +const int numfpins = 10; // Number of Output pins to initialize +const int num_active_functions = 11; // Number of Functions stating with F0 +byte fpins [] = {8,9,10,11,12,13,14,17,18,19}; //These are all the Output Pins (first 15 is placeholder) +const int FunctionPin0 = 20; // Place holders ONLY +const int FunctionPin1 = 20; // Channel 1 +const int FunctionPin2 = 20; // Channel 2 +const int FunctionPin3 = 20; // Channel 3 +const int FunctionPin4 = 20; // Channel 4 +const int FunctionPin5 = 20; // Channel 5 +const int FunctionPin6 = 20; // Channel 6 +const int FunctionPin7 = 20; // Channel 7 +const int FunctionPin8 = 20; // Channel 8 +const int FunctionPin9 = 20; // Place holders ONLY +const int FunctionPin10 = 20; // Place holders ONLY +const int FunctionPin11 = 20; // Place holders ONLY +int MasterDecoderDisable = 0; +int Function0_value = 0; +byte function_value [ ] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +uint8_t cv_value; + +NmraDcc Dcc ; +DCC_MSG Packet ; +int t; // temp +struct QUEUE +{ + int inuse; + int current_position; + int increment; + int stop_value; + int start_value; +}; +QUEUE *ftn_queue = new QUEUE[17]; + +struct CVPair +{ + uint16_t CV; + uint8_t Value; +}; +CVPair FactoryDefaultCVs [] = +{ + {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address&0x7F }, + + // These two CVs define the Long DCC Address + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, ((This_Decoder_Address>>8)&0x7F)+192 }, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address&0xFF }, + + // ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS +// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps + {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps +// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps + {CV_DECODER_MASTER_RESET, 0}, + + {30, 0}, //F0 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + + {31, 1}, //F1 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {32, 2}, //F2 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {33, 3}, //F3 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {34, 4}, //F4 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {35, 5}, //F5 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {36, 6}, //F6 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {37, 7}, //F7 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {38, 8}, //F8 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {39, 9}, //F9 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {40, 10}, //F10 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + + {41, 22}, //F11 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {42, 22}, //F12 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {43, 22}, //F13 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {44, 22}, //F14Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {45, 22}, //F15 not used + + {50, 6}, // Wait1 0-254 0.1 Seconds // SOUND SET 1 + {51, 55}, // Volume1 0-30 >30 == no volume change + {52, 4}, // Sound Clip1 + {53, 13}, // Wait2 0-254 0.1 Seconds + {54, 55}, // Volume2 0-30 >30 == no volume change + {55, 4}, // Sound Clip2 + {56, 13}, // Wait3 0-254 0.1 Seconds + {57, 55}, // Volume3 0-30 >30 == no volume change + {58, 4}, // Sound Clip3 + {59, 13}, // Wait4 0-254 0.1 Seconds + {60, 55}, // Volume4 0-30 >30 == no volume change + {61, 4}, // Sound Clip4 + {62, 8}, // Wait5 0-254 0.1 Seconds + {63, 55}, // Volume5 0-30 >30 == no volume change + {64, 0}, // Sound Clip5 + {65, 0}, // Sound Set Channel == LSB 0/1 + + {66, 2}, // Wait1 0-254 0.1 Seconds // SOUND SET 2 + {67, 20}, // Volume1 0-30 >30 == no volume change + {68, 4}, // Sound Clip1 + {69, 6}, // Wait2 0-254 0.1 Seconds + {70, 20}, // Volume2 0-30 >30 == no volume change + {71, 5}, // Sound Clip2 + {72, 6}, // Wait3 0-254 0.1 Seconds + {73, 20}, // Volume3 0-30 >30 == no volume change + {74, 6}, // Sound Clip3 + {75, 6}, // Wait4 0-254 0.1 Seconds + {76, 20}, // Volume4 0-30 >30 == no volume change + {77, 7}, // Sound Clip4 + {78, 6}, // Wait5 0-254 0.1 Seconds + {79, 20}, // Volume5 0-30 >30 == no volume change + {80, 8}, // Sound Clip5 + {81, 1}, // Sound Set Channel == LSB 0/1 + + {82, 1}, // Wait1 0-254 0.1 Seconds // SOUND SET 3 + {83, 20}, // Volume1 0-30 >30 == no volume change + {84, 5}, // Sound Clip1 + {85, 6}, // Wait2 0-254 0.1 Seconds + {86, 20}, // Volume2 0-30 >30 == no volume change + {87, 6}, // Sound Clip2 + {88, 6}, // Wait3 0-254 0.1 Seconds + {89, 20}, // Volume3 0-30 >30 == no volume change + {90, 7}, // Sound Clip3 + {91, 6}, // Wait4 0-254 0.1 Seconds + {92, 20}, // Volume4 0-30 >30 == no volume change + {93, 8}, // Sound Clip4 + {94, 6}, // Wait5 0-254 0.1 Seconds + {95, 20}, // Volume5 0-30 >30 == no volume change + {96, 8}, // Sound Clip5 + {97, 0}, // Sound Set Channel == LSB 0/1 + + {98, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 4 + {99, 23}, // Volume1 0-30 >30 == no volume change + {100, 9}, // Sound Clip1 + {101,110}, // Wait2 0-254 0.1 Seconds + {102, 99}, // Volume2 0-30 >30 == no volume change + {103, 0}, // Sound Clip2 + {104, 0}, // Wait3 0-254 0.1 Seconds + {105, 20}, // Volume3 0-30 >30 == no volume change + {106, 0}, // Sound Clip3 + {107, 0}, // Wait4 0-254 0.1 Seconds + {108, 99}, // Volume4 0-30 >30 == no volume change + {109, 0}, // Sound Clip4 + {110, 0}, // Wait5 0-254 0.1 Seconds + {111, 99}, // Volume5 0-30 >30 == no volume change + {112, 0}, // Sound Clip5 + {113, 0}, // Sound Set Channel == LSB 0/1 + + {114, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 5 + {115, 20}, // Volume1 0-30 >30 == no volume change + {116, 1}, // Sound Clip1 + {117, 20}, // Wait2 0-254 0.1 Seconds + {118, 20}, // Volume2 0-30 >30 == no volume change + {119, 2}, // Sound Clip2 + {120, 30}, // Wait3 0-254 0.1 Seconds + {121, 20}, // Volume3 0-30 >30 == no volume change + {122, 3}, // Sound Clip3 + {123, 50}, // Wait4 0-254 0.1 Seconds + {124, 20}, // Volume4 0-30 >30 == no volume change + {125, 4}, // Sound Clip4 + {126, 100}, // Wait5 0-254 0.1 Seconds + {127, 20}, // Volume5 0-30 >30 == no volume change + {128, 5}, // Sound Clip5 + {129, 0}, // Sound Set Channel == LSB 0/1 + + {130, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 6 + {131, 20}, // Volume1 0-30 >30 == no volume change + {132, 1}, // Sound Clip1 + {133, 20}, // Wait2 0-254 0.1 Seconds + {134, 20}, // Volume2 0-30 >30 == no volume change + {135, 2}, // Sound Clip2 + {136, 30}, // Wait3 0-254 0.1 Seconds + {137, 20}, // Volume3 0-30 >30 == no volume change + {138, 3}, // Sound Clip3 + {139, 50}, // Wait4 0-254 0.1 Seconds + {140, 20}, // Volume4 0-30 >30 == no volume change + {141, 4}, // Sound Clip4 + {142, 100}, // Wait5 0-254 0.1 Seconds + {143, 20}, // Volume5 0-30 >30 == no volume change + {144, 5}, // Sound Clip5 + {145, 1}, // Sound Set Channel == LSB 0/1 + // ================================================ + {146, 140}, // Servo Set 1 140,40,140,40,140,90 + {147, 50}, // + {148, 140}, // + {149, 50}, // + {150, 140}, // + {151, 90}, // + + {152, 40}, // Servo Set 2 40,60,90,120,150,30 + {153, 60}, // + {154, 90}, // + {155, 120}, // + {156, 150}, // + {157, 30}, // + + {158, 30}, // Servo Set 3 30,60,90,120,150,30 + {159, 60}, // + {160, 90}, // + {161, 120}, // + {162, 150}, // + {163, 30}, // + + {164, 30}, // Servo Set 4 30,60,90,120,150,30 + {165, 60}, // + {166, 90}, // + {167, 120}, // + {168, 150}, // + {169, 30}, // + + {170, 30}, // Servo Set 5 30,50,90,120,150,30 + {171, 50}, // + {172, 90}, // + {173, 120}, // + {174, 150}, // + {175, 30}, // + + {176, 1}, // LED Set 1 1,0,1,0,1,0 + {177, 0}, // + {178, 1}, // + {179, 0}, // + {180, 1}, // + {181, 0}, // + + {182, 1}, // LED Set 2 1,1,1,1,1,0 + {183, 1}, // + {184, 1}, // + {185, 1}, // + {186, 1}, // + {187, 0}, // + + {188, 1}, // LED Set 3 0,0,1,1,1,0 + {189, 0}, // + {190, 1}, // + {191, 0}, // + {192, 1}, // + {193, 0}, // + + {194, 1}, // LED Set 4 1,0,0,0,0,1 + {195, 0}, // + {196, 0}, // + {197, 0}, // + {198, 0}, // + {199, 1}, // + + {200, 0}, // LED Set 5 0,1,1,1,1,0 + {201, 1}, // + {202, 1}, // + {203, 1}, // + {204, 1}, // + {205, 0}, // + + {206, 0}, // Extra + //252,252 CV_DECODER_MASTER_RESET +}; + +uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +void notifyCVResetFactoryDefault() +{ + // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset + // to flag to the loop() function that a reset to Factory Defaults needs to be done + FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +}; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS + +void setup() //****************************************************** +{ +#ifdef DEBUG + Serial.begin(115200); +#endif + DFSerial1.begin (9600); + Player1.begin (DFSerial1); + + // initialize the digital pins as outputs + for (int i=0; i < numfpins; i++) { + pinMode(fpins[i], OUTPUT); + digitalWrite(fpins[i], 0); // All OUPUT pins initialized LOW + } + CV_load( ); // Load all relevant CVs + //Set up servos + for (i=0; i<5; i++) { + servo[i].attach(Vs_pins[i]); // Start Servos + //for (t=0; t<180; t++) SoftwareServo::refresh(); + } + servo[0].write(Vs1[5]); // Set Servos Initial positions + SoftwareServo::refresh(); + servo_pos[0].current_position = Vs1[5]; + servo[1].write(Vs2[5]); + SoftwareServo::refresh(); + servo_pos[1].current_position = Vs2[5]; + servo[2].write(Vs3[5]); + SoftwareServo::refresh(); + servo_pos[2].current_position = Vs3[5]; + servo[3].write(Vs4[5]); + SoftwareServo::refresh(); + servo_pos[3].current_position = Vs4[5]; + servo[4].write(Vs5[5]); + SoftwareServo::refresh(); + servo_pos[4].current_position = Vs5[5]; + for (i=0; i<5; i++) servo_pos[i].delta = 0; + + pinMode (MasterDecoderDisablePin,INPUT_PULLUP); // Master Decoder Disable Input Pin Active LOW + + // initialize the digital pins as inputs + for (int i=0; i < numINpins; i++) { + pinMode ( inputpins[i], INPUT_PULLUP ); + } + // Setup which External Interrupt, the Pin it's associated with that we're using + Dcc.pin(0, 2, 0); + // Call the main DCC Init function to enable the DCC Receiver + Dcc.init( MAN_ID_DIY, 61, FLAGS_MY_ADDRESS_ONLY, 0 ); + delay(800); +#if defined(DECODER_LOADED) + if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET ) +#endif + { + for (int j=0; j < FactoryDefaultCVIndex; j++ ) + Dcc.setCV( FactoryDefaultCVs[j].CV, FactoryDefaultCVs[j].Value); + } + // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + setVolumeOnChannel (starting_volume); +#ifdef DEBUG + Serial.println("CV Dump:"); + for (i=30; i<45; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=30; i<45; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 1"); + for (i=50; i<66; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=50; i<66; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 2"); + for (i=66; i<82; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=66; i<82; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 3"); + for (i=82; i<98; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=82; i<98; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 4"); + for (i=98; i<114; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=98; i<114; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 5"); + for (i=114; i<130; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=114; i<130; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 6"); + for (i=130; i<146; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=130; i<146; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Servo Set 1"); + for (i=146; i<152; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=146; i<152; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Servo Set 2"); + for (i=152; i<158; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=152; i<158; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Servo Set 3"); + for (i=158; i<164; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=158; i<164; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Servo Set 4"); + for (i=164; i<170; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=164; i<170; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Servo Set 5"); + for (i=170; i<176; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=170; i<176; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("LED Set 1"); + for (i=176; i<182; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=176; i<182; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("LED Set 2"); + for (i=182; i<188; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=182; i<188; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("LED Set 3"); + for (i=188; i<194; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=188; i<194; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("LED Set 4"); + for (i=194; i<200; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=194; i<200; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("LED Set 5"); + for (i=200; i<206; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=200; i<206; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } +#endif +} +void loop() //*********************************************************************************** +{ + //MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation + Dcc.process(); + SoftwareServo::refresh(); + if (servo_slow_counter > servo_master_slowdown) update_servos(); + else servo_slow_counter++; + delay(1); +// INPUT OVER RIDES + // Check Master Input Over ride + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + else MasterDecoderDisable = Function0_value & 1; + if (MasterDecoderDisable == 1) { + for (i=0; i < numfpins; i++) digitalWrite(fpins[i], 0); // All LEDs set LOW + } +// ******************************************************************************** + if (MasterDecoderDisable == 0) { + for (i=0; i < num_active_functions; i++) { + cv_value = Dcc.getCV(30+i) ; +#ifdef DEBUG + //Serial.print(" cv_value: "); + //Serial.println(cv_value, DEC) ; +#endif + switch ( cv_value ) { + case 0: // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + break; + case 1: // + if (((digitalRead(3)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss1[0]=1; + playing_sound_set[cv_value]=true; + } + break; + case 2: // + if (((digitalRead(4)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss2[0]=1; + digitalWrite( Ls_pins[2],Ls2[0]); + set_servo (1,Vs2[0]); + playing_sound_set[cv_value]=true; + } + break; + case 3: // + if (((digitalRead(5)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss3[0]=1; + digitalWrite( Ls_pins[3],Ls3[0]); + set_servo (2,Vs3[0]); + playing_sound_set[cv_value]=true; } + break; + case 4: // + if (((digitalRead(6)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss4[0]=1; + digitalWrite( Ls_pins[4],Ls4[0]); + set_servo (3,Vs4[0]); + playing_sound_set[cv_value]=true; } + break; + case 5: // + if (((digitalRead(7)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss5[0]=1; + digitalWrite( Ls_pins[5],Ls5[0]); + set_servo (4,Vs5[0]); + playing_sound_set[cv_value]=true; } + break; + case 6: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss6[0]=1; playing_sound_set[cv_value]=true; } + break; + case 7: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss7[0]=1; playing_sound_set[cv_value]=true; } + break; + case 8: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss8[0]=1; playing_sound_set[cv_value]=true; } + break; + case 9: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss9[0]=1; playing_sound_set[cv_value]=true; } + break; + case 10: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss10[0]=1; playing_sound_set[cv_value]=true; } + break; + default: + break; + } + } + } + // ========================== Sound Set 1 Begin Play + if (ss1[0]==1) { + digitalWrite( Ls_pins[1],Ls1[0]); + set_servo (0,Vs1[0]); + ss1delay=millis()+(long(Dcc.getCV(50)*MasterTimeConstant)); // Wait1 + ss1[0]=0; ss1[1]=1; + } + if ((ss1[1]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(52)); + setVolumeOnChannel (Dcc.getCV(51)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss1delay=millis()+(long(Dcc.getCV(53)*MasterTimeConstant)); // Wait2 + ss1[1]=0; ss1[2]=1; digitalWrite( Ls_pins[1],Ls1[1]); + set_servo (0,Vs1[1]); + } + if ((ss1[2]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(55)); + setVolumeOnChannel (Dcc.getCV(54)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss1delay=millis()+(long(Dcc.getCV(56)*MasterTimeConstant)); // Wait3 + ss1[2]=0; ss1[3]=1; digitalWrite( Ls_pins[1],Ls1[2]); + set_servo (0,Vs1[2]); + } + if ((ss1[3]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(58)); + setVolumeOnChannel (Dcc.getCV(57)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss1delay=millis()+(long(Dcc.getCV(59)*MasterTimeConstant)); // Wait4 + ss1[3]=0; ss1[4]=1; digitalWrite( Ls_pins[1],Ls1[3]); + set_servo (0,Vs1[3]); + } + if ((ss1[4]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(61)); + setVolumeOnChannel (Dcc.getCV(60)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss1delay=millis()+(long(Dcc.getCV(62)*MasterTimeConstant)); // Wait5 + ss1[4]=0; ss1[5]=1; digitalWrite( Ls_pins[1],Ls1[4]); + set_servo (0,Vs1[4]); + } + if ((ss1[5]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(64)); + setVolumeOnChannel (Dcc.getCV(63)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss1[5]=0; digitalWrite( Ls_pins[1],Ls1[5]); + set_servo (0,Vs1[5]); + playing_sound_set[1]=false; + } +// ========================== Sound Set 2 Begin Play + if (ss2[0]==1) { + ss2delay=millis()+(long(Dcc.getCV(66)*MasterTimeConstant)); // Wait1 + ss2[0]=0; ss2[1]=1; + } + if ((ss2[1]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(68)); + setVolumeOnChannel (Dcc.getCV(67)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss2delay=millis()+(long(Dcc.getCV(69)*MasterTimeConstant)); // Wait2 + ss2[1]=0; ss2[2]=1; digitalWrite( Ls_pins[2],Ls2[1]); + set_servo (1,Vs2[1]); + } + if ((ss2[2]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(71)); + setVolumeOnChannel (Dcc.getCV(70)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss2delay=millis()+(long(Dcc.getCV(72)*MasterTimeConstant)); // Wait3 + ss2[2]=0; ss2[3]=1; digitalWrite( Ls_pins[2],Ls2[2]); + set_servo (1,Vs2[2]); + } + if ((ss2[3]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(74)); + setVolumeOnChannel (Dcc.getCV(73)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss2delay=millis()+(long(Dcc.getCV(75)*MasterTimeConstant)); // Wait4 + ss2[3]=0; ss2[4]=1; digitalWrite( Ls_pins[2],Ls2[3]); + set_servo (1,Vs2[3]); + } + if ((ss2[4]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(77)); + setVolumeOnChannel (Dcc.getCV(76)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss2delay=millis()+(long(Dcc.getCV(78)*MasterTimeConstant)); // Wait5 + ss2[4]=0; ss2[5]=1; digitalWrite( Ls_pins[2],Ls2[4]); + set_servo (1,Vs2[4]); + } + if ((ss2[5]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(80)); + setVolumeOnChannel (Dcc.getCV(79)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss2[5]=0; digitalWrite( Ls_pins[2],Ls2[5]); + set_servo (1,Vs2[5]); + playing_sound_set[2]=false; + } +// ========================== Sound Set 3 Begin Play + if (ss3[0]==1) { + ss3delay=millis()+(long(Dcc.getCV(82)*MasterTimeConstant)); // Wait1 + ss3[0]=0; ss3[1]=1; + } + if ((ss3[1]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(84)); + setVolumeOnChannel (Dcc.getCV(83)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss3delay=millis()+(long(Dcc.getCV(85)*MasterTimeConstant)); // Wait2 + ss3[1]=0; ss3[2]=1; digitalWrite( Ls_pins[3],Ls3[1]); + set_servo (2,Vs3[1]); + } + if ((ss3[2]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(87)); + setVolumeOnChannel (Dcc.getCV(86)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss3delay=millis()+(long(Dcc.getCV(88)*MasterTimeConstant)); // Wait3 + ss3[2]=0; ss3[3]=1; digitalWrite( Ls_pins[3],Ls3[2]); + set_servo (2,Vs3[2]); + } + if ((ss3[3]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(90)); + setVolumeOnChannel (Dcc.getCV(89)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss3delay=millis()+(long(Dcc.getCV(91)*MasterTimeConstant)); // Wait4 + ss3[3]=0; ss3[4]=1; digitalWrite( Ls_pins[3],Ls3[3]); + set_servo (2,Vs3[3]); + } + if ((ss3[4]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(93)); + setVolumeOnChannel (Dcc.getCV(92)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss3delay=millis()+(long(Dcc.getCV(94)*MasterTimeConstant)); // Wait5 + ss3[4]=0; ss3[5]=1; digitalWrite( Ls_pins[3],Ls3[4]); + set_servo (2,Vs3[4]); + } + if ((ss3[5]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(96)); + setVolumeOnChannel (Dcc.getCV(95)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss3[5]=0; digitalWrite( Ls_pins[3],Ls3[5]); + set_servo (2,Vs3[5]); + playing_sound_set[3]=false; + } +// ========================== Sound Set 4 Begin Play + if (ss4[0]==1) { + ss4delay=millis()+(long(Dcc.getCV(98)*MasterTimeConstant)); // Wait1 + ss4[0]=0; ss4[1]=1; + } + if ((ss4[1]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(100)); + setVolumeOnChannel (Dcc.getCV(99)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss4delay=millis()+(long(Dcc.getCV(101)*MasterTimeConstant)); // Wait2 + ss4[1]=0; ss4[2]=1; digitalWrite( Ls_pins[4],Ls4[1]); + set_servo (3,Vs4[1]); + } + if ((ss4[2]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(103)); + setVolumeOnChannel (Dcc.getCV(102)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss4delay=millis()+(long(Dcc.getCV(104)*MasterTimeConstant)); // Wait3 + ss4[2]=0; ss4[3]=1; digitalWrite( Ls_pins[4],Ls4[2]); + set_servo (3,Vs4[2]); + } + if ((ss4[3]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(106)); + setVolumeOnChannel (Dcc.getCV(105)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss4delay=millis()+(long(Dcc.getCV(107)*MasterTimeConstant)); // Wait4 + ss4[3]=0; ss4[4]=1; digitalWrite( Ls_pins[4],Ls4[3]); + set_servo (3,Vs4[3]); + } + if ((ss4[4]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(109)); + setVolumeOnChannel (Dcc.getCV(108)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss4delay=millis()+(long(Dcc.getCV(110)*MasterTimeConstant)); // Wait5 + ss4[4]=0; ss4[5]=1; digitalWrite( Ls_pins[4],Ls4[4]); + set_servo (3,Vs4[4]); + } + if ((ss4[5]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(112)); + setVolumeOnChannel (Dcc.getCV(111)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss4[5]=0; digitalWrite( Ls_pins[4],Ls4[5]); + set_servo (3,Vs4[5]); + playing_sound_set[4]=false; + } +// ========================== Sound Set 5 Begin Play + if (ss5[0]==1) { + ss5delay=millis()+(long(Dcc.getCV(114)*MasterTimeConstant)); // Wait1 + ss5[0]=0; ss5[1]=1; + } + if ((ss5[1]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(116)); + setVolumeOnChannel (Dcc.getCV(115)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss5delay=millis()+(long(Dcc.getCV(117)*MasterTimeConstant)); // Wait2 + ss5[1]=0; ss5[2]=1; digitalWrite( Ls_pins[5],Ls5[1]); + set_servo (4,Vs5[1]); + } + if ((ss5[2]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(119)); + setVolumeOnChannel (Dcc.getCV(118)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss5delay=millis()+(long(Dcc.getCV(120)*MasterTimeConstant)); // Wait3 + ss5[2]=0; ss5[3]=1; digitalWrite( Ls_pins[5],Ls5[2]); + set_servo (4,Vs5[2]); + } + if ((ss5[3]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(122)); + setVolumeOnChannel (Dcc.getCV(121)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss5delay=millis()+(long(Dcc.getCV(123)*MasterTimeConstant)); // Wait4 + ss5[3]=0; ss5[4]=1; digitalWrite( Ls_pins[5],Ls5[3]); + set_servo (4,Vs5[3]); + } + if ((ss5[4]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(125)); + setVolumeOnChannel (Dcc.getCV(124)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss5delay=millis()+(long(Dcc.getCV(126)*MasterTimeConstant)); // Wait5 + ss5[4]=0; ss5[5]=1; digitalWrite( Ls_pins[5],Ls5[4]); + set_servo (4,Vs5[4]); + } + if ((ss5[5]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(128)); + setVolumeOnChannel (Dcc.getCV(127)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss5[5]=0; digitalWrite( Ls_pins[5],Ls5[5]); + set_servo (4,Vs5[5]); + playing_sound_set[5]=false; + } + +// ========================== Sound Set 6 Begin Play + if (ss6[0]==1) { + ss6delay=millis()+(long(Dcc.getCV(130)*MasterTimeConstant)); // Wait1 + ss6[0]=0; ss6[1]=1; + } + if ((ss6[1]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(132)); + setVolumeOnChannel (Dcc.getCV(131)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss6delay=millis()+(long(Dcc.getCV(133)*MasterTimeConstant)); // Wait2 + ss6[1]=0; ss6[2]=1; + } + if ((ss6[2]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(135)); + setVolumeOnChannel (Dcc.getCV(134)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss6delay=millis()+(long(Dcc.getCV(136)*MasterTimeConstant)); // Wait3 + ss6[2]=0; ss6[3]=1; + } + if ((ss6[3]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(138)); + setVolumeOnChannel (Dcc.getCV(137)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss6delay=millis()+(long(Dcc.getCV(139)*MasterTimeConstant)); // Wait4 + ss6[3]=0; ss6[4]=1; + } + if ((ss6[4]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(141)); + setVolumeOnChannel (Dcc.getCV(140)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss6delay=millis()+(long(Dcc.getCV(142)*MasterTimeConstant)); // Wait5 + ss6[4]=0; ss6[5]=1; + } + if ((ss6[5]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(144)); + setVolumeOnChannel (Dcc.getCV(143)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss6[5]=0; playing_sound_set[6]=false; + } + +// ========================== Sound Set 7 Begin Play + if (ss7[0]==1) { + ss7delay=millis()+(long(Dcc.getCV(146)*MasterTimeConstant)); // Wait1 + ss7[0]=0; ss7[1]=1; + } + if ((ss7[1]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(148)); + setVolumeOnChannel (Dcc.getCV(147)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss7delay=millis()+(long(Dcc.getCV(149)*MasterTimeConstant)); // Wait2 + ss7[1]=0; ss7[2]=1; + } + if ((ss7[2]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(151)); + setVolumeOnChannel (Dcc.getCV(150)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss7delay=millis()+(long(Dcc.getCV(152)*MasterTimeConstant)); // Wait3 + ss7[2]=0; ss7[3]=1; + } + if ((ss7[3]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(154)); + setVolumeOnChannel (Dcc.getCV(153)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss7delay=millis()+(long(Dcc.getCV(155)*MasterTimeConstant)); // Wait4 + ss7[3]=0; ss7[4]=1; + } + if ((ss7[4]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(157)); + setVolumeOnChannel (Dcc.getCV(156)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss7delay=millis()+(long(Dcc.getCV(158)*MasterTimeConstant)); // Wait5 + ss7[4]=0; ss7[5]=1; + } + if ((ss7[5]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(160)); + setVolumeOnChannel (Dcc.getCV(159)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss7[5]=0; playing_sound_set[7]=false; + } +// ========================== Sound Set 8 Begin Play + if (ss8[0]==1) { + ss8delay=millis()+(long(Dcc.getCV(162)*MasterTimeConstant)); // Wait1 + ss8[0]=0; ss8[1]=1; + } + if ((ss8[1]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(164)); + setVolumeOnChannel (Dcc.getCV(163)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss8delay=millis()+(long(Dcc.getCV(165)*MasterTimeConstant)); // Wait2 + ss8[1]=0; ss8[2]=1; + } + if ((ss8[2]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(167)); + setVolumeOnChannel (Dcc.getCV(166)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss8delay=millis()+(long(Dcc.getCV(168)*MasterTimeConstant)); // Wait3 + ss8[2]=0; ss8[3]=1; + } + if ((ss8[3]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(170)); + setVolumeOnChannel (Dcc.getCV(169)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss8delay=millis()+(long(Dcc.getCV(171)*MasterTimeConstant)); // Wait4 + ss8[3]=0; ss8[4]=1; + } + if ((ss8[4]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(173)); + setVolumeOnChannel (Dcc.getCV(172)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss8delay=millis()+(long(Dcc.getCV(174)*MasterTimeConstant)); // Wait5 + ss8[4]=0; ss8[5]=1; + } + if ((ss8[5]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(176)); + setVolumeOnChannel (Dcc.getCV(175)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss8[5]=0; playing_sound_set[8]=false; + } +// ========================== Sound Set 9 Begin Play + if (ss9[0]==1) { + ss9delay=millis()+(long(Dcc.getCV(178)*MasterTimeConstant)); // Wait1 + ss9[0]=0; ss9[1]=1; + } + if ((ss9[1]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(180)); + setVolumeOnChannel (Dcc.getCV(179)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss9delay=millis()+(long(Dcc.getCV(181)*MasterTimeConstant)); // Wait2 + ss9[1]=0; ss9[2]=1; + } + if ((ss9[2]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(183)); + setVolumeOnChannel (Dcc.getCV(182)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss9delay=millis()+(long(Dcc.getCV(184)*MasterTimeConstant)); // Wait3 + ss9[2]=0; ss9[3]=1; + } + if ((ss9[3]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(186)); + setVolumeOnChannel (Dcc.getCV(185)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss9delay=millis()+(long(Dcc.getCV(187)*MasterTimeConstant)); // Wait4 + ss9[3]=0; ss9[4]=1; + } + if ((ss9[4]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(189)); + setVolumeOnChannel (Dcc.getCV(188)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss9delay=millis()+(long(Dcc.getCV(190)*MasterTimeConstant)); // Wait5 + ss9[4]=0; ss9[5]=1; + } + if ((ss9[5]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(192)); + setVolumeOnChannel (Dcc.getCV(191)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss9[5]=0; playing_sound_set[9]=false; + } +// ========================== Sound Set 10 Begin Play + if (ss10[0]==1) { + ss10delay=millis()+(long(Dcc.getCV(194)*MasterTimeConstant)); // Wait1 + ss10[0]=0; ss10[1]=1; + } + if ((ss10[1]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(196)); + setVolumeOnChannel (Dcc.getCV(195)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss10delay=millis()+(long(Dcc.getCV(197)*MasterTimeConstant)); // Wait2 + ss10[1]=0; ss10[2]=1; + } + if ((ss10[2]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(199)); + setVolumeOnChannel (Dcc.getCV(198)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss10delay=millis()+(long(Dcc.getCV(200)*MasterTimeConstant)); // Wait3 + ss10[2]=0; ss10[3]=1; + } + if ((ss10[3]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(202)); + setVolumeOnChannel (Dcc.getCV(201)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss10delay=millis()+(long(Dcc.getCV(203)*MasterTimeConstant)); // Wait4 + ss10[3]=0; ss10[4]=1; + } + if ((ss10[4]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(205)); + setVolumeOnChannel (Dcc.getCV(204)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss10delay=millis()+(long(Dcc.getCV(206)*MasterTimeConstant)); // Wait5 + ss10[4]=0; ss10[5]=1; + } + if ((ss10[5]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(208)); + setVolumeOnChannel (Dcc.getCV(207)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss10[5]=0; playing_sound_set[10]=false; + } +} // end loop() + +void set_servo (byte servonum, byte position) { + if (servo_pos[servonum].current_position == position) { + servo_pos[servonum].delta = 0; + servo_pos[servonum].target_position = position; + return; + } + if (servo_pos[servonum].current_position < position) servo_pos[servonum].delta = 1+servo_unit_faster; + else servo_pos[servonum].delta = -1-servo_unit_faster; + servo_pos[servonum].target_position = position; +} // end set_servo() + +void update_servos() { + servo_slow_counter = 1; + for (i=0; i<5; i++) { + if (servo_pos[i].delta != 0 ) { + servo_pos[i].current_position=servo_pos[i].current_position+servo_pos[i].delta; + if ((servo_pos[i].delta > 0)&&(servo_pos[i].current_position > servo_pos[i].target_position)) + { + servo_pos[i].current_position = servo_pos[i].target_position; + servo_pos[i].delta = 0; + } + if ((servo_pos[i].delta < 0)&&(servo_pos[i].current_position < servo_pos[i].target_position)) + { + servo_pos[i].current_position = servo_pos[i].target_position; + servo_pos[i].delta = 0; + } + if (servo_pos[i].current_position == servo_pos[i].target_position) servo_pos[i].delta = 0; + } + servo[i].write ( servo_pos[i].current_position ); + } +} // end update_servos() + +void playTrackOnChannel ( byte dtrack) { + if (dtrack!=255) {Player1.play(dtrack); delay(audiocmddelay); } + else {Player1.play(random(First_Track,Last_Track+1));} // delay(audiocmddelay); } +} +void setVolumeOnChannel ( byte dvolume) { + if(dvolume>30) return; // Don't change the volume if out of range + Player1.volume (dvolume); + delay(audiocmddelay); +} + +void notifyCVChange( uint16_t CV, uint8_t Value) { +#ifdef DEBUG + //Serial.print("CV= "); + //Serial.println(CV, DEC) ; + //Serial.print("Value= "); + //Serial.println(Value, DEC) ; +#endif + if (( CV > 145 )&&( CV < 176)) CV_load(); +} // end notifyCVChange() + +void CV_load( ) { + for (i=0; i<6; i++) { + Vs1[i]= Dcc.getCV(146+i); // if a CV changes update all the internals + Vs2[i]= Dcc.getCV(152+i); + Vs3[i]= Dcc.getCV(158+i); + Vs4[i]= Dcc.getCV(164+i); + Vs5[i]= Dcc.getCV(170+i); + Ls1[i]= Dcc.getCV(176+i); + Ls2[i]= Dcc.getCV(182+i); + Ls3[i]= Dcc.getCV(188+i); + Ls4[i]= Dcc.getCV(194+i); + Ls5[i]= Dcc.getCV(200+i); + } +} // end CV_load() + +void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { +#ifdef DEBUG + //Serial.print("Addr= "); + //Serial.println(Addr, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch(FuncGrp) + { + case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1 + exec_function( 0, FunctionPin0, (FuncState & FN_BIT_00)>>4 ); + exec_function( 1, FunctionPin1, (FuncState & FN_BIT_01)); + exec_function( 2, FunctionPin2, (FuncState & FN_BIT_02)>>1); + exec_function( 3, FunctionPin3, (FuncState & FN_BIT_03)>>2 ); + exec_function( 4, FunctionPin4, (FuncState & FN_BIT_04)>>3 ); + break; + case FN_5_8: //Function Group 1 S FFFF == 1 F8 F7 F6 F5 & == 0 F12 F11 F10 F9 F8 + exec_function( 5, FunctionPin5, (FuncState & FN_BIT_05)); + exec_function( 6, FunctionPin6, (FuncState & FN_BIT_06)>>1 ); + exec_function( 7, FunctionPin7, (FuncState & FN_BIT_07)>>2 ); + exec_function( 8, FunctionPin8, (FuncState & FN_BIT_08)>>3 ); + break; + + case FN_9_12: + exec_function( 9, FunctionPin9, (FuncState & FN_BIT_09)); + exec_function( 10, FunctionPin10, (FuncState & FN_BIT_10)>>1 ); + //exec_function( 11, FunctionPin11, (FuncState & FN_BIT_11)>>2 ); + //exec_function( 12, FunctionPin12, (FuncState & FN_BIT_12)>>3 ); + break; + case FN_13_20: //Function Group 2 FuncState == F20-F13 Function Control + //exec_function( 13, FunctionPin13, (FuncState & FN_BIT_13)); + //exec_function( 14, FunctionPin14, (FuncState & FN_BIT_14)>>1 ); + //exec_function( 15, FunctionPin15, (FuncState & FN_BIT_15)>>2 ); + //exec_function( 16, FunctionPin16, (FuncState & FN_BIT_16)>>3 ); + break; + + case FN_21_28: + break; + } +} // end notifyDccFunc +void exec_function (int function, int pin, int FuncState) { +#ifdef DEBUG + //Serial.print("ex function= "); + //Serial.println(function, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch ( Dcc.getCV( 30+function) ) { // Config + case 0: // Master Disable + Function0_value = byte(FuncState); + break; + case 1: // play sound set [ function ] + + case 2: // play sound set [ function ] + + case 3: // play sound set [ function ] + + case 4: // play sound set [ function ] + + case 5: // play sound set [ function ] + + case 6: // play sound set [ function ] + + case 7: // play sound set [ function ] + + case 8: // play sound set [ function ] + + case 9: // play sound set [ function ] + + case 10: // play sound set [ function ] + function_value[function] = byte(FuncState); + break; + case 11: // + default: + break;; + } +} // end exec_function + +/* DFPlayer Commands +//----Set volume---- + myDFPlayer.volume(10); //Set volume value (0~30). + myDFPlayer.volumeUp(); //Volume Up + myDFPlayer.volumeDown(); //Volume Down + //----Set different EQ---- + myDFPlayer.EQ(DFPLAYER_EQ_NORMAL); +// myDFPlayer.EQ(DFPLAYER_EQ_POP); +// myDFPlayer.EQ(DFPLAYER_EQ_ROCK); +// myDFPlayer.EQ(DFPLAYER_EQ_JAZZ); +// myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC); +// myDFPlayer.EQ(DFPLAYER_EQ_BASS); + //----Set device we use SD as default---- +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_U_DISK); + myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_AUX); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_SLEEP); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_FLASH); + //----Mp3 control---- +// myDFPlayer.sleep(); //sleep +// myDFPlayer.reset(); //Reset the module +// myDFPlayer.enableDAC(); //Enable On-chip DAC +// myDFPlayer.disableDAC(); //Disable On-chip DAC +// myDFPlayer.outputSetting(true, 15); //output setting, enable the output and set the gain to 15 + //----Mp3 play---- + myDFPlayer.next(); //Play next mp3 + myDFPlayer.previous(); //Play previous mp3 + myDFPlayer.play(1); //Play the first mp3 + myDFPlayer.loop(1); //Loop the first mp3 + myDFPlayer.pause(); //pause the mp3 + myDFPlayer.start(); //start the mp3 from the pause + myDFPlayer.playFolder(15, 4); //play specific mp3 in SD:/15/004.mp3; Folder Name(1~99); File Name(1~255) + myDFPlayer.enableLoopAll(); //loop all mp3 files. + myDFPlayer.disableLoopAll(); //stop loop all mp3 files. + myDFPlayer.playMp3Folder(4); //play specific mp3 in SD:/MP3/0004.mp3; File Name(0~65535) + myDFPlayer.advertise(3); //advertise specific mp3 in SD:/ADVERT/0003.mp3; File Name(0~65535) + myDFPlayer.stopAdvertise(); //stop advertise + myDFPlayer.playLargeFolder(2, 999); //play specific mp3 in SD:/02/004.mp3; Folder Name(1~10); File Name(1~1000) + myDFPlayer.loopFolder(5); //loop all mp3 files in folder SD:/05. + myDFPlayer.randomAll(); //Random play all the mp3. + myDFPlayer.enableLoop(); //enable loop. + myDFPlayer.disableLoop(); //disable loop. +*/ diff --git a/examples/IDECDemo&Diags/IDEC4_4_ServosCVBell_Demo3A/IDEC4_4_ServosCVBell_Demo3A.ino b/examples/IDECDemo&Diags/IDEC4_4_ServosCVBell_Demo3A/IDEC4_4_ServosCVBell_Demo3A.ino new file mode 100644 index 0000000..cb7d8c1 --- /dev/null +++ b/examples/IDECDemo&Diags/IDEC4_4_ServosCVBell_Demo3A/IDEC4_4_ServosCVBell_Demo3A.ino @@ -0,0 +1,1213 @@ +// Switched Pins Servos, LEDs Sounds Variable Slow Servvo Travel IDEC4_4_ServosLEDsSoundsCV.ino +// Servo Positions and LED controls set by CV dynamically +// Version 1.08 Geoff Bunza 2020 +// 5 Functions and Switched Inputs Plays Sound Sets 1-5 stepped with Leds 1-5 and Servos 1-5 +// F0 Master Decoder Disable Function Turn Function ON to disable the decoder +// F1-F5 and Switched Inputs Plays Sound Sets 1-5 stepped with Leds 1-5 and Servos 1-5 +// F6 Plays Sound Sets 6 +// Master Disable Function Turn Function ON to disable the decoder +// Works with both short and long DCC Addesses +// Config 0=DISABLE On/Off,1-16=Sound Set Control 1-6 + +/* +PRO MINI PIN ASSIGNMENT: +2 - DCC Input +3 - Input Pin Channel Switch1 & Function1 +4 - Input Pin Channel Switch2 & Function2 +5 - Input Pin Channel Switch3 & Function3 +6 - Input Pin Channel Switch4 & Function4 +7 - Input Pin Channel Switch5 & Function5 +8 - Servo Pin Channel 1 +9 - LED Pin Channel 1 +10 - Servo Pin Channel 2 +11 - LED Pin Channel 2 +12 - Servo Pin Channel 3 +13 - LED Pin Channel 3 +14 A0 - Servo Pin Channel 4 +15 A1 - (TX) connected to DFPlayer1 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor +16 A2 - Input Pin for MasterDecoderDisable Active LOW & F0 +17 A3 - LED Pin Channel 4 +18 A4 - Servo Pin Channel 5 +19 A5 - LED Pin Channel 5 +*/ +// ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP +// ******** AFTER THE INITIAL DECODER LOAD REMOVE THE "//" IN THE FOOLOWING LINE!! +//#define DECODER_LOADED + +// ******** REMOVE THE "//" IN THE FOOLOWING LINE TO SEND DEBUGGING +// ******** INFO TO THE SERIAL MONITOR +//#define DEBUG + +#include +#include +#include +#include +SoftwareSerial DFSerial1(22,15); // PRO MINI RX, PRO MINI TX serial to DFPlayer +DFRobotDFPlayerMini Player1; + +SoftwareServo servo[5]; + +#define This_Decoder_Address 24 +uint8_t CV_DECODER_MASTER_RESET = 252; + +//Uncomment ONLY ONE of the following: +//#define MasterTimeConstant 10L // 10's of milliseconds Timing +#define MasterTimeConstant 100L // Tenths of a second Timing +//#define MasterTimeConstant 1000L // Seconds Timing +//#define MasterTimeConstant 10000L // 10's of Seconds Timing +//#define MasterTimeConstant 60000L // Minutes Timing +//#define MasterTimeConstant 3600000L // Hours Timing + +uint16_t ttemp, i; +#define First_Track 1 // Play Random Tracks First_Track#=Start_Track >=1 +#define Last_Track 12 // Play Random Tracks Last_Track= Last Playable Track in Range <= Last Numbered Track +#define starting_volume 21 // If no volume is set use this at the start +const int audiocmddelay = 34; + +#define servo_master_slowdown 9 //servo loop counter limit +int servo_slow_counter = 1; //servo loop counter to slowdown servo transit +byte servo_unit_faster = 0; + + // Vsx and Lsx are all loaded from CVs +byte ss1[] = {0,0,0,0,0,0}; unsigned long ss1delay=0; // Time state variabler for the set +byte Ls1[] = {1,0,1,0,1,0}; // LED states set by CV_load()at setup() +byte Vs1[] = {0,0,0,0,0,0}; // Servo Positions set by CV_load()at setup() +byte ss2[] = {0,0,0,0,0,0}; unsigned long ss2delay=0; // Time state variabler for the set +byte Ls2[] = {1,1,1,1,1,0}; // LED states set by CV_load()at setup() +byte Vs2[] = {0,0,0,0,0,0}; // Servo Positions set by CV_load()at setup() +byte ss3[] = {0,0,0,0,0,0}; unsigned long ss3delay=0; // Time state variabler for the set +byte Ls3[] = {0,0,1,1,1,0}; // LED states set by CV_load()at setup() +byte Vs3[] = {0,0,0,0,0,0}; // Servo Positions set by CV_load()at setup() +byte ss4[] = {0,0,0,0,0,0}; unsigned long ss4delay=0; // Time state variabler for the set +byte Ls4[] = {1,0,0,0,0,1}; // LED states set by CV_load()at setup() +byte Vs4[] = {0,0,0,0,0,0}; // Servo Positions set by CV_load()at setup() +byte ss5[] = {0,0,0,0,0,0}; unsigned long ss5delay=0; // Time state variabler for the set +byte Ls5[] = {0,1,1,1,1,0}; // LED states set by CV_load()at setup() +byte Vs5[] = {0,0,0,0,0,0}; // Servo Positions set by CV_load()at setup() +byte ss6[] = {0,0,0,0,0,0}; unsigned long ss6delay=0; // Time state variabler for the set +byte ss7[] = {0,0,0,0,0,0}; unsigned long ss7delay=0; // Time state variabler for the set +byte ss8[] = {0,0,0,0,0,0}; unsigned long ss8delay=0; // Time state variabler for the set +byte ss9[] = {0,0,0,0,0,0}; unsigned long ss9delay=0; // Time state variabler for the set +byte ss10[] = {0,0,0,0,0,0}; unsigned long ss10delay=0; // Time state variabler for the set +bool playing_sound_set [ ] = {false,false,false,false,false,false,false,false,false,false,false}; +byte soundset_channel[ ]={0,0,0,0,0,0,0,0,0,0,0}; +byte Vs_pins[] = {8,10,12,14,18}; //Servo pins per channel starting with 1 +byte Ls_pins[] = {0,13,11,9,17,19}; // LED pins per channel starting with 1 + +struct SERVO_TRACKING +{ + byte current_position; + byte target_position; + char delta; +}; +SERVO_TRACKING *servo_pos = new SERVO_TRACKING[5]; + +const int MasterDecoderDisablePin = 16; // D16/A0 Master Decoder Disable Input Pin Active LOW + +const int numINpins = 6; // Number of INput pins to initialize +byte inputpins [] = {3,4,5,6,7,16}; //These are all the Input Pins +const int numfpins = 10; // Number of Output pins to initialize +const int num_active_functions = 11; // Number of Functions stating with F0 +byte fpins [] = {8,9,10,11,12,13,14,17,18,19}; //These are all the Output Pins (first 15 is placeholder) +const int FunctionPin0 = 20; // Place holders ONLY +const int FunctionPin1 = 20; // Channel 1 +const int FunctionPin2 = 20; // Channel 2 +const int FunctionPin3 = 20; // Channel 3 +const int FunctionPin4 = 20; // Channel 4 +const int FunctionPin5 = 20; // Channel 5 +const int FunctionPin6 = 20; // Channel 6 +const int FunctionPin7 = 20; // Channel 7 +const int FunctionPin8 = 20; // Channel 8 +const int FunctionPin9 = 20; // Place holders ONLY +const int FunctionPin10 = 20; // Place holders ONLY +const int FunctionPin11 = 20; // Place holders ONLY +int MasterDecoderDisable = 0; +int Function0_value = 0; +byte function_value [ ] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +uint8_t cv_value; + +NmraDcc Dcc ; +DCC_MSG Packet ; +int t; // temp +struct QUEUE +{ + int inuse; + int current_position; + int increment; + int stop_value; + int start_value; +}; +QUEUE *ftn_queue = new QUEUE[17]; + +struct CVPair +{ + uint16_t CV; + uint8_t Value; +}; +CVPair FactoryDefaultCVs [] = +{ + {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address&0x7F }, + + // These two CVs define the Long DCC Address + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, ((This_Decoder_Address>>8)&0x7F)+192 }, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address&0xFF }, + + // ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS +// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps + {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps +// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps + {CV_DECODER_MASTER_RESET, 0}, + + {30, 0}, //F0 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + + {31, 1}, //F1 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {32, 2}, //F2 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {33, 3}, //F3 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {34, 4}, //F4 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {35, 5}, //F5 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {36, 6}, //F6 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {37, 7}, //F7 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {38, 8}, //F8 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {39, 9}, //F9 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {40, 10}, //F10 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + + {41, 22}, //F11 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {42, 22}, //F12 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {43, 22}, //F13 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {44, 22}, //F14Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {45, 22}, //F15 not used + + {50, 6}, // Wait1 0-254 0.1 Seconds // SOUND SET 1 + {51, 55}, // Volume1 0-30 >30 == no volume change + {52, 13}, // Sound Clip1 + {53, 13}, // Wait2 0-254 0.1 Seconds + {54, 55}, // Volume2 0-30 >30 == no volume change + {55, 13}, // Sound Clip2 + {56, 13}, // Wait3 0-254 0.1 Seconds + {57, 55}, // Volume3 0-30 >30 == no volume change + {58, 13}, // Sound Clip3 + {59, 13}, // Wait4 0-254 0.1 Seconds + {60, 55}, // Volume4 0-30 >30 == no volume change + {61, 13}, // Sound Clip4 + {62, 9}, // Wait5 0-254 0.1 Seconds + {63, 55}, // Volume5 0-30 >30 == no volume change + {64, 0}, // Sound Clip5 + {65, 0}, // Sound Set Channel == LSB 0/1 + + {66, 2}, // Wait1 0-254 0.1 Seconds // SOUND SET 2 + {67, 20}, // Volume1 0-30 >30 == no volume change + {68, 4}, // Sound Clip1 + {69, 6}, // Wait2 0-254 0.1 Seconds + {70, 20}, // Volume2 0-30 >30 == no volume change + {71, 5}, // Sound Clip2 + {72, 6}, // Wait3 0-254 0.1 Seconds + {73, 20}, // Volume3 0-30 >30 == no volume change + {74, 6}, // Sound Clip3 + {75, 6}, // Wait4 0-254 0.1 Seconds + {76, 20}, // Volume4 0-30 >30 == no volume change + {77, 7}, // Sound Clip4 + {78, 6}, // Wait5 0-254 0.1 Seconds + {79, 20}, // Volume5 0-30 >30 == no volume change + {80, 8}, // Sound Clip5 + {81, 1}, // Sound Set Channel == LSB 0/1 + + {82, 1}, // Wait1 0-254 0.1 Seconds // SOUND SET 3 + {83, 20}, // Volume1 0-30 >30 == no volume change + {84, 5}, // Sound Clip1 + {85, 6}, // Wait2 0-254 0.1 Seconds + {86, 20}, // Volume2 0-30 >30 == no volume change + {87, 6}, // Sound Clip2 + {88, 6}, // Wait3 0-254 0.1 Seconds + {89, 20}, // Volume3 0-30 >30 == no volume change + {90, 7}, // Sound Clip3 + {91, 6}, // Wait4 0-254 0.1 Seconds + {92, 20}, // Volume4 0-30 >30 == no volume change + {93, 8}, // Sound Clip4 + {94, 6}, // Wait5 0-254 0.1 Seconds + {95, 20}, // Volume5 0-30 >30 == no volume change + {96, 8}, // Sound Clip5 + {97, 0}, // Sound Set Channel == LSB 0/1 + + {98, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 4 + {99, 23}, // Volume1 0-30 >30 == no volume change + {100, 9}, // Sound Clip1 + {101,110}, // Wait2 0-254 0.1 Seconds + {102, 99}, // Volume2 0-30 >30 == no volume change + {103, 0}, // Sound Clip2 + {104, 0}, // Wait3 0-254 0.1 Seconds + {105, 20}, // Volume3 0-30 >30 == no volume change + {106, 0}, // Sound Clip3 + {107, 0}, // Wait4 0-254 0.1 Seconds + {108, 99}, // Volume4 0-30 >30 == no volume change + {109, 0}, // Sound Clip4 + {110, 0}, // Wait5 0-254 0.1 Seconds + {111, 99}, // Volume5 0-30 >30 == no volume change + {112, 0}, // Sound Clip5 + {113, 0}, // Sound Set Channel == LSB 0/1 + + {114, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 5 + {115, 20}, // Volume1 0-30 >30 == no volume change + {116, 1}, // Sound Clip1 + {117, 20}, // Wait2 0-254 0.1 Seconds + {118, 20}, // Volume2 0-30 >30 == no volume change + {119, 2}, // Sound Clip2 + {120, 30}, // Wait3 0-254 0.1 Seconds + {121, 20}, // Volume3 0-30 >30 == no volume change + {122, 3}, // Sound Clip3 + {123, 50}, // Wait4 0-254 0.1 Seconds + {124, 20}, // Volume4 0-30 >30 == no volume change + {125, 4}, // Sound Clip4 + {126, 100}, // Wait5 0-254 0.1 Seconds + {127, 20}, // Volume5 0-30 >30 == no volume change + {128, 5}, // Sound Clip5 + {129, 0}, // Sound Set Channel == LSB 0/1 + + {130, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 6 + {131, 20}, // Volume1 0-30 >30 == no volume change + {132, 1}, // Sound Clip1 + {133, 20}, // Wait2 0-254 0.1 Seconds + {134, 20}, // Volume2 0-30 >30 == no volume change + {135, 2}, // Sound Clip2 + {136, 30}, // Wait3 0-254 0.1 Seconds + {137, 20}, // Volume3 0-30 >30 == no volume change + {138, 3}, // Sound Clip3 + {139, 50}, // Wait4 0-254 0.1 Seconds + {140, 20}, // Volume4 0-30 >30 == no volume change + {141, 4}, // Sound Clip4 + {142, 100}, // Wait5 0-254 0.1 Seconds + {143, 20}, // Volume5 0-30 >30 == no volume change + {144, 5}, // Sound Clip5 + {145, 1}, // Sound Set Channel == LSB 0/1 + // ================================================ + {146, 140}, // Servo Set 1 140,40,140,40,140,90 + {147, 50}, // + {148, 140}, // + {149, 50}, // + {150, 140}, // + {151, 90}, // + + {152, 40}, // Servo Set 2 40,60,90,120,150,30 + {153, 60}, // + {154, 90}, // + {155, 120}, // + {156, 150}, // + {157, 30}, // + + {158, 30}, // Servo Set 3 30,60,90,120,150,30 + {159, 60}, // + {160, 90}, // + {161, 120}, // + {162, 150}, // + {163, 30}, // + + {164, 30}, // Servo Set 4 30,60,90,120,150,30 + {165, 60}, // + {166, 90}, // + {167, 120}, // + {168, 150}, // + {169, 30}, // + + {170, 30}, // Servo Set 5 30,50,90,120,150,30 + {171, 50}, // + {172, 90}, // + {173, 120}, // + {174, 150}, // + {175, 30}, // + + {176, 1}, // LED Set 1 1,0,1,0,1,0 + {177, 0}, // + {178, 1}, // + {179, 0}, // + {180, 1}, // + {181, 0}, // + + {182, 1}, // LED Set 2 1,1,1,1,1,0 + {183, 1}, // + {184, 1}, // + {185, 1}, // + {186, 1}, // + {187, 0}, // + + {188, 1}, // LED Set 3 0,0,1,1,1,0 + {189, 0}, // + {190, 1}, // + {191, 0}, // + {192, 1}, // + {193, 0}, // + + {194, 1}, // LED Set 4 1,0,0,0,0,1 + {195, 0}, // + {196, 0}, // + {197, 0}, // + {198, 0}, // + {199, 1}, // + + {200, 0}, // LED Set 5 0,1,1,1,1,0 + {201, 1}, // + {202, 1}, // + {203, 1}, // + {204, 1}, // + {205, 0}, // + + {206, 0}, // Extra + //252,252 CV_DECODER_MASTER_RESET +}; + +uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +void notifyCVResetFactoryDefault() +{ + // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset + // to flag to the loop() function that a reset to Factory Defaults needs to be done + FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +}; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS + +void setup() //****************************************************** +{ +#ifdef DEBUG + Serial.begin(115200); +#endif + DFSerial1.begin (9600); + Player1.begin (DFSerial1); + + // initialize the digital pins as outputs + for (int i=0; i < numfpins; i++) { + pinMode(fpins[i], OUTPUT); + digitalWrite(fpins[i], 0); // All OUPUT pins initialized LOW + } + CV_load( ); // Load all relevant CVs + //Set up servos + for (i=0; i<5; i++) { + servo[i].attach(Vs_pins[i]); // Start Servos + //for (t=0; t<180; t++) SoftwareServo::refresh(); + } + servo[0].write(Vs1[5]); // Set Servos Initial positions + SoftwareServo::refresh(); + servo_pos[0].current_position = Vs1[5]; + servo[1].write(Vs2[5]); + SoftwareServo::refresh(); + servo_pos[1].current_position = Vs2[5]; + servo[2].write(Vs3[5]); + SoftwareServo::refresh(); + servo_pos[2].current_position = Vs3[5]; + servo[3].write(Vs4[5]); + SoftwareServo::refresh(); + servo_pos[3].current_position = Vs4[5]; + servo[4].write(Vs5[5]); + SoftwareServo::refresh(); + servo_pos[4].current_position = Vs5[5]; + for (i=0; i<5; i++) servo_pos[i].delta = 0; + + pinMode (MasterDecoderDisablePin,INPUT_PULLUP); // Master Decoder Disable Input Pin Active LOW + + // initialize the digital pins as inputs + for (int i=0; i < numINpins; i++) { + pinMode ( inputpins[i], INPUT_PULLUP ); + } + // Setup which External Interrupt, the Pin it's associated with that we're using + Dcc.pin(0, 2, 0); + // Call the main DCC Init function to enable the DCC Receiver + Dcc.init( MAN_ID_DIY, 61, FLAGS_MY_ADDRESS_ONLY, 0 ); + delay(800); +#if defined(DECODER_LOADED) + if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET ) +#endif + { + for (int j=0; j < FactoryDefaultCVIndex; j++ ) + Dcc.setCV( FactoryDefaultCVs[j].CV, FactoryDefaultCVs[j].Value); + } + // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + setVolumeOnChannel (starting_volume); +#ifdef DEBUG + Serial.println("CV Dump:"); + for (i=30; i<45; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=30; i<45; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 1"); + for (i=50; i<66; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=50; i<66; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 2"); + for (i=66; i<82; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=66; i<82; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 3"); + for (i=82; i<98; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=82; i<98; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 4"); + for (i=98; i<114; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=98; i<114; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 5"); + for (i=114; i<130; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=114; i<130; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 6"); + for (i=130; i<146; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=130; i<146; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Servo Set 1"); + for (i=146; i<152; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=146; i<152; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Servo Set 2"); + for (i=152; i<158; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=152; i<158; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Servo Set 3"); + for (i=158; i<164; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=158; i<164; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Servo Set 4"); + for (i=164; i<170; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=164; i<170; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Servo Set 5"); + for (i=170; i<176; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=170; i<176; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("LED Set 1"); + for (i=176; i<182; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=176; i<182; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("LED Set 2"); + for (i=182; i<188; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=182; i<188; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("LED Set 3"); + for (i=188; i<194; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=188; i<194; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("LED Set 4"); + for (i=194; i<200; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=194; i<200; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("LED Set 5"); + for (i=200; i<206; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=200; i<206; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } +#endif +} +void loop() //*********************************************************************************** +{ + //MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation + Dcc.process(); + SoftwareServo::refresh(); + if (servo_slow_counter > servo_master_slowdown) update_servos(); + else servo_slow_counter++; + delay(1); +// INPUT OVER RIDES + // Check Master Input Over ride + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + else MasterDecoderDisable = Function0_value & 1; + if (MasterDecoderDisable == 1) { + for (i=0; i < numfpins; i++) digitalWrite(fpins[i], 0); // All LEDs set LOW + } +// ******************************************************************************** + if (MasterDecoderDisable == 0) { + for (i=0; i < num_active_functions; i++) { + cv_value = Dcc.getCV(30+i) ; +#ifdef DEBUG + //Serial.print(" cv_value: "); + //Serial.println(cv_value, DEC) ; +#endif + switch ( cv_value ) { + case 0: // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + break; + case 1: // + if (((digitalRead(3)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss1[0]=1; + playing_sound_set[cv_value]=true; + } + break; + case 2: // + if (((digitalRead(4)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss2[0]=1; + digitalWrite( Ls_pins[2],Ls2[0]); + set_servo (1,Vs2[0]); + playing_sound_set[cv_value]=true; + } + break; + case 3: // + if (((digitalRead(5)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss3[0]=1; + digitalWrite( Ls_pins[3],Ls3[0]); + set_servo (2,Vs3[0]); + playing_sound_set[cv_value]=true; } + break; + case 4: // + if (((digitalRead(6)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss4[0]=1; + digitalWrite( Ls_pins[4],Ls4[0]); + set_servo (3,Vs4[0]); + playing_sound_set[cv_value]=true; } + break; + case 5: // + if (((digitalRead(7)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss5[0]=1; + digitalWrite( Ls_pins[5],Ls5[0]); + set_servo (4,Vs5[0]); + playing_sound_set[cv_value]=true; } + break; + case 6: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss6[0]=1; playing_sound_set[cv_value]=true; } + break; + case 7: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss7[0]=1; playing_sound_set[cv_value]=true; } + break; + case 8: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss8[0]=1; playing_sound_set[cv_value]=true; } + break; + case 9: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss9[0]=1; playing_sound_set[cv_value]=true; } + break; + case 10: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss10[0]=1; playing_sound_set[cv_value]=true; } + break; + default: + break; + } + } + } + // ========================== Sound Set 1 Begin Play + if (ss1[0]==1) { + digitalWrite( Ls_pins[1],Ls1[0]); + set_servo (0,Vs1[0]); + ss1delay=millis()+(long(Dcc.getCV(50)*MasterTimeConstant)); // Wait1 + ss1[0]=0; ss1[1]=1; + } + if ((ss1[1]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(52)); + setVolumeOnChannel (Dcc.getCV(51)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss1delay=millis()+(long(Dcc.getCV(53)*MasterTimeConstant)); // Wait2 + ss1[1]=0; ss1[2]=1; digitalWrite( Ls_pins[1],Ls1[1]); + set_servo (0,Vs1[1]); + } + if ((ss1[2]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(55)); + setVolumeOnChannel (Dcc.getCV(54)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss1delay=millis()+(long(Dcc.getCV(56)*MasterTimeConstant)); // Wait3 + ss1[2]=0; ss1[3]=1; digitalWrite( Ls_pins[1],Ls1[2]); + set_servo (0,Vs1[2]); + } + if ((ss1[3]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(58)); + setVolumeOnChannel (Dcc.getCV(57)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss1delay=millis()+(long(Dcc.getCV(59)*MasterTimeConstant)); // Wait4 + ss1[3]=0; ss1[4]=1; digitalWrite( Ls_pins[1],Ls1[3]); + set_servo (0,Vs1[3]); + } + if ((ss1[4]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(61)); + setVolumeOnChannel (Dcc.getCV(60)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss1delay=millis()+(long(Dcc.getCV(62)*MasterTimeConstant)); // Wait5 + ss1[4]=0; ss1[5]=1; digitalWrite( Ls_pins[1],Ls1[4]); + set_servo (0,Vs1[4]); + } + if ((ss1[5]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(64)); + setVolumeOnChannel (Dcc.getCV(63)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss1[5]=0; digitalWrite( Ls_pins[1],Ls1[5]); + set_servo (0,Vs1[5]); + playing_sound_set[1]=false; + } +// ========================== Sound Set 2 Begin Play + if (ss2[0]==1) { + ss2delay=millis()+(long(Dcc.getCV(66)*MasterTimeConstant)); // Wait1 + ss2[0]=0; ss2[1]=1; + } + if ((ss2[1]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(68)); + setVolumeOnChannel (Dcc.getCV(67)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss2delay=millis()+(long(Dcc.getCV(69)*MasterTimeConstant)); // Wait2 + ss2[1]=0; ss2[2]=1; digitalWrite( Ls_pins[2],Ls2[1]); + set_servo (1,Vs2[1]); + } + if ((ss2[2]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(71)); + setVolumeOnChannel (Dcc.getCV(70)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss2delay=millis()+(long(Dcc.getCV(72)*MasterTimeConstant)); // Wait3 + ss2[2]=0; ss2[3]=1; digitalWrite( Ls_pins[2],Ls2[2]); + set_servo (1,Vs2[2]); + } + if ((ss2[3]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(74)); + setVolumeOnChannel (Dcc.getCV(73)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss2delay=millis()+(long(Dcc.getCV(75)*MasterTimeConstant)); // Wait4 + ss2[3]=0; ss2[4]=1; digitalWrite( Ls_pins[2],Ls2[3]); + set_servo (1,Vs2[3]); + } + if ((ss2[4]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(77)); + setVolumeOnChannel (Dcc.getCV(76)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss2delay=millis()+(long(Dcc.getCV(78)*MasterTimeConstant)); // Wait5 + ss2[4]=0; ss2[5]=1; digitalWrite( Ls_pins[2],Ls2[4]); + set_servo (1,Vs2[4]); + } + if ((ss2[5]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(80)); + setVolumeOnChannel (Dcc.getCV(79)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss2[5]=0; digitalWrite( Ls_pins[2],Ls2[5]); + set_servo (1,Vs2[5]); + playing_sound_set[2]=false; + } +// ========================== Sound Set 3 Begin Play + if (ss3[0]==1) { + ss3delay=millis()+(long(Dcc.getCV(82)*MasterTimeConstant)); // Wait1 + ss3[0]=0; ss3[1]=1; + } + if ((ss3[1]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(84)); + setVolumeOnChannel (Dcc.getCV(83)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss3delay=millis()+(long(Dcc.getCV(85)*MasterTimeConstant)); // Wait2 + ss3[1]=0; ss3[2]=1; digitalWrite( Ls_pins[3],Ls3[1]); + set_servo (2,Vs3[1]); + } + if ((ss3[2]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(87)); + setVolumeOnChannel (Dcc.getCV(86)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss3delay=millis()+(long(Dcc.getCV(88)*MasterTimeConstant)); // Wait3 + ss3[2]=0; ss3[3]=1; digitalWrite( Ls_pins[3],Ls3[2]); + set_servo (2,Vs3[2]); + } + if ((ss3[3]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(90)); + setVolumeOnChannel (Dcc.getCV(89)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss3delay=millis()+(long(Dcc.getCV(91)*MasterTimeConstant)); // Wait4 + ss3[3]=0; ss3[4]=1; digitalWrite( Ls_pins[3],Ls3[3]); + set_servo (2,Vs3[3]); + } + if ((ss3[4]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(93)); + setVolumeOnChannel (Dcc.getCV(92)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss3delay=millis()+(long(Dcc.getCV(94)*MasterTimeConstant)); // Wait5 + ss3[4]=0; ss3[5]=1; digitalWrite( Ls_pins[3],Ls3[4]); + set_servo (2,Vs3[4]); + } + if ((ss3[5]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(96)); + setVolumeOnChannel (Dcc.getCV(95)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss3[5]=0; digitalWrite( Ls_pins[3],Ls3[5]); + set_servo (2,Vs3[5]); + playing_sound_set[3]=false; + } +// ========================== Sound Set 4 Begin Play + if (ss4[0]==1) { + ss4delay=millis()+(long(Dcc.getCV(98)*MasterTimeConstant)); // Wait1 + ss4[0]=0; ss4[1]=1; + } + if ((ss4[1]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(100)); + setVolumeOnChannel (Dcc.getCV(99)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss4delay=millis()+(long(Dcc.getCV(101)*MasterTimeConstant)); // Wait2 + ss4[1]=0; ss4[2]=1; digitalWrite( Ls_pins[4],Ls4[1]); + set_servo (3,Vs4[1]); + } + if ((ss4[2]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(103)); + setVolumeOnChannel (Dcc.getCV(102)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss4delay=millis()+(long(Dcc.getCV(104)*MasterTimeConstant)); // Wait3 + ss4[2]=0; ss4[3]=1; digitalWrite( Ls_pins[4],Ls4[2]); + set_servo (3,Vs4[2]); + } + if ((ss4[3]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(106)); + setVolumeOnChannel (Dcc.getCV(105)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss4delay=millis()+(long(Dcc.getCV(107)*MasterTimeConstant)); // Wait4 + ss4[3]=0; ss4[4]=1; digitalWrite( Ls_pins[4],Ls4[3]); + set_servo (3,Vs4[3]); + } + if ((ss4[4]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(109)); + setVolumeOnChannel (Dcc.getCV(108)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss4delay=millis()+(long(Dcc.getCV(110)*MasterTimeConstant)); // Wait5 + ss4[4]=0; ss4[5]=1; digitalWrite( Ls_pins[4],Ls4[4]); + set_servo (3,Vs4[4]); + } + if ((ss4[5]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(112)); + setVolumeOnChannel (Dcc.getCV(111)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss4[5]=0; digitalWrite( Ls_pins[4],Ls4[5]); + set_servo (3,Vs4[5]); + playing_sound_set[4]=false; + } +// ========================== Sound Set 5 Begin Play + if (ss5[0]==1) { + ss5delay=millis()+(long(Dcc.getCV(114)*MasterTimeConstant)); // Wait1 + ss5[0]=0; ss5[1]=1; + } + if ((ss5[1]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(116)); + setVolumeOnChannel (Dcc.getCV(115)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss5delay=millis()+(long(Dcc.getCV(117)*MasterTimeConstant)); // Wait2 + ss5[1]=0; ss5[2]=1; digitalWrite( Ls_pins[5],Ls5[1]); + set_servo (4,Vs5[1]); + } + if ((ss5[2]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(119)); + setVolumeOnChannel (Dcc.getCV(118)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss5delay=millis()+(long(Dcc.getCV(120)*MasterTimeConstant)); // Wait3 + ss5[2]=0; ss5[3]=1; digitalWrite( Ls_pins[5],Ls5[2]); + set_servo (4,Vs5[2]); + } + if ((ss5[3]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(122)); + setVolumeOnChannel (Dcc.getCV(121)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss5delay=millis()+(long(Dcc.getCV(123)*MasterTimeConstant)); // Wait4 + ss5[3]=0; ss5[4]=1; digitalWrite( Ls_pins[5],Ls5[3]); + set_servo (4,Vs5[3]); + } + if ((ss5[4]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(125)); + setVolumeOnChannel (Dcc.getCV(124)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss5delay=millis()+(long(Dcc.getCV(126)*MasterTimeConstant)); // Wait5 + ss5[4]=0; ss5[5]=1; digitalWrite( Ls_pins[5],Ls5[4]); + set_servo (4,Vs5[4]); + } + if ((ss5[5]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(128)); + setVolumeOnChannel (Dcc.getCV(127)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss5[5]=0; digitalWrite( Ls_pins[5],Ls5[5]); + set_servo (4,Vs5[5]); + playing_sound_set[5]=false; + } + +// ========================== Sound Set 6 Begin Play + if (ss6[0]==1) { + ss6delay=millis()+(long(Dcc.getCV(130)*MasterTimeConstant)); // Wait1 + ss6[0]=0; ss6[1]=1; + } + if ((ss6[1]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(132)); + setVolumeOnChannel (Dcc.getCV(131)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss6delay=millis()+(long(Dcc.getCV(133)*MasterTimeConstant)); // Wait2 + ss6[1]=0; ss6[2]=1; + } + if ((ss6[2]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(135)); + setVolumeOnChannel (Dcc.getCV(134)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss6delay=millis()+(long(Dcc.getCV(136)*MasterTimeConstant)); // Wait3 + ss6[2]=0; ss6[3]=1; + } + if ((ss6[3]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(138)); + setVolumeOnChannel (Dcc.getCV(137)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss6delay=millis()+(long(Dcc.getCV(139)*MasterTimeConstant)); // Wait4 + ss6[3]=0; ss6[4]=1; + } + if ((ss6[4]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(141)); + setVolumeOnChannel (Dcc.getCV(140)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss6delay=millis()+(long(Dcc.getCV(142)*MasterTimeConstant)); // Wait5 + ss6[4]=0; ss6[5]=1; + } + if ((ss6[5]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(144)); + setVolumeOnChannel (Dcc.getCV(143)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss6[5]=0; playing_sound_set[6]=false; + } + +// ========================== Sound Set 7 Begin Play + if (ss7[0]==1) { + ss7delay=millis()+(long(Dcc.getCV(146)*MasterTimeConstant)); // Wait1 + ss7[0]=0; ss7[1]=1; + } + if ((ss7[1]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(148)); + setVolumeOnChannel (Dcc.getCV(147)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss7delay=millis()+(long(Dcc.getCV(149)*MasterTimeConstant)); // Wait2 + ss7[1]=0; ss7[2]=1; + } + if ((ss7[2]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(151)); + setVolumeOnChannel (Dcc.getCV(150)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss7delay=millis()+(long(Dcc.getCV(152)*MasterTimeConstant)); // Wait3 + ss7[2]=0; ss7[3]=1; + } + if ((ss7[3]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(154)); + setVolumeOnChannel (Dcc.getCV(153)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss7delay=millis()+(long(Dcc.getCV(155)*MasterTimeConstant)); // Wait4 + ss7[3]=0; ss7[4]=1; + } + if ((ss7[4]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(157)); + setVolumeOnChannel (Dcc.getCV(156)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss7delay=millis()+(long(Dcc.getCV(158)*MasterTimeConstant)); // Wait5 + ss7[4]=0; ss7[5]=1; + } + if ((ss7[5]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(160)); + setVolumeOnChannel (Dcc.getCV(159)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss7[5]=0; playing_sound_set[7]=false; + } +// ========================== Sound Set 8 Begin Play + if (ss8[0]==1) { + ss8delay=millis()+(long(Dcc.getCV(162)*MasterTimeConstant)); // Wait1 + ss8[0]=0; ss8[1]=1; + } + if ((ss8[1]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(164)); + setVolumeOnChannel (Dcc.getCV(163)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss8delay=millis()+(long(Dcc.getCV(165)*MasterTimeConstant)); // Wait2 + ss8[1]=0; ss8[2]=1; + } + if ((ss8[2]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(167)); + setVolumeOnChannel (Dcc.getCV(166)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss8delay=millis()+(long(Dcc.getCV(168)*MasterTimeConstant)); // Wait3 + ss8[2]=0; ss8[3]=1; + } + if ((ss8[3]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(170)); + setVolumeOnChannel (Dcc.getCV(169)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss8delay=millis()+(long(Dcc.getCV(171)*MasterTimeConstant)); // Wait4 + ss8[3]=0; ss8[4]=1; + } + if ((ss8[4]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(173)); + setVolumeOnChannel (Dcc.getCV(172)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss8delay=millis()+(long(Dcc.getCV(174)*MasterTimeConstant)); // Wait5 + ss8[4]=0; ss8[5]=1; + } + if ((ss8[5]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(176)); + setVolumeOnChannel (Dcc.getCV(175)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss8[5]=0; playing_sound_set[8]=false; + } +// ========================== Sound Set 9 Begin Play + if (ss9[0]==1) { + ss9delay=millis()+(long(Dcc.getCV(178)*MasterTimeConstant)); // Wait1 + ss9[0]=0; ss9[1]=1; + } + if ((ss9[1]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(180)); + setVolumeOnChannel (Dcc.getCV(179)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss9delay=millis()+(long(Dcc.getCV(181)*MasterTimeConstant)); // Wait2 + ss9[1]=0; ss9[2]=1; + } + if ((ss9[2]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(183)); + setVolumeOnChannel (Dcc.getCV(182)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss9delay=millis()+(long(Dcc.getCV(184)*MasterTimeConstant)); // Wait3 + ss9[2]=0; ss9[3]=1; + } + if ((ss9[3]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(186)); + setVolumeOnChannel (Dcc.getCV(185)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss9delay=millis()+(long(Dcc.getCV(187)*MasterTimeConstant)); // Wait4 + ss9[3]=0; ss9[4]=1; + } + if ((ss9[4]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(189)); + setVolumeOnChannel (Dcc.getCV(188)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss9delay=millis()+(long(Dcc.getCV(190)*MasterTimeConstant)); // Wait5 + ss9[4]=0; ss9[5]=1; + } + if ((ss9[5]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(192)); + setVolumeOnChannel (Dcc.getCV(191)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss9[5]=0; playing_sound_set[9]=false; + } +// ========================== Sound Set 10 Begin Play + if (ss10[0]==1) { + ss10delay=millis()+(long(Dcc.getCV(194)*MasterTimeConstant)); // Wait1 + ss10[0]=0; ss10[1]=1; + } + if ((ss10[1]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(196)); + setVolumeOnChannel (Dcc.getCV(195)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss10delay=millis()+(long(Dcc.getCV(197)*MasterTimeConstant)); // Wait2 + ss10[1]=0; ss10[2]=1; + } + if ((ss10[2]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(199)); + setVolumeOnChannel (Dcc.getCV(198)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss10delay=millis()+(long(Dcc.getCV(200)*MasterTimeConstant)); // Wait3 + ss10[2]=0; ss10[3]=1; + } + if ((ss10[3]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(202)); + setVolumeOnChannel (Dcc.getCV(201)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss10delay=millis()+(long(Dcc.getCV(203)*MasterTimeConstant)); // Wait4 + ss10[3]=0; ss10[4]=1; + } + if ((ss10[4]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(205)); + setVolumeOnChannel (Dcc.getCV(204)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss10delay=millis()+(long(Dcc.getCV(206)*MasterTimeConstant)); // Wait5 + ss10[4]=0; ss10[5]=1; + } + if ((ss10[5]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(208)); + setVolumeOnChannel (Dcc.getCV(207)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss10[5]=0; playing_sound_set[10]=false; + } +} // end loop() + +void set_servo (byte servonum, byte position) { + if (servo_pos[servonum].current_position == position) { + servo_pos[servonum].delta = 0; + servo_pos[servonum].target_position = position; + return; + } + if (servo_pos[servonum].current_position < position) servo_pos[servonum].delta = 1+servo_unit_faster; + else servo_pos[servonum].delta = -1-servo_unit_faster; + servo_pos[servonum].target_position = position; +} // end set_servo() + +void update_servos() { + servo_slow_counter = 1; + for (i=0; i<5; i++) { + if (servo_pos[i].delta != 0 ) { + servo_pos[i].current_position=servo_pos[i].current_position+servo_pos[i].delta; + if ((servo_pos[i].delta > 0)&&(servo_pos[i].current_position > servo_pos[i].target_position)) + { + servo_pos[i].current_position = servo_pos[i].target_position; + servo_pos[i].delta = 0; + } + if ((servo_pos[i].delta < 0)&&(servo_pos[i].current_position < servo_pos[i].target_position)) + { + servo_pos[i].current_position = servo_pos[i].target_position; + servo_pos[i].delta = 0; + } + if (servo_pos[i].current_position == servo_pos[i].target_position) servo_pos[i].delta = 0; + } + servo[i].write ( servo_pos[i].current_position ); + } +} // end update_servos() + +void playTrackOnChannel ( byte dtrack) { + if (dtrack!=255) {Player1.play(dtrack); delay(audiocmddelay); } + else {Player1.play(random(First_Track,Last_Track+1));} // delay(audiocmddelay); } +} +void setVolumeOnChannel ( byte dvolume) { + if(dvolume>30) return; // Don't change the volume if out of range + Player1.volume (dvolume); + delay(audiocmddelay); +} + +void notifyCVChange( uint16_t CV, uint8_t Value) { +#ifdef DEBUG + //Serial.print("CV= "); + //Serial.println(CV, DEC) ; + //Serial.print("Value= "); + //Serial.println(Value, DEC) ; +#endif + if (( CV > 145 )&&( CV < 176)) CV_load(); +} // end notifyCVChange() + +void CV_load( ) { + for (i=0; i<6; i++) { + Vs1[i]= Dcc.getCV(146+i); // if a CV changes update all the internals + Vs2[i]= Dcc.getCV(152+i); + Vs3[i]= Dcc.getCV(158+i); + Vs4[i]= Dcc.getCV(164+i); + Vs5[i]= Dcc.getCV(170+i); + Ls1[i]= Dcc.getCV(176+i); + Ls2[i]= Dcc.getCV(182+i); + Ls3[i]= Dcc.getCV(188+i); + Ls4[i]= Dcc.getCV(194+i); + Ls5[i]= Dcc.getCV(200+i); + } +} // end CV_load() + +void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { +#ifdef DEBUG + //Serial.print("Addr= "); + //Serial.println(Addr, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch(FuncGrp) + { + case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1 + exec_function( 0, FunctionPin0, (FuncState & FN_BIT_00)>>4 ); + exec_function( 1, FunctionPin1, (FuncState & FN_BIT_01)); + exec_function( 2, FunctionPin2, (FuncState & FN_BIT_02)>>1); + exec_function( 3, FunctionPin3, (FuncState & FN_BIT_03)>>2 ); + exec_function( 4, FunctionPin4, (FuncState & FN_BIT_04)>>3 ); + break; + case FN_5_8: //Function Group 1 S FFFF == 1 F8 F7 F6 F5 & == 0 F12 F11 F10 F9 F8 + exec_function( 5, FunctionPin5, (FuncState & FN_BIT_05)); + exec_function( 6, FunctionPin6, (FuncState & FN_BIT_06)>>1 ); + exec_function( 7, FunctionPin7, (FuncState & FN_BIT_07)>>2 ); + exec_function( 8, FunctionPin8, (FuncState & FN_BIT_08)>>3 ); + break; + + case FN_9_12: + exec_function( 9, FunctionPin9, (FuncState & FN_BIT_09)); + exec_function( 10, FunctionPin10, (FuncState & FN_BIT_10)>>1 ); + //exec_function( 11, FunctionPin11, (FuncState & FN_BIT_11)>>2 ); + //exec_function( 12, FunctionPin12, (FuncState & FN_BIT_12)>>3 ); + break; + case FN_13_20: //Function Group 2 FuncState == F20-F13 Function Control + //exec_function( 13, FunctionPin13, (FuncState & FN_BIT_13)); + //exec_function( 14, FunctionPin14, (FuncState & FN_BIT_14)>>1 ); + //exec_function( 15, FunctionPin15, (FuncState & FN_BIT_15)>>2 ); + //exec_function( 16, FunctionPin16, (FuncState & FN_BIT_16)>>3 ); + break; + + case FN_21_28: + break; + } +} // end notifyDccFunc +void exec_function (int function, int pin, int FuncState) { +#ifdef DEBUG + //Serial.print("ex function= "); + //Serial.println(function, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch ( Dcc.getCV( 30+function) ) { // Config + case 0: // Master Disable + Function0_value = byte(FuncState); + break; + case 1: // play sound set [ function ] + + case 2: // play sound set [ function ] + + case 3: // play sound set [ function ] + + case 4: // play sound set [ function ] + + case 5: // play sound set [ function ] + + case 6: // play sound set [ function ] + + case 7: // play sound set [ function ] + + case 8: // play sound set [ function ] + + case 9: // play sound set [ function ] + + case 10: // play sound set [ function ] + function_value[function] = byte(FuncState); + break; + case 11: // + default: + break;; + } +} // end exec_function + +/* DFPlayer Commands +//----Set volume---- + myDFPlayer.volume(10); //Set volume value (0~30). + myDFPlayer.volumeUp(); //Volume Up + myDFPlayer.volumeDown(); //Volume Down + //----Set different EQ---- + myDFPlayer.EQ(DFPLAYER_EQ_NORMAL); +// myDFPlayer.EQ(DFPLAYER_EQ_POP); +// myDFPlayer.EQ(DFPLAYER_EQ_ROCK); +// myDFPlayer.EQ(DFPLAYER_EQ_JAZZ); +// myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC); +// myDFPlayer.EQ(DFPLAYER_EQ_BASS); + //----Set device we use SD as default---- +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_U_DISK); + myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_AUX); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_SLEEP); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_FLASH); + //----Mp3 control---- +// myDFPlayer.sleep(); //sleep +// myDFPlayer.reset(); //Reset the module +// myDFPlayer.enableDAC(); //Enable On-chip DAC +// myDFPlayer.disableDAC(); //Disable On-chip DAC +// myDFPlayer.outputSetting(true, 15); //output setting, enable the output and set the gain to 15 + //----Mp3 play---- + myDFPlayer.next(); //Play next mp3 + myDFPlayer.previous(); //Play previous mp3 + myDFPlayer.play(1); //Play the first mp3 + myDFPlayer.loop(1); //Loop the first mp3 + myDFPlayer.pause(); //pause the mp3 + myDFPlayer.start(); //start the mp3 from the pause + myDFPlayer.playFolder(15, 4); //play specific mp3 in SD:/15/004.mp3; Folder Name(1~99); File Name(1~255) + myDFPlayer.enableLoopAll(); //loop all mp3 files. + myDFPlayer.disableLoopAll(); //stop loop all mp3 files. + myDFPlayer.playMp3Folder(4); //play specific mp3 in SD:/MP3/0004.mp3; File Name(0~65535) + myDFPlayer.advertise(3); //advertise specific mp3 in SD:/ADVERT/0003.mp3; File Name(0~65535) + myDFPlayer.stopAdvertise(); //stop advertise + myDFPlayer.playLargeFolder(2, 999); //play specific mp3 in SD:/02/004.mp3; Folder Name(1~10); File Name(1~1000) + myDFPlayer.loopFolder(5); //loop all mp3 files in folder SD:/05. + myDFPlayer.randomAll(); //Random play all the mp3. + myDFPlayer.enableLoop(); //enable loop. + myDFPlayer.disableLoop(); //disable loop. +*/ diff --git a/examples/IDECDemo&Diags/IDEC4_4_ServosCVBell_Demo3B/IDEC4_4_ServosCVBell_Demo3B.ino b/examples/IDECDemo&Diags/IDEC4_4_ServosCVBell_Demo3B/IDEC4_4_ServosCVBell_Demo3B.ino new file mode 100644 index 0000000..bdd407c --- /dev/null +++ b/examples/IDECDemo&Diags/IDEC4_4_ServosCVBell_Demo3B/IDEC4_4_ServosCVBell_Demo3B.ino @@ -0,0 +1,1213 @@ +// Switched Pins Servos, LEDs Sounds Variable Slow Servvo Travel IDEC4_4_ServosLEDsSoundsCV.ino +// Servo Positions and LED controls set by CV dynamically +// Version 1.08 Geoff Bunza 2020 +// 5 Functions and Switched Inputs Plays Sound Sets 1-5 stepped with Leds 1-5 and Servos 1-5 +// F0 Master Decoder Disable Function Turn Function ON to disable the decoder +// F1-F5 and Switched Inputs Plays Sound Sets 1-5 stepped with Leds 1-5 and Servos 1-5 +// F6 Plays Sound Sets 6 +// Master Disable Function Turn Function ON to disable the decoder +// Works with both short and long DCC Addesses +// Config 0=DISABLE On/Off,1-16=Sound Set Control 1-6 + +/* +PRO MINI PIN ASSIGNMENT: +2 - DCC Input +3 - Input Pin Channel Switch1 & Function1 +4 - Input Pin Channel Switch2 & Function2 +5 - Input Pin Channel Switch3 & Function3 +6 - Input Pin Channel Switch4 & Function4 +7 - Input Pin Channel Switch5 & Function5 +8 - Servo Pin Channel 1 +9 - LED Pin Channel 1 +10 - Servo Pin Channel 2 +11 - LED Pin Channel 2 +12 - Servo Pin Channel 3 +13 - LED Pin Channel 3 +14 A0 - Servo Pin Channel 4 +15 A1 - (TX) connected to DFPlayer1 Receive (RX) Pin 2 via 1K Ohm 1/4W Resistor +16 A2 - Input Pin for MasterDecoderDisable Active LOW & F0 +17 A3 - LED Pin Channel 4 +18 A4 - Servo Pin Channel 5 +19 A5 - LED Pin Channel 5 +*/ +// ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP +// ******** AFTER THE INITIAL DECODER LOAD REMOVE THE "//" IN THE FOOLOWING LINE!! +//#define DECODER_LOADED + +// ******** REMOVE THE "//" IN THE FOOLOWING LINE TO SEND DEBUGGING +// ******** INFO TO THE SERIAL MONITOR +//#define DEBUG + +#include +#include +#include +#include +SoftwareSerial DFSerial1(22,15); // PRO MINI RX, PRO MINI TX serial to DFPlayer +DFRobotDFPlayerMini Player1; + +SoftwareServo servo[5]; + +#define This_Decoder_Address 24 +uint8_t CV_DECODER_MASTER_RESET = 252; + +//Uncomment ONLY ONE of the following: +//#define MasterTimeConstant 10L // 10's of milliseconds Timing +#define MasterTimeConstant 100L // Tenths of a second Timing +//#define MasterTimeConstant 1000L // Seconds Timing +//#define MasterTimeConstant 10000L // 10's of Seconds Timing +//#define MasterTimeConstant 60000L // Minutes Timing +//#define MasterTimeConstant 3600000L // Hours Timing + +uint16_t ttemp, i; +#define First_Track 1 // Play Random Tracks First_Track#=Start_Track >=1 +#define Last_Track 12 // Play Random Tracks Last_Track= Last Playable Track in Range <= Last Numbered Track +#define starting_volume 21 // If no volume is set use this at the start +const int audiocmddelay = 34; + +#define servo_master_slowdown 9 //servo loop counter limit +int servo_slow_counter = 1; //servo loop counter to slowdown servo transit +byte servo_unit_faster = 0; + + // Vsx and Lsx are all loaded from CVs +byte ss1[] = {0,0,0,0,0,0}; unsigned long ss1delay=0; // Time state variabler for the set +byte Ls1[] = {1,0,1,0,1,0}; // LED states set by CV_load()at setup() +byte Vs1[] = {0,0,0,0,0,0}; // Servo Positions set by CV_load()at setup() +byte ss2[] = {0,0,0,0,0,0}; unsigned long ss2delay=0; // Time state variabler for the set +byte Ls2[] = {1,1,1,1,1,0}; // LED states set by CV_load()at setup() +byte Vs2[] = {0,0,0,0,0,0}; // Servo Positions set by CV_load()at setup() +byte ss3[] = {0,0,0,0,0,0}; unsigned long ss3delay=0; // Time state variabler for the set +byte Ls3[] = {0,0,1,1,1,0}; // LED states set by CV_load()at setup() +byte Vs3[] = {0,0,0,0,0,0}; // Servo Positions set by CV_load()at setup() +byte ss4[] = {0,0,0,0,0,0}; unsigned long ss4delay=0; // Time state variabler for the set +byte Ls4[] = {1,0,0,0,0,1}; // LED states set by CV_load()at setup() +byte Vs4[] = {0,0,0,0,0,0}; // Servo Positions set by CV_load()at setup() +byte ss5[] = {0,0,0,0,0,0}; unsigned long ss5delay=0; // Time state variabler for the set +byte Ls5[] = {0,1,1,1,1,0}; // LED states set by CV_load()at setup() +byte Vs5[] = {0,0,0,0,0,0}; // Servo Positions set by CV_load()at setup() +byte ss6[] = {0,0,0,0,0,0}; unsigned long ss6delay=0; // Time state variabler for the set +byte ss7[] = {0,0,0,0,0,0}; unsigned long ss7delay=0; // Time state variabler for the set +byte ss8[] = {0,0,0,0,0,0}; unsigned long ss8delay=0; // Time state variabler for the set +byte ss9[] = {0,0,0,0,0,0}; unsigned long ss9delay=0; // Time state variabler for the set +byte ss10[] = {0,0,0,0,0,0}; unsigned long ss10delay=0; // Time state variabler for the set +bool playing_sound_set [ ] = {false,false,false,false,false,false,false,false,false,false,false}; +byte soundset_channel[ ]={0,0,0,0,0,0,0,0,0,0,0}; +byte Vs_pins[] = {8,10,12,14,18}; //Servo pins per channel starting with 1 +byte Ls_pins[] = {0,13,11,9,17,19}; // LED pins per channel starting with 1 + +struct SERVO_TRACKING +{ + byte current_position; + byte target_position; + char delta; +}; +SERVO_TRACKING *servo_pos = new SERVO_TRACKING[5]; + +const int MasterDecoderDisablePin = 16; // D16/A0 Master Decoder Disable Input Pin Active LOW + +const int numINpins = 6; // Number of INput pins to initialize +byte inputpins [] = {3,4,5,6,7,16}; //These are all the Input Pins +const int numfpins = 10; // Number of Output pins to initialize +const int num_active_functions = 11; // Number of Functions stating with F0 +byte fpins [] = {8,9,10,11,12,13,14,17,18,19}; //These are all the Output Pins (first 15 is placeholder) +const int FunctionPin0 = 20; // Place holders ONLY +const int FunctionPin1 = 20; // Channel 1 +const int FunctionPin2 = 20; // Channel 2 +const int FunctionPin3 = 20; // Channel 3 +const int FunctionPin4 = 20; // Channel 4 +const int FunctionPin5 = 20; // Channel 5 +const int FunctionPin6 = 20; // Channel 6 +const int FunctionPin7 = 20; // Channel 7 +const int FunctionPin8 = 20; // Channel 8 +const int FunctionPin9 = 20; // Place holders ONLY +const int FunctionPin10 = 20; // Place holders ONLY +const int FunctionPin11 = 20; // Place holders ONLY +int MasterDecoderDisable = 0; +int Function0_value = 0; +byte function_value [ ] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +uint8_t cv_value; + +NmraDcc Dcc ; +DCC_MSG Packet ; +int t; // temp +struct QUEUE +{ + int inuse; + int current_position; + int increment; + int stop_value; + int start_value; +}; +QUEUE *ftn_queue = new QUEUE[17]; + +struct CVPair +{ + uint16_t CV; + uint8_t Value; +}; +CVPair FactoryDefaultCVs [] = +{ + {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address&0x7F }, + + // These two CVs define the Long DCC Address + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, ((This_Decoder_Address>>8)&0x7F)+192 }, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address&0xFF }, + + // ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS +// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps + {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps +// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps + {CV_DECODER_MASTER_RESET, 0}, + + {30, 0}, //F0 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + + {31, 1}, //F1 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {32, 2}, //F2 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {33, 3}, //F3 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {34, 4}, //F4 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {35, 5}, //F5 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {36, 6}, //F6 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {37, 7}, //F7 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {38, 8}, //F8 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {39, 9}, //F9 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {40, 10}, //F10 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + + {41, 22}, //F11 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {42, 22}, //F12 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {43, 22}, //F13 Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {44, 22}, //F14Config 0=DISABLE On/Off,1-10=Sound Set Control 1-10,11=LED On/Off + {45, 22}, //F15 not used + + {50, 6}, // Wait1 0-254 0.1 Seconds // SOUND SET 1 + {51, 55}, // Volume1 0-30 >30 == no volume change + {52, 13}, // Sound Clip1 + {53, 13}, // Wait2 0-254 0.1 Seconds + {54, 55}, // Volume2 0-30 >30 == no volume change + {55, 13}, // Sound Clip2 + {56, 13}, // Wait3 0-254 0.1 Seconds + {57, 55}, // Volume3 0-30 >30 == no volume change + {58, 13}, // Sound Clip3 + {59, 13}, // Wait4 0-254 0.1 Seconds + {60, 55}, // Volume4 0-30 >30 == no volume change + {61, 13}, // Sound Clip4 + {62, 8}, // Wait5 0-254 0.1 Seconds + {63, 55}, // Volume5 0-30 >30 == no volume change + {64, 0}, // Sound Clip5 + {65, 0}, // Sound Set Channel == LSB 0/1 + + {66, 2}, // Wait1 0-254 0.1 Seconds // SOUND SET 2 + {67, 20}, // Volume1 0-30 >30 == no volume change + {68, 4}, // Sound Clip1 + {69, 6}, // Wait2 0-254 0.1 Seconds + {70, 20}, // Volume2 0-30 >30 == no volume change + {71, 5}, // Sound Clip2 + {72, 6}, // Wait3 0-254 0.1 Seconds + {73, 20}, // Volume3 0-30 >30 == no volume change + {74, 6}, // Sound Clip3 + {75, 6}, // Wait4 0-254 0.1 Seconds + {76, 20}, // Volume4 0-30 >30 == no volume change + {77, 7}, // Sound Clip4 + {78, 6}, // Wait5 0-254 0.1 Seconds + {79, 20}, // Volume5 0-30 >30 == no volume change + {80, 8}, // Sound Clip5 + {81, 1}, // Sound Set Channel == LSB 0/1 + + {82, 1}, // Wait1 0-254 0.1 Seconds // SOUND SET 3 + {83, 20}, // Volume1 0-30 >30 == no volume change + {84, 5}, // Sound Clip1 + {85, 6}, // Wait2 0-254 0.1 Seconds + {86, 20}, // Volume2 0-30 >30 == no volume change + {87, 6}, // Sound Clip2 + {88, 6}, // Wait3 0-254 0.1 Seconds + {89, 20}, // Volume3 0-30 >30 == no volume change + {90, 7}, // Sound Clip3 + {91, 6}, // Wait4 0-254 0.1 Seconds + {92, 20}, // Volume4 0-30 >30 == no volume change + {93, 8}, // Sound Clip4 + {94, 6}, // Wait5 0-254 0.1 Seconds + {95, 20}, // Volume5 0-30 >30 == no volume change + {96, 8}, // Sound Clip5 + {97, 0}, // Sound Set Channel == LSB 0/1 + + {98, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 4 + {99, 23}, // Volume1 0-30 >30 == no volume change + {100, 9}, // Sound Clip1 + {101,110}, // Wait2 0-254 0.1 Seconds + {102, 99}, // Volume2 0-30 >30 == no volume change + {103, 0}, // Sound Clip2 + {104, 0}, // Wait3 0-254 0.1 Seconds + {105, 20}, // Volume3 0-30 >30 == no volume change + {106, 0}, // Sound Clip3 + {107, 0}, // Wait4 0-254 0.1 Seconds + {108, 99}, // Volume4 0-30 >30 == no volume change + {109, 0}, // Sound Clip4 + {110, 0}, // Wait5 0-254 0.1 Seconds + {111, 99}, // Volume5 0-30 >30 == no volume change + {112, 0}, // Sound Clip5 + {113, 0}, // Sound Set Channel == LSB 0/1 + + {114, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 5 + {115, 20}, // Volume1 0-30 >30 == no volume change + {116, 1}, // Sound Clip1 + {117, 20}, // Wait2 0-254 0.1 Seconds + {118, 20}, // Volume2 0-30 >30 == no volume change + {119, 2}, // Sound Clip2 + {120, 30}, // Wait3 0-254 0.1 Seconds + {121, 20}, // Volume3 0-30 >30 == no volume change + {122, 3}, // Sound Clip3 + {123, 50}, // Wait4 0-254 0.1 Seconds + {124, 20}, // Volume4 0-30 >30 == no volume change + {125, 4}, // Sound Clip4 + {126, 100}, // Wait5 0-254 0.1 Seconds + {127, 20}, // Volume5 0-30 >30 == no volume change + {128, 5}, // Sound Clip5 + {129, 0}, // Sound Set Channel == LSB 0/1 + + {130, 0}, // Wait1 0-254 0.1 Seconds // SOUND SET 6 + {131, 20}, // Volume1 0-30 >30 == no volume change + {132, 1}, // Sound Clip1 + {133, 20}, // Wait2 0-254 0.1 Seconds + {134, 20}, // Volume2 0-30 >30 == no volume change + {135, 2}, // Sound Clip2 + {136, 30}, // Wait3 0-254 0.1 Seconds + {137, 20}, // Volume3 0-30 >30 == no volume change + {138, 3}, // Sound Clip3 + {139, 50}, // Wait4 0-254 0.1 Seconds + {140, 20}, // Volume4 0-30 >30 == no volume change + {141, 4}, // Sound Clip4 + {142, 100}, // Wait5 0-254 0.1 Seconds + {143, 20}, // Volume5 0-30 >30 == no volume change + {144, 5}, // Sound Clip5 + {145, 1}, // Sound Set Channel == LSB 0/1 + // ================================================ + {146, 140}, // Servo Set 1 140,40,140,40,140,90 + {147, 50}, // + {148, 140}, // + {149, 50}, // + {150, 140}, // + {151, 90}, // + + {152, 40}, // Servo Set 2 40,60,90,120,150,30 + {153, 60}, // + {154, 90}, // + {155, 120}, // + {156, 150}, // + {157, 30}, // + + {158, 30}, // Servo Set 3 30,60,90,120,150,30 + {159, 60}, // + {160, 90}, // + {161, 120}, // + {162, 150}, // + {163, 30}, // + + {164, 30}, // Servo Set 4 30,60,90,120,150,30 + {165, 60}, // + {166, 90}, // + {167, 120}, // + {168, 150}, // + {169, 30}, // + + {170, 30}, // Servo Set 5 30,50,90,120,150,30 + {171, 50}, // + {172, 90}, // + {173, 120}, // + {174, 150}, // + {175, 30}, // + + {176, 1}, // LED Set 1 1,0,1,0,1,0 + {177, 0}, // + {178, 1}, // + {179, 0}, // + {180, 1}, // + {181, 0}, // + + {182, 1}, // LED Set 2 1,1,1,1,1,0 + {183, 1}, // + {184, 1}, // + {185, 1}, // + {186, 1}, // + {187, 0}, // + + {188, 1}, // LED Set 3 0,0,1,1,1,0 + {189, 0}, // + {190, 1}, // + {191, 0}, // + {192, 1}, // + {193, 0}, // + + {194, 1}, // LED Set 4 1,0,0,0,0,1 + {195, 0}, // + {196, 0}, // + {197, 0}, // + {198, 0}, // + {199, 1}, // + + {200, 0}, // LED Set 5 0,1,1,1,1,0 + {201, 1}, // + {202, 1}, // + {203, 1}, // + {204, 1}, // + {205, 0}, // + + {206, 0}, // Extra + //252,252 CV_DECODER_MASTER_RESET +}; + +uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +void notifyCVResetFactoryDefault() +{ + // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset + // to flag to the loop() function that a reset to Factory Defaults needs to be done + FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); +}; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS + +void setup() //****************************************************** +{ +#ifdef DEBUG + Serial.begin(115200); +#endif + DFSerial1.begin (9600); + Player1.begin (DFSerial1); + + // initialize the digital pins as outputs + for (int i=0; i < numfpins; i++) { + pinMode(fpins[i], OUTPUT); + digitalWrite(fpins[i], 0); // All OUPUT pins initialized LOW + } + CV_load( ); // Load all relevant CVs + //Set up servos + for (i=0; i<5; i++) { + servo[i].attach(Vs_pins[i]); // Start Servos + //for (t=0; t<180; t++) SoftwareServo::refresh(); + } + servo[0].write(Vs1[5]); // Set Servos Initial positions + SoftwareServo::refresh(); + servo_pos[0].current_position = Vs1[5]; + servo[1].write(Vs2[5]); + SoftwareServo::refresh(); + servo_pos[1].current_position = Vs2[5]; + servo[2].write(Vs3[5]); + SoftwareServo::refresh(); + servo_pos[2].current_position = Vs3[5]; + servo[3].write(Vs4[5]); + SoftwareServo::refresh(); + servo_pos[3].current_position = Vs4[5]; + servo[4].write(Vs5[5]); + SoftwareServo::refresh(); + servo_pos[4].current_position = Vs5[5]; + for (i=0; i<5; i++) servo_pos[i].delta = 0; + + pinMode (MasterDecoderDisablePin,INPUT_PULLUP); // Master Decoder Disable Input Pin Active LOW + + // initialize the digital pins as inputs + for (int i=0; i < numINpins; i++) { + pinMode ( inputpins[i], INPUT_PULLUP ); + } + // Setup which External Interrupt, the Pin it's associated with that we're using + Dcc.pin(0, 2, 0); + // Call the main DCC Init function to enable the DCC Receiver + Dcc.init( MAN_ID_DIY, 61, FLAGS_MY_ADDRESS_ONLY, 0 ); + delay(800); +#if defined(DECODER_LOADED) + if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET ) +#endif + { + for (int j=0; j < FactoryDefaultCVIndex; j++ ) + Dcc.setCV( FactoryDefaultCVs[j].CV, FactoryDefaultCVs[j].Value); + } + // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + setVolumeOnChannel (starting_volume); +#ifdef DEBUG + Serial.println("CV Dump:"); + for (i=30; i<45; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=30; i<45; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 1"); + for (i=50; i<66; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=50; i<66; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 2"); + for (i=66; i<82; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=66; i<82; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 3"); + for (i=82; i<98; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=82; i<98; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 4"); + for (i=98; i<114; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=98; i<114; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 5"); + for (i=114; i<130; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=114; i<130; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Sound Set 6"); + for (i=130; i<146; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=130; i<146; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Servo Set 1"); + for (i=146; i<152; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=146; i<152; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Servo Set 2"); + for (i=152; i<158; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=152; i<158; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Servo Set 3"); + for (i=158; i<164; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=158; i<164; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Servo Set 4"); + for (i=164; i<170; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=164; i<170; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("Servo Set 5"); + for (i=170; i<176; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=170; i<176; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("LED Set 1"); + for (i=176; i<182; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=176; i<182; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("LED Set 2"); + for (i=182; i<188; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=182; i<188; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("LED Set 3"); + for (i=188; i<194; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=188; i<194; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("LED Set 4"); + for (i=194; i<200; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=194; i<200; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } + Serial.println(""); + Serial.println("LED Set 5"); + for (i=200; i<206; i++) { Serial.print(i,DEC); Serial.print("\t"); } + Serial.println(""); + for (i=200; i<206; i++) { Serial.print(Dcc.getCV(i),DEC); Serial.print("\t"); } +#endif +} +void loop() //*********************************************************************************** +{ + //MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation + Dcc.process(); + SoftwareServo::refresh(); + if (servo_slow_counter > servo_master_slowdown) update_servos(); + else servo_slow_counter++; + delay(1); +// INPUT OVER RIDES + // Check Master Input Over ride + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + else MasterDecoderDisable = Function0_value & 1; + if (MasterDecoderDisable == 1) { + for (i=0; i < numfpins; i++) digitalWrite(fpins[i], 0); // All LEDs set LOW + } +// ******************************************************************************** + if (MasterDecoderDisable == 0) { + for (i=0; i < num_active_functions; i++) { + cv_value = Dcc.getCV(30+i) ; +#ifdef DEBUG + //Serial.print(" cv_value: "); + //Serial.println(cv_value, DEC) ; +#endif + switch ( cv_value ) { + case 0: // Master Decoder Disable + MasterDecoderDisable = 0; + if (digitalRead(MasterDecoderDisablePin)==LOW) MasterDecoderDisable = 1; + break; + case 1: // + if (((digitalRead(3)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss1[0]=1; + playing_sound_set[cv_value]=true; + } + break; + case 2: // + if (((digitalRead(4)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss2[0]=1; + digitalWrite( Ls_pins[2],Ls2[0]); + set_servo (1,Vs2[0]); + playing_sound_set[cv_value]=true; + } + break; + case 3: // + if (((digitalRead(5)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss3[0]=1; + digitalWrite( Ls_pins[3],Ls3[0]); + set_servo (2,Vs3[0]); + playing_sound_set[cv_value]=true; } + break; + case 4: // + if (((digitalRead(6)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss4[0]=1; + digitalWrite( Ls_pins[4],Ls4[0]); + set_servo (3,Vs4[0]); + playing_sound_set[cv_value]=true; } + break; + case 5: // + if (((digitalRead(7)==LOW)||(function_value[cv_value]==1)) && !playing_sound_set[cv_value]) { + ss5[0]=1; + digitalWrite( Ls_pins[5],Ls5[0]); + set_servo (4,Vs5[0]); + playing_sound_set[cv_value]=true; } + break; + case 6: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss6[0]=1; playing_sound_set[cv_value]=true; } + break; + case 7: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss7[0]=1; playing_sound_set[cv_value]=true; } + break; + case 8: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss8[0]=1; playing_sound_set[cv_value]=true; } + break; + case 9: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss9[0]=1; playing_sound_set[cv_value]=true; } + break; + case 10: // + if ((function_value[cv_value]==1) && !playing_sound_set[cv_value]) { + ss10[0]=1; playing_sound_set[cv_value]=true; } + break; + default: + break; + } + } + } + // ========================== Sound Set 1 Begin Play + if (ss1[0]==1) { + digitalWrite( Ls_pins[1],Ls1[0]); + set_servo (0,Vs1[0]); + ss1delay=millis()+(long(Dcc.getCV(50)*MasterTimeConstant)); // Wait1 + ss1[0]=0; ss1[1]=1; + } + if ((ss1[1]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(52)); + setVolumeOnChannel (Dcc.getCV(51)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss1delay=millis()+(long(Dcc.getCV(53)*MasterTimeConstant)); // Wait2 + ss1[1]=0; ss1[2]=1; digitalWrite( Ls_pins[1],Ls1[1]); + set_servo (0,Vs1[1]); + } + if ((ss1[2]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(55)); + setVolumeOnChannel (Dcc.getCV(54)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss1delay=millis()+(long(Dcc.getCV(56)*MasterTimeConstant)); // Wait3 + ss1[2]=0; ss1[3]=1; digitalWrite( Ls_pins[1],Ls1[2]); + set_servo (0,Vs1[2]); + } + if ((ss1[3]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(58)); + setVolumeOnChannel (Dcc.getCV(57)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss1delay=millis()+(long(Dcc.getCV(59)*MasterTimeConstant)); // Wait4 + ss1[3]=0; ss1[4]=1; digitalWrite( Ls_pins[1],Ls1[3]); + set_servo (0,Vs1[3]); + } + if ((ss1[4]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(61)); + setVolumeOnChannel (Dcc.getCV(60)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss1delay=millis()+(long(Dcc.getCV(62)*MasterTimeConstant)); // Wait5 + ss1[4]=0; ss1[5]=1; digitalWrite( Ls_pins[1],Ls1[4]); + set_servo (0,Vs1[4]); + } + if ((ss1[5]==1)&&(ss1delay<=millis())) { + ttemp=(Dcc.getCV(64)); + setVolumeOnChannel (Dcc.getCV(63)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss1[5]=0; digitalWrite( Ls_pins[1],Ls1[5]); + set_servo (0,Vs1[5]); + playing_sound_set[1]=false; + } +// ========================== Sound Set 2 Begin Play + if (ss2[0]==1) { + ss2delay=millis()+(long(Dcc.getCV(66)*MasterTimeConstant)); // Wait1 + ss2[0]=0; ss2[1]=1; + } + if ((ss2[1]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(68)); + setVolumeOnChannel (Dcc.getCV(67)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss2delay=millis()+(long(Dcc.getCV(69)*MasterTimeConstant)); // Wait2 + ss2[1]=0; ss2[2]=1; digitalWrite( Ls_pins[2],Ls2[1]); + set_servo (1,Vs2[1]); + } + if ((ss2[2]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(71)); + setVolumeOnChannel (Dcc.getCV(70)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss2delay=millis()+(long(Dcc.getCV(72)*MasterTimeConstant)); // Wait3 + ss2[2]=0; ss2[3]=1; digitalWrite( Ls_pins[2],Ls2[2]); + set_servo (1,Vs2[2]); + } + if ((ss2[3]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(74)); + setVolumeOnChannel (Dcc.getCV(73)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss2delay=millis()+(long(Dcc.getCV(75)*MasterTimeConstant)); // Wait4 + ss2[3]=0; ss2[4]=1; digitalWrite( Ls_pins[2],Ls2[3]); + set_servo (1,Vs2[3]); + } + if ((ss2[4]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(77)); + setVolumeOnChannel (Dcc.getCV(76)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss2delay=millis()+(long(Dcc.getCV(78)*MasterTimeConstant)); // Wait5 + ss2[4]=0; ss2[5]=1; digitalWrite( Ls_pins[2],Ls2[4]); + set_servo (1,Vs2[4]); + } + if ((ss2[5]==1)&&(ss2delay<=millis())) { + ttemp=(Dcc.getCV(80)); + setVolumeOnChannel (Dcc.getCV(79)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss2[5]=0; digitalWrite( Ls_pins[2],Ls2[5]); + set_servo (1,Vs2[5]); + playing_sound_set[2]=false; + } +// ========================== Sound Set 3 Begin Play + if (ss3[0]==1) { + ss3delay=millis()+(long(Dcc.getCV(82)*MasterTimeConstant)); // Wait1 + ss3[0]=0; ss3[1]=1; + } + if ((ss3[1]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(84)); + setVolumeOnChannel (Dcc.getCV(83)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss3delay=millis()+(long(Dcc.getCV(85)*MasterTimeConstant)); // Wait2 + ss3[1]=0; ss3[2]=1; digitalWrite( Ls_pins[3],Ls3[1]); + set_servo (2,Vs3[1]); + } + if ((ss3[2]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(87)); + setVolumeOnChannel (Dcc.getCV(86)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss3delay=millis()+(long(Dcc.getCV(88)*MasterTimeConstant)); // Wait3 + ss3[2]=0; ss3[3]=1; digitalWrite( Ls_pins[3],Ls3[2]); + set_servo (2,Vs3[2]); + } + if ((ss3[3]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(90)); + setVolumeOnChannel (Dcc.getCV(89)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss3delay=millis()+(long(Dcc.getCV(91)*MasterTimeConstant)); // Wait4 + ss3[3]=0; ss3[4]=1; digitalWrite( Ls_pins[3],Ls3[3]); + set_servo (2,Vs3[3]); + } + if ((ss3[4]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(93)); + setVolumeOnChannel (Dcc.getCV(92)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss3delay=millis()+(long(Dcc.getCV(94)*MasterTimeConstant)); // Wait5 + ss3[4]=0; ss3[5]=1; digitalWrite( Ls_pins[3],Ls3[4]); + set_servo (2,Vs3[4]); + } + if ((ss3[5]==1)&&(ss3delay<=millis())) { + ttemp=(Dcc.getCV(96)); + setVolumeOnChannel (Dcc.getCV(95)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss3[5]=0; digitalWrite( Ls_pins[3],Ls3[5]); + set_servo (2,Vs3[5]); + playing_sound_set[3]=false; + } +// ========================== Sound Set 4 Begin Play + if (ss4[0]==1) { + ss4delay=millis()+(long(Dcc.getCV(98)*MasterTimeConstant)); // Wait1 + ss4[0]=0; ss4[1]=1; + } + if ((ss4[1]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(100)); + setVolumeOnChannel (Dcc.getCV(99)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss4delay=millis()+(long(Dcc.getCV(101)*MasterTimeConstant)); // Wait2 + ss4[1]=0; ss4[2]=1; digitalWrite( Ls_pins[4],Ls4[1]); + set_servo (3,Vs4[1]); + } + if ((ss4[2]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(103)); + setVolumeOnChannel (Dcc.getCV(102)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss4delay=millis()+(long(Dcc.getCV(104)*MasterTimeConstant)); // Wait3 + ss4[2]=0; ss4[3]=1; digitalWrite( Ls_pins[4],Ls4[2]); + set_servo (3,Vs4[2]); + } + if ((ss4[3]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(106)); + setVolumeOnChannel (Dcc.getCV(105)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss4delay=millis()+(long(Dcc.getCV(107)*MasterTimeConstant)); // Wait4 + ss4[3]=0; ss4[4]=1; digitalWrite( Ls_pins[4],Ls4[3]); + set_servo (3,Vs4[3]); + } + if ((ss4[4]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(109)); + setVolumeOnChannel (Dcc.getCV(108)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss4delay=millis()+(long(Dcc.getCV(110)*MasterTimeConstant)); // Wait5 + ss4[4]=0; ss4[5]=1; digitalWrite( Ls_pins[4],Ls4[4]); + set_servo (3,Vs4[4]); + } + if ((ss4[5]==1)&&(ss4delay<=millis())) { + ttemp=(Dcc.getCV(112)); + setVolumeOnChannel (Dcc.getCV(111)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss4[5]=0; digitalWrite( Ls_pins[4],Ls4[5]); + set_servo (3,Vs4[5]); + playing_sound_set[4]=false; + } +// ========================== Sound Set 5 Begin Play + if (ss5[0]==1) { + ss5delay=millis()+(long(Dcc.getCV(114)*MasterTimeConstant)); // Wait1 + ss5[0]=0; ss5[1]=1; + } + if ((ss5[1]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(116)); + setVolumeOnChannel (Dcc.getCV(115)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss5delay=millis()+(long(Dcc.getCV(117)*MasterTimeConstant)); // Wait2 + ss5[1]=0; ss5[2]=1; digitalWrite( Ls_pins[5],Ls5[1]); + set_servo (4,Vs5[1]); + } + if ((ss5[2]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(119)); + setVolumeOnChannel (Dcc.getCV(118)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss5delay=millis()+(long(Dcc.getCV(120)*MasterTimeConstant)); // Wait3 + ss5[2]=0; ss5[3]=1; digitalWrite( Ls_pins[5],Ls5[2]); + set_servo (4,Vs5[2]); + } + if ((ss5[3]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(122)); + setVolumeOnChannel (Dcc.getCV(121)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss5delay=millis()+(long(Dcc.getCV(123)*MasterTimeConstant)); // Wait4 + ss5[3]=0; ss5[4]=1; digitalWrite( Ls_pins[5],Ls5[3]); + set_servo (4,Vs5[3]); + } + if ((ss5[4]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(125)); + setVolumeOnChannel (Dcc.getCV(124)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss5delay=millis()+(long(Dcc.getCV(126)*MasterTimeConstant)); // Wait5 + ss5[4]=0; ss5[5]=1; digitalWrite( Ls_pins[5],Ls5[4]); + set_servo (4,Vs5[4]); + } + if ((ss5[5]==1)&&(ss5delay<=millis())) { + ttemp=(Dcc.getCV(128)); + setVolumeOnChannel (Dcc.getCV(127)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss5[5]=0; digitalWrite( Ls_pins[5],Ls5[5]); + set_servo (4,Vs5[5]); + playing_sound_set[5]=false; + } + +// ========================== Sound Set 6 Begin Play + if (ss6[0]==1) { + ss6delay=millis()+(long(Dcc.getCV(130)*MasterTimeConstant)); // Wait1 + ss6[0]=0; ss6[1]=1; + } + if ((ss6[1]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(132)); + setVolumeOnChannel (Dcc.getCV(131)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss6delay=millis()+(long(Dcc.getCV(133)*MasterTimeConstant)); // Wait2 + ss6[1]=0; ss6[2]=1; + } + if ((ss6[2]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(135)); + setVolumeOnChannel (Dcc.getCV(134)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss6delay=millis()+(long(Dcc.getCV(136)*MasterTimeConstant)); // Wait3 + ss6[2]=0; ss6[3]=1; + } + if ((ss6[3]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(138)); + setVolumeOnChannel (Dcc.getCV(137)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss6delay=millis()+(long(Dcc.getCV(139)*MasterTimeConstant)); // Wait4 + ss6[3]=0; ss6[4]=1; + } + if ((ss6[4]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(141)); + setVolumeOnChannel (Dcc.getCV(140)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss6delay=millis()+(long(Dcc.getCV(142)*MasterTimeConstant)); // Wait5 + ss6[4]=0; ss6[5]=1; + } + if ((ss6[5]==1)&&(ss6delay<=millis())) { + ttemp=(Dcc.getCV(144)); + setVolumeOnChannel (Dcc.getCV(143)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss6[5]=0; playing_sound_set[6]=false; + } + +// ========================== Sound Set 7 Begin Play + if (ss7[0]==1) { + ss7delay=millis()+(long(Dcc.getCV(146)*MasterTimeConstant)); // Wait1 + ss7[0]=0; ss7[1]=1; + } + if ((ss7[1]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(148)); + setVolumeOnChannel (Dcc.getCV(147)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss7delay=millis()+(long(Dcc.getCV(149)*MasterTimeConstant)); // Wait2 + ss7[1]=0; ss7[2]=1; + } + if ((ss7[2]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(151)); + setVolumeOnChannel (Dcc.getCV(150)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss7delay=millis()+(long(Dcc.getCV(152)*MasterTimeConstant)); // Wait3 + ss7[2]=0; ss7[3]=1; + } + if ((ss7[3]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(154)); + setVolumeOnChannel (Dcc.getCV(153)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss7delay=millis()+(long(Dcc.getCV(155)*MasterTimeConstant)); // Wait4 + ss7[3]=0; ss7[4]=1; + } + if ((ss7[4]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(157)); + setVolumeOnChannel (Dcc.getCV(156)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss7delay=millis()+(long(Dcc.getCV(158)*MasterTimeConstant)); // Wait5 + ss7[4]=0; ss7[5]=1; + } + if ((ss7[5]==1)&&(ss7delay<=millis())) { + ttemp=(Dcc.getCV(160)); + setVolumeOnChannel (Dcc.getCV(159)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss7[5]=0; playing_sound_set[7]=false; + } +// ========================== Sound Set 8 Begin Play + if (ss8[0]==1) { + ss8delay=millis()+(long(Dcc.getCV(162)*MasterTimeConstant)); // Wait1 + ss8[0]=0; ss8[1]=1; + } + if ((ss8[1]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(164)); + setVolumeOnChannel (Dcc.getCV(163)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss8delay=millis()+(long(Dcc.getCV(165)*MasterTimeConstant)); // Wait2 + ss8[1]=0; ss8[2]=1; + } + if ((ss8[2]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(167)); + setVolumeOnChannel (Dcc.getCV(166)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss8delay=millis()+(long(Dcc.getCV(168)*MasterTimeConstant)); // Wait3 + ss8[2]=0; ss8[3]=1; + } + if ((ss8[3]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(170)); + setVolumeOnChannel (Dcc.getCV(169)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss8delay=millis()+(long(Dcc.getCV(171)*MasterTimeConstant)); // Wait4 + ss8[3]=0; ss8[4]=1; + } + if ((ss8[4]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(173)); + setVolumeOnChannel (Dcc.getCV(172)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss8delay=millis()+(long(Dcc.getCV(174)*MasterTimeConstant)); // Wait5 + ss8[4]=0; ss8[5]=1; + } + if ((ss8[5]==1)&&(ss8delay<=millis())) { + ttemp=(Dcc.getCV(176)); + setVolumeOnChannel (Dcc.getCV(175)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss8[5]=0; playing_sound_set[8]=false; + } +// ========================== Sound Set 9 Begin Play + if (ss9[0]==1) { + ss9delay=millis()+(long(Dcc.getCV(178)*MasterTimeConstant)); // Wait1 + ss9[0]=0; ss9[1]=1; + } + if ((ss9[1]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(180)); + setVolumeOnChannel (Dcc.getCV(179)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss9delay=millis()+(long(Dcc.getCV(181)*MasterTimeConstant)); // Wait2 + ss9[1]=0; ss9[2]=1; + } + if ((ss9[2]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(183)); + setVolumeOnChannel (Dcc.getCV(182)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss9delay=millis()+(long(Dcc.getCV(184)*MasterTimeConstant)); // Wait3 + ss9[2]=0; ss9[3]=1; + } + if ((ss9[3]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(186)); + setVolumeOnChannel (Dcc.getCV(185)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss9delay=millis()+(long(Dcc.getCV(187)*MasterTimeConstant)); // Wait4 + ss9[3]=0; ss9[4]=1; + } + if ((ss9[4]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(189)); + setVolumeOnChannel (Dcc.getCV(188)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss9delay=millis()+(long(Dcc.getCV(190)*MasterTimeConstant)); // Wait5 + ss9[4]=0; ss9[5]=1; + } + if ((ss9[5]==1)&&(ss9delay<=millis())) { + ttemp=(Dcc.getCV(192)); + setVolumeOnChannel (Dcc.getCV(191)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss9[5]=0; playing_sound_set[9]=false; + } +// ========================== Sound Set 10 Begin Play + if (ss10[0]==1) { + ss10delay=millis()+(long(Dcc.getCV(194)*MasterTimeConstant)); // Wait1 + ss10[0]=0; ss10[1]=1; + } + if ((ss10[1]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(196)); + setVolumeOnChannel (Dcc.getCV(195)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 1 + ss10delay=millis()+(long(Dcc.getCV(197)*MasterTimeConstant)); // Wait2 + ss10[1]=0; ss10[2]=1; + } + if ((ss10[2]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(199)); + setVolumeOnChannel (Dcc.getCV(198)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 2 + ss10delay=millis()+(long(Dcc.getCV(200)*MasterTimeConstant)); // Wait3 + ss10[2]=0; ss10[3]=1; + } + if ((ss10[3]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(202)); + setVolumeOnChannel (Dcc.getCV(201)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 3 + ss10delay=millis()+(long(Dcc.getCV(203)*MasterTimeConstant)); // Wait4 + ss10[3]=0; ss10[4]=1; + } + if ((ss10[4]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(205)); + setVolumeOnChannel (Dcc.getCV(204)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 4 + ss10delay=millis()+(long(Dcc.getCV(206)*MasterTimeConstant)); // Wait5 + ss10[4]=0; ss10[5]=1; + } + if ((ss10[5]==1)&&(ss10delay<=millis())) { + ttemp=(Dcc.getCV(208)); + setVolumeOnChannel (Dcc.getCV(207)); + if (ttemp!=0) playTrackOnChannel(ttemp); // play clip 5 + ss10[5]=0; playing_sound_set[10]=false; + } +} // end loop() + +void set_servo (byte servonum, byte position) { + if (servo_pos[servonum].current_position == position) { + servo_pos[servonum].delta = 0; + servo_pos[servonum].target_position = position; + return; + } + if (servo_pos[servonum].current_position < position) servo_pos[servonum].delta = 1+servo_unit_faster; + else servo_pos[servonum].delta = -1-servo_unit_faster; + servo_pos[servonum].target_position = position; +} // end set_servo() + +void update_servos() { + servo_slow_counter = 1; + for (i=0; i<5; i++) { + if (servo_pos[i].delta != 0 ) { + servo_pos[i].current_position=servo_pos[i].current_position+servo_pos[i].delta; + if ((servo_pos[i].delta > 0)&&(servo_pos[i].current_position > servo_pos[i].target_position)) + { + servo_pos[i].current_position = servo_pos[i].target_position; + servo_pos[i].delta = 0; + } + if ((servo_pos[i].delta < 0)&&(servo_pos[i].current_position < servo_pos[i].target_position)) + { + servo_pos[i].current_position = servo_pos[i].target_position; + servo_pos[i].delta = 0; + } + if (servo_pos[i].current_position == servo_pos[i].target_position) servo_pos[i].delta = 0; + } + servo[i].write ( servo_pos[i].current_position ); + } +} // end update_servos() + +void playTrackOnChannel ( byte dtrack) { + if (dtrack!=255) {Player1.play(dtrack); delay(audiocmddelay); } + else {Player1.play(random(First_Track,Last_Track+1));} // delay(audiocmddelay); } +} +void setVolumeOnChannel ( byte dvolume) { + if(dvolume>30) return; // Don't change the volume if out of range + Player1.volume (dvolume); + delay(audiocmddelay); +} + +void notifyCVChange( uint16_t CV, uint8_t Value) { +#ifdef DEBUG + //Serial.print("CV= "); + //Serial.println(CV, DEC) ; + //Serial.print("Value= "); + //Serial.println(Value, DEC) ; +#endif + if (( CV > 145 )&&( CV < 176)) CV_load(); +} // end notifyCVChange() + +void CV_load( ) { + for (i=0; i<6; i++) { + Vs1[i]= Dcc.getCV(146+i); // if a CV changes update all the internals + Vs2[i]= Dcc.getCV(152+i); + Vs3[i]= Dcc.getCV(158+i); + Vs4[i]= Dcc.getCV(164+i); + Vs5[i]= Dcc.getCV(170+i); + Ls1[i]= Dcc.getCV(176+i); + Ls2[i]= Dcc.getCV(182+i); + Ls3[i]= Dcc.getCV(188+i); + Ls4[i]= Dcc.getCV(194+i); + Ls5[i]= Dcc.getCV(200+i); + } +} // end CV_load() + +void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { +#ifdef DEBUG + //Serial.print("Addr= "); + //Serial.println(Addr, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch(FuncGrp) + { + case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1 + exec_function( 0, FunctionPin0, (FuncState & FN_BIT_00)>>4 ); + exec_function( 1, FunctionPin1, (FuncState & FN_BIT_01)); + exec_function( 2, FunctionPin2, (FuncState & FN_BIT_02)>>1); + exec_function( 3, FunctionPin3, (FuncState & FN_BIT_03)>>2 ); + exec_function( 4, FunctionPin4, (FuncState & FN_BIT_04)>>3 ); + break; + case FN_5_8: //Function Group 1 S FFFF == 1 F8 F7 F6 F5 & == 0 F12 F11 F10 F9 F8 + exec_function( 5, FunctionPin5, (FuncState & FN_BIT_05)); + exec_function( 6, FunctionPin6, (FuncState & FN_BIT_06)>>1 ); + exec_function( 7, FunctionPin7, (FuncState & FN_BIT_07)>>2 ); + exec_function( 8, FunctionPin8, (FuncState & FN_BIT_08)>>3 ); + break; + + case FN_9_12: + exec_function( 9, FunctionPin9, (FuncState & FN_BIT_09)); + exec_function( 10, FunctionPin10, (FuncState & FN_BIT_10)>>1 ); + //exec_function( 11, FunctionPin11, (FuncState & FN_BIT_11)>>2 ); + //exec_function( 12, FunctionPin12, (FuncState & FN_BIT_12)>>3 ); + break; + case FN_13_20: //Function Group 2 FuncState == F20-F13 Function Control + //exec_function( 13, FunctionPin13, (FuncState & FN_BIT_13)); + //exec_function( 14, FunctionPin14, (FuncState & FN_BIT_14)>>1 ); + //exec_function( 15, FunctionPin15, (FuncState & FN_BIT_15)>>2 ); + //exec_function( 16, FunctionPin16, (FuncState & FN_BIT_16)>>3 ); + break; + + case FN_21_28: + break; + } +} // end notifyDccFunc +void exec_function (int function, int pin, int FuncState) { +#ifdef DEBUG + //Serial.print("ex function= "); + //Serial.println(function, DEC) ; + //Serial.print("FuncState= "); + //Serial.println(FuncState, DEC) ; +#endif + switch ( Dcc.getCV( 30+function) ) { // Config + case 0: // Master Disable + Function0_value = byte(FuncState); + break; + case 1: // play sound set [ function ] + + case 2: // play sound set [ function ] + + case 3: // play sound set [ function ] + + case 4: // play sound set [ function ] + + case 5: // play sound set [ function ] + + case 6: // play sound set [ function ] + + case 7: // play sound set [ function ] + + case 8: // play sound set [ function ] + + case 9: // play sound set [ function ] + + case 10: // play sound set [ function ] + function_value[function] = byte(FuncState); + break; + case 11: // + default: + break;; + } +} // end exec_function + +/* DFPlayer Commands +//----Set volume---- + myDFPlayer.volume(10); //Set volume value (0~30). + myDFPlayer.volumeUp(); //Volume Up + myDFPlayer.volumeDown(); //Volume Down + //----Set different EQ---- + myDFPlayer.EQ(DFPLAYER_EQ_NORMAL); +// myDFPlayer.EQ(DFPLAYER_EQ_POP); +// myDFPlayer.EQ(DFPLAYER_EQ_ROCK); +// myDFPlayer.EQ(DFPLAYER_EQ_JAZZ); +// myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC); +// myDFPlayer.EQ(DFPLAYER_EQ_BASS); + //----Set device we use SD as default---- +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_U_DISK); + myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_AUX); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_SLEEP); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_FLASH); + //----Mp3 control---- +// myDFPlayer.sleep(); //sleep +// myDFPlayer.reset(); //Reset the module +// myDFPlayer.enableDAC(); //Enable On-chip DAC +// myDFPlayer.disableDAC(); //Disable On-chip DAC +// myDFPlayer.outputSetting(true, 15); //output setting, enable the output and set the gain to 15 + //----Mp3 play---- + myDFPlayer.next(); //Play next mp3 + myDFPlayer.previous(); //Play previous mp3 + myDFPlayer.play(1); //Play the first mp3 + myDFPlayer.loop(1); //Loop the first mp3 + myDFPlayer.pause(); //pause the mp3 + myDFPlayer.start(); //start the mp3 from the pause + myDFPlayer.playFolder(15, 4); //play specific mp3 in SD:/15/004.mp3; Folder Name(1~99); File Name(1~255) + myDFPlayer.enableLoopAll(); //loop all mp3 files. + myDFPlayer.disableLoopAll(); //stop loop all mp3 files. + myDFPlayer.playMp3Folder(4); //play specific mp3 in SD:/MP3/0004.mp3; File Name(0~65535) + myDFPlayer.advertise(3); //advertise specific mp3 in SD:/ADVERT/0003.mp3; File Name(0~65535) + myDFPlayer.stopAdvertise(); //stop advertise + myDFPlayer.playLargeFolder(2, 999); //play specific mp3 in SD:/02/004.mp3; Folder Name(1~10); File Name(1~1000) + myDFPlayer.loopFolder(5); //loop all mp3 files in folder SD:/05. + myDFPlayer.randomAll(); //Random play all the mp3. + myDFPlayer.enableLoop(); //enable loop. + myDFPlayer.disableLoop(); //disable loop. +*/ diff --git a/examples/IDECDemo&Diags/IDECServoTestPin8/ServoTestPin8.ino b/examples/IDECDemo&Diags/IDECServoTestPin8/ServoTestPin8.ino new file mode 100644 index 0000000..69bbcd8 --- /dev/null +++ b/examples/IDECDemo&Diags/IDECServoTestPin8/ServoTestPin8.ino @@ -0,0 +1,32 @@ +/* Sweep + by BARRAGAN + This example code is in the public domain. + + modified 8 Nov 2013 + by Scott Fitzgerald + http://www.arduino.cc/en/Tutorial/Sweep +*/ + +#include + +Servo myservo; // create servo object to control a servo +// twelve servo objects can be created on most boards + +int pos = 0; // variable to store the servo position + +void setup() { + myservo.attach(8); // attaches the servo on pin 9 to the servo object +} + +void loop() { + for (pos = 50; pos <= 140; pos += 1) { // goes from 0 degrees to 180 degrees + // in steps of 1 degree + myservo.write(pos); // tell servo to go to position in variable 'pos' + delay(15); // waits 15ms for the servo to reach the position + } + for (pos = 140; pos >= 50; pos -= 1) { // goes from 180 degrees to 0 degrees + myservo.write(pos); // tell servo to go to position in variable 'pos' + delay(15); // waits 15ms for the servo to reach the position + } + delay(12000); +} diff --git a/examples/IDECDemo&Diags/IDEC_Sound_Test/IDEC9_Sound_Test.ino b/examples/IDECDemo&Diags/IDEC_Sound_Test/IDEC9_Sound_Test.ino new file mode 100644 index 0000000..64c2e37 --- /dev/null +++ b/examples/IDECDemo&Diags/IDEC_Sound_Test/IDEC9_Sound_Test.ino @@ -0,0 +1,92 @@ +// Interactive Decoder Sound Test IDEC9_Sound_Test.ino +// Version 1.08 Geoff Bunza 2020 +/* + * Copyright: DFRobot + * name: DFPlayer_Mini_Mp3 sample code + * Author: lisper + * Date: 2014-05-30 + * Description: connect DFPlayer Mini by SoftwareSerial, this code is test on Uno + * Note: the mp3 files must put into mp3 folder in your tf card + */ +// ******** EMOVE THE "//" IN THE FOOLOWING LINE TO SEND DEBUGGING +// ******** INFO TO THE SERIAL MONITOR +#define DEBUG +#include +#include + +//15 A1 - DFPlayer1 Receive (RX) Pin 2 via 470 Ohm Resistor +SoftwareSerial DFSerial1(22,11); // PRO MINI RX, PRO MINI TX serial to DFPlayer +DFRobotDFPlayerMini Player1; + +#define Max_Num_Tracks_On_SDCard 12 +const int audiocmddelay = 40; +void setup () { + //pinMode(8,INPUT_PULLUP); +#ifdef DEBUG + Serial.begin(115200); +#endif + DFSerial1.begin (9600); + Player1.begin (DFSerial1); + Player1.reset (); + delay(1000); + Player1.volume (21); + delay(audiocmddelay); +} // end setup() + +int delta = 1500; +int track = 1; +void loop () { + for (int i=1; i<=Max_Num_Tracks_On_SDCard; i++) { + Player1.play (i); +#ifdef DEBUG + Serial.print("Playing Track "); + Serial.println(i); +#endif + delay(2000); + } +delay (6000); +} // end loop () + +/* DFPlayer Commands +//----Set volume---- + myDFPlayer.volume(10); //Set volume value (0~30). + myDFPlayer.volumeUp(); //Volume Up + myDFPlayer.volumeDown(); //Volume Down + //----Set different EQ---- + myDFPlayer.EQ(DFPLAYER_EQ_NORMAL); +// myDFPlayer.EQ(DFPLAYER_EQ_POP); +// myDFPlayer.EQ(DFPLAYER_EQ_ROCK); +// myDFPlayer.EQ(DFPLAYER_EQ_JAZZ); +// myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC); +// myDFPlayer.EQ(DFPLAYER_EQ_BASS); + //----Set device we use SD as default---- +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_U_DISK); + myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_AUX); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_SLEEP); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_FLASH); + //----Mp3 control---- +// myDFPlayer.sleep(); //sleep +// myDFPlayer.reset(); //Reset the module +// myDFPlayer.enableDAC(); //Enable On-chip DAC +// myDFPlayer.disableDAC(); //Disable On-chip DAC +// myDFPlayer.outputSetting(true, 15); //output setting, enable the output and set the gain to 15 + //----Mp3 play---- + myDFPlayer.next(); //Play next mp3 + myDFPlayer.previous(); //Play previous mp3 + myDFPlayer.play(1); //Play the first mp3 + myDFPlayer.loop(1); //Loop the first mp3 + myDFPlayer.pause(); //pause the mp3 + myDFPlayer.start(); //start the mp3 from the pause + myDFPlayer.playFolder(15, 4); //play specific mp3 in SD:/15/004.mp3; Folder Name(1~99); File Name(1~255) + myDFPlayer.enableLoopAll(); //loop all mp3 files. + myDFPlayer.disableLoopAll(); //stop loop all mp3 files. + myDFPlayer.playMp3Folder(4); //play specific mp3 in SD:/MP3/0004.mp3; File Name(0~65535) + myDFPlayer.advertise(3); //advertise specific mp3 in SD:/ADVERT/0003.mp3; File Name(0~65535) + myDFPlayer.stopAdvertise(); //stop advertise + myDFPlayer.playLargeFolder(2, 999); //play specific mp3 in SD:/02/004.mp3; Folder Name(1~10); File Name(1~1000) + myDFPlayer.loopFolder(5); //loop all mp3 files in folder SD:/05. + myDFPlayer.randomAll(); //Random play all the mp3. + myDFPlayer.enableLoop(); //enable loop. + myDFPlayer.disableLoop(); //disable loop. +*/