Arduino Uno - 最小化内存使用

Arduino Uno - minimize memory usage

我有一个天气计,我可以从中读取数据。

我的问题出现了,当我尝试使用库时 UnoWiFiDevEd.h 发送数据以在 Internet 上存储信息。

Arduino 说明如下:

全局变量使用 1648 字节 (80%) 的动态内存,为局部变量留下 400 字节。 最大为 2048 字节。可用内存不足,可能会出现稳定性问题。

我读到,另一种说法是,Uno WiFi 库本身导致了近 50% 的动态内存使用。

有没有人知道我如何才能最大限度地减少内存使用量?

提前致谢

#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++;
}

Arduino 有 the F() macro 用于常量字符串,简单地表明该字符串应该从哈佛架构 CPU 的 'ROM' 闪存中使用,而不是加载到 'dynamic memory' (内存)。通过将常量字符串包装到 F 宏中,可以减少 RAM 的使用。