Jasmine Karlsson / Mbed 2 deprecated train_rail

Dependencies:   mbed TextLCD

main.cpp

Committer:
KwamsC
Date:
2018-06-06
Revision:
14:a5fd98a957e6
Parent:
13:78a2481fd65b
Child:
15:8d96f7a06103

File content as of revision 14:a5fd98a957e6:

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

//board 1

I2C i2c(p28, p27);              // sda, scl pins (you can also use the other I2C port pins: 9,10)

const int addr0 = 0x20 << 1;    // 7-bit base address of the MCP23017 + address bits (which are 000 for the first one), shifted 1 place to the right (see top header)

/* LED Definitions */
DigitalOut myled(LED1);
DigitalOut myled2(LED2);
DigitalOut myled3(LED3);
DigitalOut myled4(LED4);

TextLCD lcd(p22, p21, p23, p24, p25, p26); // lcd

AnalogIn Ain(p20);          // pot. met.
DigitalOut Track(p21);      // train track

/* Train detectors d2, d21, d22 (trainstation) */
AnalogIn detect_21(p15);
AnalogIn detect_22(p16);
AnalogIn detect_2(p17);

/* Switch Definitions */
DigitalIn sw1(p5);
DigitalIn sw2(p30);
DigitalIn sw3(p29);
DigitalIn sw4(p28);

/* Train Definitions */
unsigned int DCCaddress_darkRed = 0x01;
unsigned int DCCaddress_lightRed = 0x03;

/* Train movement */

/*----------------------------------------------------------------------------
Train movement
*----------------------------------------------------------------------------*/
//move forward
unsigned int DCCinst_forward = 0x68; //forward half speed

//move backwards/reverse
unsigned int DCCinst_reverse = 01001000; //reverse half speed

//speed dial
unsigned int DCCinst_step1 = 01100010; //step 1
unsigned int DCCinst_step2 = 01110010; //step 2
unsigned int DCCinst_step3 = 01100011; //step 3
unsigned int DCCinst_step4 = 01110011; //step 4
unsigned int DCCinst_step5 = 01100100; //step 5
unsigned int DCCinst_step6 = 01110100; //step 6 1/4 speed

unsigned int DCCinst_step13 = 01100000; //step 13 1/2 speed

unsigned int DCCinst_step20 = 01110101; //step 20 3/4 speed

unsigned int DCCinst_step28 = 01111111; //step 28 Full speed

//stop 
unsigned int DCCinst_forward_stop = 0x60; //forward and stop 01100000

//move forward

//speed dial

//stop 

//read switch out

//read signal

//display message


/*----------------------------------------------------------------------------
Functions
*----------------------------------------------------------------------------*/
/* Functions definition */
void mcpWriteReg(uint8_t address, uint8_t reg, uint8_t data);   // Write an I2C register
uint8_t mcpReadReg(uint8_t address, uint8_t reg);               // Read an I2C register 
void initMcp0(void);            // Initialization of MCP23017 with address bits 000 (track sensors)
void testMcp0(void);            // Test of MCP23017 with address bits 000
void readVoltage();
void readDetector();
void DCC_send_command(unsigned int address, unsigned int inst, unsigned int repeat_count); //send command

int main() {
    while(1){
        //unsigned int DCCaddress = 0x03;
        //unsigned int DCCaddress_darkRed = 0x01;
        readDetector();
        lcd.printf("Forward");
        DCC_send_command(DCCaddress_lightRed,DCCinst_forward,400); // forward half speed train address 3
        wait(0.5);
        lcd.printf("Stop");
        DCC_send_command(DCCaddress_lightRed,DCCinst_forward_stop,400); // forward half speed train address 3
        wait(1);
        //readVoltage();
        //myled=1; 
    }
}

void readDetector(){
    float val = detect_21.read();
    lcd.printf("%.2f", val);
    }

void readVoltage(){
        float f = Ain.read(); //Read voltage value
        float Vin = f *3.3;
        lcd.printf("%.2f", Vin);
        wait(0.1);
        lcd.printf("\n");
    }

void mcpWriteReg(uint8_t address, uint8_t reg, uint8_t data){
    char cmd[2];cmd[0] = reg;
    cmd[1] = data;
    i2c.write(address, cmd, 2);   // Write 2 bytes to device on specified address
}

uint8_t mcpReadReg(uint8_t address, uint8_t reg){
    char cmd[1];
    cmd[0] = reg;
    i2c.write(address, cmd, 1);     // Write address
    i2c.read(address, cmd, 1);      // Read value (one byte)
    
    return cmd[0];                  // Return the read value
}

/* Initialization of the MCP23017 for the track sensors. 
We should enable the MCP23017 interrupts here because the sensors will only give a short pulse to the MCP23017*/
void initMcp0(void){
    mcpWriteReg(addr0, MCP_IODIRA, 0xff);     // All inputs
    mcpWriteReg(addr0, MCP_IODIRB, 0xff);     // All inputs
}

/* Test of the track sensors
*  This does not use interrupts so the chance of actually detecting a train is very, very low
*  With some patience it's good enough to test the hardware though.
*/
void testMcp0(void) {
    uint16_t sensors; // Put both ports in the sensor variable
    sensors = (mcpReadReg(addr0, MCP_GPIOB) << 8) | mcpReadReg(addr0, MCP_GPIOA);
    // Flip all bits, since the sensors are active low and it gives me headaches
    // You could also set the IPOLA / IPOLB registers instead (see page 13 of the MCP23017 datasheet)
    sensors = ~sensors;
    lcd.printf("sensors: %04X\n", sensors);
    }

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);
            } else {
                //send data for a "1"bit
                Track=0;
                wait_us(58);
                Track=1;
                wait_us(58);
            }
            // next bit in packet
            temp_command = temp_command<<1;
        }
        i++;
    }
}