Denver / Mbed 2 deprecated denver_train_proj

Dependencies:   mbed TextLCD

Committer:
mglmx
Date:
Fri Jun 08 10:09:46 2018 +0000
Revision:
21:e6f1649add39
Parent:
20:608ab9bf340d
Child:
22:e4153ca757dd
Switches but errors in code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mglmx 0:4d06a6a8e785 1 #include "mbed.h"
mglmx 3:fe7010b693a0 2 #include "TextLCD.h"
mglmx 18:aa43bb62e60f 3 #include "MCP23017.h"
mglmx 18:aa43bb62e60f 4
mglmx 18:aa43bb62e60f 5
mglmx 1:0ab26889af9b 6 //mbed DCC Model Train Demo
mglmx 1:0ab26889af9b 7
carlosperales95 7:e2b8461d4f05 8 /******PINS AND DECLARATIONS*******/
carlosperales95 7:e2b8461d4f05 9
mglmx 21:e6f1649add39 10
mglmx 21:e6f1649add39 11 //SWITCHES p5 - p8
mglmx 21:e6f1649add39 12 DigitalIn switch1(p5);
mglmx 21:e6f1649add39 13 DigitalIn switch2(p6);
mglmx 21:e6f1649add39 14 DigitalIn switch3(p7);
mglmx 21:e6f1649add39 15 DigitalIn switch4(p8);
carlosperales95 7:e2b8461d4f05 16
carlosperales95 10:2088b1935a93 17 //RAIL SENSORS - INT0,INT1
carlosperales95 7:e2b8461d4f05 18 //INT0 - p9
mglmx 18:aa43bb62e60f 19 InterruptIn int0(p9);
carlosperales95 7:e2b8461d4f05 20 //INT1 - p10
mglmx 18:aa43bb62e60f 21 InterruptIn int1(p10);
carlosperales95 7:e2b8461d4f05 22
carlosperales95 7:e2b8461d4f05 23 ///p11
carlosperales95 7:e2b8461d4f05 24 ///p12
carlosperales95 12:e914ca5cd44b 25
carlosperales95 7:e2b8461d4f05 26 //M0 - p13
carlosperales95 7:e2b8461d4f05 27 DigitalIn d21(p13);
carlosperales95 7:e2b8461d4f05 28 //M1 - p14
carlosperales95 7:e2b8461d4f05 29 DigitalIn d22(p14);
carlosperales95 7:e2b8461d4f05 30 //M2 - p15
carlosperales95 7:e2b8461d4f05 31 DigitalIn d23(p15);
carlosperales95 12:e914ca5cd44b 32
carlosperales95 7:e2b8461d4f05 33 //p16
carlosperales95 12:e914ca5cd44b 34 //p17
carlosperales95 12:e914ca5cd44b 35
carlosperales95 11:021210c59a95 36 //BUZZER - p18
carlosperales95 11:021210c59a95 37 DigitalOut buzz(p18); // buzz=0 doesn't beep, buzz=1 beeps
carlosperales95 7:e2b8461d4f05 38
carlosperales95 7:e2b8461d4f05 39 //POTENTIOMETER - p19
carlosperales95 13:dbf1ead12cee 40 AnalogIn pot(p19); //Gives float value pot.read(). Convert analog input to V with f*3.3
carlosperales95 7:e2b8461d4f05 41
carlosperales95 7:e2b8461d4f05 42 //DAT - p20
mglmx 3:fe7010b693a0 43 DigitalOut Track(p20); //Digital output bit used to drive track power via H-bridge
carlosperales95 7:e2b8461d4f05 44
carlosperales95 7:e2b8461d4f05 45 //LCD SCREEN - p21, p22, p23, p24, p25, p26
carlosperales95 11:021210c59a95 46 TextLCD lcd(p22,p21,p23,p24,p25,p26); // RS, E, A4, A5, A6, A7 // ldc.cls() to clear and printf(String up to 16char)
carlosperales95 7:e2b8461d4f05 47
carlosperales95 7:e2b8461d4f05 48 ///p27
carlosperales95 7:e2b8461d4f05 49 ///p28
carlosperales95 7:e2b8461d4f05 50
carlosperales95 7:e2b8461d4f05 51 //LED1 - p29
mglmx 3:fe7010b693a0 52 DigitalOut redled(p29);
carlosperales95 7:e2b8461d4f05 53 //LED2 - p30
mglmx 3:fe7010b693a0 54 DigitalOut greenled(p30);
carlosperales95 7:e2b8461d4f05 55
mglmx 18:aa43bb62e60f 56 DigitalOut led1(LED1);
mglmx 18:aa43bb62e60f 57 DigitalOut led2(LED2);
mglmx 18:aa43bb62e60f 58 DigitalOut led3(LED3);
mglmx 16:2a2da0e67793 59
mglmx 16:2a2da0e67793 60 //MCP
mglmx 16:2a2da0e67793 61 MCP23017 *mcp;
carlosperales95 12:e914ca5cd44b 62
carlosperales95 11:021210c59a95 63 //**************** FUNCTIONS FOR DENVER TRAIN ****************//
carlosperales95 10:2088b1935a93 64
mglmx 18:aa43bb62e60f 65
mglmx 18:aa43bb62e60f 66
mglmx 18:aa43bb62e60f 67 void initialize_mcp(){
mglmx 18:aa43bb62e60f 68 mcp = new MCP23017(p28,p27,0x40); //Connect to SCL - p28 and SDA - p27 and MPC I2C address 0x40
mglmx 18:aa43bb62e60f 69
mglmx 18:aa43bb62e60f 70 mcp->reset();
mglmx 18:aa43bb62e60f 71 mcp->writeRegister(0x00, (unsigned char )0xff);
mglmx 18:aa43bb62e60f 72 mcp->writeRegister(0x01, (unsigned char )0xff);
mglmx 18:aa43bb62e60f 73 mcp->writeRegister(0x02, (unsigned char )0x00);
mglmx 18:aa43bb62e60f 74 mcp->writeRegister(0x03, (unsigned char )0x00);
mglmx 18:aa43bb62e60f 75 mcp->writeRegister(0x04, (unsigned char )0xff);
mglmx 18:aa43bb62e60f 76 mcp->writeRegister(0x05, (unsigned char )0xff);
mglmx 18:aa43bb62e60f 77 mcp->writeRegister(0x06, (unsigned char )0xff);
mglmx 18:aa43bb62e60f 78 mcp->writeRegister(0x07, (unsigned char )0xff);
mglmx 18:aa43bb62e60f 79 mcp->writeRegister(0x08, (unsigned char )0xff);
mglmx 18:aa43bb62e60f 80 mcp->writeRegister(0x09, (unsigned char )0xff);
mglmx 18:aa43bb62e60f 81 mcp->writeRegister(0x0a, (unsigned char )0x42);
mglmx 18:aa43bb62e60f 82 mcp->writeRegister(0x0b, (unsigned char )0x42);
mglmx 18:aa43bb62e60f 83 mcp->writeRegister(0x0c, (unsigned char )0x00);
mglmx 18:aa43bb62e60f 84 mcp->writeRegister(0x0d, (unsigned char )0x00);
mglmx 18:aa43bb62e60f 85 }
mglmx 18:aa43bb62e60f 86
mglmx 16:2a2da0e67793 87 void interrupt0(){
mglmx 16:2a2da0e67793 88 int data = mcp->readRegister(GPIO);
mglmx 17:0a657e338356 89 lcd.cls();
mglmx 16:2a2da0e67793 90 lcd.printf("int0 %d",data);
mglmx 17:0a657e338356 91 buzz = 1;
mglmx 17:0a657e338356 92 wait(0.5);
mglmx 17:0a657e338356 93 buzz = 0;
mglmx 16:2a2da0e67793 94 }
mglmx 16:2a2da0e67793 95
mglmx 16:2a2da0e67793 96 void interrupt1(){
mglmx 16:2a2da0e67793 97 int data = mcp->readRegister(GPIO);
mglmx 17:0a657e338356 98 lcd.cls();
mglmx 17:0a657e338356 99 lcd.printf("int1 %d",data);
mglmx 17:0a657e338356 100 buzz = 1;
mglmx 17:0a657e338356 101 wait(0.5);
mglmx 17:0a657e338356 102 buzz = 0;
mglmx 16:2a2da0e67793 103 }
mglmx 5:ce0f66ea12c5 104
mglmx 1:0ab26889af9b 105
mglmx 1:0ab26889af9b 106 void DCC_send_command(unsigned int address, unsigned int inst, unsigned int repeat_count)
mglmx 1:0ab26889af9b 107 {
mglmx 1:0ab26889af9b 108 unsigned __int64 command = 0x0000000000000000; // __int64 is the 64-bit integer type
mglmx 1:0ab26889af9b 109 unsigned __int64 temp_command = 0x0000000000000000;
mglmx 1:0ab26889af9b 110 unsigned __int64 prefix = 0x3FFF; // 14 "1" bits needed at start
mglmx 1:0ab26889af9b 111 unsigned int error = 0x00; //error byte
mglmx 1:0ab26889af9b 112 //calculate error detection byte with xor
mglmx 1:0ab26889af9b 113 error = address ^ inst;
mglmx 1:0ab26889af9b 114 //combine packet bits in basic DCC format
mglmx 1:0ab26889af9b 115 command = (prefix<<28)|(address<<19)|(inst<<10)|((error)<<1)|0x01;
mglmx 1:0ab26889af9b 116 //printf("\n\r %llx \n\r",command);
mglmx 1:0ab26889af9b 117 int i=0;
mglmx 1:0ab26889af9b 118 //repeat DCC command lots of times
mglmx 1:0ab26889af9b 119 while(i < repeat_count) {
mglmx 1:0ab26889af9b 120 temp_command = command;
mglmx 1:0ab26889af9b 121 //loops through packet bits encoding and sending out digital pulses for a DCC command
mglmx 1:0ab26889af9b 122 for (int j=0; j<64; j++) {
mglmx 1:0ab26889af9b 123 if((temp_command&0x8000000000000000)==0) { //test packet bit
mglmx 1:0ab26889af9b 124 //send data for a "0" bit
mglmx 1:0ab26889af9b 125 Track=0;
mglmx 1:0ab26889af9b 126 wait_us(100);
mglmx 1:0ab26889af9b 127 Track=1;
mglmx 1:0ab26889af9b 128 wait_us(100);
mglmx 1:0ab26889af9b 129 //printf("0011");
mglmx 1:0ab26889af9b 130 } else {
mglmx 1:0ab26889af9b 131 //send data for a "1"bit
mglmx 1:0ab26889af9b 132 Track=0;
mglmx 1:0ab26889af9b 133 wait_us(58);
mglmx 1:0ab26889af9b 134 Track=1;
mglmx 1:0ab26889af9b 135 wait_us(58);
mglmx 1:0ab26889af9b 136 //printf("01");
mglmx 1:0ab26889af9b 137 }
mglmx 1:0ab26889af9b 138 // next bit in packet
mglmx 1:0ab26889af9b 139 temp_command = temp_command<<1;
mglmx 1:0ab26889af9b 140 }
mglmx 1:0ab26889af9b 141 i++;
mglmx 0:4d06a6a8e785 142 }
mglmx 0:4d06a6a8e785 143 }
carlosperales95 11:021210c59a95 144
mglmx 21:e6f1649add39 145 void flipSwitch(int switchId, int times){
mglmx 21:e6f1649add39 146 //Command variables for Switches using DCC
mglmx 21:e6f1649add39 147
mglmx 21:e6f1649add39 148 unsigned int SWBaddress = 0x06; //address for switch box
mglmx 21:e6f1649add39 149
mglmx 21:e6f1649add39 150 ////100DDDDD where DDDDD
mglmx 21:e6f1649add39 151 ///00001 to flip the first switch SW1 (F1 active)
mglmx 21:e6f1649add39 152 ///00010 to flip the second switch SW2 (F2 active)
mglmx 21:e6f1649add39 153 ///00100 to flip the third switch SW3 (F3 active)
mglmx 21:e6f1649add39 154 ///01000 to flip the fourth switch SW4 (F4 active)
mglmx 21:e6f1649add39 155 //example - 111111 0 00000101 0 10000000 0 10000101 1 - idleç
mglmx 21:e6f1649add39 156
mglmx 21:e6f1649add39 157 unsigned int SWBflip = 0x80; //No switches -- idle
mglmx 21:e6f1649add39 158
mglmx 21:e6f1649add39 159 switch(switchId){
mglmx 21:e6f1649add39 160 case 1:
mglmx 21:e6f1649add39 161 SWBflip = 0x81; //FLIP 1
mglmx 21:e6f1649add39 162 break;
mglmx 21:e6f1649add39 163 case 2:
mglmx 21:e6f1649add39 164 SWBflip = 0x82;
mglmx 21:e6f1649add39 165 break;
mglmx 21:e6f1649add39 166 case 3:
mglmx 21:e6f1649add39 167 SWBflip = 0x84;
mglmx 21:e6f1649add39 168 break;
mglmx 21:e6f1649add39 169 case 4:
mglmx 21:e6f1649add39 170 SWBflip = 0x90;
mglmx 21:e6f1649add39 171 break;
mglmx 21:e6f1649add39 172 default:
mglmx 21:e6f1649add39 173 break;
mglmx 21:e6f1649add39 174
mglmx 21:e6f1649add39 175 }
carlosperales95 11:021210c59a95 176
mglmx 21:e6f1649add39 177 //Security measure not to burn the switch.
mglmx 21:e6f1649add39 178 if(times <=5){
mglmx 21:e6f1649add39 179 DCC_send_command(SWBaddress,SWBflip,times);
mglmx 21:e6f1649add39 180 }
mglmx 21:e6f1649add39 181
mglmx 21:e6f1649add39 182
mglmx 21:e6f1649add39 183 }
mglmx 21:e6f1649add39 184
mglmx 21:e6f1649add39 185 void checkSwitch(){
mglmx 21:e6f1649add39 186 if(switch)
mglmx 21:e6f1649add39 187 }
carlosperales95 12:e914ca5cd44b 188
carlosperales95 11:021210c59a95 189 //**************** MAIN PROGRAM FOR DENVER TRAIN ****************//
carlosperales95 11:021210c59a95 190
mglmx 1:0ab26889af9b 191 int main()
mglmx 1:0ab26889af9b 192 {
mglmx 2:f580707c44fa 193 led1 = 1;
mglmx 2:f580707c44fa 194 wait(0.5);
mglmx 2:f580707c44fa 195 led1 = 0;
mglmx 2:f580707c44fa 196 wait(0.5);
mglmx 2:f580707c44fa 197 led1 = 1;
mglmx 16:2a2da0e67793 198
mglmx 16:2a2da0e67793 199 initialize_mcp();
mglmx 16:2a2da0e67793 200
mglmx 18:aa43bb62e60f 201 int0.rise(&interrupt0);
mglmx 18:aa43bb62e60f 202 int1.rise(&interrupt1);
mglmx 16:2a2da0e67793 203
mglmx 21:e6f1649add39 204 led2 = 1;
mglmx 21:e6f1649add39 205 flipSwitch(1,1);
mglmx 21:e6f1649add39 206 wait(0.2);
mglmx 21:e6f1649add39 207 led2 = 0;
mglmx 21:e6f1649add39 208 wait(0.2);
mglmx 21:e6f1649add39 209
mglmx 21:e6f1649add39 210 led2 = 1;
mglmx 21:e6f1649add39 211 flipSwitch(2,1);
mglmx 21:e6f1649add39 212 wait(0.2)
mglmx 21:e6f1649add39 213 led2 = 0;
mglmx 21:e6f1649add39 214
mglmx 21:e6f1649add39 215
mglmx 21:e6f1649add39 216
mglmx 21:e6f1649add39 217
mglmx 21:e6f1649add39 218
mglmx 16:2a2da0e67793 219
mglmx 1:0ab26889af9b 220 //typical out of box default engine DCC address is 3 (at least for Bachmann trains)
mglmx 1:0ab26889af9b 221 //Note: A DCC controller can reprogram the address whenever needed
mglmx 1:0ab26889af9b 222 unsigned int DCCaddress = 0x01;
mglmx 1:0ab26889af9b 223 //see http://www.nmra.org/standards/DCC/standards_rps/RP-921%202006%20Aug%2021.pdf
mglmx 1:0ab26889af9b 224 //01DCSSSS for speed, D is direction (fwd=1 and rev=0), C is speed(SSSSC) LSB
mglmx 1:0ab26889af9b 225 unsigned int DCCinst_forward = 0x68; //forward half speed
mglmx 1:0ab26889af9b 226 unsigned int DCCinst_reverse = 0x48; //reverse half speed
mglmx 4:50879dfb82d5 227 unsigned int DCCinst_stop = 0x50;
mglmx 1:0ab26889af9b 228 //100DDDDD for basic headlight functions
mglmx 1:0ab26889af9b 229 unsigned int DCC_func_lighton = 0x90; //F0 turns on headlight function
mglmx 1:0ab26889af9b 230 unsigned int DCC_func_dimlight = 0x91; //F0 + F1 dims headlight
mglmx 1:0ab26889af9b 231 //
mglmx 1:0ab26889af9b 232 //Basic DCC Demo Commands
mglmx 1:0ab26889af9b 233 DCC_send_command(DCCaddress,DCC_func_lighton,200); // turn light on full
mglmx 1:0ab26889af9b 234 DCC_send_command(DCCaddress,DCC_func_dimlight,200); //dim light
mglmx 1:0ab26889af9b 235 DCC_send_command(DCCaddress,DCC_func_lighton,200); //light full again
carlosperales95 14:7bb998edd819 236
carlosperales95 19:ff21ba3a4dc5 237
carlosperales95 19:ff21ba3a4dc5 238
carlosperales95 19:ff21ba3a4dc5 239
carlosperales95 19:ff21ba3a4dc5 240
carlosperales95 14:7bb998edd819 241 //Demo for stopping at the station
mglmx 1:0ab26889af9b 242 while(1) {
mglmx 4:50879dfb82d5 243
mglmx 4:50879dfb82d5 244 if(d21 == 1 || d22 == 1 || d23 == 1){
carlosperales95 14:7bb998edd819 245
mglmx 4:50879dfb82d5 246 lcd.cls();
mglmx 4:50879dfb82d5 247 lcd.printf("Choo Choo station");
carlosperales95 14:7bb998edd819 248 DCC_send_command(DCCaddress,DCCinst_stop,400); // Stop train address 3
mglmx 4:50879dfb82d5 249
mglmx 21:e6f1649add39 250 }else if(switch1 == 1){
mglmx 21:e6f1649add39 251 switchFlip(1,1);
mglmx 21:e6f1649add39 252
mglmx 21:e6f1649add39 253 }
mglmx 21:e6f1649add39 254 {
carlosperales95 14:7bb998edd819 255 DCC_send_command(DCCaddress,DCCinst_forward,1); // Forward half speed train address 3
mglmx 4:50879dfb82d5 256 }
mglmx 4:50879dfb82d5 257
mglmx 4:50879dfb82d5 258
mglmx 4:50879dfb82d5 259 /*
mglmx 3:fe7010b693a0 260 float f = pot.read();
mglmx 3:fe7010b693a0 261 float vin = f * 3.3;
mglmx 3:fe7010b693a0 262
mglmx 2:f580707c44fa 263 led3 = 1;
mglmx 3:fe7010b693a0 264 if(switch1 == 1){
mglmx 3:fe7010b693a0 265 lcd.cls();
mglmx 3:fe7010b693a0 266 lcd.printf("Going forward");
mglmx 3:fe7010b693a0 267 greenled = 0;
mglmx 3:fe7010b693a0 268 redled = 1;
mglmx 3:fe7010b693a0 269 DCC_send_command(DCCaddress,DCCinst_forward,400); // forward half speed train address 3
mglmx 3:fe7010b693a0 270 lcd.cls();
mglmx 3:fe7010b693a0 271
mglmx 3:fe7010b693a0 272 lcd.printf("vin: %.4f",vin);
mglmx 3:fe7010b693a0 273 wait(0.2);
mglmx 3:fe7010b693a0 274
mglmx 3:fe7010b693a0 275 }else{
mglmx 3:fe7010b693a0 276 lcd.cls();
mglmx 3:fe7010b693a0 277 lcd.printf("Going backwards");
mglmx 3:fe7010b693a0 278 greenled = 1;
mglmx 3:fe7010b693a0 279 redled = 0;
mglmx 3:fe7010b693a0 280 DCC_send_command(DCCaddress,DCCinst_reverse,400); // reverse half speed train address 3
mglmx 3:fe7010b693a0 281 lcd.cls();
mglmx 3:fe7010b693a0 282
mglmx 3:fe7010b693a0 283 lcd.printf("vin: %.4f",vin);
mglmx 3:fe7010b693a0 284 wait(0.2);
mglmx 3:fe7010b693a0 285
mglmx 3:fe7010b693a0 286 }
mglmx 4:50879dfb82d5 287 */
mglmx 1:0ab26889af9b 288 }
mglmx 3:fe7010b693a0 289 }