Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: main.cpp
- Revision:
- 45:d589318238bf
- Parent:
- 44:94870081aece
- Child:
- 46:7a0933676b13
--- a/main.cpp Mon Jun 18 13:51:39 2018 +0000 +++ b/main.cpp Mon Jun 18 14:16:43 2018 +0000 @@ -71,6 +71,7 @@ //......SENSOR POSITION VARS +//Definition of D sensors, will be interpreted as ints for the program's logic #define D0 0 #define D1 1 #define D2 2 @@ -89,7 +90,6 @@ #define D22 15 - /** * *Position class. @@ -107,8 +107,6 @@ *add_ccw() - * **/ - - class Position{ private: int position; @@ -148,55 +146,84 @@ }; }; + //Creating a vector with all the positions. vector<Position> positions; + +/** +* +*Train class. +* +*@position - +*@going_cw - +* +*Train(int, bool) - +*Train(bool) - +* +*Vector get_next_sensors() - +*set_position(int) - +*set_goes_cw(bool) - +*Position get_position() - +*Int get_position_number() - +*Bool goes_cw() - +* +**/ class Train{ + private: Position *position; bool going_cw; + public: Train(int pos, bool cw){ + position = &positions[pos]; going_cw = cw; } - Train(bool cw){ - going_cw = cw; - } + + Train(bool cw){ going_cw = cw; } vector<int> get_next_sensors(){ //Checking direction if(going_cw){ + return position->get_next_cw(); }else{ + return position->get_next_ccw(); } } void set_position(int pos){ + position = &positions[pos]; //Taking the new position from the positions vector } void set_goes_cw(bool cw){ + going_cw = cw; } Position get_position(){ + return *position; } int get_position_number(){ + return position->get_pos(); } bool goes_cw(){ + return going_cw; } }; + //Creation of all the positions. One for every sensor on the table - Position name(mapping) - Position d0(D0); Position d1(D1); Position d2(D2); @@ -214,6 +241,11 @@ Position d21(D21); Position d22(D22); +/** +*Defining areas for train detection and collision logic. +*area_A_arr/area_B_arr - Arrays that hold the Dsensors for each area, used to initialize the vectors. +*area_A/area_B - Vectors that hold the different sensors of the corresponding areas of the track. +**/ int area_A_arr[] = {D21,D2,D22,D1,D0,D13,D12}; int area_B_arr[] = {D6,D7,D8}; @@ -222,7 +254,6 @@ - //.....DCC TRAIN COMMAND VARS //typical out of box default engine DCC address is 3 (at least for Bachmann trains) @@ -256,19 +287,31 @@ const unsigned int SWBflip_4 = 0x88; //Flip SW4 -//Starting position and orientation of the trains +/** +*Creation of 2 Train objects. +*Using boolean constructor because position initialization will be done after initializing all position vectors. +*DR_train = Dark Red train - LR_train = Light Red Train +**/ Train DR_train(true); //Position and going_cw Train LR_train(true); +/** +*Booleans that will determine if the train should be moving or not. +*Booleans will switch to false to stop any of the trains and avoid collisions. +*DR_run - Boolean for DR_train / LR_run - Boolean for LR_train +**/ bool DR_run = true; bool LR_run = true; + //**************** FUNCTIONS FOR DENVER TRAIN ****************// /** +* *Activates the buzzer for 0.5 seconds. +* **/ void doBuzz(){ @@ -277,9 +320,14 @@ buzz = 0; } + +/** +* +* +* +**/ void init_positions(){ - d0.add_prev_cw(D1); d0.add_prev_ccw(D13); @@ -351,6 +399,7 @@ positions.push_back(d22); } + /** * *Here we initialize the mcp that will be used to manage the interrupts. @@ -374,32 +423,46 @@ } + /** * *Returns the number of the sensor where the train was detected. * **/ int get_sensor(unsigned int number,int interrupt){ + int sensor = -1; for(int i=0; i<8; i++){ - if(~number & 1<<i){ + if(~number & 1<<i){ + sensor = i; } } if(interrupt == 1){ + sensor+= 8; // Sensors caught by interreupt1 are identified from 8 to 15. } + return sensor; } + +/** +* +* +* +**/ bool in_vector(vector<int>v,int element){ + bool exist = false; for(int i=0; i< v.size(); i++){ + if(v[i] == element){ + exist = true; } } @@ -407,32 +470,40 @@ return exist; } + /** * Check if there is an avodable frontal collision: * Both trains in area A or B with different direction * Trains in (D11 and D5) or (D9 and D3) with same direction */ bool check_NAC(bool DR_in_A, bool DR_in_B,bool LR_in_A,bool LR_in_B){ + bool NAC = false; if((DR_in_A && LR_in_A) || (DR_in_B && LR_in_B) ){ //Check if both are in same area + if(DR_train.goes_cw() ^ LR_train.goes_cw()){ //XOR: They must have different values to be true (Different direction) + NAC = true; } }else if((DR_train.get_position_number() == D11) && (LR_train.get_position_number() == D5 )){ //Check if they are in position D11 and D5 + if(!(DR_train.goes_cw() ^ LR_train.goes_cw())){ // NOT XOR: They must have same values to be true (Same direction) + NAC = true; } }else if((DR_train.get_position_number() == D9) && (LR_train.get_position_number() == D3 )){//Check if they are in position D9 and D3 + if(!(DR_train.goes_cw() ^ LR_train.goes_cw())){ // NOT XOR: They must have same values to be true (Same direction) + NAC = true; } } - return NAC; - + return NAC; } + /** * Check if there is an Avoidable Frontal Collision * Train in area A(ccw) and train in D4(cw) @@ -441,15 +512,21 @@ * Train in area B(ccw) and train in D10(ccw) */ bool check_AFC(bool DR_in_A, bool DR_in_B,bool LR_in_A,bool LR_in_B){ - if( DR_train.get_position_number() == D4){ + + if( DR_train.get_position_number() == D4){ + if(DR_train.goes_cw()){ + if(LR_in_A && !LR_train.goes_cw()){ + //Activate switch2 //DR_train has to stop //When LR is at D3 DR continues } }else{ //DR goes ccw + if(LR_in_B && LR_train.goes_cw()){ + //DR_train stops //Activate switch3 //When LR is at D5 DR continues @@ -457,14 +534,19 @@ } }else if(DR_train.get_position_number() == D10){ + if(DR_train.goes_cw()){ + if(LR_in_B && !LR_train.goes_cw()){ + //DR train stops //Activate switch4 //When LR is at D9 DR continues } }else{ + if(LR_in_A && LR_train.goes_cw()){ + //DR train stops //Activate switch1 //When LR is at D9 DR continues @@ -473,7 +555,14 @@ } } + +/** +* +* +* +**/ void check_position(){ + bool DR_in_A, DR_in_B, LR_in_A, LR_in_B; DR_in_A=in_vector(area_A,DR_train.get_position_number()); //Check if DR train is in area A @@ -483,6 +572,12 @@ } + +/** +* +* +* +**/ void update_train_pos(int sensor){ bool found_DR = false; @@ -493,34 +588,41 @@ //TODO: Do a for to print all next sensors. for(int i=0; i<DR_train.get_next_sensors().size(); i++){ + lcd.printf("%d,",DR_train.get_next_sensors()[i]); } + lcd.printf(") LR("); - for(int i=0; i<LR_train.get_next_sensors().size(); i++){ + for(int i=0; i<LR_train.get_next_sensors().size(); i++){ + lcd.printf("%d,",LR_train.get_next_sensors()[i]); } + lcd.printf(")"); - wait(0.7); //Checking next sensors for DR train for(int i=0; i<DR_train.get_next_sensors().size(); i++){ if(DR_train.get_next_sensors()[i] == sensor){ //If the sensor is one expected to visit by the train we update the position + found_DR = true; DR_train.set_position(sensor); if(DR_train.goes_cw()){ - if(sensor == D9 || sensor == D3){ + + if(sensor == D9 || sensor == D3){ + DR_train.set_goes_cw(false); //If train goes cw and passes D5 or D11 we change orientation } }else{ + if(sensor == D5 || sensor == D11){ + DR_train.set_goes_cw(true); //If train goes ccw and passes D9 or D3 we change orientation } } - } } @@ -528,37 +630,43 @@ for(int i=0; i<LR_train.get_next_sensors().size(); i++){ if(LR_train.get_next_sensors()[i] == sensor){ + lcd.cls(); lcd.printf("Detected!"); found_LR = true; LR_train.set_position(sensor); - if(LR_train.goes_cw()){ + if(LR_train.goes_cw()){ + if(sensor == D9 || sensor == D3){ + LR_train.set_goes_cw(false); //If train goes cw and passes D5 or D11 we change orientation } }else{ if(sensor == D5 || sensor == D11){ + LR_train.set_goes_cw(true); //If train goes ccw and passes D9 or D3 we change orientation } } } } - if(found_DR){ + //doBuzz(); lcd.cls(); lcd.printf("DR is at D%d",DR_train.get_position_number()); - } + if(found_LR){ lcd.cls(); lcd.printf("LR is at D%d",LR_train.get_position_number()); } + if(!found_DR && !found_LR){ + lcd.cls(); lcd.printf("No train before :("); } @@ -578,12 +686,10 @@ lcd.cls(); lcd.printf("int0 0x%x \n Sensor: %d",sensor_data,sensor); - update_train_pos(sensor); } - /** * *Method to catch interrupts 1 @@ -600,8 +706,13 @@ update_train_pos(sensor); } +/** +* +* +* +**/ +void init() { // Clear current interrupts -void init() { // Clear current interrupts mcp->_read(GPIOA); mcp->_read(GPIOB); // Register callbacks int0.fall(&on_int0_change); @@ -620,8 +731,8 @@ *@repeat_count - Number of times the command will be sent * **/ -void DCC_send_command(unsigned int address, unsigned int inst, unsigned int repeat_count) -{ +void DCC_send_command(unsigned int address, unsigned int inst, unsigned int repeat_count){ + unsigned __int64 command = 0x0000000000000000; // __int64 is the 64-bit integer type unsigned __int64 temp_command = 0x0000000000000000; unsigned __int64 prefix = 0x3FFF; // 14 "1" bits needed at start @@ -650,7 +761,6 @@ Track=1; wait_us(100); //printf("0011"); - }else{ //send data for a "1"bit @@ -682,30 +792,36 @@ unsigned int SWBflip = SWBidle; //IDLE - Flip last activated SW. switch(switchId){ + case 1: SWBflip = SWBflip_1; //FLIP SW1 break; + case 2: SWBflip = SWBflip_2; //FLIP SW2 break; + case 3: SWBflip = SWBflip_3; //FLIP SW3 break; + case 4: SWBflip = SWBflip_4; //FLIP SW4 break; + default: break; } //Security measure not to burn the switch. if(times <=5){ + DCC_send_command(SWBaddress,SWBflip,times); //Activating switch if(!activate){ + DCC_send_command(SWBaddress,SWBidle,times); //Sending IDLE to flip back. } } - } @@ -722,19 +838,16 @@ lcd.cls(); lcd.printf("Switch 1 ON - SW1"); flipSwitch(1,5); - }else if(switch2 == 1){ lcd.cls(); lcd.printf("Switch 2 ON - SW2"); flipSwitch(2,5); - }else if(switch3 == 0){ lcd.cls(); lcd.printf("Switch 3 ON - SW3"); - flipSwitch(3,5); - + flipSwitch(3,5); }else if(switch4 == 0){ lcd.cls(); @@ -743,22 +856,36 @@ } } + +/** +* +* +* +**/ void send_command(){ + if(DR_run){ + DCC_send_command(DCCaddressDR,DCCinst_forward,1); // Forward half speed train addres DARK-RED }else{ + DCC_send_command(DCCaddressDR,DCCinst_stop,400); } if(LR_run){ + DCC_send_command(DCCaddressLR,DCCinst_forward,1); // Forward half speed train addres DARK-RED }else{ + DCC_send_command(DCCaddressLR,DCCinst_stop,400); } } + + //**************** MAIN PROGRAM FOR DENVER TRAIN ****************// + int main() { //RISE FOR INTERRUPTS?? NOT WORKING ATM