1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-11-23 08:06:13 +01:00

Alter Stream to Print

In prep for Wifi siolution, all output  functions changed to expect Print class instead of Stream... Can still pass Serial1 etc because Stream extends Print, but this allows for an output-only class extending Print to collect a response buffer for Wifi sending with AT commands.
This commit is contained in:
Asbelos 2020-06-12 14:28:35 +01:00
parent e769361c26
commit e0c76a9dc4
14 changed files with 114 additions and 113 deletions

View File

@ -24,7 +24,7 @@ DCCEXParser wifiParser;
void setup() {
Serial.begin(115200);
DCC::begin();
// if (WIFI_PORT>0) WifiInterface::setup();
if (WIFI_PORT>0) WifiInterface::setup();
DIAG(F("\n===== CVReader demonstrating DCC::getLocoId() call ==========\n"));
DCC::getLocoId(myCallback); // myCallback will be called with the result
DIAG(F("\n===== DCC::getLocoId has returned, but wont be executed until we are in loop() ======\n"));
@ -36,9 +36,5 @@ void loop() {
// This line passes input on Serial to the DCCEXParser
serialParser.loop(Serial);
if (WIFI_PORT>0) {
// wifiParser=WifiInterface::getSingleClient(wifiParser);
// if (wifiParser) wifiParser->loop();
}
if (WIFI_PORT>0) WifiInterface::loop(wifiParser);
}

View File

@ -1,7 +1,7 @@
#ifndef Config_h
#define Config_h
const int WIFI_PORT = 0; // OR set to zero for no wifi
const int WIFI_PORT = 99; // OR set to zero for no wifi
const char WIFI_SSID[] = "BTHub5-M6PT"; // your network SSID (name)
const char WIFI_PASS[] = "49de8d4862"; // your network password
const long WIFI_BAUD_RATE=115200;

View File

@ -14,7 +14,7 @@ const char VERSION[]="99.666";
int DCCEXParser::stashP[MAX_PARAMS];
bool DCCEXParser::stashBusy;
Stream & DCCEXParser::stashStream=Serial; // keep compiler happy but ovevride in constructor
Print & DCCEXParser::stashStream=Serial; // keep compiler happy but ovevride in constructor
// This is a JMRI command parser, one instance per incoming stream
// It doesnt know how the string got here, nor how it gets back.
@ -23,14 +23,17 @@ bool DCCEXParser::stashBusy;
// Non-DCC things like turnouts, pins and sensors are handled in additional JMRI interface classes.
DCCEXParser::DCCEXParser() {}
void DCCEXParser::loop(Stream & stream) {
//DIAG(F("\nDCCEXParser Loop in %d "),stream.available());
while(stream.available()) {
if (bufferLength==MAX_BUFFER) {
void DCCEXParser::flush() {
DIAG(F("\nBuffer flush"));
bufferLength=0;
inCommandPayload=false;
}
void DCCEXParser::loop(Stream & stream) {
while(stream.available()) {
if (bufferLength==MAX_BUFFER) {
flush();
}
char ch = stream.read();
if (ch == '<') {
inCommandPayload = true;
@ -46,7 +49,6 @@ void DCCEXParser::loop(Stream & stream) {
buffer[bufferLength++]= ch;
}
}
//DIAG(F(" out\n"));
}
int DCCEXParser::splitValues( int result[MAX_PARAMS]) {
@ -93,7 +95,8 @@ void DCCEXParser::loop(Stream & stream) {
}
// See documentation on DCC class for info on this section
void DCCEXParser::parse(Stream & stream, const char *com) {
void DCCEXParser::parse(Print & stream, const char *com) {
// DIAG(F("\nPARSING:%s\n"),com);
(void) EEPROM; // tell compiler not to warn thi is unused
int p[MAX_PARAMS];
int params=splitValues(p);
@ -173,8 +176,8 @@ void DCCEXParser::parse(Stream & stream, const char *com) {
break;
case 's': // <s>
StringFormatter::send(stream,F("<iDCC-Asbelos BASE STATION FOR ARDUINO / %s: V-%s %s/%s\n>"), BOARD_NAME, VERSION, __DATE__, __TIME__ );
// TODO send power status
StringFormatter::send(stream,F("<p%d>"),DCCWaveform::mainTrack.getPowerMode()==POWERMODE::ON );
StringFormatter::send(stream,F("<iDCC-Asbelos BASE STATION FOR ARDUINO / %s: V-%s %s/%s>"), BOARD_NAME, VERSION, __DATE__, __TIME__ );
// TODO Send stats of speed reminders table
// TODO send status of turnouts etc etc
return;
@ -202,7 +205,7 @@ void DCCEXParser::parse(Stream & stream, const char *com) {
StringFormatter::send(stream, F("<X>"));
}
bool DCCEXParser::parseZ( Stream & stream,int params, int p[]){
bool DCCEXParser::parseZ( Print & stream,int params, int p[]){
switch (params) {
@ -233,7 +236,7 @@ bool DCCEXParser::parseZ( Stream & stream,int params, int p[]){
//===================================
bool DCCEXParser::parseT(Stream & stream, int params, int p[]) {
bool DCCEXParser::parseT(Print & stream, int params, int p[]) {
switch(params){
case 0: // <T>
return (Turnout::showAll(stream)); break;
@ -258,7 +261,7 @@ bool DCCEXParser::parseT(Stream & stream, int params, int p[]) {
}
}
bool DCCEXParser::parseS( Stream & stream,int params, int p[]) {
bool DCCEXParser::parseS( Print & stream,int params, int p[]) {
switch(params){
@ -282,7 +285,7 @@ bool DCCEXParser::parseS( Stream & stream,int params, int p[]) {
// CALLBACKS must be static
bool DCCEXParser::stashCallback(Stream & stream,int p[MAX_PARAMS]) {
bool DCCEXParser::stashCallback(Print & stream,int p[MAX_PARAMS]) {
if (stashBusy) return false;
stashBusy=true;
stashStream=stream;

View File

@ -4,26 +4,26 @@ struct DCCEXParser
{
DCCEXParser();
void loop(Stream & pstream);
void flush();
private:
static const int MAX_PARAMS=10; // longest command sent in
static const int MAX_BUFFER=50; // longest command sent in
Stream & stream;
byte bufferLength=0;
bool inCommandPayload=false;
char buffer[MAX_BUFFER+2];
int splitValues( int result[MAX_PARAMS]);
void parse(Stream & stream, const char * command);
void parse(Print & stream, const char * command);
bool parseT(Stream & stream, int params, int p[]);
bool parseZ(Stream & stream, int params, int p[]);
bool parseS(Stream & stream, int params, int p[]);
bool parseT(Print & stream, int params, int p[]);
bool parseZ(Print & stream, int params, int p[]);
bool parseS(Print & stream, int params, int p[]);
static bool stashBusy;
static Stream & stashStream;
static Print & stashStream;
static int stashP[MAX_PARAMS];
static bool stashCallback(Stream & stream, int p[MAX_PARAMS]);
static bool stashCallback(Print & stream, int p[MAX_PARAMS]);
static void callback_W(int result);
static void callback_B(int result);
static void callback_R(int result);

View File

@ -102,7 +102,7 @@ bool Output::remove(int n){
///////////////////////////////////////////////////////////////////////////////
bool Output::showAll(Stream & stream){
bool Output::showAll(Print & stream){
bool gotone=false;
for(Output * tt=firstOutput;tt!=NULL;tt=tt->nextOutput){
gotone=true;
@ -111,7 +111,7 @@ bool Output::showAll(Stream & stream){
return gotone;
}
void Output::show(Stream & stream){
void Output::show(Print & stream){
for(Output * tt=firstOutput;tt!=NULL;tt=tt->nextOutput){
StringFormatter::send(stream,F("<Y %d %d>"), tt->data.id, tt->data.oStatus);
}

View File

@ -18,8 +18,8 @@ class Output{
static void load();
static void store();
static Output *create(int, int, int, int=0);
static void show(Stream & stream);
static bool showAll(Stream & stream);
static void show(Print & stream);
static bool showAll(Print & stream);
private:
static Output *firstOutput;

View File

@ -54,7 +54,7 @@ decide to ignore the <q ID> return and only react to <Q ID> triggers.
///////////////////////////////////////////////////////////////////////////////
void Sensor::check(Stream & stream){
void Sensor::check(Print & stream){
Sensor *tt;
for(tt=firstSensor;tt!=NULL;tt=tt->nextSensor){
@ -129,7 +129,7 @@ bool Sensor::remove(int n){
///////////////////////////////////////////////////////////////////////////////
void Sensor::show(Stream & stream){
void Sensor::show(Print & stream){
for(Sensor * tt=firstSensor;tt!=NULL;tt=tt->nextSensor){
StringFormatter::send(stream, F("<Q %d %d %d>"), tt->data.snum, tt->data.pin, tt->data.pullUp);
}
@ -137,7 +137,7 @@ void Sensor::show(Stream & stream){
///////////////////////////////////////////////////////////////////////////////
void Sensor::status(Stream & stream){
void Sensor::status(Print & stream){
for(Sensor * tt=firstSensor;tt!=NULL;tt=tt->nextSensor){
StringFormatter::send(stream,F("<%s %d>"), tt->active?"Q":"q", tt->data.snum);
}

View File

@ -22,9 +22,9 @@ struct Sensor{
static Sensor *create(int, int, int);
static Sensor* get(int);
static bool remove(int);
static void show(Stream & stream);
static void status(Stream & stream);
static void check(Stream & stream);
static void show(Print & stream);
static void status(Print & stream);
static void check(Print & stream);
}; // Sensor
#endif

View File

@ -8,13 +8,13 @@ void StringFormatter::print( const __FlashStringHelper* input...) {
send(Serial,input,args);
}
void StringFormatter::send(Stream & stream, const __FlashStringHelper* input...) {
void StringFormatter::send(Print & stream, const __FlashStringHelper* input...) {
va_list args;
va_start(args, input);
send(stream,input,args);
}
void StringFormatter::send(Stream & stream,const __FlashStringHelper* format, va_list args) {
void StringFormatter::send(Print & stream,const __FlashStringHelper* format, va_list args) {
// thanks to Jan Turoň https://arduino.stackexchange.com/questions/56517/formatting-strings-in-arduino-for-output
@ -27,6 +27,7 @@ void StringFormatter::send(Stream & stream,const __FlashStringHelper* format, va
c=pgm_read_byte_near(flash+i);
switch(c) {
case '%': stream.print('%'); break;
case 'c': stream.print((char) va_arg(args, int)); break;
case 's': stream.print(va_arg(args, char*)); break;
case 'd': stream.print(va_arg(args, int), DEC); break;
case 'b': stream.print(va_arg(args, int), BIN); break;

View File

@ -6,9 +6,9 @@ class StringFormatter
public:
static int parse(const char * com, int result[], byte maxResults);
static void print( const __FlashStringHelper* input...);
static void send(Stream & serial, const __FlashStringHelper* input...);
static void send(Print & serial, const __FlashStringHelper* input...);
private:
static void send(Stream & serial, const __FlashStringHelper* input,va_list args);
static void send(Print & serial, const __FlashStringHelper* input,va_list args);
};

View File

@ -40,7 +40,7 @@ bool Turnout::remove(int n){
///////////////////////////////////////////////////////////////////////////////
void Turnout::show(Stream & stream, int n){
void Turnout::show(Print & stream, int n){
for(Turnout *tt=firstTurnout;tt!=NULL;tt=tt->nextTurnout){
if (tt->data.id==n) {
StringFormatter::send(stream,F("<H %d %d>"), tt->data.id, tt->data.tStatus);
@ -49,7 +49,7 @@ void Turnout::show(Stream & stream, int n){
}
}
bool Turnout::showAll(Stream & stream){
bool Turnout::showAll(Print & stream){
bool gotOne=false;
for(Turnout * tt=firstTurnout;tt!=NULL;tt=tt->nextTurnout){
StringFormatter::send(stream,F("<H %d %d %d %d>"), tt->data.id, tt->data.address, tt->data.subAddress, tt->data.tStatus);

View File

@ -22,8 +22,8 @@ struct Turnout{
static void load();
static void store();
static Turnout *create(int, int, int);
static void show(Stream & stream, int n);
static bool showAll(Stream & stream);
static void show(Print & stream, int n);
static bool showAll(Print & stream);
}; // Turnout
#endif

View File

@ -1,49 +1,49 @@
//
//#include "WifiInterface.h"
//#include "Config.h"
//#include "DIAG.h"
//
//
//WiFiEspServer WifiInterface::server(WIFI_PORT);
//
//bool WifiInterface::connected=false;
//
//void WifiInterface::setup()
//{
// Serial1.begin(WIFI_BAUD_RATE); // initialize serial for ESP module
// WiFi.init(&Serial1); // initialize ESP module
//
// // check for the presence of the shield
// if (WiFi.status() == WL_NO_SHIELD) {
// Serial.println("WiFi shield not present");
// return;
// }
//
// // attempt to connect to WiFi network
// int status = WL_IDLE_STATUS;
// for (int retries=0;status != WL_CONNECTED && retries<WIFI_CONNECT_RETRIES; retries++) {
// DIAG(F("\nAttempting to connect to WPA SSID: %s\n"),WIFI_SSID);
// delay(100);
// status = WiFi.begin(WIFI_SSID, WIFI_PASS);
// }
//
// if (status==WL_CONNECTED) {
// connected=true;
//
//
// // start the web server on port WIFI_PORT
// server.begin();
//
// // print the SSID of the network you're attached to
// DIAG(F("SSID: %s IP=%s "), WiFi.SSID(), WiFi.localIP());
// }
//}
//
//
//void WifiInterface::loop(DCCEXParser * parser) {
// if (!connected) return existing;
// if (!client) return existing;
// DIAG(F("\nnew Wifi Client connected %s \n"),client.remoteIP());
// if (existing) delete existing;
// return new DCCEXParser(client);
//}
#include "WifiInterface.h"
#include "Config.h"
#include "DIAG.h"
WiFiEspServer WifiInterface::server(WIFI_PORT);
WiFiEspClient WifiInterface::client;
bool WifiInterface::haveClient=false;
bool WifiInterface::connected=false;
void WifiInterface::setup()
{
Serial1.begin(WIFI_BAUD_RATE); // initialize serial for ESP module
WiFi.init(&Serial1); // initialize ESP module
// check for the presence of the shield
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
return;
}
// attempt to connect to WiFi network
int status = WiFi.begin(WIFI_SSID, WIFI_PASS);
if (status==WL_CONNECTED) {
connected=true;
// start the server on port WIFI_PORT
server.begin();
// print the SSID of the network you're attached to
DIAG(F("\nWifi Connected SSID: %s IP=%d.%d.%d.%d port %d\n "),
WiFi.SSID(), WiFi.localIP()[0],WiFi.localIP()[1],WiFi.localIP()[2],WiFi.localIP()[3],WIFI_PORT);
}
}
void WifiInterface::loop(DCCEXParser & parser) {
if (!connected) return;
WiFiEspClient xclient= server.available(); // listen for incoming clients
if (xclient.connected()) {
DIAG(F("\nNew Wifi Client connected\n"));
parser.loop(xclient);
xclient.stop();
}
}

View File

@ -1,19 +1,20 @@
//
//#ifndef WifiInterface_h
//#define WifiInterface_h
//#include <WiFiEsp.h>
//#include "DCCEXParser.h"
//
//class WifiInterface {
//
// public:
// static void setup();
// static DCCEXParser * getSingleClient(DCCEXParser * existing);
//
// private:
// static WiFiEspServer server;
// static bool connected;
//};
//
//#endif
//
#ifndef WifiInterface_h
#define WifiInterface_h
#include <WiFiEsp.h>
#include "DCCEXParser.h"
class WifiInterface {
public:
static void setup();
static void loop(DCCEXParser & parser);
private:
static WiFiEspServer server;
static WiFiEspClient client;
static bool connected;
static bool haveClient;
};
#endif