Как уменьшить объем приведенного кода?
- Войдите на сайт для отправки комментариев
Ср, 22/01/2020 - 23:04
Здравствуйте. Написал скетч, который при компиляции вылился в hex файл объемом больше 57кБ. К сожалению, пока не имею под рукой винды, обхожусь мобильным BluinoLoader. Понимаю, что шансы залить 57кБ в UNO или Micro никакие )) Поэтому прошу помощи. Подозреваю, что много памяти отнимают библиотеки, т.к. сам скетч не объемный. Можно ли как-то урезать Adafruit_GFX, т.к. экран хочу использовать только для вывода текста одним шрифтом одного цвета? Может, как-то перестроить математические выражения в самом скетче? Особенностей компилятора не знаю. За счет чего такой объем получился?
#include <Adafruit_GFX.h> //это
#include <Adafruit_ST7789.h>// для
#include <SPI.h> // экрана
#include <VarSpeedServo.h>
#include <iarduino_RTC.h>
#include <EEPROM.h>
#define TFT_MOSI 4
#define TFT_SCLK 13
#define TFT_CS 5
#define TFT_RST 6
#define TFT_DC 12
#define pinTouch 3
#define pinVklDatch 2//пин включения всех датчиков
#define pinPump 7//пин управления помпой (через ключ)
#define pinServo 11//пин управления сервомотором
#define ChRast 4// ччисло растений
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
VarSpeedServo myServo;
iarduino_RTC time(RTC_DS1302, 10, 8, 9); //RST, CLK, DAT
const byte ServoArr[ChRast][4]={//определяем массив, где 1-номер пина датчика влажности или число >100, если нужен безусловный полив раз в 1 или несколько дней (порог в этом случае - любое положительное число ставим); 2-угол поворота шланга к этому цветку, 3-порог датчика, при котором поливаем, 4-секунды полива
{101,0,30,8},{101,40,30,18},{101,100,30,5},{101,140,30,5}//
};
unsigned int tempor;
void setup() {
time.begin();
tft.init(240, 240);
time.gettime();
for(byte i=0;i<ChRast;i++){//эти три закомментировать. первого запуска
EEPROM.update(i,time.weekday);//. строки. после.
delay(4);//
}// это начальная установка дней полива
myServo.write(0);
pinMode(pinTouch, INPUT_PULLUP);
pinMode(pinPump, OUTPUT);
pinMode(pinVklDatch, OUTPUT);
pinMode(pinServo, OUTPUT);
digitalWrite(pinPump, LOW);
pinMode(10, OUTPUT); //это для RTC
myServo.attach(pinServo);
myServo.write(0, 20,true); //установка на исходную точку со скоростью 20, и ждать пока доползет
delay(1000);
}
void loop() {
time.gettime();
if((time.Hours==16&&time.minutes==0)||(digitalRead(pinTouch)==LOW)){//если 16 часов вечера или нажата кнопка теста
tft.setTextWrap(false);//подготавливаем экран к выводу таблицы
tft.fillScreen(0x00);
tft.setTextColor(0xFFFF);
tft.setTextSize(1);
for (byte i=0;i<ChRast;i++){//то перебираем все растения,
if ((ServoArr[i][0]<100)&&(map(myUsrednFunction(pinVklDatch,ServoArr[i][0]), 100, 700, 100, 0)<=ServoArr[i][2])){
myPolivFunction(ServoArr[i][1],ServoArr[i][3]);
mySetScreenFunction(i,0,0,ServoArr[i][3],ServoArr[i][2],map(myUsrednFunction(pinVklDatch,ServoArr[i][0]), 100, 700, 100, 0));
}//если растение с датч влажн и значение датчика ниже порога, то вызываем функц полива и пишем на экран данные
if ((ServoArr[i][0]>100)&&myGetDayFunction(i,ServoArr[i][0]-100)){
myPolivFunction(ServoArr[i][1],ServoArr[i][3]);
delay(4);//т.к. операции с еепром длительны
mySetScreenFunction(i,ServoArr[i][0]-100,EEPROM.read(i),ServoArr[i][3],0,0);
delay(4);//т.к. операции с еепром длительны
}//если нет датчика влажн, и функция определения дня полива вернула 1, то поливаем и данные на экран
}
myServo.write(0,20,true);//в конце обхода с поливом всех растений возвращаем шланг на место
delay(61000);//задержка в 61 секунду, чтобы полив был не чаще раза в сутки
}
}
int myUsrednFunction(byte pinVkl,byte dataPin) {//функция среднего из 10 последовательных значений датчика влажности
int result = 0;
digitalWrite(pinVkl, HIGH); //включаем датчик
delay(1000);
for (byte i = 0; i < 10; i++) {
result += analogRead(dataPin); // берем 10 показаний подряд
delay(10);
}
result /= 10;
digitalWrite(pinVkl, LOW); //снимаем питание с датчика
return result;
}
void myPolivFunction(byte ugol, byte secund){
myServo.write(ugol, 20,true);//и если сухие, то подводим этому растению шланг
delay(1000);
digitalWrite(pinPump, HIGH);//включаем помпу
tempor=secund*1000;
delay(tempor);//на время полива именно этого цветка
digitalWrite(pinPump, LOW);//а затем отключаем ее
delay(5000);//задержка, чтобы стекли остатки воды из трубки
}
boolean myGetDayFunction(byte nomer, byte day){// определяем, поливочный ли день сегодня
if(time.weekday!=EEPROM.read(nomer)){return false;}//если сегодня не тот день недели, что записанв еепром, как очереднойдень полива, то функция вернет 0
//иначе, т.е. сегодня нужно поливать
if(time.weekday+day<7){//добавляем к сегодня период полива
EEPROM.update(nomer, (time.weekday+day));//проверяя, нет ли переполнения цикла дней неели
}else{//и корректируя вычитанием 7
EEPROM.update(nomer, (time.weekday+day-7));//помещаем следующий поливочный день в еепром
}
return true;//возвращаем 1, т.е. добро на полив
}
void mySetScreenFunction(byte nom, byte per, byte sle, byte sec, byte por, byte vla){
tft.println(F("N°\tper\tsle\tsec\tpor\tvla"));//заголовок таблицы с номером растения, периодом полива, следующим поливочным днем, секундами полива, порогом влажности и измеренной влажностью
for (byte i=0;i<ChRast;i++){//каждое растение в своей строке
tft.setCursor(0, nom*10);
tft.print(String(nom)+"\t"+String(per)+"\t"+String(sle)+"\t"+String(sec)+"\t"+String(por)+"\t"+String(vla));
}
}
У меня Ваш скетч в IDE 1.8.10 для UNO занимает
Спасибо большое! Камень с души. Значит, дело в компиляторе. Продолжу оттачивать, а через неделю смогу и на IDE проверить.
Может пригодится. Книга - https://yadi.sk/d/tPf7uEe23RxuWH , глава 6 в книге. (по оптимизации кода.)
Спасибо! Книга полезная. Воспользуюсь.