// Inglnook.C 30-Dec-2008 Loren Blaney loren.blaney@idcomm.com // Inglenook Sidings Controller // // Allow for a maximum speed of 10 inches per second, and a minimum of 1"/sec. // // WARNING: Do not attempt to run with ICD2 plugged in. // Remove jumper across diode when B15 is changed to an analog input. #include _CONFIG1(JTAGEN_OFF & GCP_OFF & GWRP_OFF & BKBUG_OFF & COE_OFF & FWDTEN_OFF & WINDIS_OFF) _CONFIG2(IESO_OFF & FNOSC_FRC & FCKSM_CSDCMD & OSCIOFNC_ON & IOL1WAY_OFF & I2C1SEL_PRI & POSCMOD_NONE) #define LEFT 0 #define RIGHT 1 #define OFF 0 #define ON 1 #define FwdSw PORTBbits.RB0 #define RevSw PORTBbits.RB1 #define TurnSw1 PORTBbits.RB2 #define TurnSw2 PORTBbits.RB3 #define ReedSw1 PORTAbits.RA0 #define ReedSw2 PORTAbits.RA1 #define ReedSw3 PORTAbits.RA2 #define ReedSw4 PORTAbits.RA3 #define ReedSw5 PORTAbits.RA4 #define ModeSw PORTBbits.RB15 #define TrackPWM LATBbits.LATB5 #define TrackA LATBbits.LATB6 #define TrackB LATBbits.LATB7 #define Turnout1A LATBbits.LATB8 #define Turnout1B LATBbits.LATB9 #define Turnout2A LATBbits.LATB10 #define Turnout2B LATBbits.LATB11 #define Uncoupler1 LATBbits.LATB12 #define Uncoupler2 LATBbits.LATB13 #define Uncoupler3 LATBbits.LATB14 void DelayMS(int t) // Delay specified number of milliseconds {int i, j; for (i=0; i100) break; // don't keep checking if a clearance reed if (Reed(5) && i>100) break; // gets activated (but check a little) if (ModeSw == 1) break; } L200: SetUncoupler(n, OFF); // make sure uncoupler is off Stop(); } // Uncouple void Couple(int n) // Couple a car on siding n {while (1) { MoveRev(); // back train while (Reed(n)) // if car is on reed then back until it's off {if (ModeSw == 1) return;} Skip(n); // wait for car ahead to pass reed // car should now be coupled MoveFwd(); Skip(n); // wait for car ahead to pass reed int i; for (i=0; i<400; i++) // check to make sure that car did couple {DelayMS(1); if (Reed(n)) // if reed comes on then car coupled {Skip(n); goto L200;} if (Reed(4)) goto L200; // don't keep checking if a clearance if (Reed(5)) goto L200; // reed gets activated if (ModeSw == 1) return; } } L200: Stop(); } // Couple void Test() // Uncoupler tester (for debug) { SelectSiding(3); Couple(3); // car MoveFwd(); Skip(5); // coal car Skip(5); // car Uncouple(3); // car MoveFwd(); Skip(5); // coal car Stop(); } // Test void Reverse() // Reverse sequence of cars { // Cars are initially arranged as follows: // siding cars // 1 - - // 2 - - // 3 1 2 3 4 5 Eng // // uncouple cars 1, 2 & 3 SelectSiding(3); Uncouple(3); // cars 1, 2 & 3 MoveFwd(); Skip(5); // car 1 Skip(5); // car 2 Stop(); if (ModeSw == 1) return; // move cars 4 & 5 to siding 2 SelectSiding(2); MoveRev(); Skip(2); // car 4 Uncouple(2); // cars 4 & 5 MoveFwd(); Skip(5); // coal car Stop(); if (ModeSw == 1) return; // move car 3 from siding 3 to siding 1 SelectSiding(3); Couple(3); // car 3 MoveFwd(); Skip(3); // car 2 Uncouple(3); // cars 1 & 2 MoveFwd(); Skip(5); // coal car Skip(5); // car 3 Stop(); if (ModeSw == 1) return; SelectSiding(1); Uncouple(1); // car 3 MoveFwd(); Skip(5); // coal car Stop(); if (ModeSw == 1) return; // move car 2 from siding 3 to siding 1 SelectSiding(3); Couple(3); // car 2 MoveFwd(); Skip(3); // car 1 Uncouple(3); // car 1 MoveFwd(); Skip(5); // coal car Skip(5); // car 2 Stop(); if (ModeSw == 1) return; SelectSiding(1); Uncouple(1); // car 2 MoveFwd(); Skip(5); // coal car Stop(); if (ModeSw == 1) return; // pick up car 1 on siding 3 SelectSiding(3); Couple(3); // car 1 MoveFwd(); Skip(5); // coal car Skip(5); // car 1 Stop(); if (ModeSw == 1) return; // pick up car 5 on siding 2 SelectSiding(2); Couple(2); // car 5 MoveFwd(); Skip(2); // car 4 Uncouple(2); // car 4 MoveFwd(); Skip(5); // coal car Skip(5); // car 1 Skip(5); // car 5 Stop(); if (ModeSw == 1) return; // move car 5 to siding 3 SelectSiding(3); Uncouple(3); // 5 MoveFwd(); Skip(5); // coal car Skip(5); // car 1 Stop(); if (ModeSw == 1) return; // pick up car 4 on siding 2 SelectSiding(2); Couple(2); // car 4 MoveFwd(); Skip(5); // coal car Skip(5); // car 1 Skip(5); // car 4 Stop(); if (ModeSw == 1) return; // move car 4 to siding 3 SelectSiding(3); Uncouple(3); // car 4 MoveFwd(); Skip(5); // coal car Skip(5); // car 1 Stop(); if (ModeSw == 1) return; // pick up car 2 on siding 1 SelectSiding(1); Couple(1); // car 2 MoveFwd(); Skip(1); // car 3 Uncouple(1); // car 3 MoveFwd(); Skip(5); // coal car might already be over reed 4 Stop(); if (ModeSw == 1) return; // move cars 2 and 1 to siding 2 SelectSiding(2); MoveRev(); Skip(2); // car 2 Uncouple(2); // cars 2 & 1 MoveFwd(); Skip(4); // coal car Stop(); if (ModeSw == 1) return; // pick up car 3 on siding 1 SelectSiding(1); Couple(1); // car 4 MoveFwd(); Skip(5); // coal car Skip(5); // car 3 Stop(); if (ModeSw == 1) return; // move car 3 to siding 3 SelectSiding(3); Uncouple(3); // car 3 MoveFwd(); Skip(5); // coal car Stop(); if (ModeSw == 1) return; // pick up cars 2 & 1 on siding 2 SelectSiding(2); Couple(2); // car 1 MoveFwd(); Skip(5); // coal car Skip(5); // car 1 Skip(5); // car 2 Stop(); if (ModeSw == 1) return; // couple cars 5, 4 & 3 on siding 3 SelectSiding(3); Couple(3); // car 3 MoveFwd(); Skip(5); // coal car Skip(5); // car 1 Stop(); if (ModeSw == 1) return; int i; for (i=0; i<100; i++) // pause at end of cycle {DelayMS(100); if (ModeSw == 1) return; } } // Reverse void Manual() // Manual operation mode { SetTurnout(1, TurnSw1); // set turnouts according to control panel switches SetTurnout(2, TurnSw2); if (FwdSw == 0) MoveFwd(); // move train according to Fwd/Rev switch else if (RevSw == 0) MoveRev(); else Stop(); } // Manual void Init() // Initialize PIC I/O ports { //CNPU1 = 0x00FF; // enable pull-ups for all digital inputs (B15=analog) CNPU1 = 0x08FF; // enable pull-ups for all digital inputs CNPU2 = 0x6000; //AD1PCFG = 0x1DFF; // convert analog inputs to digital (except B15) AD1PCFG = 0x1FFF; // convert analog inputs to digital (including B15) TRISB = 0x801F; // enable outputs Stop(); // make sure everything is turned off SetUncoupler(1, OFF); SetUncoupler(2, OFF); SetUncoupler(3, OFF); } // Init // ============================================================================= void main(void) {Init(); while (1) {if (ModeSw == 1) Manual(); else Reverse(); } } // main