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 的使用。
我有一个天气计,我可以从中读取数据。
我的问题出现了,当我尝试使用库时 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 的使用。