// -------------------------------------------------- //
// WWW.ARDUINORAILWAYCONTROL.COM //
// comm_urb.ino //
// V.2.0 11/24/2019 //
// //
// SMALL INTERLOCKING //
// For URB unit V.2.FINAL //
// 122Hz Thrust contol //
// https://arduinorailwaycontrol.com/urb_unit.html //
// //
// Author: Steve Massikker //
// -------------------------------------------------- //
void(* resetFunc) (void) = 0;
#include <Wire.h>
#include <SoftwareSerial.h>
// Bluetooth module
SoftwareSerial Bluetooth(12, 13); // D12 - RX | D13 - TX
// PWM (SPEED)
#define MD_1_ENA 10 // LINES A, B
#define MD_1_ENB 9 // BLOCK 1
#define MD_2_ENA 11 // BLOCK 3
#define MD_2_ENB 3 // BLOCK 2
// DIRECTION DRIVER A
#define MD_1_IN1 4
#define MD_1_IN2 2
// DIRECTION DRIVER B
#define MD_12_IN3_IN3_IN1 5
#define MD_12_IN4_IN4_IN2 6
// SENSORS
#define SNS_1 17
#define SNS_2 14
#define SNS_3 15
#define SNS_4 7
#define SNS_5 8
#define SNS_6 16
#define SNS_7 A6
// Variables
int addressI2C;
byte dataToI2C;
bool stringComplete = false;
String inputString = "";
// 24 speed
byte speedArrayA [] = {30,40,50,60,80,110,140,160,180,200,220,255};
byte speedTrainA = 0;
// Interlocking
unsigned long timerBlock1, timerBlock2, timerBlock3, timerStation;
byte speedBlock1, speedBlock2, speedBlock3;
// Dispather AWS
bool flag_interlocking = false;
bool flag_station_open = true;
// Sensors
unsigned long timer_protected_sensor1, timer_protected_sensor3,
timer_protected_sensor5, timer_protected_sensor7;
bool protected_sensor1, protected_sensor3,
protected_sensor5, protected_sensor7;
bool sensor_block1_IN, sensor_block2_IN, sensor_block3_IN,
sensor_block1_OUT, sensor_block2_OUT, sensor_block3_OUT,
sensor_OUT;
bool latch_stop_block1, latch_stop_block2, latch_stop_block3;
// Latches
bool open_block1 = true, open_block2 = true, open_block3 = true;
// TURNOUTS & SET DEFAULT POSITIONS
bool switch_A = true, switch_B = false;
void setup() {
// Initializie Serials & I2C
Serial.begin(9600);
Bluetooth.begin(9600);
inputString.reserve(4);
Wire.begin(); // Set as Master
// Initialize pins
pinMode (MD_1_ENA, OUTPUT);
pinMode (MD_1_ENB, OUTPUT);
pinMode (MD_2_ENA, OUTPUT);
pinMode (MD_2_ENB, OUTPUT);
pinMode (MD_1_IN1, OUTPUT);
pinMode (MD_1_IN2, OUTPUT);
pinMode (MD_12_IN3_IN3_IN1, OUTPUT);
pinMode (MD_12_IN4_IN4_IN2, OUTPUT);
pinMode (SNS_1, INPUT);
pinMode (SNS_2, INPUT);
pinMode (SNS_3, INPUT);
pinMode (SNS_4, INPUT);
pinMode (SNS_5, INPUT);
pinMode (SNS_6, INPUT);
pinMode (SNS_7, INPUT);
// Set PWM frequency for D3, D9, D10, D11
// Timer 1 divisor to 256 for PWM frequency of 122.55 Hz (9, 10)
TCCR1B = TCCR1B & B11111000 | B00000100;
// Timer 2 divisor to 256 for PWM frequency of 122.55 Hz (3, 11)
TCCR2B = TCCR2B & B11111000 | B00000100;
// Set default direction to FORWARD (POLARITY) NON Interlocking
digitalWrite(MD_1_IN1, LOW);
digitalWrite(MD_1_IN2, HIGH);
digitalWrite(MD_12_IN3_IN3_IN1, LOW);
digitalWrite(MD_12_IN4_IN4_IN2, HIGH);
}
void loop() {
// ---- START PARSING INCOMING APP COMMANDS
if (stringComplete) {
// RESET
if (inputString =="999z") {
dataToI2C = 99;
addressI2C = 2;
sendDataViaI2C();
resetFunc();
}
// FUNCTIONS
if (inputString.charAt(0) =='a') {
// Speed
if (inputString.charAt(1) =='0') {
if (inputString.charAt(2) =='0') speedTrainA = 0;
if (inputString.charAt(2) =='2') speedTrainA = speedArrayA[0];
if (inputString.charAt(2) =='4') speedTrainA = speedArrayA[1];
if (inputString.charAt(2) =='6') speedTrainA = speedArrayA[2];
if (inputString.charAt(2) =='8') speedTrainA = speedArrayA[3];
}
if (inputString.charAt(1) =='1') {
if (inputString.charAt(2) =='0') speedTrainA = speedArrayA[4];
if (inputString.charAt(2) =='2') speedTrainA = speedArrayA[5];
if (inputString.charAt(2) =='4') speedTrainA = speedArrayA[6];
if (inputString.charAt(2) =='6') speedTrainA = speedArrayA[7];
if (inputString.charAt(2) =='8') speedTrainA = speedArrayA[8];
}
if (inputString.charAt(1) =='2') {
if (inputString.charAt(2) =='0') speedTrainA = speedArrayA[9];
if (inputString.charAt(2) =='2') speedTrainA = speedArrayA[10];
if (inputString.charAt(2) =='4') speedTrainA = speedArrayA[11];
}
// Direction and Stop
if (inputString.charAt(1) =='d') {
if (inputString.charAt(2) =='f') { // (f) Forward
digitalWrite(MD_1_IN1, LOW);
digitalWrite(MD_1_IN2, HIGH);
digitalWrite(MD_12_IN3_IN3_IN1, LOW);
digitalWrite(MD_12_IN4_IN4_IN2, HIGH);
}
if (inputString.charAt(2) =='b') { // (b) Backward - Interlocking
digitalWrite(MD_1_IN1, HIGH);
digitalWrite(MD_1_IN2, LOW);
digitalWrite(MD_12_IN3_IN3_IN1, HIGH);
digitalWrite(MD_12_IN4_IN4_IN2, LOW);
}
if (inputString.charAt(2) =='s') { // (s) Stop button
speedTrainA = 0;
}
analogWrite(MD_1_ENA, speedTrainA); // Throttle Driver A
if (!flag_interlocking) {
analogWrite(MD_1_ENB, speedTrainA);
analogWrite(MD_2_ENB, speedTrainA);
if (flag_station_open) analogWrite(MD_2_ENA, speedTrainA);
else analogWrite(MD_2_ENA,0);
}
}
}
if (inputString.charAt(0) =='j') {
// Switch A
if (inputString.charAt(1) =='a') {
if (inputString.charAt(2) =='0') { // Branch direction
switch_A = false;
Bluetooth.print("a0z"); // Feedback to App
Serial.print("a0z");
addressI2C = 2; dataToI2C = 30; sendDataViaI2C();
}
if (inputString.charAt(2) =='1') { // Throw direction
switch_A = true;
Bluetooth.print("a1z"); // Feedback to App
Serial.print("a1z");
addressI2C = 2; dataToI2C = 31; sendDataViaI2C();
}
}
// Switch B
if (inputString.charAt(1) =='b') {
if (inputString.charAt(2) =='0') {
switch_B = false;
Bluetooth.print("b0z");
Serial.print("b0z");
addressI2C = 2; dataToI2C = 32; sendDataViaI2C();
}
if (inputString.charAt(2) =='1') {
switch_B = true;
Bluetooth.print("b1z");
Serial.print("b1z");
addressI2C = 2; dataToI2C = 33; sendDataViaI2C();
}
}
}
// AUTOMATE ON | OFF
if (inputString.charAt(0) =='f') {
if (inputString.charAt(1) =='a') {
if (inputString.charAt(2) =='0') {
flag_interlocking = false;
speedBlock1 = 0; speedBlock2 = 0; speedBlock3 = 0;
addressI2C = 2; dataToI2C = 50; sendDataViaI2C(); // AUTOMATE OFF
}
if (inputString.charAt(2) =='1') {
flag_interlocking = true;
speedBlock1 = 180; speedBlock2 = 140; speedBlock3 = 160;
digitalWrite(MD_1_IN1, HIGH);
digitalWrite(MD_1_IN2, LOW);
digitalWrite(MD_12_IN3_IN3_IN1, HIGH);
digitalWrite(MD_12_IN4_IN4_IN2, LOW);
protected_sensor1 = false; protected_sensor3 = false;
protected_sensor5 = false; protected_sensor7 = false;
latch_stop_block1 = false; latch_stop_block2 = false; latch_stop_block3 = false;
open_block1 = true; open_block2 = true; open_block3 = true;
addressI2C = 2; dataToI2C = 51; sendDataViaI2C(); // AUTOMATE ON
}
analogWrite(MD_1_ENB, speedBlock1);
analogWrite(MD_2_ENB, speedBlock2);
analogWrite(MD_2_ENA, speedBlock3);
}
}
dataToI2C = 0;
inputString = "";
stringComplete = false;
}
// ---- MAIN BLOCK
if (flag_interlocking) {
// CHECK SENSORS STATES
if (digitalRead(SNS_1) == LOW) { // BLOCK 1 | HALL
sensor_block1_IN = true;
open_block1 = false;
//Serial.println("SENSOR 1");
}
else sensor_block1_IN = false;
if (digitalRead(SNS_2) == LOW) { // HALL
sensor_block1_OUT = true;
latch_stop_block1 = true;
//Serial.println("SENSOR 2");
}
else sensor_block1_OUT = false;
if (digitalRead(SNS_3) == HIGH) { // BLOCK 2 | IR
sensor_block2_IN = true;
open_block2 = false;
//Serial.println("SENSOR 3");
}
else sensor_block2_IN = false;
if (digitalRead(SNS_4) == LOW) { // HALL
sensor_block2_OUT = true;
latch_stop_block2 = true;
//Serial.println("SENSOR 4");
}
else sensor_block2_OUT = false;
if (digitalRead(SNS_5) == HIGH) { // BLOCK 3 | IR
sensor_block3_IN = true;
open_block3 = false;
//Serial.println("SENSOR 5");
}
else sensor_block3_IN = false;
if (digitalRead(SNS_6) == LOW) { // HALL
sensor_block3_OUT = true;
latch_stop_block3 = true;
//Serial.println("SENSOR 6");
}
else sensor_block3_OUT = false;
// OUT
if (analogRead(SNS_7) > 550) { // ANALOGUE HALL
sensor_OUT = true;
//Serial.println("SENSOR 7");
}
else sensor_OUT = false;
// RESET BLOCK LATCHES
if (sensor_block2_IN) open_block1 = true;
if (sensor_block3_IN) open_block2 = true;
if (sensor_OUT) open_block3 = true;
// RESET AUTOSTOP LATCHES
if (sensor_block2_IN) latch_stop_block1 = false;
if (sensor_block3_IN) latch_stop_block2 = false;
if (sensor_OUT) latch_stop_block3 = false;
// ---- SIGNALS
// SIGNAL 1
if (sensor_block1_IN && !protected_sensor1) {
timer_protected_sensor1 = millis();
protected_sensor1 = true;
addressI2C = 2; dataToI2C = 101; sendDataViaI2C();
}
// SIGNAL 2
if (sensor_block2_IN && !protected_sensor3) {
timer_protected_sensor3 = millis();
protected_sensor3 = true;
addressI2C = 2; dataToI2C = 102; sendDataViaI2C();
}
// SIGNAL 3
if (sensor_block3_IN && !protected_sensor5) {
timer_protected_sensor5 = millis();
protected_sensor5 = true;
addressI2C = 2; dataToI2C = 103; sendDataViaI2C();
}
// SIGNAL 4
if (sensor_OUT && !protected_sensor7) {
timer_protected_sensor7 = millis();
timerStation = millis();
protected_sensor7 = true;
flag_station_open = false;
addressI2C = 2; dataToI2C = 104; sendDataViaI2C();
}
// AUTOSTOP
// BLOCK 1
if (!open_block2) {
if (latch_stop_block1) {
if (millis() > (timerBlock1 + 100)) {
timerBlock1 = millis();
if (speedBlock1 > 40) speedBlock1 = speedBlock1 - 25;
else speedBlock1 = 0;
}
}
}
else speedBlock1 = 180;
// BLOCK 2
if (!open_block3) {
if (latch_stop_block2) {
if (millis() > (timerBlock2 + 100)) {
timerBlock2 = millis();
if (speedBlock2 > 60) speedBlock2 = speedBlock2 - 30;
else speedBlock2 = 0;
}
}
}
else speedBlock2 = 140;
// BLOCK 3
if (!flag_station_open) {
if (latch_stop_block3) {
if (millis() > (timerBlock3 + 100)) {
timerBlock3 = millis();
if (speedBlock3 > 40) speedBlock3 = speedBlock3 - 18;
else speedBlock3 = 0;
}
}
}
else speedBlock3 = 160;
analogWrite(MD_1_ENB, speedBlock1);
analogWrite(MD_2_ENB, speedBlock2);
analogWrite(MD_2_ENA, speedBlock3);
}
// ---- TIMERS
if (millis() > (timer_protected_sensor1 + 1000)) protected_sensor1 = false;
if (millis() > (timer_protected_sensor3 + 1500)) protected_sensor3 = false;
if (millis() > (timer_protected_sensor5 + 1500)) protected_sensor5 = false;
if (millis() > (timer_protected_sensor7 + 1000)) protected_sensor7 = false;
if (millis() > (timerStation + 15000)) flag_station_open = true; // Delay 15 sec.
bluetoothEvent();
}
// ----------- FUNCTIONS ----------- //
void serialEvent() {
if (Serial.available()) {
char inChar = (char)Serial.read();
inputString += inChar;
if (inChar == 'z') {
stringComplete = true;
}
}
}
void bluetoothEvent() {
if (Bluetooth.available()) {
char inChar = (char)Bluetooth.read();
inputString += inChar;
if (inChar == 'z') {
//Serial.println(inputString); // Command from App
stringComplete = true;
}
}
}
void sendDataViaI2C() {
Wire.beginTransmission(addressI2C);
Wire.write(dataToI2C);
Wire.endTransmission();
}
Comments