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.
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);
}
