Как сохранить в файл значения переменной color?

RainMan
Offline
Зарегистрирован: 21.06.2011

Доброго дня. Уже перепробовал кучу вариантов ничего не получается.

Есть переменная типа Color. Например a=Color(255,0,128).

Задача сохранить в файл значение этой переменной, что бы в дальнейшем прочитать этот файл с SD-карты на ардуине.  

Как  ни бился,  но получить в результате манипуляций в файле 3 байта подряд, с значениями FF,00,80

пробовал так:

PrintWriter output;
color c;
void setup() {
  output = createWriter("screen.txt"); 
  c=color(255,0,255);
  output.print(byte(red(c))); //red
  output.flush(); // Writes the remaining data to the file
  output.close(); // Finishes the file
  exit(); // Stops the program
}
void draw() {
 
}

пробовал и так:

 output.print((red(c))); //red

Похоже проблема в большей степени в том что тип Byte в процессинге лежит в диапазоне значений -127 +127. И таким образом не понятно как сохранить число 255, как FF в файл. На паскале я бы сохранил как  Сhar(c), и было бы все отлично, но в процессинге output.print(char(red(c))); выдает ошибку, т.к red(c) выдает тип Float (255.0) и привести его к  типу byte с диапозоном 0-255 не представляется возмлжным.

 

 

ourlive
Offline
Зарегистрирован: 26.05.2012

Ну так запишите текстом в текстовый же файл "255,0,255" или "FF,0,FF", его потом глазками можно будет поглядеть и без мега супер декодера понять, что написано. Неэкономно, требует "туды-сюды" преобразование из текста в числа и обратно, однако организуете вы скорее всего файл типа *.ini где неизбежно будет записано ещё много чего.

RainMan
Offline
Зарегистрирован: 21.06.2011

такойы вариант не подходит. Полученный файл будет обрабатываться на ардуине, и тратить лишнее время на преобразование данных из строки в число не хочется. Думаю что должно быть стандартное решение

ourlive
Offline
Зарегистрирован: 26.05.2012

Всё равно записывать три байта минимум, либо если набор цветов ограничен, то кодировать одним байтом, например. И кстати само преобразование строки в числа соверщенно несущественно сравнительно с чтением этой строки с карты. "Стандартное решение" это плюс ещё одна библиотека в дуину.

RainMan
Offline
Зарегистрирован: 21.06.2011

набор цветов не ограничен. Эти цвета надо еще успевать читать с карты в реальном времени  и  выводить на ленту  ws2812B со скоростью 27-36кб. сек. 

ourlive
Offline
Зарегистрирован: 26.05.2012

Флешки с ардуиной я не пользовал, хотя модуль под SPI валялся где то. Скорость печально низкая по данному интерфейсу. Нужно на практике замерять и оценивать возможности. Но без буфера наверное никак. Ну раз не ограничен набор, то блоки по 4 байта, 3 на цвет, один на маркер.

RainMan
Offline
Зарегистрирован: 21.06.2011

вопрос стоит не в организации файла, а в том как в него передать эти 3 байта:)

ourlive
Offline
Зарегистрирован: 26.05.2012

(r,g,b) r=200, g=5, b=105(например); три байта, в процессинге есть функция отвечающая за запись в файл именно этого типа данных. Есть функция позволяющая записать из как сумму символов, при этом служебные символы также отлично пишутся и читаются. Есть ещё группа функций позволяющих записать данные в файл. По какой причине ни одна из них вам не подходит?

RainMan
Offline
Зарегистрирован: 21.06.2011

все эти функции  вместо того чтобы записать  в файл 1 байт (число 255 ($FF)) пишут или строку "FF"  - 2байта, или строку "255"  -3 байта. У меня в связи с этим увеличивается обьем считываемых данных по и так медленному интерфейсу SPI в 2-3раза + надо привести в ардуине эти строки к типу данных byte, что тоже занимает время. А все головняки от того, что разработчику процессинга почему-то захотелось сделать тип данных байт как -127 +128 

RainMan
Offline
Зарегистрирован: 21.06.2011

и функция SaveBytes не сохранит как вы говорите, т.к если у меня цвет 255, то это уже не тип данных byte

Datak
Offline
Зарегистрирован: 09.10.2014

Не знаю что такое процессинг, но в нормальных языках 255 умещается в беззнаковый байт (unsigned byte).

Если есть в этом процессинге что-то похожее - пользуйтесь, всё должно получиться.

А если нет - можно что-нибудь такое попробовать:







output.print(byte(red(c)-128)); //red

Потом, при чтении, эти 128, естественно, придётся прибавить к прочитанному значению.

ourlive
Offline
Зарегистрирован: 26.05.2012

Ну есть такая беда, API и UTF-8 заставляют пользоваться бубном, saveBytes вполне вписывается в требования записать один байт одним байтом, а не двумя. Сделано это для совместимости с 7-и битными древностями.

void setup() {
  int r=10;
  int g=222;
  int b=100;
byte[] nums = { byte(r), byte(g), byte(b)}; //конвертировали
saveBytes("numbers.txt", nums); //записали

byte q[] = loadBytes("numbers.txt"); //прочитали
for (int i = 0; i < q.length; i++) { 
  int a = q[i] & 0xff; //преобразовали -127...+127 в 0...255
  print(a + " "); //напечатали проверку
} 
exit(); //ой, всё...
}
 
void draw() {

}

в файле при этом 3 байта.

RainMan
Offline
Зарегистрирован: 21.06.2011

спасибо за помощь. Как ни странно вчера тоже пришел к этому же решению. Но реализция опять через одно место. В отличие от output.print, функция savebytes() позволяет сохранить весь массив одним махом, без возможности дописывания данных ы файл. Отсюда прийдется мой массив цветов типа Color, растянуть в массив bytes  и потом сохраниять. Только непонятно что делать, если у меня данные о цветах типа Color расчитываются динамически, и например будут занимать в конечном итоге 20мб? Так-бы я их по мере поступления дописывал в файл, а так, не зная заранее конечный обьем данных color,  прийдется делать нереальной длинны масив типа color, и такой же нереальный массив  byte. 

И в вашем примере, очевидно перед занесением байта в массив надо было бы от значения цвета отнять 127:) Но каким-то мне непонятным образом процессинг приводит byte(255) к FF, вместо того чтобы ругнуться на то, что исходные данные находятся вне диапазона значений byte (-128 127)

ourlive
Offline
Зарегистрирован: 26.05.2012

там всё написано же, весь пример цельнотянут из справик к разным функциям. Зачем отнимать, если оно при конвертации само куда надо отнимется. Цыфры в пример не от балды ж выбраны, а показать, что всё работает.

А париться на счёт буфера данных на компе несколько странно, но и эта проблема решаема, хотя тут шаманить без крайней надобности не стоит, всё равно всё упрётся в необходимость кэша.