BrewPiLess icon indicating copy to clipboard operation
BrewPiLess copied to clipboard

Massive iSpindel temperature error

Open walldad opened this issue 6 years ago • 11 comments

I just finished building an iSpindel and linking it up my brewpiless setup. The gravity reading seems to coming through fine but the temperature is off by almost 100F. The temperature reads correct in the iSpindel AP portal. I can't find a correction factor in brewpiless anywhere.

walldad avatar Feb 16 '19 22:02 walldad

That sounds like a Celsius vs Fahrenheit issue.

vitotai avatar Mar 01 '19 03:03 vitotai

I'm having the same problem. My iSpindel temperature reads ok and shows up correct as Aux Temp, but although in the device setting it's set as Beer temp and displays the correct temperature over there in the graph window it was going from +1 to -1 degrees C and is now suddenly at 67 C.

kynsi avatar Jan 10 '21 09:01 kynsi

The values in "aux temp" series are raw values, while the values of "beer" temperature are "filtered". I am not familiar with the filtering algorithm, but in my test, the beer temperature will converge to real value after a short time.

vitotai avatar Jan 12 '21 13:01 vitotai

Yes I saw this happen earlier but on my most recent brew it didn't so i had to use fridge temperature. Could it be esp32 related? I switched from esp8266 to esp32..

kynsi avatar Jan 12 '21 19:01 kynsi

Connect to BPL, and open Javascript console. You can see the raw data from iSpindel when received.

vitotai avatar Jan 12 '21 23:01 vitotai

The raw values are ok, it's the filtered value which stays around either +/-1 degrees or jumps to 67..

kynsi avatar Jan 13 '21 08:01 kynsi

You might try modifying the filter parameters by JSON command. beerFastFilt, beerSlowFilt, beerSlopeFilt set all of them to zero.

The jumps might be result of disconnecting, when some reports missed for some reason and no reports received within 5 minutes.

vitotai avatar Jan 13 '21 10:01 vitotai

I have a connect interval of 30s. Also if there's no connection it would mean the aux temp and SG wouldn't update but they are changed almost real-time.

kynsi avatar Jan 14 '21 19:01 kynsi

What is your temperature unit on BPL? Fahrenheit or Celsius? What is the temperature unit on iSpindel? F, C or K?

The related code of "wireless sensor" is so simple that it has less than 70 lines. Check TempSensorWireless.h if you read source code.

Maybe you can copy the output of Javascript console, and let me try if I can reproduce it.

vitotai avatar Jan 15 '21 02:01 vitotai

I've experienced the same issue. The problem is that when TempSensorWireless is initialized there is no reading from the iSpindel yet. So when TempSensor::init() is called the first time, the filters are not initialized. When TempSensor::update() is then subsequently called, it increments failedReadCount. When the iSpindel eventually sends a measurement, failedReadCount > 0 and TempSensor::update() will run as if the filters have been properly initialized.

updateSensor(TempSensor* sensor) in TempControl.cpp also doesn't deal with it properly, because it runs sensor->update() before checking if the sensor is connected. However, even if sensor->update() is called after the check, the filters would still not be initialized because failedReadCount has been incremented.

In my opinion, the check to make sure that the filters are properly initialized should be done in TempSensor::update() [TempSensor.cpp] and not in updateSensor(TempSensor* sensor) [TempControl.cpp] because there should be no scenario in which the TempSensor is updated without the filters being properly initialized.

Only after failedReadCount is incremented above 60, are the filters correctly initialized.

The solution that I tested is the following:

Add the following check at the start of the method,

TempSensor.cpp:

void TempSensor::update()
{
	// Ensure filters are initialized
	if (failedReadCount<0 || failedReadCount>60){
		if(!init()){return;}
	}
.... 
}

Add return statements and remove (failedReadCount<0 || failedReadCount>60) from the if statement.

TempSensor.cpp:

bool TempSensor::init()
{
	logDebug("tempsensor::init - begin %d", failedReadCount);
	if (_sensor && _sensor->init()) {
		temperature temp = _sensor->read();
		if (temp!=TEMP_SENSOR_DISCONNECTED) {
			logDebug("initializing filters with value %d", tempToInt(temp));
			fastFilter.init(temp);
			slowFilter.init(temp);
			slopeFilter.init(0);
			prevOutputForSlope = slowFilter.readOutputDoublePrecision();
			failedReadCount = 0;
			return true; // Added
		} 
	}
	return false; //Added
}

Update the header file from void to bool,

TempSensor.h:

bool TempSensor::init()

Just call update() since the check for isConnected is now handled in the update() method.

TempControl.cpp:

void updateSensor(TempSensor* sensor) {
	sensor->update();
}

DMT07 avatar Feb 25 '24 16:02 DMT07

There is one outstanding issue that this fix doesn't resolve.

In TempSensor::update(), if the primary sensor fails it falls back to a _backupSensor and the filter values are updated with the temperature reading from the _backupSensor.

However, the existing code does not make provision to use the _backupSensor when initializing the filters in TempSensor::init(). So the fallback _backupSensor can only be used if the primary sensor worked at least initially. To fix this, TempSensor::init() should also implement the fallback to the _backupSensor.

DMT07 avatar Feb 25 '24 17:02 DMT07