From c2de60b8cb92eda1467079beba73fc323b8b4b51 Mon Sep 17 00:00:00 2001 From: Geoff Bunza Date: Thu, 5 Jul 2018 15:18:48 -0700 Subject: [PATCH 1/7] Add files via upload --- .../AccDec_10Servos_7LED_6Ftn.ino | 65 +- .../AccDec_13Servos_4LED_6Ftn.ino | 50 +- .../AccDec_15Servos_2LED_6Ftn.ino | 51 +- .../AccDec_17LED_1Ftn/AccDec_17LED_1Ftn.ino | 43 +- .../AccDec_17LED_6Ftn/AccDec_17LED_6Ftn.ino | 60 +- .../AccDec_7ServoBackandForth6Ftn.ino | 39 +- .../AccDec_7Servos_10LED_6Ftn.ino | 79 +- .../Dec_10Serv_7LED_6Ftn.ino | 53 +- .../Dec_13Serv_4LED_6Ftn.ino | 35 +- .../Dec_15Serv_2LED_6Ftn.ino | 17 +- .../SMA/Dec_17LED_1Ftn/Dec_17LED_1Ftn.ino | 31 +- .../SMA/Dec_17LED_6Ftn/Dec_17LED_6Ftn.ino | 87 ++- .../Dec_2Mot_12LED_1Srv_6Ftn.ino | 595 +++++++++++++++ .../Dec_2Mot_3LED_TrigAud.ino | 702 ++++++++++++++++++ .../Dec_2Mot_4LED_Aud_8Ftn.ino | 669 +++++++++++++++++ .../Dec_7Serv_10LED_6Ftn.ino | 40 +- .../SMA/Dec_Dir_and_Fade/Dec_Dir_and_Fade.ino | 34 +- .../Dec_SMA12_LED_Groups.ino | 51 +- .../SMA/Dec_Stepper_6Ftn/Dec_Stepper_6Ftn.ino | 508 +++++++++++++ examples/SMA/SMA 6.0 Release Notes.rtf | Bin 0 -> 5831 bytes 20 files changed, 2940 insertions(+), 269 deletions(-) create mode 100644 examples/SMA/Dec_2Mot_12LED_1Srv_6Ftn/Dec_2Mot_12LED_1Srv_6Ftn.ino create mode 100644 examples/SMA/Dec_2Mot_3LED_TrigAud/Dec_2Mot_3LED_TrigAud.ino create mode 100644 examples/SMA/Dec_2Mot_4LED_Aud_8Ftn/Dec_2Mot_4LED_Aud_8Ftn.ino create mode 100644 examples/SMA/Dec_Stepper_6Ftn/Dec_Stepper_6Ftn.ino create mode 100644 examples/SMA/SMA 6.0 Release Notes.rtf diff --git a/examples/SMA/AccDec_10Servos_7LED_6Ftn/AccDec_10Servos_7LED_6Ftn.ino b/examples/SMA/AccDec_10Servos_7LED_6Ftn/AccDec_10Servos_7LED_6Ftn.ino index ac981a7..68798d4 100755 --- a/examples/SMA/AccDec_10Servos_7LED_6Ftn/AccDec_10Servos_7LED_6Ftn.ino +++ b/examples/SMA/AccDec_10Servos_7LED_6Ftn/AccDec_10Servos_7LED_6Ftn.ino @@ -1,5 +1,10 @@ -// Production 17 Function DCC Decoder -// Version 5.4 Geoff Bunza 2014,2015,2016 +// Production 17 Switch Acessory DCC Decoder AccDec_10Servos_7LED_6Ftn.ino +// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018 +// Now works with both short and long DCC Addesses for CV Control Default 24 (LSB CV 121 ; MSB CV 122) +// ACCESSORY DECODER DEFAULT ADDRESS IS 40 (MAX 40-56 SWITCHES) +// ACCESSRY DECODER ADDRESS CAN NOW BE SET ABOVE 255 +// BE CAREFUL! DIFFERENT DCC BASE STATIONS ALLOW DIFFERING MAX ADDRESSES + // NO LONGER REQUIRES modified software servo Lib // Software restructuring mods added from Alex Shepherd and Franz-Peter // With sincere thanks @@ -19,7 +24,7 @@ SoftwareServo servo[17]; #define servo_start_delay 50 #define servo_init_delay 7 -#define servo_slowdown 3 //servo loop counter limit +#define servo_slowdown 12 //servo loop counter limit int servo_slow_counter = 0; //servo loop counter to slowdown servo transit int tim_delay = 500; @@ -49,6 +54,7 @@ int t; // temp #define SET_CV_Address 24 // THIS ADDRESS IS FOR SETTING CV'S Like a Loco #define Accessory_Address 40 // THIS ADDRESS IS THE START OF THE SWITCHES RANGE // WHICH WILL EXTEND FOR 16 MORE SWITCH ADDRESSES + // THIS CAN START ABOVE ADDRESS 256 uint8_t CV_DECODER_MASTER_RESET = 120; // THIS IS THE CV ADDRESS OF THE FULL RESET #define CV_To_Store_SET_CV_Address 121 #define CV_Accessory_Address CV_ACCESSORY_DECODER_ADDRESS_LSB @@ -61,7 +67,7 @@ struct QUEUE int stop_value; int start_value; }; -QUEUE *ftn_queue = new QUEUE[16]; +QUEUE *ftn_queue = new QUEUE[17]; struct CVPair { @@ -70,15 +76,22 @@ struct CVPair }; CVPair FactoryDefaultCVs [] = { - {CV_ACCESSORY_DECODER_ADDRESS_LSB, Accessory_Address}, - {CV_ACCESSORY_DECODER_ADDRESS_MSB, 0}, + // These two CVs define the Long Accessory Address + {CV_ACCESSORY_DECODER_ADDRESS_LSB, Accessory_Address&0xFF}, + {CV_ACCESSORY_DECODER_ADDRESS_MSB, (Accessory_Address>>8)&0x07}, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0}, {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0}, + // Speed Steps don't matter for this decoder + // 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}, - {CV_To_Store_SET_CV_Address, SET_CV_Address}, - {CV_To_Store_SET_CV_Address+1, 0}, + {CV_To_Store_SET_CV_Address, SET_CV_Address&0xFF }, // LSB Set CV Address + {CV_To_Store_SET_CV_Address+1,(SET_CV_Address>>8)&0x3F }, //MSB Set CV Address {30, 2}, //F0 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade - {31, 1}, //F0 Rate Blink=Eate,PWM=Rate,Servo=Rate {32, 28}, //F0 Start Position F0=0 {33, 140}, //F0 End Position F0=1 {34, 28}, //F0 Current Position @@ -112,21 +125,21 @@ CVPair FactoryDefaultCVs [] = {62, 28}, // Start Position Fx=0 {63, 140}, // End Position Fx=1 {64, 28}, // Current Position - {65, 2}, //F7 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {65, 1}, //F7 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {66, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate - {67, 28}, // Start Position Fx=0 - {68,140}, // End Position Fx=1 - {69, 28}, // Current Position - {70, 2}, //F8 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {67, 1}, // Start Position Fx=0 + {68,35}, // End Position Fx=1 + {69, 1}, // Current Position + {70, 1}, //F8 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {71, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate - {72, 28}, // Start Position Fx=0 - {73, 140}, // End Position Fx=1 - {74, 28}, // Current Position - {75, 2}, //F9 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {72, 1}, // Start Position Fx=0 + {73, 100}, // End Position Fx=1 + {74, 1}, // Current Position + {75, 0}, //F9 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {76, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate - {77, 28}, // Start Position Fx=0 - {78, 140}, // End Position Fx=1 - {79, 28}, // Current Position + {77, 1}, // Start Position Fx=0 + {78, 10}, // End Position Fx=1 + {79, 1}, // Current Position {80, 0}, //F10 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {81, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {82, 1}, // Start Position Fx=0 @@ -135,22 +148,22 @@ CVPair FactoryDefaultCVs [] = {85, 1}, //F11 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {86, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {87, 1}, // Start Position Fx=0 - {88, 5}, // End Position Fx=1 + {88, 50}, // End Position Fx=1 {89, 1}, // Current Position {90, 1}, //F12 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {91, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {92, 1}, // Start Position Fx=0 - {93, 20}, // End Position Fx=1 + {93, 100}, // End Position Fx=1 {94, 1}, // Current Position {95, 3}, //F13 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {96, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {97, 1}, // Start Position Fx=0 - {98, 35}, // End Position Fx=1 + {98, 200}, // End Position Fx=1 {99, 2}, // Current Position {100, 0}, //F14 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {101, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {102, 1}, // Start Position Fx=0 - {103, 4}, // End Position Fx=1 + {103, 200}, // End Position Fx=1 {104, 1}, // Current Position {105, 3}, //F15 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {106, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate @@ -299,7 +312,7 @@ void loop() //**************************************************************** // from the Arduino loop() function for correct library operation Dcc.process(); SoftwareServo::refresh(); - delay(4); + delay(3); for (int i=0; i < numfpins; i++) { if (ftn_queue[i].inuse==1) { diff --git a/examples/SMA/AccDec_13Servos_4LED_6Ftn/AccDec_13Servos_4LED_6Ftn.ino b/examples/SMA/AccDec_13Servos_4LED_6Ftn/AccDec_13Servos_4LED_6Ftn.ino index b887187..a6cf15b 100755 --- a/examples/SMA/AccDec_13Servos_4LED_6Ftn/AccDec_13Servos_4LED_6Ftn.ino +++ b/examples/SMA/AccDec_13Servos_4LED_6Ftn/AccDec_13Servos_4LED_6Ftn.ino @@ -1,5 +1,11 @@ // Production 17 Function DCC Decoder -// Version 5.1 Geoff Bunza 2014,2015,2016 +// Production 17 Switch Acessory DCC Decoder AccDec_13Servos_4LED_6Ftn.ino +// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018 +// Now works with both short and long DCC Addesses for CV Control Default 24 (LSB CV 121 ; MSB CV 122) +// ACCESSORY DECODER DEFAULT ADDRESS IS 40 (MAX 40-56 SWITCHES) +// ACCESSRY DECODER ADDRESS CAN NOW BE SET ABOVE 255 +// BE CAREFUL! DIFFERENT DCC BASE STATIONS ALLOW DIFFERING MAX ADDRESSES + // NO LONGER REQUIRES modified software servo Lib // Software restructuring mods added from Alex Shepherd and Franz-Peter // With sincere thanks @@ -12,14 +18,13 @@ // ******** INFO TO THE SERIAL MONITOR //#define DEBUG - #include #include SoftwareServo servo[17]; #define servo_start_delay 50 #define servo_init_delay 7 -#define servo_slowdown 3 //servo loop counter limit +#define servo_slowdown 12 //servo loop counter limit int servo_slow_counter = 0; //servo loop counter to slowdown servo transit int tim_delay = 500; @@ -49,6 +54,7 @@ int t; // temp #define SET_CV_Address 24 // THIS ADDRESS IS FOR SETTING CV'S Like a Loco #define Accessory_Address 40 // THIS ADDRESS IS THE START OF THE SWITCHES RANGE // WHICH WILL EXTEND FOR 16 MORE SWITCH ADDRESSES + // THIS CAN START ABOVE ADDRESS 256 uint8_t CV_DECODER_MASTER_RESET = 120; // THIS IS THE CV ADDRESS OF THE FULL RESET #define CV_To_Store_SET_CV_Address 121 #define CV_Accessory_Address CV_ACCESSORY_DECODER_ADDRESS_LSB @@ -61,7 +67,7 @@ struct QUEUE int stop_value; int start_value; }; -QUEUE *ftn_queue = new QUEUE[16]; +QUEUE *ftn_queue = new QUEUE[17]; struct CVPair { @@ -70,13 +76,21 @@ struct CVPair }; CVPair FactoryDefaultCVs [] = { - {CV_ACCESSORY_DECODER_ADDRESS_LSB, Accessory_Address}, - {CV_ACCESSORY_DECODER_ADDRESS_MSB, 0}, + // These two CVs define the Long Accessory Address + {CV_ACCESSORY_DECODER_ADDRESS_LSB, Accessory_Address&0xFF}, + {CV_ACCESSORY_DECODER_ADDRESS_MSB, (Accessory_Address>>8)&0x07}, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0}, {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0}, + // Speed Steps don't matter for this decoder + // 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}, - {CV_To_Store_SET_CV_Address, SET_CV_Address}, - {CV_To_Store_SET_CV_Address+1, 0}, + {CV_To_Store_SET_CV_Address, SET_CV_Address&0xFF }, // LSB Set CV Address + {CV_To_Store_SET_CV_Address+1,(SET_CV_Address>>8)&0x3F }, //MSB Set CV Address {30, 2}, //F0 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {31, 1}, //F0 Rate Blink=Eate,PWM=Rate,Servo=Rate {32, 28}, //F0 Start Position F0=0 @@ -142,22 +156,22 @@ CVPair FactoryDefaultCVs [] = {92, 28}, // Start Position Fx=0 {93, 140}, // End Position Fx=1 {94, 28}, // Current Position - {95, 1}, //F13 Config 0=On/Off,1=Blink,2=Servo,3=PWM + {95, 3}, //F13 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {96, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {97, 1}, // Start Position Fx=0 - {98, 20}, // End Position Fx=1 - {99, 1}, // Current Position - {100, 0}, //F14 Config 0=On/Off,1=Blink,2=Servo,3=PWM + {98, 200}, // End Position Fx=1 + {99, 2}, // Current Position + {100, 0}, //F14 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {101, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {102, 1}, // Start Position Fx=0 - {103, 4}, // End Position Fx=1 + {103, 200}, // End Position Fx=1 {104, 1}, // Current Position - {105, 3}, //F15 Config 0=On/Off,1=Blink,2=Servo,3=PWM + {105, 3}, //F15 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {106, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {107, 1}, // Start Position Fx=0 {108, 60}, // End Position Fx=1 - {109, 20}, // Current Position - {110, 0}, //F16 Config 0=On/Off,1=Blink,2=Servo,3=PWM + {109, 1}, // Current Position + {110, 0}, //F16 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {111, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {112, 1}, // Start Position Fx=0 {113, 4}, // End Position Fx=1 @@ -203,7 +217,7 @@ void setup() //****************************************************** // 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, 100, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address); + Dcc.init( MAN_ID_DIY, 600, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address); delay(800); #if defined(DECODER_LOADED) @@ -299,7 +313,7 @@ void loop() //**************************************************************** // from the Arduino loop() function for correct library operation Dcc.process(); SoftwareServo::refresh(); - delay(4); + delay(3); for (int i=0; i < numfpins; i++) { if (ftn_queue[i].inuse==1) { diff --git a/examples/SMA/AccDec_15Servos_2LED_6Ftn/AccDec_15Servos_2LED_6Ftn.ino b/examples/SMA/AccDec_15Servos_2LED_6Ftn/AccDec_15Servos_2LED_6Ftn.ino index 087fe6d..f6e407b 100755 --- a/examples/SMA/AccDec_15Servos_2LED_6Ftn/AccDec_15Servos_2LED_6Ftn.ino +++ b/examples/SMA/AccDec_15Servos_2LED_6Ftn/AccDec_15Servos_2LED_6Ftn.ino @@ -1,5 +1,10 @@ -// Production 17 Function DCC Decoder -// Version 5.4 Geoff Bunza 2014,2015,2016 +// Production 17 Switch Acessory DCC Decoder AccDec_15Servos_2LED_6Ftn.ino +// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018 +// Now works with both short and long DCC Addesses for CV Control Default 24 (LSB CV 121 ; MSB CV 122) +// ACCESSORY DECODER DEFAULT ADDRESS IS 40 (MAX 40-56 SWITCHES) +// ACCESSRY DECODER ADDRESS CAN NOW BE SET ABOVE 255 +// BE CAREFUL! DIFFERENT DCC BASE STATIONS ALLOW DIFFERING MAX ADDRESSES + // NO LONGER REQUIRES modified software servo Lib // Software restructuring mods added from Alex Shepherd and Franz-Peter // With sincere thanks @@ -12,14 +17,13 @@ // ******** INFO TO THE SERIAL MONITOR //#define DEBUG - #include #include SoftwareServo servo[17]; #define servo_start_delay 50 #define servo_init_delay 7 -#define servo_slowdown 3 //servo loop counter limit +#define servo_slowdown 12 //servo loop counter limit int servo_slow_counter = 0; //servo loop counter to slowdown servo transit int tim_delay = 500; @@ -49,6 +53,7 @@ int t; // temp #define SET_CV_Address 24 // THIS ADDRESS IS FOR SETTING CV'S Like a Loco #define Accessory_Address 40 // THIS ADDRESS IS THE START OF THE SWITCHES RANGE // WHICH WILL EXTEND FOR 16 MORE SWITCH ADDRESSES + // THIS CAN START ABOVE ADDRESS 256 uint8_t CV_DECODER_MASTER_RESET = 120; // THIS IS THE CV ADDRESS OF THE FULL RESET #define CV_To_Store_SET_CV_Address 121 #define CV_Accessory_Address CV_ACCESSORY_DECODER_ADDRESS_LSB @@ -61,7 +66,7 @@ struct QUEUE int stop_value; int start_value; }; -QUEUE *ftn_queue = new QUEUE[16]; +QUEUE *ftn_queue = new QUEUE[17]; struct CVPair { @@ -70,13 +75,21 @@ struct CVPair }; CVPair FactoryDefaultCVs [] = { - {CV_ACCESSORY_DECODER_ADDRESS_LSB, Accessory_Address}, - {CV_ACCESSORY_DECODER_ADDRESS_MSB, 0}, + // These two CVs define the Long Accessory Address + {CV_ACCESSORY_DECODER_ADDRESS_LSB, Accessory_Address&0xFF}, + {CV_ACCESSORY_DECODER_ADDRESS_MSB, (Accessory_Address>>8)&0x07}, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0}, {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0}, + // Speed Steps don't matter for this decoder + // 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}, - {CV_To_Store_SET_CV_Address, SET_CV_Address}, - {CV_To_Store_SET_CV_Address+1, 0}, + {CV_To_Store_SET_CV_Address, SET_CV_Address&0xFF }, // LSB Set CV Address + {CV_To_Store_SET_CV_Address+1,(SET_CV_Address>>8)&0x3F }, //MSB Set CV Address {30, 2}, //F0 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {31, 1}, //F0 Rate Blink=Eate,PWM=Rate,Servo=Rate {32, 28}, //F0 Start Position F0=0 @@ -203,7 +216,7 @@ void setup() //****************************************************** // 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, 100, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address); + Dcc.init( MAN_ID_DIY, 600, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address); delay(800); #if defined(DECODER_LOADED) @@ -277,7 +290,13 @@ void setup() //****************************************************** } break; case 5: // Fade On - + { + ftn_queue[i].inuse = 0; + ftn_queue[i].start_value = 0; + ftn_queue[i].increment = int (char (Dcc.getCV( 31+(i*5)))); + digitalWrite(fpins[i], 0); + ftn_queue[i].stop_value = int(Dcc.getCV( 33+(i*5))) *10.; + } break; case 6: // NEXT FEATURE to pin break; @@ -293,7 +312,7 @@ void loop() //**************************************************************** // from the Arduino loop() function for correct library operation Dcc.process(); SoftwareServo::refresh(); - delay(4); + delay(3); for (int i=0; i < numfpins; i++) { if (ftn_queue[i].inuse==1) { @@ -353,13 +372,7 @@ void loop() //**************************************************************** } break; case 5: // Fade On - { - ftn_queue[i].inuse = 0; - ftn_queue[i].start_value = 0; - ftn_queue[i].increment = int (char (Dcc.getCV( 31+(i*5)))); - digitalWrite(fpins[i], 0); - ftn_queue[i].stop_value = int(Dcc.getCV( 33+(i*5))) *10.; - } + break; case 6: // NEXT FEATURE to pin break; diff --git a/examples/SMA/AccDec_17LED_1Ftn/AccDec_17LED_1Ftn.ino b/examples/SMA/AccDec_17LED_1Ftn/AccDec_17LED_1Ftn.ino index 658bfe3..a8c8fbf 100755 --- a/examples/SMA/AccDec_17LED_1Ftn/AccDec_17LED_1Ftn.ino +++ b/examples/SMA/AccDec_17LED_1Ftn/AccDec_17LED_1Ftn.ino @@ -1,5 +1,9 @@ -// Production 17 Function DCC Decoder -// Version 5.4 Geoff Bunza 2014,2015,2016 +// Production 17 Switch Acessory DCC Decoder AccDec_17LED_1Ftn.ino +// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018 +// Now works with both short and long DCC Addesses for CV Control Default 24 (LSB CV 121 ; MSB CV 122) +// ACCESSORY DECODER DEFAULT ADDRESS IS 40 (MAX 40-56 SWITCHES) +// ACCESSRY DECODER ADDRESS CAN NOW BE SET ABOVE 255 +// BE CAREFUL! DIFFERENT DCC BASE STATIONS ALLOW DIFFERING MAX ADDRESSES // ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP // ******** AFTER THE INITIAL DECODER LOAD REMOVE THE "//" IN THE FOOLOWING LINE!! @@ -9,7 +13,7 @@ int tim_delay = 500; #define numleds 17 -byte ledpins [] = {0,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; +byte ledpins [] = {3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; const int FunctionPin0 = 3; const int FunctionPin1 = 4; @@ -31,9 +35,14 @@ const int FunctionPin16 = 19; //A5 NmraDcc Dcc ; DCC_MSG Packet ; -#define This_Decoder_Address 40 //ACCESSORY DECODER ADDRESS - //Start of SWITCHES RANGE -uint8_t CV_DECODER_MASTER_RESET = 120; +#define SET_CV_Address 24 // THIS ADDRESS IS FOR SETTING CV'S Like a Loco +#define Accessory_Address 40 // THIS ADDRESS IS THE START OF THE SWITCHES RANGE + // WHICH WILL EXTEND FOR 16 MORE SWITCH ADDRESSES + // THIS CAN START ABOVE ADDRESS 256 +uint8_t CV_DECODER_MASTER_RESET = 120; // THIS IS THE CV ADDRESS OF THE FULL RESET +#define CV_To_Store_SET_CV_Address 121 +#define CV_Accessory_Address CV_ACCESSORY_DECODER_ADDRESS_LSB + struct CVPair { uint16_t CV; @@ -41,11 +50,21 @@ struct CVPair }; CVPair FactoryDefaultCVs [] = { - {CV_ACCESSORY_DECODER_ADDRESS_LSB, This_Decoder_Address}, - {CV_ACCESSORY_DECODER_ADDRESS_MSB, 0}, + // These two CVs define the Long Accessory Address + {CV_ACCESSORY_DECODER_ADDRESS_LSB, Accessory_Address&0xFF}, + {CV_ACCESSORY_DECODER_ADDRESS_MSB, (Accessory_Address>>8)&0x07}, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0}, {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0}, + // Speed Steps don't matter for this decoder + // 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}, + {CV_To_Store_SET_CV_Address, SET_CV_Address&0xFF }, // LSB Set CV Address + {CV_To_Store_SET_CV_Address+1,(SET_CV_Address>>8)&0x3F }, //MSB Set CV Address }; uint8_t FactoryDefaultCVIndex = 0; @@ -86,7 +105,7 @@ void setup() // Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up Dcc.pin(0, 2, 0); // Call the main DCC Init function to enable the DCC Receiver - Dcc.init( MAN_ID_DIY, 100, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, 0 ); + Dcc.init( MAN_ID_DIY, 600, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address); } void loop() { @@ -94,7 +113,7 @@ void loop() Dcc.process(); } extern void notifyDccAccTurnoutOutput( uint16_t Addr, uint8_t Direction, uint8_t OutputPower ) { - if ( Addr >= This_Decoder_Address && Addr < This_Decoder_Address+17) //Controls This_Decoder_Address+16 - digitalWrite( ledpins[Addr-This_Decoder_Address], Direction ); + if ( Addr >= Accessory_Address && Addr < Accessory_Address+17) //Controls This_Decoder_Address+16 + digitalWrite( ledpins[Addr-Accessory_Address], Direction ); } - + diff --git a/examples/SMA/AccDec_17LED_6Ftn/AccDec_17LED_6Ftn.ino b/examples/SMA/AccDec_17LED_6Ftn/AccDec_17LED_6Ftn.ino index fea3c93..99b6c28 100755 --- a/examples/SMA/AccDec_17LED_6Ftn/AccDec_17LED_6Ftn.ino +++ b/examples/SMA/AccDec_17LED_6Ftn/AccDec_17LED_6Ftn.ino @@ -1,5 +1,10 @@ -// Production 17 Function DCC Decoder -// Version 5.4 Geoff Bunza 2014,2015,2016 +// Production 17 Switch Acessory DCC Decoder AccDec_17LED_6Ftn.ino +// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018 +// Now works with both short and long DCC Addesses for CV Control Default 24 (LSB CV 121 ; MSB CV 122) +// ACCESSORY DECODER DEFAULT ADDRESS IS 40 (MAX 40-56 SWITCHES) +// ACCESSRY DECODER ADDRESS CAN NOW BE SET ABOVE 255 +// BE CAREFUL! DIFFERENT DCC BASE STATIONS ALLOW DIFFERING MAX ADDRESSES + // NO LONGER REQUIRES modified software servo Lib // Software restructuring mods added from Alex Shepherd and Franz-Peter // With sincere thanks @@ -12,14 +17,13 @@ // ******** INFO TO THE SERIAL MONITOR //#define DEBUG - #include #include SoftwareServo servo[17]; #define servo_start_delay 50 #define servo_init_delay 7 -#define servo_slowdown 3 //servo loop counter limit +#define servo_slowdown 12 //servo loop counter limit int servo_slow_counter = 0; //servo loop counter to slowdown servo transit int tim_delay = 500; @@ -49,6 +53,7 @@ int t; // temp #define SET_CV_Address 24 // THIS ADDRESS IS FOR SETTING CV'S Like a Loco #define Accessory_Address 40 // THIS ADDRESS IS THE START OF THE SWITCHES RANGE // WHICH WILL EXTEND FOR 16 MORE SWITCH ADDRESSES + // THIS CAN START ABOVE ADDRESS 256 uint8_t CV_DECODER_MASTER_RESET = 120; // THIS IS THE CV ADDRESS OF THE FULL RESET #define CV_To_Store_SET_CV_Address 121 #define CV_Accessory_Address CV_ACCESSORY_DECODER_ADDRESS_LSB @@ -61,7 +66,7 @@ struct QUEUE int stop_value; int start_value; }; -QUEUE *ftn_queue = new QUEUE[16]; +QUEUE *ftn_queue = new QUEUE[17]; struct CVPair { @@ -70,13 +75,21 @@ struct CVPair }; CVPair FactoryDefaultCVs [] = { - {CV_ACCESSORY_DECODER_ADDRESS_LSB, Accessory_Address}, - {CV_ACCESSORY_DECODER_ADDRESS_MSB, 0}, + // These two CVs define the Long Accessory Address + {CV_ACCESSORY_DECODER_ADDRESS_LSB, Accessory_Address&0xFF}, + {CV_ACCESSORY_DECODER_ADDRESS_MSB, (Accessory_Address>>8)&0x07}, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0}, {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0}, + // Speed Steps don't matter for this decoder + // 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}, - {CV_To_Store_SET_CV_Address, SET_CV_Address}, - {CV_To_Store_SET_CV_Address+1, 0}, + {CV_To_Store_SET_CV_Address, SET_CV_Address&0xFF }, // LSB Set CV Address + {CV_To_Store_SET_CV_Address+1,(SET_CV_Address>>8)&0x3F }, //MSB Set CV Address {30, 0}, //F0 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {31, 1}, //F0 Rate Blink=Eate,PWM=Rate,Servo=Rate {32, 28}, //F0 Start Position F0=0 @@ -127,36 +140,36 @@ CVPair FactoryDefaultCVs [] = {77, 1}, // Start Position Fx=0 {78, 10}, // End Position Fx=1 {79, 1}, // Current Position - {80, 5}, //F10 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {80, 0}, //F10 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {81, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {82, 1}, // Start Position Fx=0 {83, 5}, // End Position Fx=1 {84, 1}, // Current Position - {85, 4}, //F11 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade - {86, 10}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {85, 1}, //F11 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {86, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {87, 1}, // Start Position Fx=0 - {88, 5}, // End Position Fx=1 + {88, 50}, // End Position Fx=1 {89, 1}, // Current Position - {90, 0}, //F12 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {90, 1}, //F12 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {91, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {92, 1}, // Start Position Fx=0 - {93, 20}, // End Position Fx=1 + {93, 100}, // End Position Fx=1 {94, 1}, // Current Position - {95, 0}, //F13 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {95, 3}, //F13 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {96, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {97, 1}, // Start Position Fx=0 - {98, 35}, // End Position Fx=1 + {98, 200}, // End Position Fx=1 {99, 2}, // Current Position {100, 0}, //F14 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {101, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {102, 1}, // Start Position Fx=0 - {103, 4}, // End Position Fx=1 + {103, 200}, // End Position Fx=1 {104, 1}, // Current Position - {105, 0}, //F15 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {105, 3}, //F15 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {106, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {107, 1}, // Start Position Fx=0 {108, 60}, // End Position Fx=1 - {109, 20}, // Current Position + {109, 1}, // Current Position {110, 0}, //F16 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {111, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {112, 1}, // Start Position Fx=0 @@ -177,6 +190,9 @@ void notifyCVResetFactoryDefault() FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); }; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS + void setup() //****************************************************** { #ifdef DEBUG @@ -203,7 +219,7 @@ void setup() //****************************************************** // 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, 100, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address); + Dcc.init( MAN_ID_DIY, 600, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address); delay(800); #if defined(DECODER_LOADED) @@ -299,7 +315,7 @@ void loop() //**************************************************************** // from the Arduino loop() function for correct library operation Dcc.process(); SoftwareServo::refresh(); - delay(4); + delay(3); for (int i=0; i < numfpins; i++) { if (ftn_queue[i].inuse==1) { diff --git a/examples/SMA/AccDec_7ServoBackandForth6Ftn/AccDec_7ServoBackandForth6Ftn.ino b/examples/SMA/AccDec_7ServoBackandForth6Ftn/AccDec_7ServoBackandForth6Ftn.ino index 73ddc2d..3923248 100755 --- a/examples/SMA/AccDec_7ServoBackandForth6Ftn/AccDec_7ServoBackandForth6Ftn.ino +++ b/examples/SMA/AccDec_7ServoBackandForth6Ftn/AccDec_7ServoBackandForth6Ftn.ino @@ -1,13 +1,19 @@ -// Production 17 Function DCC Decoder -// Version 5.4 Geoff Bunza 2014,2015,2016 +// Production 17 Switch Acessory DCC Decoder AccDec_7ServoBackandForth6Ftn.ino +// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018 +// Now works with both short and long DCC Addesses for CV Control Default 24 (LSB CV 121 ; MSB CV 122) +// ACCESSORY DECODER DEFAULT ADDRESS IS 40 (MAX 40-56 SWITCHES) +// ACCESSRY DECODER ADDRESS CAN NOW BE SET ABOVE 255 +// BE CAREFUL! DIFFERENT DCC BASE STATIONS ALLOW DIFFERING MAX ADDRESSES + // NO LONGER REQUIRES modified software servo Lib // Software restructuring mods added from Alex Shepherd and Franz-Peter // With sincere thanks + // This Decoder Version has been modified so that each Switch Closure Transition from Thrown to Closed // Swings the Servo Quickly from Start to Stop and Back to Start // This is ONLY done in the transition from Thrown to Closed Servo Speed can be slowed by changing the // RATE CV towards 1 -// + // ******** 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 @@ -22,7 +28,7 @@ SoftwareServo servo[17]; #define servo_start_delay 50 #define servo_init_delay 7 -#define servo_slowdown 3 //servo loop counter limit +#define servo_slowdown 12 //servo loop counter limit int servo_slow_counter = 0; //servo loop counter to slowdown servo transit int tim_delay = 500; @@ -64,7 +70,7 @@ struct QUEUE int stop_value; int start_value; }; -QUEUE *ftn_queue = new QUEUE[16]; +QUEUE *ftn_queue = new QUEUE[17]; struct CVPair { @@ -73,13 +79,21 @@ struct CVPair }; CVPair FactoryDefaultCVs [] = { - {CV_ACCESSORY_DECODER_ADDRESS_LSB, Accessory_Address}, - {CV_ACCESSORY_DECODER_ADDRESS_MSB, 0}, + // These two CVs define the Long Accessory Address + {CV_ACCESSORY_DECODER_ADDRESS_LSB, Accessory_Address&0xFF}, + {CV_ACCESSORY_DECODER_ADDRESS_MSB, (Accessory_Address>>8)&0x07}, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0}, {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0}, + // Speed Steps don't matter for this decoder + // 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}, - {CV_To_Store_SET_CV_Address, SET_CV_Address}, - {CV_To_Store_SET_CV_Address+1, 0}, + {CV_To_Store_SET_CV_Address, SET_CV_Address&0xFF }, // LSB Set CV Address + {CV_To_Store_SET_CV_Address+1,(SET_CV_Address>>8)&0x3F }, //MSB Set CV Address {30, 2}, //F0 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {31, 1}, //F0 Rate Blink=Eate,PWM=Rate,Servo=Rate {32, 28}, //F0 Start Position @@ -180,6 +194,9 @@ void notifyCVResetFactoryDefault() FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); }; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS + void setup() //****************************************************** { #ifdef DEBUG @@ -206,7 +223,7 @@ void setup() //****************************************************** // 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, 100, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address); + Dcc.init( MAN_ID_DIY, 600, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address); delay(800); #if defined(DECODER_LOADED) @@ -302,7 +319,7 @@ void loop() //**************************************************************** // from the Arduino loop() function for correct library operation Dcc.process(); SoftwareServo::refresh(); - delay(4); + delay(3); for (int i=0; i < numfpins; i++) { if (ftn_queue[i].inuse==1) { diff --git a/examples/SMA/AccDec_7Servos_10LED_6Ftn/AccDec_7Servos_10LED_6Ftn.ino b/examples/SMA/AccDec_7Servos_10LED_6Ftn/AccDec_7Servos_10LED_6Ftn.ino index ae92e0a..c888b63 100755 --- a/examples/SMA/AccDec_7Servos_10LED_6Ftn/AccDec_7Servos_10LED_6Ftn.ino +++ b/examples/SMA/AccDec_7Servos_10LED_6Ftn/AccDec_7Servos_10LED_6Ftn.ino @@ -1,5 +1,10 @@ -// Production 17 Function DCC Decoder -// Version 5.4 Geoff Bunza 2014,2015,2016 +// Production 17 Switch Acessory DCC Decoder AccDec_7Servos_10LED_6Ftn.ino +// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018 +// Now works with both short and long DCC Addesses for CV Control Default 24 (LSB CV 121 ; MSB CV 122) +// ACCESSORY DECODER DEFAULT ADDRESS IS 40 (MAX 40-56 SWITCHES) +// ACCESSRY DECODER ADDRESS CAN NOW BE SET ABOVE 255 +// BE CAREFUL! DIFFERENT DCC BASE STATIONS ALLOW DIFFERING MAX ADDRESSES + // NO LONGER REQUIRES modified software servo Lib // Software restructuring mods added from Alex Shepherd and Franz-Peter // With sincere thanks @@ -12,14 +17,13 @@ // ******** INFO TO THE SERIAL MONITOR //#define DEBUG - #include #include SoftwareServo servo[17]; #define servo_start_delay 50 #define servo_init_delay 7 -#define servo_slowdown 3 //servo loop counter limit +#define servo_slowdown 12 //servo loop counter limit int servo_slow_counter = 0; //servo loop counter to slowdown servo transit int tim_delay = 500; @@ -49,6 +53,7 @@ int t; // temp #define SET_CV_Address 24 // THIS ADDRESS IS FOR SETTING CV'S Like a Loco #define Accessory_Address 40 // THIS ADDRESS IS THE START OF THE SWITCHES RANGE // WHICH WILL EXTEND FOR 16 MORE SWITCH ADDRESSES + // THIS CAN START ABOVE ADDRESS 256 uint8_t CV_DECODER_MASTER_RESET = 120; // THIS IS THE CV ADDRESS OF THE FULL RESET #define CV_To_Store_SET_CV_Address 121 #define CV_Accessory_Address CV_ACCESSORY_DECODER_ADDRESS_LSB @@ -61,7 +66,7 @@ struct QUEUE int stop_value; int start_value; }; -QUEUE *ftn_queue = new QUEUE[16]; +QUEUE *ftn_queue = new QUEUE[17]; struct CVPair { @@ -70,13 +75,21 @@ struct CVPair }; CVPair FactoryDefaultCVs [] = { - {CV_ACCESSORY_DECODER_ADDRESS_LSB, Accessory_Address}, - {CV_ACCESSORY_DECODER_ADDRESS_MSB, 0}, + // These two CVs define the Long Accessory Address + {CV_ACCESSORY_DECODER_ADDRESS_LSB, Accessory_Address&0xFF}, + {CV_ACCESSORY_DECODER_ADDRESS_MSB, (Accessory_Address>>8)&0x07}, + {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0}, {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0}, + // Speed Steps don't matter for this decoder + // 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}, - {CV_To_Store_SET_CV_Address, SET_CV_Address}, - {CV_To_Store_SET_CV_Address+1, 0}, + {CV_To_Store_SET_CV_Address, SET_CV_Address&0xFF }, // LSB Set CV Address + {CV_To_Store_SET_CV_Address+1,(SET_CV_Address>>8)&0x3F }, //MSB Set CV Address {30, 2}, //F0 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {31, 1}, //F0 Rate Blink=Eate,PWM=Rate,Servo=Rate {32, 28}, //F0 Start Position F0=0 @@ -129,41 +142,41 @@ CVPair FactoryDefaultCVs [] = {79, 28}, // Current Position {80, 0}, //F10 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {81, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate - {82, 28}, // Start Position Fx=0 - {83, 140}, // End Position Fx=1 - {84, 28}, // Current Position - {85, 0}, //F11 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {82, 1}, // Start Position Fx=0 + {83, 5}, // End Position Fx=1 + {84, 1}, // Current Position + {85, 1}, //F11 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {86, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate - {87, 28}, // Start Position Fx=0 - {88, 140}, // End Position Fx=1 - {89, 28}, // Current Position - {90, 0}, //F12 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {87, 1}, // Start Position Fx=0 + {88, 50}, // End Position Fx=1 + {89, 1}, // Current Position + {90, 1}, //F12 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {91, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate - {92, 28}, // Start Position Fx=0 - {93, 140}, // End Position Fx=1 - {94, 28}, // Current Position - {95, 1}, //F13 Config 0=On/Off,1=Blink,2=Servo,3=PWM + {92, 1}, // Start Position Fx=0 + {93, 100}, // End Position Fx=1 + {94, 1}, // Current Position + {95, 3}, //F13 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {96, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {97, 1}, // Start Position Fx=0 - {98, 20}, // End Position Fx=1 - {99, 1}, // Current Position - {100, 0}, //F14 Config 0=On/Off,1=Blink,2=Servo,3=PWM + {98, 200}, // End Position Fx=1 + {99, 2}, // Current Position + {100, 0}, //F14 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {101, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {102, 1}, // Start Position Fx=0 - {103, 4}, // End Position Fx=1 + {103, 200}, // End Position Fx=1 {104, 1}, // Current Position - {105, 3}, //F15 Config 0=On/Off,1=Blink,2=Servo,3=PWM + {105, 3}, //F15 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {106, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {107, 1}, // Start Position Fx=0 {108, 60}, // End Position Fx=1 - {109, 20}, // Current Position - {110, 0}, //F16 Config 0=On/Off,1=Blink,2=Servo,3=PWM + {109, 1}, // Current Position + {110, 0}, //F16 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {111, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {112, 1}, // Start Position Fx=0 {113, 4}, // End Position Fx=1 {114, 1}, // Current Position //FUTURE USE - {115, 0}, //F17 Config 0=On/Off,1=Blink,2=Servo,3=PWM + {115, 0}, //F17 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {116, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {117, 28}, // Start Position Fx=0 {118, 50}, // End Position Fx=1 @@ -177,6 +190,9 @@ void notifyCVResetFactoryDefault() FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); }; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS + void setup() //****************************************************** { #ifdef DEBUG @@ -203,7 +219,7 @@ void setup() //****************************************************** // 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, 100, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address); + Dcc.init( MAN_ID_DIY, 600, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address); delay(800); #if defined(DECODER_LOADED) @@ -299,7 +315,7 @@ void loop() //**************************************************************** // from the Arduino loop() function for correct library operation Dcc.process(); SoftwareServo::refresh(); - delay(4); + delay(3); for (int i=0; i < numfpins; i++) { if (ftn_queue[i].inuse==1) { @@ -370,6 +386,7 @@ void loop() //**************************************************************** } } +// This function is called whenever a normal DCC Turnout Packet is received and we're in Output Addressing Mode extern void notifyDccAccTurnoutOutput( uint16_t Addr, uint8_t Direction, uint8_t OutputPower ) { uint16_t Current_Decoder_Addr = Dcc.getAddr(); diff --git a/examples/SMA/Dec_10Serv_7LED_6Ftn/Dec_10Serv_7LED_6Ftn.ino b/examples/SMA/Dec_10Serv_7LED_6Ftn/Dec_10Serv_7LED_6Ftn.ino index 7471ee6..cc97362 100755 --- a/examples/SMA/Dec_10Serv_7LED_6Ftn/Dec_10Serv_7LED_6Ftn.ino +++ b/examples/SMA/Dec_10Serv_7LED_6Ftn/Dec_10Serv_7LED_6Ftn.ino @@ -1,5 +1,6 @@ // Production 17 Function DCC Decoder -// Version 5.4 Geoff Bunza 2014,2015,2016 +// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018 +// Now works with both short and long DCC Addesses // NO LONGER REQUIRES modified software servo Lib // Software restructuring mods added from Alex Shepherd and Franz-Peter // With sincere thanks @@ -19,7 +20,7 @@ SoftwareServo servo[17]; #define servo_start_delay 50 #define servo_init_delay 7 -#define servo_slowdown 3 //servo loop counter limit +#define servo_slowdown 12 //servo loop counter limit int servo_slow_counter = 0; //servo loop counter to slowdown servo transit int tim_delay = 500; @@ -49,7 +50,6 @@ NmraDcc Dcc ; DCC_MSG Packet ; uint8_t CV_DECODER_MASTER_RESET = 120; int t; // temp -#define This_Decoder_Address 24 struct QUEUE { int inuse; @@ -58,19 +58,29 @@ struct QUEUE int stop_value; int start_value; }; -QUEUE *ftn_queue = new QUEUE[16]; +QUEUE *ftn_queue = new QUEUE[17]; struct CVPair { uint16_t CV; uint8_t Value; }; + +#define This_Decoder_Address 24 + CVPair FactoryDefaultCVs [] = { - {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address}, - {CV_ACCESSORY_DECODER_ADDRESS_MSB, 0}, - {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0}, - {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0}, + {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, 2}, //F0 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {31, 1}, //F0 Rate Blink=Eate,PWM=Rate,Servo=Rate @@ -130,22 +140,22 @@ CVPair FactoryDefaultCVs [] = {85, 1}, //F11 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {86, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {87, 1}, // Start Position Fx=0 - {88, 5}, // End Position Fx=1 + {88, 50}, // End Position Fx=1 {89, 1}, // Current Position {90, 1}, //F12 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {91, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {92, 1}, // Start Position Fx=0 - {93, 20}, // End Position Fx=1 + {93, 100}, // End Position Fx=1 {94, 1}, // Current Position {95, 3}, //F13 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {96, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {97, 1}, // Start Position Fx=0 - {98, 35}, // End Position Fx=1 + {98, 200}, // End Position Fx=1 {99, 2}, // Current Position {100, 0}, //F14 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {101, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {102, 1}, // Start Position Fx=0 - {103, 4}, // End Position Fx=1 + {103, 200}, // End Position Fx=1 {104, 1}, // Current Position {105, 3}, //F15 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {106, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate @@ -173,6 +183,8 @@ void notifyCVResetFactoryDefault() FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); }; +// NOTE: NO PROGRAMMING ACK IS SET UP TO MAXIMAIZE +// OUTPUT PINS FOR FUNCTIONS void setup() //****************************************************** { #ifdef DEBUG @@ -199,7 +211,7 @@ void setup() //****************************************************** // 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, 100, FLAGS_MY_ADDRESS_ONLY, 0 ); + Dcc.init( MAN_ID_DIY, 600, FLAGS_MY_ADDRESS_ONLY, 0 ); delay(800); #if defined(DECODER_LOADED) @@ -295,7 +307,7 @@ void loop() //**************************************************************** // from the Arduino loop() function for correct library operation Dcc.process(); SoftwareServo::refresh(); - delay(4); + delay(3); for (int i=0; i < numfpins; i++) { if (ftn_queue[i].inuse==1) { @@ -367,6 +379,17 @@ void loop() //**************************************************************** } void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { +#ifdef DEBUG + Serial.print(" addr: "); + Serial.print(Addr, DEC) ; + Serial.print(" at: "); + Serial.print(AddrType, DEC) ; + Serial.print(" fg : "); + Serial.print(FuncGrp, DEC) ; + Serial.print(" fs: "); + Serial.println(FuncState, DEC) ; +#endif + switch(FuncGrp) { case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1 @@ -480,4 +503,4 @@ void exec_function (int function, int pin, int FuncState) { ftn_queue[function].inuse = 0; break; } -} +} diff --git a/examples/SMA/Dec_13Serv_4LED_6Ftn/Dec_13Serv_4LED_6Ftn.ino b/examples/SMA/Dec_13Serv_4LED_6Ftn/Dec_13Serv_4LED_6Ftn.ino index 863c97a..b463aa4 100755 --- a/examples/SMA/Dec_13Serv_4LED_6Ftn/Dec_13Serv_4LED_6Ftn.ino +++ b/examples/SMA/Dec_13Serv_4LED_6Ftn/Dec_13Serv_4LED_6Ftn.ino @@ -1,4 +1,4 @@ -// Production 17 Function DCC Decoder +// Production 17 Function DCC Decoder Dec_13Serv_4LED_6Ftn.ino // Version 5.4 Geoff Bunza 2014,2015,2016 // NO LONGER REQUIRES modified software servo Lib // Software restructuring mods added from Alex Shepherd and Franz-Peter @@ -19,7 +19,7 @@ SoftwareServo servo[17]; #define servo_start_delay 50 #define servo_init_delay 7 -#define servo_slowdown 3 //servo loop counter limit +#define servo_slowdown 12 //servo loop counter limit int servo_slow_counter = 0; //servo loop counter to slowdown servo transit int tim_delay = 500; @@ -49,7 +49,6 @@ NmraDcc Dcc ; DCC_MSG Packet ; uint8_t CV_DECODER_MASTER_RESET = 120; int t; // temp -#define This_Decoder_Address 24 struct QUEUE { int inuse; @@ -65,12 +64,22 @@ struct CVPair uint16_t CV; uint8_t Value; }; + +#define This_Decoder_Address 24 + CVPair FactoryDefaultCVs [] = { - {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address}, - {CV_ACCESSORY_DECODER_ADDRESS_MSB, 0}, - {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0}, - {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0}, + {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, 2}, //F0 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {31, 1}, //F0 Rate Blink=Eate,PWM=Rate,Servo=Rate @@ -137,21 +146,21 @@ CVPair FactoryDefaultCVs [] = {92, 28}, // Start Position Fx=0 {93, 140}, // End Position Fx=1 {94, 28}, // Current Position - {95, 1}, //F13 CConfig 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {95, 3}, //F13 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {96, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {97, 1}, // Start Position Fx=0 - {98, 20}, // End Position Fx=1 - {99, 1}, // Current Position + {98, 200}, // End Position Fx=1 + {99, 2}, // Current Position {100, 0}, //F14 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {101, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {102, 1}, // Start Position Fx=0 - {103, 4}, // End Position Fx=1 + {103, 200}, // End Position Fx=1 {104, 1}, // Current Position {105, 3}, //F15 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {106, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {107, 1}, // Start Position Fx=0 {108, 60}, // End Position Fx=1 - {109, 20}, // Current Position + {109, 1}, // Current Position {110, 0}, //F16 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {111, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {112, 1}, // Start Position Fx=0 @@ -295,7 +304,7 @@ void loop() //**************************************************************** // from the Arduino loop() function for correct library operation Dcc.process(); SoftwareServo::refresh(); - delay(4); + delay(3); for (int i=0; i < numfpins; i++) { if (ftn_queue[i].inuse==1) { diff --git a/examples/SMA/Dec_15Serv_2LED_6Ftn/Dec_15Serv_2LED_6Ftn.ino b/examples/SMA/Dec_15Serv_2LED_6Ftn/Dec_15Serv_2LED_6Ftn.ino index 653644f..2cfbfdb 100755 --- a/examples/SMA/Dec_15Serv_2LED_6Ftn/Dec_15Serv_2LED_6Ftn.ino +++ b/examples/SMA/Dec_15Serv_2LED_6Ftn/Dec_15Serv_2LED_6Ftn.ino @@ -1,4 +1,4 @@ -// Production 17 Function DCC Decoder +// Production 17 Function DCC Decoder Dec_15Serv_2LED_6Ftn.ino // Version 5.4 Geoff Bunza 2014,2015,2016 // NO LONGER REQUIRES modified software servo Lib // Software restructuring mods added from Alex Shepherd and Franz-Peter @@ -12,14 +12,13 @@ // ******** INFO TO THE SERIAL MONITOR //#define DEBUG - #include #include SoftwareServo servo[17]; #define servo_start_delay 50 #define servo_init_delay 7 -#define servo_slowdown 3 //servo loop counter limit +#define servo_slowdown 12 //servo loop counter limit int servo_slow_counter = 0; //servo loop counter to slowdown servo transit int tim_delay = 500; @@ -49,7 +48,6 @@ NmraDcc Dcc ; DCC_MSG Packet ; uint8_t CV_DECODER_MASTER_RESET = 120; int t; // temp -#define This_Decoder_Address 24 struct QUEUE { int inuse; @@ -65,6 +63,9 @@ struct CVPair uint16_t CV; uint8_t Value; }; + +#define This_Decoder_Address 24 + CVPair FactoryDefaultCVs [] = { {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address}, @@ -147,15 +148,15 @@ CVPair FactoryDefaultCVs [] = {102, 28}, // Start Position Fx=0 {103, 140}, // End Position Fx=1 {104, 28}, // Current Position - {105, 1}, //F15 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {105, 3}, //F15 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {106, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {107, 1}, // Start Position Fx=0 - {108, 10}, // End Position Fx=1 + {108, 60}, // End Position Fx=1 {109, 1}, // Current Position {110, 0}, //F16 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {111, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {112, 1}, // Start Position Fx=0 - {113, 10}, // End Position Fx=1 + {113, 4}, // End Position Fx=1 {114, 1}, // Current Position //FUTURE USE {115, 0}, //F17 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade @@ -295,7 +296,7 @@ void loop() //**************************************************************** // from the Arduino loop() function for correct library operation Dcc.process(); SoftwareServo::refresh(); - delay(4); + delay(3); for (int i=0; i < numfpins; i++) { if (ftn_queue[i].inuse==1) { diff --git a/examples/SMA/Dec_17LED_1Ftn/Dec_17LED_1Ftn.ino b/examples/SMA/Dec_17LED_1Ftn/Dec_17LED_1Ftn.ino index 1fd6a8a..81a57f3 100755 --- a/examples/SMA/Dec_17LED_1Ftn/Dec_17LED_1Ftn.ino +++ b/examples/SMA/Dec_17LED_1Ftn/Dec_17LED_1Ftn.ino @@ -1,5 +1,6 @@ -// Production 17 Function DCC Decoder -// Version 5.4 Geoff Bunza 2014,2015,2016 +// Production 17 Function DCC Decoder Dec_17LED_1Ftn.ino +// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018 +// Now works with both short and long DCC Addesses // ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP // ******** AFTER THE INITIAL DECODER LOAD REMOVE THE "//" IN THE FOOLOWING LINE!! @@ -9,7 +10,7 @@ int tim_delay = 500; #define numleds 17 -byte ledpins [] = {0,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; +byte ledpins [] = {3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; const int FunctionPin0 = 3; const int FunctionPin1 = 4; @@ -26,7 +27,6 @@ const int FunctionPin9 = 12; const int FunctionPin10 = 13; const int FunctionPin11 = 14; //A0 const int FunctionPin12 = 15; //A1 - const int FunctionPin13 = 16; //A2 const int FunctionPin14 = 17; //A3 const int FunctionPin15 = 18; //A4 @@ -34,7 +34,6 @@ const int FunctionPin16 = 19; //A5 NmraDcc Dcc ; DCC_MSG Packet ; uint8_t CV_DECODER_MASTER_RESET = 120; -#define This_Decoder_Address 24 struct CVPair { @@ -42,15 +41,25 @@ struct CVPair uint8_t Value; }; CVPair FactoryDefaultCVs [] = + +#define This_Decoder_Address 24 + { - {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address}, - {CV_ACCESSORY_DECODER_ADDRESS_MSB, 0}, - {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0}, - {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0}, + {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}, }; -uint8_t FactoryDefaultCVIndex = 4; +uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); void notifyCVResetFactoryDefault() { // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset @@ -78,7 +87,7 @@ void setup() // Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up Dcc.pin(0, 2, 0); // Call the main DCC Init function to enable the DCC Receiver - Dcc.init( MAN_ID_DIY, 100, FLAGS_MY_ADDRESS_ONLY, 0 ); + Dcc.init( MAN_ID_DIY, 600, FLAGS_MY_ADDRESS_ONLY, 0 ); delay(800); #if defined(DECODER_LOADED) if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET ) diff --git a/examples/SMA/Dec_17LED_6Ftn/Dec_17LED_6Ftn.ino b/examples/SMA/Dec_17LED_6Ftn/Dec_17LED_6Ftn.ino index f5d3009..e022030 100755 --- a/examples/SMA/Dec_17LED_6Ftn/Dec_17LED_6Ftn.ino +++ b/examples/SMA/Dec_17LED_6Ftn/Dec_17LED_6Ftn.ino @@ -1,5 +1,6 @@ -// Production 17 Function DCC Decoder -// Version 5.4 Geoff Bunza 2014,2015,2016 +// Production 17 Function DCC Decoder Dec_17LED_6Ftn.ino +// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018 +// Now works with both short and long DCC Addesses // NO LONGER REQUIRES modified software servo Lib // Software restructuring mods added from Alex Shepherd and Franz-Peter // With sincere thanks @@ -10,15 +11,14 @@ // ******** EMOVE THE "//" IN THE FOOLOWING LINE TO SEND DEBUGGING // ******** INFO TO THE SERIAL MONITOR -//#define DEBUG - +#define DEBUG #include #include SoftwareServo servo[17]; #define servo_start_delay 50 #define servo_init_delay 7 -#define servo_slowdown 3 //servo loop counter limit +#define servo_slowdown 12 //servo loop counter limit int servo_slow_counter = 0; //servo loop counter to slowdown servo transit int tim_delay = 500; @@ -48,7 +48,7 @@ NmraDcc Dcc ; DCC_MSG Packet ; uint8_t CV_DECODER_MASTER_RESET = 120; int t; // temp -#define This_Decoder_Address 24 + struct QUEUE { int inuse; @@ -64,18 +64,27 @@ struct CVPair uint16_t CV; uint8_t Value; }; + +#define This_Decoder_Address 24 + CVPair FactoryDefaultCVs [] = { {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address}, - {CV_ACCESSORY_DECODER_ADDRESS_MSB, 0}, - {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0}, - {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0}, + + // 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, 5}, //F0 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade - {31, 1}, //F0 Rate Blink=Eate,PWM=Rate,Servo=Rate - {32, 0}, //F0 Start Position F0=0 + {31, 1}, //F0 Rate Blink=Eate,PWM=Rate,Servo=Rate + {32, 0}, //F0 Start Position F0=0 {33, 8}, //F0 End Position F0=1 - {34, 1}, //F0 Current Position + {34, 1}, //F0 Current Position {35, 5}, //F1 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {36, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {37, 0}, // Start Position Fx=0 @@ -121,40 +130,40 @@ CVPair FactoryDefaultCVs [] = {77, 28}, // Start Position Fx=0 {78, 140}, // End Position Fx=1 {79, 28}, // Current Position - {80, 0}, //F10 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {80, 0}, //F10 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {81, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {82, 1}, // Start Position Fx=0 {83, 5}, // End Position Fx=1 {84, 1}, // Current Position - {85, 1}, //F11 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {85, 1}, //F11 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {86, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {87, 1}, // Start Position Fx=0 - {88, 5}, // End Position Fx=1 + {88, 50}, // End Position Fx=1 {89, 1}, // Current Position - {90, 1}, //F12 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {90, 1}, //F12 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {91, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {92, 1}, // Start Position Fx=0 - {93, 10}, // End Position Fx=1 + {93, 100}, // End Position Fx=1 {94, 1}, // Current Position - {95, 3}, //F13 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {95, 3}, //F13 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {96, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {97, 1}, // Start Position Fx=0 - {98, 6}, // End Position Fx=1 - {99, 1}, // Current Position - {100, 0}, //F14 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {98, 200}, // End Position Fx=1 + {99, 2}, // Current Position + {100, 0}, //F14 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {101, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {102, 1}, // Start Position Fx=0 - {103, 6}, // End Position Fx=1 + {103, 200}, // End Position Fx=1 {104, 1}, // Current Position - {105, 3}, //F15 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {105, 3}, //F15 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {106, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {107, 1}, // Start Position Fx=0 - {108, 10}, // End Position Fx=1 + {108, 60}, // End Position Fx=1 {109, 1}, // Current Position - {110, 0}, //F16 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {110, 0}, //F16 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {111, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {112, 1}, // Start Position Fx=0 - {113, 10}, // End Position Fx=1 + {113, 4}, // End Position Fx=1 {114, 1}, // Current Position //FUTURE USE {115, 0}, //F17 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade @@ -164,7 +173,7 @@ CVPair FactoryDefaultCVs [] = {119, 28}, // Current Position }; -uint8_t FactoryDefaultCVIndex = 95; +uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); void notifyCVResetFactoryDefault() { // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset @@ -172,14 +181,17 @@ void notifyCVResetFactoryDefault() 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 int i; uint8_t cv_value; - Serial.begin(115200); // initialize the digital pins as outputs for (int i=0; i < numfpins; i++) { pinMode(fpins[i], OUTPUT); @@ -199,12 +211,12 @@ void setup() //****************************************************** // 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, 100, FLAGS_MY_ADDRESS_ONLY, 0 ); + Dcc.init( MAN_ID_DIY, 600, FLAGS_MY_ADDRESS_ONLY, 0 ); delay(800); #if defined(DECODER_LOADED) if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET ) -#endif +#endif { for (int j=0; j < FactoryDefaultCVIndex; j++ ) @@ -213,8 +225,9 @@ void setup() //****************************************************** delay (1000); digitalWrite(fpins[14], 0); } + for ( i=0; i < numfpins; i++) { - cv_value = Dcc.getCV( 30+(i*5)) ; + cv_value = Dcc.getCV( 30+(i*5)) ; #ifdef DEBUG Serial.print(" cv_value: "); Serial.println(cv_value, DEC) ; @@ -295,7 +308,7 @@ void loop() //**************************************************************** // from the Arduino loop() function for correct library operation Dcc.process(); SoftwareServo::refresh(); - delay(4); + delay(3); for (int i=0; i < numfpins; i++) { if (ftn_queue[i].inuse==1) { @@ -367,6 +380,12 @@ void loop() //**************************************************************** } 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 @@ -403,7 +422,7 @@ void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uin } } void exec_function (int function, int pin, int FuncState) { - switch ( Dcc.getCV( 30+(function*5)) ) { // Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + switch ( Dcc.getCV( 30+(function*5)) ) { // Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade case 0: // On - Off LED digitalWrite (pin, FuncState); ftn_queue[function].inuse = 0; @@ -480,4 +499,4 @@ void exec_function (int function, int pin, int FuncState) { ftn_queue[function].inuse = 0; break; } -} +} diff --git a/examples/SMA/Dec_2Mot_12LED_1Srv_6Ftn/Dec_2Mot_12LED_1Srv_6Ftn.ino b/examples/SMA/Dec_2Mot_12LED_1Srv_6Ftn/Dec_2Mot_12LED_1Srv_6Ftn.ino new file mode 100644 index 0000000..2f5658f --- /dev/null +++ b/examples/SMA/Dec_2Mot_12LED_1Srv_6Ftn/Dec_2Mot_12LED_1Srv_6Ftn.ino @@ -0,0 +1,595 @@ +// Production 2 Motor 13 Function DCC Decoder Dec_2MotDrive_12LED_1Srv_6Ftn.ino +// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018 +// Now works with both short and long DCC Addesses + +// NO LONGER REQUIRES modified software servo Lib +// Software restructuring mods added from Alex Shepherd and Franz-Peter +// With sincere thanks +/* + * Motor selection is via motor select Function 13 (Motor1) and Function 14 (Motor2) + * Motor speed for each can only be changed if the corresponding Function is on + * (F13 and/or F14). Motor speed is maintained if the corresponding Motor select function + * is off. Thus, each motor can be controlled independently and run at different speeds. + * F0-F12 control LEDs on Pro Mini Digital Pins 5,6,7,8,11,12,13,14,15,16,17,18,19 + * Simple speed control is made via throttle speed setting for two motors. Motor selection + * is via motor select Function 13 (Motor1) and Function 14 (Motor2). Motor speed for each + * can only be changed if the corresponding Function is on (F13 and/or F14). Motor speed is + * maintained if the corresponding motor select function is off. Thus, each motor can be + * controlled independently and run at different speeds. The other functions are configurable + * but are preset for LED on/off control. +*/ +// ******** 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 + +SoftwareServo servo[13]; +#define servo_start_delay 50 +#define servo_init_delay 7 +#define servo_slowdown 12 //servo loop counter limit +int servo_slow_counter = 0; //servo loop counter to slowdown servo transit + +uint8_t Motor1Speed = 0; +uint8_t Motor1ForwardDir = 1; +uint8_t Motor1MaxSpeed = 127; +uint8_t Motor2Speed = 0; +uint8_t Motor2ForwardDir = 1; +uint8_t Motor2MaxSpeed = 127; +int kickstarton = 1400; //kick start cycle on time +int kickstarttime = 5; //kick start duration on time +int fwdon = 0; +int fwdtime = 1; +int bwdon = 0; +int bwdtime = 1; +int bwdshift = 0; +int cyclewidth = 2047; +int m2h = 3; //R H Bridge //Motor1 +int m2l = 4; //B H Bridge //Motor1 +int m0h = 9; //R H Bridge //Motor2 +int m0l = 10; //B H Bridge //Motor2 + +int speedup = 112; //Right track time differntial +int deltime = 1500; +int tim_delay = 80; +int numfpins = 17; +int num_active_fpins = 13; +byte fpins [] = {3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; +const int FunctionPin0 = 5; +const int FunctionPin1 = 6; +const int FunctionPin2 = 7; +const int FunctionPin3 = 8; +const int FunctionPin4 = 11; + +const int FunctionPin5 = 12; +const int FunctionPin6 = 13; +const int FunctionPin7 = 14; //A0 +const int FunctionPin8 = 15; //A1 + + +const int FunctionPin9 = 16; //A2 +const int FunctionPin10 = 17; //A3 +const int FunctionPin11 = 18; //A4 +const int FunctionPin12 = 19; //A5 + +int Function13_value = 0; +int Function14_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[17]; + +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=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {31, 1}, //F0 Rate Blink=Eate,PWM=Rate,Servo=Rate + {32, 0}, //F0 Start Position F0=0 + {33, 8}, //F0 End Position F0=1 + {34, 1}, //F0 Current Position + {35, 0}, //F1 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {36, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {37, 0}, // Start Position Fx=0 + {38, 8}, // End Position Fx=1 + {39, 1}, // Current Position + {40, 0}, //F2 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {41, 10}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {42, 28}, // Start Position Fx=0 + {43, 140}, // End Position Fx=1 + {44, 0}, // Current Position + {45, 0}, //F3 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {46, 10}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {47, 28}, // Start Position Fx=0 + {48, 140}, // End Position Fx=1 + {49, 0}, // Current Position + {50, 0}, //F4 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {51, 10}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {52, 28}, // Start Position Fx=0 + {53, 140}, // End Position Fx=1 + {54, 0}, // Current Position + {55, 0}, //F5 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {56, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {57, 28}, // Start Position Fx=0 + {58, 140}, // End Position Fx=1 + {59, 28}, // Current Position + {60, 0}, //F6 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {61, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {62, 28}, // Start Position Fx=0 + {63, 140}, // End Position Fx=1 + {64, 28}, // Current Position + {65, 0}, //F7 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {66, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {67, 28}, // Start Position Fx=0 + {68,140}, // End Position Fx=1 + {69, 28}, // Current Position + {70, 0}, //F8 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {71, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {72, 28}, // Start Position Fx=0 + {73, 140}, // End Position Fx=1 + {74, 28}, // Current Position + {75, 0}, //F9 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {76, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {77, 28}, // Start Position Fx=0 + {78, 140}, // End Position Fx=1 + {79, 28}, // Current Position + {80, 0}, //F10 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {81, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {82, 1}, // Start Position Fx=0 + {83, 5}, // End Position Fx=1 + {84, 1}, // Current Position + {85, 1}, //F11 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {86, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {87, 1}, // Start Position Fx=0 + {88, 5}, // End Position Fx=1 + {89, 1}, // Current Position + {90, 2}, //F12 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {91, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {92, 1}, // Start Position Fx=0 + {93, 10}, // End Position Fx=1 + {94, 1}, // Current Position + {95, 0}, //F13 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {96, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {97, 1}, // Start Position Fx=0 + {98, 6}, // End Position Fx=1 + {99, 1}, // Current Position + {100, 0}, //F14 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {101, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {102, 1}, // Start Position Fx=0 + {103, 6}, // End Position Fx=1 + {104, 1}, // Current Position + {105, 3}, //F15 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {106, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {107, 1}, // Start Position Fx=0 + {108, 10}, // End Position Fx=1 + {109, 1}, // Current Position + {110, 0}, //F16 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {111, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {112, 1}, // Start Position Fx=0 + {113, 10}, // End Position Fx=1 + {114, 1}, // Current Position +//FUTURE USE + {115, 0}, //F17 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {116, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {117, 28}, // Start Position Fx=0 + {118, 50}, // End Position Fx=1 + {119, 28}, // Current Position +}; + +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 + int i; + 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); + } + for (int i=8; i < numfpins; i++) { + digitalWrite(fpins[i], 1); + delay (tim_delay); + } + delay( tim_delay); + for (int i=8; i < numfpins; i++) { + digitalWrite(fpins[i], 0); + delay (tim_delay); + } + // 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, 600, 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[14], 1); + delay (1000); + digitalWrite(fpins[14], 0); + } + for ( i=0; i < num_active_fpins; i++) { + cv_value = Dcc.getCV( 30+(i*5)) ; +#ifdef DEBUG + Serial.print(" cv_value: "); + Serial.println(cv_value, DEC) ; +#endif + switch ( cv_value ) { + case 0: // LED on/off + ftn_queue[i].inuse = 0; + break; + case 1: // LED Blink + { + ftn_queue[i].inuse = 0; + ftn_queue[i].current_position = 0; + ftn_queue[i].start_value = 0; + ftn_queue[i].increment = int (char (Dcc.getCV( 31+(i*5)))); + digitalWrite(fpins[i], 0); + ftn_queue[i].stop_value = int(Dcc.getCV( 33+(i*5))) ; + } + break; + case 2: //servo + { + ftn_queue[i].current_position =int (Dcc.getCV( 34+(i*5))); + ftn_queue[i].stop_value = int (Dcc.getCV( 33+(i*5))); + ftn_queue[i].start_value = int (Dcc.getCV( 32+(i*5))); + ftn_queue[i].increment = -int (char (Dcc.getCV( 31+(i*5)))); + // attaches servo on pin to the servo object + servo[i].attach(fpins[i]); + +#ifdef DEBUG + Serial.print("InitServo ID= "); + Serial.println(i, DEC) ; +#endif + servo[i].write(ftn_queue[i].start_value); + for (t=0; t ftn_queue[i].stop_value) { + ftn_queue[i].start_value = ~ftn_queue[i].start_value; + digitalWrite(fpins[i], ftn_queue[i].start_value); + ftn_queue[i].current_position = 0; + ftn_queue[i].stop_value = int(Dcc.getCV( 33+(i*5))); + } + break; + case 2: + { + if (servo_slow_counter++ > servo_slowdown) + { + ftn_queue[i].current_position = ftn_queue[i].current_position + ftn_queue[i].increment; + if (ftn_queue[i].increment > 0) { + if (ftn_queue[i].current_position > ftn_queue[i].stop_value) { + ftn_queue[i].current_position = ftn_queue[i].stop_value; + ftn_queue[i].inuse = 0; + servo[i].detach(); + } + } + if (ftn_queue[i].increment < 0) { + if (ftn_queue[i].current_position < ftn_queue[i].start_value) { + ftn_queue[i].current_position = ftn_queue[i].start_value; + ftn_queue[i].inuse = 0; + servo[i].detach(); + } + } + servo[i].write(ftn_queue[i].current_position); + servo_slow_counter = 0; + } + } + break; + case 3: + ftn_queue[i].current_position = ftn_queue[i].current_position + ftn_queue[i].increment; + if (ftn_queue[i].current_position > ftn_queue[i].stop_value) { + ftn_queue[i].start_value = ~ftn_queue[i].start_value; + digitalWrite(fpins[i], ftn_queue[i].start_value); + digitalWrite(fpins[i]+1, ~ftn_queue[i].start_value); + ftn_queue[i].current_position = 0; + ftn_queue[i].stop_value = int(Dcc.getCV( 33+(i*5))); + } + i++; + break; + case 4: // Simple Pulsed Output based on saved Rate =10*Rate in Milliseconds + { + ftn_queue[i].inuse = 0; + ftn_queue[i].current_position = 0; + ftn_queue[i].increment = 10 * int (char (Dcc.getCV( 31+(i*5)))); + digitalWrite(fpins[i], 0); + } + break; + case 5: // Fade On + + break; + case 6: // NEXT FEATURE to pin + break; + default: + break; + } + } + } +} +void gofwd1(int fcnt,int fcycle) { + int icnt; + int totcycle; + icnt = 0; + while (icnt < fcnt) + { + digitalWrite(m2h, HIGH); //Motor1 + delayMicroseconds(fcycle); + digitalWrite(m2h, LOW); //Motor1 + delayMicroseconds(cyclewidth - fcycle); + icnt++; + } +} +void gobwd1(int bcnt,int bcycle) { + int icnt; + icnt=0; + while (icnt < bcnt) + { + digitalWrite(m2l, HIGH); //Motor1 + delayMicroseconds(bcycle); + digitalWrite(m2l, LOW); //Motor1 + delayMicroseconds(cyclewidth - bcycle); + icnt++; + } +} +void gofwd2(int fcnt,int fcycle) { + int icnt; + int totcycle; + icnt = 0; + while (icnt < fcnt) + { + digitalWrite(m0h, HIGH); //Motor2 + delayMicroseconds(fcycle); + digitalWrite(m0h, LOW); //Motor2 + delayMicroseconds(cyclewidth - fcycle); + icnt++; + } +} +void gobwd2(int bcnt,int bcycle) { + int icnt; + icnt=0; + while (icnt < bcnt) + { + digitalWrite(m0l, HIGH); //Motor2 + delayMicroseconds(bcycle); + digitalWrite(m0l, LOW); //Motor2 + delayMicroseconds(cyclewidth - bcycle); + icnt++; + } +} +void notifyDccSpeed( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Speed, DCC_DIRECTION ForwardDir, DCC_SPEED_STEPS SpeedSteps ) { + if (Function13_value==1) { + Motor1Speed = Speed; + Motor1ForwardDir = ForwardDir; + } + if (Function14_value==1) { + Motor2Speed = Speed; + Motor2ForwardDir = ForwardDir; + } +} +void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { + 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 + Function13_value = (FuncState & FN_BIT_13); + Function14_value = (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; + } +} +void exec_function (int function, int pin, int FuncState) { + switch ( Dcc.getCV( 30+(function*5)) ) { // Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + case 0: // On - Off LED + digitalWrite (pin, FuncState); + ftn_queue[function].inuse = 0; + break; + case 1: // Blinking LED + if ((ftn_queue[function].inuse==0) && (FuncState==1)) { + ftn_queue[function].inuse = 1; + ftn_queue[function].start_value = 0; + digitalWrite(pin, 0); + ftn_queue[function].stop_value = int(Dcc.getCV( 33+(function*5))); + } else { + if ((ftn_queue[function].inuse==1) && (FuncState==0)) { + ftn_queue[function].inuse = 0; + digitalWrite(pin, 0); + } + } + break; + case 2: // Servo + if (ftn_queue[function].inuse == 0) { + ftn_queue[function].inuse = 1; + servo[function].attach(pin); + } + if (FuncState==1) ftn_queue[function].increment = char ( Dcc.getCV( 31+(function*5))); + else ftn_queue[function].increment = - char(Dcc.getCV( 31+(function*5))); + if (FuncState==1) ftn_queue[function].stop_value = Dcc.getCV( 33+(function*5)); + else ftn_queue[function].stop_value = Dcc.getCV( 32+(function*5)); + break; + case 3: // Blinking LED PAIR + if ((ftn_queue[function].inuse==0) && (FuncState==1)) { + ftn_queue[function].inuse = 1; + ftn_queue[function].start_value = 0; + digitalWrite(fpins[function], 0); + digitalWrite(fpins[function+1], 1); + ftn_queue[function].stop_value = int(Dcc.getCV( 33+(function*5))); + } else { + if (FuncState==0) { + ftn_queue[function].inuse = 0; + digitalWrite(fpins[function], 0); + digitalWrite(fpins[function+1], 0); + } + } + break; + case 4: // Pulse Output based on Rate*10 Milliseconds + if ((ftn_queue[function].inuse==0) && (FuncState==1)) { //First Turn On Detected + digitalWrite(fpins[function], 1); + delay (10*ftn_queue[function].increment); + digitalWrite(fpins[function], 0); + ftn_queue[function].inuse = 1; //inuse set to 1 says we already pulsed + } else + if (FuncState==0) ftn_queue[function].inuse = 0; + break; + case 5: // Fade On +#define fadedelay 24 + if ((ftn_queue[function].inuse==0) && (FuncState==1)) { + ftn_queue[function].inuse = 1; + for (t=0; t +#include +#include +#include +SoftwareSerial mySerial(6,7); // PRO MINI RX, PRO MINI TX serial to DFPlayer + +int busy_pin = 5; // DFPlayer Busy status pin +#define num_clips 6 //number of sound tracks/clips on the Micro SD Memory Card +int del_tim = 4000; +int tctr, tctr2, i; +byte audio_on = 0; // Audio ON sets this to 1; otherwise 0 + +SoftwareServo servo[10]; +#define servo_start_delay 50 +#define servo_init_delay 7 +#define servo_slowdown 4 //servo loop counter limit +int servo_slow_counter = 0; //servo loop counter to slowdown servo transit + +uint8_t Motor1Speed = 0; +uint8_t Motor1ForwardDir = 1; +uint8_t Motor1MaxSpeed = 127; +uint8_t Motor2Speed = 0; +uint8_t Motor2ForwardDir = 1; +uint8_t Motor2MaxSpeed = 127; +int kickstarton = 1400; //kick start cycle on time +int kickstarttime = 5; //kick start duration on time +int fwdon = 0; +int fwdtime = 1; +int bwdon = 0; +int bwdtime = 1; +int bwdshift = 0; +int cyclewidth = 2047; +int m2h = 3; //R H Bridge //Motor1 +int m2l = 4; //B H Bridge //Motor1 +int m0h = 9; //R H Bridge //Motor2 +int m0l = 10; //B H Bridge //Motor2 + +int speedup = 112; //Right track time differntial +int deltime = 1500; +int tim_delay = 100; +int numfpins = 13; +int num_active_fpins = 9; +byte fpins [] = {3,4,8,9,10,11,12,13,14,15,16,18}; +const int FunctionPin0 = 8; +const int FunctionPin1 = 11; +const int FunctionPin2 = 12; +const int FunctionPin3 = 13; +const int FunctionPin4 = 14; //A0 + +const int FunctionPin5 = 15; //A1 +const int FunctionPin6 = 16; //A2 +const int FunctionPin7 = 18; //A5 +const int FunctionPin8 = 19; //A4 + +const int AudioTriggerPin = 17; //A3 NOW USED AS Audio Trigger Pin INPUT_PULLUP + +const int FunctionPin9 = 20; // Place holders ONLY +const int FunctionPin10 = 20; // Place holders ONLY +const int FunctionPin11 = 20; +const int FunctionPin12 = 20; +const int FunctionPin13 = 20; +const int FunctionPin14 = 20; +const int FunctionPin15 = 20; +const int FunctionPin16 = 20; + +int Function13_value = 0; +int Function14_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[17]; + +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=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade,6=Audio,7=Random Audio,8=Triggered Audio + {31, 10}, //F0 Rate Blink=Eate,PWM=Rate,Servo=Rate,Audio=Volume(0-30) + {32, 0}, //F0 Start Position F0=0,Audio=Audio Track/Clip# + {33, 8}, //F0 End Position F0=1 + {34, 1}, //F0 Current Position + {35, 6}, //F1 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade,6=Audio,7=Random Audio,8=Triggered Audio + {36, 22}, // Rate Blink=Eate,PWM=Rate,Servo=Rate,Audio=Volume(0-30) + {37, 1}, // Start Position Fx=0,Audio=Audio Track/Clip# + {38, 8}, // End Position Fx=1 + {39, 1}, // Current Position + {40, 6}, //F2 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade,6=Audio,7=Random Audio,8=Triggered Audio + {41, 22}, // Rate Blink=Eate,PWM=Rate,Servo=Rate,Audio=Volume(0-30) + {42, 2}, // Start Position Fx=0,Audio=Audio Track/Clip# + {43, 140}, // End Position Fx=1 + {44, 0}, // Current Position + {45, 6}, //F3 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade,6=Audio,7=Random Audio,8=Triggered Audio + {46, 22}, // Rate Blink=Eate,PWM=Rate,Servo=Rate,Audio=Volume(0-30) + {47, 3}, // Start Position Fx=0,Audio=Audio Track/Clip# + {48, 140}, // End Position Fx=1 + {49, 0}, // Current Position + {50, 6}, //F4 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade,6=Audio,7=Random Audio,8=Triggered Audio + {51, 22}, // Rate Blink=Eate,PWM=Rate,Servo=Rate,Audio=Volume(0-30) + {52, 4}, // Start Position Fx=0,Audio=Audio Track/Clip# + {53, 140}, // End Position Fx=1 + {54, 0}, // Current Position + {55, 8}, //F5 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade,6=Audio,7=Random Audio,8=Triggered Audio + {56, 22}, // Rate Blink=Eate,PWM=Rate,Servo=Rate,Audio=Volume(0-30) + {57, 6}, // Start Position Fx=0,Audio=Audio Track/Clip# + {58, 140}, // End Position Fx=1 + {59, 0}, // Current Position + {60, 7}, //F6 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade,6=Audio,7=Random Audio,8=Triggered Audio + {61, 22}, // Rate Blink=Eate,PWM=Rate,Servo=Rate,Audio=Volume(0-30) + {62, 6}, // Start Position Fx=0,Audio=Audio Track/Clip# + {63, 140}, // End Position Fx=1 + {64, 28}, // Current Position + {65, 0}, //F7 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade,6=Audio,7=Random Audio,8=Triggered Audio + {66, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate,Audio=Volume(0-30) + {67, 28}, // Start Position Fx=0,Audio=Audio Track/Clip# + {68,140}, // End Position Fx=1 + {69, 28}, // Current Position + {70, 0}, //F8 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade,6=Audio,7=Random Audio,8=Triggered Audio + {71, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate,Audio=Volume(0-30) + {72, 28}, // Start Position Fx=0,Audio=Audio Track/Clip# + {73, 140}, // End Position Fx=1 + {74, 28}, // Current Position + {75, 0}, //F9 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade,6=Audio,7=Random Audio,8=Triggered Audio + {76, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate,Audio=Volume(0-30) + {77, 28}, // Start Position Fx=0,Audio=Audio Track/Clip# + {78, 140}, // End Position Fx=1 + {79, 28}, // Current Position +}; + +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 (busy_pin, INPUT); // MUST NOT Pull Up == 3.3V device output pin + pinMode (AudioTriggerPin, INPUT_PULLUP); + + mySerial.begin (9600); + mp3_set_serial (mySerial); //set softwareSerial for DFPlayer-mini mp3 module + mp3_reset (); + delay(100); + mp3_set_volume (18); + delay(50); + audio_on = 0; + 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); + } + // 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, 600, 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[14], 1); + delay (1000); + digitalWrite(fpins[14], 0); + } + for ( i=0; i < num_active_fpins; i++) { + cv_value = Dcc.getCV( 30+(i*5)) ; +#ifdef DEBUG + Serial.print(" cv_value: "); + Serial.println(cv_value, DEC) ; +#endif + switch ( cv_value ) { + case 0: // LED on/off + ftn_queue[i].inuse = 0; + break; + case 1: // LED Blink + { + ftn_queue[i].inuse = 0; + ftn_queue[i].current_position = 0; + ftn_queue[i].start_value = 0; + ftn_queue[i].increment = int (char (Dcc.getCV( 31+(i*5)))); + digitalWrite(fpins[i], 0); + ftn_queue[i].stop_value = int(Dcc.getCV( 33+(i*5))) ; + } + break; + case 2: //servo + { + ftn_queue[i].current_position =int (Dcc.getCV( 34+(i*5))); + ftn_queue[i].stop_value = int (Dcc.getCV( 33+(i*5))); + ftn_queue[i].start_value = int (Dcc.getCV( 32+(i*5))); + ftn_queue[i].increment = -int (char (Dcc.getCV( 31+(i*5)))); + // attaches servo on pin to the servo object + servo[i].attach(fpins[i]); + +#ifdef DEBUG + Serial.print("InitServo ID= "); + Serial.println(i, DEC) ; +#endif + servo[i].write(ftn_queue[i].start_value); + for (t=0; t ftn_queue[i].stop_value) { + ftn_queue[i].start_value = ~ftn_queue[i].start_value; + digitalWrite(fpins[i], ftn_queue[i].start_value); + ftn_queue[i].current_position = 0; + ftn_queue[i].stop_value = int(Dcc.getCV( 33+(i*5))); + } + break; + case 2: + { + if (servo_slow_counter++ > servo_slowdown) + { + ftn_queue[i].current_position = ftn_queue[i].current_position + ftn_queue[i].increment; + if (ftn_queue[i].increment > 0) { + if (ftn_queue[i].current_position > ftn_queue[i].stop_value) { + ftn_queue[i].current_position = ftn_queue[i].stop_value; + ftn_queue[i].inuse = 0; + servo[i].detach(); + } + } + if (ftn_queue[i].increment < 0) { + if (ftn_queue[i].current_position < ftn_queue[i].start_value) { + ftn_queue[i].current_position = ftn_queue[i].start_value; + ftn_queue[i].inuse = 0; + servo[i].detach(); + } + } + servo[i].write(ftn_queue[i].current_position); + servo_slow_counter = 0; + } + } + break; + case 3: + ftn_queue[i].current_position = ftn_queue[i].current_position + ftn_queue[i].increment; + if (ftn_queue[i].current_position > ftn_queue[i].stop_value) { + ftn_queue[i].start_value = ~ftn_queue[i].start_value; + digitalWrite(fpins[i], ftn_queue[i].start_value); + digitalWrite(fpins[i]+1, ~ftn_queue[i].start_value); + ftn_queue[i].current_position = 0; + ftn_queue[i].stop_value = int(Dcc.getCV( 33+(i*5))); + } + i++; + break; + case 4: // Simple Pulsed Output based on saved Rate =10*Rate in Milliseconds + { + ftn_queue[i].inuse = 0; + ftn_queue[i].current_position = 0; + ftn_queue[i].increment = 10 * int (char (Dcc.getCV( 31+(i*5)))); + digitalWrite(fpins[i], 0); + } + break; + case 5: // Fade On + + break; + case 6: // Audio Track Play + if (digitalRead(busy_pin)== HIGH) { + ftn_queue[i].inuse = 0; + } + break; + case 7: // Audio Random Track/Clip Play + if (digitalRead(busy_pin)== HIGH) { + ftn_queue[i].inuse = 0; +/* Insert the following code if you want continuous random play as long as F6 is selected + if (ftn_queue[i].inuse ==1) { // Audio Off continue playing clips + mp3_play (random(1,num_clips)); // play random clip + delay(5); + } +*/ + } + break; + case 8: // Triggered Audio Track Play + if (ftn_queue[i].inuse ==1) { // Function is set ON + if ((digitalRead(AudioTriggerPin)== LOW)&&(digitalRead(busy_pin)== HIGH)) { // Trigger ON Audio Off + mp3_set_volume (ftn_queue[i].increment); + delay(8); + mp3_play (ftn_queue[i].start_value); // play clip function + delay(5); + } + } + break; + case 9: // NEXT FEATURE for the Future + break; + default: + break; + } + } + } +} +void gofwd1(int fcnt,int fcycle) { + int icnt; + int totcycle; + icnt = 0; + while (icnt < fcnt) + { + digitalWrite(m2h, HIGH); //Motor1 + delayMicroseconds(fcycle); + digitalWrite(m2h, LOW); //Motor1 + delayMicroseconds(cyclewidth - fcycle); + icnt++; + } +} +void gobwd1(int bcnt,int bcycle) { + int icnt; + icnt=0; + while (icnt < bcnt) + { + digitalWrite(m2l, HIGH); //Motor1 + delayMicroseconds(bcycle); + digitalWrite(m2l, LOW); //Motor1 + delayMicroseconds(cyclewidth - bcycle); + icnt++; + } +} +void gofwd2(int fcnt,int fcycle) { + int icnt; + int totcycle; + icnt = 0; + while (icnt < fcnt) + { + digitalWrite(m0h, HIGH); //Motor2 + delayMicroseconds(fcycle); + digitalWrite(m0h, LOW); //Motor2 + delayMicroseconds(cyclewidth - fcycle); + icnt++; + } +} +void gobwd2(int bcnt,int bcycle) { + int icnt; + icnt=0; + while (icnt < bcnt) + { + digitalWrite(m0l, HIGH); //Motor2 + delayMicroseconds(bcycle); + digitalWrite(m0l, LOW); //Motor2 + delayMicroseconds(cyclewidth - bcycle); + icnt++; + } +} +void notifyDccSpeed( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Speed, DCC_DIRECTION ForwardDir, DCC_SPEED_STEPS SpeedSteps ) { + if (Function13_value==1) { + Motor1Speed = Speed; + Motor1ForwardDir = ForwardDir; + } + if (Function14_value==1) { + Motor2Speed = Speed; + Motor2ForwardDir = ForwardDir; + } +} + +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 + Function13_value = (FuncState & FN_BIT_13); + Function14_value = (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; + } +} +void exec_function (int function, int pin, int FuncState) { + switch ( Dcc.getCV( 30+(function*5)) ) { // Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + case 0: // On - Off LED + digitalWrite (pin, FuncState); + ftn_queue[function].inuse = 0; + break; + case 1: // Blinking LED + if ((ftn_queue[function].inuse==0) && (FuncState==1)) { + ftn_queue[function].inuse = 1; + ftn_queue[function].start_value = 0; + digitalWrite(pin, 0); + ftn_queue[function].stop_value = int(Dcc.getCV( 33+(function*5))); + } else { + if ((ftn_queue[function].inuse==1) && (FuncState==0)) { + ftn_queue[function].inuse = 0; + digitalWrite(pin, 0); + } + } + break; + case 2: // Servo + if (ftn_queue[function].inuse == 0) { + ftn_queue[function].inuse = 1; + servo[function].attach(pin); + } + if (FuncState==1) ftn_queue[function].increment = char ( Dcc.getCV( 31+(function*5))); + else ftn_queue[function].increment = - char(Dcc.getCV( 31+(function*5))); + if (FuncState==1) ftn_queue[function].stop_value = Dcc.getCV( 33+(function*5)); + else ftn_queue[function].stop_value = Dcc.getCV( 32+(function*5)); + break; + case 3: // Blinking LED PAIR + if ((ftn_queue[function].inuse==0) && (FuncState==1)) { + ftn_queue[function].inuse = 1; + ftn_queue[function].start_value = 0; + digitalWrite(fpins[function], 0); + digitalWrite(fpins[function+1], 1); + ftn_queue[function].stop_value = int(Dcc.getCV( 33+(function*5))); + } else { + if (FuncState==0) { + ftn_queue[function].inuse = 0; + digitalWrite(fpins[function], 0); + digitalWrite(fpins[function+1], 0); + } + } + break; + case 4: // Pulse Output based on Rate*10 Milliseconds + if ((ftn_queue[function].inuse==0) && (FuncState==1)) { //First Turn On Detected + digitalWrite(fpins[function], 1); + delay (10*ftn_queue[function].increment); + digitalWrite(fpins[function], 0); + ftn_queue[function].inuse = 1; //inuse set to 1 says we already pulsed + } else + if (FuncState==0) ftn_queue[function].inuse = 0; + break; + case 5: // Fade On +#define fadedelay 24 + if ((ftn_queue[function].inuse==0) && (FuncState==1)) { + ftn_queue[function].inuse = 1; + for (t=0; t +#include +#include +#include +SoftwareSerial mySerial(6,7); // PRO MINI RX, PRO MINI TX serial to DFPlayer + +int busy_pin = 5; // DFPlayer Busy status pin +#define num_clips 6 //number of sound tracks/clips on the Micro SD Memory Card +int del_tim = 4000; +int tctr, tctr2, i; +byte audio_on = 0; // Audio ON sets this to 1; otherwise 0 + +SoftwareServo servo[10]; +#define servo_start_delay 50 +#define servo_init_delay 7 +#define servo_slowdown 4 //servo loop counter limit +int servo_slow_counter = 0; //servo loop counter to slowdown servo transit + +uint8_t Motor1Speed = 0; +uint8_t Motor1ForwardDir = 1; +uint8_t Motor1MaxSpeed = 127; +uint8_t Motor2Speed = 0; +uint8_t Motor2ForwardDir = 1; +uint8_t Motor2MaxSpeed = 127; +int kickstarton = 1400; //kick start cycle on time +int kickstarttime = 5; //kick start duration on time +int fwdon = 0; +int fwdtime = 1; +int bwdon = 0; +int bwdtime = 1; +int bwdshift = 0; +int cyclewidth = 2047; +int m2h = 3; //R H Bridge //Motor1 +int m2l = 4; //B H Bridge //Motor1 +int m0h = 9; //R H Bridge //Motor2 +int m0l = 10; //B H Bridge //Motor2 + +int speedup = 112; //Right track time differntial +int deltime = 1500; +int tim_delay = 100; +int numfpins = 14; +int num_active_fpins = 10; +byte fpins [] = {3,4,8,9,10,11,12,13,14,15,16,17,18,19}; +const int FunctionPin0 = 8; +const int FunctionPin1 = 11; +const int FunctionPin2 = 12; +const int FunctionPin3 = 13; +const int FunctionPin4 = 14; //A0 + +const int FunctionPin5 = 15; //A1 +const int FunctionPin6 = 16; //A2 +const int FunctionPin7 = 17; //A3 +const int FunctionPin8 = 18; //A4 +const int FunctionPin9 = 19; //A5 + +const int FunctionPin10 = 20; // Place holders ONLY +const int FunctionPin11 = 20; +const int FunctionPin12 = 20; +const int FunctionPin13 = 20; +const int FunctionPin14 = 20; +const int FunctionPin15 = 20; +const int FunctionPin16 = 20; + +int Function13_value = 0; +int Function14_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[17]; + +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=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade,6=Audio + {31, 10}, //F0 Rate Blink=Eate,PWM=Rate,Servo=Rate,Audio=Volume(0-30) + {32, 0}, //F0 Start Position F0=0,Audio=Audio Track/Clip# + {33, 8}, //F0 End Position F0=1 + {34, 1}, //F0 Current Position + {35, 6}, //F1 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade,6=Audio + {36, 22}, // Rate Blink=Eate,PWM=Rate,Servo=Rate,Audio=Volume(0-30) + {37, 1}, // Start Position Fx=0,Audio=Audio Track/Clip# + {38, 8}, // End Position Fx=1 + {39, 1}, // Current Position + {40, 6}, //F2 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade,6=Audio + {41, 22}, // Rate Blink=Eate,PWM=Rate,Servo=Rate,Audio=Volume(0-30) + {42, 2}, // Start Position Fx=0,Audio=Audio Track/Clip# + {43, 140}, // End Position Fx=1 + {44, 0}, // Current Position + {45, 6}, //F3 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade,6=Audio + {46, 22}, // Rate Blink=Eate,PWM=Rate,Servo=Rate,Audio=Volume(0-30) + {47, 3}, // Start Position Fx=0,Audio=Audio Track/Clip# + {48, 140}, // End Position Fx=1 + {49, 0}, // Current Position + {50, 6}, //F4 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade,6=Audio + {51, 22}, // Rate Blink=Eate,PWM=Rate,Servo=Rate,Audio=Volume(0-30) + {52, 4}, // Start Position Fx=0,Audio=Audio Track/Clip# + {53, 140}, // End Position Fx=1 + {54, 0}, // Current Position + {55, 6}, //F5 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade,6=Audio + {56, 22}, // Rate Blink=Eate,PWM=Rate,Servo=Rate,Audio=Volume(0-30) + {57, 5}, // Start Position Fx=0,Audio=Audio Track/Clip# + {58, 140}, // End Position Fx=1 + {59, 28}, // Current Position + {60, 7}, //F6 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade,6=Audio + {61, 22}, // Rate Blink=Eate,PWM=Rate,Servo=Rate,Audio=Volume(0-30) + {62, 6}, // Start Position Fx=0,Audio=Audio Track/Clip# + {63, 140}, // End Position Fx=1 + {64, 28}, // Current Position + {65, 0}, //F7 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade,6=Audio + {66, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate,Audio=Volume(0-30) + {67, 28}, // Start Position Fx=0,Audio=Audio Track/Clip# + {68,140}, // End Position Fx=1 + {69, 28}, // Current Position + {70, 0}, //F8 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade,6=Audio + {71, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate,Audio=Volume(0-30) + {72, 28}, // Start Position Fx=0,Audio=Audio Track/Clip# + {73, 140}, // End Position Fx=1 + {74, 28}, // Current Position + {75, 0}, //F9 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade,6=Audio + {76, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate,Audio=Volume(0-30) + {77, 28}, // Start Position Fx=0,Audio=Audio Track/Clip# + {78, 140}, // End Position Fx=1 + {79, 28}, // Current Position +}; + +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 (busy_pin, INPUT); + mySerial.begin (9600); + mp3_set_serial (mySerial); //set softwareSerial for DFPlayer-mini mp3 module + mp3_reset (); + delay(100); + mp3_set_volume (18); + delay(50); + audio_on = 0; + 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); + } + // 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, 600, 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[14], 1); + delay (1000); + digitalWrite(fpins[14], 0); + } + for ( i=0; i < num_active_fpins; i++) { + cv_value = Dcc.getCV( 30+(i*5)) ; +#ifdef DEBUG + Serial.print(" cv_value: "); + Serial.println(cv_value, DEC) ; +#endif + switch ( cv_value ) { + case 0: // LED on/off + ftn_queue[i].inuse = 0; + break; + case 1: // LED Blink + { + ftn_queue[i].inuse = 0; + ftn_queue[i].current_position = 0; + ftn_queue[i].start_value = 0; + ftn_queue[i].increment = int (char (Dcc.getCV( 31+(i*5)))); + digitalWrite(fpins[i], 0); + ftn_queue[i].stop_value = int(Dcc.getCV( 33+(i*5))) ; + } + break; + case 2: //servo + { + ftn_queue[i].current_position =int (Dcc.getCV( 34+(i*5))); + ftn_queue[i].stop_value = int (Dcc.getCV( 33+(i*5))); + ftn_queue[i].start_value = int (Dcc.getCV( 32+(i*5))); + ftn_queue[i].increment = -int (char (Dcc.getCV( 31+(i*5)))); + // attaches servo on pin to the servo object + servo[i].attach(fpins[i]); + +#ifdef DEBUG + Serial.print("InitServo ID= "); + Serial.println(i, DEC) ; +#endif + servo[i].write(ftn_queue[i].start_value); + for (t=0; t ftn_queue[i].stop_value) { + ftn_queue[i].start_value = ~ftn_queue[i].start_value; + digitalWrite(fpins[i], ftn_queue[i].start_value); + ftn_queue[i].current_position = 0; + ftn_queue[i].stop_value = int(Dcc.getCV( 33+(i*5))); + } + break; + case 2: + { + if (servo_slow_counter++ > servo_slowdown) + { + ftn_queue[i].current_position = ftn_queue[i].current_position + ftn_queue[i].increment; + if (ftn_queue[i].increment > 0) { + if (ftn_queue[i].current_position > ftn_queue[i].stop_value) { + ftn_queue[i].current_position = ftn_queue[i].stop_value; + ftn_queue[i].inuse = 0; + servo[i].detach(); + } + } + if (ftn_queue[i].increment < 0) { + if (ftn_queue[i].current_position < ftn_queue[i].start_value) { + ftn_queue[i].current_position = ftn_queue[i].start_value; + ftn_queue[i].inuse = 0; + servo[i].detach(); + } + } + servo[i].write(ftn_queue[i].current_position); + servo_slow_counter = 0; + } + } + break; + case 3: + ftn_queue[i].current_position = ftn_queue[i].current_position + ftn_queue[i].increment; + if (ftn_queue[i].current_position > ftn_queue[i].stop_value) { + ftn_queue[i].start_value = ~ftn_queue[i].start_value; + digitalWrite(fpins[i], ftn_queue[i].start_value); + digitalWrite(fpins[i]+1, ~ftn_queue[i].start_value); + ftn_queue[i].current_position = 0; + ftn_queue[i].stop_value = int(Dcc.getCV( 33+(i*5))); + } + i++; + break; + case 4: // Simple Pulsed Output based on saved Rate =10*Rate in Milliseconds + { + ftn_queue[i].inuse = 0; + ftn_queue[i].current_position = 0; + ftn_queue[i].increment = 10 * int (char (Dcc.getCV( 31+(i*5)))); + digitalWrite(fpins[i], 0); + } + break; + case 5: // Fade On + + break; + case 6: // Audio Track Play + if (digitalRead(busy_pin)== HIGH) { + ftn_queue[i].inuse = 0; + } + break; + case 7: // Audio Random Track/Clip Play + if (digitalRead(busy_pin)== HIGH) { + ftn_queue[i].inuse = 0; +/* Insert the following code if you want continuous random play as long as F6 is selected + if (ftn_queue[i].inuse ==1) { // Audio Off continue playing clips + mp3_play (random(1,num_clips)); // play random clip + delay(5); + } +*/ + } + break; + case 8: // NEXT FEATURE to pin + break; + default: + break; + } + } + } +} +void gofwd1(int fcnt,int fcycle) { + int icnt; + int totcycle; + icnt = 0; + while (icnt < fcnt) + { + digitalWrite(m2h, HIGH); //Motor1 + delayMicroseconds(fcycle); + digitalWrite(m2h, LOW); //Motor1 + delayMicroseconds(cyclewidth - fcycle); + icnt++; + } +} +void gobwd1(int bcnt,int bcycle) { + int icnt; + icnt=0; + while (icnt < bcnt) + { + digitalWrite(m2l, HIGH); //Motor1 + delayMicroseconds(bcycle); + digitalWrite(m2l, LOW); //Motor1 + delayMicroseconds(cyclewidth - bcycle); + icnt++; + } +} +void gofwd2(int fcnt,int fcycle) { + int icnt; + int totcycle; + icnt = 0; + while (icnt < fcnt) + { + digitalWrite(m0h, HIGH); //Motor2 + delayMicroseconds(fcycle); + digitalWrite(m0h, LOW); //Motor2 + delayMicroseconds(cyclewidth - fcycle); + icnt++; + } +} +void gobwd2(int bcnt,int bcycle) { + int icnt; + icnt=0; + while (icnt < bcnt) + { + digitalWrite(m0l, HIGH); //Motor2 + delayMicroseconds(bcycle); + digitalWrite(m0l, LOW); //Motor2 + delayMicroseconds(cyclewidth - bcycle); + icnt++; + } +} +void notifyDccSpeed( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Speed, DCC_DIRECTION ForwardDir, DCC_SPEED_STEPS SpeedSteps ) { + if (Function13_value==1) { + Motor1Speed = Speed; + Motor1ForwardDir = ForwardDir; + } + if (Function14_value==1) { + Motor2Speed = Speed; + Motor2ForwardDir = ForwardDir; + } +} + +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 + Function13_value = (FuncState & FN_BIT_13); + Function14_value = (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; + } +} +void exec_function (int function, int pin, int FuncState) { + switch ( Dcc.getCV( 30+(function*5)) ) { // Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + case 0: // On - Off LED + digitalWrite (pin, FuncState); + ftn_queue[function].inuse = 0; + break; + case 1: // Blinking LED + if ((ftn_queue[function].inuse==0) && (FuncState==1)) { + ftn_queue[function].inuse = 1; + ftn_queue[function].start_value = 0; + digitalWrite(pin, 0); + ftn_queue[function].stop_value = int(Dcc.getCV( 33+(function*5))); + } else { + if ((ftn_queue[function].inuse==1) && (FuncState==0)) { + ftn_queue[function].inuse = 0; + digitalWrite(pin, 0); + } + } + break; + case 2: // Servo + if (ftn_queue[function].inuse == 0) { + ftn_queue[function].inuse = 1; + servo[function].attach(pin); + } + if (FuncState==1) ftn_queue[function].increment = char ( Dcc.getCV( 31+(function*5))); + else ftn_queue[function].increment = - char(Dcc.getCV( 31+(function*5))); + if (FuncState==1) ftn_queue[function].stop_value = Dcc.getCV( 33+(function*5)); + else ftn_queue[function].stop_value = Dcc.getCV( 32+(function*5)); + break; + case 3: // Blinking LED PAIR + if ((ftn_queue[function].inuse==0) && (FuncState==1)) { + ftn_queue[function].inuse = 1; + ftn_queue[function].start_value = 0; + digitalWrite(fpins[function], 0); + digitalWrite(fpins[function+1], 1); + ftn_queue[function].stop_value = int(Dcc.getCV( 33+(function*5))); + } else { + if (FuncState==0) { + ftn_queue[function].inuse = 0; + digitalWrite(fpins[function], 0); + digitalWrite(fpins[function+1], 0); + } + } + break; + case 4: // Pulse Output based on Rate*10 Milliseconds + if ((ftn_queue[function].inuse==0) && (FuncState==1)) { //First Turn On Detected + digitalWrite(fpins[function], 1); + delay (10*ftn_queue[function].increment); + digitalWrite(fpins[function], 0); + ftn_queue[function].inuse = 1; //inuse set to 1 says we already pulsed + } else + if (FuncState==0) ftn_queue[function].inuse = 0; + break; + case 5: // Fade On +#define fadedelay 24 + if ((ftn_queue[function].inuse==0) && (FuncState==1)) { + ftn_queue[function].inuse = 1; + for (t=0; t #include @@ -19,7 +18,7 @@ SoftwareServo servo[17]; #define servo_start_delay 50 #define servo_init_delay 7 -#define servo_slowdown 3 //servo loop counter limit +#define servo_slowdown 12 //servo loop counter limit int servo_slow_counter = 0; //servo loop counter to slowdown servo transit int tim_delay = 500; @@ -49,7 +48,6 @@ NmraDcc Dcc ; DCC_MSG Packet ; uint8_t CV_DECODER_MASTER_RESET = 120; int t; // temp -#define This_Decoder_Address 24 struct QUEUE { int inuse; @@ -65,12 +63,22 @@ struct CVPair uint16_t CV; uint8_t Value; }; + +#define This_Decoder_Address 24 + CVPair FactoryDefaultCVs [] = { - {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address}, - {CV_ACCESSORY_DECODER_ADDRESS_MSB, 0}, - {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0}, - {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0}, + {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, 2}, //F0 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {31, 1}, //F0 Rate Blink=Eate,PWM=Rate,Servo=Rate @@ -130,28 +138,28 @@ CVPair FactoryDefaultCVs [] = {85, 1}, //F11 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {86, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {87, 1}, // Start Position Fx=0 - {88, 5}, // End Position Fx=1 + {88, 50}, // End Position Fx=1 {89, 1}, // Current Position {90, 1}, //F12 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {91, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {92, 1}, // Start Position Fx=0 - {93, 20}, // End Position Fx=1 + {93, 100}, // End Position Fx=1 {94, 1}, // Current Position {95, 3}, //F13 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {96, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {97, 1}, // Start Position Fx=0 - {98, 35}, // End Position Fx=1 + {98, 200}, // End Position Fx=1 {99, 2}, // Current Position {100, 0}, //F14 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {101, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {102, 1}, // Start Position Fx=0 - {103, 4}, // End Position Fx=1 + {103, 200}, // End Position Fx=1 {104, 1}, // Current Position {105, 3}, //F15 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {106, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {107, 1}, // Start Position Fx=0 {108, 60}, // End Position Fx=1 - {109, 20}, // Current Position + {109, 1}, // Current Position {110, 0}, //F16 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade {111, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate {112, 1}, // Start Position Fx=0 @@ -295,7 +303,7 @@ void loop() //**************************************************************** // from the Arduino loop() function for correct library operation Dcc.process(); SoftwareServo::refresh(); - delay(4); + delay(3); for (int i=0; i < numfpins; i++) { if (ftn_queue[i].inuse==1) { @@ -480,4 +488,4 @@ void exec_function (int function, int pin, int FuncState) { ftn_queue[function].inuse = 0; break; } -} +} diff --git a/examples/SMA/Dec_Dir_and_Fade/Dec_Dir_and_Fade.ino b/examples/SMA/Dec_Dir_and_Fade/Dec_Dir_and_Fade.ino index 8651c1f..2df4109 100755 --- a/examples/SMA/Dec_Dir_and_Fade/Dec_Dir_and_Fade.ino +++ b/examples/SMA/Dec_Dir_and_Fade/Dec_Dir_and_Fade.ino @@ -1,6 +1,8 @@ -// Production 17 Function DCC Decoder -// Version 5.4 Geoff Bunza 2014,2015,2016 -// LED control is dependent on direction of travel +// Production 17 Function DCC Decoder Dec_Dir_and_Fade.ino +// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018 +// Now works with both short and long DCC Addesses +// LED control is dependent on direction of travel and Fade can be added + // ******** 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 @@ -11,11 +13,12 @@ int tim_delay = 500; #define numleds 17 byte ledpins [] = {3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; //Defines all possible LED pins +// IMPORTANT: // The following list defines how each of the 17 function pins operate: // a 0 allows for normal On/Off control with fade on and fade off // a 1 allows for normal control when the decoder sees a forward speed setting, reverse turns the LED off // a 2 allows for normal control when the decoder sees a reverse speed setting, forward turns the LED off -byte led_direction [] = {0,1,2,0,1,1,1,1,2,2,2,2,0,0,0,0,0}; //0=On/Off, 1=On Forward, 2=On Reverse +byte led_direction [] = {0,1,2,0,1,1,1,1,2,2,2,1,1,1,2,0,0}; //0=On/Off, 1=On Forward, 2=On Reverse boolean led_last_state [] = {false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false}; //last state of led boolean Last_Function_State[] = {false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false}; //These hold the last Fx assignments @@ -46,18 +49,27 @@ NmraDcc Dcc ; DCC_MSG Packet ; uint8_t CV_DECODER_MASTER_RESET = 120; -#define This_Decoder_Address 24 struct CVPair { uint16_t CV; uint8_t Value; }; + +#define This_Decoder_Address 24 + CVPair FactoryDefaultCVs [] = { - {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address}, - {CV_ACCESSORY_DECODER_ADDRESS_MSB, 0}, - {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0}, - {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0}, + {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}, }; uint8_t FactoryDefaultCVIndex = 0; @@ -98,7 +110,7 @@ void setup() // Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up Dcc.pin(0, 2, 0); // Call the main DCC Init function to enable the DCC Receiver - Dcc.init( MAN_ID_DIY, 100, FLAGS_MY_ADDRESS_ONLY, 0 ); + Dcc.init( MAN_ID_DIY, 600, FLAGS_MY_ADDRESS_ONLY, 0 ); } void loop() { @@ -201,4 +213,4 @@ void Switch_LED (int Function) { } led_last_state[Function] = end_state; } - + diff --git a/examples/SMA/Dec_SMA12_LED_Groups/Dec_SMA12_LED_Groups.ino b/examples/SMA/Dec_SMA12_LED_Groups/Dec_SMA12_LED_Groups.ino index 7af8a0b..413678a 100755 --- a/examples/SMA/Dec_SMA12_LED_Groups/Dec_SMA12_LED_Groups.ino +++ b/examples/SMA/Dec_SMA12_LED_Groups/Dec_SMA12_LED_Groups.ino @@ -1,5 +1,7 @@ -// Production 17 Function DCC Decoder -// Version 5.4 Geoff Bunza 2014,2015,2016 +// Production 17 Function DCC Decoder Dec_SMA12_LED_Groups.ino +// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018 +// Now works with both short and long DCC Addesses + // NO LONGER REQUIRES modified software servo Lib // Software restructuring mods added from Alex Shepherd and Franz-Peter // With sincere thanks @@ -13,8 +15,8 @@ //#define DEBUG #include - int tim_delay = 500; + #define numleds 17 byte ledpins [] = {3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; byte FPins_Assigned [12][5] = { // This array defines the pins controlled by each function @@ -52,14 +54,17 @@ const int FunctionPin1 = 4; const int FunctionPin2 = 5; const int FunctionPin3 = 6; const int FunctionPin4 = 7; + const int FunctionPin5 = 8; const int FunctionPin6 = 9; const int FunctionPin7 = 10; const int FunctionPin8 = 11; + const int FunctionPin9 = 12; const int FunctionPin10 = 13; const int FunctionPin11 = 14; //A0 const int FunctionPin12 = 15; //A1 + const int FunctionPin13 = 16; //A2 const int FunctionPin14 = 17; //A3 const int FunctionPin15 = 18; //A4 @@ -67,24 +72,31 @@ const int FunctionPin16 = 19; //A5 NmraDcc Dcc ; DCC_MSG Packet ; uint8_t CV_DECODER_MASTER_RESET = 120; - -#define This_Decoder_Address 24 - struct CVPair { uint16_t CV; uint8_t Value; }; + +#define This_Decoder_Address 24 + CVPair FactoryDefaultCVs [] = { - {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address}, - {CV_ACCESSORY_DECODER_ADDRESS_MSB, 0}, - {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0}, - {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0}, + {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}, }; -uint8_t FactoryDefaultCVIndex = 0; +uint8_t FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair); void notifyCVResetFactoryDefault() { // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset @@ -112,7 +124,11 @@ void setup() delay (tim_delay/10); } delay( tim_delay); - + // Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up + Dcc.pin(0, 2, 0); + // Call the main DCC Init function to enable the DCC Receiver + Dcc.init( MAN_ID_DIY, 600, FLAGS_MY_ADDRESS_ONLY, 0 ); + delay(800); #if defined(DECODER_LOADED) if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET ) #endif @@ -123,18 +139,12 @@ void setup() delay (1000); digitalWrite(ledpins[14], 0); } - // Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up - Dcc.pin(0, 2, 0); - // Call the main DCC Init function to enable the DCC Receiver - Dcc.init( MAN_ID_DIY, 100, FLAGS_MY_ADDRESS_ONLY, 0 ); - delay(800); } void loop() { // You MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation Dcc.process(); } - void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { int f_index; switch (FuncGrp) { @@ -145,20 +155,17 @@ switch (FuncGrp) { exec_function( 3, (FuncState & FN_BIT_03)>>2 ); exec_function( 4, (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, (FuncState & FN_BIT_05)); exec_function( 6, (FuncState & FN_BIT_06)>>1 ); exec_function( 7, (FuncState & FN_BIT_07)>>2 ); exec_function( 8, (FuncState & FN_BIT_08)>>3 ); - break; - + break; case FN_9_12: exec_function( 9, (FuncState & FN_BIT_09)); exec_function( 10,(FuncState & FN_BIT_10)>>1 ); exec_function( 11,(FuncState & FN_BIT_11)>>2 ); break; - } } void exec_function (int f_index, int FuncState) { diff --git a/examples/SMA/Dec_Stepper_6Ftn/Dec_Stepper_6Ftn.ino b/examples/SMA/Dec_Stepper_6Ftn/Dec_Stepper_6Ftn.ino new file mode 100644 index 0000000..9bde9b7 --- /dev/null +++ b/examples/SMA/Dec_Stepper_6Ftn/Dec_Stepper_6Ftn.ino @@ -0,0 +1,508 @@ +// Production Stepper Drive DCC Decoder Dec_Stepper_6Ftn.ino +// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018 +// Now works with both short and long DCC Addesses + +// NO LONGER REQUIRES modified software servo Lib +// Software restructuring mods added from Alex Shepherd and Franz-Peter +// With sincere thanks +/* + * Stepper Motor Drive (4 Pins Bi dirrectional) uses the 2 Motor controls MOT1 and MOT2 + * F0 LED Pin 5 + * This is a “mobile/function” decoder that controls a single four wire stepper motor + * (5/12 Volt) via throttle speed setting and a multiplier which can be set in CV121. + * Stepper speed is pre-set in the sketch but can be changed. The library also supports + * setting acceleration/deceleration for the stepper. The other functions are configurable + * but are preset for LED on/off control. No servo motor control is available. + * Steppers whose coils need less than 500 ma can be accommodated. Each coil of the + * stepper attaches to MOT1 and MOT2. You may have to reverse the connections of one + * or the other until you get the connections right. The number of steps moved is set + * by the speed setting multiplied by the contents of CV 121. + * Every Off to On activation of F2 will move the stepper the specified number of steps, + * in the direction set by the DCC speed direction. +*/ +// ******** 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 +AccelStepper stepper(AccelStepper::FULL4WIRE, 3, 4, 9, 10); + +int servo_slow_counter = 0; //servo loop counter to slowdown servo transit +long Motor1Speed = 0; +uint8_t Motor1ForwardDir = 1; +uint8_t Motor1MaxSpeed = 127; +long Motor2Speed = 0; +uint8_t Motor2ForwardDir = 1; +uint8_t Motor2MaxSpeed = 127; +int kickstarton = 1400; //kick start cycle on time +int kickstarttime = 5; //kick start duration on time +int fwdon = 0; +int fwdtime = 1; +int bwdon = 0; +int bwdtime = 1; +int bwdshift = 0; +int cyclewidth = 2047; +int m2h = 3; //R H Bridge //Motor1 +int m2l = 4; //B H Bridge //Motor1 +int m0h = 9; //R H Bridge //Motor2 +int m0l = 10; //B H Bridge //Motor2 + +int speedup = 112; //Right track time differntial +int deltime = 1500; +int tim_delay = 100; +int numfpins = 17; +int num_active_fpins = 13; +byte fpins [] = {3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; +const int FunctionPin0 = 5; +const int FunctionPin1 = 6; +const int FunctionPin2 = 7; +const int FunctionPin3 = 8; +const int FunctionPin4 = 11; + +const int FunctionPin5 = 12; +const int FunctionPin6 = 13; +const int FunctionPin7 = 14; //A0 +const int FunctionPin8 = 15; //A1 + +const int FunctionPin9 = 16; //A2 +const int FunctionPin10 = 17; //A3 +const int FunctionPin11 = 18; //A4 +const int FunctionPin12 = 19; //A5 + +byte Function2_value = 0; +int Function13_value = 0; +int Function14_value = 0; + +NmraDcc Dcc ; +DCC_MSG Packet ; +uint8_t CV_DECODER_MASTER_RESET = 120; +uint8_t Motor_Multiplier = 121; +int t; // temp + +struct QUEUE +{ + int inuse; + int current_position; + int increment; + int stop_value; + int start_value; +}; +QUEUE *ftn_queue = new QUEUE[16]; +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}, // CV 120 + {Motor_Multiplier, 10}, // CV 121 + {30, 0}, //F0 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {31, 1}, //F0 Rate Blink=Eate,PWM=Rate,Servo=Rate + {32, 0}, //F0 Start Position F0=0 + {33, 8}, //F0 End Position F0=1 + {34, 1}, //F0 Current Position + {35, 0}, //F1 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {36, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {37, 0}, // Start Position Fx=0 + {38, 8}, // End Position Fx=1 + {39, 1}, // Current Position + {40, 0}, //F2 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {41, 10}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {42, 28}, // Start Position Fx=0 + {43, 140}, // End Position Fx=1 + {44, 0}, // Current Position + {45, 0}, //F3 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {46, 10}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {47, 28}, // Start Position Fx=0 + {48, 140}, // End Position Fx=1 + {49, 0}, // Current Position + {50, 0}, //F4 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {51, 10}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {52, 28}, // Start Position Fx=0 + {53, 140}, // End Position Fx=1 + {54, 0}, // Current Position + {55, 0}, //F5 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {56, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {57, 28}, // Start Position Fx=0 + {58, 140}, // End Position Fx=1 + {59, 28}, // Current Position + {60, 0}, //F6 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {61, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {62, 1}, // Start Position Fx=0 + {63, 255}, // End Position Fx=1 + {64, 28}, // Current Position + {65, 0}, //F7 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {66, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {67, 28}, // Start Position Fx=0 + {68,140}, // End Position Fx=1 + {69, 28}, // Current Position + {70, 0}, //F8 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {71, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {72, 28}, // Start Position Fx=0 + {73, 140}, // End Position Fx=1 + {74, 28}, // Current Position + {75, 0}, //F9 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {76, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {77, 28}, // Start Position Fx=0 + {78, 140}, // End Position Fx=1 + {79, 28}, // Current Position + {80, 0}, //F10 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {81, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {82, 1}, // Start Position Fx=0 + {83, 5}, // End Position Fx=1 + {84, 1}, // Current Position + {85, 0}, //F11 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {86, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {87, 1}, // Start Position Fx=0 + {88, 5}, // End Position Fx=1 + {89, 1}, // Current Position + {90, 0}, //F12 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {91, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {92, 1}, // Start Position Fx=0 + {93, 10}, // End Position Fx=1 + {94, 1}, // Current Position + {95, 0}, //F13 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {96, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {97, 1}, // Start Position Fx=0 + {98, 6}, // End Position Fx=1 + {99, 1}, // Current Position + {100, 0}, //F14 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {101, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {102, 1}, // Start Position Fx=0 + {103, 6}, // End Position Fx=1 + {104, 1}, // Current Position + {105, 0}, //F15 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {106, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {107, 1}, // Start Position Fx=0 + {108, 10}, // End Position Fx=1 + {109, 1}, // Current Position + {110, 0}, //F16 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {111, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {112, 1}, // Start Position Fx=0 + {113, 10}, // End Position Fx=1 + {114, 1}, // Current Position +//FUTURE USE + {115, 0}, //F17 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + {116, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate + {117, 28}, // Start Position Fx=0 + {118, 50}, // End Position Fx=1 + {119, 28}, // Current Position +}; + +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 + int i; + 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); + } + + // 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, 600, 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[14], 1); + delay (1000); + digitalWrite(fpins[14], 0); + } + for ( i=0; i < num_active_fpins; i++) { + cv_value = Dcc.getCV( 30+(i*5)) ; +#ifdef DEBUG + Serial.print(" cv_value: "); + Serial.println(cv_value, DEC) ; +#endif + stepper.setMaxSpeed(100.0); + stepper.setAcceleration(50.0); + stepper.moveTo(1); + switch ( cv_value ) { + case 0: // LED on/off + ftn_queue[i].inuse = 0; + break; + case 1: // LED Blink + { + ftn_queue[i].inuse = 0; + ftn_queue[i].current_position = 0; + ftn_queue[i].start_value = 0; + ftn_queue[i].increment = int (char (Dcc.getCV( 31+(i*5)))); + digitalWrite(fpins[i], 0); + ftn_queue[i].stop_value = int(Dcc.getCV( 33+(i*5))) ; + } + break; + case 2: //servo NOT AVAILABLE WITH THIS DECODER - STEPPER ONLY + break; + case 3: // DOUBLE ALTERNATING LED Blink + { + ftn_queue[i].inuse = 0; + ftn_queue[i].current_position = 0; + ftn_queue[i].start_value = 0; + ftn_queue[i].increment = Dcc.getCV( 31+(i*5)); + digitalWrite(fpins[i], 0); + digitalWrite(fpins[i+1], 0); + ftn_queue[i].stop_value = int(Dcc.getCV( 33+(i*5))); + } + break; + case 4: // Simple Pulsed Output based on saved Rate =10*Rate in Milliseconds + { + ftn_queue[i].inuse = 0; + ftn_queue[i].current_position = 0; + ftn_queue[i].increment = 10 * int (char (Dcc.getCV( 31+(i*5)))); + digitalWrite(fpins[i], 0); + } + break; + case 5: // Fade On + { + ftn_queue[i].inuse = 0; + ftn_queue[i].start_value = 0; + ftn_queue[i].increment = int (char (Dcc.getCV( 31+(i*5)))); + digitalWrite(fpins[i], 0); + ftn_queue[i].stop_value = int(Dcc.getCV( 33+(i*5))) *10.; + } + break; + case 6: // NEXT FEATURE to pin + break; + default: + break; + } + } +} +void loop() //********************************************************************** +{ + //MUST call the NmraDcc.process() method frequently + // from the Arduino loop() function for correct library operation + Dcc.process(); + delay(2); + stepper.run(); + //*************************Normal Function Processing follows + for (int i=0; i < num_active_fpins; i++) { + if (ftn_queue[i].inuse==1) { + switch (Dcc.getCV( 30+(i*5))) { + case 0: + break; + case 1: + ftn_queue[i].current_position = ftn_queue[i].current_position + ftn_queue[i].increment; + if (ftn_queue[i].current_position > ftn_queue[i].stop_value) { + ftn_queue[i].start_value = ~ftn_queue[i].start_value; + digitalWrite(fpins[i], ftn_queue[i].start_value); + ftn_queue[i].current_position = 0; + ftn_queue[i].stop_value = int(Dcc.getCV( 33+(i*5))); + } + break; + case 2: + break; + case 3: + ftn_queue[i].current_position = ftn_queue[i].current_position + ftn_queue[i].increment; + if (ftn_queue[i].current_position > ftn_queue[i].stop_value) { + ftn_queue[i].start_value = ~ftn_queue[i].start_value; + digitalWrite(fpins[i], ftn_queue[i].start_value); + digitalWrite(fpins[i]+1, ~ftn_queue[i].start_value); + ftn_queue[i].current_position = 0; + ftn_queue[i].stop_value = int(Dcc.getCV( 33+(i*5))); + } + i++; + break; + case 4: // Simple Pulsed Output based on saved Rate =10*Rate in Milliseconds + { + ftn_queue[i].inuse = 0; + ftn_queue[i].current_position = 0; + ftn_queue[i].increment = 10 * int (char (Dcc.getCV( 31+(i*5)))); + digitalWrite(fpins[i], 0); + } + break; + case 5: // Fade On + + break; + case 6: // NEXT FEATURE to pin + break; + default: + break; + } + } + } +} +void notifyDccSpeed( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Speed, DCC_DIRECTION ForwardDir, DCC_SPEED_STEPS SpeedSteps ) { + //if (Function13_value==1) { + Motor1Speed = Speed * Dcc.getCV( Motor_Multiplier); + //Motor1ForwardDir = ForwardDir & 1; + if (ForwardDir == DCC_DIR_REV) Motor1Speed = -Motor1Speed;; + //} +} +void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { + if (FuncGrp==FN_0_4 && ((FuncState & FN_BIT_02)>>1) == 1) { + if (Function2_value == 0) { + Function2_value=1; + stepper.move(Motor1Speed); + return; + } + } else if (FuncGrp==FN_0_4 && ((FuncState & FN_BIT_02)>>1) == 0) { + Function2_value = 0; + return; + } + 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 +// Function13_value = (FuncState & FN_BIT_13); +// Function14_value = (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; + } +} +void exec_function (int function, int pin, int FuncState) { +#ifdef DEBUG + Serial.print(" function: "); + Serial.println(function, DEC) ; + Serial.print(" pin: "); + Serial.println(pin, DEC) ; + Serial.print(" FuncState: "); + Serial.println(FuncState, DEC) ; + Serial.print(" Dcc.getCV( 30+(function*5)): "); + Serial.println(Dcc.getCV( 30+(function*5)), DEC) ; +#endif + if (function!=2) + switch ( Dcc.getCV( 30+(function*5)) ) { // Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade + case 0: // On - Off LED + digitalWrite (pin, FuncState); +#ifdef DEBUG + Serial.print(" Dcc.getCV( 30+(function*5)): "); + Serial.println(Dcc.getCV( 30+(function*5)), DEC) ; + Serial.print(" pin: "); + Serial.println(pin, DEC) ; + Serial.print(" FuncState: "); + Serial.println(FuncState, DEC) ; +#endif + ftn_queue[function].inuse = 0; + break; + case 1: // Blinking LED + if ((ftn_queue[function].inuse==0) && (FuncState==1)) { + ftn_queue[function].inuse = 1; + ftn_queue[function].start_value = 0; + digitalWrite(pin, 0); + ftn_queue[function].stop_value = int(Dcc.getCV( 33+(function*5))); + } else { + if ((ftn_queue[function].inuse==1) && (FuncState==0)) { + ftn_queue[function].inuse = 0; + digitalWrite(pin, 0); + } + } + break; + case 2: // Servo + break; + case 3: // Blinking LED PAIR + if ((ftn_queue[function].inuse==0) && (FuncState==1)) { + ftn_queue[function].inuse = 1; + ftn_queue[function].start_value = 0; + digitalWrite(fpins[function], 0); + digitalWrite(fpins[function+1], 1); + ftn_queue[function].stop_value = int(Dcc.getCV( 33+(function*5))); + } else { + if (FuncState==0) { + ftn_queue[function].inuse = 0; + digitalWrite(fpins[function], 0); + digitalWrite(fpins[function+1], 0); + } + } + break; + case 4: // Pulse Output based on Rate*10 Milliseconds + if ((ftn_queue[function].inuse==0) && (FuncState==1)) { //First Turn On Detected + digitalWrite(fpins[function], 1); + delay (10*ftn_queue[function].increment); + digitalWrite(fpins[function], 0); + ftn_queue[function].inuse = 1; //inuse set to 1 says we already pulsed + } else + if (FuncState==0) ftn_queue[function].inuse = 0; + break; + case 5: // Fade On +#define fadedelay 24 + if ((ftn_queue[function].inuse==0) && (FuncState==1)) { + ftn_queue[function].inuse = 1; + for (t=0; tmMEJWiPVx*+#tw* z-*ZXHmh)(~EwI2AsAF5?;e8z5d#-O&>x(26+Nto8)r(}jKTdO56r)s|MrEd|h379y zp%=+$GU?tIl0V(1h0)&6OS~DSMP+hnbz0Q+-$`0zOJSY#BRV#XRnpSAT)n-!d->uv z%}i-5w$a((v`|HUt(SG&y5rMR7&9_IVs=p{+BN<&)#7re4|sdg0Id~ za!AKZp|vb&dVEY%nQ>qo5n>tk+#+5|mO1-Sl)2K*-~RodpFVs({doQlT6$l<84fv` z<*pT~v_|B+OEaI}DCY-A%24CkaJ)B34(JY%0ETs?zx}SAX;Y5UtQg(lU*}#lPw1S! z!_d`gHE@|IWw2Oig{&x}gQ1U^_pS9$8&!Y@m9dg?=@Ao|Q)Uo1+hly$4w;(Cg15xx zD~KgZDho+4v5d{8@ofJ*34ArH$*$JQX?Z@7##X{nO^%nLG z9uGiS9EQWKbdJxBL7pSL@qjGD17mLx^p?ZX(v|W{I{ux;zmltErV5pX*!STl1G<#g zND53=8Ya&h9H71;IBYzEKHcAU{R0K7a<04{sZuS1@* z5>dbd#`uCV;%@pz><#FP!tv2HUK4}1_NNjzG?!EfyHHw`JV#DdP3eV}rg7M=G&N4**rkGbj?OQ>kYL{jeY^GtbP-}x_K{tQ64IV$ zxh^xG9W8}}jZ%}9yWUE1g_L>&n|-znesk>Z#|-odS3qZS>*Rw0CBG7VvdE||)S_X6 zwBaCkC4tEq!bOX*m3dp}qWNbguw&Zt;Z5qrJU$`j_-qWy&L*cHrn4`g-@7Ic3$Un9 z-U(p=@dEHOC#+KD0mvSM;L+^$iPw*z>;;stnO@ULn~(=M$(VtXOM5*#cmgT6>RRql zG7g9b5vvb$cnK2Bk`W{ILD(!h1kafw$*8{_nd>7YqX2REC<1myh{JCoOaej(%L5yd zNsADJ(zd!CqgU z(1)+0s!Q2Y6*A?0Y}(v!&>hj9D)AK!uOd^h`;IH$7O|l!c+ZLY%6l?n`EJq}y{m+b zrN3gBP?}X7{>1*)zZMV;ES(oJHn@M`8lDj1?ix2odX|f^IP{N!EI472)7`z<8CtmNTF7iFU1n7sR4its(14?ck-73w+;Pt> z7(W4>#P+j!h4Y|D~wrDgF>CRAJ?)) zF{O9~Yg}XtM2c`kEl5`~*Q#nje=H$*MEjhfoHx+K5VJmL9tjPJOmjNC6|5A|!Pl_L zL%fwGOS@M*F!22Nismk2%7cxlT|0jq zR?_I`LJu#BVkbFzUn+gIGd^M|VRj}*)Ay&Le#Yyi9va1|ENIYrcMn- zWZb{7zZ1Wl0?~cI7>R)bk#46VFh+hwR%lxuhm@}k?dnPh|BP4WW~GTH;Mi~&lTvae z$xH(xTIl6Uwc|LJ9LK=m_X;Yksc6LY1;0fQ?e2ysFV$j+U13sbs(JgC&uQOwB% zD*v+OT3^J+sWk|1oYD?Aj}Aa6n*4Kv+puxN7B;0Fn0C)pW+4@p_`&4

tSriDv|HShI!H7uEdqdr=-&)&b>7UEK>`r%QiWSob|j cepp*?q5L>KJ8!n8494#MKc%$sOYvX+1H*o$q5uE@ literal 0 HcmV?d00001 From 2b12179152f3a868bf8de9851ab0ab4d5b5c0139 Mon Sep 17 00:00:00 2001 From: Geoff Bunza Date: Thu, 5 Jul 2018 16:13:14 -0700 Subject: [PATCH 2/7] Delete Dec_2MotDrive_12LED_1Srv_6Ftn.ino --- .../Dec_2MotDrive_12LED_1Srv_6Ftn.ino | 573 ------------------ 1 file changed, 573 deletions(-) delete mode 100755 examples/SMA/Dec_2MotDrive_12LED_1Srv_6Ftn/Dec_2MotDrive_12LED_1Srv_6Ftn.ino diff --git a/examples/SMA/Dec_2MotDrive_12LED_1Srv_6Ftn/Dec_2MotDrive_12LED_1Srv_6Ftn.ino b/examples/SMA/Dec_2MotDrive_12LED_1Srv_6Ftn/Dec_2MotDrive_12LED_1Srv_6Ftn.ino deleted file mode 100755 index 3374fb3..0000000 --- a/examples/SMA/Dec_2MotDrive_12LED_1Srv_6Ftn/Dec_2MotDrive_12LED_1Srv_6Ftn.ino +++ /dev/null @@ -1,573 +0,0 @@ -// Production 17 Function DCC Decoder -// Version 5.4 Geoff Bunza 2014,2015,2016 -// NO LONGER REQUIRES modified software servo Lib -// Software restructuring mods added from Alex Shepherd and Franz-Peter -// With sincere thanks - -// ******** 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 - -SoftwareServo servo[13]; -#define servo_start_delay 50 -#define servo_init_delay 7 -#define servo_slowdown 3 //servo loop counter limit -int servo_slow_counter = 0; //servo loop counter to slowdown servo transit - -uint8_t Motor1Speed = 0; -uint8_t Motor1ForwardDir = 1; -uint8_t Motor1MaxSpeed = 127; -uint8_t Motor2Speed = 0; -uint8_t Motor2ForwardDir = 1; -uint8_t Motor2MaxSpeed = 127; -int kickstarton = 1400; //kick start cycle on time -int kickstarttime = 5; //kick start duration on time -int fwdon = 0; -int fwdtime = 1; -int bwdon = 0; -int bwdtime = 1; -int bwdshift = 0; -int cyclewidth = 2047; -int m2h = 3; //R H Bridge //Motor1 -int m2l = 4; //B H Bridge //Motor1 -int m0h = 9; //R H Bridge //Motor2 -int m0l = 10; //B H Bridge //Motor2 - -int speedup = 112; //Right track time differntial -int deltime = 1500; -int tim_delay = 100; -int numfpins = 17; -int num_active_fpins = 13; -byte fpins [] = {3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; -const int FunctionPin0 = 5; -const int FunctionPin1 = 6; -const int FunctionPin2 = 7; -const int FunctionPin3 = 8; -const int FunctionPin4 = 11; - -const int FunctionPin5 = 12; -const int FunctionPin6 = 13; -const int FunctionPin7 = 14; //A0 -const int FunctionPin8 = 15; //A1 - -const int FunctionPin9 = 16; //A2 -const int FunctionPin10 = 17; //A3 -const int FunctionPin11 = 18; //A4 -const int FunctionPin12 = 19; //A5 - -int Function13_value = 0; -int Function14_value = 0; - -NmraDcc Dcc ; -DCC_MSG Packet ; -uint8_t CV_DECODER_MASTER_RESET = 120; -int t; // temp -#define This_Decoder_Address 24 -struct QUEUE -{ - int inuse; - int current_position; - int increment; - int stop_value; - int start_value; -}; -QUEUE *ftn_queue = new QUEUE[16]; - -extern uint8_t Decoder_Address = This_Decoder_Address; -struct CVPair -{ - uint16_t CV; - uint8_t Value; -}; -CVPair FactoryDefaultCVs [] = -{ - {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address}, - {CV_ACCESSORY_DECODER_ADDRESS_MSB, 0}, - {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0}, - {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0}, - {CV_DECODER_MASTER_RESET, 0}, - {30, 0}, //F0 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade - {31, 1}, //F0 Rate Blink=Eate,PWM=Rate,Servo=Rate - {32, 0}, //F0 Start Position F0=0 - {33, 8}, //F0 End Position F0=1 - {34, 1}, //F0 Current Position - {35, 0}, //F1 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade - {36, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate - {37, 0}, // Start Position Fx=0 - {38, 8}, // End Position Fx=1 - {39, 1}, // Current Position - {40, 0}, //F2 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade - {41, 10}, // Rate Blink=Eate,PWM=Rate,Servo=Rate - {42, 28}, // Start Position Fx=0 - {43, 140}, // End Position Fx=1 - {44, 0}, // Current Position - {45, 0}, //F3 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade - {46, 10}, // Rate Blink=Eate,PWM=Rate,Servo=Rate - {47, 28}, // Start Position Fx=0 - {48, 140}, // End Position Fx=1 - {49, 0}, // Current Position - {50, 0}, //F4 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade - {51, 10}, // Rate Blink=Eate,PWM=Rate,Servo=Rate - {52, 28}, // Start Position Fx=0 - {53, 140}, // End Position Fx=1 - {54, 0}, // Current Position - {55, 0}, //F5 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade - {56, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate - {57, 28}, // Start Position Fx=0 - {58, 140}, // End Position Fx=1 - {59, 28}, // Current Position - {60, 0}, //F6 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade - {61, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate - {62, 28}, // Start Position Fx=0 - {63, 140}, // End Position Fx=1 - {64, 28}, // Current Position - {65, 0}, //F7 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade - {66, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate - {67, 28}, // Start Position Fx=0 - {68,140}, // End Position Fx=1 - {69, 28}, // Current Position - {70, 0}, //F8 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade - {71, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate - {72, 28}, // Start Position Fx=0 - {73, 140}, // End Position Fx=1 - {74, 28}, // Current Position - {75, 0}, //F9 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade - {76, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate - {77, 28}, // Start Position Fx=0 - {78, 140}, // End Position Fx=1 - {79, 28}, // Current Position - {80, 0}, //F10 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade - {81, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate - {82, 1}, // Start Position Fx=0 - {83, 5}, // End Position Fx=1 - {84, 1}, // Current Position - {85, 1}, //F11 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade - {86, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate - {87, 1}, // Start Position Fx=0 - {88, 5}, // End Position Fx=1 - {89, 1}, // Current Position - {90, 2}, //F12 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade - {91, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate - {92, 1}, // Start Position Fx=0 - {93, 10}, // End Position Fx=1 - {94, 1}, // Current Position - {95, 0}, //F13 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade - {96, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate - {97, 1}, // Start Position Fx=0 - {98, 6}, // End Position Fx=1 - {99, 1}, // Current Position - {100, 0}, //F14 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade - {101, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate - {102, 1}, // Start Position Fx=0 - {103, 6}, // End Position Fx=1 - {104, 1}, // Current Position - {105, 3}, //F15 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade - {106, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate - {107, 1}, // Start Position Fx=0 - {108, 10}, // End Position Fx=1 - {109, 1}, // Current Position - {110, 0}, //F16 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade - {111, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate - {112, 1}, // Start Position Fx=0 - {113, 10}, // End Position Fx=1 - {114, 1}, // Current Position -//FUTURE USE - {115, 0}, //F17 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade - {116, 1}, // Rate Blink=Eate,PWM=Rate,Servo=Rate - {117, 28}, // Start Position Fx=0 - {118, 50}, // End Position Fx=1 - {119, 28}, // Current Position -}; - -uint8_t FactoryDefaultCVIndex = 95; -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); -}; - -void setup() //****************************************************** -{ -#ifdef DEBUG - Serial.begin(115200); -#endif - int i; - 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); - } - for (int i=0; i < numfpins; i++) { - digitalWrite(fpins[i], 1); - delay (tim_delay/10); - } - delay( tim_delay); - for (int i=0; i < numfpins; i++) { - digitalWrite(fpins[i], 0); - delay (tim_delay/10); - } - delay( tim_delay); - - // 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, 100, 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[14], 1); - delay (1000); - digitalWrite(fpins[14], 0); - } - for ( i=0; i < num_active_fpins; i++) { - cv_value = Dcc.getCV( 30+(i*5)) ; -#ifdef DEBUG - Serial.print(" cv_value: "); - Serial.println(cv_value, DEC) ; -#endif - switch ( cv_value ) { - case 0: // LED on/off - ftn_queue[i].inuse = 0; - break; - case 1: // LED Blink - { - ftn_queue[i].inuse = 0; - ftn_queue[i].current_position = 0; - ftn_queue[i].start_value = 0; - ftn_queue[i].increment = int (char (Dcc.getCV( 31+(i*5)))); - digitalWrite(fpins[i], 0); - ftn_queue[i].stop_value = int(Dcc.getCV( 33+(i*5))) ; - } - break; - case 2: //servo - { - ftn_queue[i].current_position =int (Dcc.getCV( 34+(i*5))); - ftn_queue[i].stop_value = int (Dcc.getCV( 33+(i*5))); - ftn_queue[i].start_value = int (Dcc.getCV( 32+(i*5))); - ftn_queue[i].increment = -int (char (Dcc.getCV( 31+(i*5)))); - // attaches servo on pin to the servo object - servo[i].attach(fpins[i]); - -#ifdef DEBUG - Serial.print("InitServo ID= "); - Serial.println(i, DEC) ; -#endif - servo[i].write(ftn_queue[i].start_value); - for (t=0; t ftn_queue[i].stop_value) { - ftn_queue[i].start_value = ~ftn_queue[i].start_value; - digitalWrite(fpins[i], ftn_queue[i].start_value); - ftn_queue[i].current_position = 0; - ftn_queue[i].stop_value = int(Dcc.getCV( 33+(i*5))); - } - break; - case 2: - { - if (servo_slow_counter++ > servo_slowdown) - { - ftn_queue[i].current_position = ftn_queue[i].current_position + ftn_queue[i].increment; - if (ftn_queue[i].increment > 0) { - if (ftn_queue[i].current_position > ftn_queue[i].stop_value) { - ftn_queue[i].current_position = ftn_queue[i].stop_value; - ftn_queue[i].inuse = 0; - servo[i].detach(); - } - } - if (ftn_queue[i].increment < 0) { - if (ftn_queue[i].current_position < ftn_queue[i].start_value) { - ftn_queue[i].current_position = ftn_queue[i].start_value; - ftn_queue[i].inuse = 0; - servo[i].detach(); - } - } - servo[i].write(ftn_queue[i].current_position); - servo_slow_counter = 0; - } - } - break; - case 3: - ftn_queue[i].current_position = ftn_queue[i].current_position + ftn_queue[i].increment; - if (ftn_queue[i].current_position > ftn_queue[i].stop_value) { - ftn_queue[i].start_value = ~ftn_queue[i].start_value; - digitalWrite(fpins[i], ftn_queue[i].start_value); - digitalWrite(fpins[i]+1, ~ftn_queue[i].start_value); - ftn_queue[i].current_position = 0; - ftn_queue[i].stop_value = int(Dcc.getCV( 33+(i*5))); - } - i++; - break; - case 4: // Simple Pulsed Output based on saved Rate =10*Rate in Milliseconds - { - ftn_queue[i].inuse = 0; - ftn_queue[i].current_position = 0; - ftn_queue[i].increment = 10 * int (char (Dcc.getCV( 31+(i*5)))); - digitalWrite(fpins[i], 0); - } - break; - case 5: // Fade On - - break; - case 6: // NEXT FEATURE to pin - break; - default: - break; - } - } - } -} -void gofwd1(int fcnt,int fcycle) { - int icnt; - int totcycle; - icnt = 0; - while (icnt < fcnt) - { - digitalWrite(m2h, HIGH); //Motor1 - delayMicroseconds(fcycle); - digitalWrite(m2h, LOW); //Motor1 - delayMicroseconds(cyclewidth - fcycle); - icnt++; - } -} -void gobwd1(int bcnt,int bcycle) { - int icnt; - icnt=0; - while (icnt < bcnt) - { - digitalWrite(m2l, HIGH); //Motor1 - delayMicroseconds(bcycle); - digitalWrite(m2l, LOW); //Motor1 - delayMicroseconds(cyclewidth - bcycle); - icnt++; - } -} -void gofwd2(int fcnt,int fcycle) { - int icnt; - int totcycle; - icnt = 0; - while (icnt < fcnt) - { - digitalWrite(m0h, HIGH); //Motor2 - delayMicroseconds(fcycle); - digitalWrite(m0h, LOW); //Motor2 - delayMicroseconds(cyclewidth - fcycle); - icnt++; - } -} -void gobwd2(int bcnt,int bcycle) { - int icnt; - icnt=0; - while (icnt < bcnt) - { - digitalWrite(m0l, HIGH); //Motor2 - delayMicroseconds(bcycle); - digitalWrite(m0l, LOW); //Motor2 - delayMicroseconds(cyclewidth - bcycle); - icnt++; - } -} -void notifyDccSpeed( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Speed, DCC_DIRECTION ForwardDir, DCC_SPEED_STEPS SpeedSteps ) { - if (Function13_value==1) { - Motor1Speed = Speed; - Motor1ForwardDir = ForwardDir; - } - if (Function14_value==1) { - Motor2Speed = Speed; - Motor2ForwardDir = ForwardDir; - } -} - -void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) { - 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 - Function13_value = (FuncState & FN_BIT_13); - Function14_value = (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; - } -} -void exec_function (int function, int pin, int FuncState) { - switch ( Dcc.getCV( 30+(function*5)) ) { // Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade - case 0: // On - Off LED - digitalWrite (pin, FuncState); - ftn_queue[function].inuse = 0; - break; - case 1: // Blinking LED - if ((ftn_queue[function].inuse==0) && (FuncState==1)) { - ftn_queue[function].inuse = 1; - ftn_queue[function].start_value = 0; - digitalWrite(pin, 0); - ftn_queue[function].stop_value = int(Dcc.getCV( 33+(function*5))); - } else { - if ((ftn_queue[function].inuse==1) && (FuncState==0)) { - ftn_queue[function].inuse = 0; - digitalWrite(pin, 0); - } - } - break; - case 2: // Servo - if (ftn_queue[function].inuse == 0) { - ftn_queue[function].inuse = 1; - servo[function].attach(pin); - } - if (FuncState==1) ftn_queue[function].increment = char ( Dcc.getCV( 31+(function*5))); - else ftn_queue[function].increment = - char(Dcc.getCV( 31+(function*5))); - if (FuncState==1) ftn_queue[function].stop_value = Dcc.getCV( 33+(function*5)); - else ftn_queue[function].stop_value = Dcc.getCV( 32+(function*5)); - break; - case 3: // Blinking LED PAIR - if ((ftn_queue[function].inuse==0) && (FuncState==1)) { - ftn_queue[function].inuse = 1; - ftn_queue[function].start_value = 0; - digitalWrite(fpins[function], 0); - digitalWrite(fpins[function+1], 1); - ftn_queue[function].stop_value = int(Dcc.getCV( 33+(function*5))); - } else { - if (FuncState==0) { - ftn_queue[function].inuse = 0; - digitalWrite(fpins[function], 0); - digitalWrite(fpins[function+1], 0); - } - } - break; - case 4: // Pulse Output based on Rate*10 Milliseconds - if ((ftn_queue[function].inuse==0) && (FuncState==1)) { //First Turn On Detected - digitalWrite(fpins[function], 1); - delay (10*ftn_queue[function].increment); - digitalWrite(fpins[function], 0); - ftn_queue[function].inuse = 1; //inuse set to 1 says we already pulsed - } else - if (FuncState==0) ftn_queue[function].inuse = 0; - break; - case 5: // Fade On -#define fadedelay 24 - if ((ftn_queue[function].inuse==0) && (FuncState==1)) { - ftn_queue[function].inuse = 1; - for (t=0; t Date: Thu, 5 Jul 2018 16:14:20 -0700 Subject: [PATCH 3/7] Delete SMA 5.4 Release Notes.txt --- examples/SMA/SMA 5.4 Release Notes.txt | 47 -------------------------- 1 file changed, 47 deletions(-) delete mode 100644 examples/SMA/SMA 5.4 Release Notes.txt diff --git a/examples/SMA/SMA 5.4 Release Notes.txt b/examples/SMA/SMA 5.4 Release Notes.txt deleted file mode 100644 index dd51080..0000000 --- a/examples/SMA/SMA 5.4 Release Notes.txt +++ /dev/null @@ -1,47 +0,0 @@ -Release Notes for the 5.4 SMA Decoder Examples -1. Buf fix to allow maximum of 17 servos - -2. Bug Fix to correct 2 reload #define definitions - -3. Change to major Loop Delay cut in half to allow for fewer misses of DCC packet detection - -4. File Decoders_MultiFunction_Description.rtf has minor edits for new file names and 6FTN version. - -Release Notes for the 5.1 SMA Decoder Examples - -1. Automatic servo attachment and detachment has been implemented for all - servo control functions. When a servo has stopped at the end of its traverse, - it will be "detached" by the software. This has been demonstrated - to reduce power consumption greatly and reduce servo "chatter." - -2. Several bug fixes including all reported bugs as of May 2016 - -3. In the fully conficurable verions. all 17 pins now can be configured for any of 6 functions - Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=variable Pulse ,5=fade on - -4. Servo timing has a timing modifier added for extra slow servo traverse - #define servo_slowdown 3 //servo loop counter limit - Can be set from 0 to 255 -- the higher the number the slower the traverse - -5. Software has been restructured to support new NmraDcc library releases - including the NmraDcc-MicroBahner library version. - -6. 18 Predefined decoder skectekes are included: -Mobile Decoders: - Dec_2MotDrive_12LED_1Srv_6Ftn Dual motor drive, 12 LED 6 Function - Dec_7Serv_10LED_6Ftn 7 Servo 10 LED 6 Function - Dec_10Serv_7LED_6Ftn 10 Servo 7 LED 6 Function - Dec_13Serv_4LED_6Ftn 13 Servo 4 LED 6 Function - Dec_15Serv_2LED_6Ftn 15 Servo 2 LED 6 Function - Dec_17LED_1Ftn 17 LED ON/OFF Control - Dec_17LED_6Ftn 17 LED 6 Function - Dec_Dir_and_Fade 17 LED with Dual Direction Control and FADE - Dec_SMA12_LED_Groups LED Group Control for Euro Signaling -Accessory Decoders: - AccDec_7ServoBackandForth6Ftn 7 Servo 10 LED 6 Function - AccDec_7Servos_10LED_6Ftn 7 Servo 10 LED 6 Function - AccDec_10Servos_7LED_6Ftn 10 Servo 7 LED 6 Function - AccDec_13Servos_4LED_6Ftn 13 Servo 4 LED 6 Function - AccDec_15Servos_2LED_6Ftn 15 Servo 2 LED 6 Function - AccDec_17LED_1Ftn 17 LED ON/OFF Control - AccDec_17LED_6Ftn 17 LED 6 Function \ No newline at end of file From 32c559787021f3225af1fb2fd256908ee9090955 Mon Sep 17 00:00:00 2001 From: Franz-Peter Date: Sat, 7 Jul 2018 03:26:51 +0200 Subject: [PATCH 4/7] Additional changes regarding output addressing and new callback notifyDccCVChanged() (#17) * outputaddressing corrected declared notifyDccAccState for backward compatibility * version define in NmraDcc.h * DB_PRINT introduced Changed debug printing to a macro. Added cv29 to CV-addresses that reset caching of myAddress * Corrections regarding Outputaddressing OutputAddress must be a signed variable * Changes/additions regarding output addressing and CVChange callback Change Flag FLAGS_OUTPUT_ADDRESS_MODE accordingly, when CV29 Bit 6 (output addressing) is changed. New callback 'notifyDccCVChange' which is NOT called if the CV is changed by means of the setCV() method * Shorten Debug Messages Because of Buffer overrun in the serial output. This leads to blocking Serial.write() calls * notifyDccSigState restored Restore the old callback notifyDccSigState for compatibiltity to version 1.4.2 * switch off debug printing --- NmraDcc.cpp | 91 ++++++++++++++++++++++++++++++++--------------------- NmraDcc.h | 21 +++++++++++-- 2 files changed, 74 insertions(+), 38 deletions(-) diff --git a/NmraDcc.cpp b/NmraDcc.cpp index 9df1429..29ab28d 100644 --- a/NmraDcc.cpp +++ b/NmraDcc.cpp @@ -39,7 +39,7 @@ #endif // Uncomment to print DEBUG messages -// #define DEBUG_PRINT +//#define DEBUG_PRINT //------------------------------------------------------------------------ // DCC Receive Routine @@ -581,11 +581,14 @@ uint8_t writeCV( unsigned int CV, uint8_t Value) { switch( CV ) { + case CV_29_CONFIG: + // copy addressmode Bit to Flags + DccProcState.Flags = ( DccProcState.Flags & ~FLAGS_OUTPUT_ADDRESS_MODE) | (Value & FLAGS_OUTPUT_ADDRESS_MODE); + // no break, because myDccAdress must also be reset case CV_ACCESSORY_DECODER_ADDRESS_LSB: // Also same CV for CV_MULTIFUNCTION_PRIMARY_ADDRESS case CV_ACCESSORY_DECODER_ADDRESS_MSB: case CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB: case CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB: - case CV_29_CONFIG: DccProcState.myDccAddress = -1; // Assume any CV Write Operation might change the Address } @@ -598,6 +601,10 @@ uint8_t writeCV( unsigned int CV, uint8_t Value) if( notifyCVChange ) notifyCVChange( CV, Value) ; + if( notifyDccCVChange && !(DccProcState.Flags & FLAGS_SETCV_CALLED) ) + notifyDccCVChange( CV, Value ); + + DccProcState.Flags &= ~FLAGS_SETCV_CALLED; } return readEEPROM( CV ) ; } @@ -882,11 +889,10 @@ void processServiceModeOperation( DCC_MSG * pDccMsg ) { uint16_t CVAddr ; uint8_t Value ; - if( pDccMsg->Size == 3) // 3 Byte Packets are for Address Only, Register and Paged Mode { uint8_t RegisterAddr ; - + DB_PRINT("3-BytePkt"); RegisterAddr = pDccMsg->Data[0] & 0x07 ; Value = pDccMsg->Data[1] ; @@ -928,7 +934,7 @@ void processServiceModeOperation( DCC_MSG * pDccMsg ) } else if( pDccMsg->Size == 4) // 4 Byte Packets are for Direct Byte & Bit Mode - { + { DB_PRINT("BB-Mode"); CVAddr = ( ( ( pDccMsg->Data[0] & 0x03 ) << 8 ) | pDccMsg->Data[1] ) + 1 ; Value = pDccMsg->Data[2] ; @@ -1048,46 +1054,48 @@ void execDccProcessor( DCC_MSG * pDccMsg ) { if( DccProcState.Flags & FLAGS_DCC_ACCESSORY_DECODER ) { - uint16_t BoardAddress ; - uint16_t OutputAddress ; + int16_t BoardAddress ; + int16_t OutputAddress ; uint8_t TurnoutPairIndex ; #ifdef DEBUG_PRINT - SerialPrintPacketHex(F( "execDccProcessor: Accessory Decoder Command: "), pDccMsg); + SerialPrintPacketHex(F( "eDP: AccCmd: "), pDccMsg); #endif BoardAddress = ( ( (~pDccMsg->Data[1]) & 0b01110000 ) << 2 ) | ( pDccMsg->Data[0] & 0b00111111 ) ; - DB_PRINT("execDccProcessor: Board Addr: %d", BoardAddress); + TurnoutPairIndex = (pDccMsg->Data[1] & 0b00000110) >> 1; + DB_PRINT("eDP: BAddr:%d, Index:%d", BoardAddress, TurnoutPairIndex); + // First check for Legacy Accessory Decoder Configuration Variable Access Instruction // as it's got a different format to the others if((pDccMsg->Size == 5) && ((pDccMsg->Data[1] & 0b10001100) == 0b00001100)) { - DB_PRINT( "execDccProcessor: Legacy Accessory Decoder CV Access Command"); + DB_PRINT( "eDP: Legacy Accessory Decoder CV Access Command"); // Check if this command is for our address or the broadcast address if((BoardAddress != getMyAddr()) && ( BoardAddress < 511 )) { - DB_PRINT("execDccProcessor: Board Address Not Matched"); + DB_PRINT("eDP: Board Address Not Matched"); return; } uint16_t cvAddress = ((pDccMsg->Data[1] & 0b00000011) << 8) + pDccMsg->Data[2] + 1; uint8_t cvValue = pDccMsg->Data[3]; - DB_PRINT("execDccProcessor: CV: %d Value: %d", cvAddress, cvValue ); + DB_PRINT("eDP: CV:%d Value:%d", cvAddress, cvValue ); if(validCV( cvAddress, 1 )) writeCV(cvAddress, cvValue); return; } - TurnoutPairIndex = (pDccMsg->Data[1] & 0b00000110) >> 1; OutputAddress = (((BoardAddress - 1) << 2 ) | TurnoutPairIndex) + 1 ; //decoder output addresses start with 1, packet address range starts with 0 // ( according to NMRA 9.2.2 ) + DB_PRINT("eDP: OAddr:%d", OutputAddress); if( DccProcState.inAccDecDCCAddrNextReceivedMode) { if( DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE ) { - DB_PRINT("execDccProcessor: Set Output Addr: %d", OutputAddress); + DB_PRINT("eDP: Set OAddr:%d", OutputAddress); //uint16_t storedOutputAddress = OutputAddress + 1; // The value stored in CV1 & 9 for Output Addressing Mode is + 1 writeCV(CV_ACCESSORY_DECODER_ADDRESS_LSB, (uint8_t)(OutputAddress % 256)); writeCV(CV_ACCESSORY_DECODER_ADDRESS_MSB, (uint8_t)(OutputAddress / 256)); @@ -1097,7 +1105,7 @@ void execDccProcessor( DCC_MSG * pDccMsg ) } else { - DB_PRINT("execDccProcessor: Set Board Addr: %d", BoardAddress); + DB_PRINT("eDP: Set BAddr:%d", BoardAddress); writeCV(CV_ACCESSORY_DECODER_ADDRESS_LSB, (uint8_t)(BoardAddress % 64)); writeCV(CV_ACCESSORY_DECODER_ADDRESS_MSB, (uint8_t)(BoardAddress / 64)); @@ -1111,21 +1119,32 @@ void execDccProcessor( DCC_MSG * pDccMsg ) // If we're filtering addresses, does the address match our address or is it a broadcast address? If NOT then return if( DccProcState.Flags & FLAGS_MY_ADDRESS_ONLY ) { - if( ( DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE ) && ( OutputAddress != getMyAddr() ) && ( OutputAddress < 2045 ) ) - return; - - else if( ( BoardAddress != getMyAddr() ) && ( BoardAddress < 511 ) ) - return; - - DB_PRINT("execDccProcessor: Address Matched"); + if( DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE ) { + DB_PRINT(" AddrChk: OAddr:%d, BAddr:%d, myAddr:%d Chk=%d", OutputAddress, BoardAddress, getMyAddr(), OutputAddress != getMyAddr() ); + if ( OutputAddress != getMyAddr() && OutputAddress < 2045 ) { + DB_PRINT(" eDP: OAddr:%d, myAddr:%d - no match", OutputAddress, getMyAddr() ); + return; + } + } else { + if( ( BoardAddress != getMyAddr() ) && ( BoardAddress < 511 ) ) { + DB_PRINT(" eDP: BAddr:%d, myAddr:%d - no match", BoardAddress, getMyAddr() ); + return; + } + } + DB_PRINT("eDP: Address Matched"); } + if((pDccMsg->Size == 4) && ((pDccMsg->Data[1] & 0b10001001) == 1)) // Extended Accessory Decoder Control Packet Format { uint8_t state = pDccMsg->Data[2] ;// & 0b00011111; - DB_PRINT("execDccProcessor: Output Addr: %d Extended State: %0X", OutputAddress, state); + DB_PRINT("eDP: OAddr:%d Extended State:%0X", OutputAddress, state); if( notifyDccSigOutputState ) notifyDccSigOutputState(OutputAddress, state); + + // old callback ( for compatibility with 1.4.2, not to be used in new designs ) + if( notifyDccSigState ) + notifyDccSigState( OutputAddress, TurnoutPairIndex, pDccMsg->Data[2] ) ; } else if(pDccMsg->Size == 3) // Basic Accessory Decoder Packet Format @@ -1133,49 +1152,49 @@ void execDccProcessor( DCC_MSG * pDccMsg ) uint8_t direction = pDccMsg->Data[1] & 0b00000001; uint8_t outputPower = (pDccMsg->Data[1] & 0b00001000) >> 3; - // for compatibility with 1.4.2 + // old callback ( for compatibility with 1.4.2, not to be used in new designs ) if ( notifyDccAccState ) notifyDccAccState( OutputAddress, BoardAddress, pDccMsg->Data[1] & 0b00000111, outputPower ); if( DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE ) { - DB_PRINT("execDccProcessor: Output Addr: %d Turnout Dir: %d Output Power: %d", OutputAddress, direction, outputPower); + DB_PRINT("eDP: OAddr:%d Turnout Dir:%d Output Power:%d", OutputAddress, direction, outputPower); if( notifyDccAccTurnoutOutput ) notifyDccAccTurnoutOutput( OutputAddress, direction, outputPower ); } else { - DB_PRINT("execDccProcessor: Turnout Pair Index: %d Dir: %d Output Power: ", TurnoutPairIndex, direction, outputPower); + DB_PRINT("eDP: Turnout Pair Index:%d Dir:%d Output Power: ", TurnoutPairIndex, direction, outputPower); if( notifyDccAccTurnoutBoard ) notifyDccAccTurnoutBoard( BoardAddress, TurnoutPairIndex, direction, outputPower ); } } else if(pDccMsg->Size == 6) // Accessory Decoder OPS Mode Programming { - DB_PRINT("execDccProcessor: OPS Mode CV Programming Command"); + DB_PRINT("eDP: OPS Mode CV Programming Command"); // Check for unsupported OPS Mode Addressing mode if(((pDccMsg->Data[1] & 0b10001001) != 1) && ((pDccMsg->Data[1] & 0b10001111) != 0x80)) { - DB_PRINT("execDccProcessor: Unsupported OPS Mode CV Addressing Mode"); + DB_PRINT("eDP: Unsupported OPS Mode CV Addressing Mode"); return; } // Check if this command is for our address or the broadcast address if(DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE) { - DB_PRINT("execDccProcessor: Check Output Address: %d", OutputAddress); + DB_PRINT("eDP: Check Output Address:%d", OutputAddress); if((OutputAddress != getMyAddr()) && ( OutputAddress < 2045 )) { - DB_PRINT("execDccProcessor: Output Address Not Matched"); + DB_PRINT("eDP: Output Address Not Matched"); return; } } else { - DB_PRINT("execDccProcessor: Check Board Address: %d", BoardAddress); + DB_PRINT("eDP: Check Board Address:%d", BoardAddress); if((BoardAddress != getMyAddr()) && ( BoardAddress < 511 )) { - DB_PRINT("execDccProcessor: Board Address Not Matched"); + DB_PRINT("eDP: Board Address Not Matched"); return; } } @@ -1185,16 +1204,16 @@ void execDccProcessor( DCC_MSG * pDccMsg ) OpsInstructionType insType = (OpsInstructionType)((pDccMsg->Data[2] & 0b00001100) >> 2) ; - DB_PRINT("execDccProcessor: OPS Mode Instruction: %d", insType); + DB_PRINT("eDP: OPS Mode Instruction:%d", insType); switch(insType) { case OPS_INS_RESERVED: case OPS_INS_VERIFY_BYTE: - DB_PRINT("execDccProcessor: Unsupported OPS Mode Instruction: %d", insType); + DB_PRINT("eDP: Unsupported OPS Mode Instruction:%d", insType); break; // We only support Write Byte or Bit Manipulation case OPS_INS_WRITE_BYTE: - DB_PRINT("execDccProcessor: CV: %d Value: %d", cvAddress, cvValue); + DB_PRINT("eDP: CV:%d Value:%d", cvAddress, cvValue); if(validCV( cvAddress, 1 )) writeCV(cvAddress, cvValue); break; @@ -1314,6 +1333,7 @@ uint8_t NmraDcc::getCV( uint16_t CV ) //////////////////////////////////////////////////////////////////////// uint8_t NmraDcc::setCV( uint16_t CV, uint8_t Value) { + DccProcState.Flags |= FLAGS_SETCV_CALLED; return writeCV(CV,Value); } @@ -1398,6 +1418,7 @@ uint8_t NmraDcc::process() xorValue ^= DccRx.PacketCopy.Data[i]; if(xorValue) { #ifdef DCC_DBGVAR + DB_PRINT("Cerr"); countOf.Err++; #endif return 0 ; diff --git a/NmraDcc.h b/NmraDcc.h index 3f74178..ed2191d 100644 --- a/NmraDcc.h +++ b/NmraDcc.h @@ -202,6 +202,7 @@ class NmraDcc // Flag values to be logically ORed together and passed into the init() method #define FLAGS_MY_ADDRESS_ONLY 0x01 // Only process DCC Packets with My Address #define FLAGS_AUTO_FACTORY_DEFAULT 0x02 // Call notifyCVResetFactoryDefault() if CV 7 & 8 == 255 +#define FLAGS_SETCV_CALLED 0x10 // only used internally !! #define FLAGS_OUTPUT_ADDRESS_MODE 0x40 // CV 29/541 bit 6 #define FLAGS_DCC_ACCESSORY_DECODER 0x80 // CV 29/541 bit 7 @@ -630,6 +631,8 @@ extern uint8_t notifyIsSetCVReady(void) __attribute__ ((weak)); /*+ * notifyCVChange() Called when a CV value is changed. * This is called whenever a CV's value is changed. + * notifyDccCVChange() Called only when a CV value is changed by a Dcc packet or a internal lib function. + * it is NOT called if the CV is chaged by means of the setCV() method. * Note: It is not called if notifyCVWrite() is defined * or if the value in the EEPROM is the same as the value * in the write command. @@ -642,6 +645,7 @@ extern uint8_t notifyIsSetCVReady(void) __attribute__ ((weak)); * None */ extern void notifyCVChange( uint16_t CV, uint8_t Value) __attribute__ ((weak)); +extern void notifyDccCVChange( uint16_t CV, uint8_t Value) __attribute__ ((weak)); /*+ * notifyCVResetFactoryDefault() Called when CVs must be reset. @@ -654,7 +658,7 @@ extern void notifyCVChange( uint16_t CV, uint8_t Value) __attribute__ ((weak) * * Inputs: * None - * * + * * * Returns: * None */ @@ -667,15 +671,26 @@ extern void notifyCVResetFactoryDefault(void) __attribute__ ((weak)); * * Inputs: * None - * * + * * * Returns: * None */ extern void notifyCVAck(void) __attribute__ ((weak)); +/*+ + * notifyServiceMode(bool) Called when state of 'inServiceMode' changes + * + * Inputs: + * bool state of inServiceMode + * * + * Returns: + * None + */ extern void notifyServiceMode(bool) __attribute__ ((weak)); -// Deprecated, only for backward compatibility with version 1.4.2. Don't use in new designs +// Deprecated, only for backward compatibility with version 1.4.2. +// Don't use in new designs. These functions may be dropped in future versions extern void notifyDccAccState( uint16_t Addr, uint16_t BoardAddr, uint8_t OutputAddr, uint8_t State ) __attribute__ ((weak)); +extern void notifyDccSigState( uint16_t Addr, uint8_t OutputIndex, uint8_t State) __attribute__ ((weak)); #if defined (__cplusplus) } From 1717a2efb06a0482b950d872417bfe2269e73d07 Mon Sep 17 00:00:00 2001 From: Alex Shepherd Date: Sat, 7 Jul 2018 19:21:48 +1200 Subject: [PATCH 5/7] Made some minor tweaks / tidy-ups after committing Franz-Peter's changes --- NmraDcc.cpp | 33 ++++++++++++++++++++++++--------- NmraDcc.h | 23 ++++++++++++++++++++++- library.properties | 2 +- 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/NmraDcc.cpp b/NmraDcc.cpp index 29ab28d..2d49e41 100644 --- a/NmraDcc.cpp +++ b/NmraDcc.cpp @@ -583,7 +583,7 @@ uint8_t writeCV( unsigned int CV, uint8_t Value) { case CV_29_CONFIG: // copy addressmode Bit to Flags - DccProcState.Flags = ( DccProcState.Flags & ~FLAGS_OUTPUT_ADDRESS_MODE) | (Value & FLAGS_OUTPUT_ADDRESS_MODE); + DccProcState.Flags = ( DccProcState.Flags & ~FLAGS_CV29_BITS) | (Value & FLAGS_CV29_BITS); // no break, because myDccAdress must also be reset case CV_ACCESSORY_DECODER_ADDRESS_LSB: // Also same CV for CV_MULTIFUNCTION_PRIMARY_ADDRESS case CV_ACCESSORY_DECODER_ADDRESS_MSB: @@ -601,11 +601,11 @@ uint8_t writeCV( unsigned int CV, uint8_t Value) if( notifyCVChange ) notifyCVChange( CV, Value) ; + if( notifyDccCVChange && !(DccProcState.Flags & FLAGS_SETCV_CALLED) ) notifyDccCVChange( CV, Value ); - - DccProcState.Flags &= ~FLAGS_SETCV_CALLED; } + return readEEPROM( CV ) ; } @@ -934,7 +934,8 @@ void processServiceModeOperation( DCC_MSG * pDccMsg ) } else if( pDccMsg->Size == 4) // 4 Byte Packets are for Direct Byte & Bit Mode - { DB_PRINT("BB-Mode"); + { + DB_PRINT("BB-Mode"); CVAddr = ( ( ( pDccMsg->Data[0] & 0x03 ) << 8 ) | pDccMsg->Data[1] ) + 1 ; Value = pDccMsg->Data[2] ; @@ -1056,7 +1057,7 @@ void execDccProcessor( DCC_MSG * pDccMsg ) { int16_t BoardAddress ; int16_t OutputAddress ; - uint8_t TurnoutPairIndex ; + uint8_t TurnoutPairIndex ; #ifdef DEBUG_PRINT SerialPrintPacketHex(F( "eDP: AccCmd: "), pDccMsg); @@ -1137,7 +1138,9 @@ void execDccProcessor( DCC_MSG * pDccMsg ) if((pDccMsg->Size == 4) && ((pDccMsg->Data[1] & 0b10001001) == 1)) // Extended Accessory Decoder Control Packet Format { - uint8_t state = pDccMsg->Data[2] ;// & 0b00011111; + // According to the NMRA Dcc Spec the Signal State should only use the lower 5 Bits, + // however some manufacturers seem to allow/use all 8 bits, so we'll relax that constraint for now + uint8_t state = pDccMsg->Data[2] ; DB_PRINT("eDP: OAddr:%d Extended State:%0X", OutputAddress, state); if( notifyDccSigOutputState ) notifyDccSigOutputState(OutputAddress, state); @@ -1262,6 +1265,13 @@ NmraDcc::NmraDcc() { } +#ifdef digitalPinToInterrupt +void NmraDcc::pin( uint8_t ExtIntPinNum, uint8_t EnablePullup) +{ + pin(digitalPinToInterrupt(ExtIntPinNum), ExtIntPinNum, EnablePullup); +} +#endif + void NmraDcc::pin( uint8_t ExtIntNum, uint8_t ExtIntPinNum, uint8_t EnablePullup) { #if defined ( __STM32F1__ ) @@ -1308,8 +1318,8 @@ void NmraDcc::init( uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, ui // Set the Bits that control Multifunction or Accessory behaviour // and if the Accessory decoder optionally handles Output Addressing - uint8_t cv29Mask = CV29_ACCESSORY_DECODER | CV29_OUTPUT_ADDRESS_MODE ; // peal off the top two bits - writeCV( CV_29_CONFIG, ( readCV( CV_29_CONFIG ) & ~cv29Mask ) | (Flags & cv29Mask) ) ; + // we need to peal off the top two bits + writeCV( CV_29_CONFIG, ( readCV( CV_29_CONFIG ) & ~FLAGS_CV29_BITS ) | (Flags & FLAGS_CV29_BITS) ) ; uint8_t doAutoFactoryDefault = 0; if((Flags & FLAGS_AUTO_FACTORY_DEFAULT) && (readCV(CV_VERSION_ID) == 255) && (readCV(CV_MANUFACTURER_ID) == 255)) @@ -1334,7 +1344,12 @@ uint8_t NmraDcc::getCV( uint16_t CV ) uint8_t NmraDcc::setCV( uint16_t CV, uint8_t Value) { DccProcState.Flags |= FLAGS_SETCV_CALLED; - return writeCV(CV,Value); + + uint8_t returnValue = writeCV(CV,Value); + + DccProcState.Flags &= ~FLAGS_SETCV_CALLED; + + return returnValue; } //////////////////////////////////////////////////////////////////////// diff --git a/NmraDcc.h b/NmraDcc.h index ed2191d..9f2cb62 100644 --- a/NmraDcc.h +++ b/NmraDcc.h @@ -44,6 +44,8 @@ #include "WProgram.h" #endif +#include "pins_arduino.h" + #include "EEPROM.h" #ifndef NMRADCC_IS_IN @@ -109,7 +111,7 @@ typedef struct typedef enum { CV29_LOCO_DIR = 0b00000001, /** bit 0: Locomotive Direction: "0" = normal, "1" = reversed */ CV29_F0_LOCATION = 0b00000010, /** bit 1: F0 location: "0" = bit 4 in Speed and Direction instructions, "1" = bit 4 in function group one instruction */ - CV29_APS = 0b00000100, /** bit 2: Alternate Power Source (APS) "0" = NMRA Digital only, "1" = Alternate power source set by CV12 */ + CV29_APS = 0b00000100, /** bit 2: Alternate Power Source (APS) "0" = NMRA Digital only, "1" = Alternate power source set by CV12 */ CV29_ADV_ACK = 0b00001000, /** bit 3: ACK, Advanced Acknowledge mode enabled if 1, disabled if 0 */ CV29_SPEED_TABLE_ENABLE = 0b00010000, /** bit 4: STE, Speed Table Enable, "0" = values in CVs 2, 4 and 6, "1" = Custom table selected by CV 25 */ CV29_EXT_ADDRESSING = 0b00100000, /** bit 5: "0" = one byte addressing, "1" = two byte addressing */ @@ -206,6 +208,10 @@ class NmraDcc #define FLAGS_OUTPUT_ADDRESS_MODE 0x40 // CV 29/541 bit 6 #define FLAGS_DCC_ACCESSORY_DECODER 0x80 // CV 29/541 bit 7 +// Flag Bits that are cloned from CV29 relating the DCC Accessory Decoder +#define FLAGS_CV29_BITS (FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER) + + /*+ * pin() is called from setup() and sets up the pin used to receive DCC packets. * @@ -219,6 +225,21 @@ class NmraDcc */ void pin( uint8_t ExtIntNum, uint8_t ExtIntPinNum, uint8_t EnablePullup); + /*+ + * pin() is called from setup() and sets up the pin used to receive DCC packets. + * This relies on the internal function: digitalPinToInterrupt() to map the input pin number to the right interrupt + * + * Inputs: + * ExtIntPinNum - Input pin number. + * EnablePullup - Set true to enable the pins pullup resistor. + * + * Returns: + * None. + */ +#ifdef digitalPinToInterrupt +void pin( uint8_t ExtIntPinNum, uint8_t EnablePullup); +#endif + /*+ * init() is called from setup() after the pin() command is called. * It initializes the NmDcc object and makes it ready to process packets. diff --git a/library.properties b/library.properties index c81337b..35818c6 100644 --- a/library.properties +++ b/library.properties @@ -3,7 +3,7 @@ version=2.0.0 author=Alex Shepherd, Wolfgang Kuffer, Geoff Bunza, Martin Pischky, Franz-Peter Müller, Sven (littleyoda) maintainer=Alex Shepherd sentence=Enables NMRA DCC Communication -paragraph=This library allows you to interface to a NMRA DCC track signal and receive DCC commands. The library currently supports the AVR ATTiny84/85 & ATMega88/168/328/32u4 and Teensy 3.x using the INT0/1 Hardware Interrupt and micros() ONLY and no longer uses Timer0 Compare Match B, which makes it much more portable to other platforms. WARNING as of version 1.4.4 support for the call-back functions notifyDccAccState() and notifyDccSigState() has been removed, please check and update your sketches, as they will silently fail. +paragraph=This library allows you to interface to a NMRA DCC track signal and receive DCC commands. The library currently supports the AVR ATTiny84/85 & ATMega88/168/328/32u4, ESP8266 and Teensy 3.x using the INT0/1 Hardware Interrupt and micros() ONLY and no longer uses Timer0 Compare Match B, which makes it much more portable to other platforms. category=Communication url=https://github.com/mrrwa/NmraDcc architectures=avr,esp8266,STM32F1 From 7a3845cbdfbd6e23ec41d1175a4050e1c4503825 Mon Sep 17 00:00:00 2001 From: Alex Shepherd Date: Sun, 8 Jul 2018 00:54:21 +1200 Subject: [PATCH 6/7] Changed the architectures to now be * as we're no longer tied to AVR specific hardware, however I've listed the architectures its been tested on Fixed a bug with CV bit-write --- NmraDcc.cpp | 4 ++-- NmraDcc.h | 2 -- library.properties | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/NmraDcc.cpp b/NmraDcc.cpp index 2d49e41..39c80c8 100644 --- a/NmraDcc.cpp +++ b/NmraDcc.cpp @@ -1234,9 +1234,9 @@ void execDccProcessor( DCC_MSG * pDccMsg ) uint8_t currentValue = readCV(cvAddress); uint8_t newValueMask = 1 << (cvValue & 0b00000111); if(cvValue & 0b00001000) - writeCV(cvAddress, cvValue | newValueMask); + writeCV(cvAddress, currentValue | newValueMask); else - writeCV(cvAddress, cvValue & ~newValueMask); + writeCV(cvAddress, currentValue & ~newValueMask); } break; } diff --git a/NmraDcc.h b/NmraDcc.h index 9f2cb62..d5ae4b8 100644 --- a/NmraDcc.h +++ b/NmraDcc.h @@ -44,8 +44,6 @@ #include "WProgram.h" #endif -#include "pins_arduino.h" - #include "EEPROM.h" #ifndef NMRADCC_IS_IN diff --git a/library.properties b/library.properties index 35818c6..0e6e49b 100644 --- a/library.properties +++ b/library.properties @@ -3,7 +3,7 @@ version=2.0.0 author=Alex Shepherd, Wolfgang Kuffer, Geoff Bunza, Martin Pischky, Franz-Peter Müller, Sven (littleyoda) maintainer=Alex Shepherd sentence=Enables NMRA DCC Communication -paragraph=This library allows you to interface to a NMRA DCC track signal and receive DCC commands. The library currently supports the AVR ATTiny84/85 & ATMega88/168/328/32u4, ESP8266 and Teensy 3.x using the INT0/1 Hardware Interrupt and micros() ONLY and no longer uses Timer0 Compare Match B, which makes it much more portable to other platforms. +paragraph=This library allows you to interface to a NMRA DCC track signal and receive DCC commands. The library has been tested on AVR ATTiny84/85 & ATMega88/168/328/32u4, ESP8266 and Teensy 3.x using the INT0/1 Hardware Interrupt and micros() ONLY and no longer uses Timer0 Compare Match B, which makes it much more portable to other platforms. category=Communication url=https://github.com/mrrwa/NmraDcc -architectures=avr,esp8266,STM32F1 +architectures=* From 15da83c4110afba9472bbfb124d7904784922c5b Mon Sep 17 00:00:00 2001 From: per1234 Date: Sun, 15 Jul 2018 04:21:17 -0700 Subject: [PATCH 7/7] Use a single tab field separator in keywords.txt (#19) Each field of keywords.txt is separated by a single true tab. When you use multiple tabs it causes the field to be interpreted as empty. On Arduino IDE 1.6.5 and newer an empty KEYWORD_TOKENTYPE causes the default editor.function.style coloration to be used (as with KEYWORD2, KEYWORD3, LITERAL2). On Arduino IDE 1.6.4 and older it causes the keyword to not be recognized for any special coloration. Reference: https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Library-specification#keywords --- keywords.txt | 84 ++++++++++++++++++++++++++-------------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/keywords.txt b/keywords.txt index d0fb2c6..060d077 100755 --- a/keywords.txt +++ b/keywords.txt @@ -6,58 +6,58 @@ # Datatypes (KEYWORD1) ####################################### -DCC_MSG KEYWORD1 -NmraDcc KEYWORD1 +DCC_MSG KEYWORD1 +NmraDcc KEYWORD1 ####################################### # Methods and Functions (KEYWORD2) ####################################### -NmraDcc KEYWORD2 -pin KEYWORD2 -init KEYWORD2 -process KEYWORD2 -getCV KEYWORD2 -setCV KEYWORD2 -isSetCVReady KEYWORD2 -notifyDccReset KEYWORD2 -notifyDccIdle KEYWORD2 -notifyDccSpeed KEYWORD2 -notifyDccSpeedRaw KEYWORD2 -notifyDccFunc KEYWORD2 -notifyDccAccTurnoutBoard KEYWORD2 -notifyDccAccTurnoutOutput KEYWORD2 -notifyDccAccBoardAddrSet KEYWORD2 -notifyDccAccOutputAddrSet KEYWORD2 -notifyDccSigOutputState KEYWORD2 -notifyDccMsg KEYWORD2 -notifyCVValid KEYWORD2 -notifyCVRead KEYWORD2 -notifyCVWrite KEYWORD2 -notifyIsSetCVReady KEYWORD2 -notifyCVChange KEYWORD2 -notifyCVAck KEYWORD2 -notifyCVResetFactoryDefault KEYWORD2 +NmraDcc KEYWORD2 +pin KEYWORD2 +init KEYWORD2 +process KEYWORD2 +getCV KEYWORD2 +setCV KEYWORD2 +isSetCVReady KEYWORD2 +notifyDccReset KEYWORD2 +notifyDccIdle KEYWORD2 +notifyDccSpeed KEYWORD2 +notifyDccSpeedRaw KEYWORD2 +notifyDccFunc KEYWORD2 +notifyDccAccTurnoutBoard KEYWORD2 +notifyDccAccTurnoutOutput KEYWORD2 +notifyDccAccBoardAddrSet KEYWORD2 +notifyDccAccOutputAddrSet KEYWORD2 +notifyDccSigOutputState KEYWORD2 +notifyDccMsg KEYWORD2 +notifyCVValid KEYWORD2 +notifyCVRead KEYWORD2 +notifyCVWrite KEYWORD2 +notifyIsSetCVReady KEYWORD2 +notifyCVChange KEYWORD2 +notifyCVAck KEYWORD2 +notifyCVResetFactoryDefault KEYWORD2 ####################################### # Constants (LITERAL1) -MAN_ID_JMRI LITERAL1 -MAN_ID_DIY LITERAL1 -MAN_ID_SILICON_RAILWAY LITERAL1 -FLAGS_MY_ADDRESS_ONLY LITERAL1 -FLAGS_OUTPUT_ADDRESS_MODE LITERAL1 -FLAGS_DCC_ACCESSORY_DECODER LITERAL1 +MAN_ID_JMRI LITERAL1 +MAN_ID_DIY LITERAL1 +MAN_ID_SILICON_RAILWAY LITERAL1 +FLAGS_MY_ADDRESS_ONLY LITERAL1 +FLAGS_OUTPUT_ADDRESS_MODE LITERAL1 +FLAGS_DCC_ACCESSORY_DECODER LITERAL1 -CV_ACCESSORY_DECODER_ADDRESS_LSB LITERAL1 -CV_ACCESSORY_DECODER_ADDRESS_MSB LITERAL1 +CV_ACCESSORY_DECODER_ADDRESS_LSB LITERAL1 +CV_ACCESSORY_DECODER_ADDRESS_MSB LITERAL1 -CV_MULTIFUNCTION_PRIMARY_ADDRESS LITERAL1 -CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB LITERAL1 -CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB LITERAL1 +CV_MULTIFUNCTION_PRIMARY_ADDRESS LITERAL1 +CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB LITERAL1 +CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB LITERAL1 -CV_VERSION_ID LITERAL1 -CV_MANUFACTURER_ID LITERAL1 -CV_29_CONFIG LITERAL1 -CV_OPS_MODE_ADDRESS_LSB LITERAL1 +CV_VERSION_ID LITERAL1 +CV_MANUFACTURER_ID LITERAL1 +CV_29_CONFIG LITERAL1 +CV_OPS_MODE_ADDRESS_LSB LITERAL1 #######################################