Denver / Mbed 2 deprecated denver_train_proj

Dependencies:   mbed TextLCD

main.cpp

Committer:
mglmx
Date:
2018-06-11
Revision:
23:3fe9e76e06f2
Parent:
22:e4153ca757dd
Child:
24:1d71dd8778c4

File content as of revision 23:3fe9e76e06f2:

#include "mbed.h"
#include "TextLCD.h"
#include "MCP23017.h"
#include <string>
#include <iostream>

//mbed DCC Model Train Demo
 
/******PINS AND DECLARATIONS*******/


//SWITCHES p5 - p8
DigitalIn switch1(p5);
DigitalIn switch2(p6);
DigitalIn switch3(p7);
DigitalIn switch4(p8);

//RAIL SENSORS - INT0,INT1
//INT0 - p9
InterruptIn int0(p9);
//INT1 - p10
InterruptIn int1(p10);

///p11
///p12

//M0 - p13
DigitalIn d21(p13);
//M1 - p14
DigitalIn d22(p14);
//M2 - p15
DigitalIn d23(p15);

//p16
//p17

//BUZZER - p18
DigitalOut buzz(p18); // buzz=0 doesn't beep, buzz=1 beeps

//POTENTIOMETER - p19
AnalogIn pot(p19);  //Gives float value pot.read(). Convert analog input to V with f*3.3

//DAT - p20
DigitalOut Track(p20); //Digital output bit used to drive track power via H-bridge

//LCD SCREEN - p21, p22, p23, p24, p25, p26
TextLCD lcd(p22,p21,p23,p24,p25,p26); // RS, E, A4, A5, A6, A7 // ldc.cls() to clear and printf(String up to 16char)

///p27
///p28

//LED1 - p29
DigitalOut redled(p29);
//LED2 - p30
DigitalOut greenled(p30);

DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);

//MCP
MCP23017 *mcp;

//**************** FUNCTIONS FOR DENVER TRAIN ****************//


/**
*  Activates the buzzer for 0.5 seconds.
**/
void doBuzz(){
    buzz = 1;
    wait(0.5);
    buzz = 0;    
}

/**

*/
void initialize_mcp(){
    mcp = new MCP23017(p28,p27,0x40); //Connect to SCL - p28 and SDA - p27 and MPC I2C address 0x40 
    
    mcp->reset();
    mcp->writeRegister(0x00, (unsigned char )0xff);
    mcp->writeRegister(0x01, (unsigned char )0xff);
    mcp->writeRegister(0x02, (unsigned char )0x00);
    mcp->writeRegister(0x03, (unsigned char )0x00);
    mcp->writeRegister(0x04, (unsigned char )0xff);
    mcp->writeRegister(0x05, (unsigned char )0xff);
    mcp->writeRegister(0x06, (unsigned char )0xff);
    mcp->writeRegister(0x07, (unsigned char )0xff);
    mcp->writeRegister(0x08, (unsigned char )0xff);
    mcp->writeRegister(0x09, (unsigned char )0xff);
    mcp->writeRegister(0x0a, (unsigned char )0x42);
    mcp->writeRegister(0x0b, (unsigned char )0x42);
    mcp->writeRegister(0x0c, (unsigned char )0x00);
    mcp->writeRegister(0x0d, (unsigned char )0x00);
}

void interrupt0(){
     int data = mcp->readRegister(GPIO);
     lcd.cls();
     lcd.printf("int0 %x",data);
     redled = 1;
     wait(0.2);
     redled = 0;
     
}

void interrupt1(){
    int data = mcp->readRegister(GPIO);
    lcd.cls();
    lcd.printf("int1 %x",data);
    greenled = 1;
    wait(0.2);
    greenled = 0;
}
 
 
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
    unsigned int error = 0x00; //error byte
    //calculate error detection byte with xor
    error = address ^ inst;
    //combine packet bits in basic DCC format
    command = (prefix<<28)|(address<<19)|(inst<<10)|((error)<<1)|0x01;
    //printf("\n\r %llx \n\r",command);
    int i=0;
//repeat DCC command lots of times
    while(i < repeat_count) {
        temp_command = command;
//loops through packet bits encoding and sending out digital pulses for a DCC command
        for (int j=0; j<64; j++) {
            if((temp_command&0x8000000000000000)==0) { //test packet bit
                //send data for a "0" bit
                Track=0;
                wait_us(100);
                Track=1;
                wait_us(100);
                //printf("0011");
            } else {
                //send data for a "1"bit
                Track=0;
                wait_us(58);
                Track=1;
                wait_us(58);
                //printf("01");
            }
            // next bit in packet
            temp_command = temp_command<<1;
        }
        i++;
    }
}

void flipSwitch(int switchId, int times){
    //Command variables for Switches using DCC
    
    unsigned int SWBaddress = 0x06; //address for switch box
    
    ////100DDDDD where DDDDD 
    ///00001 to flip the first switch SW1 (F1 active)
    ///00010 to flip the second switch SW2 (F2 active)
    ///00100 to flip the third switch SW3 (F3 active)
    ///01000 to flip the fourth switch SW4 (F4 active)
    
    /// 00011 maybe flips 1 and 2
    
    //example - 111111 0 00000101 0 10000000 0 10000101 1 - idleç
    
    unsigned int SWBflip = 0x80; //No switches -- idle
    
    switch(switchId){
        case 1:
            SWBflip = 0x81;     //FLIP 1
            break;
        case 2:
            SWBflip = 0x82;
            break;
        case 3:
            SWBflip = 0x84;
            break;
        case 4:
            SWBflip = 0x88;
            break;
        default:
            break;
            
    }          

    //Security measure not to burn the switch.
    if(times <=5){
        DCC_send_command(SWBaddress,SWBflip,times);
    }
    

}



/* 
Check the swithces of the box. If they have 1 value the railSiwtches flip.
*/

void switching(string sw1,string sw2, string sw3, string sw4){
    string strInst = "1000" + sw1 + sw2 + sw3 + sw4;
    
    //unsigned int inst = stoi(strInst);
    
    
    //DCC_send_command(0x06,inst,5);
    
       
}

void checkSwitch(){
    if(switch1 == 1){
        lcd.cls();
        lcd.printf("Switch 1 ON - SW1");
        flipSwitch(1,5); //IDLE
     }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);
    } else if(switch4 == 0){
        lcd.cls();
        lcd.printf("Switch 4 ON - IDLE");
        flipSwitch(0,5);
    }

}
/*
void checkSwitch(){
    int switches[] = [0,0,0,0]
    bool changed = false;
    if(switch1 == 1){
        changed = true;
        switches[0]=1;
    }
    if(switch2 == 1){ 
        changed = true; 
        switches[1]=1;   
    }
    if(switch3 == 1){
        changed = true;
        switches[2]=1;
    }
    if(switch4 == 1){
        changed = true;
        switches[3]=1;
        
    }
    
    if(changed){
        switching(switches[0],switches[)
    }
    
        
}

*/

//**************** MAIN PROGRAM FOR DENVER TRAIN ****************//

int main()
{
    led1 = 1;
    wait(0.2);
    led1 = 0;
    wait(0.2);
    led1 = 1;
    
    
    initialize_mcp();
    
    //int0.rise(&interrupt0);
    //int1.rise(&interrupt1);
         

    //typical out of box default engine DCC address is 3 (at least for Bachmann trains)
    //Note: A DCC controller can reprogram the address whenever needed
    unsigned int DCCaddress = 0x01;
    //see http://www.nmra.org/standards/DCC/standards_rps/RP-921%202006%20Aug%2021.pdf
    //01DCSSSS for speed, D is direction (fwd=1 and rev=0), C is speed(SSSSC) LSB
    unsigned int DCCinst_forward = 0x68; //forward half speed
    unsigned int DCCinst_reverse = 0x48; //reverse half speed
    unsigned int DCCinst_stop = 0x50;
    //100DDDDD for basic headlight functions
    unsigned int DCC_func_lighton = 0x90; //F0 turns on headlight function
    unsigned int DCC_func_dimlight = 0x91; //F0 + F1 dims headlight
    //
    //Basic DCC Demo Commands
    DCC_send_command(DCCaddress,DCC_func_lighton,200); // turn light on full
    DCC_send_command(DCCaddress,DCC_func_dimlight,200); //dim light
    DCC_send_command(DCCaddress,DCC_func_lighton,200);  //light full again


    //DCC_send_command(0x06,0x8F,5);  ALL SWITCHES
    
    led3 = 1; // Entering the while
    
    lcd.cls();
    lcd.printf("Ready to start");
    
    //Demo for stopping at the station
    while(1) {
        
        if(d21 == 1 || d22 == 1 || d23 == 1){
            
            lcd.cls();
            lcd.printf("Choo Choo station");
            DCC_send_command(DCCaddress,DCCinst_stop,400); // Stop train address 3 
            checkSwitch();    
            
        }else{
            checkSwitch();    
            DCC_send_command(DCCaddress,DCCinst_forward,1); // Forward half speed train address 3 
        }
        
        
        /*
        float f = pot.read();
        float vin = f * 3.3;
            
        led3 = 1;
        if(switch1 == 1){
            lcd.cls();
            lcd.printf("Going forward");
            greenled = 0;
            redled = 1;  
            DCC_send_command(DCCaddress,DCCinst_forward,400); // forward half speed train address 3 
            lcd.cls();
            
            lcd.printf("vin: %.4f",vin);
            wait(0.2);
            
        }else{
            lcd.cls();
            lcd.printf("Going backwards");
            greenled = 1;
            redled = 0; 
            DCC_send_command(DCCaddress,DCCinst_reverse,400); // reverse half speed train address 3
            lcd.cls();
            
            lcd.printf("vin: %.4f",vin);
            wait(0.2);
            
        }
        */
    }
}