собрать unsigned long из Serial.read();
- Войдите на сайт для отправки комментариев
Чт, 21/01/2016 - 17:36
Доброго времени суток!
Есть входящий поток данных , мне необходимо "поймать" 4 первых байта и собрать в unsigned long
например так:
byte i = 0: unsigned long *ptrVar; while (Serial.available()) { if (i < 4) ptrVar[i] = Serial.read(); i ++; } Serial.println(*ptrVar);
В итоге получаю 10, хотя при чтении идут сплошные нули. Что делаю не так?
Надо объявить массив символов char arr[4] заполнить его данными из порта и после этого смотреть на него как на unsigned long. Либо полученные данные сразу класть в unsigned long переменную со сдвигом.
Надо объявить массив символов char arr[4] заполнить его данными из порта и после этого смотреть на него как на unsigned long. Либо полученные данные сразу класть в unsigned long переменную со сдвигом.
Ну с первым понятно, хотелось бы второй вариант, можете поподробнее?
типа такого:
типа такого:
А Вы это пробовали, прежде, чем человеку предлагать? Оно ж в таком виде не работает ни фига.
Да, действительно не работает, вот например:
Вроде как 256 должно быть, а получаю 1310785793
Вроде как 256 должно быть, а получаю 1310785793
Ну, во-первых, Вы забыли проинициализировать ptrVar.
Во-вторых, для корректности эксперимента Вам следует в строке 3 вместо
char
a[4]
использоватьint
a[4]
, т.к. метод read() возвращает именно int.Но работать всё равно не будет.
Переопределить тип переменным не судьба? ptrVar |= (long)a[i] << (i*8);
Переопределить тип переменным не судьба? ptrVar |= (long)a[i] << (i*8);
Не знаю, Вам виднее судьба Вам или не судьба. Видимо, не судьба, раз дали начинающему коллеге неработающий код.
Да и сейчас signed с unsigned в одну кучу свалили, что тоже не самая лучшая практика.
Из чего следует что я что-то с чем-то свалил в одну кучу? Я так понимаю на этом возражения закончились....
Почитал о регистровом сдвиге, наваял такой код:
Работает, только задом на перед, младшие байты попадают на место старших. Как это сделать правильно?
Код ptrVar |= (long)a[i] << (i*8); я не совсем понимаю, это получается мы сдвигаем биты элемента массива a[i], а потом проводим логическую операцию ИЛИ этого сдвинутого элемента и переменной ptrVar?
И по поводу приведения char в long, разве так можно? Мы же так код символа получим вместо самого числа?
Ну, во-первых, Вы забыли проинициализировать ptrVar.
Во-вторых, для корректности эксперимента Вам следует в строке 3 вместо
char
a[4]
использоватьint
a[4]
, т.к. метод read() возвращает именно int.Да, увидел свою ошибку, спасибо!
Из чего следует что я что-то с чем-то свалил в одну кучу? Я так понимаю на этом возражения закончились....
prtVar какого типа? А в правой части Вы к какому приводите? Вот из этого и следует. что свалили в одну кучу.
ЕвгенийП, х...вый из тебя инженер программист, если свои сопли пытаешься на меня повесить. Я лишь кинул идею, то что новичек не разобрался это простительно, то что ты начал сопрли пузырями надувать - это говорит о том, какой ты программист. Просто помоги челу и слейся.
rene, хорошо, что разобрались, но с точки зрения эффективности и по памяти, и по времени, лучше всё-таки использовать другой способ о котором Вам говорили. Там не нужно ничего никуда сдвигать, само всё ложится.
Вот смотрите:
Здесь мы присваиваем значения байтам, а потом печатаем получившийся unsigned long. Никаких сдвигов и вообще никаких дополнительных действий.
И по поводу приведения char в long, разве так можно? Мы же так код символа получим вместо самого числа?
При преобразованиях вида (<тип>)<переменная> на самом деле НИЧЕГО не преобразовывается и ничего не меняется. Просто впредь компилятор считает это новым типом. А реально в памяти остаётся ровно то, что было до этого - ничего не меняется никак.
Код ptrVar |= (long)a[i] << (i*8); я не совсем понимаю, это получается мы сдвигаем биты элемента массива a[i], а потом проводим логическую операцию ИЛИ этого сдвинутого элемента и переменной ptrVar?
1. заводим long и в младший байт помещаем значение a[i] (более грамотно здесь делать не long, а unsigned long)
2. этот long сдвигаем влево на i*8 битов
3. Переменной ptrVar присваиваем результат операции ИЛИ между её старым значением и нашим long, получившимся после сдвига.
Спасибо за помощь!