Skip to content

Commit

Permalink
Merge pull request #54 from pischky/master
Browse files Browse the repository at this point in the history
added version numbers and libraries to ino file and added speed step mode
  • Loading branch information
newHeiko authored Nov 14, 2023
2 parents 63082b5 + 4da789c commit d0f4808
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 28 deletions.
11 changes: 10 additions & 1 deletion software/esp-firmware/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
*/

#include <stdbool.h>
//sloeber>> #include <string.h> // strndup(), strdup()
#include <FS.h>
#include <SPIFFS.h>
//sloeber>> #include <WString.h> // class String
#include <ArduinoJson.h>

#include "config.h"
Expand Down Expand Up @@ -49,6 +51,7 @@ void initConfig(void)
for(int i=0; i<4; i++)
{
locos[i].address = -1;
locos[i].mode = strdup(MODE_DEFAULT); // allocate on heap
locos[i].direction = DIR_NORMAL;
locos[i].longAddress = true;
for(int j=0; j<MAX_FUNCTION + 1; j++)
Expand Down Expand Up @@ -178,9 +181,14 @@ void initConfig(void)
if(!deserializeJson(doc, f))
{
locos[i].address = doc[FIELD_LOCO_ADDRESS] | -1;
if(doc.containsKey(FIELD_LOCO_MODE))
{
free(locos[i].mode);
locos[i].mode = strdup(doc[FIELD_LOCO_MODE]);
}
if(doc.containsKey(FIELD_LOCO_LONG))
{
locos[i].longAddress = doc[FIELD_LOCO_LONG];
locos[i].longAddress = doc[FIELD_LOCO_LONG];
}
if(doc.containsKey(FIELD_LOCO_REVERSE))
{
Expand Down Expand Up @@ -292,6 +300,7 @@ void saveLocoConfig(uint8_t loco)

// save loco configuration for current loco to SPIFFS
doc[FIELD_LOCO_ADDRESS] = locos[loco].address;
doc[FIELD_LOCO_MODE] = locos[loco].mode;
doc[FIELD_LOCO_LONG] = locos[loco].longAddress;
doc[FIELD_LOCO_DIRECTION] = locos[loco].direction;
doc.createNestedArray(FIELD_LOCO_FUNCTIONS);
Expand Down
1 change: 1 addition & 0 deletions software/esp-firmware/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@

#define FN_LOCO_STUB "/loco"
#define FIELD_LOCO_ADDRESS "address"
#define FIELD_LOCO_MODE "mode"
#define FIELD_LOCO_LONG "long"
#define FIELD_LOCO_REVERSE "reverse"
#define FIELD_LOCO_DIRECTION "direction"
Expand Down
27 changes: 24 additions & 3 deletions software/esp-firmware/esp-firmware.ino
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,30 @@
*
* This project was made for ESP32-S2
* with Arduino ESP32 from the 2.0 series
* Board settings: ESP32S2 Dev Module, UART0, Disabled,
* Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS), 160MHz (WiFi),
* QIO, 40MHz, 4MB (32Mb), 921600, None on /dev/ttyUSB0
*
* Versions:
* Arduino IDE 1.8.19
* esp32 2.0.5
*
* Libraries:
* ArduinoJson 6.19.4
*
* Board settings:
* Board: "ESP32S2 Dev Module"
* Upload Speed: "921600"
* USB CDC On Boot: "Disabled"
* USB Firmware MSC On Boot; "Disabled"
* USB DFU On Boot: "Disabled"
* Upload Mode: "UART0"
* CPU Frequency: "160MHz (WiFI/BT)
* Flash Frequency: "40 MHz"
* Flash Mode "QIO"
* Flash Size: "4MB (32Mb)"
* Partion Scheme: "Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)"
* Core Debug Level: "Verbose"
* PSRAM: "Disabled"
* Erase All Flash Before Sketch Upload: "Disabled"
* Port: "COMxx"
*/
/* Boards:
* - ESP32S2 Dev Module * esp32:esp32:esp32s2:UploadSpeed=921600,CDCOnBoot=default,MSCOnBoot=default,DFUOnBoot=default,UploadMode=default,CPUFreq=160,FlashFreq=80,FlashMode=qio,FlashSize=4M,PartitionScheme=default,DebugLevel=none,PSRAM=disabled,EraseFlash=none,JTAGAdapter=default,CONSOLEBAUD=115200
Expand Down
66 changes: 47 additions & 19 deletions software/esp-firmware/locoHandling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,39 @@

#include <WiFi.h>
#include <ESPmDNS.h>
//sloeber>> #include <esp32-hal-log.h> // log_d()

#include <string.h> // strcmp()

#include "locoHandling.h"
#include "lowbat.h"
#include "config.h"
#include "stateMachine.h"
#include "throttleHandling.h"

// see jmri.jmrit.withrottle.ThrottleController#decodeSpeedStepMode()
// and jmri.SpeedStepMode.
const ModeEntry_t MODES[MODES_LENGTH]
{
//"unknown",
{ MODE_DO_NOT_SEND, "(do not set speed step mode)" },
// from decodeSpeedStepMode():
{ "128", "DCC 126 speed steps" }, // DCC 126 speed steps
{ "28", "DCC 28 speed steps" }, // DCC 28 speed steps
{ "27", "DCC 27 speed steps" }, // DCC 27 speed steps
{ "14", "DCC 14 speed steps" }, // DCC 14 speed steps
{ "motorola_28", "Motorola Trinary" }, // Motorola Trinary
{ "tmcc_32", "Lionel TMCC 32" }, // Lionel TMCC 32 speed step mode
{ "incremental", "do not know" },
// from SpeedStepMode:
{ "1", "DCC 126 speed steps" }, // SpeedStepMode.NMRA_DCC_128: DCC 126 speed steps
{ "2", "DCC 28 speed steps" }, // SpeedStepMode.NMRA_DCC_28: DCC 28 speed steps
{ "4", "DCC 27 speed steps" }, // SpeedStepMode.NMRA_DCC_27: DCC 27 speed steps
{ "8", "DCC 14 speed steps" }, // SpeedStepMode.NMRA_DCC_14: DCC 14 speed steps
{ "16", "Motorola Trinary" } // SpeedStepMode.MOTOROLA_28: Motorola Trinary
};


locoInfo locos[4];

/**
Expand Down Expand Up @@ -211,9 +237,8 @@ void locoHandler(void)
if(!isOnlyLoco(currentLoco))
{
break;
}

// intentionally fall through
} // @suppress("No break at end of case")
// intentionally fall through

case THROTTLE_MOMENTARY:
case THROTTLE_LOCKING:
Expand Down Expand Up @@ -426,10 +451,9 @@ void setFunction(uint8_t f)
if(!isOnlyLoco(l))
{
break;
}

// intentionally fall through

} // @suppress("No break at end of case")
// intentionally fall through

case THROTTLE:
case THROTTLE_LOCKING:
// if this is the first loco which uses this function
Expand All @@ -445,10 +469,9 @@ void setFunction(uint8_t f)
{
globalFunctionStatus[f] = ALWAYS_ON;
}
}
} // @suppress("No break at end of case")
// intentionally fall through

// intentionally fall through

case THROTTLE_MOMENTARY:
client.print(String("MTA") + locoThrottleID[l] + "<;>F1" + f + "\n");
break;
Expand Down Expand Up @@ -485,10 +508,9 @@ void clearFunction(uint8_t f)
if(!isOnlyLoco(l))
{
break;
}

// intentionally fall through

} // @suppress("No break at end of case")
// intentionally fall through

case THROTTLE:
case THROTTLE_LOCKING:
case THROTTLE_MOMENTARY:
Expand Down Expand Up @@ -584,7 +606,7 @@ void requestLoco(uint8_t loco)
return;
}

// first step for new loco: Send "loco acquire" command and send ESTOP command right afterwards to make sure loco is not moving
// first step for new loco: Send "loco acquire" command, set speed mode and send ESTOP command right afterwards to make sure loco is not moving
if(locos[loco].longAddress)
{
locoThrottleID[loco] = String("L") + locos[loco].address;
Expand All @@ -593,7 +615,14 @@ void requestLoco(uint8_t loco)
{
locoThrottleID[loco] = String("S") + locos[loco].address;
}
// '+' - Add a locomotive to the throttle
client.print(String("MT+") + locoThrottleID[loco] + "<;>" + locoThrottleID[loco] + "\n");
// 'A' - Action, 's' - set speed step mode
if (strcmp(MODE_DO_NOT_SEND, locos[loco].mode) != 0)
{
client.print(String("MTA") + locoThrottleID[loco] + "<;>s" + locos[loco].mode + "\n");
}
// 'A' - Action, 'X' - emergency stop
client.print(String("MTA") + locoThrottleID[loco] + "<;>X\n");
setESTOP();
locoState[loco] = LOCO_FUNCTIONS;
Expand Down Expand Up @@ -653,10 +682,9 @@ void setLocoFunctions(uint8_t loco)
if(!isOnlyLoco(loco))
{
break;
}

// intentionally fall through

} // @suppress("No break at end of case")
// intentionally fall through

case THROTTLE_MOMENTARY:
if(centerPosition && centerFunction == f)
{
Expand Down
14 changes: 14 additions & 0 deletions software/esp-firmware/locoHandling.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#define NO_ACTIVITY_TIMEOUT (1000L * 60 * 60 * 3) // 3 hours

#include <WiFi.h>
//sloeber>> #include <IPAddress.h> // class IPAddress

#include <stdint.h>
#include <stdbool.h>
Expand All @@ -57,9 +58,22 @@ typedef struct
uint16_t port;
} serverInfo;

const int MODES_LENGTH = 13;

typedef struct ModeEntry {
const char val[12];
const char text[30];
} ModeEntry_t;

extern const ModeEntry_t MODES[MODES_LENGTH];

const char MODE_DEFAULT[] = ""; //"128";
#define MODE_DO_NOT_SEND "" // See requestLoco (should be 'const char MODE_DO_NOT_SEND[] = ""')

typedef struct
{
int16_t address;
char* mode; // values are from MODES and always allocated on the heap
bool longAddress;
functionInfo functions[MAX_FUNCTION + 1];
eDirection direction;
Expand Down
3 changes: 2 additions & 1 deletion software/esp-firmware/throttleHandling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <stdbool.h>
#include <Ticker.h>
//sloeber>> #include <WString.h> // class String

#include "locoHandling.h"
#include "stateMachine.h"
Expand Down Expand Up @@ -69,7 +70,7 @@ Ticker reduceCalibValues;
/**
* Flag to show we want to save new config data
*/
volatile boolean saveAnalog = false;
volatile bool saveAnalog = false;

/**
* Potentiometer value for zero speed (counterclockwise limit)
Expand Down
3 changes: 3 additions & 0 deletions software/esp-firmware/throttleHandling.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
#ifndef _THROTTLE_HANDLING_H_
#define _THROTTLE_HANDLING_H_

//sloeber>> #include <WString.h> // class String
//sloeber>> #include <esp32-hal-log.h> // log_d()

#define LED_STOP 14
#define LED_FWD 39
#define LED_REV 15
Expand Down
23 changes: 19 additions & 4 deletions software/esp-firmware/wifi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
* as providing a webserver for configuration of the device and status readout.
*/

//sloeber>> #include <string.h> // strndup(), strdup(), strcmp()
#include <WiFi.h>
#include <WiFiMulti.h>
#include <WiFiClient.h>
Expand All @@ -29,7 +30,7 @@
#include <AsyncUDP.h>

#include "wifi.h"
#include "locoHandling.h"
#include "locoHandling.h" // MODES, MODES_LENGTH
#include "config.h"
#include "lowbat.h"
#include "stateMachine.h"
Expand Down Expand Up @@ -58,7 +59,7 @@ void handleWiFi(void)
switch(wiFredState)
{
case STATE_CONFIG_AP:
dnsServer.processNextRequest();
dnsServer.processNextRequest(); // @suppress("No break at end of case")
// intentional fall-through

case STATE_CONNECTED:
Expand Down Expand Up @@ -220,7 +221,7 @@ void writeMainPage()
free(locoServer.name);
locoServer.name = strdup(server.arg("loco.serverName").c_str());
locoServer.port = server.arg("loco.serverPort").toInt();
locoServer.automatic = server.hasArg("loco.automatic");
locoServer.automatic = server.hasArg("loco.automatic"); //sloeber>> hasArg(String("loco.automatic")) makes sloeber happy

if(!locoServer.automatic)
{
Expand All @@ -237,6 +238,7 @@ void writeMainPage()
if(server.hasArg (String("loco.address") + i+1) )
{
locos[i].address = server.arg(String("loco.address") + i+1).toInt();
locos[i].mode = strdup(server.arg(String("loco.mode") + i+1).c_str());
locos[i].longAddress = server.hasArg(String("loco.longAddress") + i+1);
locos[i].direction = (eDirection) server.arg(String("loco.direction") + i+1).toInt();
saveLocoConfig(i);
Expand All @@ -247,6 +249,7 @@ void writeMainPage()
if(loco >= 1 && loco <= 4 && server.hasArg("loco.address"))
{
locos[loco-1].address = server.arg("loco.address").toInt();
locos[loco-1].mode = strdup(server.arg("loco.mode").c_str());
locos[loco-1].longAddress = server.hasArg("loco.longAddress");
locos[loco-1].direction = (eDirection) server.arg("loco.direction").toInt();
saveLocoConfig(loco-1);
Expand Down Expand Up @@ -375,7 +378,7 @@ void writeMainPage()
}

String resp = String("<!DOCTYPE HTML>\r\n")
+ "<html><head><title>wiFred configuration page</title></head>\r\n"
+ "<html lang=\"en\"><head><meta charset=\"utf-8\"><title>wiFred configuration page</title></head>\r\n"
+ "<body><h1>wiFred configuration page</h1>\r\n"
+ "<hr>General configuration and status<hr>\r\n"
+ "<form action=\"index.html\" method=\"get\"><table border=0>"
Expand All @@ -394,6 +397,17 @@ void writeMainPage()
resp += String("<hr>Loco configuration for loco: ") + (i+1) + "\r\n"
+ "<form action=\"index.html\" method=\"get\"><table border=0>"
+ "<tr><td>DCC address: (-1 to disable)</td> <td><input type=\"text\" name=\"loco.address\" value=\"" + locos[i].address + "\"></td></tr>"
+ "<tr><td>Speed Step Mode: </td> <td><select name='loco.mode'>";
for(int j=0; j<MODES_LENGTH; ++j)
{
resp += String("<option value=\"") + MODES[j].val + "\"";
if( strcmp(MODES[j].val, locos[i].mode) == 0 )
{
resp += String(" selected");
}
resp += String(">") + MODES[j].val + " - "+ MODES[j].text + "</option>";
}
resp += String("</select></td></tr>")
+ "<tr><td>Direction:</td><td>"
+ "<input type=\"radio\" name=\"loco.direction\" value=\"" + DIR_NORMAL + "\"" + (locos[i].direction == DIR_NORMAL ? " checked" : "" ) + ">Forward"
+ "<input type=\"radio\" name=\"loco.direction\" value=\"" + DIR_REVERSE + "\"" + (locos[i].direction == DIR_REVERSE ? " checked" : "" ) + ">Reverse"
Expand Down Expand Up @@ -651,6 +665,7 @@ void getConfigXML()
{
resp += " <LOCO ID=\"" + String(i+1) + "\">\r\n"
+ " <DCCadress value=\""+ locos[i].address + "\"/>\r\n"
+ " <Mode value=\""+ locos[i].mode + "\" />\r\n"
+ " <Direction value=\""+ locos[i].direction + "\" />\r\n"
+ " <LongAdress value=\""+ locos[i].longAddress + "\" />\r\n"
+ " <FUNCTIONS>\r\n" ;
Expand Down

0 comments on commit d0f4808

Please sign in to comment.