Liking cljdoc? Tell your friends :D



Interact with the popular BME280 sensor via I2C from clojure.

IO libraries often enforce specific behaviors such as error checking. The user is sometimes disconnected from what is happening. For instance, it is often unclear what exactly failed when an error occurs. Sometimes those libraries log what is happening, sometimes not.

Rather, this API aims to ressemble the datasheet. It offers specs, values and functions for processing and computing what is needed but do not perform IO operations. This approach means there is a bit more boilerplate but at least, the user has the freedom to handle things as suited.

We recommend using dvlopt.i2c for performing I2C operations.


Read the API.

The dvlopt.i2c.bme280/io map describes IO operations and holds useful information such as registers.

Using dvlopt.i2c (without error checking) :

(require '[dvlopt.i2c        :as i2c]
         '[dvlopt.i2c.bme280 :as bme280])

;; First, we need to open the I2C bus.
(def bus
     (::i2c/bus (i2c/open "/dev/i2c-1")))

;; Then, select the sensor (with the proper address).
(i2c/select bus

;; We need to configure our device as needed.
;; The easiest way is to use the high level function `prepare` which tells us what
;; we have to do.
(let [preparation (bme280/prepare {::bme280/iir-filter               0
                                   ::bme280/mode                     :forced
                                   ::bme280/oversampling.humidity    :x1
                                   ::bme280/oversampling.pressure    :x2
                                   ::bme280/oversampling.temperature :x4
                                   ::bme280/standby                  :1000-ms})]
 ;; Let's write the various configuration bytes to the proper registers.
 ;; Attention, order matters.
 (doseq [{register ::bme280/register
          ubyte    ::bme280/ubyte}   (::bme280/configuration.writes preparation)]
   (i2c/write-byte bus
 ;; Let's sleep util the measure completes.
 (Thread/sleep (::bme280/duration.max preparation)))

;; We need to read and prepare compensation words for adjusting sensor data later on.
(def cw
     (bme280/compensation-words (let [cmd (:compensation-words bme280/io)
                                      ba  (byte-array (::bme280/length cmd))]
                                 (doseq [{index    ::bme280/index
                                          length   ::bme280/length
                                          register ::bme280/register} (::bme280/registers cmd)]
                                   (i2c/read-bytes bus

;; Everything is ready for reading the sensors when needed.
(def buffer
     (byte-array (::length (:data bme280/io))))

(i2c/read-bytes bus
                (::bme280/register (:data bme280/io))

;; And finally processing this data.
(bme280/data buffer

;; => {::bme280/humidity    46.932   ;; %rH  
;;     ::bme280/pressure    960.3226 ;; Pa
;;     ::bme280/temperature 23.3}    ;; °C

(i2c/close bus)


Copyright © 2017-2018 Adam Helinski

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

Can you improve this documentation?Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close