Components and supplies
LA38-11X2 20X3 22mm switch
PC computer with triple screen supported GPU (generic)
Arduino Mega 2560
AD16-16C 16mm LED
LAY37-11Y2 20Y3 22mm key switch
USB-A to Mini-USB Cable
LA38-11 LA38-11BN 22mm button
Nextion NX8048T070 - Generic 7.0" HMI TFT LCD Touch Display
Computer LCD Monitor (generic)
CH340G USB-TTL Cable
KHT-2 16W1D Band Switch
Acrylic sheet 5mm (generic)
Tools and machines
Hot glue gun (generic)
Soldering iron (generic)
3D Printer (generic)
Laser cutter (generic)
Apps and platforms
OpenBVE Core & RAGLINK+ Application
Windows 10
Project description
Code
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}
Controller Arduino Source Code on Github
GitHub
HMI Source Code on Github
GitHub
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}
Controller Arduino Source Code on Github
GitHub
HMI Source Code on Github
GitHub
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
Only logged in users can leave comments
TSDArthur
0 Followers
•0 Projects
Table of contents
Intro
6
0