Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用多个传感器克服Arduino内存限制_C++_Performance_Memory Management_Arduino_Ethernet - Fatal编程技术网

C++ 使用多个传感器克服Arduino内存限制

C++ 使用多个传感器克服Arduino内存限制,c++,performance,memory-management,arduino,ethernet,C++,Performance,Memory Management,Arduino,Ethernet,我有一个搭载在ENC28j60以太网模块上的Arduino Nano。我有八(8)个DHT22传感器(名为A、B、C…H),我想将它们的温度和湿度数据写入Pushingbox 该计划是伟大的工作与一个传感器。那很好。但是,当我对超过一个传感器的任何内容取消注释(即取出//)时,即使是对另一个传感器,它也不会写入任何内容 arduino IDE编译器说: Sketch uses 23824 bytes (77%) of program storage space. Maximum is 30720

我有一个搭载在ENC28j60以太网模块上的Arduino Nano。我有八(8)个DHT22传感器(名为A、B、C…H),我想将它们的温度和湿度数据写入Pushingbox

该计划是伟大的工作与一个传感器。那很好。但是,当我对超过一个传感器的任何内容取消注释(即取出//)时,即使是对另一个传感器,它也不会写入任何内容

arduino IDE编译器说:

Sketch uses 23824 bytes (77%) of program storage space. Maximum is 30720 bytes.
Global variables use 1870 bytes (91%) of dynamic memory, leaving 178 bytes for local variables. Maximum is 2048 bytes.
Low memory available, stability problems may occur.
仅供参考,如果我只取下另一个传感器,它将上升+2%至93%的动态内存并停止工作。所以我假设这是一个记忆问题。我已经删除了所有的
浮点数
(并使整数
*10
保持精度的小数点后一位),我需要8个DHT实例,因此考虑减小库大小,但.h看起来很小,而且已经很瘦了(在.h文件中,它甚至吹嘘:
内存占用非常低-代码非常小
。因此我没有修改这个或.cpp

我写的代码总量不大,可能效率有一些提高,但我看不出它能为接下来的7个传感器节省多少内存

完整的arduino代码(为所有8个传感器编写,4个传感器使用“重影”位,仅为一个传感器使用)如下:

#include "DHTesp.h"
//#include <SPI.h>
#include <UIPEthernet.h>

DHTesp dhtA;
//DHTesp dhtB; 
//DHTesp dhtC;
//DHTesp dhtD;
//DHTesp dhtE;
//DHTesp dhtF;
//DHTesp dhtG;
//DHTesp dhtH;


const int ledPin =  LED_BUILTIN; 
int ledState = LOW;

int interval = 10; // this is the number of seconds between reads (120=2mins)
int numReads = 5;   // Number of reads between posting to google docs.
int multFact = 10;   // multiplication factor 10 = 1 dec. place 100 = 2 dec places

byte mac[] = {0xBE, 0xEF, 0xDE, 0xAD, 0xDE, 0xAD };  //Ethernet shield MAC. Andy's working {0xBE, 0xEF, 0xDE, 0xAD, 0xDE, 0xAD}
byte ip[] = { 192,168,1,12 };     //  Arduino device IP address     
char devid [] = "vCE3D036xxxxxxxx";  // Gsheets device ID from Pushingbox ('x's for privacy:)

char server[] = "api.pushingbox.com";
EthernetClient client;


void setup()
{
  Serial.begin(9600);
  Serial.println ("RESTART");

  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.println("Trying to connect...");
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }
  else{
    Serial.print("OK, connected. Ethernet ready. ");
    // print the Ethernet board/shield's IP address:
    Serial.print("IP address: ");
    Serial.println(Ethernet.localIP());
  }

  // give the Ethernet shield a second to initialize:
  delay(1000);   
  Serial.println();
  //Serial.println("A-Stat\t\tA-Temp (C)\tA-humdid%\tA-HeatI (C)\tB-Stat\t\tB-Temp (C)\tA-humdid%\tB-HeatI (C)");
  Serial.println("\t\t\t\tt-A\th-A\tt-B\th-B\tt-C\th-C\tt-D\th-D\tt-E\th-E\tt-F\th-F\tt-G\th-G\tt-H\th-H");

  //hey dB for some reason the Ethernet sheild uses pin D2 :(      and pins 10,11,12,13
  // https://arduinodiy.wordpress.com/2013/04/07/connect-an-enc28j60-ethernet-module-to-an-arduino/

  // assign data pins
  dhtA.setup(3); 
  //dhtB.setup(4);
  //dhtC.setup(5); 
  //dhtD.setup(6);
  //dhtE.setup(7); 
  //dhtF.setup(8);
  //dhtG.setup(9); 
  //dhtH.setup(10); //watchout! i think Ethernet uses this pin too?
  pinMode(ledPin, OUTPUT);

 //end of void setup 
}


void loop()
{
  int Ahumid = 0;  int Atemp = 0;
  int Bhumid = 0;  int Btemp = 0;
  int Chumid = 0;  int Ctemp = 0;
  int Dhumid = 0;  int Dtemp = 0;
  //int Ehumid = 0;  int Etemp = 0;
  //int Fhumid = 0;  int Ftemp = 0;
  //int Ghumid = 0;  int Gtemp = 0;
  //int Hhumid = 0;  int Htemp = 0;

  int j=0;
  for (j = 1; j <= numReads ; j++ ) {

    int p = 0;
    for (p=1; p <= interval ; p++) {
      delay (1000);
      // swap the led state
      if (ledState == LOW) { ledState = HIGH; } else { ledState = LOW; }
      Serial.print (p); //show the seconds passing
      Serial.print (",");
      digitalWrite(ledPin, ledState);
    }

    Serial.print (" Reading");
    Atemp += dhtA.getTemperature()*multFact;  Ahumid += dhtA.getHumidity()*multFact;
    //Btemp += dhtB.getTemperature()*multFact;  Bhumid += dhtB.getHumidity()*multFact;
    //Ctemp += dhtC.getTemperature()*multFact;   Chumid += dhtC.getHumidity()*multFact;  
    //Dtemp += dhtD.getTemperature()*multFact;   Dhumid += dhtD.getHumidity()*multFact;

    // print the readings
    //Serial.print(dhtA.getStatusString());
    Serial.print("\t"); Serial.print(Atemp); 
    Serial.print("\t"); Serial.print(Ahumid);

    Serial.print("\t"); Serial.print(Btemp); 
    Serial.print("\t"); Serial.print(Bhumid);

    Serial.print("\t"); Serial.print(Ctemp);
    Serial.print("\t"); Serial.print(Chumid);

    Serial.print("\t"); Serial.print(Dtemp);
    Serial.print("\t"); Serial.print(Dhumid);
    Serial.println();
    // and so here endeth 'j', the number of reads
  }

  Serial.print ("Avg...");
  Atemp = Atemp/numReads;    Ahumid = Ahumid/numReads;
  Btemp = Btemp/numReads;    Bhumid = Bhumid/numReads;
  Ctemp = Ctemp/numReads;    Chumid = Chumid/numReads;
  Dtemp = Dtemp/numReads;    Dhumid = Dhumid/numReads;

  // print the averages so we can see what it is going to send
  Serial.print("\t\t\t");
  Serial.print("\t");  Serial.print(Atemp); Serial.print("\t"); Serial.print(Ahumid);
  Serial.print("\t");  Serial.print(Btemp); Serial.print("\t"); Serial.print(Bhumid);
  Serial.print("\t");  Serial.print(Ctemp); Serial.print("\t"); Serial.print(Chumid);
  Serial.print("\t");  Serial.print(Dtemp); Serial.print("\t"); Serial.print(Dhumid);
  Serial.println();

  Serial.print ("Prep for upload... ");
  if (client.connect(server, 80)) 
  {
    Serial.print("Connected OK ... writing...");

    client.print("GET /pushingbox?devid=");
    client.print(devid);
    client.print("&tempA=");     client.print(Atemp);
    client.print("&tempB=");     client.print(Btemp);
    client.print("&tempC=");     client.print(Ctemp);
    client.print("&tempD=");     client.print(Dtemp);
    client.print("&tempE=29&tempF=39&tempG=49&tempH=59");
    //now humidity too
    client.print("&humidA=");     client.print(Ahumid);
    client.print("&humidB=");     client.print(Bhumid);
    client.print("&humidC=");     client.print(Chumid);
    client.print("&humidD=");     client.print(Dhumid);
    client.print("&humidE=26&humidF=27&humidG=28&humidH=29");
    client.print("&submit=Submit");
    client.println(" HTTP/1.1"); 
    client.println("Host: api.pushingbox.com");
    client.println("Connection: close");
    client.println();

    Serial.println("written OK. & connection closed.");
    Serial.println(); //Serial.println();

    delay(1000); // maybe take this out to keep time stable?
    client.stop(); 
  }
  else {
    Serial.println("** NO CONNEX **"); Serial.println(); 
  }

//here endeth void loop     
}

将F宏用于双引号字符串文字打印。而不是:

Serial.println ("RESTART");
       or
client.print("GET /pushingbox?devid=");
…这样做:

Serial.println ( F("RESTART") );
       or
client.print( F("GET /pushingbox?devid=") );
这将很容易节省大量内存

我还建议对单个字符使用单引号,而不是双引号:

Serial.print( '\t' );

将F宏用于双引号字符串文字打印。而不是:

Serial.println ("RESTART");
       or
client.print("GET /pushingbox?devid=");
…这样做:

Serial.println ( F("RESTART") );
       or
client.print( F("GET /pushingbox?devid=") );
这将很容易节省大量内存

我还建议对单个字符使用单引号,而不是双引号:

Serial.print( '\t' );

将所有的<代码>串行。打印< /代码>字符串文字用作用户的消息。这是捆绑一组2K的SRAM。也可以编写一个例程来查询每个传感器,用一组分配与一次分配所有8个传感器的内存吗?@ USER 2206361:考虑使用UINT8YT代替INT数据类型来减少。只要发现可行,变量的大小。Thx@Joe和@seccpur。我试着去掉了大部分的
串行打印,91%的动态内存减少到87%。所以这是一个开始,但离需要的还差得远。我看不出这怎么可能是一些
int
s的内存使用-我有比这个小东西大得多的程序运行正常。但是一个调用传感器“n”的例程可能会让它运行起来……为什么你要在Nano上使用ESP32库?减少所有那些
串行。打印只用作给用户的消息的字符串文本。这会占用一堆2k的SRAM。你还可以编写一个例程来查询每个传感器,使用一组分配器吗ONE2206361:考虑到使用INUT88T代替INT数据类型来减少变量的大小,每当找到可行的时候。THX @乔和@ SeCcPUR。我试着把大部分的<代码>串行。打印< /代码> S和91%减少到动态存储器的87%。所以这是一个开始,但是没有什么需要的。我不能。看看它是如何使用一些
int
s的内存的-我有比这个小东西大得多的程序运行正常。但是一个调用sensor'n'的例程可能会让它运行起来……你为什么要在Nano上使用ESP32库?谢谢@slash dev的建议,我不知道
F(
会将它们移动到Progmem而不是RAM。谢谢。+现在会让这成为一个热门话题。后续问题:为什么你会建议
而不是
?这也是一个内存问题,还是仅仅是一个好语法?使用单引号效率略高一些,但这是一个好习惯。双引号字符串实际上有一个“不可见的”NUL终止符(零字节),因此它使用2字节的RAM而不是1字节。此外,双引号字符串必须通过地址传递给
print
函数,而单引号字符可以通过值传递(在堆栈上)。代码稍微少一点,执行速度也快一点。非常好的信息@slash-dev。仅供参考您的建议这将mem的使用率(从91%)降低到70%,因此希望能够使用8个DHT22实例。感谢@slash-dev的建议,我不知道
F(
会将它们移动到Progmem而不是RAM。谢谢。+现在会让这成为一个热门话题。后续问题:为什么你会建议
而不是
?这也是一个内存问题,还是仅仅是一个好语法?使用单引号效率略高一些,但这是一个好习惯。双引号字符串实际上有一个“不可见的”NUL终止符(零字节),因此它使用2字节的RAM而不是1字节。此外,双引号字符串必须通过地址传递给
print
函数,而单引号字符可以通过值传递(在堆栈上)。代码稍微少一点,执行速度稍微快一点。很棒的信息@slash-dev。仅供参考您的建议,这将使用的内存(从91%)减少到70%,所以希望能够使用8个DHT22实例。