преобразование unsigned long > byte (4 штуки) и обратно
- Войдите на сайт для отправки комментариев
Сб, 24/11/2012 - 15:38
Появилась задачка - надо unsigned long сохранить в EEPROM.
Естественно, потом надо будет читать из EEPROM и собирать данные назад в unsigned long.
Подскажите, как сделать?
правильно ли я понимаю, что собрать можно так:
unsigned long value = (data[3] << 24) +(data[2] << 16) +(data[1] << 8) +data[0];
а как разобрать?
Пока не получается.
Поискал по форуму, нашел похожую задачу (там int разбирали на байты). "Разбор" получился красивый, а вот мое предположение по "сборке" - не сработало.
Где ошибка?
На вашем месте я сначала бы изменил формат вывода:
После чего мне сразу бы бросилось в глаза, что преобразование выполняется в общем-то правильно, но только для двух младших байтов:
val 1587632040 5EA157A8
168 A8
87 57
161 A1
94 5E
val 22440 57A8
После этого мне не оставалось бы ничего иного, как вспомнить, что обработка данных в микроконтроллерах AVR заточена под переменные размером в слово, т.е. два байта, т.е. (для математических действий) тип int. А, стало быть, компилятору необходимо явно указать, что работать будем не со словами а с двойными словами (тип unsigned long). А для этого необходимо выполнить кастинг (по-русски "приведение типа") участвующих в выражении переменных. Вот так (строка 16 в моем варианте):
После этого я прогнал бы скетч снова и получил вот такой вывод:
val 1587632040 5EA157A8
168 A8
87 57
161 A1
94 5E
val 1587632040 5EA157A8
"Почему в двух правых слагаемых нет этого чертового кастинга?" спросите вы. Да потому что там мы оперируем информацией в пределах слова, стало быть, явное приведение типов не является необходимым. А делать лишнюю работу нам естественно лень...
Можно еще воспользоваться такой интересной штукой, как Union
Тогда к переменной этого типа можно будт обращаться целиком через l или к каждому байту через b
Спасибо, оба варианта завелись. Второй вариант особенно понравился - красиво получилось!
Время доброе. Будьте добры, если не трудно разеснить выделинные действия?
unsigned long value = ((unsigned long)x[3] << 24) +((unsigned long)x[2] << 16) +(x[1] << 8) +x[0];
Зарание спасибо
Выделенные действия - результат выкрутасов HTML-редакторов и копипасты. В детстве все эти "<<" имели вид "<<". В своем посте - поправил.
Или вы имели в виду иное?
доброго времени суток.
собрал скетч по теме
с значениями val 1587632040 и 1587632040 собрать обратно число получается хорошо но с значение 1111134310 выводит
Подсажите пожалуйста где я ошибся.
Спасибо
У вас "каша-малаша" получилась. Вы зарбираете передавая ссылку на объединение (бред полный), а собираете сдвигами.
Тоже интересовал этот вопрос вот тут нашёл понятный для мне ответ http://playground.arduino.cc/Code/EEPROMReadWriteLong . Суть аналогична разложить на 4 байта , записать в епром , считать и собрать эти 4 байта обратно.
Тут https://www.arduino.cc/en/Reference/Bitshift наглядно объяснняют как это работает =)
Появилась задачка - надо unsigned long сохранить в EEPROM.
Естественно, потом надо будет читать из EEPROM и собирать данные назад в unsigned long.
Подскажите, как сделать?
Решил не создавать лишнюю тему, т.к. задача очень подобная.
Есть float, надо преобразовать в 4 байта.
float temper;
byte sendbuf[4];
temper = sensor.getTempC();
memcpy(&temper, &sendbuf[0], sizeof(float));
В результате операции в массиве sendbuf все нули, хотя в temper есть нормальное число.
Что не так?
У тебя источник и премник данных местами перепутаны в параметрах. Сначала адрес " куда", потом "откуда"
Ну так, шаблон наваяй, вместо того, чтоб некрофилией занимаца. А еще лучше - лямбда-шаблон.
Нельзя. Наебнется на куче платформ. Или порядок байтов будет неправильный.
Ну, на всех ардуинах этот код пишу при записи во внешний EEPROM по I2C, все работает, мне хватает, просто написал, может кому понадобиться.
Нормально. Компилил в линь_х64, тока буте на чар заменил. 8 байт длина лонга в х64. Какая хер разница, ежли пихать в еепром и оттуда же вытаскивать? Всё всё-равно останецца на своих местах.
EEPROM.put() поддерживает даже структуры