Перевод битов в десятичное число
- Войдите на сайт для отправки комментариев
Сб, 23/12/2017 - 18:28
Решил разобратся как работают датчики и начал писать функцию для разбора данных с датчика DHT11, прилетает мне в ответе 40 бит, как мне их разобрать для вывода в десятичном виде ? Видел с побитовыми операторами, но чет не понял что и как...
Бит - число двоичное. Только так их и можно выводить.
Это - если отдельные биты.
Но чаще биты фигурируют как часть некоторого многобитного объекта. В этом случае нужно выводить не биты, а нечто, что характеризует сам объект (а не отдельные его биты). Но для этого надо знать, что за объект перед нами.
понятно, что бит - число двоичное, написанно мне прилетает от датчика 40 бит - 5 байт, в каждом байте зашифрованна информация, температура и влажность, вот и спаршивается, как мне разобрать данные лучше, можно свой алгоритм написать и просто перевести с двоичной в десятичную, но я видел, что с помощью побитовых операторов это делают, но не понял как.
В этом случае нужно выводить не биты, а нечто, что характеризует сам объект (а не отдельные его биты). Но для этого надо знать, что за объект перед нами.
Боюсь, что ТС
чет не понял что и как...
:((((((((((
понятно, что бит - число двоичное, написанно мне прилетает от датчика 40 бит - 5 байт, в каждом байте зашифрованна информация, температура и влажность, вот и спаршивается, как мне разобрать данные лучше, можно свой алгоритм написать и просто перевести с двоичной в десятичную, но я видел, что с помощью побитовых операторов это делают, но не понял как.
Берите исходный код для любой библиотеки DHT, найдите там что-то типа:
crc = bits[0] + bits[2]; humidity = bits[0] * 10; // bits[1] == 0; temperature = bits[2] * 10; // bits[3] == 0;Теперь вам остается установить логическую связь между байтами и показаниями.
Готовое решение есть, я не могу там понять как выводятся данные с этих битов
у меня в массив byte data[40] , согласно даташиту, записанны биты, тип 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0
вот как их преобразовать в десятичные числа, я бы, например, разделил их по 8 бит, побайтно и перевел с двоичной в десятичную,
блин стыдно )), но немогу понять, как по простому все это сделать, раньше никогда не работал с этим
Не стремитесь к преждевременной оптимизации. Сделайте, как понимаете: разбейте на 5 фрагментов по 8 ячеек. Два цикла, один вложен в другой. Во внешнем перебираете "байты", во внутреннем "биты". Перед началом вложенного цикла инициализируйте временную переменную (обнуляйте) размером в байт. Во вложенном цикле выставляйте ей биты. Если не знаете, как делать это битовыми операциями, начните с https://www.arduino.cc/reference/en/language/functions/bits-and-bytes/bitset/ . По завершении вложенного цикла у вас есть сформированный во временной переменной байт. Пишите ее в массив "байты". По завершению внешнего цикла у вас есть заполненный массив "байты".
Сделаете, результат осмыслите и можете переходить к оптимизациям - битовые операции, все действия в одном цикле, прямая модификация элементов массивов "байты" без временных переменных.
у меня в массив byte data[40] ,
Жесть - читать с DHT 40 бит в массив из 40 байт - такого оверхеда давненько не видел :)
ну так подскажите как правильно сделать? А то оверхед...
ну так подскажите как правильно сделать? А то оверхед...
Ну вы же как-то читаете с линии, правда? Вот и пакуйте прочитанное значение в байты. 40 бит - это 5 байт, прочитать можно так (ПСЕВДОКОД! это значит, что он для демонстрации алгоритма, а не для чтения с DHT):
byte bytes[5] = {0}; int currentByteNum = 0; byte bitmask = 0x80; // старший бит байта установлен в единичку, его будем двигать вниз for(int i=0;i<40;i++) // читаем 40 бит { byte bitValue = readOneBitFromLine(); // читаем бит (1 или 0) с линии if(bitValue) // единичка { bytes[currentByteNum] |= bitmask; // выставляем её в байте } // сдвигаем маску вправо bitmask >>= 1; if(!bitmask) // дошли до конца байта { bitmask = 0x80; currentByteNum++; // читаем в следующий байт } }Что именно непонятно? Сами битовые операции?
Да, я пока не понимаю толком как их использовать, до вашего сообщения сидел и думал, похожее прилетело в голову, что-бы небыло 40 байт
застопорился как дозаписывать байт с каждой новой итерацией, тип 8 итерацей - создали байт
вот мой набросок
////// Начинаем принимать данные 40 бит /// byte data[5] = { 0 }; // массив для данных 5 байт unsigned char indxData = 0; // индекс для перехода к записи следующего байта unsigned char cntBit = 0; // счетчик бит по 8 для создания байта данных for (int i = 0; i < 40; i++) { // 0 - 50мкс timeOut = 0; while (digitalRead(pinDht) == LOW) { if (timeOut++ > 100) { return 3; } delayMicroseconds(4); } // сам прием, если длительность импульса 1-цы больше 40мкс, то пишем как 1, иначе 0 // 0 - 28мкс, 1 - 70мкс // засекаем время удержания 1 unsigned long int timeHoldHigh = micros(); timeOut = 0; while (digitalRead(pinDht) == HIGH) { if (timeOut++ > 100) { return 4; } delayMicroseconds(4); } //// тут думаю )) if ((micros() - timeHoldHigh) > 32) { data[indxData] = 1 <<; } else { data[indxData] = 0; } // считаем количество бит, если больше 8 - обнуляем счетчик и записываем новый байт if(cntBit++ > 7) { cntBit = 0; indxData++; } }понятно, что бит - число двоичное, написанно мне прилетает от датчика 40 бит - 5 байт, в каждом байте зашифрованна информация, температура и влажность, вот и спаршивается, как мне разобрать данные лучше, можно свой алгоритм написать и просто перевести с двоичной в десятичную, но я видел, что с помощью побитовых операторов это делают, но не понял как.
Вам не нужно переводить двоичную систему в десятичную, за Вас это потом сделает процедура print(), Вам нужно упаковать биты в байты по 8 штук в каждом. Прочитали очередной бит - записали его в младший (или старший - смотрите по дэйташиту) бит байта. Посмотрели, не готов ли целый байт (8 битов). Если готов - выдали наружу, если нет - сдвинули результат на 1 для приема следующего бита.
А вот когда байт готов целиком - посылаете его процедурой print() на экран и она сама представит его в десятичном виде.
Да я понял уже, раньше с таким не работал, да и почти 2 года ниче не кодил и тяжело врубится было, с этой штукой реально целый день ушел, тестировать в ардуино тяжело, на VS поигрался, дошло
// ConsoleApplication1.cpp: определяет точку входа для консольного приложения. // #include "stdafx.h" #include <iostream> using namespace std; int main(int argc, char* argv[]) { unsigned char data[16] = { 0,1,1,0, 1,0,1,1, 0,1,1,0, 1,1,1,0 }; // 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 // 107 110 unsigned int dataByte[2] = { 0 }; ////// Начинаем принимать данные 40 бит /// unsigned char indxData = 0; // индекс для перехода к записи следующего байта unsigned char cntBit = 7; // счетчик бит по 8 для создания байта данных, начало со старшего бита for (int i = 0; i < 16; i++) { //0 1 1 0 1 1 1 0 //0 0 0 0 0 0 0 0 //dataByte[indxData] << 1; if(data[i] == 1) dataByte[indxData] |= (1 << cntBit); //cout << indxData << " " << cntBit << endl; if (cntBit-- == 0) { cntBit = 7; indxData++; } } cout << dataByte[0] << endl; cout << dataByte[1] << endl; system("pause"); return 0; }