Using up all my Variable Memory

I’m working on a project which is basically an ip thermometer. I am running out of variable memory on my arduino uno. Can someone help me optimise my code further? I’m pretty sure I got all the F()'s.

/*
  DHCP Temp Monitor
  Circuit:
   Ethernet shield attached to pins 10, 11, 12, 13
*/

#include <SPI.h>
#include <EthernetV2_0.h>

#define W5200_CS  10
#define SDCARD_CS 4
// which analog pin to connect
#define THERMISTORPIN A0
// how many samples to take and average, more takes longer
// but is more 'smooth'
#define NUMSAMPLES 5
// the value of the 'other' resistor
#define SERIESRESISTOR 100000

//**Ethernet Vars
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network.
// gateway and subnet are optional:
byte mac[] = {0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
IPAddress ip(192, 168, 1, 177);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 0, 0);
EthernetServer server(80);
EthernetClient client;
boolean gotAMessage = false; // whether or not you got a message from the client yet

//** Temp Vars
byte samples[NUMSAMPLES];

//**Webvars
char username[] = "admin";
char password[] = "password";
const int passCount = 20;
unsigned long passIDstart[passCount];  // array to record start time of user sessions
unsigned long passIDlast[passCount];   // array to record last time of user sessions
unsigned long passIDvalid = 0;         // set default as passID : 0 = missing or invalid
unsigned long passExpireMil = 60000;   // expiry time for automatic expiry of valid passID
char buffer[256];                      // buffer for debugging
String LastAction;
String readString;                     // used to clear away incoming data that is not required
char xx1[20];                          // temp char for the long converted to char
char JoinedChar[100];                  // char to hold the joined strings
char DoAction[] = "DoAction";          // keyword for DoAction commands

part2

float Thermistor(int RawADC) {
  uint8_t i;
  float average;

  // take N samples in a row, with a slight delay
  for (i = 0; i < NUMSAMPLES; i++) {
    samples[i] = analogRead(THERMISTORPIN);
    delay(10);
  }

  // average all the samples out
  average = 0;
  for (i = 0; i < NUMSAMPLES; i++) {
    average += samples[i];
  }
  average /= NUMSAMPLES;

  Serial.print("Average analog reading ");
  Serial.println(average);
  // convert the value to resistance
  average = 1023 / average - 1;
  average = SERIESRESISTOR / average;
  Serial.print("Thermistor resistance ");
  Serial.println(average);
  float temp;
  temp = log(average);
  temp = 1 / (0.0004239682 + (0.000276987 + (-0.0000000548365 * temp * temp )) * temp );
  Serial.println(temp);
  temp = temp - 273.15;
  Serial.println(temp);
  temp = (temp * 9.0) / 5.0 + 32.0;
  Serial.println(temp);
  return temp;
}

void httpResponse() {
  client.println(F("HTTP/1.1 200 OK"));
  client.println(F("Content-Type: text/html"));
  client.println(F("Connnection: close"));
  client.println();
}

/*----------------------------------------------------------------------------*/
/* incoming data : Get a single client char                                   */
/*----------------------------------------------------------------------------*/
char getchr(void) {
  while (!client.available());         /* Await data from client           */
  return client.read();               /* Return input character            */
}                                      /* end: gchr()                        */

/*----------------------------------------------------------------------------*/
/* incoming data : Get an entire line from the client                         */
/*----------------------------------------------------------------------------*/
char *getLine(char *buf) {
  char c, *p = buf;                   /* Input char, input buffer pointer   */
  while (' ' > (c = getchr()));         /* Discard (leading) control chars    */
  do *p++ = c;                        /* Move input char to line buffer     */
  while (' ' <= (c = getchr()));        /* Until control char encountered     */
  *p = '\0';                          /* Terminate line in buffer           */
  return buf;                         /* Return pointer to input string     */
}                                       /* end: getLine()                        */

void setup() {

  Serial.begin(9600); // Open serial communications and wait for port to open

  analogReference(EXTERNAL); // connect AREF to 3.3V and use that as VCC, less noisy!

  pinMode(SDCARD_CS, OUTPUT);
  digitalWrite(SDCARD_CS, HIGH); //Deselect the SD card

  // this check is only needed on the Leonardo:
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  // start the Ethernet connection:
  Serial.println("Trying to get an IP address using DHCP");
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // initialize the ethernet device not using DHCP:
    Ethernet.begin(mac, ip, gateway, subnet);
  }
  // print your local IP address:
  Serial.print("My IP address: ");
  ip = Ethernet.localIP();
  for (byte thisByte = 0; thisByte < 4; thisByte++) {
    // print the value of each byte of the IP address:
    Serial.print(ip[thisByte], DEC);
    Serial.print(".");
  }
  Serial.println();
  //initialize the passIDstart array to hold zero values in all elements
  for (int i = 0; i < passCount; i++) {
    passIDstart[i] = 0;
  }


  // start listening for clients
  server.begin();
  Serial.println("Setup Done");
}

void loop() {
  // listen for incoming clients
  if (client = server.available()) {
    Serial.println("new client");
    // an http request ends with a blank line
    unsigned long currentMillis = millis();
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      getLine(buffer);                 // Get HTTP request line by line
      Serial.print("The current millis is : ");
      Serial.println(millis());
      Serial.print("Received: '");  // Show what we received from
      Serial.print(buffer);         // the current client
      Serial.println("'");

      passIDvalid = 0;              // set the passIDvalid to 0
      LastAction = "";

      if (strstr(buffer, "logform")) {   /* Is logform keyword present?         */
        Serial.println(F("Found logform"));
        if (strstr(buffer, password)) {   /* Is password present?                */
          Serial.println(F("Found myPass"));

You missed many opportunities for using F() macro, dude.

A small selection of them (there are a lot more...)

Serial.println("Trying to get an IP address using DHCP");
Serial.println("Failed to configure Ethernet using DHCP");
Serial.print("My IP address: ");
Serial.print(".");
Serial.println("Setup Done");
Serial.println("new client");
Serial.print("The current millis is : ");
Serial.print("Received: '"); // Show what we received from
Serial.println("'");

          // clear the rest of the incoming buffer
          char c = client.read();
          if (readString.length() < 100) {         // read char by char HTTP request
            readString += c;                       // store characters to string
          }
          if (c == '\n') {                         // if HTTP request has ended - blank line received
            Serial.println(F("Header Flushed"));
          }
          /* Login form processing */

          // get the first open passID storage space and create a new session ID.
          for (int i = 0; i < passCount; i++) {
            if (passIDvalid == 0 && passIDstart[i] == 0) {
              passIDstart[i] = currentMillis;  // set the variable to use as the passID
              passIDlast[i] = currentMillis;   // set the last time the passID was used
              passIDvalid = passIDstart[i];
              Serial.print(F("New alocated passID = "));
              Serial.print(passIDvalid);
              Serial.print(F(" in array space "));
              Serial.println(i);
              LastAction = "Login Completed";
            }
          }                     // end of loop for get the first open passID storage space
        }                         // end: if password is present
      }                             // end: if logform in line
      unsigned int GotAction = 0;   // shows that no DoAction command received

      // look for DoAction commands in the input buffer
      if (strstr(buffer, "DoAction")) {   /* If DoAction keyword is present         */
        Serial.println(F("Found DoAction keyword"));
        Serial.println(F("Looking for valid passID"));

        //see if a valid passID exists in the DoAction line
        for (int i = 0; i < passCount; i++) {

          if (GotAction == 0 && passIDstart[i] != 0) {

            ltoa(passIDstart[i], xx1, 10); // convert the long to char

            //check for the passID + DoAction keyword + action code in the buffer

            JoinedChar[0] = '\0';               // clear the destination array
            strcat(JoinedChar, xx1);            //add the passID to the array
            strcat(JoinedChar, DoAction);       //add the keyword to the array
            strcat(JoinedChar, "on001");        //add the action code to the array
            if (strstr(buffer, JoinedChar)) GotAction = 1;

            JoinedChar[0] = '\0';               // clear the destination array
            strcat(JoinedChar, xx1);            //add the passID to the array
            strcat(JoinedChar, DoAction);       //add the keyword to the array
            strcat(JoinedChar, "on002");        //add the action code to the array
            if (strstr(buffer, JoinedChar)) GotAction = 2;

            JoinedChar[0] = '\0';               // clear the destination array
            strcat(JoinedChar, xx1);            //add the passID to the array
            strcat(JoinedChar, DoAction);       //add the keyword to the array
            strcat(JoinedChar, "on003");        //add the action code to the array
            if (strstr(buffer, JoinedChar)) GotAction = 3;

            if (GotAction != 0) {
              Serial.print(F("Found DoAction "));
              Serial.print(GotAction);
              Serial.print(F(" for passID : "));
              Serial.println(passIDstart[i]);
              passIDlast[i] = currentMillis;   //renew the last time that the passID was used
              passIDvalid = passIDstart[i];
            }
          }
        }

        if (GotAction != 0) {

          // clear the rest of the incoming buffer
          char c = client.read();
          if (readString.length() < 100) {         // read char by char HTTP request
            readString += c;                       // store characters to string
          }
          if (c == '\n') {                         // if HTTP request has ended - blank line received
            Serial.println("Header Flushed");
          }

          /* DoAction processing */

          if (GotAction == 1) {
            Serial.println("Received Web Server command on001");
            // do tasks in response to command 1 received
            LastAction = "Command on001 processed";
          }
          if (GotAction == 2) {
            Serial.println("Received Web Server command on002");
            // do tasks in response to command 2 received
            LastAction = "Command on002 processed";
          }
          if (GotAction == 3) {
            Serial.println("Received Web Server command on003");
            // do tasks in response to command 3 received
            LastAction = "Command on003 processed";
          }
        }
      }
     // send a standard http response header
      httpResponse();
      client.println(F("<!DOCTYPE HTML>"));
      client.println(F("<html>"));
      client.println(F("<head>"));
      client.println(F("<TITLE>Home Control</TITLE>"));
      client.println(F("<link rel='shortcut icon' href='data:image/x-icon;,' type='image/x-icon'>"));
      // add a meta refresh tag, so the browser pulls again every 5 seconds:
      //client.println("<meta http-equiv=\"refresh\" content=\"5\">");
      //client.println(F("<script>function myFunction() {var user = prompt('Please enter your name'); if(user != null) { document.getElementById('demo').innerHTML = 'Hello ' + user + '! How are you today?';}}</script>"));
      client.println(F("</head>"));
      client.println(F("<body onLoad='myFunction()'>"));
      client.println(F("<p id='demo'></p>"));
      if (passIDvalid == 0) { // this is not a valid passID - ask for the password
        client.print(F("<form method=get>"));
        client.print(F("Access Key:<input type=password name=logform size=10>"));
        client.print(F(" <input type=submit value=Login>"));
        client.print(F("</form>"));
      }
      else {
        float temp = Thermistor(analogRead(0));
        client.print(int(temp));
        client.print(".");
        unsigned int frac;
        if (temp >= 0)
          frac = (temp - int(temp)) * 100;
        else
          frac = (int(temp) - temp ) * 100;
        client.println(frac, DEC);
      }
      client.println(F("</body>"));
      client.println(F("</html>"));
      break;
    }
    // give the web browser time to receive the data
    delay(2);
    // close the connection:
    client.stop();
    Serial.println(F("client disonnected"));
  }
}

Yup, more opportunities for F() in the last piece of the code you posted.

You missed many opportunities for using F() macro, dude.
Will fix. Sorry. I will edit my post…

Sorry. I will edit my post...

If you do that, many people will ignore you from then on. DO NOT EDIT CODE IN EXISTING POSTS.

Post the code again, using the Reply button, and select the Additional Options link to attach your code.

String LastAction;
String readString;                     // used to clear away incoming data that is not required

Using Strings is a good way to uselessly piss away memory. Storing incoming data that you do not need is not just useless. It’s stupid.

  // take N samples in a row, with a slight delay
  for (i = 0; i < NUMSAMPLES; i++) {
    samples[i] = analogRead(THERMISTORPIN);
    delay(10);
  }

  // average all the samples out
  average = 0;
  for (i = 0; i < NUMSAMPLES; i++) {
    average += samples[i];
  }
  average /= NUMSAMPLES;

There is no reason to waste memory storing all the values when the ONLY thing you do with them is add them up and compute an average. Just add the values as you read them.

  do *p++ = c;                        /* Move input char to line buffer     */
  while (' ' <= (c = getchr()));        /* Until control char encountered     */

Do/while statements should ALWAYS have curly braces around the body.