RAGLINK+ CabViewer
A desktop train controller based on Arduino for OpenBVE.
Components and supplies
Computer LCD Monitor (generic)
USB-A to Mini-USB Cable
Nextion NX8048T070 - Generic 7.0" HMI TFT LCD Touch Display
PC computer with triple screen supported GPU (generic)
KHT-2 16W1D Band Switch
Acrylic sheet 5mm (generic)
AD16-16C 16mm LED
Arduino Mega 2560
LA38-11X2 20X3 22mm switch
LAY37-11Y2 20Y3 22mm key switch
LA38-11 LA38-11BN 22mm button
CH340G USB-TTL Cable
Tools and machines
3D Printer (generic)
Hot glue gun (generic)
Soldering iron (generic)
Laser cutter (generic)
Apps and platforms
Windows 10
OpenBVE Core & RAGLINK+ Application
Project description
Code
Source Code for Arduino MEGA2560
c_cpp
1/*Desktop Train Controller 2=========================================== 3--Board: Arduino MEGA 2560 4--Version: 1.0 5--Simulator: OpenBVE 6=========================================== 7--Note: 8State Automatic Ready 9=========================================== 10--Devices: 11Type:0.SWITCH_C -> CHANGE 12Type:1.SWITCH_F -> FALLING 13Type:3.ENCODER -> CHANGE (in developing) 14=========================================== 15--Train: 160.SPEED -> INT 171.REVERSER -> INT 182.POWER -> U8 193.BRAKE -> U8 204.SIGNAL -> INT 215.SIGNAL_DISTANCE -> INT 226.SPEED_LIMIT -> INT 237.HORN -> BOOL 248.SPEED_CONST -> INT 259.MASTER_KEY -> BOOL 26=========================================== 27*/ 28#define SWITCH_C 0 29#define SWITCH_F 1 30#define ENCODER 2 31#define DIG_OUT 3 32#define ANALOG_OUT 4 33#define DELAY_TIME 10 34#define IGNORE -1 35#define COUNT 2 36#define KEY_UP 0 37#define KEY_WAITTING 1 38#define KEY_DOWN 2 39#define SA_COUNT_SF 500 40#define SA_COUNT_SC 300 41// 42#define SPEED_MIN 0 43#define SPEED_MAX 400 44#define REVERSER_FORWARD 1 45#define REVERSER_NEUTRAL 0 46#define REVERSER_BACKWARD -1 47#define POWER_MIN 0 48#define POWER_MAX 4 49#define BRAKE_MIN 0 50#define BRAKE_MAX 8 51#define SIGNAL_RED 0 52#define SIGNAL_YELLOW 1 53#define SIGNAM_GREEN 2 54#define SIGNAL_DISTANCE_N1 2000 55#define SIGNAL_DISTANCE_N2 1500 56#define SIGNAL_DISTANCE_N3 1000 57#define SIGNAL_DISTANCE_N4 500 58#define SIGNAL_DISTANCE_DE 0 59#define SIGNAL_PASS 0 60#define HORN_OFF 0 61#define HORN_ON 1 62#define SPEED_LIMIT_MIN 0 63#define SPEED_LIMIT_DEF 30 64#define SPEED_LIMIT_MAX 400 65#define SPEED_CONST_MIN 0 66#define SPEED_CONST_DEF 30 67#define SPEED_CONST_MAX 400 68#define MASTER_KEY_OFF 0 69#define MASTER_KEY_ON 1 70#define EMERGENCY_ON 1 71#define EMERGENCY_OFF 0 72#define OVERWRITE 0 73#define NORMAL 1 74// 75#define LDOOR_OPEN_DEF 0 76#define RDDOR_OPEN_DEF 0 77#define SANDER_OFF 0 78#define PANTO_UP 1 79#define LIGHT_OFF 0 80#define CURRENT_STATION_N 0 81#define NEXT_STATION_N 0 82#define NEXT_STATION_DIS_DEF 0 83#define CURRENT_STATION_DEPART_TIME_DEF 0 84#define NEXT_STATION_ARRIVAL_TIME_DEF 0 85#define CURRENT_TIME_DEF 0 86#define LDOOR_IN_OP_DEF 0 87#define RDOOR_IN_OP_DEF 0 88//Devices 89#define DEVICE_NUMBER 17 90#define DEVICE_TYPE_NUMBER 3 91#define ACTIVE 0 92#define NO_ACTIVE 1 93#define NO_READY 0 94#define READY 1 95#define ON 1 96#define OFF 0 97#define ANALOG_OUT_MIN 0 98#define ANALOG_OUT_MAX 255 99//Train 100#define TRAIN_DATA_NUMBER 25 101#define _INT 0 102#define _BOOL 1 103#define _STRING 3 104#define SPEED 0 105#define REVERSER 1 106#define POWER 2 107#define BRAKE 3 108#define SIGNAL_INFO 4 109#define SIGNAL_DISTANCE 5 110#define SPEED_LIMIT 6 111#define HORN 7 112#define SPEED_CONST 8 113#define MASTER_KEY 9 114#define EMERGENCY 10 115#define RC_MODE 11 116#define LDOOR_OPEN 12 117#define RDOOR_OPEN 13 118#define LIGHT_OPEN 15 119#define PANTO_OPEN 16 120#define SANDER_OPEN 14 121#define CURRENT_STATION_NAME 17 122#define NEXT_STATION_NAME 18 123#define CURRENT_STATION_DEPART 20 124#define NEXT_STATION_ARRIVAL 21 125#define NEXT_STATION_DIS 19 126#define CURRENT_TIME 22 127#define LDDOR_IN_OP 23 128#define RDOOR_IN_OP 24 129#define UPDATE_LAST_NUM 14 130#define UPDATE_OW 8 131//PC 132#define FILTER '|' 133#define START_SYM '#' 134#define END_SYM '!' 135#define NO_DATA "" 136#define RECIEVE_DELAY 2 137#define SEND_DELAY 25 138#define TIMER_TICK 200 139//Special Args 140#define CONTROLLER_INFO "#ver|" 141 142#define NOP do { __asm__ __volatile__ ("nop"); } while (0) 143 144#include "FlexiTimer2.h" 145#include "avr/wdt.h" 146#include "HardwareSerial.h" 147 148typedef void (*funcPoint)(); 149// 150/* 151 =========================================== 152 --Device Maps 153 default: 154 PowerUp:process0 155 PowerDown:process1 156 ReserverForward:process2 157 ReserverBackward:process3 158 Horn:process4 159 SpeedConst:process5 160 Emergency:process6 161 MasterKey:process7 162 =========================================== 163*/ 164 165void process0(); 166void process1(); 167void process2(); 168void process3(); 169void process4(); 170void process5(); 171void process6(); 172void process7(); 173void process8(); 174void process9(); 175void process10(); 176void process11(); 177void process12(); 178void process13(); 179void process14(); 180void process15(); 181void process16(); 182 183//change device type here 184const int deviceType[DEVICE_NUMBER] = {SWITCH_C, SWITCH_C, SWITCH_C, SWITCH_C, SWITCH_C, SWITCH_C, SWITCH_C, SWITCH_C, SWITCH_C, SWITCH_C, 185 SWITCH_C, DIG_OUT, SWITCH_C, DIG_OUT, SWITCH_C, SWITCH_C, SWITCH_C 186 }; 187//change functions here 188const int devicePinsType[] = {INPUT_PULLUP, INPUT_PULLUP, INPUT_PULLUP, OUTPUT}; 189const funcPoint Process[DEVICE_NUMBER] = {process0, process1, process2, process3, process4, process5, process6, process7, process8, process9, 190 process10, process11, process12, process13, process14, process15, process16 191 }; 192//all use PULL_UP gpio mode 193//key for bac horn -3 -2 -1 1 2 3 ld ldled rd rdled light pat sand 194const int devicePins[DEVICE_NUMBER] = {31, 32, 33, 37, 25, 26, 27, 28, 29, 30, 39, 41, 22, 24, 35, 34, 38}; 195int deviceLastState[DEVICE_NUMBER] = {KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, 196 KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP 197 }; 198int deviceSADur[DEVICE_NUMBER] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 199 0, 0, 0, 0, 0, 0, 0 200 }; 201//train data id 202const int dataDefault[TRAIN_DATA_NUMBER] = {SPEED_MIN, REVERSER_NEUTRAL, POWER_MIN, BRAKE_MIN, SIGNAL_RED, 203 SIGNAL_DISTANCE_DE, SPEED_LIMIT_DEF, HORN_OFF, SPEED_CONST_MIN, MASTER_KEY_OFF, 204 EMERGENCY_OFF, NORMAL, LDOOR_OPEN_DEF, RDDOR_OPEN_DEF, SANDER_OFF, LIGHT_OFF, PANTO_UP, CURRENT_STATION_N, NEXT_STATION_N, 205 NEXT_STATION_DIS_DEF, CURRENT_STATION_DEPART_TIME_DEF, NEXT_STATION_ARRIVAL_TIME_DEF, CURRENT_TIME_DEF, LDOOR_IN_OP_DEF, RDOOR_IN_OP_DEF 206 }; 207const int dataType[TRAIN_DATA_NUMBER] = {_INT, _INT, _INT, _INT, _INT, _INT, _INT, _BOOL, _INT, _BOOL, _BOOL, _BOOL, _BOOL, _BOOL, 208 _BOOL, _BOOL, _INT, _STRING, _STRING, _STRING, _STRING, _STRING, _STRING, _BOOL, _BOOL 209 }; 210const int recieveToUpdate[UPDATE_LAST_NUM] = {SPEED, SIGNAL_INFO, SIGNAL_DISTANCE, SPEED_LIMIT, RC_MODE, LDDOR_IN_OP, RDOOR_IN_OP, NEXT_STATION_NAME, CURRENT_STATION_NAME, 211 NEXT_STATION_DIS, NEXT_STATION_ARRIVAL, CURRENT_STATION_DEPART, NEXT_STATION_DIS, CURRENT_TIME 212 }; 213const int overwriteToUpdate[UPDATE_OW] = {POWER, BRAKE, REVERSER, SPEED, SIGNAL_INFO, SIGNAL_DISTANCE, SPEED_LIMIT, RC_MODE}; 214 215class TrainManager 216{ 217public: 218 int trainData[TRAIN_DATA_NUMBER]; 219 String trainDataStr[TRAIN_DATA_NUMBER]; 220 //did it has been sended 221 TrainManager(const int dataDefault[]) 222 { 223 //set default data to Train Manager 224 for (int i = 0; i < TRAIN_DATA_NUMBER; i++) 225 { 226 trainData[i] = dataDefault[i]; 227 trainDataStr[i] = NO_DATA; 228 } 229 } 230 // 231 void SetData(int dataID, int value) 232 { 233 trainData[dataID] = value; 234 } 235 void SetDataStr(int dataID, String value) 236 { 237 trainDataStr[dataID] = value; 238 } 239 //get train data 240 int GetData(int dataID) 241 { 242 return trainData[dataID]; 243 } 244 String GetDataStr(int dataID) 245 { 246 return trainDataStr[dataID]; 247 } 248}; 249 250class DevicesManager 251{ 252public: 253 DevicesManager(const int devicePins[], const int deviceType[], const int devicePinsType[]) 254 { 255 //define gpio mode 256 for (int i = 0; i < DEVICE_NUMBER; i++) 257 pinMode(devicePins[i], devicePinsType[deviceType[i]]); 258 } 259 // 260 int GetState(int deviceID) 261 { 262 if (deviceType[deviceID] == SWITCH_F) 263 { 264 if (digitalRead(devicePins[deviceID]) == LOW) 265 { 266 if (deviceLastState[deviceID] == KEY_UP) 267 { 268 deviceSADur[deviceID] = 0; 269 deviceLastState[deviceID] = KEY_WAITTING; 270 } 271 else if (deviceLastState[deviceID] == KEY_WAITTING) 272 { 273 deviceSADur[deviceID]++; 274 if (deviceSADur[deviceID] >= SA_COUNT_SF) 275 { 276 deviceSADur[deviceID] = 0; 277 deviceLastState[deviceID] = KEY_DOWN; 278 return ACTIVE; 279 } 280 } 281 } 282 else 283 { 284 deviceLastState[deviceID] = KEY_UP; 285 return NO_ACTIVE; 286 } 287 } 288 else if (deviceType[deviceID] == SWITCH_C) 289 { 290 if (digitalRead(devicePins[deviceID]) == LOW) 291 { 292 if (deviceLastState[deviceID] == KEY_UP) 293 { 294 deviceSADur[deviceID] = 0; 295 deviceLastState[deviceID] = KEY_WAITTING; 296 } 297 else if (deviceLastState[deviceID] == KEY_WAITTING) 298 { 299 deviceSADur[deviceID]++; 300 if (deviceSADur[deviceID] >= SA_COUNT_SC) 301 { 302 deviceSADur[deviceID] = 0; 303 deviceLastState[deviceID] = KEY_DOWN; 304 return ACTIVE; 305 } 306 } 307 else if (deviceLastState[deviceID] == KEY_DOWN)return ACTIVE; 308 } 309 else 310 { 311 deviceLastState[deviceID] = KEY_UP; 312 return NO_ACTIVE; 313 } 314 } 315 return NO_ACTIVE; 316 } 317 // 318 void delay_(int ms) 319 { 320 for (int i = 0; i < ms; i++) 321 { 322 for (int j = 0; j < 1985; j++) NOP; 323 } 324 } 325}; 326 327DevicesManager Devices(devicePins, deviceType, devicePinsType); 328TrainManager currentData(dataDefault); 329TrainManager processData(dataDefault); 330 331class CommunicationManager 332{ 333private: 334 String recieveData; 335 String sendData; 336 String sender; 337 String tmp; 338 int length, st, ed, pos, sendEd; 339public: 340 CommunicationManager() 341 { 342 Serial.begin(115200); 343 //reset the recieved data 344 sendData = NO_DATA; 345 recieveData = NO_DATA; 346 sender = NO_DATA; 347 length = st = ed = pos = 0; 348 sendEd = 0; 349 } 350 351 bool IsSpecialArgs(String recieveData) 352 { 353 if (recieveData == CONTROLLER_INFO)return true; 354 return false; 355 } 356 357 bool SendControllerInfo() 358 { 359 String sendData = NO_DATA; 360 sendData += START_SYM; 361 sendData += "ver|3.1"; 362 sendData += END_SYM; 363 Serial.print(sendData); 364 } 365 366 bool RecieveDataFromPC(TrainManager & p) 367 { 368 tmp = NO_DATA; 369 //clear last data 370 recieveData = NO_DATA; 371 //recieve from serial 372 while (Serial.available() > 0) 373 { 374 char currentRead = char(Serial.read()); 375 recieveData += currentRead; 376 Devices.delay_(RECIEVE_DELAY); 377 //if (currentRead == END_SYM)break; 378 } 379 length = recieveData.length(); 380 //no data exit 381 if (!length)return false; 382 //find start pos 383 //Serial.println(recieveData); 384 385 //Special Args 386 if (IsSpecialArgs(recieveData)) 387 { 388 SendControllerInfo(); 389 return true; 390 } 391 392 st = ed = 0; 393 for (int i = 0; i < length; i++) 394 if (recieveData.charAt(i) == START_SYM) 395 { 396 st = i; 397 break; 398 } 399 //find end pos 400 for (int i = length - 1; i >= 0; i--) 401 if (recieveData.charAt(i) == END_SYM) 402 { 403 ed = i; 404 break; 405 } 406 //cover data 407 pos = 0; 408 for (int i = st; i <= ed; i++) 409 { 410 if (recieveData.charAt(i) != START_SYM && recieveData.charAt(i) != END_SYM && recieveData.charAt(i) != FILTER)tmp += recieveData.charAt(i); 411 if (recieveData.charAt(i) == FILTER) 412 { 413 //send data to TrainManager 414 if (dataType[pos] != _STRING) 415 p.SetData(pos++, tmp.toInt()); 416 else 417 { 418 p.SetDataStr(pos++, tmp); 419 } 420 //clear tmp 421 tmp = NO_DATA; 422 } 423 } 424 return true; 425 } 426 // 427 bool SendDataToPC(TrainManager & p) 428 { 429 sendData = NO_DATA; 430 //add start symbol 431 sendData += START_SYM; 432 //add contents 433 for (int i = 0; i < TRAIN_DATA_NUMBER; i++) 434 { 435 if (dataType[i] != _STRING)sendData += p.GetData(i); 436 else sendData += " "; 437 sendData += FILTER; 438 } 439 //add end symbol 440 sendData += END_SYM; 441 if (!sendData.length())return false; 442 //send data to PC 443 Serial.print(sendData); 444 return true; 445 } 446}; 447 448class TaskManager 449{ 450public: 451 TaskManager() 452 { 453 currentData = processData; 454 } 455 // 456 void AddProc(TrainManager & p) 457 { 458 currentData = p; 459 } 460 // 461 void GetLastState(TrainManager & p) 462 { 463 p = currentData; 464 } 465 // 466 void UpdateData(TrainManager & p) 467 { 468 if (currentData.GetData(RC_MODE) == NORMAL) 469 for (int i = 0; i < UPDATE_LAST_NUM; i++) 470 { 471 if (dataType[recieveToUpdate[i]] != _STRING) 472 p.SetData(recieveToUpdate[i], currentData.GetData(recieveToUpdate[i])); 473 else 474 p.SetDataStr(recieveToUpdate[i], currentData.GetDataStr(recieveToUpdate[i])); 475 } 476 else if (currentData.GetData(RC_MODE) == OVERWRITE) 477 for (int i = 0; i < UPDATE_OW; i++) 478 { 479 if (dataType[overwriteToUpdate[i]] != _STRING) 480 p.SetData(overwriteToUpdate[i], currentData.GetData(overwriteToUpdate[i])); 481 else 482 p.SetDataStr(overwriteToUpdate[i], currentData.GetDataStr(overwriteToUpdate[i])); 483 } 484 //check AP state 485 if (p.GetData(SPEED_CONST) != SPEED_CONST_MIN && 486 currentData.GetData(SPEED_CONST) != SPEED_CONST_MIN) 487 p.SetData(SPEED_CONST, currentData.GetData(SPEED_CONST)); 488 } 489}; 490 491CommunicationManager Communication; 492TaskManager Queue; 493 494int isHandleZero = 0; 495 496 497void process0() 498{ 499 // 500 int deviceState = Devices.GetState(0); 501 isHandleZero++; 502 if (deviceState == ACTIVE) 503 { 504 processData.SetData(MASTER_KEY, MASTER_KEY_ON); 505 } 506 else 507 { 508 processData.SetData(MASTER_KEY, MASTER_KEY_OFF); 509 } 510 return; 511} 512 513void process1() 514{ 515 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF || 516 processData.GetData(EMERGENCY) == EMERGENCY_ON || 517 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 518 int deviceState = Devices.GetState(1); 519 if (deviceState == ACTIVE) 520 { 521 processData.SetData(REVERSER, REVERSER_FORWARD); 522 } 523 else 524 { 525 processData.SetData(REVERSER, REVERSER_NEUTRAL); 526 } 527 return; 528} 529 530void process2() 531{ 532 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF || 533 processData.GetData(EMERGENCY) == EMERGENCY_ON || 534 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 535 int deviceState = Devices.GetState(2); 536 if (deviceState == ACTIVE) 537 { 538 processData.SetData(REVERSER, REVERSER_BACKWARD); 539 } 540 return; 541} 542 543void process3() 544{ 545 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF)return; 546 int deviceState = Devices.GetState(3); 547 if (deviceState == ACTIVE) 548 { 549 processData.SetData(HORN, HORN_ON); 550 } 551 else 552 { 553 processData.SetData(HORN, HORN_OFF); 554 } 555 return; 556} 557 558//-3 559void process4() 560{ 561 //SWITCH_F 562 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF || 563 processData.GetData(EMERGENCY) == EMERGENCY_ON || 564 processData.GetData(REVERSER) == REVERSER_NEUTRAL || 565 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 566 int deviceState = Devices.GetState(4); 567 if (deviceState == ACTIVE) 568 { 569 isHandleZero --; 570 processData.SetData(POWER, 0); 571 processData.SetData(BRAKE, 6); 572 } 573 return; 574} 575 576//-2 577void process5() 578{ 579 //SWITCH_F 580 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF || 581 processData.GetData(EMERGENCY) == EMERGENCY_ON || 582 processData.GetData(REVERSER) == REVERSER_NEUTRAL || 583 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 584 int deviceState = Devices.GetState(5); 585 if (deviceState == ACTIVE) 586 { 587 isHandleZero --; 588 processData.SetData(POWER, 0); 589 processData.SetData(BRAKE, 4); 590 } 591 return; 592} 593 594//-1 595void process6() 596{ 597 //SWITCH_F 598 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF || 599 processData.GetData(EMERGENCY) == EMERGENCY_ON || 600 processData.GetData(REVERSER) == REVERSER_NEUTRAL || 601 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 602 int deviceState = Devices.GetState(6); 603 if (deviceState == ACTIVE) 604 { 605 isHandleZero --; 606 processData.SetData(POWER, 0); 607 processData.SetData(BRAKE, 2); 608 } 609 return; 610} 611 612//1 613void process7() 614{ 615 //SWITCH_F 616 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF || 617 processData.GetData(EMERGENCY) == EMERGENCY_ON || 618 processData.GetData(REVERSER) == REVERSER_NEUTRAL || 619 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 620 int deviceState = Devices.GetState(7); 621 if (deviceState == ACTIVE) 622 { 623 isHandleZero --; 624 processData.SetData(POWER, 1); 625 processData.SetData(BRAKE, 0); 626 } 627 return; 628} 629 630//2 631void process8() 632{ 633 //SWITCH_F 634 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF || 635 processData.GetData(EMERGENCY) == EMERGENCY_ON || 636 processData.GetData(REVERSER) == REVERSER_NEUTRAL || 637 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 638 int deviceState = Devices.GetState(8); 639 if (deviceState == ACTIVE) 640 { 641 isHandleZero --; 642 processData.SetData(POWER, 2); 643 processData.SetData(BRAKE, 0); 644 } 645 return; 646} 647 648//3 649void process9() 650{ 651 //SWITCH_F 652 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF || 653 processData.GetData(EMERGENCY) == EMERGENCY_ON || 654 processData.GetData(REVERSER) == REVERSER_NEUTRAL || 655 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 656 int deviceState = Devices.GetState(9); 657 if (deviceState == ACTIVE) 658 { 659 isHandleZero --; 660 processData.SetData(POWER, 3); 661 processData.SetData(BRAKE, 0); 662 } 663 // 664 if (isHandleZero > 600) 665 { 666 processData.SetData(POWER, 0); 667 processData.SetData(BRAKE, 0); 668 isHandleZero = 0; 669 } 670 return; 671} 672 673//key for bac horn -3 -2 -1 1 2 3 ld ldled rd rdled light pat sand 674 675void process10() 676{ 677 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF)return; 678 int deviceState = Devices.GetState(10); 679 if (deviceState == ACTIVE) 680 { 681 if (processData.GetData(LDOOR_OPEN))return; 682 processData.SetData(LDOOR_OPEN, 1); 683 } 684 else 685 { 686 if (!processData.GetData(LDOOR_OPEN))return; 687 processData.SetData(LDOOR_OPEN, 0); 688 } 689} 690 691void process11() 692{ 693 //pinMode(devicePins[11], OUTPUT); 694 digitalWrite(devicePins[11], processData.GetData(LDDOR_IN_OP)); 695} 696 697void process12() 698{ 699 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF)return; 700 int deviceState = Devices.GetState(12); 701 if (deviceState == ACTIVE) 702 { 703 if (processData.GetData(RDOOR_OPEN))return; 704 processData.SetData(RDOOR_OPEN, 1); 705 } 706 else 707 { 708 if (!processData.GetData(RDOOR_OPEN))return; 709 processData.SetData(RDOOR_OPEN, 0); 710 } 711} 712 713void process13() 714{ 715 //pinMode(devicePins[13], OUTPUT); 716 digitalWrite(devicePins[13], processData.GetData(RDOOR_IN_OP)); 717} 718 719void process14() 720{ 721 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF)return; 722 int deviceState = Devices.GetState(14); 723 if (deviceState == ACTIVE) 724 { 725 if (processData.GetData(LIGHT_OPEN))return; 726 processData.SetData(LIGHT_OPEN, 1); 727 } 728 else 729 { 730 if (!processData.GetData(LIGHT_OPEN))return; 731 processData.SetData(LIGHT_OPEN, 0); 732 } 733} 734 735void process15() 736{ 737 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF)return; 738 int deviceState = Devices.GetState(15); 739 if (deviceState == ACTIVE) 740 { 741 processData.SetData(PANTO_OPEN, !processData.GetData(PANTO_OPEN)); 742 while (Devices.GetState(15) == ACTIVE) 743 { 744 wdt_reset(); 745 } 746 //while (Devices.GetState(14) == ACTIVE); 747 } 748} 749 750void process16() 751{ 752 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF)return; 753 int deviceState = Devices.GetState(16); 754 if (deviceState == ACTIVE) 755 { 756 processData.SetData(SANDER_OPEN, 1); 757 } 758 else 759 { 760 processData.SetData(SANDER_OPEN, 0); 761 } 762} 763 764void TimerInterrupt() 765{ 766 FlexiTimer2::stop(); 767 Communication.SendDataToPC(currentData); 768 Communication.RecieveDataFromPC(currentData); 769 FlexiTimer2::start(); 770} 771 772void setup() 773{ 774 Serial.begin(115200); 775 wdt_enable(WDTO_1S); 776 FlexiTimer2::set(TIMER_TICK, TimerInterrupt); 777 FlexiTimer2::start(); 778} 779 780void loop() 781{ 782 //state automatic 783 Queue.GetLastState(processData); 784 for (int i = 0; i < DEVICE_NUMBER; i++) 785 { 786 Process[i](); 787 wdt_reset(); 788 } 789 Queue.UpdateData(processData); 790 Queue.AddProc(processData); 791}
Source Code for Arduino DUE
c_cpp
1/*Desktop Train Controller 2=========================================== 3--Board: Arduino MEGA 2560 4--Version: 1.0 5--Simulator: OpenBVE 6=========================================== 7--Note: 8State Automatic Ready 9=========================================== 10--Devices: 11Type:0.SWITCH_C -> CHANGE 12Type:1.SWITCH_F -> FALLING 13Type:3.ENCODER -> CHANGE (in developing) 14=========================================== 15--Train: 160.SPEED -> INT 171.REVERSER -> INT 182.POWER -> U8 193.BRAKE -> U8 204.SIGNAL -> INT 215.SIGNAL_DISTANCE -> INT 226.SPEED_LIMIT -> INT 237.HORN -> BOOL 248.SPEED_CONST -> INT 259.MASTER_KEY -> BOOL 26=========================================== 27*/ 28#define SWITCH_C 0 29#define SWITCH_F 1 30#define ENCODER 2 31#define DIG_OUT 3 32#define ANALOG_OUT 4 33#define DELAY_TIME 10 34#define IGNORE -1 35#define COUNT 2 36#define KEY_UP 0 37#define KEY_WAITTING 1 38#define KEY_DOWN 2 39#define SA_COUNT_SF 500 40#define SA_COUNT_SC 300 41// 42#define SPEED_MIN 0 43#define SPEED_MAX 400 44#define REVERSER_FORWARD 1 45#define REVERSER_NEUTRAL 0 46#define REVERSER_BACKWARD -1 47#define POWER_MIN 0 48#define POWER_MAX 4 49#define BRAKE_MIN 0 50#define BRAKE_MAX 8 51#define SIGNAL_RED 0 52#define SIGNAL_YELLOW 1 53#define SIGNAM_GREEN 2 54#define SIGNAL_DISTANCE_N1 2000 55#define SIGNAL_DISTANCE_N2 1500 56#define SIGNAL_DISTANCE_N3 1000 57#define SIGNAL_DISTANCE_N4 500 58#define SIGNAL_DISTANCE_DE 0 59#define SIGNAL_PASS 0 60#define HORN_OFF 0 61#define HORN_ON 1 62#define SPEED_LIMIT_MIN 0 63#define SPEED_LIMIT_DEF 30 64#define SPEED_LIMIT_MAX 400 65#define SPEED_CONST_MIN 0 66#define SPEED_CONST_DEF 30 67#define SPEED_CONST_MAX 400 68#define MASTER_KEY_OFF 0 69#define MASTER_KEY_ON 1 70#define EMERGENCY_ON 1 71#define EMERGENCY_OFF 0 72#define OVERWRITE 0 73#define NORMAL 1 74// 75#define LDOOR_OPEN_DEF 1 76#define RDDOR_OPEN_DEF 1 77#define SANDER_OFF 0 78#define PANTO_UP 1 79#define LIGHT_OFF 0 80#define CURRENT_STATION_N 0 81#define NEXT_STATION_N 0 82#define NEXT_STATION_DIS_DEF 0 83#define CURRENT_STATION_DEPART_TIME_DEF 0 84#define NEXT_STATION_ARRIVAL_TIME_DEF 0 85#define CURRENT_TIME_DEF 0 86#define LDOOR_IN_OP_DEF 0 87#define RDOOR_IN_OP_DEF 0 88//Devices 89#define DEVICE_NUMBER 17 90#define DEVICE_TYPE_NUMBER 3 91#define ACTIVE 0 92#define NO_ACTIVE 1 93#define NO_READY 0 94#define READY 1 95#define ON 1 96#define OFF 0 97#define ANALOG_OUT_MIN 0 98#define ANALOG_OUT_MAX 255 99//Train 100#define TRAIN_DATA_NUMBER 25 101#define _INT 0 102#define _BOOL 1 103#define _STRING 3 104#define SPEED 0 105#define REVERSER 1 106#define POWER 2 107#define BRAKE 3 108#define SIGNAL_INFO 4 109#define SIGNAL_DISTANCE 5 110#define SPEED_LIMIT 6 111#define HORN 7 112#define SPEED_CONST 8 113#define MASTER_KEY 9 114#define EMERGENCY 10 115#define RC_MODE 11 116#define LDOOR_OPEN 12 117#define RDOOR_OPEN 13 118#define LIGHT_OPEN 15 119#define PANTO_OPEN 16 120#define SANDER_OPEN 14 121#define CURRENT_STATION_NAME 17 122#define NEXT_STATION_NAME 18 123#define CURRENT_STATION_DEPART 20 124#define NEXT_STATION_ARRIVAL 21 125#define NEXT_STATION_DIS 19 126#define CURRENT_TIME 22 127#define LDDOR_IN_OP 23 128#define RDOOR_IN_OP 24 129#define UPDATE_LAST_NUM 14 130#define UPDATE_OW 8 131#define NO_BINDING -1 132//HMI 133#define HMI_SCRIPT_NUM 22 134#define HMI_END_SYM 0xFF 135#define MAX_SERIAL_STEP 5 136//PC 137#define FILTER '|' 138#define START_SYM '#' 139#define END_SYM '!' 140#define NO_DATA "" 141#define RECIEVE_DELAY 2 142#define SEND_DELAY 25 143#define TIMER_TICK 500000 144// 145 146#define NOP do { __asm__ __volatile__ ("nop"); } while (0) 147 148#include "DueTimer.h" 149 150typedef void (*funcPoint)(); 151// 152/* 153=========================================== 154--Device Maps 155default: 156PowerUp:process0 157PowerDown:process1 158ReserverForward:process2 159ReserverBackward:process3 160Horn:process4 161SpeedConst:process5 162Emergency:process6 163MasterKey:process7 164=========================================== 165*/ 166 167void process0(); 168void process1(); 169void process2(); 170void process3(); 171void process4(); 172void process5(); 173void process6(); 174void process7(); 175void process8(); 176void process9(); 177void process10(); 178void process11(); 179void process12(); 180void process13(); 181void process14(); 182void process15(); 183void process16(); 184 185//change device type here 186const int deviceType[DEVICE_NUMBER] = {SWITCH_C, SWITCH_C, SWITCH_C, SWITCH_C, SWITCH_C, SWITCH_C, SWITCH_C, SWITCH_C, SWITCH_C, SWITCH_C, 187 SWITCH_C, DIG_OUT, SWITCH_C, DIG_OUT, SWITCH_C, SWITCH_C, SWITCH_C 188 }; 189//change functions here 190const int devicePinsType[] = {INPUT_PULLUP, INPUT_PULLUP, INPUT_PULLUP, OUTPUT}; 191const funcPoint Process[DEVICE_NUMBER] = {process0, process1, process2, process3, process4, process5, process6, process7, process8, process9, 192 process10, process11, process12, process13, process14, process15, process16 193 }; 194//all use PULL_UP gpio mode 195//key for bac horn -3 -2 -1 1 2 3 ld ldled rd rdled light pat sand 196const int devicePins[DEVICE_NUMBER] = {31, 32, 33, 37, 25, 26, 27, 28, 29, 30, 39, 41, 22, 24, 35, 34, 38}; 197int deviceLastState[DEVICE_NUMBER] = {KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, 198 KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP 199 }; 200int deviceSADur[DEVICE_NUMBER] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201 0, 0, 0, 0, 0, 0, 0 202 }; 203//train data id 204const int dataDefault[TRAIN_DATA_NUMBER] = {SPEED_MIN, REVERSER_NEUTRAL, POWER_MIN, BRAKE_MIN, SIGNAL_RED, 205 SIGNAL_DISTANCE_DE, SPEED_LIMIT_DEF, HORN_OFF, SPEED_CONST_MIN, MASTER_KEY_OFF, 206 EMERGENCY_OFF, NORMAL, LDOOR_OPEN_DEF, RDDOR_OPEN_DEF, SANDER_OFF, LIGHT_OFF, PANTO_UP, CURRENT_STATION_N, NEXT_STATION_N, 207 NEXT_STATION_DIS_DEF, CURRENT_STATION_DEPART_TIME_DEF, NEXT_STATION_ARRIVAL_TIME_DEF, CURRENT_TIME_DEF, LDOOR_IN_OP_DEF, RDOOR_IN_OP_DEF 208 }; 209const int dataType[TRAIN_DATA_NUMBER] = {_INT, _INT, _INT, _INT, _INT, _INT, _INT, _BOOL, _INT, _BOOL, _BOOL, _BOOL, _BOOL, _BOOL, 210 _BOOL, _BOOL, _INT, _STRING, _STRING, _STRING, _STRING, _STRING, _STRING, _BOOL, _BOOL 211 }; 212const int recieveToUpdate[UPDATE_LAST_NUM] = {SPEED, SIGNAL_INFO, SIGNAL_DISTANCE, SPEED_LIMIT, RC_MODE, LDDOR_IN_OP, RDOOR_IN_OP, NEXT_STATION_NAME, CURRENT_STATION_NAME, 213 NEXT_STATION_DIS, NEXT_STATION_ARRIVAL, CURRENT_STATION_DEPART, NEXT_STATION_DIS, CURRENT_TIME 214 }; 215const int overwriteToUpdate[UPDATE_OW] = {POWER, BRAKE, REVERSER, SPEED, SIGNAL_INFO, SIGNAL_DISTANCE, SPEED_LIMIT, RC_MODE}; 216const int dataBinding[TRAIN_DATA_NUMBER] = {NO_BINDING, NO_BINDING, NO_BINDING, NO_BINDING, NO_BINDING, 217 NO_BINDING, NO_BINDING, NO_BINDING, NO_BINDING, NO_BINDING, NO_BINDING, 218 NO_BINDING, NO_BINDING, NO_BINDING, NO_BINDING, NO_BINDING, NO_BINDING, NO_BINDING, 219 NO_BINDING, NO_BINDING, NO_BINDING, NO_BINDING, NO_BINDING, 11, 13 220 }; 221 222class TrainManager 223{ 224public: 225 int trainData[TRAIN_DATA_NUMBER]; 226 String trainDataStr[TRAIN_DATA_NUMBER]; 227 //did it has been sended 228 TrainManager(const int dataDefault[]) 229 { 230 //set default data to Train Manager 231 for (int i = 0; i < TRAIN_DATA_NUMBER; i++) 232 { 233 trainData[i] = dataDefault[i]; 234 trainDataStr[i] = NO_DATA; 235 } 236 } 237 // 238 void SetData(int dataID, int value) 239 { 240 trainData[dataID] = value; 241 } 242 void SetDataStr(int dataID, String value) 243 { 244 trainDataStr[dataID] = value; 245 } 246 //get train data 247 int GetData(int dataID) 248 { 249 return trainData[dataID]; 250 } 251 String GetDataStr(int dataID) 252 { 253 return trainDataStr[dataID]; 254 } 255}; 256 257class DevicesManager 258{ 259public: 260 DevicesManager(const int devicePins[], const int deviceType[], const int devicePinsType[]) 261 { 262 //define gpio mode 263 for (int i = 0; i < DEVICE_NUMBER; i++) 264 pinMode(devicePins[i], devicePinsType[deviceType[i]]); 265 } 266 // 267 int GetState(int deviceID) 268 { 269 if (deviceType[deviceID] == SWITCH_F) 270 { 271 if (digitalRead(devicePins[deviceID]) == LOW) 272 { 273 if (deviceLastState[deviceID] == KEY_UP) 274 { 275 deviceSADur[deviceID] = 0; 276 deviceLastState[deviceID] = KEY_WAITTING; 277 } 278 else if (deviceLastState[deviceID] == KEY_WAITTING) 279 { 280 deviceSADur[deviceID]++; 281 if (deviceSADur[deviceID] >= SA_COUNT_SF) 282 { 283 deviceSADur[deviceID] = 0; 284 deviceLastState[deviceID] = KEY_DOWN; 285 return ACTIVE; 286 } 287 } 288 } 289 else 290 { 291 deviceLastState[deviceID] = KEY_UP; 292 return NO_ACTIVE; 293 } 294 } 295 else if (deviceType[deviceID] == SWITCH_C) 296 { 297 if (digitalRead(devicePins[deviceID]) == LOW) 298 { 299 if (deviceLastState[deviceID] == KEY_UP) 300 { 301 deviceSADur[deviceID] = 0; 302 deviceLastState[deviceID] = KEY_WAITTING; 303 } 304 else if (deviceLastState[deviceID] == KEY_WAITTING) 305 { 306 deviceSADur[deviceID]++; 307 if (deviceSADur[deviceID] >= SA_COUNT_SC) 308 { 309 deviceSADur[deviceID] = 0; 310 deviceLastState[deviceID] = KEY_DOWN; 311 return ACTIVE; 312 } 313 } 314 else if (deviceLastState[deviceID] == KEY_DOWN)return ACTIVE; 315 } 316 else 317 { 318 deviceLastState[deviceID] = KEY_UP; 319 return NO_ACTIVE; 320 } 321 } 322 return NO_ACTIVE; 323 } 324 // 325 void delay_(int ms) 326 { 327 for (int i = 0; i < ms; i++) 328 { 329 for (int j = 0; j < 1985; j++) NOP; 330 } 331 } 332}; 333 334DevicesManager Devices(devicePins, deviceType, devicePinsType); 335TrainManager currentData(dataDefault); 336TrainManager processData(dataDefault); 337 338class CommunicationManager 339{ 340private: 341 String recieveData; 342 String sendData; 343 String sender; 344 String tmp; 345 int length, st, ed, pos, sendEd; 346public: 347 CommunicationManager() 348 { 349 Serial.begin(115200); 350 //reset the recieved data 351 sendData = NO_DATA; 352 recieveData = NO_DATA; 353 sender = NO_DATA; 354 length = st = ed = pos = 0; 355 sendEd = 0; 356 } 357 358 bool RecieveDataFromPC(TrainManager & p) 359 { 360 tmp = NO_DATA; 361 //clear last data 362 recieveData = NO_DATA; 363 //recieve from serial 364 while (Serial.available() > 0) 365 { 366 char currentRead = char(Serial.read()); 367 recieveData += currentRead; 368 Devices.delay_(RECIEVE_DELAY); 369 //if (currentRead == END_SYM)break; 370 } 371 length = recieveData.length(); 372 //no data exit 373 if (!length)return false; 374 //find start pos 375 //Serial.println(recieveData); 376 st = ed = 0; 377 for (int i = 0; i < length; i++) 378 if (recieveData.charAt(i) == START_SYM) 379 { 380 st = i; 381 break; 382 } 383 //find end pos 384 for (int i = length - 1; i >= 0; i--) 385 if (recieveData.charAt(i) == END_SYM) 386 { 387 ed = i; 388 break; 389 } 390 //cover data 391 pos = 0; 392 for (int i = st; i <= ed; i++) 393 { 394 if (recieveData.charAt(i) != START_SYM && recieveData.charAt(i) != END_SYM && recieveData.charAt(i) != FILTER)tmp += recieveData.charAt(i); 395 if (recieveData.charAt(i) == FILTER) 396 { 397 //send data to TrainManager 398 if (dataType[pos] != _STRING) 399 p.SetData(pos++, tmp.toInt()); 400 else 401 { 402 p.SetDataStr(pos++, tmp); 403 } 404 //clear tmp 405 tmp = NO_DATA; 406 } 407 } 408 return true; 409 } 410 // 411 bool SendDataToPC(TrainManager & p) 412 { 413 sendData = NO_DATA; 414 //add start symbol 415 sendData += START_SYM; 416 //add contents 417 for (int i = 0; i < TRAIN_DATA_NUMBER; i++) 418 { 419 if (dataType[i] != _STRING)sendData += p.GetData(i); 420 else sendData += " "; 421 sendData += FILTER; 422 } 423 //add end symbol 424 sendData += END_SYM; 425 if (!sendData.length())return false; 426 //send data to PC 427 Serial.print(sendData); 428 return true; 429 } 430}; 431 432class TaskManager 433{ 434public: 435 TaskManager() 436 { 437 currentData = processData; 438 } 439 // 440 void AddProc(TrainManager & p) 441 { 442 currentData = p; 443 } 444 // 445 void GetLastState(TrainManager & p) 446 { 447 p = currentData; 448 } 449 // 450 void UpdateData(TrainManager & p) 451 { 452 if (currentData.GetData(RC_MODE) == NORMAL) 453 for (int i = 0; i < UPDATE_LAST_NUM; i++) 454 { 455 if (dataType[recieveToUpdate[i]] != _STRING) 456 p.SetData(recieveToUpdate[i], currentData.GetData(recieveToUpdate[i])); 457 else 458 p.SetDataStr(recieveToUpdate[i], currentData.GetDataStr(recieveToUpdate[i])); 459 } 460 else if (currentData.GetData(RC_MODE) == OVERWRITE) 461 for (int i = 0; i < UPDATE_OW; i++) 462 { 463 if (dataType[overwriteToUpdate[i]] != _STRING) 464 p.SetData(overwriteToUpdate[i], currentData.GetData(overwriteToUpdate[i])); 465 else 466 p.SetDataStr(overwriteToUpdate[i], currentData.GetDataStr(overwriteToUpdate[i])); 467 } 468 //check AP state 469 if (p.GetData(SPEED_CONST) != SPEED_CONST_MIN && 470 currentData.GetData(SPEED_CONST) != SPEED_CONST_MIN) 471 p.SetData(SPEED_CONST, currentData.GetData(SPEED_CONST)); 472 } 473}; 474 475CommunicationManager Communication; 476TaskManager Queue; 477 478int isHandleZero = 0; 479 480 481void process0() 482{ 483 // 484 int deviceState = Devices.GetState(0); 485 isHandleZero++; 486 if (deviceState == ACTIVE) 487 { 488 processData.SetData(MASTER_KEY, MASTER_KEY_ON); 489 } 490 else 491 { 492 processData.SetData(MASTER_KEY, MASTER_KEY_OFF); 493 } 494 return; 495} 496 497void process1() 498{ 499 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF || 500 processData.GetData(EMERGENCY) == EMERGENCY_ON || 501 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 502 int deviceState = Devices.GetState(1); 503 if (deviceState == ACTIVE) 504 { 505 processData.SetData(REVERSER, REVERSER_FORWARD); 506 } 507 else 508 { 509 processData.SetData(REVERSER, REVERSER_NEUTRAL); 510 } 511 return; 512} 513 514void process2() 515{ 516 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF || 517 processData.GetData(EMERGENCY) == EMERGENCY_ON || 518 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 519 int deviceState = Devices.GetState(2); 520 if (deviceState == ACTIVE) 521 { 522 processData.SetData(REVERSER, REVERSER_BACKWARD); 523 } 524 return; 525} 526 527void process3() 528{ 529 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF)return; 530 int deviceState = Devices.GetState(3); 531 if (deviceState == ACTIVE) 532 { 533 processData.SetData(HORN, HORN_ON); 534 } 535 else 536 { 537 processData.SetData(HORN, HORN_OFF); 538 } 539 return; 540} 541 542//-3 543void process4() 544{ 545 //SWITCH_F 546 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF || 547 processData.GetData(EMERGENCY) == EMERGENCY_ON || 548 processData.GetData(REVERSER) == REVERSER_NEUTRAL || 549 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 550 int deviceState = Devices.GetState(4); 551 if (deviceState == ACTIVE) 552 { 553 isHandleZero --; 554 processData.SetData(POWER, 0); 555 processData.SetData(BRAKE, 6); 556 } 557 return; 558} 559 560//-2 561void process5() 562{ 563 //SWITCH_F 564 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF || 565 processData.GetData(EMERGENCY) == EMERGENCY_ON || 566 processData.GetData(REVERSER) == REVERSER_NEUTRAL || 567 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 568 int deviceState = Devices.GetState(5); 569 if (deviceState == ACTIVE) 570 { 571 isHandleZero --; 572 processData.SetData(POWER, 0); 573 processData.SetData(BRAKE, 4); 574 } 575 return; 576} 577 578//-1 579void process6() 580{ 581 //SWITCH_F 582 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF || 583 processData.GetData(EMERGENCY) == EMERGENCY_ON || 584 processData.GetData(REVERSER) == REVERSER_NEUTRAL || 585 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 586 int deviceState = Devices.GetState(6); 587 if (deviceState == ACTIVE) 588 { 589 isHandleZero --; 590 processData.SetData(POWER, 0); 591 processData.SetData(BRAKE, 2); 592 } 593 return; 594} 595 596//1 597void process7() 598{ 599 //SWITCH_F 600 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF || 601 processData.GetData(EMERGENCY) == EMERGENCY_ON || 602 processData.GetData(REVERSER) == REVERSER_NEUTRAL || 603 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 604 int deviceState = Devices.GetState(7); 605 if (deviceState == ACTIVE) 606 { 607 isHandleZero --; 608 processData.SetData(POWER, 1); 609 processData.SetData(BRAKE, 0); 610 } 611 return; 612} 613 614//2 615void process8() 616{ 617 //SWITCH_F 618 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF || 619 processData.GetData(EMERGENCY) == EMERGENCY_ON || 620 processData.GetData(REVERSER) == REVERSER_NEUTRAL || 621 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 622 int deviceState = Devices.GetState(8); 623 if (deviceState == ACTIVE) 624 { 625 isHandleZero --; 626 processData.SetData(POWER, 2); 627 processData.SetData(BRAKE, 0); 628 } 629 return; 630} 631 632//3 633void process9() 634{ 635 //SWITCH_F 636 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF || 637 processData.GetData(EMERGENCY) == EMERGENCY_ON || 638 processData.GetData(REVERSER) == REVERSER_NEUTRAL || 639 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 640 int deviceState = Devices.GetState(9); 641 if (deviceState == ACTIVE) 642 { 643 isHandleZero --; 644 processData.SetData(POWER, 3); 645 processData.SetData(BRAKE, 0); 646 } 647 // 648 if (isHandleZero > 600) 649 { 650 processData.SetData(POWER, 0); 651 processData.SetData(BRAKE, 0); 652 isHandleZero = 0; 653 } 654 return; 655} 656 657//key for bac horn -3 -2 -1 1 2 3 ld ldled rd rdled light pat sand 658 659void process10() 660{ 661 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF)return; 662 int deviceState = Devices.GetState(10); 663 if (deviceState == ACTIVE) 664 { 665 if (processData.GetData(LDOOR_OPEN))return; 666 processData.SetData(LDOOR_OPEN, 1); 667 } 668 else 669 { 670 if (!processData.GetData(LDOOR_OPEN))return; 671 processData.SetData(LDOOR_OPEN, 0); 672 } 673} 674 675void process11() 676{ 677 pinMode(devicePins[11], OUTPUT); 678 digitalWrite(devicePins[11], processData.GetData(LDDOR_IN_OP)); 679} 680 681void process12() 682{ 683 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF)return; 684 int deviceState = Devices.GetState(12); 685 if (deviceState == ACTIVE) 686 { 687 if (processData.GetData(RDOOR_OPEN))return; 688 processData.SetData(RDOOR_OPEN, 1); 689 } 690 else 691 { 692 if (!processData.GetData(RDOOR_OPEN))return; 693 processData.SetData(RDOOR_OPEN, 0); 694 } 695} 696 697void process13() 698{ 699 pinMode(devicePins[13], OUTPUT); 700 digitalWrite(devicePins[13], processData.GetData(RDOOR_IN_OP)); 701} 702 703void process14() 704{ 705 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF)return; 706 int deviceState = Devices.GetState(14); 707 if (deviceState == ACTIVE) 708 { 709 if (processData.GetData(LIGHT_OPEN))return; 710 processData.SetData(LIGHT_OPEN, 1); 711 } 712 else 713 { 714 if (!processData.GetData(LIGHT_OPEN))return; 715 processData.SetData(LIGHT_OPEN, 0); 716 } 717} 718 719void process15() 720{ 721 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF)return; 722 int deviceState = Devices.GetState(15); 723 if (deviceState == ACTIVE) 724 { 725 processData.SetData(PANTO_OPEN, !processData.GetData(PANTO_OPEN)); 726 delay(1000); 727 //while (Devices.GetState(14) == ACTIVE); 728 } 729} 730 731void process16() 732{ 733 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF)return; 734 int deviceState = Devices.GetState(16); 735 if (deviceState == ACTIVE) 736 { 737 processData.SetData(SANDER_OPEN, 1); 738 } 739 else 740 { 741 processData.SetData(SANDER_OPEN, 0); 742 } 743} 744 745void TimerInterrupt() 746{ 747 Timer1.stop(); 748 Communication.SendDataToPC(currentData); 749 Communication.RecieveDataFromPC(currentData); 750 Timer1.start(); 751} 752 753void setup() 754{ 755 Serial.begin(115200); 756 Timer1.attachInterrupt(TimerInterrupt); 757 Timer1.setPeriod(TIMER_TICK); 758 Timer1.start(); 759} 760 761void loop() 762{ 763 //state automatic 764 Queue.GetLastState(processData); 765 for (int i = 0; i < DEVICE_NUMBER; i++)Process[i](); 766 Queue.UpdateData(processData); 767 Queue.AddProc(processData); 768}
Source Code for Arduino MEGA2560
c_cpp
1/*Desktop Train Controller 2=========================================== 3--Board: 4 Arduino MEGA 2560 5--Version: 1.0 6--Simulator: OpenBVE 7=========================================== 8--Note: 9State 10 Automatic Ready 11=========================================== 12--Devices: 13Type:0.SWITCH_C 14 -> CHANGE 15Type:1.SWITCH_F -> FALLING 16Type:3.ENCODER -> CHANGE (in developing) 17=========================================== 18--Train: 190.SPEED 20 -> INT 211.REVERSER -> INT 222.POWER -> U8 233.BRAKE -> U8 244.SIGNAL -> INT 255.SIGNAL_DISTANCE 26 -> INT 276.SPEED_LIMIT -> INT 287.HORN -> BOOL 298.SPEED_CONST -> INT 309.MASTER_KEY 31 -> BOOL 32=========================================== 33*/ 34#define SWITCH_C 35 0 36#define SWITCH_F 1 37#define ENCODER 2 38#define DIG_OUT 3 39#define ANALOG_OUT 40 4 41#define DELAY_TIME 10 42#define IGNORE -1 43#define COUNT 2 44#define KEY_UP 45 0 46#define KEY_WAITTING 1 47#define KEY_DOWN 2 48#define SA_COUNT_SF 500 49#define 50 SA_COUNT_SC 300 51// 52#define SPEED_MIN 0 53#define SPEED_MAX 400 54#define 55 REVERSER_FORWARD 1 56#define REVERSER_NEUTRAL 0 57#define REVERSER_BACKWARD -1 58#define 59 POWER_MIN 0 60#define POWER_MAX 4 61#define BRAKE_MIN 0 62#define BRAKE_MAX 8 63#define 64 SIGNAL_RED 0 65#define SIGNAL_YELLOW 1 66#define SIGNAM_GREEN 2 67#define SIGNAL_DISTANCE_N1 68 2000 69#define SIGNAL_DISTANCE_N2 1500 70#define SIGNAL_DISTANCE_N3 1000 71#define 72 SIGNAL_DISTANCE_N4 500 73#define SIGNAL_DISTANCE_DE 0 74#define SIGNAL_PASS 0 75#define 76 HORN_OFF 0 77#define HORN_ON 1 78#define SPEED_LIMIT_MIN 0 79#define SPEED_LIMIT_DEF 80 30 81#define SPEED_LIMIT_MAX 400 82#define SPEED_CONST_MIN 0 83#define SPEED_CONST_DEF 84 30 85#define SPEED_CONST_MAX 400 86#define MASTER_KEY_OFF 0 87#define MASTER_KEY_ON 88 1 89#define EMERGENCY_ON 1 90#define EMERGENCY_OFF 0 91#define OVERWRITE 0 92#define 93 NORMAL 1 94// 95#define LDOOR_OPEN_DEF 0 96#define RDDOR_OPEN_DEF 0 97#define 98 SANDER_OFF 0 99#define PANTO_UP 1 100#define LIGHT_OFF 0 101#define CURRENT_STATION_N 102 0 103#define NEXT_STATION_N 0 104#define NEXT_STATION_DIS_DEF 0 105#define CURRENT_STATION_DEPART_TIME_DEF 106 0 107#define NEXT_STATION_ARRIVAL_TIME_DEF 0 108#define CURRENT_TIME_DEF 0 109#define 110 LDOOR_IN_OP_DEF 0 111#define RDOOR_IN_OP_DEF 0 112//Devices 113#define DEVICE_NUMBER 114 17 115#define DEVICE_TYPE_NUMBER 3 116#define ACTIVE 0 117#define NO_ACTIVE 1 118#define 119 NO_READY 0 120#define READY 1 121#define ON 1 122#define OFF 0 123#define ANALOG_OUT_MIN 124 0 125#define ANALOG_OUT_MAX 255 126//Train 127#define TRAIN_DATA_NUMBER 25 128#define 129 _INT 0 130#define _BOOL 1 131#define _STRING 3 132#define SPEED 0 133#define REVERSER 134 1 135#define POWER 2 136#define BRAKE 3 137#define SIGNAL_INFO 4 138#define SIGNAL_DISTANCE 139 5 140#define SPEED_LIMIT 6 141#define HORN 7 142#define SPEED_CONST 8 143#define 144 MASTER_KEY 9 145#define EMERGENCY 10 146#define RC_MODE 11 147#define LDOOR_OPEN 148 12 149#define RDOOR_OPEN 13 150#define LIGHT_OPEN 15 151#define PANTO_OPEN 16 152#define 153 SANDER_OPEN 14 154#define CURRENT_STATION_NAME 17 155#define NEXT_STATION_NAME 18 156#define 157 CURRENT_STATION_DEPART 20 158#define NEXT_STATION_ARRIVAL 21 159#define NEXT_STATION_DIS 160 19 161#define CURRENT_TIME 22 162#define LDDOR_IN_OP 23 163#define RDOOR_IN_OP 24 164#define 165 UPDATE_LAST_NUM 14 166#define UPDATE_OW 8 167//PC 168#define FILTER '|' 169#define 170 START_SYM '#' 171#define END_SYM '!' 172#define NO_DATA "" 173#define RECIEVE_DELAY 174 2 175#define SEND_DELAY 25 176#define TIMER_TICK 200 177//Special Args 178#define 179 CONTROLLER_INFO "#ver|" 180 181#define NOP do { __asm__ __volatile__ ("nop"); 182 } while (0) 183 184#include "FlexiTimer2.h" 185#include "avr/wdt.h" 186#include 187 "HardwareSerial.h" 188 189typedef void (*funcPoint)(); 190// 191/* 192 =========================================== 193 --Device 194 Maps 195 default: 196 PowerUp:process0 197 PowerDown:process1 198 ReserverForward:process2 199 ReserverBackward:process3 200 Horn:process4 201 SpeedConst:process5 202 Emergency:process6 203 MasterKey:process7 204 =========================================== 205*/ 206 207void 208 process0(); 209void process1(); 210void process2(); 211void process3(); 212void 213 process4(); 214void process5(); 215void process6(); 216void process7(); 217void 218 process8(); 219void process9(); 220void process10(); 221void process11(); 222void 223 process12(); 224void process13(); 225void process14(); 226void process15(); 227void 228 process16(); 229 230//change device type here 231const int deviceType[DEVICE_NUMBER] 232 = {SWITCH_C, SWITCH_C, SWITCH_C, SWITCH_C, SWITCH_C, SWITCH_C, SWITCH_C, SWITCH_C, 233 SWITCH_C, SWITCH_C, 234 SWITCH_C, DIG_OUT, 235 SWITCH_C, DIG_OUT, SWITCH_C, SWITCH_C, SWITCH_C 236 }; 237//change 238 functions here 239const int devicePinsType[] = {INPUT_PULLUP, INPUT_PULLUP, INPUT_PULLUP, 240 OUTPUT}; 241const funcPoint Process[DEVICE_NUMBER] = {process0, process1, process2, 242 process3, process4, process5, process6, process7, process8, process9, 243 process10, 244 process11, process12, process13, process14, process15, process16 245 }; 246//all 247 use PULL_UP gpio mode 248//key for bac horn -3 -2 -1 1 2 3 ld ldled rd rdled light 249 pat sand 250const int devicePins[DEVICE_NUMBER] = {31, 32, 33, 37, 25, 26, 27, 28, 251 29, 30, 39, 41, 22, 24, 35, 34, 38}; 252int deviceLastState[DEVICE_NUMBER] = {KEY_UP, 253 KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, 254 KEY_UP, 255 KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP 256 }; 257int 258 deviceSADur[DEVICE_NUMBER] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 259 0, 260 0, 0, 0, 0, 0, 0 261 }; 262//train data id 263const 264 int dataDefault[TRAIN_DATA_NUMBER] = {SPEED_MIN, REVERSER_NEUTRAL, POWER_MIN, BRAKE_MIN, 265 SIGNAL_RED, 266 SIGNAL_DISTANCE_DE, SPEED_LIMIT_DEF, 267 HORN_OFF, SPEED_CONST_MIN, MASTER_KEY_OFF, 268 EMERGENCY_OFF, 269 NORMAL, LDOOR_OPEN_DEF, RDDOR_OPEN_DEF, SANDER_OFF, LIGHT_OFF, PANTO_UP, CURRENT_STATION_N, 270 NEXT_STATION_N, 271 NEXT_STATION_DIS_DEF, 272 CURRENT_STATION_DEPART_TIME_DEF, NEXT_STATION_ARRIVAL_TIME_DEF, CURRENT_TIME_DEF, 273 LDOOR_IN_OP_DEF, RDOOR_IN_OP_DEF 274 }; 275const 276 int dataType[TRAIN_DATA_NUMBER] = {_INT, _INT, _INT, _INT, _INT, _INT, _INT, _BOOL, 277 _INT, _BOOL, _BOOL, _BOOL, _BOOL, _BOOL, 278 _BOOL, 279 _BOOL, _INT, _STRING, _STRING, _STRING, _STRING, _STRING, _STRING, _BOOL, _BOOL 280 281 }; 282const int recieveToUpdate[UPDATE_LAST_NUM] 283 = {SPEED, SIGNAL_INFO, SIGNAL_DISTANCE, SPEED_LIMIT, RC_MODE, LDDOR_IN_OP, RDOOR_IN_OP, 284 NEXT_STATION_NAME, CURRENT_STATION_NAME, 285 NEXT_STATION_DIS, 286 NEXT_STATION_ARRIVAL, CURRENT_STATION_DEPART, NEXT_STATION_DIS, CURRENT_TIME 287 288 }; 289const int overwriteToUpdate[UPDATE_OW] 290 = {POWER, BRAKE, REVERSER, SPEED, SIGNAL_INFO, SIGNAL_DISTANCE, SPEED_LIMIT, RC_MODE}; 291 292class 293 TrainManager 294{ 295public: 296 int trainData[TRAIN_DATA_NUMBER]; 297 String 298 trainDataStr[TRAIN_DATA_NUMBER]; 299 //did it has been sended 300 TrainManager(const 301 int dataDefault[]) 302 { 303 //set default data to Train Manager 304 for 305 (int i = 0; i < TRAIN_DATA_NUMBER; i++) 306 { 307 trainData[i] = dataDefault[i]; 308 trainDataStr[i] 309 = NO_DATA; 310 } 311 } 312 // 313 void SetData(int dataID, int value) 314 { 315 trainData[dataID] 316 = value; 317 } 318 void SetDataStr(int dataID, String value) 319 { 320 trainDataStr[dataID] 321 = value; 322 } 323 //get train data 324 int GetData(int dataID) 325 { 326 return 327 trainData[dataID]; 328 } 329 String GetDataStr(int dataID) 330 { 331 return 332 trainDataStr[dataID]; 333 } 334}; 335 336class DevicesManager 337{ 338public: 339 DevicesManager(const 340 int devicePins[], const int deviceType[], const int devicePinsType[]) 341 { 342 //define 343 gpio mode 344 for (int i = 0; i < DEVICE_NUMBER; i++) 345 pinMode(devicePins[i], 346 devicePinsType[deviceType[i]]); 347 } 348 // 349 int GetState(int deviceID) 350 { 351 if 352 (deviceType[deviceID] == SWITCH_F) 353 { 354 if (digitalRead(devicePins[deviceID]) 355 == LOW) 356 { 357 if (deviceLastState[deviceID] == KEY_UP) 358 { 359 deviceSADur[deviceID] 360 = 0; 361 deviceLastState[deviceID] = KEY_WAITTING; 362 } 363 else 364 if (deviceLastState[deviceID] == KEY_WAITTING) 365 { 366 deviceSADur[deviceID]++; 367 if 368 (deviceSADur[deviceID] >= SA_COUNT_SF) 369 { 370 deviceSADur[deviceID] 371 = 0; 372 deviceLastState[deviceID] = KEY_DOWN; 373 return 374 ACTIVE; 375 } 376 } 377 } 378 else 379 { 380 deviceLastState[deviceID] 381 = KEY_UP; 382 return NO_ACTIVE; 383 } 384 } 385 else if (deviceType[deviceID] 386 == SWITCH_C) 387 { 388 if (digitalRead(devicePins[deviceID]) == LOW) 389 { 390 if 391 (deviceLastState[deviceID] == KEY_UP) 392 { 393 deviceSADur[deviceID] 394 = 0; 395 deviceLastState[deviceID] = KEY_WAITTING; 396 } 397 else 398 if (deviceLastState[deviceID] == KEY_WAITTING) 399 { 400 deviceSADur[deviceID]++; 401 if 402 (deviceSADur[deviceID] >= SA_COUNT_SC) 403 { 404 deviceSADur[deviceID] 405 = 0; 406 deviceLastState[deviceID] = KEY_DOWN; 407 return 408 ACTIVE; 409 } 410 } 411 else if (deviceLastState[deviceID] 412 == KEY_DOWN)return ACTIVE; 413 } 414 else 415 { 416 deviceLastState[deviceID] 417 = KEY_UP; 418 return NO_ACTIVE; 419 } 420 } 421 return NO_ACTIVE; 422 } 423 // 424 void 425 delay_(int ms) 426 { 427 for (int i = 0; i < ms; i++) 428 { 429 for 430 (int j = 0; j < 1985; j++) NOP; 431 } 432 } 433}; 434 435DevicesManager Devices(devicePins, 436 deviceType, devicePinsType); 437TrainManager currentData(dataDefault); 438TrainManager 439 processData(dataDefault); 440 441class CommunicationManager 442{ 443private: 444 String 445 recieveData; 446 String sendData; 447 String sender; 448 String tmp; 449 int 450 length, st, ed, pos, sendEd; 451public: 452 CommunicationManager() 453 { 454 Serial.begin(115200); 455 //reset 456 the recieved data 457 sendData = NO_DATA; 458 recieveData = NO_DATA; 459 sender 460 = NO_DATA; 461 length = st = ed = pos = 0; 462 sendEd = 0; 463 } 464 465 bool 466 IsSpecialArgs(String recieveData) 467 { 468 if (recieveData == CONTROLLER_INFO)return 469 true; 470 return false; 471 } 472 473 bool SendControllerInfo() 474 { 475 String 476 sendData = NO_DATA; 477 sendData += START_SYM; 478 sendData += "ver|3.1"; 479 sendData 480 += END_SYM; 481 Serial.print(sendData); 482 } 483 484 bool RecieveDataFromPC(TrainManager 485 & p) 486 { 487 tmp = NO_DATA; 488 //clear last data 489 recieveData = 490 NO_DATA; 491 //recieve from serial 492 while (Serial.available() > 0) 493 { 494 char 495 currentRead = char(Serial.read()); 496 recieveData += currentRead; 497 Devices.delay_(RECIEVE_DELAY); 498 //if 499 (currentRead == END_SYM)break; 500 } 501 length = recieveData.length(); 502 //no 503 data exit 504 if (!length)return false; 505 //find start pos 506 //Serial.println(recieveData); 507 508 //Special 509 Args 510 if (IsSpecialArgs(recieveData)) 511 { 512 SendControllerInfo(); 513 return 514 true; 515 } 516 517 st = ed = 0; 518 for (int i = 0; i < length; i++) 519 if 520 (recieveData.charAt(i) == START_SYM) 521 { 522 st = i; 523 break; 524 } 525 //find 526 end pos 527 for (int i = length - 1; i >= 0; i--) 528 if (recieveData.charAt(i) 529 == END_SYM) 530 { 531 ed = i; 532 break; 533 } 534 //cover 535 data 536 pos = 0; 537 for (int i = st; i <= ed; i++) 538 { 539 if 540 (recieveData.charAt(i) != START_SYM && recieveData.charAt(i) != END_SYM && recieveData.charAt(i) 541 != FILTER)tmp += recieveData.charAt(i); 542 if (recieveData.charAt(i) == FILTER) 543 { 544 //send 545 data to TrainManager 546 if (dataType[pos] != _STRING) 547 p.SetData(pos++, 548 tmp.toInt()); 549 else 550 { 551 p.SetDataStr(pos++, tmp); 552 } 553 //clear 554 tmp 555 tmp = NO_DATA; 556 } 557 } 558 return true; 559 } 560 // 561 bool 562 SendDataToPC(TrainManager & p) 563 { 564 sendData = NO_DATA; 565 //add start 566 symbol 567 sendData += START_SYM; 568 //add contents 569 for (int i = 0; 570 i < TRAIN_DATA_NUMBER; i++) 571 { 572 if (dataType[i] != _STRING)sendData 573 += p.GetData(i); 574 else sendData += " "; 575 sendData += FILTER; 576 } 577 //add 578 end symbol 579 sendData += END_SYM; 580 if (!sendData.length())return false; 581 //send 582 data to PC 583 Serial.print(sendData); 584 return true; 585 } 586}; 587 588class 589 TaskManager 590{ 591public: 592 TaskManager() 593 { 594 currentData = processData; 595 } 596 // 597 void 598 AddProc(TrainManager & p) 599 { 600 currentData = p; 601 } 602 // 603 void 604 GetLastState(TrainManager & p) 605 { 606 p = currentData; 607 } 608 // 609 void 610 UpdateData(TrainManager & p) 611 { 612 if (currentData.GetData(RC_MODE) == NORMAL) 613 for 614 (int i = 0; i < UPDATE_LAST_NUM; i++) 615 { 616 if (dataType[recieveToUpdate[i]] 617 != _STRING) 618 p.SetData(recieveToUpdate[i], currentData.GetData(recieveToUpdate[i])); 619 else 620 p.SetDataStr(recieveToUpdate[i], 621 currentData.GetDataStr(recieveToUpdate[i])); 622 } 623 else if (currentData.GetData(RC_MODE) 624 == OVERWRITE) 625 for (int i = 0; i < UPDATE_OW; i++) 626 { 627 if 628 (dataType[overwriteToUpdate[i]] != _STRING) 629 p.SetData(overwriteToUpdate[i], 630 currentData.GetData(overwriteToUpdate[i])); 631 else 632 p.SetDataStr(overwriteToUpdate[i], 633 currentData.GetDataStr(overwriteToUpdate[i])); 634 } 635 //check AP state 636 if 637 (p.GetData(SPEED_CONST) != SPEED_CONST_MIN && 638 currentData.GetData(SPEED_CONST) 639 != SPEED_CONST_MIN) 640 p.SetData(SPEED_CONST, currentData.GetData(SPEED_CONST)); 641 } 642}; 643 644CommunicationManager 645 Communication; 646TaskManager Queue; 647 648int isHandleZero = 0; 649 650 651void 652 process0() 653{ 654 // 655 int deviceState = Devices.GetState(0); 656 isHandleZero++; 657 if 658 (deviceState == ACTIVE) 659 { 660 processData.SetData(MASTER_KEY, MASTER_KEY_ON); 661 } 662 else 663 { 664 processData.SetData(MASTER_KEY, 665 MASTER_KEY_OFF); 666 } 667 return; 668} 669 670void process1() 671{ 672 if (processData.GetData(MASTER_KEY) 673 == MASTER_KEY_OFF || 674 processData.GetData(EMERGENCY) == EMERGENCY_ON 675 || 676 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 677 int 678 deviceState = Devices.GetState(1); 679 if (deviceState == ACTIVE) 680 { 681 processData.SetData(REVERSER, 682 REVERSER_FORWARD); 683 } 684 else 685 { 686 processData.SetData(REVERSER, 687 REVERSER_NEUTRAL); 688 } 689 return; 690} 691 692void process2() 693{ 694 if 695 (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF || 696 processData.GetData(EMERGENCY) 697 == EMERGENCY_ON || 698 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 699 int 700 deviceState = Devices.GetState(2); 701 if (deviceState == ACTIVE) 702 { 703 processData.SetData(REVERSER, 704 REVERSER_BACKWARD); 705 } 706 return; 707} 708 709void process3() 710{ 711 if 712 (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF)return; 713 int deviceState 714 = Devices.GetState(3); 715 if (deviceState == ACTIVE) 716 { 717 processData.SetData(HORN, 718 HORN_ON); 719 } 720 else 721 { 722 processData.SetData(HORN, HORN_OFF); 723 } 724 return; 725} 726 727//-3 728void 729 process4() 730{ 731 //SWITCH_F 732 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF 733 || 734 processData.GetData(EMERGENCY) == EMERGENCY_ON || 735 processData.GetData(REVERSER) 736 == REVERSER_NEUTRAL || 737 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 738 int 739 deviceState = Devices.GetState(4); 740 if (deviceState == ACTIVE) 741 { 742 isHandleZero 743 --; 744 processData.SetData(POWER, 0); 745 processData.SetData(BRAKE, 6); 746 } 747 return; 748} 749 750//-2 751void 752 process5() 753{ 754 //SWITCH_F 755 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF 756 || 757 processData.GetData(EMERGENCY) == EMERGENCY_ON || 758 processData.GetData(REVERSER) 759 == REVERSER_NEUTRAL || 760 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 761 int 762 deviceState = Devices.GetState(5); 763 if (deviceState == ACTIVE) 764 { 765 isHandleZero 766 --; 767 processData.SetData(POWER, 0); 768 processData.SetData(BRAKE, 4); 769 } 770 return; 771} 772 773//-1 774void 775 process6() 776{ 777 //SWITCH_F 778 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF 779 || 780 processData.GetData(EMERGENCY) == EMERGENCY_ON || 781 processData.GetData(REVERSER) 782 == REVERSER_NEUTRAL || 783 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 784 int 785 deviceState = Devices.GetState(6); 786 if (deviceState == ACTIVE) 787 { 788 isHandleZero 789 --; 790 processData.SetData(POWER, 0); 791 processData.SetData(BRAKE, 2); 792 } 793 return; 794} 795 796//1 797void 798 process7() 799{ 800 //SWITCH_F 801 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF 802 || 803 processData.GetData(EMERGENCY) == EMERGENCY_ON || 804 processData.GetData(REVERSER) 805 == REVERSER_NEUTRAL || 806 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 807 int 808 deviceState = Devices.GetState(7); 809 if (deviceState == ACTIVE) 810 { 811 isHandleZero 812 --; 813 processData.SetData(POWER, 1); 814 processData.SetData(BRAKE, 0); 815 } 816 return; 817} 818 819//2 820void 821 process8() 822{ 823 //SWITCH_F 824 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF 825 || 826 processData.GetData(EMERGENCY) == EMERGENCY_ON || 827 processData.GetData(REVERSER) 828 == REVERSER_NEUTRAL || 829 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 830 int 831 deviceState = Devices.GetState(8); 832 if (deviceState == ACTIVE) 833 { 834 isHandleZero 835 --; 836 processData.SetData(POWER, 2); 837 processData.SetData(BRAKE, 0); 838 } 839 return; 840} 841 842//3 843void 844 process9() 845{ 846 //SWITCH_F 847 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF 848 || 849 processData.GetData(EMERGENCY) == EMERGENCY_ON || 850 processData.GetData(REVERSER) 851 == REVERSER_NEUTRAL || 852 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 853 int 854 deviceState = Devices.GetState(9); 855 if (deviceState == ACTIVE) 856 { 857 isHandleZero 858 --; 859 processData.SetData(POWER, 3); 860 processData.SetData(BRAKE, 0); 861 } 862 // 863 if 864 (isHandleZero > 600) 865 { 866 processData.SetData(POWER, 0); 867 processData.SetData(BRAKE, 868 0); 869 isHandleZero = 0; 870 } 871 return; 872} 873 874//key for bac horn 875 -3 -2 -1 1 2 3 ld ldled rd rdled light pat sand 876 877void process10() 878{ 879 if 880 (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF)return; 881 int deviceState 882 = Devices.GetState(10); 883 if (deviceState == ACTIVE) 884 { 885 if (processData.GetData(LDOOR_OPEN))return; 886 processData.SetData(LDOOR_OPEN, 887 1); 888 } 889 else 890 { 891 if (!processData.GetData(LDOOR_OPEN))return; 892 processData.SetData(LDOOR_OPEN, 893 0); 894 } 895} 896 897void process11() 898{ 899 //pinMode(devicePins[11], OUTPUT); 900 digitalWrite(devicePins[11], 901 processData.GetData(LDDOR_IN_OP)); 902} 903 904void process12() 905{ 906 if (processData.GetData(MASTER_KEY) 907 == MASTER_KEY_OFF)return; 908 int deviceState = Devices.GetState(12); 909 if (deviceState 910 == ACTIVE) 911 { 912 if (processData.GetData(RDOOR_OPEN))return; 913 processData.SetData(RDOOR_OPEN, 914 1); 915 } 916 else 917 { 918 if (!processData.GetData(RDOOR_OPEN))return; 919 processData.SetData(RDOOR_OPEN, 920 0); 921 } 922} 923 924void process13() 925{ 926 //pinMode(devicePins[13], OUTPUT); 927 digitalWrite(devicePins[13], 928 processData.GetData(RDOOR_IN_OP)); 929} 930 931void process14() 932{ 933 if (processData.GetData(MASTER_KEY) 934 == MASTER_KEY_OFF)return; 935 int deviceState = Devices.GetState(14); 936 if (deviceState 937 == ACTIVE) 938 { 939 if (processData.GetData(LIGHT_OPEN))return; 940 processData.SetData(LIGHT_OPEN, 941 1); 942 } 943 else 944 { 945 if (!processData.GetData(LIGHT_OPEN))return; 946 processData.SetData(LIGHT_OPEN, 947 0); 948 } 949} 950 951void process15() 952{ 953 if (processData.GetData(MASTER_KEY) 954 == MASTER_KEY_OFF)return; 955 int deviceState = Devices.GetState(15); 956 if (deviceState 957 == ACTIVE) 958 { 959 processData.SetData(PANTO_OPEN, !processData.GetData(PANTO_OPEN)); 960 while 961 (Devices.GetState(15) == ACTIVE) 962 { 963 wdt_reset(); 964 } 965 //while 966 (Devices.GetState(14) == ACTIVE); 967 } 968} 969 970void process16() 971{ 972 if 973 (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF)return; 974 int deviceState 975 = Devices.GetState(16); 976 if (deviceState == ACTIVE) 977 { 978 processData.SetData(SANDER_OPEN, 979 1); 980 } 981 else 982 { 983 processData.SetData(SANDER_OPEN, 0); 984 } 985} 986 987void 988 TimerInterrupt() 989{ 990 FlexiTimer2::stop(); 991 Communication.SendDataToPC(currentData); 992 Communication.RecieveDataFromPC(currentData); 993 FlexiTimer2::start(); 994} 995 996void 997 setup() 998{ 999 Serial.begin(115200); 1000 wdt_enable(WDTO_1S); 1001 FlexiTimer2::set(TIMER_TICK, 1002 TimerInterrupt); 1003 FlexiTimer2::start(); 1004} 1005 1006void loop() 1007{ 1008 //state 1009 automatic 1010 Queue.GetLastState(processData); 1011 for (int i = 0; i < DEVICE_NUMBER; 1012 i++) 1013 { 1014 Process[i](); 1015 wdt_reset(); 1016 } 1017 Queue.UpdateData(processData); 1018 Queue.AddProc(processData); 1019}
Source Code for Arduino DUE
c_cpp
1/*Desktop Train Controller 2=========================================== 3--Board: 4 Arduino MEGA 2560 5--Version: 1.0 6--Simulator: OpenBVE 7=========================================== 8--Note: 9State 10 Automatic Ready 11=========================================== 12--Devices: 13Type:0.SWITCH_C 14 -> CHANGE 15Type:1.SWITCH_F -> FALLING 16Type:3.ENCODER -> CHANGE (in developing) 17=========================================== 18--Train: 190.SPEED 20 -> INT 211.REVERSER -> INT 222.POWER -> U8 233.BRAKE -> U8 244.SIGNAL -> INT 255.SIGNAL_DISTANCE 26 -> INT 276.SPEED_LIMIT -> INT 287.HORN -> BOOL 298.SPEED_CONST -> INT 309.MASTER_KEY 31 -> BOOL 32=========================================== 33*/ 34#define SWITCH_C 35 0 36#define SWITCH_F 1 37#define ENCODER 2 38#define DIG_OUT 3 39#define ANALOG_OUT 40 4 41#define DELAY_TIME 10 42#define IGNORE -1 43#define COUNT 2 44#define KEY_UP 45 0 46#define KEY_WAITTING 1 47#define KEY_DOWN 2 48#define SA_COUNT_SF 500 49#define 50 SA_COUNT_SC 300 51// 52#define SPEED_MIN 0 53#define SPEED_MAX 400 54#define 55 REVERSER_FORWARD 1 56#define REVERSER_NEUTRAL 0 57#define REVERSER_BACKWARD -1 58#define 59 POWER_MIN 0 60#define POWER_MAX 4 61#define BRAKE_MIN 0 62#define BRAKE_MAX 8 63#define 64 SIGNAL_RED 0 65#define SIGNAL_YELLOW 1 66#define SIGNAM_GREEN 2 67#define SIGNAL_DISTANCE_N1 68 2000 69#define SIGNAL_DISTANCE_N2 1500 70#define SIGNAL_DISTANCE_N3 1000 71#define 72 SIGNAL_DISTANCE_N4 500 73#define SIGNAL_DISTANCE_DE 0 74#define SIGNAL_PASS 0 75#define 76 HORN_OFF 0 77#define HORN_ON 1 78#define SPEED_LIMIT_MIN 0 79#define SPEED_LIMIT_DEF 80 30 81#define SPEED_LIMIT_MAX 400 82#define SPEED_CONST_MIN 0 83#define SPEED_CONST_DEF 84 30 85#define SPEED_CONST_MAX 400 86#define MASTER_KEY_OFF 0 87#define MASTER_KEY_ON 88 1 89#define EMERGENCY_ON 1 90#define EMERGENCY_OFF 0 91#define OVERWRITE 0 92#define 93 NORMAL 1 94// 95#define LDOOR_OPEN_DEF 1 96#define RDDOR_OPEN_DEF 1 97#define 98 SANDER_OFF 0 99#define PANTO_UP 1 100#define LIGHT_OFF 0 101#define CURRENT_STATION_N 102 0 103#define NEXT_STATION_N 0 104#define NEXT_STATION_DIS_DEF 0 105#define CURRENT_STATION_DEPART_TIME_DEF 106 0 107#define NEXT_STATION_ARRIVAL_TIME_DEF 0 108#define CURRENT_TIME_DEF 0 109#define 110 LDOOR_IN_OP_DEF 0 111#define RDOOR_IN_OP_DEF 0 112//Devices 113#define DEVICE_NUMBER 114 17 115#define DEVICE_TYPE_NUMBER 3 116#define ACTIVE 0 117#define NO_ACTIVE 1 118#define 119 NO_READY 0 120#define READY 1 121#define ON 1 122#define OFF 0 123#define ANALOG_OUT_MIN 124 0 125#define ANALOG_OUT_MAX 255 126//Train 127#define TRAIN_DATA_NUMBER 25 128#define 129 _INT 0 130#define _BOOL 1 131#define _STRING 3 132#define SPEED 0 133#define REVERSER 134 1 135#define POWER 2 136#define BRAKE 3 137#define SIGNAL_INFO 4 138#define SIGNAL_DISTANCE 139 5 140#define SPEED_LIMIT 6 141#define HORN 7 142#define SPEED_CONST 8 143#define 144 MASTER_KEY 9 145#define EMERGENCY 10 146#define RC_MODE 11 147#define LDOOR_OPEN 148 12 149#define RDOOR_OPEN 13 150#define LIGHT_OPEN 15 151#define PANTO_OPEN 16 152#define 153 SANDER_OPEN 14 154#define CURRENT_STATION_NAME 17 155#define NEXT_STATION_NAME 18 156#define 157 CURRENT_STATION_DEPART 20 158#define NEXT_STATION_ARRIVAL 21 159#define NEXT_STATION_DIS 160 19 161#define CURRENT_TIME 22 162#define LDDOR_IN_OP 23 163#define RDOOR_IN_OP 24 164#define 165 UPDATE_LAST_NUM 14 166#define UPDATE_OW 8 167#define NO_BINDING -1 168//HMI 169#define 170 HMI_SCRIPT_NUM 22 171#define HMI_END_SYM 0xFF 172#define MAX_SERIAL_STEP 5 173//PC 174#define 175 FILTER '|' 176#define START_SYM '#' 177#define END_SYM '!' 178#define NO_DATA "" 179#define 180 RECIEVE_DELAY 2 181#define SEND_DELAY 25 182#define TIMER_TICK 500000 183// 184 185#define 186 NOP do { __asm__ __volatile__ ("nop"); } while (0) 187 188#include "DueTimer.h" 189 190typedef 191 void (*funcPoint)(); 192// 193/* 194=========================================== 195--Device 196 Maps 197default: 198PowerUp:process0 199PowerDown:process1 200ReserverForward:process2 201ReserverBackward:process3 202Horn:process4 203SpeedConst:process5 204Emergency:process6 205MasterKey:process7 206=========================================== 207*/ 208 209void 210 process0(); 211void process1(); 212void process2(); 213void process3(); 214void 215 process4(); 216void process5(); 217void process6(); 218void process7(); 219void 220 process8(); 221void process9(); 222void process10(); 223void process11(); 224void 225 process12(); 226void process13(); 227void process14(); 228void process15(); 229void 230 process16(); 231 232//change device type here 233const int deviceType[DEVICE_NUMBER] 234 = {SWITCH_C, SWITCH_C, SWITCH_C, SWITCH_C, SWITCH_C, SWITCH_C, SWITCH_C, SWITCH_C, 235 SWITCH_C, SWITCH_C, 236 SWITCH_C, DIG_OUT, 237 SWITCH_C, DIG_OUT, SWITCH_C, SWITCH_C, SWITCH_C 238 }; 239//change 240 functions here 241const int devicePinsType[] = {INPUT_PULLUP, INPUT_PULLUP, INPUT_PULLUP, 242 OUTPUT}; 243const funcPoint Process[DEVICE_NUMBER] = {process0, process1, process2, 244 process3, process4, process5, process6, process7, process8, process9, 245 process10, 246 process11, process12, process13, process14, process15, process16 247 }; 248//all 249 use PULL_UP gpio mode 250//key for bac horn -3 -2 -1 1 2 3 ld ldled rd rdled light 251 pat sand 252const int devicePins[DEVICE_NUMBER] = {31, 32, 33, 37, 25, 26, 27, 28, 253 29, 30, 39, 41, 22, 24, 35, 34, 38}; 254int deviceLastState[DEVICE_NUMBER] = {KEY_UP, 255 KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, 256 KEY_UP, 257 KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP 258 }; 259int 260 deviceSADur[DEVICE_NUMBER] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 261 0, 262 0, 0, 0, 0, 0, 0 263 }; 264//train data id 265const 266 int dataDefault[TRAIN_DATA_NUMBER] = {SPEED_MIN, REVERSER_NEUTRAL, POWER_MIN, BRAKE_MIN, 267 SIGNAL_RED, 268 SIGNAL_DISTANCE_DE, SPEED_LIMIT_DEF, 269 HORN_OFF, SPEED_CONST_MIN, MASTER_KEY_OFF, 270 EMERGENCY_OFF, 271 NORMAL, LDOOR_OPEN_DEF, RDDOR_OPEN_DEF, SANDER_OFF, LIGHT_OFF, PANTO_UP, CURRENT_STATION_N, 272 NEXT_STATION_N, 273 NEXT_STATION_DIS_DEF, 274 CURRENT_STATION_DEPART_TIME_DEF, NEXT_STATION_ARRIVAL_TIME_DEF, CURRENT_TIME_DEF, 275 LDOOR_IN_OP_DEF, RDOOR_IN_OP_DEF 276 }; 277const 278 int dataType[TRAIN_DATA_NUMBER] = {_INT, _INT, _INT, _INT, _INT, _INT, _INT, _BOOL, 279 _INT, _BOOL, _BOOL, _BOOL, _BOOL, _BOOL, 280 _BOOL, 281 _BOOL, _INT, _STRING, _STRING, _STRING, _STRING, _STRING, _STRING, _BOOL, _BOOL 282 283 }; 284const int recieveToUpdate[UPDATE_LAST_NUM] 285 = {SPEED, SIGNAL_INFO, SIGNAL_DISTANCE, SPEED_LIMIT, RC_MODE, LDDOR_IN_OP, RDOOR_IN_OP, 286 NEXT_STATION_NAME, CURRENT_STATION_NAME, 287 NEXT_STATION_DIS, 288 NEXT_STATION_ARRIVAL, CURRENT_STATION_DEPART, NEXT_STATION_DIS, CURRENT_TIME 289 290 }; 291const int overwriteToUpdate[UPDATE_OW] 292 = {POWER, BRAKE, REVERSER, SPEED, SIGNAL_INFO, SIGNAL_DISTANCE, SPEED_LIMIT, RC_MODE}; 293const 294 int dataBinding[TRAIN_DATA_NUMBER] = {NO_BINDING, NO_BINDING, NO_BINDING, NO_BINDING, 295 NO_BINDING, 296 NO_BINDING, NO_BINDING, 297 NO_BINDING, NO_BINDING, NO_BINDING, NO_BINDING, 298 NO_BINDING, 299 NO_BINDING, NO_BINDING, NO_BINDING, NO_BINDING, NO_BINDING, NO_BINDING, 300 NO_BINDING, 301 NO_BINDING, NO_BINDING, NO_BINDING, NO_BINDING, 11, 13 302 }; 303 304class 305 TrainManager 306{ 307public: 308 int trainData[TRAIN_DATA_NUMBER]; 309 String 310 trainDataStr[TRAIN_DATA_NUMBER]; 311 //did it has been sended 312 TrainManager(const 313 int dataDefault[]) 314 { 315 //set default data to Train Manager 316 for 317 (int i = 0; i < TRAIN_DATA_NUMBER; i++) 318 { 319 trainData[i] = dataDefault[i]; 320 trainDataStr[i] 321 = NO_DATA; 322 } 323 } 324 // 325 void SetData(int dataID, int value) 326 { 327 trainData[dataID] 328 = value; 329 } 330 void SetDataStr(int dataID, String value) 331 { 332 trainDataStr[dataID] 333 = value; 334 } 335 //get train data 336 int GetData(int dataID) 337 { 338 return 339 trainData[dataID]; 340 } 341 String GetDataStr(int dataID) 342 { 343 return 344 trainDataStr[dataID]; 345 } 346}; 347 348class DevicesManager 349{ 350public: 351 DevicesManager(const 352 int devicePins[], const int deviceType[], const int devicePinsType[]) 353 { 354 //define 355 gpio mode 356 for (int i = 0; i < DEVICE_NUMBER; i++) 357 pinMode(devicePins[i], 358 devicePinsType[deviceType[i]]); 359 } 360 // 361 int GetState(int deviceID) 362 { 363 if 364 (deviceType[deviceID] == SWITCH_F) 365 { 366 if (digitalRead(devicePins[deviceID]) 367 == LOW) 368 { 369 if (deviceLastState[deviceID] == KEY_UP) 370 { 371 deviceSADur[deviceID] 372 = 0; 373 deviceLastState[deviceID] = KEY_WAITTING; 374 } 375 else 376 if (deviceLastState[deviceID] == KEY_WAITTING) 377 { 378 deviceSADur[deviceID]++; 379 if 380 (deviceSADur[deviceID] >= SA_COUNT_SF) 381 { 382 deviceSADur[deviceID] 383 = 0; 384 deviceLastState[deviceID] = KEY_DOWN; 385 return 386 ACTIVE; 387 } 388 } 389 } 390 else 391 { 392 deviceLastState[deviceID] 393 = KEY_UP; 394 return NO_ACTIVE; 395 } 396 } 397 else if (deviceType[deviceID] 398 == SWITCH_C) 399 { 400 if (digitalRead(devicePins[deviceID]) == LOW) 401 { 402 if 403 (deviceLastState[deviceID] == KEY_UP) 404 { 405 deviceSADur[deviceID] 406 = 0; 407 deviceLastState[deviceID] = KEY_WAITTING; 408 } 409 else 410 if (deviceLastState[deviceID] == KEY_WAITTING) 411 { 412 deviceSADur[deviceID]++; 413 if 414 (deviceSADur[deviceID] >= SA_COUNT_SC) 415 { 416 deviceSADur[deviceID] 417 = 0; 418 deviceLastState[deviceID] = KEY_DOWN; 419 return 420 ACTIVE; 421 } 422 } 423 else if (deviceLastState[deviceID] 424 == KEY_DOWN)return ACTIVE; 425 } 426 else 427 { 428 deviceLastState[deviceID] 429 = KEY_UP; 430 return NO_ACTIVE; 431 } 432 } 433 return NO_ACTIVE; 434 } 435 // 436 void 437 delay_(int ms) 438 { 439 for (int i = 0; i < ms; i++) 440 { 441 for 442 (int j = 0; j < 1985; j++) NOP; 443 } 444 } 445}; 446 447DevicesManager Devices(devicePins, 448 deviceType, devicePinsType); 449TrainManager currentData(dataDefault); 450TrainManager 451 processData(dataDefault); 452 453class CommunicationManager 454{ 455private: 456 String 457 recieveData; 458 String sendData; 459 String sender; 460 String tmp; 461 int 462 length, st, ed, pos, sendEd; 463public: 464 CommunicationManager() 465 { 466 Serial.begin(115200); 467 //reset 468 the recieved data 469 sendData = NO_DATA; 470 recieveData = NO_DATA; 471 sender 472 = NO_DATA; 473 length = st = ed = pos = 0; 474 sendEd = 0; 475 } 476 477 bool 478 RecieveDataFromPC(TrainManager & p) 479 { 480 tmp = NO_DATA; 481 //clear 482 last data 483 recieveData = NO_DATA; 484 //recieve from serial 485 while 486 (Serial.available() > 0) 487 { 488 char currentRead = char(Serial.read()); 489 recieveData 490 += currentRead; 491 Devices.delay_(RECIEVE_DELAY); 492 //if (currentRead 493 == END_SYM)break; 494 } 495 length = recieveData.length(); 496 //no data 497 exit 498 if (!length)return false; 499 //find start pos 500 //Serial.println(recieveData); 501 st 502 = ed = 0; 503 for (int i = 0; i < length; i++) 504 if (recieveData.charAt(i) 505 == START_SYM) 506 { 507 st = i; 508 break; 509 } 510 //find 511 end pos 512 for (int i = length - 1; i >= 0; i--) 513 if (recieveData.charAt(i) 514 == END_SYM) 515 { 516 ed = i; 517 break; 518 } 519 //cover 520 data 521 pos = 0; 522 for (int i = st; i <= ed; i++) 523 { 524 if 525 (recieveData.charAt(i) != START_SYM && recieveData.charAt(i) != END_SYM && recieveData.charAt(i) 526 != FILTER)tmp += recieveData.charAt(i); 527 if (recieveData.charAt(i) == FILTER) 528 { 529 //send 530 data to TrainManager 531 if (dataType[pos] != _STRING) 532 p.SetData(pos++, 533 tmp.toInt()); 534 else 535 { 536 p.SetDataStr(pos++, tmp); 537 } 538 //clear 539 tmp 540 tmp = NO_DATA; 541 } 542 } 543 return true; 544 } 545 // 546 bool 547 SendDataToPC(TrainManager & p) 548 { 549 sendData = NO_DATA; 550 //add start 551 symbol 552 sendData += START_SYM; 553 //add contents 554 for (int i = 0; 555 i < TRAIN_DATA_NUMBER; i++) 556 { 557 if (dataType[i] != _STRING)sendData 558 += p.GetData(i); 559 else sendData += " "; 560 sendData += FILTER; 561 } 562 //add 563 end symbol 564 sendData += END_SYM; 565 if (!sendData.length())return false; 566 //send 567 data to PC 568 Serial.print(sendData); 569 return true; 570 } 571}; 572 573class 574 TaskManager 575{ 576public: 577 TaskManager() 578 { 579 currentData = processData; 580 } 581 // 582 void 583 AddProc(TrainManager & p) 584 { 585 currentData = p; 586 } 587 // 588 void 589 GetLastState(TrainManager & p) 590 { 591 p = currentData; 592 } 593 // 594 void 595 UpdateData(TrainManager & p) 596 { 597 if (currentData.GetData(RC_MODE) == NORMAL) 598 for 599 (int i = 0; i < UPDATE_LAST_NUM; i++) 600 { 601 if (dataType[recieveToUpdate[i]] 602 != _STRING) 603 p.SetData(recieveToUpdate[i], currentData.GetData(recieveToUpdate[i])); 604 else 605 p.SetDataStr(recieveToUpdate[i], 606 currentData.GetDataStr(recieveToUpdate[i])); 607 } 608 else if (currentData.GetData(RC_MODE) 609 == OVERWRITE) 610 for (int i = 0; i < UPDATE_OW; i++) 611 { 612 if 613 (dataType[overwriteToUpdate[i]] != _STRING) 614 p.SetData(overwriteToUpdate[i], 615 currentData.GetData(overwriteToUpdate[i])); 616 else 617 p.SetDataStr(overwriteToUpdate[i], 618 currentData.GetDataStr(overwriteToUpdate[i])); 619 } 620 //check AP state 621 if 622 (p.GetData(SPEED_CONST) != SPEED_CONST_MIN && 623 currentData.GetData(SPEED_CONST) 624 != SPEED_CONST_MIN) 625 p.SetData(SPEED_CONST, currentData.GetData(SPEED_CONST)); 626 } 627}; 628 629CommunicationManager 630 Communication; 631TaskManager Queue; 632 633int isHandleZero = 0; 634 635 636void 637 process0() 638{ 639 // 640 int deviceState = Devices.GetState(0); 641 isHandleZero++; 642 if 643 (deviceState == ACTIVE) 644 { 645 processData.SetData(MASTER_KEY, MASTER_KEY_ON); 646 } 647 else 648 { 649 processData.SetData(MASTER_KEY, 650 MASTER_KEY_OFF); 651 } 652 return; 653} 654 655void process1() 656{ 657 if (processData.GetData(MASTER_KEY) 658 == MASTER_KEY_OFF || 659 processData.GetData(EMERGENCY) == EMERGENCY_ON 660 || 661 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 662 int 663 deviceState = Devices.GetState(1); 664 if (deviceState == ACTIVE) 665 { 666 processData.SetData(REVERSER, 667 REVERSER_FORWARD); 668 } 669 else 670 { 671 processData.SetData(REVERSER, 672 REVERSER_NEUTRAL); 673 } 674 return; 675} 676 677void process2() 678{ 679 if 680 (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF || 681 processData.GetData(EMERGENCY) 682 == EMERGENCY_ON || 683 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 684 int 685 deviceState = Devices.GetState(2); 686 if (deviceState == ACTIVE) 687 { 688 processData.SetData(REVERSER, 689 REVERSER_BACKWARD); 690 } 691 return; 692} 693 694void process3() 695{ 696 if 697 (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF)return; 698 int deviceState 699 = Devices.GetState(3); 700 if (deviceState == ACTIVE) 701 { 702 processData.SetData(HORN, 703 HORN_ON); 704 } 705 else 706 { 707 processData.SetData(HORN, HORN_OFF); 708 } 709 return; 710} 711 712//-3 713void 714 process4() 715{ 716 //SWITCH_F 717 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF 718 || 719 processData.GetData(EMERGENCY) == EMERGENCY_ON || 720 processData.GetData(REVERSER) 721 == REVERSER_NEUTRAL || 722 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 723 int 724 deviceState = Devices.GetState(4); 725 if (deviceState == ACTIVE) 726 { 727 isHandleZero 728 --; 729 processData.SetData(POWER, 0); 730 processData.SetData(BRAKE, 6); 731 } 732 return; 733} 734 735//-2 736void 737 process5() 738{ 739 //SWITCH_F 740 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF 741 || 742 processData.GetData(EMERGENCY) == EMERGENCY_ON || 743 processData.GetData(REVERSER) 744 == REVERSER_NEUTRAL || 745 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 746 int 747 deviceState = Devices.GetState(5); 748 if (deviceState == ACTIVE) 749 { 750 isHandleZero 751 --; 752 processData.SetData(POWER, 0); 753 processData.SetData(BRAKE, 4); 754 } 755 return; 756} 757 758//-1 759void 760 process6() 761{ 762 //SWITCH_F 763 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF 764 || 765 processData.GetData(EMERGENCY) == EMERGENCY_ON || 766 processData.GetData(REVERSER) 767 == REVERSER_NEUTRAL || 768 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 769 int 770 deviceState = Devices.GetState(6); 771 if (deviceState == ACTIVE) 772 { 773 isHandleZero 774 --; 775 processData.SetData(POWER, 0); 776 processData.SetData(BRAKE, 2); 777 } 778 return; 779} 780 781//1 782void 783 process7() 784{ 785 //SWITCH_F 786 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF 787 || 788 processData.GetData(EMERGENCY) == EMERGENCY_ON || 789 processData.GetData(REVERSER) 790 == REVERSER_NEUTRAL || 791 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 792 int 793 deviceState = Devices.GetState(7); 794 if (deviceState == ACTIVE) 795 { 796 isHandleZero 797 --; 798 processData.SetData(POWER, 1); 799 processData.SetData(BRAKE, 0); 800 } 801 return; 802} 803 804//2 805void 806 process8() 807{ 808 //SWITCH_F 809 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF 810 || 811 processData.GetData(EMERGENCY) == EMERGENCY_ON || 812 processData.GetData(REVERSER) 813 == REVERSER_NEUTRAL || 814 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 815 int 816 deviceState = Devices.GetState(8); 817 if (deviceState == ACTIVE) 818 { 819 isHandleZero 820 --; 821 processData.SetData(POWER, 2); 822 processData.SetData(BRAKE, 0); 823 } 824 return; 825} 826 827//3 828void 829 process9() 830{ 831 //SWITCH_F 832 if (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF 833 || 834 processData.GetData(EMERGENCY) == EMERGENCY_ON || 835 processData.GetData(REVERSER) 836 == REVERSER_NEUTRAL || 837 processData.GetData(SPEED_CONST) != SPEED_CONST_MIN)return; 838 int 839 deviceState = Devices.GetState(9); 840 if (deviceState == ACTIVE) 841 { 842 isHandleZero 843 --; 844 processData.SetData(POWER, 3); 845 processData.SetData(BRAKE, 0); 846 } 847 // 848 if 849 (isHandleZero > 600) 850 { 851 processData.SetData(POWER, 0); 852 processData.SetData(BRAKE, 853 0); 854 isHandleZero = 0; 855 } 856 return; 857} 858 859//key for bac horn 860 -3 -2 -1 1 2 3 ld ldled rd rdled light pat sand 861 862void process10() 863{ 864 if 865 (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF)return; 866 int deviceState 867 = Devices.GetState(10); 868 if (deviceState == ACTIVE) 869 { 870 if (processData.GetData(LDOOR_OPEN))return; 871 processData.SetData(LDOOR_OPEN, 872 1); 873 } 874 else 875 { 876 if (!processData.GetData(LDOOR_OPEN))return; 877 processData.SetData(LDOOR_OPEN, 878 0); 879 } 880} 881 882void process11() 883{ 884 pinMode(devicePins[11], OUTPUT); 885 digitalWrite(devicePins[11], 886 processData.GetData(LDDOR_IN_OP)); 887} 888 889void process12() 890{ 891 if (processData.GetData(MASTER_KEY) 892 == MASTER_KEY_OFF)return; 893 int deviceState = Devices.GetState(12); 894 if (deviceState 895 == ACTIVE) 896 { 897 if (processData.GetData(RDOOR_OPEN))return; 898 processData.SetData(RDOOR_OPEN, 899 1); 900 } 901 else 902 { 903 if (!processData.GetData(RDOOR_OPEN))return; 904 processData.SetData(RDOOR_OPEN, 905 0); 906 } 907} 908 909void process13() 910{ 911 pinMode(devicePins[13], OUTPUT); 912 digitalWrite(devicePins[13], 913 processData.GetData(RDOOR_IN_OP)); 914} 915 916void process14() 917{ 918 if (processData.GetData(MASTER_KEY) 919 == MASTER_KEY_OFF)return; 920 int deviceState = Devices.GetState(14); 921 if (deviceState 922 == ACTIVE) 923 { 924 if (processData.GetData(LIGHT_OPEN))return; 925 processData.SetData(LIGHT_OPEN, 926 1); 927 } 928 else 929 { 930 if (!processData.GetData(LIGHT_OPEN))return; 931 processData.SetData(LIGHT_OPEN, 932 0); 933 } 934} 935 936void process15() 937{ 938 if (processData.GetData(MASTER_KEY) 939 == MASTER_KEY_OFF)return; 940 int deviceState = Devices.GetState(15); 941 if (deviceState 942 == ACTIVE) 943 { 944 processData.SetData(PANTO_OPEN, !processData.GetData(PANTO_OPEN)); 945 delay(1000); 946 //while 947 (Devices.GetState(14) == ACTIVE); 948 } 949} 950 951void process16() 952{ 953 if 954 (processData.GetData(MASTER_KEY) == MASTER_KEY_OFF)return; 955 int deviceState 956 = Devices.GetState(16); 957 if (deviceState == ACTIVE) 958 { 959 processData.SetData(SANDER_OPEN, 960 1); 961 } 962 else 963 { 964 processData.SetData(SANDER_OPEN, 0); 965 } 966} 967 968void 969 TimerInterrupt() 970{ 971 Timer1.stop(); 972 Communication.SendDataToPC(currentData); 973 Communication.RecieveDataFromPC(currentData); 974 Timer1.start(); 975} 976 977void 978 setup() 979{ 980 Serial.begin(115200); 981 Timer1.attachInterrupt(TimerInterrupt); 982 Timer1.setPeriod(TIMER_TICK); 983 Timer1.start(); 984} 985 986void 987 loop() 988{ 989 //state automatic 990 Queue.GetLastState(processData); 991 for 992 (int i = 0; i < DEVICE_NUMBER; i++)Process[i](); 993 Queue.UpdateData(processData); 994 Queue.AddProc(processData); 995}
Downloadable files
PCB Board Design
PcbDoc files on GitHub
https://github.com/TSDArthur/RAGLINK/tree/master/Devices%20part/PCB
PCB Board Design
PcbDoc files on GitHub
https://github.com/TSDArthur/RAGLINK/tree/master/Devices%20part/PCB
Documentation
Power / Brake Combien Handle Design
DXF files on GitHub
https://github.com/TSDArthur/RAGLINK/tree/master/Devices%20part/DXF/Handle
Power / Brake Combien Handle Design
DXF files on GitHub
https://github.com/TSDArthur/RAGLINK/tree/master/Devices%20part/DXF/Handle
Comments