Побайтово чтение с SD
- Войдите на сайт для отправки комментариев
Ср, 08/08/2018 - 19:15
О, великие и могучие ГУРУ.
Научите оленя.
На карте лежит бинарник, его надо считать побайтово.
Мануалы курил(может плохо),
Какими функциями это реализовать ?
Типа
File myFile;
myFile=SD.open("BIN");
Byte=myFile(номер байта)????
Или как то так.
На парсер памяти нет и процессорного времени нет.
Я же правильно понимаю, что
командой
myFile=SD.read("bin");
Создаётся буфер в 512байт ?
Как с ним работать ?
Не знаю, чего ты там накурился и откуда взял read("bin");, но простой read(); спокойно читает один байт.
Да , херню написал.
Следовало.
myFile=SD.open("bin");
Далее вроде как разобрался:
myFile.seek(num);
myByte=myFile.peek();
Слишком сложно так для каждого байта.
Или можно как то проще ?
В общем задача, с карты памяти выводить бмпшки на экран.
Библиотеки(графика+СД) сжирают 90% оперативы.
Ну и фиг с ним главное разобраться.
Потом буду смотреть в сторону spiflash
ну так ты же хотел побайтно читать? - "побайтно" - это по одному байту. что не так?
Если хочешь быстрее, читай описание библиотеки SD. например функция read может читать из файла блоками.
Ты уверен, что разобрался. Что точно знаешь, что тебе надо именно peek, а не read? Разницу между ними понимаешь?
peek() - экономная команда, не разбазаривает байтики почем зря...
У меня в цикле for эта связка.
Так , что думаю без разницы, peek() или read()
А, ну правильно. Если нет разницы, то peek() гораздо лучше смотрится рядом с seek(). Рифма и всё такое.
А, ну правильно. Если нет разницы, то peek() гораздо лучше смотрится рядом с seek(). Рифма и всё такое.
Может за место стеба, что то дельное напишешь ?
Может за место стеба, что то дельное напишешь ?
Например?
Может за место стеба, что то дельное напишешь ?
может ты вместо хамства все же посмотришь в учебнике, в чем разница read() и peek()?
Может за место стеба, что то дельное напишешь ?
может ты вместо хамства все же посмотришь в учебнике, в чем разница read() и peek()?
Ну я посмотрел.
Отличия в том, что read() считывает баит и сдвигается на следующий.
А peek() считывает и не сдвигается.
Учитывая, что я явно читаю байт по конкретному адресу, что меняется ?
Может я учебник, взял херовый ?
По делу то в состоянии кто нибудь ответить ?
И в чем заключается хамство ?
Отличия в том, что read() считывает баит и сдвигается на следующий.
А peek() считывает и не сдвигается.
Учитывая, что я явно читаю байт по конкретному адресу, что меняется ?
фигово у тебя с логикой. В своем коде ты в цикле считываешь кучу байт подряд. Если взять read() вместо peek() - seek() на каждом шаге становится лишним.
А если наморщить лоб дальше - можно вместо двух циклов считывать весь блок байт одним действием.
Отличия в том, что read() считывает баит и сдвигается на следующий.
А peek() считывает и не сдвигается.
Учитывая, что я явно читаю байт по конкретному адресу, что меняется ?
фигово у тебя с логикой. В своем коде ты в цикле считываешь кучу байт подряд. Если взять read() вместо peek() - seek() на каждом шаге становится лишним.
А если наморщить лоб дальше - можно вместо двух циклов считывать весь блок байт одним действием.
А если ещё наморщить лоб и внимательно прочитать условия, то тогда становится понятно, что весь блок не куда пихать.
У меня свободных ОЗУ 100 байт, а блок 512.
У меня свободных ОЗУ 100 байт, а блок 512.
с чего это блок именно 512? - можно читать блок произвольного размера - тот, который тебе нужен.
Кроме того, если я правильно понял код выше - для извлечения каждого бита ты 8 раз подряд читаешь один и тот же байт. При таком стиле никакой памяти не хватит
А что это как то на память влияет ?
Количество переменных не меняется вроде.
Процессорное время кушает, это да.
По другому как реализовать , так и не придумал.
Ещё один цикл for вкладывать, дак он точно от ОЗУ кусок откусит.
Если я читаю блок, этот блок нужно тоже хранить где то.
И потом точно так же из него выгрызать байты нужные.
По другому как реализовать , так и не придумал.
а если вставить чтение байта между двумя For? - первым циклом читаем байт, вторым перебираем биты.
Ну нет готовой библиотеки которая может с карты битмапы читать и выводить на ssd1306.
Ну нет готовой библиотеки которая может с карты битмапы читать и выводить на ssd1306.
при чем тут это? какое это имеет отношение к тому. что вы два цикла неправильно написали?
По другому как реализовать , так и не придумал.
а если вставить чтение байта между двумя For? - первым циклом читаем байт, вторым перебираем биты.
Нет, нельзя.
В строке может быть произвольное количество байт.
Первым циклом я перебираю строки, вторым столбцы.
Придется вводить , либо переменную, либо опять же считать момент , когда на следующий байт переходить.
Я сделал, расчет номера байта по координатам.
В функцию передаются, координаты картинки х,у
Ее размеры sx,sy.
А дальше построчно рассчитывается состояние каждого пикселя.
У меня в цикле for эта связка.
Так , что думаю без разницы, peek() или read()
тяжелый случай, зачем каждый пиксель то рисовать.
берете пример из любой библиотеки работы с oled
там вполне себе примитивно выводится одной командой содержимое графического файла
т.е. никакого цикла по байту нафиг не надо, считали байт из файла и его же сразу вывели
sendData(
Научите, как битмап с карты памяти читать ?
Без парсинга только, а то памяти нет от слова совсем.
И желательно не с фиксированным 16х8 размером, а произвольным.
И да в вашем примере считать ничего не нужно в принципе.
Все размерами ограниченно.
Только вот придется большие картинки на кучу паззлов делить и потом собирать.
И да в вашем примере считать ничего не нужно в принципе.
Все размерами ограниченно.
что там ограничено? Вы в коде разберитесь - там картинка точно так же последовательно читается побайтно. вся разница - что там чтение из массива, а у вас из файла на карте
У меня в цикле for эта связка.
Так , что думаю без разницы, peek() или read()
тяжелый случай, зачем каждый пиксель то рисовать.
берете пример из любой библиотеки работы с oled
там вполне себе примитивно выводится одной командой содержимое графического файла
т.е. никакого цикла по байту нафиг не надо, считали байт из файла и его же сразу вывели
sendData(
В качестве примера вам код того же самого от adafruit
Но тут опять же, как и в вашем примере, с массива идёт чтение.
Но тут опять же, как и в вашем примере, с массива идёт чтение.
а есть разница? - файл битмапа - этот тот же массив. Смещение байта в файле - все равно что индекс в массиве.
разница между кодом Адафруита и Андиката в том, что у него байты по вертикали (как и в экране), а у Адафруита по горизонтали.
Поэтому первый вопрос - как идут байты у вас в файле? Судя по вашему коду - видимо как у Адафруита. тогда выгоднее читать сразу по 8 байт. расположенных друг под другом (8*8 пикселей) -а потом разом выводить
.del
В том то и дело, что ему не надо знать положение курсора в двух координатах массива, ТК она у него одна.
В том то и дело, что ему не надо знать положение курсора в двух координатах массива, ТК она у него одна.
Да неужели? думаете, у него все битмапы - в ниточку 1 пиксель? :) Точно так же там есть координата по х и кордината по у.
Можно и с другой стороны посмотреть - можно сказать, у вас в файле тоже только одна координата - смещение байта.
Резюме -чтение их массива и чтение из файла - операции, похожие как близнецы.
По смыслу да, а вот по исполнению не очень.
Одно дело , когда то что надо уже в памяти, и совсем другое, когда это в память надо как то засунуть . и
По смыслу да, а вот по исполнению не очень.
Одно дело , когда то что надо уже в памяти, и совсем другое, когда это в память надо как то засунуть . и
вы наверное не поняли, если в память и надо что то засовывать, то исключительно за один цикл сразу несколько байт.
например у вас в файле на карте лежат такие числа
1 2 4 8 16 16 16 255 1 2 4 8 16 16 16 255 1 2 4 8 16 16 16 255 и т.д. Если это все перевести в картинку то получится наклонная линии потом горизонтальная линия потом вертикальная линия в воображаемых квадратиках 8 на 8 пикселей.
Теперь вам необходимо вывести его на oled дисплей, но там растр изображения идет построчно по например 8 символов, но каждые 8 байт в символе идут растр сверху вниз.
т.е. мы считываем 8 байт, сразу же при чтении в этом же цикле, отбираем сначала нулевые потом первые и т.д биты в новые байты.
после получения новых 8и байт уже перевернутых
1 1 1 15 17 33 65 129 (если не понятно - на бумажке матрицу 8 на 8 нарисуте и все поймете)
в цикле их выводим в oled дисплей
читаем следующие 8 байт из файла и так по кругу пока файл не закончиться или дисплей не заполниться - в зависимости от задачи.
я когда экспериментировал со своим странным модулем oled, я тупо в память его записывал разные числа с паузой в треть секунды и смотрел что он и как отображает, сразу вырисовывается как у него организована структура памяти.
У меня свободных 121 байт, программа перестает работать, если пытаюсь монитор для отладки включить. А вы мне предлагаете ещё переменных туда напихать, формул, циклов и массив ещё один.
Он мне там даже на 8байт не нужен.
Была бы мега2560.
Читал бы сразу всю картинку в массив , а потом выводил бы стандартным drawBitmap.
А покажите весь скетч :)
Я почти уверен что можно много выкинуть.
Помниться на финише одного проекта в этом году я сократил память с 91 % до 39 %.
Безвыходных ситуаций не бывает.
Похоже, медицина бессильна, хльт показывай скетч, хоть нет.
Современные веянья : вместо того чтоб включить мозг для оптимизации ПО, покупают новый более мощный МК.
ЗЫ. Помниться тут ЕвгенийП скидывал табличку сравнения современных МК и тех кто спутниками управляют.
Кактус, хватит ныть про память. Память надо экономить не говнокодом, который пиксели по отдельности отрисовывает, а разумным проектированием программы. Уверен, что у тебя можно выиграть в программе кучу места. Начать с того, какую библиотеку для Sd ты используешь - например SD.h самая крутая. но и самая прожорливая, SDFat.h - попроще и поэкономнее, а еще есть специальные моды для малой памяти типа SDMini... - разница в расходе памяти может достигнуть 500 байт.
Во вторых - все ли текстовые строки запихнуты во флеш? Константы - обьявлены константами? Размер переменных оптимизирован?
В третьих - зайдем с глобальной стороны. А нужна ли тебе вообще SDкарта? Если ты с нее только битмапы грузишь - может их во флеш загрузить? какого размера битмапы?
ну и в четвертых - а битмапы вообще нужны? основной смысл программы в чем? если это какая-то автоматика с датчиками, то битмапы - это бесполезные "бантики", от которых нужно отказаться в пользу простого текстового интерфейса...
Вот весь скетч
Буду рад, если получится отсюда что нибудь выкинуть без кастрации библиотек. Т.к. сами библиотеки оставляют 193 байта ОЗУ.
Ну монитор разве что убрать.
Что касается библиотеки SD , тут ввиду непонятного формата используемых карт вариантов нет.
Была бы уверенность в том, какая конкретно карта с какой конкретно файловой системой, можно было бы без библиотеки обойтись.
можно поинтересоваться смыслом проекта? Читать любые битмапы с любых карт и выводить на крохотный экран? А что дальше - если 42 строчки кода уже заняли всю доступную память?
Может все-таки можно выбрать какие-то определенные картинки и заранее загрузить их в ардуину. чтобы отказаться от СД-карточек вовсе?
Кроме того, библиотеки OLED тоже есть разные. Не знаю, что там в вашей, но во многих буфер во весь экран размером... Но есть и другие - совсем без буфера.
А что Меги на али закончились? Если нет, то поставь.
А ещё лучше, с Архатом поговори. Он как-то там к Меге еще полвагона дополнительной памяти прицеплял. Будешь картинки с порносайтов показывать. Круто!
К сожалению хотелки не мои.
Да, только картинки буду показывать.
Но их количество перевалит за сотню, так что флеш не вариант.
В дальнейшем планируется перейти на SPIflash.
К сожалению хотелки не мои.
Да, только картинки буду показывать. Но их количество перевалит за сотню, так что флеш не вариант.В дальнейшем планируется перейти на SPIflash.
"Хотелки не ваши" ? - хотите сказать, что вы это на заказ кодите?:)))
Если не хотите потрошить библиотеки, размер этого кода особо не уменьшить. Возьмите другую плату - например BluePill от СТМ32 (шутка)
Жесть!
Т.к. сами библиотеки оставляют 193 байта ОЗУ.
Это кто ж тебе такое сказал? Плюнь ему в рожу! Открой файл OLED_I2C.h и посмотри на строку 132
uint8_t scrbuf[1024];
и объясни мне как программа с такой строкой может занимать 193 байта?
---------------
Значит так. Буфер экрана видишь? Так вот читай со своей карты ПРЯМО в этот буфер. И тогда тебе вообще не нужна никакая дполнительная память от слова совсем.
Чтобы понять как писать прямо в буфер посмотри как утсроена библиотечная функция
void OLED::setPixel(uint16_t x, uint16_t y)
и делай как она - пихай прочитанные байты прямо в буффер.
Ну или откажись от буфера, но это ты, боюсь, пока не сумеешь.
Да в общем то уже все.
Результат устроил работа закончена.
Да в общем то уже все.
Результат устроил работа закончена.
ну да, ну да... и скетч, который только и знает, что читает один и тот же байт 8 раз...
"Результат устроил" - я плачу...
to b707
Если выкинуть в скетче SD и SPI, а оставить только то , что относиться к OLED_I2C.
То используется 1064 байта ОЗУ, и с ваших слов там ещё буфер на 1кБ.
На весь скетч и обработчик библиотеки 40 байт ???
Ну,ну.
С буфером Adafruit_SSD1306.h.
Вот там уже голая библиотека 1,5кБ кушает.
Поэтому от нее пришлось отказаться в первую очередь.
Голая OLED_I2C , чуть больше 800 байт занимает.
Какой там килобайтный буфер ?
На весь скетч и обработчик библиотеки 40 байт ???
Ну,ну.
А что там в скетче, если выкинуть SD, SPI и OLED? НИЧЕГО! - код на уровне примера блинк. Смотрели, сколько памяти занимает блинк? - посмотрите. 9 байт.
Так что для вашего скетча 40 байт - это много.