mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2025-03-14 18:13:09 +01:00
Merge branch 'TM_nofloat' into TM-mergetest
This commit is contained in:
commit
7fba96417f
@ -30,16 +30,29 @@
|
|||||||
#include "DCC.h"
|
#include "DCC.h"
|
||||||
#include "TrackManager.h"
|
#include "TrackManager.h"
|
||||||
|
|
||||||
#if defined(BIG_MEMORY) | defined(WIFI_ON) | defined(ETHERNET_ON)
|
|
||||||
// This section of CommandDistributor is simply not relevant on a uno or similar
|
|
||||||
const byte NO_CLIENT=255;
|
|
||||||
|
|
||||||
RingStream * CommandDistributor::ring=0;
|
#ifdef BIG_RAM
|
||||||
byte CommandDistributor::ringClient=NO_CLIENT;
|
// use a buffer to allow broadcast
|
||||||
CommandDistributor::clientType CommandDistributor::clients[8]={
|
#define BUFFER broadcastBufferWriter
|
||||||
NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE};
|
#define FLUSH broadcastBufferWriter->flush();
|
||||||
RingStream * CommandDistributor::broadcastBufferWriter=new RingStream(100);
|
#define SHOVE(type) broadcastToClients(type);
|
||||||
|
StringBuffer * CommandDistributor::broadcastBufferWriter=new StringBuffer();
|
||||||
|
#else
|
||||||
|
// on a UNO/NANO write direct to Serial and ignore flush/shove
|
||||||
|
#define BUFFER &Serial
|
||||||
|
#define FLUSH
|
||||||
|
#define SHOVE(type)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CD_HANDLE_RING
|
||||||
|
// wifi or ethernet ring streams with multiple client types
|
||||||
|
RingStream * CommandDistributor::ring=0;
|
||||||
|
byte CommandDistributor::ringClient=NO_CLIENT;
|
||||||
|
CommandDistributor::clientType CommandDistributor::clients[8]={
|
||||||
|
NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE};
|
||||||
|
|
||||||
|
// Parse is called by Withrottle or Ethernet interface to determine which
|
||||||
|
// protocol the client is using and call the appropriate part of dcc++Ex
|
||||||
void CommandDistributor::parse(byte clientId,byte * buffer, RingStream * stream) {
|
void CommandDistributor::parse(byte clientId,byte * buffer, RingStream * stream) {
|
||||||
ring=stream;
|
ring=stream;
|
||||||
ringClient=stream->peekTargetMark();
|
ringClient=stream->peekTargetMark();
|
||||||
@ -56,15 +69,15 @@ void CommandDistributor::parse(byte clientId,byte * buffer, RingStream * stream
|
|||||||
void CommandDistributor::forget(byte clientId) {
|
void CommandDistributor::forget(byte clientId) {
|
||||||
clients[clientId]=NONE_TYPE;
|
clients[clientId]=NONE_TYPE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// This will not be called on a uno
|
||||||
void CommandDistributor::broadcast(bool includeWithrottleClients) {
|
void CommandDistributor::broadcastToClients(clientType type) {
|
||||||
broadcastBufferWriter->write((byte)'\0');
|
|
||||||
|
|
||||||
/* Boadcast to Serials */
|
/* Boadcast to Serials */
|
||||||
SerialManager::broadcast(broadcastBufferWriter);
|
if (type==COMMAND_TYPE) SerialManager::broadcast(broadcastBufferWriter->getString());
|
||||||
|
|
||||||
#if defined(WIFI_ON) | defined(ETHERNET_ON)
|
#ifdef CD_HANDLE_RING
|
||||||
// If we are broadcasting from a wifi/eth process we need to complete its output
|
// If we are broadcasting from a wifi/eth process we need to complete its output
|
||||||
// before merging broadcasts in the ring, then reinstate it in case
|
// before merging broadcasts in the ring, then reinstate it in case
|
||||||
// the process continues to output to its client.
|
// the process continues to output to its client.
|
||||||
@ -72,49 +85,46 @@ void CommandDistributor::broadcast(bool includeWithrottleClients) {
|
|||||||
|
|
||||||
/* loop through ring clients */
|
/* loop through ring clients */
|
||||||
for (byte clientId=0; clientId<sizeof(clients); clientId++) {
|
for (byte clientId=0; clientId<sizeof(clients); clientId++) {
|
||||||
if (clients[clientId]==NONE_TYPE) continue;
|
if (clients[clientId]==type) {
|
||||||
if ( clients[clientId]==WITHROTTLE_TYPE && !includeWithrottleClients) continue;
|
ring->mark(clientId);
|
||||||
ring->mark(clientId);
|
ring->print(broadcastBufferWriter->getString());
|
||||||
broadcastBufferWriter->printBuffer(ring);
|
ring->commit();
|
||||||
ring->commit();
|
}
|
||||||
}
|
}
|
||||||
if (ringClient!=NO_CLIENT) ring->mark(ringClient);
|
if (ringClient!=NO_CLIENT) ring->mark(ringClient);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
broadcastBufferWriter->flush();
|
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
// For a UNO/NANO we can broadcast direct to just one Serial instead of the ring
|
|
||||||
// Redirect ring output ditrect to Serial
|
|
||||||
#define broadcastBufferWriter &Serial
|
|
||||||
// and ignore the internal broadcast call.
|
|
||||||
void CommandDistributor::broadcast(bool includeWithrottleClients) {
|
|
||||||
(void)includeWithrottleClients;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
// Public broadcast functions below
|
||||||
void CommandDistributor::broadcastSensor(int16_t id, bool on ) {
|
void CommandDistributor::broadcastSensor(int16_t id, bool on ) {
|
||||||
StringFormatter::send(broadcastBufferWriter,F("<%c %d>\n"), on?'Q':'q', id);
|
FLUSH
|
||||||
broadcast(false);
|
StringFormatter::send(BUFFER,F("<%c %d>\n"), on?'Q':'q', id);
|
||||||
|
SHOVE(COMMAND_TYPE)
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandDistributor::broadcastTurnout(int16_t id, bool isClosed ) {
|
void CommandDistributor::broadcastTurnout(int16_t id, bool isClosed ) {
|
||||||
// For DCC++ classic compatibility, state reported to JMRI is 1 for thrown and 0 for closed;
|
// For DCC++ classic compatibility, state reported to JMRI is 1 for thrown and 0 for closed;
|
||||||
// The string below contains serial and Withrottle protocols which should
|
// The string below contains serial and Withrottle protocols which should
|
||||||
// be safe for both types.
|
// be safe for both types.
|
||||||
StringFormatter::send(broadcastBufferWriter,F("<H %d %d>\n"),id, !isClosed);
|
FLUSH
|
||||||
#if defined(WIFI_ON) | defined(ETHERNET_ON)
|
StringFormatter::send(BUFFER,F("<H %d %d>\n"),id, !isClosed);
|
||||||
StringFormatter::send(broadcastBufferWriter,F("PTA%c%d\n"), isClosed?'2':'4', id);
|
SHOVE(COMMAND_TYPE)
|
||||||
|
|
||||||
|
#ifdef CD_HANDLE_RING
|
||||||
|
FLUSH
|
||||||
|
StringFormatter::send(BUFFER,F("PTA%c%d\n"), isClosed?'2':'4', id);
|
||||||
|
SHOVE(WITHROTTLE_TYPE)
|
||||||
#endif
|
#endif
|
||||||
broadcast(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandDistributor::broadcastLoco(byte slot) {
|
void CommandDistributor::broadcastLoco(byte slot) {
|
||||||
DCC::LOCO * sp=&DCC::speedTable[slot];
|
DCC::LOCO * sp=&DCC::speedTable[slot];
|
||||||
StringFormatter::send(broadcastBufferWriter,F("<l %d %d %d %l>\n"),
|
FLUSH
|
||||||
|
StringFormatter::send(BUFFER,F("<l %d %d %d %l>\n"),
|
||||||
sp->loco,slot,sp->speedCode,sp->functions);
|
sp->loco,slot,sp->speedCode,sp->functions);
|
||||||
broadcast(false);
|
SHOVE(COMMAND_TYPE)
|
||||||
#if defined(WIFI_ON) | defined(ETHERNET_ON)
|
#ifdef CD_HANDLE_RING
|
||||||
WiThrottle::markForBroadcast(sp->loco);
|
WiThrottle::markForBroadcast(sp->loco);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -130,14 +140,24 @@ void CommandDistributor::broadcastPower() {
|
|||||||
else if (main) reason=F(" MAIN");
|
else if (main) reason=F(" MAIN");
|
||||||
else if (prog) reason=F(" PROG");
|
else if (prog) reason=F(" PROG");
|
||||||
else state='0';
|
else state='0';
|
||||||
|
FLUSH
|
||||||
StringFormatter::send(broadcastBufferWriter,
|
StringFormatter::send(BUFFER,F("<p %c%S>\n"),state,reason);
|
||||||
F("<p%c%S>\nPPA%c\n"),state,reason, main?'1':'0');
|
SHOVE(COMMAND_TYPE)
|
||||||
LCD(2,F("Power %S%S"),state=='1'?F("On"):F("Off"),reason);
|
#ifdef CD_HANDLE_RING
|
||||||
broadcast(true);
|
FLUSH
|
||||||
|
StringFormatter::send(BUFFER,F("PPA%c\n"), main?'1':'0');
|
||||||
|
SHOVE(WITHROTTLE_TYPE)
|
||||||
|
#endif
|
||||||
|
LCD(2,F("Power %S%S"),state=='1'?F("On"):F("Off"),reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandDistributor::broadcastText(const FSH * msg) {
|
void CommandDistributor::broadcastText(const FSH * msg) {
|
||||||
StringFormatter::send(broadcastBufferWriter,F("%S"),msg);
|
FLUSH
|
||||||
broadcast(false);
|
StringFormatter::send(BUFFER,F("%S"),msg);
|
||||||
|
SHOVE(COMMAND_TYPE)
|
||||||
|
#ifdef CD_HANDLE_RING
|
||||||
|
FLUSH
|
||||||
|
StringFormatter::send(BUFFER,F("Hm%S\n"), msg);
|
||||||
|
SHOVE(WITHROTTLE_TYPE)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,13 @@
|
|||||||
#define CommandDistributor_h
|
#define CommandDistributor_h
|
||||||
#include "DCCEXParser.h"
|
#include "DCCEXParser.h"
|
||||||
#include "RingStream.h"
|
#include "RingStream.h"
|
||||||
|
#include "StringBuffer.h"
|
||||||
|
#include "defines.h"
|
||||||
|
|
||||||
|
#if WIFI_ON | ETHERNET_ON
|
||||||
|
// Command Distributor must handle a RingStream of clients
|
||||||
|
#define CD_HANDLE_RING
|
||||||
|
#endif
|
||||||
|
|
||||||
class CommandDistributor {
|
class CommandDistributor {
|
||||||
|
|
||||||
@ -35,14 +42,15 @@ public :
|
|||||||
static void broadcastText(const FSH * msg);
|
static void broadcastText(const FSH * msg);
|
||||||
static void forget(byte clientId);
|
static void forget(byte clientId);
|
||||||
private:
|
private:
|
||||||
static void broadcast(bool includeWithrottleClients);
|
enum clientType: byte {NONE_TYPE,COMMAND_TYPE,WITHROTTLE_TYPE};
|
||||||
static RingStream * ring;
|
static void broadcastToClients(clientType type);
|
||||||
static RingStream * broadcastBufferWriter;
|
static StringBuffer * broadcastBufferWriter;
|
||||||
static byte ringClient;
|
#ifdef CD_HANDLE_RING
|
||||||
|
static RingStream * ring;
|
||||||
// each bit in broadcastlist = 1<<clientid
|
static const byte NO_CLIENT=255;
|
||||||
enum clientType: byte {NONE_TYPE,COMMAND_TYPE,WITHROTTLE_TYPE};
|
static byte ringClient;
|
||||||
static clientType clients[8];
|
static clientType clients[8];
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1 +1 @@
|
|||||||
#define GITHUB_SHA "TM-PORTX-20220611"
|
#define GITHUB_SHA "TM-PORTX-20220611-1"
|
||||||
|
@ -88,16 +88,23 @@ MotorDriver::MotorDriver(VPIN power_pin, byte signal_pin, byte signal_pin2, int8
|
|||||||
pinMode(faultPin, INPUT);
|
pinMode(faultPin, INPUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
senseFactor=sense_factor;
|
// This conversion performed at compile time so the remainder of the code never needs
|
||||||
|
// float calculations or libraray code.
|
||||||
|
senseFactorInternal=sense_factor * senseScale;
|
||||||
tripMilliamps=trip_milliamps;
|
tripMilliamps=trip_milliamps;
|
||||||
rawCurrentTripValue=(int)(trip_milliamps / sense_factor);
|
rawCurrentTripValue=mA2raw(trip_milliamps);
|
||||||
|
|
||||||
if (currentPin==UNUSED_PIN)
|
if (currentPin==UNUSED_PIN)
|
||||||
DIAG(F("MotorDriver ** WARNING ** No current or short detection"));
|
DIAG(F("MotorDriver ** WARNING ** No current or short detection"));
|
||||||
else
|
else {
|
||||||
DIAG(F("MotorDriver currentPin=A%d, senseOffset=%d, rawCurrentTripValue(relative to offset)=%d"),
|
DIAG(F("MotorDriver currentPin=A%d, senseOffset=%d, rawCurrentTripValue(relative to offset)=%d"),
|
||||||
currentPin-A0, senseOffset,rawCurrentTripValue);
|
currentPin-A0, senseOffset,rawCurrentTripValue);
|
||||||
|
|
||||||
|
// self testing diagnostic for the non-float converters... may be removed when happy
|
||||||
|
// DIAG(F("senseFactorInternal=%d raw2mA(1000)=%d mA2Raw(1000)=%d"),
|
||||||
|
// senseFactorInternal, raw2mA(1000),mA2raw(1000));
|
||||||
|
}
|
||||||
|
|
||||||
// prepare values for current detection
|
// prepare values for current detection
|
||||||
sampleDelay = 0;
|
sampleDelay = 0;
|
||||||
lastSampleTaken = millis();
|
lastSampleTaken = millis();
|
||||||
@ -213,10 +220,10 @@ int MotorDriver::getCurrentRawInInterrupt() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned int MotorDriver::raw2mA( int raw) {
|
unsigned int MotorDriver::raw2mA( int raw) {
|
||||||
return (unsigned int)(raw * senseFactor);
|
return (int32_t)raw * senseFactorInternal / senseScale;
|
||||||
}
|
}
|
||||||
int MotorDriver::mA2raw( unsigned int mA) {
|
unsigned int MotorDriver::mA2raw( unsigned int mA) {
|
||||||
return (int)(mA / senseFactor);
|
return (int32_t)mA * senseScale / senseFactorInternal;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MotorDriver::getFastPin(const FSH* type,int pin, bool input, FASTPIN & result) {
|
void MotorDriver::getFastPin(const FSH* type,int pin, bool input, FASTPIN & result) {
|
||||||
|
@ -113,9 +113,9 @@ class MotorDriver {
|
|||||||
virtual int getCurrentRaw();
|
virtual int getCurrentRaw();
|
||||||
virtual int getCurrentRawInInterrupt();
|
virtual int getCurrentRawInInterrupt();
|
||||||
virtual unsigned int raw2mA( int raw);
|
virtual unsigned int raw2mA( int raw);
|
||||||
virtual int mA2raw( unsigned int mA);
|
|
||||||
inline bool brakeCanPWM() {
|
inline bool brakeCanPWM() {
|
||||||
return ((brakePin!=UNUSED_PIN) && (digitalPinToTimer(brakePin)));
|
return ((brakePin!=UNUSED_PIN) && (digitalPinToTimer(brakePin)));
|
||||||
|
virtual unsigned int mA2raw( unsigned int mA);
|
||||||
}
|
}
|
||||||
inline int getRawCurrentTripValue() {
|
inline int getRawCurrentTripValue() {
|
||||||
return rawCurrentTripValue;
|
return rawCurrentTripValue;
|
||||||
@ -142,7 +142,14 @@ class MotorDriver {
|
|||||||
FASTPIN fastSignalPin, fastSignalPin2, fastBrakePin,fastFaultPin;
|
FASTPIN fastSignalPin, fastSignalPin2, fastBrakePin,fastFaultPin;
|
||||||
bool dualSignal; // true to use signalPin2
|
bool dualSignal; // true to use signalPin2
|
||||||
bool invertBrake; // brake pin passed as negative means pin is inverted
|
bool invertBrake; // brake pin passed as negative means pin is inverted
|
||||||
float senseFactor;
|
|
||||||
|
// Raw to milliamp conversion factors avoiding float data types.
|
||||||
|
// Milliamps=rawADCreading * sensefactorInternal / senseScale
|
||||||
|
//
|
||||||
|
// senseScale is chosen as 256 to give enough scale for 2 decimal place
|
||||||
|
// raw->mA conversion with an ultra fast optimised integer multiplication
|
||||||
|
int senseFactorInternal; // set to senseFactor * senseScale
|
||||||
|
static const int senseScale=256;
|
||||||
int senseOffset;
|
int senseOffset;
|
||||||
unsigned int tripMilliamps;
|
unsigned int tripMilliamps;
|
||||||
int rawCurrentTripValue;
|
int rawCurrentTripValue;
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "SerialManager.h"
|
#include "SerialManager.h"
|
||||||
#include "DCCEXParser.h"
|
#include "DCCEXParser.h"
|
||||||
|
|
||||||
SerialManager * SerialManager::first=NULL;
|
SerialManager * SerialManager::first=NULL;
|
||||||
|
|
||||||
SerialManager::SerialManager(Stream * myserial) {
|
SerialManager::SerialManager(Stream * myserial) {
|
||||||
@ -49,11 +50,11 @@ void SerialManager::init() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerialManager::broadcast(RingStream * ring) {
|
void SerialManager::broadcast(char * stringBuffer) {
|
||||||
for (SerialManager * s=first;s;s=s->next) s->broadcast2(ring);
|
for (SerialManager * s=first;s;s=s->next) s->broadcast2(stringBuffer);
|
||||||
}
|
}
|
||||||
void SerialManager::broadcast2(RingStream * ring) {
|
void SerialManager::broadcast2(char * stringBuffer) {
|
||||||
ring->printBuffer(serial);
|
serial->print(stringBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerialManager::loop() {
|
void SerialManager::loop() {
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "RingStream.h"
|
|
||||||
|
|
||||||
#ifndef COMMAND_BUFFER_SIZE
|
#ifndef COMMAND_BUFFER_SIZE
|
||||||
#define COMMAND_BUFFER_SIZE 100
|
#define COMMAND_BUFFER_SIZE 100
|
||||||
@ -33,13 +33,13 @@ class SerialManager {
|
|||||||
public:
|
public:
|
||||||
static void init();
|
static void init();
|
||||||
static void loop();
|
static void loop();
|
||||||
static void broadcast(RingStream * ring);
|
static void broadcast(char * stringBuffer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static SerialManager * first;
|
static SerialManager * first;
|
||||||
SerialManager(Stream * myserial);
|
SerialManager(Stream * myserial);
|
||||||
void loop2();
|
void loop2();
|
||||||
void broadcast2(RingStream * ring);
|
void broadcast2(char * stringBuffer);
|
||||||
Stream * serial;
|
Stream * serial;
|
||||||
SerialManager * next;
|
SerialManager * next;
|
||||||
byte bufferLength;
|
byte bufferLength;
|
||||||
|
45
StringBuffer.cpp
Normal file
45
StringBuffer.cpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* © 2022 Chris Harlow
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This file is part of DCC-EX CommandStation-EX
|
||||||
|
*
|
||||||
|
* This 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.
|
||||||
|
*
|
||||||
|
* It 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 CommandStation. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "StringBuffer.h"
|
||||||
|
#include "DIAG.h"
|
||||||
|
|
||||||
|
StringBuffer::StringBuffer() {
|
||||||
|
flush();
|
||||||
|
};
|
||||||
|
|
||||||
|
char * StringBuffer::getString() {
|
||||||
|
return _buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringBuffer::flush() {
|
||||||
|
_pos_write=0;
|
||||||
|
_buffer[0]='\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t StringBuffer::write(uint8_t b) {
|
||||||
|
if (_pos_write>=buffer_max) return 0;
|
||||||
|
_buffer[_pos_write] = b;
|
||||||
|
++_pos_write;
|
||||||
|
_buffer[_pos_write]='\0';
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
38
StringBuffer.h
Normal file
38
StringBuffer.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* © 2022 Chris Harlow
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This file is part of DCC++EX
|
||||||
|
*
|
||||||
|
* This 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.
|
||||||
|
*
|
||||||
|
* It 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 CommandStation. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef StringBuffer_h
|
||||||
|
#define StringBuffer_h
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
class StringBuffer : public Print {
|
||||||
|
public:
|
||||||
|
StringBuffer();
|
||||||
|
// Override Print default
|
||||||
|
virtual size_t write(uint8_t b);
|
||||||
|
void flush();
|
||||||
|
char * getString();
|
||||||
|
private:
|
||||||
|
static const int buffer_max=64; // enough for long text msgs to throttles
|
||||||
|
int16_t _pos_write;
|
||||||
|
char _buffer[buffer_max+1];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -104,7 +104,7 @@ void StringFormatter::send2(Print * stream,const FSH* format, va_list args) {
|
|||||||
case 'b': stream->print(va_arg(args, int), BIN); break;
|
case 'b': stream->print(va_arg(args, int), BIN); break;
|
||||||
case 'o': stream->print(va_arg(args, int), OCT); break;
|
case 'o': stream->print(va_arg(args, int), OCT); break;
|
||||||
case 'x': stream->print(va_arg(args, int), HEX); break;
|
case 'x': stream->print(va_arg(args, int), HEX); break;
|
||||||
case 'f': stream->print(va_arg(args, double), 2); break;
|
//case 'f': stream->print(va_arg(args, double), 2); break;
|
||||||
//format width prefix
|
//format width prefix
|
||||||
case '-':
|
case '-':
|
||||||
formatLeft=true;
|
formatLeft=true;
|
||||||
|
@ -4,8 +4,10 @@
|
|||||||
#include "StringFormatter.h"
|
#include "StringFormatter.h"
|
||||||
|
|
||||||
|
|
||||||
#define VERSION "4.2.0 rc1"
|
#define VERSION "4.2.0 rc2"
|
||||||
// 4.2.0 Track Manager additions:
|
// 4.2.0 Track Manager additions:
|
||||||
|
// Broadcast improvements to separate <> and Withrottle responses
|
||||||
|
// Float eliminated saving >1.5kb PROGMEM and speed.
|
||||||
// SET_TRACK(track,mode) Functions (A-H, MAIN|PROG|DC|DCX|OFF)
|
// SET_TRACK(track,mode) Functions (A-H, MAIN|PROG|DC|DCX|OFF)
|
||||||
// New DC track function and DCX reverse polarity function
|
// New DC track function and DCX reverse polarity function
|
||||||
// TrackManager DCC & DC up to 8 Districts Architecture
|
// TrackManager DCC & DC up to 8 Districts Architecture
|
||||||
|
Loading…
Reference in New Issue
Block a user