Оптимизация работы с картами SD
- Войдите на сайт для отправки комментариев
Пт, 22/02/2019 - 20:01
Помогите, пожалуйста, оптимизировать работу с либой SD (максимально ее уменьшить, а то жрет много): в частности мне не нужны функции записи, стирания и работы с каталогами...
Как бы ее почистить от этого, либо вставить в код только те функции, которые требуются? (я не силен в С++).
Компилятор и так выкидывает функции, которые остались невостребованны при написании исхрдного текста.
Тогда переиначу вопрос:
можно ли програмно отключить (до перезагрузки) всё это с целью экономии RAM после чтения инфы с карты?
Отключить что? На недостаток какого ресурса жалуетесь?
Всё, понял. Надо в либе посмотреть деструктор - если он имеется и возвращает память, то вызывать его.
вот это-то, наверное, мне и надо... Вот только в какой либе он есть и как им пользоваться? (я уже писал, что в с++ не силен)... :(
Конкретно, у меня с карты читается строковая переменная. Вот, после ее прочтения и присвоения ее значения имеющейся переменной, всё предыдущее надо бы очищать и отключать SD.
Никто посторонний не знает, какой вы пользуетесь.
Я пробовал SD и SDFAT
В отсутствии ссылки на библиотеку - это просто набор букв.
сейчас поищу, хотя обе с гитхаба...
Вот ссылка на SD.h: https://github.com/arduino-libraries/SD
А вот на sdfat.h: https://github.com/greiman/SdFat
Сходу не вижу никаких перспектив.
очень жаль... А есть какие-нибудь иные либы, где это есть?
Я не в курсе, подождем ещё кого-нить.
Может вам стоит прооптимизировать другие места?
Везде, где смог, пооптимизировал, даже кое-где вставил строчки голого С++ вместо ардуино-команд...
Всё равно маловато RAM...
Не думаю, что вы освободите достаточно памяти, но...
Есть процедура SD.end().
Дальше из .cpp выпиливаете строчку с объявлением этой самой SD. Ищите в конце. Объявляейте этот обьект у себя в коде используя new например.Или локально в какой-то подпрограмме.
Нельзя ли подсказать как? У меня всё чтение происходит с процедуре SETUP, а дальше работа с картой мне уже не нужна, можно, даже её полностью отключить после присвоения переменной значения, прочитанного из файла.
Ну дык где ваша процедура ?
Вот весь код программы: #include <CyberLib.h> #include <SPI.h> #include <SdFat.h> SdFat SD; //#include <SD.h> #include <Adafruit_GFX.h> #include <Adafruit_NeoMatrix.h> #include <Adafruit_NeoPixel.h> #define PIN 2 Adafruit_NeoPixel strip = Adafruit_NeoPixel(150, PIN, NEO_GRB + NEO_KHZ800); Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(15, 10, PIN, NEO_MATRIX_BOTTOM + NEO_MATRIX_LEFT + NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG, NEO_GRB + NEO_KHZ800); int x = matrix.width(); File myFile; String dd; void setup() { DDRB = DDRB | B00000100; //pinMode(10,OUTPUT); matrix.cp437(true); strip.begin(); matrix.begin(); matrix.setTextWrap(false); matrix.setBrightness(200); matrix.setTextColor(matrix.Color(245,0,0)); if (!SD.begin(4)) { //Serial.println("initialization failed!"); return; } // open the file for reading: myFile = SD.open("text.txt"); if (myFile) { //myFile.seek(0); dd=readLine(); dd=dd.substring(4, dd.length()); myFile.close(); } else { // if the file didn't open, print an error: }} void loop() { Start colorWipe(strip.Color(255, 0, 0), 100); showText(dd,matrix.Color(245,0,0), 100, 255); snake ( 200); stars(100, 30); // FullRainbow(60); rainbow(60); // showText(dd,matrix.Color(0,255,0), 60, 100); theaterChase(strip.Color(255, 255, 255), 30); // theaterChase(strip.Color(255, 255, 255), 30); End } // ----------- Заполнение цветом -------------- void colorWipe(uint32_t c, uint8_t wait) { for(uint16_t i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, c); strip.show(); delay(wait); } } // ----------- Заполнение цветом -------------- // ----------- Змейка -------------- void snake ( byte t) { for (byte x=0; x<150; x++) { strip.setPixelColor(x,255,255,255); strip.setPixelColor(x-1,80,80,80); strip.setPixelColor(x-2,30,30,30); strip.setPixelColor(x-3,5,5,5); strip.setPixelColor(x-4,0,0,0); strip.show(); delay_ms (t); } } // ----------- Змейка -------------- // -------- Бегущая строка ----------- void showText( String t, uint16_t color, byte wait, byte len){ matrix.setTextColor(color); while (--x > (len*(-1))) { matrix.fillScreen(0); matrix.setCursor(x, 0); matrix.print(utf8rus(t)); matrix.show(); delay_ms(wait); } x = matrix.width(); } // -------- Бегущая строка ----------- /* // --------- FULLRAINBOW --------------- void FullRainbow(uint8_t wait) { uint16_t i, j; for(j=0; j<256; j++) { for(i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, Wheel(j & 255)); } strip.show(); delay(wait); } }*/ // --------- FULLRAINBOW --------------- void rainbow(byte wait) { uint16_t i, j; for(j=0; j<255; j++) { for(i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, Wheel((i+j) & 255)); } strip.show(); delay_ms(wait); } } /* void star(byte wait) { byte i, j; for(j=0; j<256; j++) { for(i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, Wheel((i+j) & 255)); } strip.show(); delay_ms(wait); } } */ void stars (byte t, byte pause){ byte x=0; byte y=0; while (t > 0){ for ( byte i=0; i<strip.numPixels(); i++){ y = random(0,2); if (y>0) { strip.setPixelColor(i,255,255,255); } else { strip.setPixelColor(i,0, 0, 0); } } strip.show(); t--; delay_ms(pause); } } // ----------- Сияющий эффект --------------- void theaterChase(uint32_t c, uint8_t wait) { for (int j=0; j<50; j++) { //do 10 cycles of chasing for (int q=0; q < 3; q++) { for (uint16_t i=0; i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, c); //turn every third pixel on } strip.show(); delay_us(wait); for (uint16_t i=0; i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, 0); //turn every third pixel off } } } } // ----------- Сияющий эффект --------------- // ------------Отображение русского шрифта------------- String utf8rus(String source) { byte i,k; String target; unsigned char n; char m[2] = { '0', '\0' }; k = source.length(); i = 0; while (i < k) { n = source[i]; i++; if (n >= 0xC0) { switch (n) { case 0xD0: { n = source[i]; i++; if (n == 0x81) { n = 0xA8; break; } if (n >= 0x90 && n <= 0xBF) n = n + 0x30; break; } case 0xD1: { n = source[i]; i++; if (n == 0x91) { n = 0xB8; break; } if (n >= 0x80 && n <= 0x8F) n = n + 0x70; break; } } } m[0] = n; target = target + String(m); } return target; } // ------------Отображение русского шрифта------------- String readLine() { String received = ""; char ch; while(myFile.available()){ ch = myFile.read(); if(ch == '\n') { return String(received); } else { received+=ch; } } return ""; } // ------------ Генератор радуги ------------- uint32_t Wheel(byte WheelPos) { WheelPos = 255 - WheelPos; if(WheelPos < 85) { return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3); } if(WheelPos < 170) { WheelPos -= 85; return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); } WheelPos -= 170; return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); }В 10 раз проще не трахаться с оптимизацией чужой библиотеки, а просто перенести код на платку СТМ32. Размер чуть больше Нано. стоит даже дешевле - а памяти ровно в 10 раз больше.
STM32 - Да, только тогда придется сменить шилд.
Лучше сразу выбрать ESPшку.
А пока В файле библиотеки SD.cpp находите строку
Коментируете или удаляете ее.
void setup(){ SDClass SD; SD.begin(); // тут картой кручу верчу SD.end(); } void loop(){ // ТУТ объекта SD уже нет // все занимаемое им озу свободно // во флеше куски кода от ваших танцев в сетапе // так что делайте это только если вам мало озу // в остальных случаях это не поможет }Пробовал, но не могу найти адекватных библиотек типа неоматрикс и неопиксель для STM32...
Пробовал, но не могу найти адекватных библиотек типа неоматрикс и неопиксель для STM32...
А для ESP они есть :) И у ESP32 два ядра. Там сетевые функции работают на другом ядре и ваше ресурсов не потребляют .
Конечно,...
Конечно,...
Чего конечно. Реально. Причем сетевые библиотеки для ESP32 полностью совместимы со стандартными ардуиновскими. Если для 8826 была полная голиматья, то тут все красиво. Все стандартные примеры работают легко.
Вот, когда получу ещё несколько ESP-шек, тогда и сделаю на них... а пока она у меня в единственном числе...
после из
Выдает вот такую ошибку:
exit status 1
STM32 - Да, только тогда придется сменить шилд.
Лучше сразу выбрать ESPшку.
А пока В файле библиотеки SD.cpp находите строку
Коментируете или удаляете ее.
void setup(){ SDClass SD; SD.begin(); // тут картой кручу верчу SD.end(); } void loop(){ // ТУТ объекта SD уже нет // все занимаемое им озу свободно // во флеше куски кода от ваших танцев в сетапе // так что делайте это только если вам мало озу // в остальных случаях это не поможет }После выполнения этих изменений выпадает ошибка: exit status 1
ну значит в вашей библиотеки этого метода нет. Просто удалите 5 строчку
А вообще, что у вас за библиотека.
В SD.h все есть.
Пробовал, но не могу найти адекватных библиотек типа неоматрикс и неопиксель для STM32...
есть неадекватные
https://github.com/rogerclarkmelbourne/WS2812B_STM32_Libmaple
Пробовал, но не могу найти адекватных библиотек типа неоматрикс и неопиксель для STM32...
есть неадекватные
https://github.com/rogerclarkmelbourne/WS2812B_STM32_Libmaple
Хорошо, с неопикселем (под STM32) разобрались, а где взять неоматрикс?
ну значит в вашей библиотеки этого метода нет. Просто удалите 5 строчку
А вообще, что у вас за библиотека.
В SD.h все есть.
Библиотека та, на которую я давал ссылку... Метод там только объявлен, но никак не описан, потому и не работает...
А ну да . Глубоко не вникал.
В этом-то всё и дело... не пашет... :(
SD-то обязательна? Мошт попроще придумать, раз не выходит?
В этом-то всё и дело... не пашет... :(
Если у вас на карточке этот файл единожды создан и не удаляется, а только меняется содержимое, то прочтите его на низком уровне, прочитав сектор. Вся работа уложиться в десяток строк работы с SPI. Созданный файл в системе фат не меняет своего адреса пока не будет удален.
Так любой может написать. Прям Америку открыл. Ты покажи как этот сектор найти, как прочитать. Как найти следующий. Пять строк говоришь. Ну-ну....
В этом-то всё и дело... не пашет... :(
Чего именно не пашет то ? У меня все ок.
Всмысле найти? Можно карточку всунуть в комп и увидеть программой, например winhex. Если такой возможности нет, то пишем в файл уникальные данные и их ищем начиная с нулевого сектора. Разве это сложно?
void mmc_read_block(unsigned char *cmd,unsigned char *Buffer,unsigned int Bytes) { if (mmc_write_command (cmd) != 0) { return; } while (SPIReadChar(0xFF) != 0xfe){}; for (unsigned int a=0;a<Bytes;a++) { *Buffer++ = SPIReadChar(0xFF); } //CRC-Byte auslesen SPIReadChar(0xFF); SPIReadChar(0xFF); MMC_Disable(); return; } unsigned char mmc_read_sector (unsigned long addr,unsigned char *Buffer) { unsigned char cmd[] = {0x51,0x00,0x00,0x00,0x00,0xFF}; addr = addr << 9; //addr = addr * 512 cmd[1] = ((addr & 0xFF000000) >>24 ); cmd[2] = ((addr & 0x00FF0000) >>16 ); cmd[3] = ((addr & 0x0000FF00) >>8 ); mmc_read_block(cmd,Buffer,512); return(0); }del
попробуйте скомпилить прогу с командой SD.end()
у вас выскочит ошибка!
попробуйте скомпилить прогу с командой SD.end()
у вас выскочит ошибка!
Читайте внимательно. Выбросьте эту строку из своего скетча. Уже писал. Вы не читаете что ли? В таком случае вам советов больше не даю.
SD-то обязательна? Мошт попроще придумать, раз не выходит?
В это-то и вся задумка: менять строку без пепрепрошиски устройства...
SD-то обязательна? Мошт попроще придумать, раз не выходит?
В это-то и вся задумка: менять строку без пепрепрошиски устройства...
Тогда надо сидеть, башку чесать. Самое простое, конечно, сменить МК. У микро про, к примеру, не 2Кб Озу, а 2.5Кб.
SD-то обязательна? Мошт попроще придумать, раз не выходит?
В это-то и вся задумка: менять строку без пепрепрошиски устройства...
Тогда надо сидеть, башку чесать. Самое простое, конечно, сменить МК. У микро про, к примеру, не 2Кб Озу, а 2.5Кб.
К сожалению, прихлдится работать с тем, что есть в наличии...
К сожалению чудес не бывает. Или меняете МК или становитесь хорошим программистом.
придётся упирать на 2й вариант, хотя смена МК тоже в перспективе (например, STM32 или ESP8266)...
хотя смена МК тоже в перспективе (например, STM32 или ESP8266)...
Это не поможет. Не зная как работает карта на низком уровне, Вы все равно поставите левую библиотеку и у она у вас сожрет всю память. Хоть на стм, хоть на есп. Так что, вариант только второй.
Тогда подскажите нормальную, не "левую" библиотеку (ксли таковая есть в природе)...
Да любая библиотека отожрёт 512 байт под буфер сектора, ибо так правильнее. Но __Alexander вам привел пример, как считывать сектора напрямую (и тоже с буфером :), но его легко переделать под побайтовое чтение и уже эти байты на лету обрабатывать.
Ясно. Спасибо всем за помощь. Вопрос решился (вроде) при помощи перехода на ESP8266, да еще и с управлением по wifi.
Так, что, тему, наверное, можно закрывать... Большое спасибо всем откликнувшимся. :)
ESP8266 - весьма капризный процессор, а становиться хорошим программистом вы не хотите. Ждём вас в следующих темах "оптимизация работы с wemos(nodemcu) ..." :)
Дело в том, что изучать новый язык мне уже поздновато, а так - с удовольствием !
А на esp8266 (NODEMCU) у меня уже несколько месяцев работают интернет-синхронизированные часы-погодная станция со счетчиком подписок 2х каналов ютуба...