/********************************************************************* * Auto stop/start for DSmainR5 * * S88_1Loco10_ suzu 2015.12.1 * */ #include #include #include "DSGatewayLib.h" #include "TrackReporterS88_DS.h" #define ON 1 #define OFF 0 #define MAX_S88DECODER 1 #define STOP_A 1 // Loco stop point S88 Clamp# #define MUTE OFF // Sound mute ON/OFF #define SPEED_UP 2000 // speed up rate m-second #define SPEED_DOWN 500 // speed down rate m-second #define SPEED_CONT 7 // speed up/down count #define STOP_TIME 8000 // station stop time m-second #define CMD_DELAY 300 // command delay time m-second #define SOMETIME 12 // Random Max seed, min=12, Sometime happen function #define FCONT 5 // Random Function Continue count #define S88CHK 500 // S88 check time m-second TrackReporterS88_DS reporter( MAX_S88DECODER ); DSGatewayLib Gateway; #define LOCO_FB 1 // Loco forward=1, backward=2 #define LOCO_ADR 44 // ***Loco DCC address (search loco_d[ HMT ][13] ) #define HMT 18 // ***How many trains on DB loco_d[][] word loco_d[ HMT ][17]= { { 9999, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 9999, 0, 1024, 0 }, // Dummy (Don't delete) { 3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 3, 0, 500, 0 }, { 5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 5, 0, 500, 0 }, { 6, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 6, 0, 900, 0 }, { 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 9, 0, 350, 0 }, { 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12, 0, 450, 0 }, { 2016, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 16, 0, 300, 0 }, { 3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 33, 0, 450, 0 }, { 41, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 41, 0, 500, 0 }, { 44, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 44, 0, 400, 0 }, { 50, 1, 2, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 50, 0, 400, 0 }, { 5106, 1, 2, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 51, 0, 700, 0 }, { 56, 13, 2, 2, 4, 5, 6, 7, 1, 9, 10, 11, 12, 56, 0, 900, 0 }, { 59, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 59, 0, 400, 0 }, { 156, 13, 2, 2, 4, 5, 6, 7, 1, 9, 10, 11, 12, 56, 0, 500, 0 }, { 236, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 36, 0, 800, 0 }, { 278, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 78, 0, 400, 0 }, { 341, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 341, 0, 700, 0 } }; // 0=***Loco_Number, 1=Bell, 2=Whistle, 3=Short Whistle, 4=Steam Release, // 5=xxx/Generator, 6=Water/Voice, 7=Light Dimmer/Cupler, 8=Mute sound, // 9=Water, 10=Injectors, 11=Break, 12=Cupler, 13=***DCC_Address, // 14=Speed_cont_tmp, 15=***Normal_Speed_max=1024, 16=Speed_Now int locoAdrL, tmp, speed; unsigned char fwdBwd = LOCO_FB; // define functions word getClamp() { word aFlags = 0; reporter.refresh( MAX_S88DECODER ); int j = 0; aFlags = ( reporter.getByte( (j << 1) + 1) << 8 ) + reporter.getByte( j << 1 ); // Serial.print("clamps="); // Serial.println(aFlags, HEX); return( aFlags ); } int getExist( int arg ) { int value = 0; reporter.refresh( MAX_S88DECODER ); value = reporter.getValue( arg ); // Serial.print("getValue="); // Serial.println(value, HEX); return( value ); } void loco_speed( int arg ) { delay( CMD_DELAY ); Gateway.SetLocoSpeed( loco_d[ locoAdrL ] [13], arg ); delay( CMD_DELAY ); } void loco_direction( int arg ) { delay( CMD_DELAY ); Gateway.SetLocoDirection( loco_d[ locoAdrL ] [13], arg ); delay( CMD_DELAY ); } void loco_function( unsigned char arg1, int arg2 ) // arg2 = ON/OFF { delay( CMD_DELAY ); Gateway.SetLocoFunction( loco_d[ locoAdrL ] [13], loco_d[ locoAdrL ][arg1], arg2 ); delay( CMD_DELAY ); } void light( unsigned char on_off ) { delay( CMD_DELAY ); Gateway.SetLocoFunction( loco_d[ locoAdrL ] [13], 0, on_off ); delay( CMD_DELAY ); } void bell( int arg ) // arg = time m-sec { delay( CMD_DELAY ); Gateway.SetLocoFunction( loco_d[ locoAdrL ] [13], loco_d[ locoAdrL ][1], ON ); delay( arg ); Gateway.SetLocoFunction( loco_d[ locoAdrL ] [13], loco_d[ locoAdrL ][1], OFF ); delay( CMD_DELAY ); } void whistle( int arg ) // arg = time m-sec { delay( CMD_DELAY ); Gateway.SetLocoFunction( loco_d[ locoAdrL ] [13], loco_d[ locoAdrL ][2], ON ); delay( arg ); Gateway.SetLocoFunction( loco_d[ locoAdrL ] [13], loco_d[ locoAdrL ][2], OFF ); delay( CMD_DELAY ); } void s_whistle( int arg ) // arg = time m-sec { delay( CMD_DELAY ); Gateway.SetLocoFunction( loco_d[ locoAdrL ] [13], loco_d[ locoAdrL ][3], ON ); delay( arg ); Gateway.SetLocoFunction( loco_d[ locoAdrL ] [13], loco_d[ locoAdrL ][3], OFF ); delay( CMD_DELAY ); } void steam( int arg ) // arg = time m-sec { delay( CMD_DELAY ); Gateway.SetLocoFunction( loco_d[ locoAdrL ] [13], loco_d[ locoAdrL ][4], ON ); delay( arg ); Gateway.SetLocoFunction( loco_d[ locoAdrL ] [13], loco_d[ locoAdrL ][4], OFF ); delay( CMD_DELAY ); } void blink( int arg ) // arg = time m-sec { light( OFF ); delay( arg ); light( ON ); delay( arg ); light( OFF ); delay( arg ); light( ON ); delay( arg ); light( OFF ); delay( arg ); light( ON ); } void all_func_off() { for( int i = 12; i< 0 ; i-- ) { // Serial.println( i ); loco_function( i, OFF ); } } //////////////////////////////////////////////////////// void setup() { Serial.begin( 115200 ); reporter.refresh(); Gateway.begin(); delay( 4000 ); Gateway.SetPower( true ); delay( 1000 ); /**** for( int i = 0; i< 10 ; i++ ) { Serial.print( i ); Serial.print( " = " ); Serial.println( analogRead(i) ); delay( 1000 ); } */ randomSeed( analogRead( 1 ) ); for( int i = 0 ; i < HMT ; i++ ) { if( loco_d[ i ] [13] == LOCO_ADR ) locoAdrL = i; } loco_d[ locoAdrL ] [13] = ADDR_DCC + loco_d[ locoAdrL ] [13]; // set system address loco_d[ locoAdrL ] [14] = loco_d[ locoAdrL ] [15] / SPEED_CONT; Serial.println( "Function initialize" ); loco_speed( 0 ); loco_direction( fwdBwd ); light( OFF ); Serial.print( "#" ); Serial.print( loco_d[ locoAdrL ] [0] ); Serial.println( " start." ); tmp = LOCO_ADR; Serial.print( "DCC address=" ); Serial.println( tmp ); Serial.print( "Max speed=" ); Serial.println( loco_d[ locoAdrL ] [15] ); tmp = STOP_A; Serial.print( "S88 target= " ); Serial.println( tmp ); // Mute ON/OFF Gateway.SetLocoFunction( loco_d[ locoAdrL ][13], 8, MUTE ); // Gateway.SetLocoFunction( ( ADDR_DCC +56 ), 1, ON ); // for Roco 36-156 only } //////////////////////////////////////////////////////// void loop() { int count, r; light( ON ); whistle( 1000 ); loco_d[ locoAdrL ] [16] = 0; // Loco Speed 0 // Speed up Serial.println( "Speed up" ); tmp = 0; do{ loco_d[ locoAdrL ] [16] = loco_d[ locoAdrL ] [16] + loco_d[ locoAdrL ] [14]; if( loco_d[ locoAdrL ] [16] > loco_d[ locoAdrL ] [15] ) loco_d[ locoAdrL ] [16] = loco_d[ locoAdrL ] [15]; Serial.println( loco_d[ locoAdrL ] [16] ); Gateway.SetLocoSpeed( loco_d[ locoAdrL ] [13], loco_d[ locoAdrL ] [16] ); delay( SPEED_UP ); tmp++; }while( tmp < SPEED_CONT ); // Max Speed Serial.println( "Max Speed" ); s_whistle( 1000 ); // Continue Serial.println( "Continue, wait target S88" ); while( getExist( STOP_A ) == 0 ) { if( random( SOMETIME ) == 1 ) // It happens sometime { tmp = ( random( SOMETIME ) % 12 ) + 1; if( tmp != 8 ) { Serial.print( "Loco_Func =" ); Serial.println( tmp ); loco_function( loco_d[ locoAdrL ] [ tmp ], ON ); count = FCONT; while( getExist( STOP_A ) == 0 ) { delay( S88CHK ); count--; if( count <= 0 ) break; } loco_function( loco_d[ locoAdrL ] [ tmp ], OFF ); } } else delay( S88CHK ); } Serial.print( "get clamps=" ); Serial.println( getClamp() ); // Speed down Serial.println( "Speed down" ); bell( 2000 ); tmp = 0; do{ loco_d[ locoAdrL ] [16] = loco_d[ locoAdrL ] [16] - loco_d[ locoAdrL ] [14]; if( loco_d[ locoAdrL ] [16] < 0 ) loco_d[ locoAdrL ] [16] = 0; Serial.println( loco_d[ locoAdrL ] [16] ); Gateway.SetLocoSpeed( loco_d[ locoAdrL ] [13], loco_d[ locoAdrL ] [16] ); delay( SPEED_DOWN ); tmp++; }while( tmp < SPEED_CONT ); // STOP Serial.println( "STOP" ); steam( 1000 ); loco_speed( 0 ); all_func_off(); delay( STOP_TIME ); /** Reverse Serial.println( "Reverse" ); Serial.print( "fwdBwd = " ); if ( fwdBwd == 1 ) fwdBwd = 2; else fwdBwd = 1; Serial.println( fwdBwd ); loco_direction( fwdBwd ); */ }