RAM optim to save huge configs to flash, PID min/max

This commit is contained in:
2022-11-19 23:30:02 +03:00
parent 07688f53ae
commit a956b6f8e2
6 changed files with 65 additions and 23 deletions

View File

@@ -39,6 +39,8 @@ extern NRFFlashStorage EEPROM;
#if defined(__SAM3X8E__) #if defined(__SAM3X8E__)
DueFlashStorage EEPROM; DueFlashStorage EEPROM;
static char samBuffer[64];
short samBufferPos = 0;
#endif #endif
#ifdef NRF5 #ifdef NRF5
@@ -129,6 +131,10 @@ NRFFlashStorage EEPROM;
int flashStream::open(short fileNum, char mode) int flashStream::open(short fileNum, char mode)
{ {
#if defined(__SAM3X8E__)
samBufferPos = 0;
#endif
switch (fileNum) { switch (fileNum) {
case FN_CONFIG_JSON: case FN_CONFIG_JSON:
pos = 0; pos = 0;
@@ -138,6 +144,7 @@ NRFFlashStorage EEPROM;
#ifdef OTA #ifdef OTA
contentType = HTTP_TEXT_JSON; contentType = HTTP_TEXT_JSON;
#endif #endif
openmode = mode;
return 1; return 1;
case FN_CONFIG_BIN: case FN_CONFIG_BIN:
@@ -148,6 +155,7 @@ NRFFlashStorage EEPROM;
#ifdef OTA #ifdef OTA
contentType = HTTP_OCTET_STREAM; contentType = HTTP_OCTET_STREAM;
#endif #endif
openmode = mode;
return 1; return 1;
default: default:
@@ -171,7 +179,13 @@ NRFFlashStorage EEPROM;
}; };
unsigned int flashStream::seek(unsigned int _pos) unsigned int flashStream::seek(unsigned int _pos)
{ pos=min(_pos, streamSize); {
#if defined(__SAM3X8E__)
if (samBufferPos) flush();
#endif
pos=min(_pos, streamSize);
//debugSerial<<F("Seek:")<<pos<<endl; //debugSerial<<F("Seek:")<<pos<<endl;
return pos; return pos;
}; };
@@ -196,21 +210,37 @@ NRFFlashStorage EEPROM;
else return -1; else return -1;
}; };
void flashStream::flush() { void flashStream::flush() {
#if defined(ESP8266) || defined(ESP32) #if defined(ESP8266) || defined(ESP32)
if (EEPROM.commitReset()) if (EEPROM.commitReset())
infoSerial<<"Commited to FLASH"<<endl; infoSerial<<"Commited to FLASH"<<endl;
else errorSerial<<"Commit error. len:"<<EEPROM.length()<<endl; else errorSerial<<"Commit error. len:"<<EEPROM.length()<<endl;
#elif defined(__SAM3X8E__)
if (samBufferPos)
EEPROM.write(startPos+pos-samBufferPos,(byte*)samBuffer,samBufferPos);
#endif #endif
}; };
size_t flashStream::write(uint8_t ch) size_t flashStream::write(uint8_t ch)
{ {
#if defined(__AVR__) #if defined(__AVR__)
EEPROM.update(startPos+pos++,(char)ch); EEPROM.update(startPos+pos++,(char)ch);
return 1; return 1;
#elif defined(__SAM3X8E__) #elif defined(__SAM3X8E__)
return EEPROM.write(startPos+pos++,(char)ch);
if (samBufferPos==sizeof(samBuffer))
{
samBufferPos = 0;
EEPROM.write(startPos+pos-sizeof(samBuffer),(byte*)samBuffer,sizeof(samBuffer));
}
samBuffer[samBufferPos++]=ch;
pos++;
return 1;
// return EEPROM.write(startPos+pos++,(char)ch);
#else #else
EEPROM.write(startPos+pos++,(char)ch); EEPROM.write(startPos+pos++,(char)ch);
return 1; return 1;
@@ -237,7 +267,10 @@ NRFFlashStorage EEPROM;
void flashStream::close() void flashStream::close()
{ {
putEOF(); if (openmode == 'w') putEOF();
#if defined(__SAM3X8E__)
if (samBufferPos) flush();
#endif
} }

View File

@@ -53,9 +53,10 @@ class flashStream : public seekableStream
protected: protected:
unsigned int pos; unsigned int pos;
unsigned int startPos; unsigned int startPos;
char openmode ;
public: public:
flashStream():seekableStream(MAX_STREAM_SIZE){}; flashStream():seekableStream(MAX_STREAM_SIZE){openmode = '\0';};
void setSize(unsigned int _size); void setSize(unsigned int _size);
int open(short fileNum, char mode='\0') ; int open(short fileNum, char mode='\0') ;
virtual int open(String _filename, char mode='\0') override; virtual int open(String _filename, char mode='\0') override;

View File

@@ -664,6 +664,8 @@ lan_status lanLoop() {
setTopic(buf,sizeof(buf),T_OUT); setTopic(buf,sizeof(buf),T_OUT);
strncat(buf, "+/+/#", sizeof(buf)); // Subscribing only on separated command/parameters topics strncat(buf, "+/+/#", sizeof(buf)); // Subscribing only on separated command/parameters topics
mqttClient.unsubscribe(buf); mqttClient.unsubscribe(buf);
onMQTTConnect();
lanStatus = OPERATION;//3; lanStatus = OPERATION;//3;
infoSerial<<F("Accepting commands...\n"); infoSerial<<F("Accepting commands...\n");
@@ -1002,7 +1004,7 @@ void ip_ready_config_loaded_connecting_to_broker() {
debugSerialPort.println(buf); debugSerialPort.println(buf);
mqttClient.subscribe(buf); mqttClient.subscribe(buf);
onMQTTConnect(); //onMQTTConnect();
// if (_once) {DMXput(); _once=0;} // if (_once) {DMXput(); _once=0;}
lanStatus = RETAINING_COLLECTING;//4; lanStatus = RETAINING_COLLECTING;//4;
timerLanCheckTime = millis();// + 5000; timerLanCheckTime = millis();// + 5000;
@@ -1497,11 +1499,11 @@ if (arg_cnt>1)
#else #else
sysConfStream.open(FN_CONFIG_JSON,'w'); sysConfStream.open(FN_CONFIG_JSON,'w');
#endif #endif
/*
#if defined(__SAM3X8E__) #if defined(__SAM3X8E__)
long configBufSize = min(MAX_JSON_CONF_SIZE,freeRam()-1024); long configBufSize = min(MAX_JSON_CONF_SIZE,freeRam()-1024);
debugSerial<<"Allocate "<<configBufSize<<" bytes for buffer"<<endl; debugSerial<<"Allocate "<<configBufSize<<" bytes for buffer"<<endl;
char* outBuf = (char*) malloc(configBufSize); /* XXX: Dynamic size. */ char* outBuf = (char*) malloc(configBufSize);
if (!outBuf) if (!outBuf)
{ {
sysConfStream.close(); sysConfStream.close();
@@ -1509,23 +1511,22 @@ if (arg_cnt>1)
return 500; return 500;
} }
infoSerial<<F("Saving config to EEPROM..")<<endl; infoSerial<<F("Saving config to EEPROM..")<<endl;
aJsonStringStream stringStream(NULL, outBuf, configBufSize); aJsonStringStream stringStream(NULL, outBuf, configBufSize-2);
aJson.print(root, &stringStream); aJson.print(root, &stringStream);
int len = strlen(outBuf); int len = strlen(outBuf);
outBuf[len++]= EOFchar; outBuf[len++]= EOFchar;
infoSerial<<len<< F(" bytes collected")<<endl;
size_t res = sysConfStream.write((byte*) outBuf,len); size_t res = sysConfStream.write((byte*) outBuf,len);
free (outBuf); free (outBuf);
infoSerial<<res<< F(" bytes from ")<<len<<F(" are saved to EEPROM")<<endl; infoSerial<<res<< F(" bytes are saved to EEPROM")<<endl;
#else #else */
aJsonStream jsonEEPROMStream = aJsonStream(&sysConfStream); aJsonStream jsonEEPROMStream = aJsonStream(&sysConfStream);
infoSerial<<F("Saving config to EEPROM.."); infoSerial<<F("Saving config to EEPROM..");
aJson.print(root, &jsonEEPROMStream); aJson.print(root, &jsonEEPROMStream);
//sysConfStream.putEOF();
//sysConfStream.flush();
sysConfStream.close(); sysConfStream.close();
infoSerial<<F("Saved to EEPROM")<<endl; infoSerial<<F("Saved to EEPROM")<<endl;
#endif //#endif
sysConf.saveETAG(); sysConf.saveETAG();
return 200; return 200;
} }
@@ -2285,6 +2286,10 @@ infoSerial<<F("\n(+)HUMIDIFIER");
#ifdef ELEVATOR_ENABLE #ifdef ELEVATOR_ENABLE
infoSerial<<F("\n(+)ELEVATOR"); infoSerial<<F("\n(+)ELEVATOR");
#endif #endif
#ifdef IPMODBUS
infoSerial<<F("\n(+)IPMODBUS");
#endif
infoSerial<<endl; infoSerial<<endl;
// WDT_Disable( WDT ) ; // WDT_Disable( WDT ) ;

View File

@@ -317,4 +317,6 @@ void ip_ready_config_loaded_connecting_to_broker();
void printCurentLanConfig(); void printCurentLanConfig();
void onMQTTConnect();
//void printFreeRam(); //void printFreeRam();

View File

@@ -14,6 +14,7 @@ bool out_pid::getConfig()
double kI=0.0; double kI=0.0;
double kD=0.0; double kD=0.0;
int direction = DIRECT; int direction = DIRECT;
bool limits = false;
// Retrieve and store // Retrieve and store
if (!store || !item || !item->itemArg || (item->itemArg->type != aJson_Array) || aJson.getArraySize(item->itemArg)<1) if (!store || !item || !item->itemArg || (item->itemArg->type != aJson_Array) || aJson.getArraySize(item->itemArg)<1)
@@ -28,8 +29,8 @@ bool out_pid::getConfig()
errorSerial<<F("Invalid PID param array.")<<endl; errorSerial<<F("Invalid PID param array.")<<endl;
return false; return false;
} }
double outMin=0.; //UNUSED double outMin=0.;
double outMax=255.;//UNUSED double outMax=255.;
float dT=5.; float dT=5.;
uint32_t alarmTO=PERIOD_THERMOSTAT_FAILED; uint32_t alarmTO=PERIOD_THERMOSTAT_FAILED;
@@ -37,13 +38,13 @@ bool out_pid::getConfig()
switch (aJson.getArraySize(kPIDObj)) switch (aJson.getArraySize(kPIDObj))
{ case 8: //kP,kI,kD,dT, alarmTO, alarmVal, outMin, outMax { case 8: //kP,kI,kD,dT, alarmTO, alarmVal, outMin, outMax
param = aJson.getArrayItem(kPIDObj, 7); param = aJson.getArrayItem(kPIDObj, 7);
if (param->type == aJson_Float) outMax=param->valuefloat; if (param->type == aJson_Float) {outMax=param->valuefloat;limits=true;}
else if (param->type == aJson_Int) outMax=param->valueint; else if (param->type == aJson_Int) {outMax=param->valueint;limits=true;}
case 7: //kP,kI,kD,dT alarmTO, alarmVal, outMin case 7: //kP,kI,kD,dT alarmTO, alarmVal, outMin
param = aJson.getArrayItem(kPIDObj, 6); param = aJson.getArrayItem(kPIDObj, 6);
if (param->type == aJson_Float) outMin=param->valuefloat; if (param->type == aJson_Float) {outMin=param->valuefloat;limits=true;}
else if (param->type == aJson_Int) outMin=param->valueint; else if (param->type == aJson_Int) {outMin=param->valueint;limits=true;}
case 6: //kP,kI,kD,dT, alarmTO, alarmVal case 6: //kP,kI,kD,dT, alarmTO, alarmVal
case 5: //kP,kI,kD,dT, alarmTO case 5: //kP,kI,kD,dT, alarmTO
@@ -99,7 +100,7 @@ bool out_pid::getConfig()
{store->pid= new PID (&store->input, &store->output, &store->setpoint, kP, kI, kD, direction); {store->pid= new PID (&store->input, &store->output, &store->setpoint, kP, kI, kD, direction);
if (!store->pid) return false; if (!store->pid) return false;
store->pid->SetMode(AUTOMATIC); store->pid->SetMode(AUTOMATIC);
//store->pid->SetOutputLimits(outMin,outMax); if (limits) store->pid->SetOutputLimits(outMin,outMax);
store->pid->SetSampleTime(dT*1000.0); store->pid->SetSampleTime(dT*1000.0);
return true;} return true;}
else errorSerial<<F("PID already initialized")<<endl; else errorSerial<<F("PID already initialized")<<endl;

View File

@@ -9,7 +9,7 @@
#ifndef MAX_JSON_CONF_SIZE #ifndef MAX_JSON_CONF_SIZE
#if defined(__SAM3X8E__) #if defined(__SAM3X8E__)
#define MAX_JSON_CONF_SIZE 24000 #define MAX_JSON_CONF_SIZE 65535
#elif defined(ARDUINO_ARCH_AVR) #elif defined(ARDUINO_ARCH_AVR)
#define MAX_JSON_CONF_SIZE 4096 #define MAX_JSON_CONF_SIZE 4096
#elif defined(ARDUINO_ARCH_ESP32) #elif defined(ARDUINO_ARCH_ESP32)