198 lines
6.9 KiB
Plaintext
198 lines
6.9 KiB
Plaintext
//////////////////////////////////////////////////////////////////////////
|
|
// DCC++ CONTROLLER
|
|
// COPYRIGHT (c) 2013-2015 Gregg E. Berman
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see http://www.gnu.org/licenses
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// DCC++ CONTROLLER is a Java program written using the 64-bit Processing Library
|
|
// and Processing IDE (version 3.01).
|
|
//
|
|
// DCC++ CONTROLLER provides users with a fully customizeable graphical
|
|
// front end for the total control of model trains and model train layouts
|
|
// via its companion program, DCC++ BASE STATION.
|
|
//
|
|
// DCC++ BASE STATION allows a standard Arduino Uno with an Arduino Motor Shield
|
|
// to be used as a fully-functioning digital command and control (DCC) base station
|
|
// for controlling model train layouts that conform to current National Model
|
|
// Railroad Association (NMRA) DCC standards.
|
|
//
|
|
// DCC++ CONTROLLER communicates with DCC++ BASE STATION using simple text commands sent
|
|
// via a standard USB Serial Cord at speeds of up to 115200 Baud. A Bluetooth Wireless
|
|
// Connection may be used in place of a USB Serial Cord without any software modification.
|
|
//
|
|
// This version of DCC++ CONTROLLER supports:
|
|
//
|
|
// * Multi-Cab / Multi-Throttle configurations using 128-step speed control
|
|
// * 2-byte and 4-byte cab addresses
|
|
// * Customizable cab function buttons F0-F12
|
|
// * User-created multi-layout track plan
|
|
// * Customizeable turnouts and crossovers with controls integrated into track plan
|
|
// * Customizeable routes with configurable buttons
|
|
// * Customizeable routes with route buttons integrated into track plan
|
|
// * Master Power Button
|
|
// * Customizable key-controls
|
|
// * Real-time current monitor
|
|
// * Optional track-integrated sensors
|
|
// * Optional user-created Auto Pilot routines (when used with track-integrated sensors)
|
|
// * Manual activation/de-activation of accessory functions using 512 addresses, each with 4 sub-addresses
|
|
// * Programming on the Main Operations Track
|
|
// - write configuration variable bytes
|
|
// - set/clear specific configuration variable bits
|
|
// * Programming on the Programming Track
|
|
// - write configuration variable bytes
|
|
// - read configuration variable bytes
|
|
//
|
|
// With the exception of a standard 15V power supply for the Arduino Uno that can
|
|
// be purchased in any electronics store, no additional hardware is required.
|
|
//
|
|
// Neither DCC++ BASE STATION nor DCC++ CONTROLLER use any known proprietary or
|
|
// commercial hardware, software, interfaces, specifications, or methods related
|
|
// to the control of model trains using NMRA DCC standards. Both programs are wholly
|
|
// original, developed by the author, and are not derived from any known commercial,
|
|
// free, or open-source model railroad control packages by any other parties.
|
|
//
|
|
// However, DCC++ BASE STATION and DCC++ CONTROLLER do heavily rely on the IDEs and
|
|
// embedded libraries associated with Arduino and Processing. Tremendous thanks to those
|
|
// responsible for these terrific open-source initiatives that enable programs like
|
|
// DCC++ to be developed and distributed in the same fashion.
|
|
//
|
|
// REFERENCES:
|
|
//
|
|
// NMRA DCC Standards: http://www.nmra.org/standards/DCC/standards_rps/DCCStds.html
|
|
// Arduino: http://www.arduino.cc/
|
|
// Processing: http://processing.org/
|
|
// GNU General Public License: http://opensource.org/licenses/GPL-3.0
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
import processing.serial.*;
|
|
import processing.net.*;
|
|
import java.util.regex.Pattern;
|
|
import java.util.regex.Matcher;
|
|
import java.util.*;
|
|
|
|
final String CONTROLLER_VERSION = "3.0";
|
|
final int BASE_BAUD = 115200;
|
|
final int SCREEN_WIDTH = 1366;
|
|
final int SCREEN_HEIGHT = 768;
|
|
final String STATUS_FILE = "dccStatus.xml";
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
void settings(){
|
|
size(SCREEN_WIDTH,SCREEN_HEIGHT);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
void setup(){
|
|
Initialize();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
void draw(){
|
|
|
|
background(backgroundColor);
|
|
|
|
for(DccComponent dcc : dccComponents)
|
|
dcc.display();
|
|
|
|
if(frameCount==1) // if this is the first frame, just display components and return (otherwise user stare at a blank screen while serial is opening
|
|
return;
|
|
|
|
if(frameCount==2) // is this is the second frame, open the serial port --- screen will have already been displayed in prior frame
|
|
aPort.open(arduinoPortXML.getContent());
|
|
|
|
for(int i=buttonQueue2.size()-1;i>=0;i--){
|
|
buttonQueue2.get(i).init();
|
|
buttonQueue2.remove(i);
|
|
}
|
|
|
|
for(int i=buttonQueue.size()-1;i>=0;i--){
|
|
buttonQueue2.add(buttonQueue.get(i));;
|
|
buttonQueue.remove(i);
|
|
}
|
|
|
|
if(!mousePressed){
|
|
cursorType=ARROW;
|
|
previousComponent=selectedComponent;
|
|
selectedComponent=null;
|
|
|
|
int nComponents = dccComponents.size();
|
|
|
|
for(int i=nComponents-1;i>=0;i--)
|
|
dccComponents.get(i).check();
|
|
|
|
cursor(cursorType);
|
|
}
|
|
|
|
int m=millis();
|
|
if(m-lastTime>250 && aPort!=null && currentMeter.isOn){
|
|
lastTime=m;
|
|
aPort.write("<c>");
|
|
}
|
|
|
|
msgBoxClock.setMessage(nf(hour(),2)+":"+nf(minute(),2)+":"+nf(second(),2));
|
|
|
|
if(saveXMLFlag){
|
|
try{
|
|
saveXML(dccStatusXML,STATUS_FILE);
|
|
saveXMLFlag=false;
|
|
} catch(Exception e){
|
|
println("Couldn't save. Will retry");
|
|
}
|
|
}
|
|
|
|
autoPilot.safetyCheck();
|
|
|
|
} // draw
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
abstract class DccComponent{
|
|
Window window=null;
|
|
int xPos, yPos;
|
|
String componentName="NAME NOT DEFINED";
|
|
abstract void display();
|
|
void check(){};
|
|
void pressed(){};
|
|
void rightClick(){};
|
|
void shiftPressed(){};
|
|
void released(){};
|
|
void drag(){};
|
|
void init(){};
|
|
|
|
protected int xWindow(){
|
|
if(window==null)
|
|
return 0;
|
|
return window.xPos;
|
|
}
|
|
|
|
protected int yWindow(){
|
|
if(window==null)
|
|
return 0;
|
|
return window.yPos;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
interface CallBack{
|
|
void execute(int n, String c);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////// |