Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 8 additions & 32 deletions DCCpp_Uno/Config.h → DCCpp_NodeMCU/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,50 +9,26 @@ Part of DCC++ BASE STATION for the Arduino

/////////////////////////////////////////////////////////////////////////////////////
//
// DEFINE MOTOR_SHIELD_TYPE ACCORDING TO THE FOLLOWING TABLE:
// DEFINE PORT TO USE FOR ETHERNET COMMUNICATIONS INTERFACE
//
// 0 = ARDUINO MOTOR SHIELD (MAX 18V/2A PER CHANNEL)
// 1 = POLOLU MC33926 MOTOR SHIELD (MAX 28V/3A PER CHANNEL)

#define MOTOR_SHIELD_TYPE 0

/////////////////////////////////////////////////////////////////////////////////////
//
// DEFINE NUMBER OF MAIN TRACK REGISTER

#define MAX_MAIN_REGISTERS 12

/////////////////////////////////////////////////////////////////////////////////////
//
// DEFINE COMMUNICATIONS INTERFACE
//
// 0 = Built-in Serial Port
// 1 = Arduino.cc Ethernet/SD-Card Shield
// 2 = Arduino.org Ethernet/SD-Card Shield
// 3 = Seeed Studio Ethernet/SD-Card Shield W5200

#define COMM_INTERFACE 0
#define ETHERNET_PORT 2560

/////////////////////////////////////////////////////////////////////////////////////
//
// DEFINE STATIC IP ADDRESS *OR* COMMENT OUT TO USE DHCP
// DEFINE WIFI PARAMETERS
//

//#define IP_ADDRESS { 192, 168, 1, 200 }

/////////////////////////////////////////////////////////////////////////////////////
//
// DEFINE PORT TO USE FOR ETHERNET COMMUNICATIONS INTERFACE
//

#define ETHERNET_PORT 2560
#define _SSID ""
#define _PASSWORD ""
#define _HOSTNAME "sensor02"

/////////////////////////////////////////////////////////////////////////////////////
//
// DEFINE MAC ADDRESS ARRAY FOR ETHERNET COMMUNICATIONS INTERFACE
// DEFINE REMOTE SENSOR PARAMETERS
//

#define MAC_ADDRESS { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEF }

/////////////////////////////////////////////////////////////////////////////////////

#define REMOTE_SENSORS_FIRST_SENSOR 100
22 changes: 22 additions & 0 deletions DCCpp_NodeMCU/DCCpp_NodeMCU.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**********************************************************************

DCCpp_Uno.h
COPYRIGHT (c) 2013-2016 Gregg E. Berman

Part of DCC++ BASE STATION for the Arduino

**********************************************************************/

#ifndef DCCpp_Uno_h
#define DCCpp_Uno_h

/////////////////////////////////////////////////////////////////////////////////////
// RELEASE VERSION
/////////////////////////////////////////////////////////////////////////////////////

#define VERSION "1.2.1++"
#define ARDUINO_TYPE "NodeMCU"

#endif


123 changes: 123 additions & 0 deletions DCCpp_NodeMCU/DCCpp_NodeMCU.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/**********************************************************************

DCC++ BASE STATION
COPYRIGHT (c) 2013-2016 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++ BASE STATION is a C++ program written for the Arduino Uno and Arduino Mega
using the Arduino IDE 1.6.6.

It allows a standard Arduino Uno or Mega with an Arduino Motor Shield (as well as others)
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.

This stripped-down version of DCC++ BASE STATION only supports sensor inputs connected
to the NodeMCU.

DCC++ BASE STATION is controlled with simple text commands received via
the NodeMCU WiFi interface.

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/index-nmra-standards-and-recommended-practices
Arduino: http://www.arduino.cc/
Processing: http://processing.org/
GNU General Public License: http://opensource.org/licenses/GPL-3.0

BRIEF NOTES ON THE THEORY AND OPERATION OF DCC++ BASE STATION:


DCC++ BASE STATION in split into multiple modules, each with its own header file:

DCCpp_NodeMCU: declares required global objects and contains initial Arduino setup()
and Arduino loop() functions, as well as and optional array of Sensors

WiFiCommand: contains methods to read and interpret text commands from the WiFi interface,
process those instructions.

Sensor: contains methods to monitor and report on the status of optionally-defined infrared
sensors embedded in the Main Track and connected to various pins on the NodeMCU

EEStore: contains methods to store, update, and the sensor settings in the EEPROM for
recall after power-up

DCC++ BASE STATION is configured through the Config.h file that contains all user-definable parameters

**********************************************************************/

// BEGIN BY INCLUDING THE HEADER FILES FOR EACH MODULE

#include <ESP8266WiFi.h>
#include "Config.h"
#include "DCCpp_NodeMCU.h"
#include "Sensor.h"
#include "RemoteSensor.h"
#include "EEstore.h"
#include "WiFiCommand.h"

///////////////////////////////////////////////////////////////////////////////
// MAIN ARDUINO LOOP
///////////////////////////////////////////////////////////////////////////////

void loop(){

WiFiCommand::process(); // check for, and process, and new WiFi commands
RemoteSensor::check(); // check remotesensors for inactivity
Sensor::check(); // check sensors for activate/de-activate
} // loop

///////////////////////////////////////////////////////////////////////////////
// INITIAL SETUP
///////////////////////////////////////////////////////////////////////////////

void setup(){

Serial.begin(115200); // configure serial interface
Serial.flush();

EEStore::init(); // initialize and load Turnout and Sensor definitions stored in EEPROM
WiFiCommand::init();

Serial.print("<iDCC++ BASE STATION FOR ESP8266 "); // Print Status to Serial Line regardless of COMM_TYPE setting so use can open Serial Monitor and check configurtion
Serial.print(ARDUINO_TYPE);
Serial.print(" / ");
Serial.print(VERSION);
Serial.print(" / ");
Serial.print(__DATE__);
Serial.print(" ");
Serial.print(__TIME__);
Serial.print(">");
Serial.print("<N");
Serial.print("1");
Serial.print(": ");

Serial.print(WiFi.localIP());
Serial.println(">");
} // setup
24 changes: 13 additions & 11 deletions DCCpp_Uno/EEStore.cpp → DCCpp_NodeMCU/EEStore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,18 @@ Part of DCC++ BASE STATION for the Arduino

**********************************************************************/

#include "DCCpp_Uno.h"
#include "DCCpp_NodeMCU.h"
#include "EEStore.h"
#include "Accessories.h"
#include "Sensor.h"
#include "Outputs.h"
#include <EEPROM.h>

///////////////////////////////////////////////////////////////////////////////

void EEStore::init(){


eeStore=(EEStore *)calloc(1,sizeof(EEStore));

EEPROM.begin( 4096 );
EEPROM.get(0,eeStore->data); // get eeStore data

if(strncmp(eeStore->data.id,EESTORE_ID,sizeof(EESTORE_ID))!=0){ // check to see that eeStore contains valid DCC++ ID
Expand All @@ -32,32 +30,36 @@ void EEStore::init(){
}

reset(); // set memory pointer to first free EEPROM space
Turnout::load(); // load turnout definitions
Sensor::load(); // load sensor definitions
Output::load(); // load output definitions
Output::load(); // load output definitions

}

///////////////////////////////////////////////////////////////////////////////

void EEStore::clear(){


EEPROM.begin( 4096 );
sprintf(eeStore->data.id,EESTORE_ID); // create blank eeStore structure (no turnouts, no sensors) and save it back to EEPROM
eeStore->data.nTurnouts=0;
eeStore->data.nSensors=0;
eeStore->data.nOutputs=0;
EEPROM.put(0,eeStore->data);
EEPROM.commit();
EEPROM.end();

}

///////////////////////////////////////////////////////////////////////////////

void EEStore::store(){
reset();
Turnout::store();
Sensor::store();
EEPROM.begin( 4096 );
Sensor::store();
Output::store();
EEPROM.put(0,eeStore->data);
EEPROM.put(0,eeStore->data);
EEPROM.commit();
EEPROM.end();
}

///////////////////////////////////////////////////////////////////////////////
Expand Down
File renamed without changes.
43 changes: 22 additions & 21 deletions DCCpp_Uno/Outputs.cpp → DCCpp_NodeMCU/Outputs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,13 @@ the state of any outputs being monitored or controlled by a separate interface o

**********************************************************************/

#include <ESP8266WiFi.h>
#include "Config.h"
#include "DCCpp_NodeMCU.h"
#include "Outputs.h"
#include "SerialCommand.h"
#include "DCCpp_Uno.h"
#include "EEStore.h"
#include "WiFiCommand.h"
#include <EEPROM.h>
#include "Comm.h"

///////////////////////////////////////////////////////////////////////////////

Expand All @@ -85,12 +86,12 @@ void Output::activate(int s){
digitalWrite(data.pin,data.oStatus ^ bitRead(data.iFlag,0)); // set state of output pin to HIGH or LOW depending on whether bit zero of iFlag is set to 0 (ACTIVE=HIGH) or 1 (ACTIVE=LOW)
if(num>0)
EEPROM.put(num,data.oStatus);
INTERFACE.print("<Y");
INTERFACE.print(data.id);
WiFiCommand::print("<Y");
WiFiCommand::print(data.id);
if(data.oStatus==0)
INTERFACE.print(" 0>");
WiFiCommand::print(" 0>");
else
INTERFACE.print(" 1>");
WiFiCommand::print(" 1>");
}

///////////////////////////////////////////////////////////////////////////////
Expand All @@ -108,7 +109,7 @@ void Output::remove(int n){
for(tt=firstOutput;tt!=NULL && tt->data.id!=n;pp=tt,tt=tt->nextOutput);

if(tt==NULL){
INTERFACE.print("<X>");
WiFiCommand::print("<X>");
return;
}

Expand All @@ -119,7 +120,7 @@ void Output::remove(int n){

free(tt);

INTERFACE.print("<O>");
WiFiCommand::print("<O>");
}

///////////////////////////////////////////////////////////////////////////////
Expand All @@ -128,23 +129,23 @@ void Output::show(int n){
Output *tt;

if(firstOutput==NULL){
INTERFACE.print("<X>");
WiFiCommand::print("<X>");
return;
}

for(tt=firstOutput;tt!=NULL;tt=tt->nextOutput){
INTERFACE.print("<Y");
INTERFACE.print(tt->data.id);
WiFiCommand::print("<Y");
WiFiCommand::print(tt->data.id);
if(n==1){
INTERFACE.print(" ");
INTERFACE.print(tt->data.pin);
INTERFACE.print(" ");
INTERFACE.print(tt->data.iFlag);
WiFiCommand::print(" ");
WiFiCommand::print(tt->data.pin);
WiFiCommand::print(" ");
WiFiCommand::print(tt->data.iFlag);
}
if(tt->data.oStatus==0)
INTERFACE.print(" 0>");
WiFiCommand::print(" 0>");
else
INTERFACE.print(" 1>");
WiFiCommand::print(" 1>");
}
}

Expand All @@ -161,7 +162,7 @@ void Output::parse(char *c){
if(t!=NULL)
t->activate(s);
else
INTERFACE.print("<X>");
WiFiCommand::print("<X>");
break;

case 3: // argument is string with id number of output followed by a pin number and invert flag
Expand Down Expand Up @@ -230,7 +231,7 @@ Output *Output::create(int id, int pin, int iFlag, int v){

if(tt==NULL){ // problem allocating memory
if(v==1)
INTERFACE.print("<X>");
WiFiCommand::print("<X>");
return(tt);
}

Expand All @@ -243,7 +244,7 @@ Output *Output::create(int id, int pin, int iFlag, int v){
tt->data.oStatus=bitRead(tt->data.iFlag,1)?bitRead(tt->data.iFlag,2):0; // sets status to 0 (INACTIVE) is bit 1 of iFlag=0, otherwise set to value of bit 2 of iFlag
digitalWrite(tt->data.pin,tt->data.oStatus ^ bitRead(tt->data.iFlag,0));
pinMode(tt->data.pin,OUTPUT);
INTERFACE.print("<O>");
WiFiCommand::print("<O>");
}

return(tt);
Expand Down
File renamed without changes.
Loading