Jasmine Karlsson / Mbed 2 deprecated train_rail

Dependencies:   mbed TextLCD

main.cpp

Committer:
KwamsC
Date:
2018-06-14
Revision:
24:418711ed8c52
Parent:
23:bb57966cb776
Child:
25:90f7a34c253a

File content as of revision 24:418711ed8c52:

#include "mbed.h"
#include "TextLCD.h"
#include "MCP23017.h"
#include "Train.h"
#include "Switch.h"
#include "Track.h"
#include "Detector.h"
#include <cstdlib>

//Board 1
/*----------------------------------------------------------------------------
Pin definitions
*----------------------------------------------------------------------------*/
DigitalOut Track(p20);      // train track

DigitalOut myled1(LED1), myled2(LED2), myled3(LED3), myled4(LED4);
DigitalOut externalLed1(p15), externalLed2(p16), externalLed3(p17), externalLed4(p18);
TextLCD lcd(p22, p21, p23, p24, p25, p26); // lcd

DigitalIn sw1(p29), sw2(p30), sw3(p11), sw4(p12);

//InterruptIn sw1(p5);
InterruptIn int0(p13), int1(p14);
I2C i2c(p28, p27);
MCP23017 *mcp;

/*----------------------------------------------------------------------------
Addresses
*----------------------------------------------------------------------------*/
const unsigned int DCCaddress_silver = 0x01;
const unsigned int DCCaddress_red = 0x03;
const unsigned int DCCaddress_switch = 0x06;

/*----------------------------------------------------------------------------
Train movement
*----------------------------------------------------------------------------*/
//move backwards/reverse
const unsigned int DCCinst_reverse = 0x48; //reverse speed

//speed dial forward
const unsigned int DCCinst_step2 = 0x72; //step 2
const unsigned int DCCinst_step4 = 0x73; //step 4
//const unsigned int DCCinst_step6 = 0x68; //step 6 1/4 speed
const unsigned int DCCinst_step13 = 0x78; //step 13 1/2 speed
//const unsigned int DCCinst_step20 = 0x75; //step 20 3/4 speed
//const unsigned int DCCinst_step28 = 0x7F; //step 28 Full speed
const unsigned int DCCinst_switch1 = 0x81; //Activate switch1
const unsigned int DCCinst_switch2 = 0x82; //Activate switch2
const unsigned int DCCinst_switch3 = 0x84; //Activate switch3
const unsigned int DCCinst_switch4 = 0x88; //Activate switch4
const unsigned int DCCinst_deactive_switch = 0x80; //Deactivate switches
//stop 
const unsigned int DCCinst_stop = 0x40; //forward and stop 01100000

/*----------------------------------------------------------------------------
Function definitions
*----------------------------------------------------------------------------*/
bool readSwitch(DigitalIn theSwitch);
int convertHextoDec(int pos, int intnr);
void checkDetector(int inter);
void init_mcp();
void init_interrupt();
void init_trains();
void executeCase(int pos);
Train& assignTrain(int pos);

//Trains
Train redTrain(DCCaddress_red, DCCinst_step13, 12);
Train silverTrain(DCCaddress_silver,DCCinst_step13, 2);
//Switches
Switch switch1(DCCaddress_switch,DCCinst_switch1);
Switch switch2(DCCaddress_switch,DCCinst_switch2);
Switch switch3(DCCaddress_switch,DCCinst_switch3);
Switch switch4(DCCaddress_switch,DCCinst_switch4);
//Detectors
Detector dect(false);

// Detectors address
/*
d0 = 0xfe //254
d1 = 0xfd //253
d2 = fb //251
d3 = f7 //247
d4 = ef //239
d5 = df //223
d6 = bf //191
d7 = 7f //255
d8 = 0xfe //254
d9 = fd
d10 = fb
d11 = f7
d12 = ef
d13 = df
*/
/*----------------------------------------------------------------------------
Main
*----------------------------------------------------------------------------*/
int main() {
    lcd.printf("Start journey");
    init_mcp();
    init_interrupt();
    init_trains();
    wait(2);
    while(1){ 
        redTrain.sendCommand();
        silverTrain.sendCommand();
        
        if(!readSwitch(sw3)){ //Change speed
            lcd.printf("Go forward");
            redTrain.changeSpeed(DCCinst_step13);
            silverTrain.changeSpeed(DCCinst_step13);
        }
        
        if(redTrain.checkStop()){                       //check if Train stopped
            lcd.cls();
            lcd.printf("in stop");
            wait(2);
            executeCase(redTrain.getPosition());
        }
        else if(silverTrain.checkStop()){
            executeCase(silverTrain.getPosition());
        }        
    }
}

/*----------------------------------------------------------------------------
Functions
*----------------------------------------------------------------------------*/
int convertHextoDec(int pos, int intnr){
    int newPos;
    switch(pos){
        case 0xfe: 
            newPos = 0;
            break;
        case 0xfd: 
            newPos = 1;
            break; 
        case 0xfb: 
            newPos = 2;
            break; 
        case 0xf7: 
            newPos = 3;
            break; 
        case 0xef: 
            newPos = 4;
            break; 
        case 0xdf: 
            newPos = 5;
            break; 
        case 0xbf: 
            newPos = 6;
            break; 
        case 0x7f: 
            newPos = 7;
            break; 
        default:
            return -1;
        }
        
        if(intnr == 1)
            newPos += 8;
    return newPos;
}

Train& assignTrain(int pos){
    
    //Check which train got the interupt
    if(redTrain.checkInterupt(pos)){
        redTrain.setPosition(pos);
        //lcd.cls();
        //lcd.printf("Red train!");
        return redTrain;
    }
    else if(silverTrain.checkInterupt(pos)){
        silverTrain.setPosition(pos);
        //lcd.cls();   
        lcd.printf("Silver train!"); 
        return silverTrain;
    }
}

void executeCase(int pos){
    Train* currTrain = &assignTrain(pos);
    
    switch(pos){
    case 0:
        lcd.printf("at 0");
        break;
    case 1:
        lcd.printf("at 1");
        currTrain->changeSpeed(DCCinst_step4);//Slow down
        lcd.printf("slow down");
        break;
    case 2:
       /*
       Stop everytime at 2
       
       
       
       */
       
        lcd.printf("at 2");        
        if(currTrain->isClockwise())        //IF C goes towards 1
        {
            switch2.switchOff();                                             //Disable switch4
            int arr [3] = {3,4,9};                                          
            vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
            dect.clearReservation(detectors);                                //Free 3,4,9
            currTrain->changeSpeed(DCCinst_step13);                          //Move forward
        }
       else{                                                               //IF CC                        
           if(!dect.checkReservation(4) && !dect.checkReservation(3)){     //Check if 4 or 3 is reserved
               int v1 = rand() % 100;                                       //IF NOT randomize which way to go
               if (v1 < 25){                                                //0.25 chance to enable the switch2,  reserve 3,9
                    switch2.switchOn();
                    int arr [2] = {3,9};
                    vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
                    dect.makeReservation(detectors);
                } 
                else {                                                      //0.75 chance to disable switch2, reserve 4
                   switch2.switchOff(); 
                    vector<int> detectors(4);
                    dect.makeReservation(detectors);
                }
            
            }else if(dect.checkReservation(10)){                             //IF 4 is reserved
                switch2.switchOn();                                        //Enable switch2, reserve 3,9
                int arr [2] = {3,9};
                vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
                dect.makeReservation(detectors);
                    
            }else{                                                          //IF 3 reserved 
                switch2.switchOff();                                         //Disable switch2, reserve 4
                vector<int> detectors(4);
                dect.makeReservation(detectors);
            }
            
            currTrain->changeSpeed(DCCinst_step13);                          //Go forward
        }         
        break;
    case 3:
        lcd.printf("at 3");
        if(currTrain->isClockwise()){   //Clock: Goes from 3 to 2 
            if(!dect.checkReservation(2)){
                switch2.switchOn();         //Enable switch2
                int arr [5] = {0,1,2,12,13};
                vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
                dect.makeReservation(detectors);                                 //Reserve 0,1,2, 12, 13
                currTrain->changeSpeed(DCCinst_step13);         //go forward
            }
            else{
                currTrain->Stop();       
            }
        }
        else{                                           //Other Clock: Goes from 3->9
            currTrain->changeDirection();               //change direction  
            switch2.switchOff();                        //Disable switch2
            int arr [5] = {0,1,2,12,13};
            vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
            dect.clearReservation(detectors);              //free nr 0,1,2,12,13    
            currTrain->changeSpeed(DCCinst_step13);         //go forward                                                                 
        }
        
        break;
    case 4:
        lcd.printf("At 4");
        if(currTrain->isClockwise())        //IF Clock goes towards 2
        {
            int arr [4] = {5,6,7,8};
            vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
            dect.clearReservation(detectors); //free nr 5,6, 7, 8
            switch2.switchOff();          //Turn of switch2
            if(dect.checkReservation(2)){   //Check if 2 is reserved
                currTrain->Stop();           //IF yes STOP
            }
            else{                           
                int arr [5] = {0,1,2,12,13};//else reserve 12,13,0,1,2 
                vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
                dect.makeReservation(detectors);
                currTrain->changeSpeed(DCCinst_step13);      //go forward
            }    
        }                     
        else{ //IF CC :goes towards 6
            int arr [5] = {0,1,2,12,13};
            vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
            dect.clearReservation(detectors);   //free nr 0,1,2,12,13
            switch3.switchOn();                 //Turn on switch3
            dect.showReservation();
            wait(2);
            if(dect.checkReservation(6)){   //Check if 6 is reserved
                lcd.printf("stop, 6 is reserved");
                currTrain->Stop();           //IF yes STOP
                lcd.cls();
                lcd.printf("Currtrain: ");
                lcd.printf("%d", currTrain->getSpeed());
                lcd.printf("\n Silver: ");
                lcd.printf("%d", silverTrain.getSpeed());
                
            }
            else{
                int arr [3] = {6,7,8};
                vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
                dect.makeReservation(detectors);  //else reserve 6,7,8 and go forward
                currTrain->changeSpeed(DCCinst_step13);
            }
            
        }   
        break;      
    case 5:
        lcd.printf("at 5");
        
        if(!currTrain->isClockwise()){   //CC: Goes from 5 to 6
            if(!dect.checkReservation(2)){
                switch3.switchOff();         //Disable switch3
                int arr [3] = {6,7,8};
                vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
                dect.makeReservation(detectors);                                 //Reserve 6,7,8
                currTrain->changeSpeed(DCCinst_step13);         //go forward
            }
            else{
                currTrain->Stop();       
            }
        }
        else{                                           //Other Clock: Goes from 5->11
            currTrain->changeDirection();               //change direction  
            switch3.switchOn();                        //Enable switch3
            int arr [3] = {6,7,8};
            vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
            dect.clearReservation(detectors);              //free nr 6,7,8
            currTrain->changeSpeed(DCCinst_step13);          //go forward                                                               
        }
        break;
    case 6:
        lcd.printf("At 6");
        if(!currTrain->isClockwise())        //IF CC goes towards 7
        {
            switch3.switchOn();                                             //Enable switch3
            int arr [3] = {4,5,11};
            vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
            dect.clearReservation(detectors);                               //free nr 4,5,11
            currTrain->changeSpeed(DCCinst_step13);                          //Move forward
        }
        else{                           
           if(!dect.checkReservation(4) && !dect.checkReservation(5)){      //Check if 4 or 5 is reserved
               int v1 = rand() % 100;                                       //IF NOT randomize which way to go
               if (v1 < 25){                                                //0.25 chance to disable the switch3, reserve 5,11
                    switch3.switchOff();
                    int arr [2] = {5,11};
                    vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
                    dect.makeReservation(detectors);
                } 
                else {                                                      //0.75 chance to Enable switch3, reserve 4
                   switch3.switchOn(); 
                    vector<int> detectors(4);
                    dect.makeReservation(detectors);
                }
            
            }else if(dect.checkReservation(4)){                             //IF 4 is reserved
                switch3.switchOff();                                        //Disable switch3, reserve 5,11
                int arr [2] = {5, 11};
                vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
                dect.makeReservation(detectors);
                    
            }else{                                                          //IF 5 reserved
                switch3.switchOn();                                         //Enable switch3, reserve 4
                vector<int> detectors(4);
                dect.makeReservation(detectors);
            }
            
            currTrain->changeSpeed(DCCinst_step13);                          //Go forward
        }         
        break;
    case 7:
        lcd.printf("At 7yhyh");
        break;
    case 8:
          lcd.printf("At 8");
        if(currTrain->isClockwise())        //IF C goes towards 7
        {
            switch4.switchOff();                                             //Disable switch4
            int arr [3] = {3,9,10};                                          
            vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
            dect.clearReservation(detectors);                                //Free 3,9,10
            currTrain->changeSpeed(DCCinst_step13);                          //Move forward
        }
       else{                                                               //IF CC                        
           if(!dect.checkReservation(9) && !dect.checkReservation(10)){     //Check if 9 or 10 is reserved
               int v1 = rand() % 100;                                       //IF NOT randomize which way to go
               if (v1 < 25){                                                //0.25 chance to enable the switch4,  reserve 3,9
                    switch4.switchOn();
                    int arr [2] = {3,9};
                    vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
                    dect.makeReservation(detectors);
                } 
                else {                                                      //0.75 chance to disable switch4, reserve 10
                   switch4.switchOff(); 
                    vector<int> detectors(10);
                    dect.makeReservation(detectors);
                }
            
            }else if(dect.checkReservation(10)){                             //IF 10 is reserved
                switch4.switchOn();                                        //Enable switch4, reserve 3,9
                int arr [2] = {3,9};
                vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
                dect.makeReservation(detectors);
                    
            }else{                                                          //IF 9 reserved 
                switch4.switchOff();                                         //Disable switch4, reserve 10
                vector<int> detectors(10);
                dect.makeReservation(detectors);
            }
            
            currTrain->changeSpeed(DCCinst_step13);                          //Go forward
        }         
        break;
    case 9:
        lcd.printf("at 9"); 
         if(currTrain->isClockwise()){   //Clock: Goes from 9 to 8
            if(!dect.checkReservation(8)){
                switch4.switchOn();         //Enable switch4
                int arr [3] = {6,7,8};
                vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
                dect.makeReservation(detectors);                                 //Reserve 6,7,8
                currTrain->changeSpeed(DCCinst_step13);                          //Go forward

            }
              else{
                currTrain->Stop();       
            }
        }
        else{                                           //Other Clock: Goes from 9->3
            currTrain->changeDirection();               //change direction  
            switch4.switchOff();                        //Disable switch4
            int arr [3] = {6,7,8};
            vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
            dect.clearReservation(detectors);              //free nr 6,7,8 
            currTrain->changeSpeed(DCCinst_step13);                          //Go forward                                                       
        }
        break;
    case 10:
        lcd.printf("At 10");
        if(!currTrain->isClockwise())        //IF CC goes towards 12
        {
            int arr [4] = {6,7,8,9};
            vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
            dect.clearReservation(detectors); //free nr 6, 7, 8, 9
            switch1.switchOff();          //Turn of switch1
            if(dect.checkReservation(12)){   //Check if 12 is reserved
                currTrain->Stop();           //IF yes STOP
            }
            else{                           
                int arr [5] = {0,1,2,12,13};//else reserve 12,13,0,1,2 
                vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
                dect.makeReservation(detectors);
                currTrain->changeSpeed(DCCinst_step13);      //go forward
            }    
        }         
        
         else{ //IF C :goes towards 8
            int arr [5] = {0,1,2,12,13};
            vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
            dect.clearReservation(detectors);   //free nr 0,1,2,12,13
            switch4.switchOff();                 //Turn off switch4
            
            if(dect.checkReservation(8)){   //Check if 8 is reserved
                currTrain->Stop();           //IF yes STOP                
            }
            else{
                int arr [3] = {6,7,8};
                vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
                dect.makeReservation(detectors);  //else reserve 6,7,8 and go forward
                currTrain->changeSpeed(DCCinst_step13);
            }  
        }   
        break;
        
    case 11:
        lcd.printf("at 11");
        
        if(currTrain->isClockwise()){   //Clockwise: Goes from 11 to 5
            currTrain->changeDirection();               //change direction
            switch1.switchOff();         //Disable switch1
            int arr [5] = {0,1,2,12,13};
            vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
            dect.clearReservation(detectors);                                 //free 0,1,2,12,13
            currTrain->changeSpeed(DCCinst_step13);         //go forward    

        }
        else{                                           //Other Clock: Goes from 11->12 
            if(!dect.checkReservation(8)){
                
                switch1.switchOn();                        //Enable switch1
                int arr [5] = {0,1,2, 12,13};
                vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
                dect.makeReservation(detectors);               //Reserve 0,1,2, 12, 13   
                currTrain->changeSpeed(DCCinst_step13);         //go forward   
            }
            else{
                currTrain->Stop();       
            }                                                             
        }
        break;
    case 12: 
        lcd.printf("at 12");
        if(!currTrain->isClockwise())        //IF CC goes towards 13
        {
            switch1.switchOff();               //Turn of switch1
            int arr [3] = {5,10,11};
            vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
            dect.clearReservation(detectors); //free nr 5, 10, 11
            currTrain->changeSpeed(DCCinst_step13);                          //Move forward
        }
        else{                                                               //if C
           if(!dect.checkReservation(10) && !dect.checkReservation(11)){      //Check if 10 or 11 is reserved
               int v1 = rand() % 100;                                       //IF NOT randomize which way to go
               if (v1 < 25){                                                //0.25 chance to enable the switch1, reserve 5,11
                    switch1.switchOn();
                    int arr [2] = {5,11};
                    vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
                    dect.makeReservation(detectors);
                } 
                else {                                                      //0.75 chance to disable switch1, reserve 10
                   switch1.switchOff(); 
                    vector<int> detectors(10);
                    dect.makeReservation(detectors);
                }
            
            }else if(dect.checkReservation(10)){                             //IF 10 is reserved
                switch1.switchOn();                                        //Enable switch1, reserve 5,11
                int arr [2] = {5, 11};
                vector<int> detectors(arr, arr + sizeof(arr) / sizeof(int));
                dect.makeReservation(detectors);
                    
            }else{                                                          //IF 11 reserved
                switch1.switchOff();                                         //Disable switch1, reserve 10
                vector<int> detectors(10);
                dect.makeReservation(detectors);
            }
            
            currTrain->changeSpeed(DCCinst_step13);                          //Go forward
        }         
        break;
            
    
    case 13: 
        lcd.printf("at 13");
        break;
    case 14:
        lcd.printf("at 21");
        break;
    case 15:
        lcd.printf("at 22"); 
        
        //lcd.printf("In case ");
        //lcd.printf("%d", pos);
        break;
    default:   
        lcd.printf("Not in a valid case");
        break; 
    }
    
    mcp->_read(GPIOA);
    mcp->_read(GPIOB);
}

void checkDetector(int inter){
    lcd.cls();
    int pos;
    wait_us(100);
    if (inter == 0){
        //Read from first one
        pos = mcp->_read(INTCAPA);
        pos = convertHextoDec(pos, 0);
    }
    else if (inter == 1){
        //Read from second one
        pos = mcp->_read(INTCAPB);
        pos = convertHextoDec(pos, 1);
    }
    else 
        //PROBLEM
        lcd.printf("Fail to detect int");
        
    executeCase(pos);
    
}

bool readSwitch(DigitalIn theSwitch){
    int val = theSwitch.read();
    //lcd.printf("%d", val);
    if(val == 1)
    return true;
    else
    return false;
}

void init_mcp() {
    // Initialisation of MCP registers,documentation on registers is availableatNiels/Jacco/Natalia
    mcp = new MCP23017(i2c, 0x40);
    mcp->_write(IODIRA, (unsigned char )0xff);
    mcp->_write(IODIRB, (unsigned char )0xff);
    mcp->_write(IPOLA, (unsigned char )0x00);
    mcp->_write(IPOLB, (unsigned char )0x00);
    mcp->_write(DEFVALA, (unsigned char )0xff);
    mcp->_write(DEFVALB, (unsigned char )0xff);
    mcp->_write(INTCONA, (unsigned char )0xff);
    mcp->_write(INTCONB, (unsigned char )0xff);
    mcp->_write(IOCONA, (unsigned char )0x2);
    mcp->_write(IOCONB, (unsigned char )0x2);
    mcp->_write(GPPUA, (unsigned char )0xff);
    mcp->_write(GPPUB, (unsigned char )0xff);
}
void passZero(){
    checkDetector(0);
}

void passOne(){
    checkDetector(1);
}

void init_interrupt() {
    // Clear current interrupts
    mcp->_read(GPIOA);
    mcp->_read(GPIOB);
    // Register callbacks
    int0.fall(&passZero);
    int1.fall(&passOne);
    // Enable interrupts on MCP
    mcp->_write(GPINTENA, (unsigned char )0xff);
    mcp->_write(GPINTENB, (unsigned char )0xff);// Ready to go!
}

void init_trains(){
    redTrain.changeSpeed(0x40);
    silverTrain.changeSpeed(0x40);
    
    vector<int> res;
    res.push_back(2);
    res.push_back(4);
    dect.makeReservation(res); //Run trains counterclockwise and reserve the 
    vector<int> res2;
    res2.push_back(12);
    res2.push_back(13);
    dect.makeReservation(res2);
}