Как уменьшить объём занимаемой динамической памяти?
- Войдите на сайт для отправки комментариев
Пнд, 27/03/2017 - 05:38
Пишу скетч для оранжереи. Управление светом, помпой. И индикация для начала. Пишу для UNO/NANO.
В общем компилятор пишет
Скетч использует 17298 байт (53%) памяти устройства. Всего доступно 32256 байт.
Глобальные переменные используют 1638 байт (79%) динамической памяти, оставляя 410 байт для локальных переменных. Максимум: 2048 байт.
Недостаточно памяти, программа может работать нестабильно.
Скетч работает но зависает на второй третий цикл LOOP
Это после того как я добавил LCD OLED 128X64 I2C стало не хватать памяти. В начале использовал русифицированую библиотеку LCD вообще 99%. Перешол на #include <Adafruit_SSD1306.h> стало 79%.
Вот скетч туда ещё не вставил код для управления помпой и светом отдельно без LCD всё работает памяти хватает.
#include <stdio.h>
#include <DS1302.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include "DHT.h" //DHT_sensor_library DHT_U
#define OLED_RESET 3
Adafruit_SSD1306 display(OLED_RESET);
#define DHTPIN 4
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
namespace {
const int kCePin = 2; // Chip Enable
const int kIoPin = 10; // Input/Output
const int kSclkPin = 7; // Serial Clock
// Create a DS1302 object.
DS1302 rtc(kCePin, kIoPin, kSclkPin);
String dayAsString(const Time::Day day) {
switch (day) {
case Time::kSunday: return "Sunday";
case Time::kMonday: return "Monday";
case Time::kTuesday: return "Tuesday";
case Time::kWednesday: return "Wednesday";
case Time::kThursday: return "Thursday";
case Time::kFriday: return "Friday";
case Time::kSaturday: return "Saturday";
}
return "(unknown day)";
}
void printTime() {
// Get the current time and date from the chip.
Time t = rtc.time();
// Name the day of the week.
const String day = dayAsString(t.day);
// Format the time and date and insert into the temporary buffer.
char buf[50];
snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d",
day.c_str(),
t.yr, t.mon, t.date,
t.hr, t.min, t.sec);
// Print the formatted string to serial so we can see the time.
Serial.println(buf);
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println(buf);
display.display();
delay(2000);
display.clearDisplay();
}
}
void setup()
{
Serial.begin(9600);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
dht.begin();
display.clearDisplay();
}
void loop()
{
indTempHum ();
delay(300);
printTime();
delay(300);
testdrawline();
}
void indTempHum (void) { //функция индикации температуры и влажности
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(h) || isnan(t)) {
display.clearDisplay();
display.setTextSize(3);
display.setTextColor(WHITE);
display.setCursor(0, 20);
display.println("SENSOR ERROR!");
display.display();
display.clearDisplay();
return;
}
else {
display.setTextSize(3);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("t");
display.setCursor(30, 0);
display.println(t);
display.setCursor(0, 30);
display.println("h");
display.setCursor(30, 30);
display.println(h);
display.display();
delay(300);
display.clearDisplay();
return;
}
}
void testdrawline() { //функция для украшательств не доработана
display.drawLine(0, 0, 0, 64, WHITE);
display.display();
display.drawLine(0, 0, 128, 0, WHITE);
display.display();
display.drawLine(0, 0, 128, 1, WHITE);
display.display();
delay(1);
}
хватает. Вот библиотека для DHT, которую я использую, включает три датчика DHT11 DHT21 и DHT22.
Нашёл библиотек только под DHT11, думаю с ней бужет меньше занимать дин памяти, но я не понимаю как по файлам *.cpp и *.h понять что писать в скетче. Сопостовлял пытался не понял. Подскажите.
Вот dht11.cpp
// // FILE: dht11.cpp // VERSION: 0.4.1 // PURPOSE: DHT11 Temperature & Humidity Sensor library for Arduino // LICENSE: GPL v3 (http://www.gnu.org/licenses/gpl.html) // // DATASHEET: http://www.micro4you.com/files/sensor/DHT11.pdf // // HISTORY: // George Hadjikyriacou - Original version (??) // Mod by SimKard - Version 0.2 (24/11/2010) // Mod by Rob Tillaart - Version 0.3 (28/03/2011) // + added comments // + removed all non DHT11 specific code // + added references // Mod by Rob Tillaart - Version 0.4 (17/03/2012) // + added 1.0 support // Mod by Rob Tillaart - Version 0.4.1 (19/05/2012) // + added error codes // #include "dht11.h" // Return values: // DHTLIB_OK // DHTLIB_ERROR_CHECKSUM // DHTLIB_ERROR_TIMEOUT int dht11::read(int pin) { // BUFFER TO RECEIVE uint8_t bits[5]; uint8_t cnt = 7; uint8_t idx = 0; // EMPTY BUFFER for (int i=0; i< 5; i++) bits[i] = 0; // REQUEST SAMPLE pinMode(pin, OUTPUT); digitalWrite(pin, LOW); delay(18); digitalWrite(pin, HIGH); delayMicroseconds(40); pinMode(pin, INPUT); // ACKNOWLEDGE or TIMEOUT unsigned int loopCnt = 10000; while(digitalRead(pin) == LOW) if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT; loopCnt = 10000; while(digitalRead(pin) == HIGH) if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT; // READ OUTPUT - 40 BITS => 5 BYTES or TIMEOUT for (int i=0; i<40; i++) { loopCnt = 10000; while(digitalRead(pin) == LOW) if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT; unsigned long t = micros(); loopCnt = 10000; while(digitalRead(pin) == HIGH) if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT; if ((micros() - t) > 40) bits[idx] |= (1 << cnt); if (cnt == 0) // next byte? { cnt = 7; // restart at MSB idx++; // next byte! } else cnt--; } // WRITE TO RIGHT VARS // as bits[1] and bits[3] are allways zero they are omitted in formulas. humidity = bits[0]; temperature = bits[2]; uint8_t sum = bits[0] + bits[2]; if (bits[4] != sum) return DHTLIB_ERROR_CHECKSUM; return DHTLIB_OK; } // // END OF FILE //
И вот dht11.h
// // FILE: dht11.h // VERSION: 0.4.1 // PURPOSE: DHT11 Temperature & Humidity Sensor library for Arduino // LICENSE: GPL v3 (http://www.gnu.org/licenses/gpl.html) // // DATASHEET: http://www.micro4you.com/files/sensor/DHT11.pdf // // URL: http://playground.arduino.cc/Main/DHT11Lib // // HISTORY: // George Hadjikyriacou - Original version // see dht.cpp file // #ifndef dht11_h #define dht11_h #if defined(ARDUINO) && (ARDUINO >= 100) #include <Arduino.h> #else #include <WProgram.h> #endif #define DHT11LIB_VERSION "0.4.1" #define DHTLIB_OK 0 #define DHTLIB_ERROR_CHECKSUM -1 #define DHTLIB_ERROR_TIMEOUT -2 class dht11 { public: int read(int pin); int humidity; int temperature; }; #endif // // END OF FILE //
Первое, что бросается в глаза - обилие текстовых строк. В том виде как Вы их используете - они жрут ОЗУ как маманегарюй. Судя по тому, что выдал компилятор - место в памяти программ еще есть, и предостаточно. Уберите в память программ все константные текстовые строки. Это навскидку, подробнее не разбирался.
Я имею в виду вот это и тому подобное
caseTime::kSunday:return"Sunday";024caseTime::kMonday:return"Monday";025caseTime::kTuesday:return"Tuesday";026caseTime::kWednesday:return"Wednesday";027caseTime::kThursday:return"Thursday";028caseTime::kFriday:return"Friday";029caseTime::kSaturday:return"Saturday";030serega374, дисплей 128х64 - коварная штука: для пиксельной адресации необходим экранный буфер, а для контроллеров на Атмере 328 этот буфер отжирает сразу половину всей доступной памяти.
Если Вам нужен только текстовый вывод либо текст+пиктограммы, но не нужна пиксельная графика, используйте для дисплея библиотеку, не содержашую экранного буфера.