Подключаем датчик температуры к шине данных i2c
-
i2c - шина данных для обмена информацией между устройствами. Представлена двумя линиями - линия данных SDA (второй вывод в колодке GPIO) и тактовая линия SCL (третий вывод в колодке GPIO).
Как передаются данные по i2c на электрическом уровне я описывать не буду, это всё можно прочитать в гугле, поэтому перейдём сразу к практической части. Нам потребуется чип датчика температуры LM75A:
Поскольку чип выполнен в очень неудобном для домашнего использования форм-факторе soic-8 (очень мелкий), то нам также потребуется переходник на DIP-8,
чтобы можно было сделать проводное соединение с Raspberry Pi. Припаиваем чип к переходнику. Линии SDA и SCL необходимо подтянуть резисторами 1кОм к питанию.В итоге конструкция должна выглядеть примерно так:
Я использовал Raspbian по 2 причинам:
-
В дистрибутив включены i2c драйвера в виде модулей ядра, которые остаётся лишь подгрузить командой modprobe
-
в репозитории есть i2c-tools, которые нам потребуются для работы с датчиком температуры Итак, подгружаем модули ядра, которые позволят нам работать с i2c:
sudo modprobe i2c-dev sudo modprobe i2c-bcm2708
Устанавливаем i2c-tools из репозитория:
sudo apt-get install i2c-tools
В i2c-tools входят следующие утилиты:
- i2cdetect - для определения устройств, подключенных к шине i2c
- i2cget - для чтения данных из регистров подключенных устойств
- i2cset - запись данных в регистры подключённых устройств
Для начала проверим, что драйвера успешно подгрузились и шина данных i2c видна.
i2c-detect -l
Если в выводе команды отобразились доступные шины i2c (i2c-0, i2c-1), то значит можно двигаться дальше.
Будем работать с i2c-0. Подключим датчик температуры к линиям SDA0 и SCL0, 5V питания и GND для датчика также будем брать с колодки GPIO.
Если датчик правильно подключён, то в ответ на команду i2cdetect -y 0 мы увидим сетку, в одной из ячеек которой будет стоять адрес датчика (в моём случае 48).
К одному ведущему (master) устройству по i2c можно подключить множество ведомых (slave), поэтому каждому ведомому устройству необходим адрес, по которому к нему будет обращаться ведущее устройство. Адрес датчика LM75A задаётся в регистре Conf
A2,A1,A0 - выводы 7,6,5 чипа LM75A(см.схему ниже). Если они присоединены к питанию, то принимают значение 1, если к земле, то 0. У меня А0 A1 A2 посажены на землю, а значит регистр, отвечающий за адрес имеет значение (1001000=0x48), что подтверждается командой i2cdetect
Теперь получим значение температуры. LM75A проводит замеры температуры каждые 100мс. Её значение хранится в регистре Temp, который состоит из двух байтов. t=(значение регистра Temp, сдвинутое на 5 битов вправо)*0.125
Получим значение регистра:
i2cget -y 0x48 0x00 w
-y: игнорировать предупреждение о потенциальной опасности i2c-tools для вашего оборудования.
0x48 - адрес датчика на шине i2c
0x00 - адрес регистра Temp
w - получить слово данных (поскольку ответ состоит из двух байтов. Для получения одного байта нужно использовать параметр b)
в ответ мы должны увидеть значение регистра Temp. У меня это 0xa014
0xa0 - значение младшего байта (LSByte)0x14 - значение старшего байта (MSByte) записываем в двоичной форме и сдвигаем на 5 битов вправо: 10100101=165
165*0.125 = 20.625 градусов значение температуры на датчике.
Запись в регистры рассмотрим в следующей статье, в которой будем управлять чипом FM приёмника по i2c
-
-
а нельзя ли использовать внутреннюю подтяжку линий к + питания?
-
Пользователь @pi написал в Подключаем датчик температуры к шине данных i2c:
а нельзя ли использовать внутреннюю подтяжку линий к + питания?
Можно. На Raspberry Pi реализована внутренняя подтяжка SDA и SCL 1,8kОм резисторами. Просто эта панелька с датчиком температуры у меня валялась давно и подключалась к плате, в которой не было внутренней подтяжки на i2c линиях
-
это хорошо. в описании на этоту микросхемку есть фраза, что старший бит старшего байта определяет, положительная температура или отрицательная. как это можно реализовать в программе для вывода реальной температуры?
-
Пользователь @pi написал в Подключаем датчик температуры к шине данных i2c:
а нельзя ли использовать внутреннюю подтяжку линий к + питания?
Если температура отрицательная, то бит D10 старшего байта температурного регистра будет равен 1, т.е если значение старшего байта регистра температуры >127. В этом случае температура будет вычислять следующим образом: значение регистра температуры приводится к дополнительному коду (dop_code=~temp_registry_value+1), сдвигается на 5 разрядов вправо и умножается на 0.125: temp = (dop_code>> 5)*0.125
-
ответ
Люди, подскажите где мы берем коэффициент 0,125 на который умножаем. Никак не могу понять… -
Пользователь @pi написал в Подключаем датчик температуры к шине данных i2c:
ответ
Люди, подскажите где мы берем коэффициент 0,125 на который умножаем. Никак не могу понять…из документации к датчику
- If the Temp data MSByte bit D10 = 0, then the temperature is positive and Temp value (°C) = +(Temp data)×0.125°C.
- If the Temp data MSByte bit D10 = 1, then the temperature is negative and Temp value (°C) =−(2’s complement of Temp data)×0.125°C.