'Arduino Uno - minimize memory usage

I have a Weather Meter, and I am able to read data from it.

My problem occurs, when I try to use the library UnoWiFiDevEd.h send the data to store the information on the internet.

Arduino tells following:

Global variables use 1648 bytes (80%) of dynamic memory, leaving 400 bytes for local variables. Maximum is 2048 bytes. Low memory available, stability problems may occur.

I have read, that another means, that the Uno WiFi library itself leads almost 50% Dynamic Memory usage.

Do anyone have an idea, how I can minimize memory usage?

Thank you in advance

#include <UnoWiFiDevEd.h>

//temporary rain
float calcTemp1;
int calcTemp2;

//Wind vane
const float table[16] = {3.84, 1.98, 2.25, 0.41, 0.45, 0.32, 0.90, 0.62, 1.40, 1.19, 3.08, 2.93, 4.62, 4.32, 4.78, 3.43}; //charecter 13 is not correct, but is changed due to failure in windvane

char buffer[20];

//Anometer - windpower
volatile unsigned int windRotation = 0;
//Used for timing
float windTimer = 0;

int angle = 0;
//Rain gauge
float RainMeasurement = 0;
unsigned long LastRainReset = 0;


void setup() {
  Serial.begin(9600);
  Ciao.begin(); // CIAO INIT

  Serial.write(13);
  delay(2000);
  Serial.println("Initialiserer...");
  initWind();
  initRain();
  Serial.println();
  delay(1000);
}

void loop() {
  doRequest();

  Serial.println();
  delay(30000);
} 


//Gets data about wind
void getWindData(void)
{
  Serial.print("Vindretning: ");
  Serial.println(printWindDirection(36));  

  unsigned long WindReading;
  WindReading = Vind_GetHastighed();
  sprintf(buffer, "Hastighed: %d m/s ", WindReading);
  Serial.println(buffer);
}


//Gets data about rain
void getRainData(void)
{
  if (LastRainReset+86400000 < millis()) { // LastRainReset > 24 timer
    RainMeasurement = 0;
    LastRainReset = millis();
  }

  calcTemp1 = (float)RainMeasurement;
  calcTemp2 = (calcTemp1 - (int)calcTemp1) * 100;
  sprintf(buffer, "%0d.%d", (int)calcTemp1, calcTemp2);
  Serial.print("Nedb\xF8r: ");
  Serial.print(buffer);
  Serial.println(" mm");
}

void doRequest(){
  String resource = "upload.php?key=secretKey";
  resource += "&windDir=";
  resource += String(angle);
  getWindData();
  resource += "&windSpeed=";
  resource += String(Vind_GetHastighed());
  resource += "&rainAmount=";
  getRainData();
  resource += String(buffer);
  Serial.println(resource);
  CiaoData data = Ciao.write("rest", "http://example.com/", resource, "GET");
  if (!data.isEmpty()){
    Ciao.println( "Link: " + String (resource) );
    Ciao.println( "State: " + String (data.get(1)) );
    Ciao.println( "Response: " + String (data.get(2)) );
    Ciao.println();
  }
  else{
    Ciao.println ("Write Error");
    Ciao.println();
  }
}

// Initializing processes 
void initWind(void)
{
  pinMode(3, INPUT);
  attachInterrupt(1, windSpeed, RISING);
  windTimer=millis();//start timing  
  Serial.println("* Vindretning");
  Serial.println("* Vindhastighed");
}

//initializing rainmeasure
void initRain(void)
{
  attachInterrupt(0, Rain_Measure, RISING); //analog port 0
  LastRainReset = millis();
  Serial.println("* Regn");
}    

//Counts amount of rain
void Rain_Measure(void)
{
  volatile byte hit = 1;
  if (hit == 1) {
    hit = 2;
  } else if (hit == 2) {
    hit = 3;
  } else if (hit == 3) {
    RainMeasurement = RainMeasurement + 0.2794;
    hit = 1;
  }  
}

//Prints winddirection
String printWindDirection(byte y)
{
   // read the analog input into a variable:
   String windDir = "unknown";
   float voltage = analogRead(0)/204.6;   
   for (int i = 0; i < 16; i++) {
     if (voltage <= table[i]+0.03 && voltage >= table[i]-0.03) {
       angle = i;
       break;
     }
   } 
   //Serial.println(angle); //print the result
   switch (angle) {
     case 0:
       windDir = "N";
       break;
     case 1:
       windDir = "NNE";
       break;       
     case 2:
       windDir = "NE";
       break;       
     case 3:
       windDir = "E";
       break;       
     case 4:
       windDir = "E";
       break;       
     case 5:
       windDir = "E";
       break;       
     case 6:
       windDir = "SE";  
       break;       
     case 7:
       windDir = "SSE";
       break;       
     case 8:
       windDir = "S";
       break;       
     case 9:
       windDir = "SW";
       break;       
     case 10:
       windDir = "SW";
       break;       
     case 11:
       windDir = "WSW";
       break;       
     case 12:
       windDir = "W";
       break;       
     case 13:
       windDir = "WNW";
       break;       
     case 14:
       windDir = "NW";
       break;       
     case 15:
       windDir = "NNW";
       break;        
     default:
       break;
   }
   return windDir;
}  

//Prints windspeed
int Vind_GetHastighed()
{
  /*
  The cup-type anemometer measures wind speed by closing a contact as 
  a magnet moves past a switch.  A wind speed of 1.492 MPH (2.4 km/h) 
  causes the switch to close once per second.
  */ 

  //Check using Interrupt
  float windDtime =  millis()-windTimer;
  windTimer = millis();
  windDtime = windDtime/1000;
  float windSpeed = windRotation/windDtime;//rotation per second
  windRotation = 0;  
  windSpeed = windSpeed*2/3;//1 rotation per second equals 2.4 km/h = 2/3 m/s
  return int(windSpeed);
}

void windSpeed()
{
  windRotation++;
}


Solution 1:[1]

Arduino has the F() macro for constant strings to simply indicate that the string should be used from the 'ROM' flash memory of Harvard architecture CPU and not loaded into 'dynamic memory' (RAM). By wrapping constant strings into F macro you reduce the usage of RAM.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Juraj