From 1e444839e068f5e7b4b024477240d062dc517bc3 Mon Sep 17 00:00:00 2001 From: David Crocker Date: Tue, 7 Jan 2014 13:42:30 +0000 Subject: [PATCH] Improved network recovery from errors and fixed small temp cal error Improved network error recovery so that it it possible to reconnect after some types of network error have occurred Corrected calculation of temperatures to give more accurate results towards the limits of the ADC range --- Platform.cpp | 28 ++++++++++++++++++---------- Platform.h | 2 +- Webserver.cpp | 24 ++++++++++++++++++++++++ Webserver.h | 1 + network/httpd.c | 20 ++++++++++++-------- 5 files changed, 56 insertions(+), 19 deletions(-) diff --git a/Platform.cpp b/Platform.cpp index a492eaf..2177d78 100644 --- a/Platform.cpp +++ b/Platform.cpp @@ -312,7 +312,7 @@ void Platform::ClassReport(char* className, float &lastTime) // should compute it for you (i.e. it won't need to be calculated at run time). // If the A->D converter has a range of 0..1023 and the measured voltage is V (between 0 and 1023) -// then the thermistor resistance, R = V.RS/(1023 - V) +// then the thermistor resistance, R = V.RS/(1024 - V) // and the temperature, T = BETA/ln(R/R_INF) // To get degrees celsius (instead of kelvin) add -273.15 to T //#define THERMISTOR_R_INFS ( THERMISTOR_25_RS*exp(-THERMISTOR_BETAS/298.15) ) // Compute in Platform constructor @@ -321,8 +321,10 @@ void Platform::ClassReport(char* className, float &lastTime) float Platform::GetTemperature(int8_t heater) { - float r = (float)GetRawTemperature(heater); - return ABS_ZERO + thermistorBetas[heater]/log( (r*thermistorSeriesRs[heater]/(AD_RANGE - r))/thermistorInfRs[heater] ); + // If the ADC reading is N then for an ideal ADC, the input voltage is at least N/(ADC_RANGE + 1) and less than (N + 1)/(ADC_RANGE + 1), times the analog reference. + // So we add 0.5 to to the reading to get a better estimate of the input. We don't care whether or not we get exactly zero with the thermistor disconnected. + float r = (float)GetRawTemperature(heater) + 0.5; + return ABS_ZERO + thermistorBetas[heater]/log( (r*thermistorSeriesRs[heater]/((AD_RANGE + 1) - r))/thermistorInfRs[heater] ); } @@ -864,9 +866,10 @@ void RepRapNetworkInputBufferReleased(void* pb) reprap.GetPlatform()->GetNetwork()->InputBufferReleased(pb); } -void RepRapNetworkHttpStateReleased(void* h) +void RepRapNetworkConnectionError(void* h) { - reprap.GetPlatform()->GetNetwork()->HttpStateReleased(h); + reprap.GetPlatform()->GetNetwork()->ConnectionError(h); + reprap.GetWebserver()->ConnectionError(); } // Called to put out a message via the RepRap firmware. @@ -1053,14 +1056,19 @@ void Network::InputBufferReleased(void* pb) netRingGetPointer->ReleasePbuf(); } -void Network::HttpStateReleased(void* h) +void Network::ConnectionError(void* h) { - if(netRingGetPointer->Hs() != h) + // h points to an http state block that the caller is about to release, so we need to stop referring to it. + // The state block is usually but not always in use by the current http request being processed, in which case we abandon the current request. + if (netRingGetPointer != netRingAddPointer && netRingGetPointer->Hs() == h) { - reprap.GetPlatform()->Message(HOST_MESSAGE, "Network::HttpStateReleased() - Pointers don't match!\n"); - return; + netRingGetPointer->Free(); + netRingGetPointer = netRingGetPointer->Next(); } - netRingGetPointer->ReleaseHs(); + + // Reset the network layer. In particular, this clears the output buffer to make sure nothing more gets sent, + // and sets statue to 'nothing' so that we can accept another connection attempt. + Reset(); } diff --git a/Platform.h b/Platform.h index f8e769a..f701f88 100644 --- a/Platform.h +++ b/Platform.h @@ -273,7 +273,7 @@ public: void Close(); void ReceiveInput(char* data, int length, void* pb, void* pc, void* h); void InputBufferReleased(void* pb); - void HttpStateReleased(void* h); + void ConnectionError(void* h); bool Active(); bool LinkIsUp(); diff --git a/Webserver.cpp b/Webserver.cpp index e743a89..3be5036 100644 --- a/Webserver.cpp +++ b/Webserver.cpp @@ -711,6 +711,30 @@ void Webserver::Init() //platform->GetMassStorage()->Delete(platform->GetWebDir(), MESSAGE_FILE); } +// This is called when the connection has been lost. +// In particular, we must cancel any pending writes. +void Webserver::ConnectionError() +{ + writing = false; + receivingPost = false; + postSeen = false; + getSeen = false; + jsonPointer = -1; + clientLineIsBlank = true; + needToCloseClient = false; + clientLinePointer = 0; + clientLine[0] = 0; + clientRequest[0] = 0; + gotPassword = false; + gcodeAvailable = false; + gcodePointer = 0; + InitialisePost(); + lastTime = platform->Time(); + longWait = lastTime; + active = true; + +} + void Webserver::Exit() { platform->Message(HOST_MESSAGE, "Webserver class exited.\n"); diff --git a/Webserver.h b/Webserver.h index 8876b6f..a05575c 100644 --- a/Webserver.h +++ b/Webserver.h @@ -50,6 +50,7 @@ class Webserver void Diagnostics(); void SetPassword(char* pw); void SetName(char* nm); + void ConnectionError(); private: diff --git a/network/httpd.c b/network/httpd.c index e9c5f8a..1366463 100644 --- a/network/httpd.c +++ b/network/httpd.c @@ -72,7 +72,7 @@ struct http_state { void RepRapNetworkReceiveInput(char* ip, int length, void* pbuf, void* pcb, void* hs); void RepRapNetworkInputBufferReleased(void* pbuf); -void RepRapNetworkHttpStateReleased(void* h); +void RepRapNetworkConnectionError(void* h); void RepRapNetworkMessage(char* s); void RepRapNetworkAllowWriting(); bool RepRapNetworkHasALiveClient(); @@ -86,15 +86,19 @@ static int initCount = 0; static void conn_err(void *arg, err_t err) { - struct http_state *hs; + // Report the error to the monitor + RepRapNetworkMessage("Network connection error, code "); + { + char tempBuf[10]; + snprintf(tempBuf, sizeof(tempBuf)/sizeof(char), "%d\n", err); + RepRapNetworkMessage(tempBuf); + } - LWIP_UNUSED_ARG(err); - - hs = arg; - mem_free(hs); - //RepRapNetworkHttpStateReleased(hs); - RepRapNetworkMessage("Network connection error.\n"); + struct http_state *hs = arg; + RepRapNetworkConnectionError(hs); // tell the higher levels about the error + mem_free(hs); // release the state data } + /*-----------------------------------------------------------------------------------*/ static void