Оптимизация кода для уменьшения размера используемой ОЗУ
- Войдите на сайт для отправки комментариев
День добрый.
Взываю к помощи. В программировании на Си - новичок, поэтому выдержу любые кидания помидорами.
Столкнулся с нехваткой ОЗУ для выполнения необходимых функций на arduino UNO:
Глобальные переменные используют 1 902 байт (92%) динамической памяти, оставляя 146 байт для локальных переменных. Максимум: 2 048 байт.
// Датчик DHT11 подключен к цифровому пину номер 2
// Реле модуль подключен к цифровому выводу 4
// ИК диод подключается на 3 пин
//Часы подключены на 7,8,9 пины
// DS1302: CE RST pin -> Arduino Digital 7
// I/O DATA pin -> Arduino Digital 8
// SCLK CLK pin -> Arduino Digital 9
//Подключение Blynk
#define BLYNK_PRINT Serial
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
#include <SimpleTimer.h>
char auth[] = "1c69d3a8cb2446229cc900e7a7df6fa8";
SimpleTimer timer;
//Подключение бибилиотеки DHT11
#include <dht11.h> // Добавляем библиотеку DHT11
dht11 DHT; // Объявление переменной класса dht11
#define DHT11_PIN 2
// Подключение библиотеки для работы с IR-светодиодом
#include <IRremote.h>
IRsend irsend;
//Модуль реального времени
#include <DS1302.h>
// Часы
DS1302 rtc(7, 8, 9);
//Контакт реле
int Relay = 4;
//Контакт диода
int LED_PIN = 6;
//Переменные для управления кондиционером
byte ConditionerON[349] = {5,180,30,90,5,5,5,15,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,15,5,5,5,5,5,15,5,5,5,5,5,15,5,15,5,15,5,15,5,15,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,15,5,15,5,15,5,15,5,30,30,90,5,15,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,15,5,5,5,5,5,15,5,5,5,15,5,15,5,15,5,15,5,15,5,15,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,30,30,90,5,15,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,15,5,5,5,5,5,5,5,5,5,15,5,15,5,5,5,15,5,15,5,15,5,15,5,15,5,15,5,15,5,15,5,5,5,5,5,5,5,15,5,15,5,15,5,5,5,5,5,5,5,5,5,5,5,15,5,15,5,15,5,5,5,15,5,5,5,5,5,5,5,15,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,15,5,15,5,15,5,15,5
};
byte ConditionerOff[349] = {5,180,30,90,5,5,5,15,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,15,5,5,5,5,5,15,5,15,5,5,5,15,5,15,5,15,5,15,5,15,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,15,5,15,5,30,30,90,5,15,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,15,5,5,5,5,5,15,5,5,5,15,5,15,5,15,5,15,5,15,5,15,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,30,30,90,5,15,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,15,5,5,5,5,5,5,5,15,5,15,5,15,5,5,5,15,5,15,5,15,5,15,5,15,5,15,5,15,5,15,5,5,5,5,5,5,5,15,5,15,5,15,5,5,5,5,5,5,5,5,5,5,5,15,5,15,5,15,5,5,5,15,5,5,5,5,5,5,5,15,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,15,5,15,5
};
boolean STATE_TEMP;
///////////////////////////////////////////////////////////
//Переменные задания температуры
unsigned int TEMP_MAX;
unsigned int TEMP_MIN;
BLYNK_WRITE(V3)
{
int widgetValue_MIN = param.asInt(); // Here we create variable to store incoming values from V1.
Serial.print("MIN TEMP ");
Serial.println(widgetValue_MIN);
TEMP_MIN = widgetValue_MIN;
}
BLYNK_WRITE(V4)
{
int widgetValue_MAX = param.asInt(); // Here we create variable to store incoming values from V1.
Serial.print("MAX TEMP ");
Serial.println(widgetValue_MAX);
TEMP_MAX = widgetValue_MAX;
}
///////////////////////////////////////////////////////////
//Установка интервала считывания данных
long previousMillis = 0;
long interval = 4000;
//Виртуальные переменные
void myTimerEvent(){
Blynk.virtualWrite(V1, DHT.temperature);
Blynk.virtualWrite(V2, DHT.humidity);
}
//Для кириллицы в мониторе порта
char* RUS(char* StrIn){char* StrOut=StrIn; uint8_t i[4]={0,0,StrIn[0],StrIn[1]}; while(i[2]>0&&i[0]<255){if(i[2]==0xd0&&i[3]>0x8F&&i[3]<0xC0){StrOut[i[1]]=i[3]+0x30;i[0]++;}else if(i[2]==0xd0&&i[3]==0x81){StrOut[i[1]]=0xA8;i[0]++;}else if(i[2]==0xd1&&i[3]>0x7F&&i[3]<0x90){StrOut[i[1]]=i[3]+0x70;i[0]++;}else if(i[2]==0xd1&&i[3]==0x91){StrOut[i[1]]=0xB8;i[0]++;}else{StrOut[i[1]]=i[2];} i[0]++; i[1]++; i[2]=StrIn[i[0]]; i[3]=StrIn[i[0]+1];} StrOut[i[1]]='\0'; return StrOut;}
////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup(){
// Set the clock to run-mode, and disable the write protection
rtc.halt(false);
rtc.writeProtect(false);
//Вывод на монитор порта
Serial.begin(9600); // Скорость работы порта
Blynk.begin(auth); //Авторизация в Blynk
// Setup a function to be called every second
timer.setInterval(1000L, myTimerEvent);
pinMode(Relay, OUTPUT); //назначение порта с Реле
pinMode(LED_PIN, OUTPUT); // назначение порта с диодом
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop(){
Blynk.run(); //Запуск Blynk в цикле
timer.run(); // Initiates SimpleTimer
// Выводим показания влажности и температуры датчика/////////////////////////////////
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
// Мониторинг ошибок датчика температуры
int chk;
chk = DHT.read(DHT11_PIN); // Чтение данных
switch (chk){
case DHTLIB_OK:
break;
}
//Часы
// Send date
Serial.print(RUS("Дата "));
Serial.print(rtc.getDateStr());
// Send time
Serial.print(RUS(" Время "));
Serial.print(rtc.getTimeStr());
//Датчики
////int TEMP_MAX = pinValue;
Serial.print(RUS(" Влажность = "));
Serial.print(DHT.humidity, 1);
Serial.print(RUS(", Температура = "));
Serial.print(DHT.temperature,1);
Serial.print(" (");
Serial.print(TEMP_MIN,1);
Serial.print(")");
Serial.print(" - (");
Serial.print(TEMP_MAX,1);
Serial.println(")");
Serial.print("Status ");
Serial.println(STATE_TEMP,1);
}
/////////////////////////////////////////////////////////////////////
//Работа диода
if (DHT.temperature >= TEMP_MAX) digitalWrite(LED_PIN, HIGH);
else if (DHT.temperature <= TEMP_MIN) digitalWrite(LED_PIN, HIGH);
else digitalWrite(LED_PIN, LOW);
//Работа автоматики по температуре
if (DHT.temperature >= TEMP_MAX && STATE_TEMP == LOW)
{
irsend.sendRaw(ConditionerON, 349, 38);
STATE_TEMP = HIGH;
}
if (DHT.temperature <= TEMP_MIN && STATE_TEMP == HIGH)
{
irsend.sendRaw(ConditionerOff, 349, 38);
STATE_TEMP = LOW;
}
}
Кириллица занимает 51 байт. Часы реального времени - 47 байт. Это все от чего я могу отказаться, но лучше от этого не становится. Blynk много берет себе, но его функционал мне понравился и отказываться от него в пользу html не хочу.
Пытался переносить переменные, ужимал все что мог, но знаний в массивах не хватает и понять как можно проще указать количество повторяющихся друг за другом переменных не могу...
Знаю, что надо еще что-то делать с массивами для передачи ИК-сигнала, но я сделал все что смог: поместил длительности интервалов из int в byte и в библиотеке подправил, чтобы умножалось значение на 100 и отправлялось на ИК передатчик.
Почитал этюды для начинающих и прочие форумы, но ничего не понял...
Надеюсь на Ваши советы или хотя бы на ссылки на понятные источники.
ConditionerOn & ConditionerOff разместить во флеше.
Эти же массивы "сжать". Самое тупое, хранить парами "значение, количество", даже это уже сократит массивы. Пятерок там море.
kisoft говорит дело :) Начните с разбора вот такого примера:
byte command[349]; #define RLE_LEN 16 byte RLEcmdOff[ RLE_LEN ] = {1, 5, 1, 180, 1, 30, 1, 90, 3, 5, 1, 15, 15, 5, 1, 15}; // original sequence: 5, 180, 30, 90, 5, 5, 5, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 15 // таким вот образом 24 байта сжимаются до 16 байт void setup() { int ptr = 0; for ( int i = 0; i < RLE_LEN; i += 2 ) for ( byte j = 0; j < RLEcmdOff[ i ]; j++ ) command[ ptr++ ] = RLEcmdOff[ i + 1 ]; // achtung! possible overflow // irsend.sendRaw(command, 349, 38); } void loop() { }Спасибо огромное за пример и советы!
Буду вечером пробовать!
Отпишусь по количеству увеличенной свободной памяти!
Прошу прощения, но я, видимо, где то накосячил.
сделал все так, как в примере, но ОЗУ теперь занимает на 500 байт больше.
В моем коде, видимо, память резервируется и для переменных и для развернутой переменной commandON/OFF. Может если способ очищать ОЗУ после каждого разворачивания переменной command?
// Датчик DHT11 подключен к цифровому пину номер 2 // Реле модуль подключен к цифровому выводу 4 // ИК диод подключается на 3 пин //Часы подключены на 7,8,9 пины // DS1302: CE RST pin -> Arduino Digital 7 // I/O DATA pin -> Arduino Digital 8 // SCLK CLK pin -> Arduino Digital 9 //Подключение Blynk #define BLYNK_PRINT Serial #include <SPI.h> #include <Ethernet.h> #include <BlynkSimpleEthernet.h> #include <SimpleTimer.h> char auth[] = "ХХХ"; SimpleTimer timer; //Подключение бибилиотеки DHT11 #include <dht11.h> // Добавляем библиотеку DHT11 dht11 DHT; // Объявление переменной класса dht11 #define DHT11_PIN 2 // Подключение библиотеки для работы с IR-светодиодом #include <IRremote.h> IRsend irsend; //Модуль реального времени #include <DS1302.h> // Часы DS1302 rtc(7, 8, 9); //Контакт реле int Relay = 4; //Контакт диода int LED_PIN = 6; //Переменные для управления кондиционером // byte ConditionerON[349] = {5,180,30,90,5,5,5,15,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,15,5,5,5,5,5,15,5,5,5,5,5,15,5,15,5,15,5,15,5,15,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,15,5,15,5,15,5,15,5,30,30,90,5,15,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,15,5,5,5,5,5,15,5,5,5,15,5,15,5,15,5,15,5,15,5,15,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,30,30,90,5,15,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,15,5,5,5,5,5,5,5,5,5,15,5,15,5,5,5,15,5,15,5,15,5,15,5,15,5,15,5,15,5,15,5,5,5,5,5,5,5,15,5,15,5,15,5,5,5,5,5,5,5,5,5,5,5,15,5,15,5,15,5,5,5,15,5,5,5,5,5,5,5,15,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,15,5,15,5,15,5,15,5 //}; // byte ConditionerOff[349] = {5,180,30,90,5,5,5,15,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,15,5,5,5,5,5,15,5,15,5,5,5,15,5,15,5,15,5,15,5,15,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,15,5,15,5,30,30,90,5,15,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,15,5,5,5,5,5,15,5,5,5,15,5,15,5,15,5,15,5,15,5,15,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,30,30,90,5,15,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,15,5,5,5,5,5,5,5,15,5,15,5,15,5,5,5,15,5,15,5,15,5,15,5,15,5,15,5,15,5,15,5,5,5,5,5,5,5,15,5,15,5,15,5,5,5,5,5,5,5,5,5,5,5,15,5,15,5,15,5,5,5,15,5,5,5,5,5,5,5,15,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,15,5,15,5 //}; boolean STATE_TEMP; byte commandON[349]; byte commandOFF[349]; #define RLE_LEN 228 byte RLEcmdON[ RLE_LEN ] = {1,5,1,180,1,30,1,90,3,5,1,15,15,5,1,15,5,5,1,15,5,5,1,15,1,5,1,15,1,5,1,15,1,5,1,15,1,5,1,15,1,5,64,5,1,15,1,5,1,15,1,5,1,15,1,5,1,15,1,5,2,30,1,90,1,5,1,15,1,5,16,5,1,15,1,5,4,5,1,15,1,5,2,5,1,15,1,5,1,15,1,5,1,15,1,5,1,15,1,5,1,15,1,5,1,15,1,5,72,5,2,30,1,90,1,5,1,15,1,5,16,5,1,15,1,5,8,5,1,15,1,5,1,15,1,5,2,5,1,15,1,5,1,15,1,5,1,15,1,5,1,15,1,5,1,15,1,5,1,15,1,5,1,15,1,5,1,15,1,5,6,5,1,15,1,5,1,15,1,5,1,15,1,5,10,5,1,15,1,5,1,15,1,5,1,15,1,5,2,5,1,15,1,5,6,5,1,15,1,5,14,5,1,15,1,5,1,15,1,5,1,15,1,5,1,15,1,5 }; byte RLEcmdOFF[ RLE_LEN ] = {1,5,1,180,1,30,1,90,1,5,2,5,1,15,1,5,14,5,1,15,1,5,4,5,1,15,1,5,1,15,1,5,2,5,1,15,1,5,1,15,1,5,1,15,1,5,1,15,1,5,1,15,1,5,68,5,1,15,1,5,1,15,1,5,2,30,1,90,1,5,1,15,1,5,16,5,1,15,1,5,4,5,1,15,1,5,2,5,1,15,1,5,1,15,1,5,1,15,1,5,1,15,1,5,1,15,1,5,1,15,1,5,72,5,2,30,1,90,1,5,1,15,1,5,16,5,1,15,1,5,6,5,1,15,1,5,1,15,1,5,1,15,1,5,2,5,1,15,1,5,1,15,1,5,1,15,1,5,1,15,1,5,1,15,1,5,1,15,1,5,1,15,1,5,1,15,1,5,6,5,1,15,1,5,1,15,1,5,1,15,1,5,10,5,1,15,1,5,1,15,1,5,1,15,1,5,2,5,1,15,1,5,6,5,1,15,1,5,18,5,1,15,1,5,1,15,1,5 }; /////////////////////////////////////////////////////////// //Переменные задания температуры unsigned int TEMP_MAX; unsigned int TEMP_MIN; BLYNK_WRITE(V3) { int widgetValue_MIN = param.asInt(); // Here we create variable to store incoming values from V1. Serial.print("MIN TEMP "); Serial.println(widgetValue_MIN); TEMP_MIN = widgetValue_MIN; } BLYNK_WRITE(V4) { int widgetValue_MAX = param.asInt(); // Here we create variable to store incoming values from V1. Serial.print("MAX TEMP "); Serial.println(widgetValue_MAX); TEMP_MAX = widgetValue_MAX; } /////////////////////////////////////////////////////////// //Установка интервала считывания данных long previousMillis = 0; long interval = 4000; //Виртуальные переменные void myTimerEvent(){ Blynk.virtualWrite(V1, DHT.temperature); Blynk.virtualWrite(V2, DHT.humidity); } //Для кириллицы в мониторе порта char* RUS(char* StrIn){char* StrOut=StrIn; uint8_t i[4]={0,0,StrIn[0],StrIn[1]}; while(i[2]>0&&i[0]<255){if(i[2]==0xd0&&i[3]>0x8F&&i[3]<0xC0){StrOut[i[1]]=i[3]+0x30;i[0]++;}else if(i[2]==0xd0&&i[3]==0x81){StrOut[i[1]]=0xA8;i[0]++;}else if(i[2]==0xd1&&i[3]>0x7F&&i[3]<0x90){StrOut[i[1]]=i[3]+0x70;i[0]++;}else if(i[2]==0xd1&&i[3]==0x91){StrOut[i[1]]=0xB8;i[0]++;}else{StrOut[i[1]]=i[2];} i[0]++; i[1]++; i[2]=StrIn[i[0]]; i[3]=StrIn[i[0]+1];} StrOut[i[1]]='\0'; return StrOut;} //////////////////////////////////////////////////////////////////////////////////////////////////////// void setup(){ // Set the clock to run-mode, and disable the write protection rtc.halt(false); rtc.writeProtect(false); //Вывод на монитор порта Serial.begin(9600); // Скорость работы порта Blynk.begin(auth); //Авторизация в Blynk // Setup a function to be called every second timer.setInterval(1000L, myTimerEvent); pinMode(Relay, OUTPUT); //назначение порта с Реле pinMode(LED_PIN, OUTPUT); // назначение порта с диодом int ptr1 = 0; for ( int i = 0; i < RLE_LEN; i += 2 ) for ( byte j = 0; j < RLEcmdON[ i ]; j++ ) commandON[ ptr1++ ] = RLEcmdON[ i + 1 ]; int ptr2 = 0; for ( int i = 0; i < RLE_LEN; i += 2 ) for ( byte j = 0; j < RLEcmdOFF[ i ]; j++ ) commandOFF[ ptr2++ ] = RLEcmdOFF[ i + 1 ]; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// void loop(){ Blynk.run(); //Запуск Blynk в цикле timer.run(); // Initiates SimpleTimer // Выводим показания влажности и температуры датчика///////////////////////////////// unsigned long currentMillis = millis(); if(currentMillis - previousMillis > interval) { previousMillis = currentMillis; // Мониторинг ошибок датчика температуры int chk; chk = DHT.read(DHT11_PIN); // Чтение данных switch (chk){ case DHTLIB_OK: break; } //Часы // Send date Serial.print(RUS("Дата ")); Serial.print(rtc.getDateStr()); // Send time Serial.print(RUS(" Время ")); Serial.print(rtc.getTimeStr()); //Датчики ////int TEMP_MAX = pinValue; Serial.print(RUS(" Влажность = ")); Serial.print(DHT.humidity, 1); Serial.print(RUS(", Температура = ")); Serial.print(DHT.temperature,1); Serial.print(" ("); Serial.print(TEMP_MIN,1); Serial.print(")"); Serial.print(" - ("); Serial.print(TEMP_MAX,1); Serial.println(")"); Serial.print("Status "); Serial.println(STATE_TEMP,1); } ///////////////////////////////////////////////////////////////////// //Работа диода if (DHT.temperature >= TEMP_MAX) digitalWrite(LED_PIN, HIGH); else if (DHT.temperature <= TEMP_MIN) digitalWrite(LED_PIN, HIGH); else digitalWrite(LED_PIN, LOW); //Работа автоматики по температуре if (DHT.temperature >= TEMP_MAX && STATE_TEMP == LOW) { //irsend.sendRaw(ConditionerON, 349, 38); irsend.sendRaw(commandON, 349, 38); STATE_TEMP = HIGH; } if (DHT.temperature <= TEMP_MIN && STATE_TEMP == HIGH) { // irsend.sendRaw(ConditionerOff, 349, 38); irsend.sendRaw(commandOFF, 349, 38); STATE_TEMP = LOW; } }Уже было и не один раз разжовано, например, здесь: http://arduino.ru/forum/programmirovanie/perepolnyaetsya-sram-komandami-dlya-pulta-pomogite-razobratsya
Mariev
немножечко накосячили ))
bytecommand[349]; // в оперативке должен остаться только он одинPROGMEM byteRLEcmdOff[ RLE_LEN ] = { .. } // эти два массива можно объявить так для перемещения их во флеш, см. ссылку kisoftPROGMEM byteRLEcmdOn[ RLE_LEN2 ] = { .. } // и проверьте, на самом ли деле совпадает у вас размерность сжатых массивов, а то она скорее всего должна быть разной - RLE_LEN1 и RLE_LEN2и перед отправкой irsend заполняйте буфер command[] уже из флеша как-то так (не проверял):
command[ ptr++ ] = pgm_read_byte_near(& RLEcmdOff[ i + 1 ] );
Спасибо.
Про занесение данных во флэш узнал из ссылки kisoft.
Уже сделал - теперь используется 75% памяти. 497 байт свободно. А главное можно внести еще несколько команд управления в память.
Архивирование массива в конечном итоге не делал, т.к. не вижу как это поможет в уменьшении используемой ОЗУ - все равно разворачивается переменная в 349 байт.
Если в чем то ошибаюсь - поправьте пожалуйста.
За советы всем спасибо
Архивирование массива в конечном итоге не делал, т.к. не вижу как это поможет в уменьшении используемой ОЗУ - все равно разворачивается переменная в 349 байт.
...
Это всего лишь твоя фантазия, не нужно ничего разворачивать в ОЗУ, коды из массива считываются в send побайтово и сразу отправляются.
1. Короче говоря, если нужно больше ОЗУ, переносить во флеш и оттуда считывать при отправке.
2. Если нужно больше флеша, то нужно делать "сжатие". При этом не нужно разворачивать сжатый массив в ОЗУ, а считывая по два байта из флеша формировать данные и сразу их отправлять.
3. Если нужно еще больше флеша, то нужно "закодировать" последовательность, хранить её во флеше в бинарном виде, а при отправке считывать из флеша в бинарном виде, после чего отправлять, например, как в sendNEC.
Возможно еще есть варианты, но третий, самый эффективный, в плане того, что можно море команд хранить во флеше. Именно третий я и буду использовать, когда буду свой DAIKIN окучивать :)
Угу. Именно п.3 - единственно верный. Мало того, если на него перейдете то только тогда поймете что ж и как на самом деле передаете в ИК на кондиционер и как установить любую температуру, режим и т.д. Читайте например http://radiokot.ru/articles/14/http://radiokot.ru/articles/14/ похоже первый описаный и ваш.
Еще для экономии ОЗУ строковые константы тоже в флеш засунуть.
Еще для экономии ОЗУ строковые константы тоже в флеш засунуть.
Вообще-то, с этого надо начинать.
Только, строго говоря, эти константы УЖЕ засунуты в флеш. А потом оттуда копируются в ОЗУ перед началом выполнения программы.
Есть у меня сомение, что такое количество (конкретных) библиотек можно запихнуть в Уно и все это будет стабильно работать.
Отбросьте сомнения. Запихнул переменные во флэш и убрал вывод информации в монитор порта. Теперь свободного ОЗУ 600 кб и все стабильно работает
Вы хотите сказать, что статические переменные занимают ровно -598 кб?
Нет. Некоторый объем был свободен и ранее. Потом при переносе переменных передачи сигнала по ИК освободилось 349 байт. И немного увеличил свободной памяти за счет исключения вывода информации в монитор порта, т.к. теперь это не надо - все выводится в blynk