如何解决ESP8266 NodeMCU堆满了
我正在尝试使用Twilio,Firebase和Arduino IDE创建SMS警报。我正在使用传感器测量温度。如果温度高于指定值(ESP从Firebase实时数据库读取该值),则应使用twilio发送SMS。我还将措施存储在Firebase实时数据库中。该代码运行良好,直到我再次尝试从Firebase检索数据并再次设置数据两次。我相信我快用完了。我只剩下1万堆内存,无法通过Twilio发送SMS。它仅打印:connecting to api.twilio.com
,但我没有收到消息。
这是我的代码:
#include <ESP8266WiFi.h>
#include <FirebaseESP8266.h>
#include "OneWire.h"
#include "DallasTemperature.h"
#include "twilio.hpp"
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
#define FIREBASE_HOST "***.firebaseio.com"
#define FIREBASE_AUTH "****"
#define WIFI_SSID "*****"
#define WIFI_PASSWORD "****"
const char fingerprint[] = "BC B0 1A 32 80 5D E6 E4 A2 29 66 2B 08 C8 E0 4C 45 29 3F D0";
const char* account_sid = "******";
const char* auth_token = "*******";
String to_number = "+*****";
String from_number = "+*****";
String message_body = "Hello from Twilio and the ESP8266!";
// The 'authorized number' to text the ESP8266 for our example
String master_number = "+******";
// Optional - a url to an image. See 'MediaUrl' here:
// https://www.twilio.com/docs/api/rest/sending-messages
String media_url = "";
// Global twilio objects
Twilio *twilio;
ESP8266WebServer twilio_server(8000);
// Optional software serial debugging
#if USE_SOFTWARE_SERIAL == 1
#include <SoftwareSerial.h>
// You'll need to set pin numbers to match your setup if you
// do use Software Serial
extern SoftwareSerial swSer(14,4,false,256);
#else
#define swSer Serial
#endif
#define ONE_WIRE_BUS 4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
float temp1 = 0;
FirebaseData *firebaseData1 = new FirebaseData();
FirebaseData *firebaseData2 = new FirebaseData();
FirebaseData *firebaseData3 = new FirebaseData();
FirebaseData firebaseData;
FirebaseData firebaseData4;
FirebaseJson tms;
FirebaseJsonArray arr;
unsigned long sendDataPrevMillis = 0;
String path = "/Test/Stream";
int count = 0;
int sms = 0;
String c;
int b;
bool deallocated = false;
void printResult(FirebaseData &data);
void printResult(StreamData &data);
void streamCallback(StreamData data)
{
Serial.println("Stream Data1 available...");
Serial.println("STREAM PATH: " + data.streamPath());
Serial.println("EVENT PATH: " + data.dataPath());
Serial.println("DATA TYPE: " + data.dataType());
Serial.println("EVENT TYPE: " + data.eventType());
Serial.print("VALUE: ");
printResult(data);
Serial.println();
}
void streamTimeoutCallback(bool timeout)
{
if (timeout)
{
Serial.println();
Serial.println("Stream timeout,resume streaming...");
Serial.println();
}
}
void setup()
{
Serial.begin(115200);
WiFiManager wm;
bool res;
res = wm.autoConnect("AutoConnectAP","password"); // password protected ap
if(!res) {
Serial.println("Failed to connect");
// ESP.restart();
}
else {
Serial.println("connected...yeey :)");
}
twilio = new Twilio(account_sid,auth_token,fingerprint);
sensors.begin();
twilio_server.begin();
Firebase.begin(FIREBASE_HOST,FIREBASE_AUTH);
Firebase.reconnectWiFi(true);
//Set the size of WiFi rx/tx buffers in the case where we want to work with large data.
firebaseData1->setBSSLBufferSize(1024,1024);
//Set the size of HTTP response buffers in the case where we want to work with large data.
firebaseData1->setResponseSize(1024);
//Set the size of WiFi rx/tx buffers in the case where we want to work with large data.
firebaseData2->setBSSLBufferSize(1024,1024);
//Set the size of HTTP response buffers in the case where we want to work with large data.
firebaseData2->setResponseSize(1024);
if (!Firebase.beginStream(*firebaseData1,path))
{
Serial.println("------------------------------------");
Serial.println("Can't begin stream connection...");
Serial.println("REASON: " + firebaseData1->errorReason());
Serial.println("------------------------------------");
Serial.println();
}
Firebase.setStreamCallback(*firebaseData1,streamCallback,streamTimeoutCallback);
}
void loop()
{
if (millis() - sendDataPrevMillis > 5000)
{
sendDataPrevMillis = millis();
sensors.requestTemperatures();
temp1 = sensors.getTempCByIndex(0);
Serial.print("");
tms.set(".sv","timestamp");
if (Firebase.getString(firebaseData,"002/alarm")) {
if (firebaseData.dataType() == "string") {
Serial.println(firebaseData.stringData());
}
} else {
Serial.println(firebaseData.errorReason());
}
int myInt = firebaseData.stringData().toInt();
if (temp1 < myInt) {
if(Firebase.setInt(*firebaseData3,"/serial/sms",sms))
{
Serial.println("PASSED");
Serial.println("PATH: " + firebaseData3->dataPath());
Serial.println("TYPE: " + firebaseData3->dataType());
Serial.print("VALUE: ");
printResult(*firebaseData3);
Serial.println("------------------------------------");
Serial.println();
}
else
{
Serial.println("FAILED");
Serial.println("REASON: " + firebaseData3->errorReason());
Serial.println("------------------------------------");
Serial.println();
}
}
if (Firebase.getInt(firebaseData4,"/serial/sms")) {
if (firebaseData4.dataType() == "int") {
Serial.println(firebaseData4.intData());
}
} else {
Serial.println(firebaseData4.errorReason());
}
if (temp1 > myInt) {
if(firebaseData4.intData() < 1){
sms++;
String response;
bool success = twilio->send_message(
to_number,from_number,message_body,response,media_url
);
if(Firebase.setInt(*firebaseData3,sms))
{
Serial.println("PASSED");
Serial.println("PATH: " + firebaseData3->dataPath());
Serial.println("TYPE: " + firebaseData3->dataType());
Serial.print("VALUE: ");
printResult(*firebaseData3);
Serial.println("------------------------------------");
Serial.println();
}
else
{
Serial.println("FAILED");
Serial.println("REASON: " + firebaseData3->errorReason());
Serial.println("------------------------------------");
Serial.println();
}
}
}
Serial.println(ESP.getFreeHeap());
delay(0);
count++;
Serial.println("------------------------------------");
Serial.println("Set Int...");
arr.clear();
arr.set("/[0]",temp1);
arr.set("/[1]",tms);
if (Firebase.push(*firebaseData2,path + "/Int",arr))
{
Serial.println("PASSED");
Serial.println("PATH: " + firebaseData2->dataPath());
Serial.println("TYPE: " + firebaseData2->dataType());
Serial.print("VALUE: ");
printResult(*firebaseData2);
Serial.println("------------------------------------");
Serial.println();
}
else
{
Serial.println("FAILED");
Serial.println("REASON: " + firebaseData2->errorReason());
Serial.println("------------------------------------");
Serial.println();
}
if (count == 1)
{
Serial.println("Deallocate the Firebase Data objects after 3 times Firebasse call");
//Need to stop the stream to prevent the readStream and callback to be called after objects deallocation
Firebase.endStream(*firebaseData1);
Firebase.removeStreamCallback(*firebaseData1);
//Deallocate
delete firebaseData1;
delete firebaseData2;
firebaseData1 = nullptr;
firebaseData2 = nullptr;
count = 0;
}
}
}
//Helper function for printing the response/received data
void printResult(FirebaseData &data)
{
if (data.dataType() == "int")
Serial.println(data.intData());
else if (data.dataType() == "float")
Serial.println(data.floatData(),5);
else if (data.dataType() == "double")
printf("%.9lf\n",data.doubleData());
else if (data.dataType() == "boolean")
Serial.println(data.boolData() == 1 ? "true" : "false");
else if (data.dataType() == "string")
Serial.println(data.stringData());
else if (data.dataType() == "json")
{
Serial.println();
FirebaseJson &json = data.jsonObject();
//Print all object data
Serial.println("Pretty printed JSON data:");
String jsonStr;
json.toString(jsonStr,true);
Serial.println(jsonStr);
Serial.println();
Serial.println("Iterate JSON data:");
Serial.println();
size_t len = json.iteratorBegin();
String key,value = "";
int type = 0;
for (size_t i = 0; i < len; i++)
{
json.iteratorGet(i,type,key,value);
Serial.print(i);
Serial.print(",");
Serial.print("Type: ");
Serial.print(type == FirebaseJson::JSON_OBJECT ? "object" : "array");
if (type == FirebaseJson::JSON_OBJECT)
{
Serial.print(",Key: ");
Serial.print(key);
}
Serial.print(",Value: ");
Serial.println(value);
}
json.iteratorEnd();
}
else if (data.dataType() == "array")
{
Serial.println();
//get array data from FirebaseData using FirebaseJsonArray object
FirebaseJsonArray &arr = data.jsonArray();
//Print all array values
Serial.println("Pretty printed Array:");
String arrStr;
arr.toString(arrStr,true);
Serial.println(arrStr);
Serial.println();
Serial.println("Iterate array values:");
Serial.println();
for (size_t i = 0; i < arr.size(); i++)
{
Serial.print(i);
Serial.print(",Value: ");
FirebaseJsonData &jsonData = data.jsonData();
//Get the result data from FirebaseJsonArray object
arr.get(jsonData,i);
if (jsonData.typeNum == FirebaseJson::JSON_BOOL)
Serial.println(jsonData.boolValue ? "true" : "false");
else if (jsonData.typeNum == FirebaseJson::JSON_INT)
Serial.println(jsonData.intValue);
else if (jsonData.typeNum == FirebaseJson::JSON_FLOAT)
Serial.println(jsonData.floatValue);
else if (jsonData.typeNum == FirebaseJson::JSON_DOUBLE)
printf("%.9lf\n",jsonData.doubleValue);
else if (jsonData.typeNum == FirebaseJson::JSON_STRING ||
jsonData.typeNum == FirebaseJson::JSON_NULL ||
jsonData.typeNum == FirebaseJson::JSON_OBJECT ||
jsonData.typeNum == FirebaseJson::JSON_ARRAY)
Serial.println(jsonData.stringValue);
}
}
else
{
Serial.println(data.payload());
}
}
//Helper function for printing the response/received stream data
void printResult(StreamData &data)
{
if (data.dataType() == "int")
Serial.println(data.intData());
else if (data.dataType() == "float")
Serial.println(data.floatData(),data.doubleData());
else if (data.dataType() == "boolean")
Serial.println(data.boolData() == 1 ? "true" : "false");
else if (data.dataType() == "string" || data.dataType() == "null")
Serial.println(data.stringData());
else if (data.dataType() == "json")
{
Serial.println();
FirebaseJson *json = data.jsonObjectPtr();
//Print all object data
Serial.println("Pretty printed JSON data:");
String jsonStr;
json->toString(jsonStr,true);
Serial.println(jsonStr);
Serial.println();
Serial.println("Iterate JSON data:");
Serial.println();
size_t len = json->iteratorBegin();
String key,value = "";
int type = 0;
for (size_t i = 0; i < len; i++)
{
json->iteratorGet(i,Value: ");
Serial.println(value);
}
json->iteratorEnd();
}
else if (data.dataType() == "array")
{
Serial.println();
//get array data from FirebaseData using FirebaseJsonArray object
FirebaseJsonArray *arr = data.jsonArrayPtr();
//Print all array values
Serial.println("Pretty printed Array:");
String arrStr;
arr->toString(arrStr,true);
Serial.println(arrStr);
Serial.println();
Serial.println("Iterate array values:");
Serial.println();
for (size_t i = 0; i < arr->size(); i++)
{
Serial.print(i);
Serial.print(",Value: ");
FirebaseJsonData *jsonData = data.jsonDataPtr();
//Get the result data from FirebaseJsonArray object
arr->get(*jsonData,i);
if (jsonData->typeNum == FirebaseJson::JSON_BOOL)
Serial.println(jsonData->boolValue ? "true" : "false");
else if (jsonData->typeNum == FirebaseJson::JSON_INT)
Serial.println(jsonData->intValue);
else if (jsonData->typeNum == FirebaseJson::JSON_FLOAT)
Serial.println(jsonData->floatValue);
else if (jsonData->typeNum == FirebaseJson::JSON_DOUBLE)
printf("%.9lf\n",jsonData->doubleValue);
else if (jsonData->typeNum == FirebaseJson::JSON_STRING ||
jsonData->typeNum == FirebaseJson::JSON_NULL ||
jsonData->typeNum == FirebaseJson::JSON_OBJECT ||
jsonData->typeNum == FirebaseJson::JSON_ARRAY)
Serial.println(jsonData->stringValue);
}
}
}
我在每个循环后都会释放Firebase Data对象,但是,我相信我仍然没有足够的堆。您对如何优化代码并获得更多内存有任何建议吗?
任何帮助将不胜感激!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。