Вопрос по системам счисления или сага о пропавшей "0b"
- Войдите на сайт для отправки комментариев
Привет всем! Курил даташит RTC DS3231 на предмет вывода из нее температуры, вывел, но получил какие-то хреновые значения. Разобрался, что микросхема по запросу выдает на шину I2C два байтика, в одном лежит целая часть числа, а во втором - дробная его часть. То есть, если у нас в комнате 25.25 градусов, то на шину свалится "00011001" и следующим упадет огрызок дробной части в виде "01". О как, обрадовался я, значит, думаю, переведу это дело в DEC и будет мне щастье. Ага, щас. Лезет что попало. Тогда я создал фиктивную переменную со значением из даташита, 25 градусов, но что бы я ни делал, в монитор падает строго единичка. Только лишь если я отправляю не "00011001", а "0b00011001", в мониторе порта оказывается заветная "25". Вот код, кто захочет повторить.
#define button 13 //будет кнопка на пине 13, шобы светик загорался на всякий void setup() { pinMode(button, INPUT); //подтягиваем резистором digitalWrite(button, HIGH); //устанавливаем состояние Serial.begin(9600); //тут и сериал подтянулся } void loop() { if (digitalRead(button) == LOW) //если кнопка нажата то { delay(500); //ждем 100мс byte byte1 = 0; byte byte2 = 0;//создаем парочку локальных переменных byte1 = 00011001; //и суем в них вот эти значения (ЭТО 25 в DEC!) //А далее пытаемся вывести в монитор порта разные варианты представления этой переменной Serial.println(byte1); //для начала просто грубо суем ее в порт. Получаем единицу. WTF? Serial.println(byte1, DEC); //ладно, пробуем принудительно вывести ее в десятичной системе //но хер там плавал. Снова получаем единицу. Serial.println(byte1, HEX); //Может тогда в шестнадцатеричной?.. Кол! Serial.println(byte1, BIN); //и повторим результат выводом тем же бинарным кодом //везде единички Serial.println(" "); //пробел для наглядности //зато как только я написал вот в таком формате, сразу же все получилось //и заветное "25" вылетело на монитор byte2 = 0b00011001; Serial.println(byte2); Serial.println(" "); //пробел для наглядности, если захочется еще раз //нажать кнопочку } }
В связи со всем вышеописанным, у меня вопрос, наверняка не зря мне дуина кол ставит, очевидно я не знаю каких-то великих тайн ардуиностроения, прошу направить меня на путь истинный, или же предложить, как переделать получаемое с датчика значение в виде "00011001" в вот такое вот удобное для понимания контроллера: "0b00011001". Да и вообще, с чего это дуинка бинарный код во что-то свое собственное переделывает?
Усаживайтесь поудобнее и берите попкорн - Вы тут надолго ))))
Звучит многообещающе:D
А где тут работа с ds3231? Что б считать температуру, программы то на 6 строчек..
И правда, ваш скетч работает:о А не могли бы вы объяснить, зачем смещать на два, потом второй полученный байт на шесть, а затем умножать на 0.25 полученное значение temp?
ellfmd, в 16 строке ты присваиваешь байтовой переменной 11 тыщ один, компилятор честно 11 тыщ откидывает, а единичку помещает в переменную byte1.
Andy, а если я указываю, что это 11001 в BIN, то почему ничего не меняется?
ellfmd, вы недокурили даташит:) Там же всё есть, даже с картинками. На два бита влево -что б зарезервировать в результатирующей переменной в качестве младших бит два бита из второго байта. А на 6 вправо -потому, что два бита во втором байте лежат на месте старших бит. 0.25 -это разрешение. Каждый "попугай" получившегося значения после всех передвижек -это 0,25 градуса. С умножением число становится в привычном счислении.
ellfmd, вы недокурили даташит:)
Или перекурили чего-то ещё.
Не понял, в чём фишка.
Запись 0b00011001 означает число 25, а запись 00011001 - число 4609. При преобразовании в байт 4609 даёт 1 - именно её Вы и наблюдали.
В чём непонятка то?
dimax, ааа, всё сразу стало ясно! Спасибо большое))
Хотя я и правда не видел, чтобы там было написано про сдвиг в какую-либо сторону... А вот еще такой вопрос, написав
я делаю запрос на получение оттуда байта. А ведь есть еще регистр 0x12, который, получается, не используется? Но ведь он является "LSB of Temp", как указано в адресной карте. Или запросом двух байт сразу из регистра 0х11 сразу запрашивается и 0х12?
ЕвгенийП, да понял уж... Все это дело изучаю не так давно, поэтому смею встречать лицом грабли, в виде таких очевидностей:)
ellfmd, это особенность библиотеки wire, достаточно указать адрес, с которого начинать чтение, и можно читать последовательно нужное кол-во байт.
ЕвгенийП, да понял уж... Все это дело изучаю не так давно, поэтому смею встречать лицом грабли, в виде таких очевидностей:)
Уверен. что понял? И понимаешь почему "00011001 - число 4609"? Точно? Т.е. ты понимаешь почему вот такой код:
Выдаст вот такие значения:
Тебя здесь ничего не смущает и всё понятно?
Если нет, то лучше уж разберись, потому что завтра опять на эти же грабли наступишь.
Можно, кстати, нескромный вопрос? А на кой хрен Вам сдалась температура поверхности кристалла RTC?
Тебя здесь ничего не смущает и всё понятно?
Полагаю, что n1=11001 он распознал, как число в десятичной системе, да так его и сунул в порт.
А n0, так как увидел, что она начинается с нулей, то подумал:"Ага! Это, 100% BIN".
А вот дальше что он стал делать, я честно не понимаю:с Ведь в двоичной это 25... Или я путаю толстое с мягким?
Не, ну а чо бы не использовать внутренний термометр кристалла, чтобы измерить температуру окружающей среды)
00011001 - число 4609.
Я не понял ... Почему? 11001, это одиннадцать тысяч один.
Я не понял ... Почему? 11001, это одиннадцать тысяч один.
Совершенно верно.
А вот 011001 - это 4609
Запустите мой скетч и убедитесь сами.
См. мой следующий пост.
А n0, так как увидел, что она начинается с нулей, то подумал:"Ага! Это, 100% BIN".
А вот дальше что он стал делать, я честно не понимаю:с Ведь в двоичной это 25... Или я путаю толстое с мягким?
Ну, вот, а говорил, что разобрался :)
Если числовая константа начинается с лидируещего нуля, то в С (как и в С++) это восьмиричная константа. Стало понятнее?
Не, ну а чо бы не использовать внутренний термометр кристалла, чтобы измерить температуру окружающей среды)
Так это ж не температура среды, а именно температура кристалла. Внутренне (в микросхеме) она используется для компенсации температурного дрейфа частоты. А Вам-то она зачем? Она всегда будет немного больше температуры среды, а если микросхема нагреется, так и намного больше.
Так вот оно чо! В голове всё сразу прояснилось)
Да вряд ли она сильно нагреется... но она достаточно точно определяет температуру приложенного к ней пальца. Кстати, а реально ли получить минусовое значение температуры на экране, если оно действительно опустилось ниже нуля?
Последнее, что я с этой микросхемой делал - "сгибридил" её с ESP8266 и полуил устройство, которое само устанавливается на точное время (через NTP получает), а заодно скачивает с gismeteo прогноз погоды :)
ellfmd, можно пользоваться встроенным термометром, и хоть на первой странице даташита заявлена точность +/- 3 °С считаю, что они этой цифрой сильно перестраховались. Фактическая точность не многим хуже популярного ds18b20, приклеить к чипу небольшой радиатор, что-б тот выходил за пределы корпуса изделия, и хорошо измеряет. С отрицательной тем-рой нет проблем, только в примере из #3 я знак затёр, нужно переделать вот так:
Я не понял ... Почему? 11001, это одиннадцать тысяч один.
Совершенно верно.
А вот 011001 - это 4609
Запустите мой скетч и убедитесь сами.
См. мой следующий пост.
А какое этому объяснение ? Где здравый смысл зарыт !?
,
А какое этому объяснение ? Где здравый смысл зарыт !?
Ну, я же сказал смотреть следующий пост. Там ясно написано, что если есть лидирующий ноль, то константа - восьмиричное число. Переведите 011001 из восьмиричной системы в десятичную и получите 4609.
Не знаю. С микросхемой я работал (с прерываниями, с генератором 32кГц сигнала и т.п.), но вот температуру у неё ни разу не спрашивал и не особо с нею разбирался ввиду ненадобности.
Последнее, что я с этой микросхемой делал - "сгибридил" её с ESP8266 и полуил устройство, которое само устанавливается на точное время (через NTP получает), а заодно скачивает с gismeteo прогноз погоды :)
Прикольно, я хочу заказать с али ESP8266, думаю, стоит того))
dimax, а знак как тут должен появиться? Сейчас довольно тепло, проверить не получается:D
Вроде одинаковое значение получается при обоих операциях... Как отсюда минус извлечь?
Прикольно, я хочу заказать с али ESP8266, думаю, стоит того))
Питать-то я ее буду от внешнего аккумулятора, а вообще, хотелось бы запрограммировать, чтобы она делала всё сама, раз уж такая возможность у нее имеется. Киньте статью по преобразованию 3.3-5В?
ellfmd, знак появиться когда результат выводится. Не переживайте, будет минус. Можно модуль в морозильник на 5 мин положить, потом быстро подключить :)
Киньте статью по преобразованию 3.3-5В?
http://we.easyelectronics.ru/Shematech/soglasovanie-logicheskih-urovney-...
Правда, сам я делал через
ж... в смысле. через Альпы - поставил туда операционный усилитель. Вернее 2 - первый по инвертирующей схеме понижал, а второй "взад" инвертировал. Они как раз оба в одной миксросхеме живут.хотелось бы запрограммировать, чтобы она делала всё сама, раз уж такая возможность у нее имеется.
Имеется специальный сайт/форум фанатов этой микросхемы - там много чего и о её программировании трётся. Сходите. полюбопытствуйте.
ellfmd, знак появиться когда результат выводится. Не переживайте, будет минус. Можно модуль в морозильник на 5 мин положить, потом быстро подключить :)
Есть минус, всего три минуты в морозилке)
Только мне бы все равно знать, в каком битике он лежит, этот самый минус, чтобы распознавать его и складывать в отдельную переменную, просто я делаю наручные часы на вакуумно-люминесцентном индикаторе, и каждую циферку мне приходится прописывать в отдельный разряд. Так что придется разбирать получаемое значение температуры по числам, и минус как-то тоже определять (определять, что он наступил и ставить соответствующую черточку)
минус как-то тоже определять (определять, что он наступил и ставить соответствующую черточку)
Я наверное чего-то не понимаю, но неужели не поможет сравнение числа на "меньше нуля"? Ну а вообще-то минус хранится в самом старшем бите числа. Чтобы много не расписывать - вот.
ellfmd, Минус лежит в старшем бите if (temp&1<<15) значит минусовая. Но можно и по-простому if (temp<0)