Не ведись квон! Это провокация, там классов нет! И даже без шаблонов. Такой код недопустим, работать будет не стабильно, он не масштабируется и его поддержка невозможна. Ему здесь не место!
Не ведись квон! Это провокация, там классов нет! И даже без шаблонов. Такой код недопустим, работать будет не стабильно, он не масштабируется и его поддержка невозможна. Ему здесь не место!
И ты, Брут. А он тебя жалел, говорил, флудерасты выгнали, на форум не пущают.
/**/
void saveStringToEeprom(int adr, String obj) {
unsigned int len = obj.length() + 1;
for (unsigned int i = 0; i < len; i++, adr++)
eeprom_write_byte((uint8_t*)adr, obj[i]);
}
void loadStringFromEeprom(int adr, String &obj) {
obj = "";
uint8_t tmp;
do {
tmp = eeprom_read_byte((uint8_t*)adr);
adr++;
obj += String((char)tmp);
}
while (tmp != 0);
}
String StringFromEeprom(int adr) {
String obj("");
uint8_t tmp;
do {
tmp = eeprom_read_byte((uint8_t*)adr);
adr++;
obj += String((char)tmp);
}
while (tmp != 0);
return obj;
}
//---------------------------------------------
const int adr1 =/*адресс eeprom*/10;
const int adr2 =/*адресс eeprom*/20;
//-----------------------------------------------------
void setup() {
Serial.begin(9600);
String aaa("qwerty");
Serial.println(aaa);
saveStringToEeprom(adr1, F("qwone"));
saveStringToEeprom(adr2, F("Winnie the Pooh"));
loadStringFromEeprom(adr1, aaa);
Serial.println(aaa);
String bbb(StringFromEeprom(adr2));
Serial.println(bbb);
}
void loop() {
}
Строка номер 2 - надо по ссылке передавать параметр типа String, чтобы не было копирования, со всеми вытекающими, типа жёсткой работы с памятью.
Писать/читаться строки в EEPROM лучше с префиксом - сколько байт сохранено. У String есть чудесный метод reserve, который избавит тебя от дичайшей переаллокации каждый раз, когда ты плюсуешь к строке один байт. Представь, что у тебя сохранена строка в 50 байт - в твоём случае это целых 50 выделений/освобождений памяти, зачем ты так не любишь микроконтроллеры?
Квон, я понимаю, что сказать нам - дуракам хоть слово, с высоты твое величия - западло. А потому я не знаю, зачем ты выложил этот вариант. Но, если в смысле, что в нём нету фрагемнтации памяти, то мимо - никуда она не делась, смотри
#include <MemoryExplorer.h>
/**/
void saveStringToEeprom(int adr, String obj) {
unsigned int len = obj.length() + 1;
for (unsigned int i = 0; i < len; i++, adr++)
eeprom_write_byte((uint8_t*)adr, obj[i]);
}
void loadStringFromEeprom(int adr, String &obj) {
obj = "";
uint8_t tmp;
do {
tmp = eeprom_read_byte((uint8_t*)adr);
adr++;
obj += String((char)tmp);
}
while (tmp != 0);
}
String StringFromEeprom(int adr) {
String obj("");
uint8_t tmp;
do {
tmp = eeprom_read_byte((uint8_t*)adr);
adr++;
obj += String((char)tmp);
}
while (tmp != 0);
return obj;
}
//---------------------------------------------
const int adr1 =/*адресс eeprom*/10;
const int adr2 =/*адресс eeprom*/20;
//-----------------------------------------------------
void setup() {
Serial.begin(115200);
memoryReport("At Start");
String aaa("qwerty");
Serial.println(aaa);
saveStringToEeprom(adr1, F("qwone"));
saveStringToEeprom(adr2, F("Winnie the Pooh"));
loadStringFromEeprom(adr1, aaa);
Serial.println(aaa);
String bbb(StringFromEeprom(adr2));
Serial.println(bbb);
memoryReport("Freed p1");
}
void loop() {
}
Ну с точками т тире каждый может. А ты с буквами покажи :)
Да там всего лишь это еще раз обернуть. Передавать побуквенно заменив буквы на точки и все. Долго таблицу составлять для всех букв русских английских больших и маленьких и спец знаков.
ua6em, я не стрелюсь к простым скетчам или компактным. Я стремлюсь к таким что бы и опыт подчерпнуть и потом в процессе совместить с другими компонентами, причем по возможности не блокирую их работу.
Пух, стандартное поведение древнего Виндовс АПИ, когда отдаваемый буфер может быть разного размера, это вызов функции с пустым указателем, тогда она реально ничо никуда не пишет, а отдает длину необходимого буфера. После этого ты отгрызаешь памяти скока надо и вызываешь ф-ю повторно, уже с правильным указателем на буфер нужного размера, и отец Вындоуз его наполняет.
Я сделал так (строка в ROM храница вместе с нулем)
// читает строку из адреса ASrcAddr в буфер AStrBuf вместе с завершающим нулем
// отдает длину в байтах прочитанной строки (вместе с нулём)
// если вызвать с NULL вместо адреса буфера куда читать, можно невозбранно поиметь длину строки
//
// Пример:
//
// size_t len = EEPROM.ReadString(0x100, NULL); сначала узнаем, скока байт надо (вместе с нулём)
// char *str = new char[len]; потом выделим память
// EEPROM.ReadString(0x100, str); потом прочитаем строку
// Serial << str << '\n'; чонить с ней сделаем
// delete[] str; и удалим, када станет не надо
size_t ReadString(addr_t ASrcAddr, char *AStrBuf) {
char c;
size_t len = 0;
do {
c = readByte(ASrcAddr++);
if (AStrBuf != NULL) AStrBuf[len] = c;
} while (len++, (c > '\0'));
return len;
}
Ну вот, квон - осталось дооптимизировать, сохраняя байт длины строки перед самой строкой, и при чтении - вычитывать сначала один байт, потом резервировать память, потом - читать данные. Не помешает ещё заголовок в пару байт, чтобы убедиться, что данные таки сохранены.
По итогу что это всё даёт:
1. Есть заголовок - проверка записи на валидность;
2. Есть длина данных - не надо её высчитывать мееедленным чтением из EEPROM.
На примере строки в 1 байт длиной: твой вариант (с хранением нулевого завершающего байта) - даст чтений 2 + 2 = 4. Мой вариант, с заголовком из двух байт, байтом длины и данными, даст чтений 2 + 1 + 1 = 4. При этом мой вариант бьёт твой, начиная с длины строки > 1.
Скетч использует 3088 байт (10%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 198 байт
Виш! 112 байт на ровном месте! И притом что "pustozvon" еще и длинней чем "qwone" ;)
Как избавится от стринга при переменной длине строки в loadFromEeprom, а заодно от использывания кучи и следовательно фрагментации - думай квон, думай ;) Меня ж тошнить начинает когда я вижу два прохода в loadFromEeprom и return obj.
Да. В WAVGAT по другому. Но не суть важно, важно другое - указатель (или адрес) всегда эффективней будет.
Еще один забавный пример, давно хотел глянуть на эти цифры.
void setup() {
int t;
// put your setup code here, to run once:
Serial.begin(9600);
for(char c='1';c<'z';c++)
{
t=micros();
Serial.print(c);
Serial.print(':');
Serial.println((int)micros()-t);
}
}
void loop() {
// put your main code here, to run repeatedly:
}
Все просто, меряем время вывода в сириал. Имеем
1:12
2:16
3:16
4:12
5:12
6:16
7:16
8:12
9:16
::12
;:12
<:1728
=:2076
>:2076
?:2076
@:2076
На 2 порядка!!!
Все просто, пока в буфер помещается - быстро. Потом сильно медлено.
На первый взгляд это к примерам выше вобще не относится. Но только на первый. Т.к. на второй позволяет понять есть ли разница между выводом всей строки сразу и выводом её по символьно. Ну и когда как стоит делать. Кстати 2076мксек - время на реальную, физическую отправку 2 байт на скорости 9600бод.
Воспользуйтесь этим драйвером I2C, ....
Не ведись квон! Это провокация, там классов нет! И даже без шаблонов. Такой код недопустим, работать будет не стабильно, он не масштабируется и его поддержка невозможна. Ему здесь не место!
Воспользуйтесь этим драйвером I2C, ....
Не ведись квон! Это провокация, там классов нет! И даже без шаблонов. Такой код недопустим, работать будет не стабильно, он не масштабируется и его поддержка невозможна. Ему здесь не место!
И ты, Брут. А он тебя жалел, говорил, флудерасты выгнали, на форум не пущают.
DetSimen,точно херня с буфером на 30 вылезла.
ПС: и да когда кому-нибудь захочется проверить этот код не забудьте подключить модуль
Примитив но просто не интересовался этим.
Примитив но просто не интересовался этим.
и так тоже отрабатывает
Да и ваша версия отъедает ОЗУ.
А Ваша? Точно так же отъёдает, ни на байт не меньше. Только не статикой, а запросом памяти при работе конструктора.
Пух, ты лучше на выборы сходи.
DetSimen, вы тоже сходите. Напишите на бумажке свой выбор и бростьте ближайшую урну.Результат будет такой же.
Пух, за что так с памятью-то? Совсем не жалко? Чё она тебе плохого сделала, что ты её так?
вот чего печатает
Это тока фрагментация, а сколько там по ходу дела нафик не нужных запросов - жуть, сам посмотри.
Строка номер 2 - надо по ссылке передавать параметр типа String, чтобы не было копирования, со всеми вытекающими, типа жёсткой работы с памятью.
Писать/читаться строки в EEPROM лучше с префиксом - сколько байт сохранено. У String есть чудесный метод reserve, который избавит тебя от дичайшей переаллокации каждый раз, когда ты плюсуешь к строке один байт. Представь, что у тебя сохранена строка в 50 байт - в твоём случае это целых 50 выделений/освобождений памяти, зачем ты так не любишь микроконтроллеры?
... У String есть чудесный метод ...
Вот если меня спросить, что мне более всего нравится в стрингах, то я отвечу, что в "стрингах" мне более всего нравятся барышни... лет 25ти. ;))))
Ответ на #163.
Квон, я понимаю, что сказать нам - дуракам хоть слово, с высоты твое величия - западло. А потому я не знаю, зачем ты выложил этот вариант. Но, если в смысле, что в нём нету фрагемнтации памяти, то мимо - никуда она не делась, смотри
Печатаить
Ну и зарисовки по Морзе
Ну с точками и тире каждый может. А ты с буквами покажи :)
А почему для статусов какой нибудь enum, ну или #define не используешь ? Какая у тебя на сей счет религия ?
Ну с точками т тире каждый может. А ты с буквами покажи :)
Не, не экономно... Не красиво получится :(
Квон - какой такой душ?
st_dush
Тире - это dash.
с точками, тире и генерацией частоты на пине самый простой скетч у Максима Клименко, занимает менее 1600 байт, озу 445 байт )))
с точками, тире и генерацией частоты на пине самый простой скетч у Максима Клименко, занимает менее 1600 байт, озу 445 байт )))
Расход ОЗУ в приведённом скетче можно сократить раз в 10 ;) Переместив кое-чего во флеш ;)
ua6em, я не стрелюсь к простым скетчам или компактным. Я стремлюсь к таким что бы и опыт подчерпнуть и потом в процессе совместить с другими компонентами, причем по возможности не блокирую их работу.
с точками, тире и генерацией частоты на пине самый простой скетч у Максима Клименко, занимает менее 1600 байт, озу 445 байт )))
Расход ОЗУ в приведённом скетче можно сократить раз в 10 ;) Переместив кое-чего во флеш ;)
со строкой понятно, а массив как?
с точками, тире и генерацией частоты на пине самый простой скетч у Максима Клименко, занимает менее 1600 байт, озу 445 байт )))
Расход ОЗУ в приведённом скетче можно сократить раз в 10 ;) Переместив кое-чего во флеш ;)
со строкой понятно, а массив как?
А чем массив отличается от строки таким, что его нельзя во флеш поместить? Правильно - ничем.
Пух, стандартное поведение древнего Виндовс АПИ, когда отдаваемый буфер может быть разного размера, это вызов функции с пустым указателем, тогда она реально ничо никуда не пишет, а отдает длину необходимого буфера. После этого ты отгрызаешь памяти скока надо и вызываешь ф-ю повторно, уже с правильным указателем на буфер нужного размера, и отец Вындоуз его наполняет.
Я сделал так (строка в ROM храница вместе с нулем)
с точками, тире и генерацией частоты на пине самый простой скетч у Максима Клименко, занимает менее 1600 байт, озу 445 байт )))
Расход ОЗУ в приведённом скетче можно сократить раз в 10 ;) Переместив кое-чего во флеш ;)
со строкой понятно, а массив как?
А чем массив отличается от строки таким, что его нельзя во флеш поместить? Правильно - ничем.
у меня не получилось, компилируется но не работает )))
Ну вот, квон - осталось дооптимизировать, сохраняя байт длины строки перед самой строкой, и при чтении - вычитывать сначала один байт, потом резервировать память, потом - читать данные. Не помешает ещё заголовок в пару байт, чтобы убедиться, что данные таки сохранены.
По итогу что это всё даёт:
1. Есть заголовок - проверка записи на валидность;
2. Есть длина данных - не надо её высчитывать мееедленным чтением из EEPROM.
На примере строки в 1 байт длиной: твой вариант (с хранением нулевого завершающего байта) - даст чтений 2 + 2 = 4. Мой вариант, с заголовком из двух байт, байтом длины и данными, даст чтений 2 + 1 + 1 = 4. При этом мой вариант бьёт твой, начиная с длины строки > 1.
Напишешь ещё вариант? Думаю, пригодится ;)
мой вариант бьёт твой, начиная с длины строки > 1.
Пожалуй, я с тобой соглашуся. Хоть чтение и не так тормозит, как запись, но сётаки переделаю.
Ой квон, безнадежен ты. Абсолютно безнадежен.
Твое:
Скетч использует 3200 байт (10%) памяти устройства. Всего доступно 30720 байт.
Правильное:
Мда. В какую битву титанов я влес... А ведь даже писАть не умею. :)
Но я, кста, не уверен, что он тут хотел из EEPROMa в EEPROM писать
мне кажеца, *p это указатель на ОЗУ.
кажется - проверь! Не сцо! В боях крепчают! Оба кода рабочие. А PROGMEM и EEPROM - точно разные штуковины.
АААААА там же из флэша в EEPROM, точно. Звиняйте.
кажется - проверь! Не сцо! В боях крепчают! Оба кода рабочие. А PROGMEM и EEPROM - точно разные штуковины.
в WAVGAT это одно и тоже вроде как, только адреса разные
Да. В WAVGAT по другому. Но не суть важно, важно другое - указатель (или адрес) всегда эффективней будет.
Еще один забавный пример, давно хотел глянуть на эти цифры.
Все просто, меряем время вывода в сириал. Имеем
Кстати 2076мксек - время на реальную, физическую отправку 2 байт на скорости 9600бод.
так буфер у сериала вроде как должен быть 16 байт, куда остальные делись?
Я слышал что 64байта по умолчанию. И по примеру тоже похоже. Первые 11 быстро прошли. Имеют строк по 6 байт в строке. Итого 66.
Кстати 2076мксек - время на реальную, физическую отправку 2 байт на скорости 9600бод.
так буфер у сериала вроде как должен быть 16 байт, куда остальные делись?
изучи нимательно
и доложи, у какой ATMeg-и Serial буфер 16 байт.
Кстати 2076мксек - время на реальную, физическую отправку 2 байт на скорости 9600бод.
так буфер у сериала вроде как должен быть 16 байт, куда остальные делись?
изучи нимательно
и доложи, у какой ATMeg-и Serial буфер 16 байт.
это тлетворное влияние PC-XT
Выдернутый отсюда код как писать большими буквами в lcd2004 https://github.com/voltnik/SmokeClock/blob/master/SmokeClock/SmokeClock.ino
Моя библиотека для работы с 2004
Сброшу мои наметки для работы EEROMом