forked from computski/ESP_DCC_Controller
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathESP_DCC_Controller.ino
165 lines (117 loc) · 4.76 KB
/
ESP_DCC_Controller.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
//
//
/*
Name: ESP_DCC_Controller.ino
updated: 2024-04-26
Author: Julian Ossowski
Target: NodeMCU 1.0 (ESP-12E Module) or WeMOS D1 (R1 only)
Note: This device is 4M flash with 1M spiffs. The spiffs hold the webserver files
and must be uploaded separately via vMicro publish server feature
Serial: default speed on the serial is 115200
IDE: vMicro inside MS Visual studio. Should also compile in the Arduino IDE.
Hardware note: the ESP is a 3v3 device, the LCD device is built for 5v but can run on 3v3 with a reduced backlight brightness
and it will also need a -ve voltage bias for the LCD. This can be provided via a charge pump driven off the DCC signal.
OR it is possible to run the LCD, keypad and INA device off 5v, but it is necessary to diode-clamp the SDA line to 3v3.
Incidentally the nodeMCU only has a 3v3 regulator on board. Vin is connected to the USB power which is assumed to be 5v.
It then feeds via a diode into the 3v3 regulator. Its possible to feed Vin with 12v for example and the regulator will drop
this to 3v3, however the regulator will run hot. Also the USB socket will have 12v present on it, which is a risk for any
device plugged into it.
Important: Tested and works with these library versions
ESP boards, latest version 3.1.2 works
Adafruit INA219 library 1.0.3 works
ArduinoJSON library use version 7
This system uses LittleFS, not SPIFFs
These libraries need to be downloaded and put in the arduino libraries folder
ESPAsyncTCP https://github.com/me-no-dev/ESPAsyncTCP
NewLiquidCrystal https://github.com/marcmerlin/NewLiquidCrystal
These can be loaded through the arduino library manager
WebSockets
Adafruit INA219
ArduinoJSON
*/
#include "Global.h"
#include "DCCcore.h"
#include "DCClayer1.h"
#include "DCCweb.h"
#include "WiThrottle.h"
//PIN ASSIGNMENTS - see global.h
//found that NMI in DCClayer1 conflicts with the WSP826WebServer.
//Had to switch to regular ints. There is no conflict with Websockets
uint16_t secCount;
bool bLED;
void setup() {
Serial.begin(115200);
Serial.println(F("\n\nBoot DCC ESP"));
trace(Serial.println(F("trace enabled"));)
//2021-10-19 the unit can operate in DCC mode, or in DC mode pwm which supports a single loco, loco 3 with 28 speed steps
//enable or disable the DC block as required in Global.h DCC and DC are mutually exclusive
#ifdef DC_PINS
//If DC_PINS is defined, this overrides DCC and we will create a DC system. Entirel optional. If you want
//a DCC system, then comment out or delete the DC_PINS definition in Global.h for the board you are using
DC_PINS
#elif defined DCC_PINS
//we expect to find DCC_PINS defined
DCC_PINS
#else
//need to define at least DCC_PINS, else we throw a compile time error.
#error "DCC_PINS or DC_PINS must be defined. Neither is."
#endif
DCCcoreBoot();
//restore settings from EEPROM
dccGetSettings();
nsJogWheel::jogInit();
#ifdef _DCCWEB_h
nsDCCweb::startWebServices();
#endif
/*2020-04-02 start WiThrottle protocol*/
#ifdef _WITHROTTLE_h
nsWiThrottle::startThrottle();
#endif
} //end boot
void loop() {
#ifdef _DCCWEB_h
nsDCCweb::loopWebServices(); // constantly check for websocket events
/*2020-05-03 new approach to broadcasting changes over all channels.
A change can occur on any comms channel, might be WiThrottle, Websockets or the local hardware UI
Flags are set in the loco and turnout objects to denote the need to broadcast.
These flags are cleared by the local UI updater as the last in sequence*/
nsDCCweb::broadcastChanges();
#endif
#ifdef _JSONTHROTTLE_h
nsJsonThrottle::broadcastJSONchanges(false);
#endif
#ifdef _WITHROTTLE_h
nsWiThrottle::broadcastChanges(false);
#endif
//broadcast turnout changes to line and clear the flags
updateLocalMachine();
//call DCCcore once per loop. We no longer use the return value
DCCcore();
if (quarterSecFlag) {
/*isQuarterSecFlag will return true and also clear the flag*/
quarterSecFlag = false;
//2021-01-29 call processTimeout every 250mS to give better resolution over timeouts
#ifdef _WITHROTTLE_h
nsWiThrottle::processTimeout();
#endif
secCount++;
if (secCount >= 8) {
/*toggle heartbeat LED, every 2s*/
bLED = !bLED;
secCount = 0;
//send power status out to web sockets
#ifdef _DCCWEB_h
nsDCCweb::broadcastPower();
#endif
#ifdef _JSONTHROTTLE_h
/*transmit power status to websocket*/
nsJsonThrottle::broadcastJsonPower();
#endif
#ifdef _WITHROTTLE_h
/*transmit power status to WiThrottles*/
//2020-11-28 no need to do this so frequently
//nsWiThrottle::broadcastWiPower();
#endif
}
}//qtr sec
}