【问题标题】:Arduino Uno Wifi - minimize memory usageArduino Uno Wifi - 最小化内存使用
【发布时间】:2020-01-16 15:09:26
【问题描述】:

我有一个气象仪,我可以从中读取数据。

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

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

【问题讨论】:

  • 为什么是 [java] 标签?对常量字符串使用 F 宏 arduino.cc/reference/en/language/variables/utilities/progmem/…
  • 如果有一天你想用你的 Uno WiFi Dev Ed 做更多事情,请将此链接添加为书签github.com/jandrassy/UnoWiFiDevEdSerial1/blob/master/README.md
  • const float table[16] 可以减少 48 个字节,如果您与 byte winddir = analogRead(0)/4; 的值相比,不使用 String 对象比您在编译时看到的节省更多的 RAM。
  • @Juraj 我删除了 Java 标记,这是一个错误。感谢您提供扩展 Uno Wifi Dev 的链接。库@datafiddler 我已将const float table[16] 更改为const float table[48]。我还将方法 printWindDirection(byte y) 和局部变量 windDir 的返回类型更改为字节。程序现在返回:Sketch 使用了 15360 字节(47%)的程序存储空间。最大值为 32256 字节。全局变量使用 1776 字节 (86%) 的动态内存,为局部变量留下 272 字节。最大值为 2048 字节。可用内存不足,可能会出现稳定性问题。
  • @Juraj 你会写你的 F 宏作为答案,这样问题就可以结束了。虽然它有时会返回写入错误,但它总是在我的数据库上提交数据。

标签: arduino arduino-uno arduino-uno-wifi


【解决方案1】:

Arduino 有the F() macro 用于常量字符串,仅表示该字符串应该从哈佛架构 CPU 的“ROM”闪存中使用,而不是加载到“动态内存”(RAM)中。通过将常量字符串包装到 F 宏中,可以减少 RAM 的使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-27
    • 1970-01-01
    • 1970-01-01
    • 2011-04-03
    相关资源
    最近更新 更多