Как уменьшить объем приведенного кода?
- Войдите на сайт для отправки комментариев
Ср, 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 в книге. (по оптимизации кода.)
Спасибо! Книга полезная. Воспользуюсь.