Skip to content

Instantly share code, notes, and snippets.

@cr0t
Last active May 23, 2023 15:20
Show Gist options
  • Select an option

  • Save cr0t/1006aa5df942b1a817a32275598a0d05 to your computer and use it in GitHub Desktop.

Select an option

Save cr0t/1006aa5df942b1a817a32275598a0d05 to your computer and use it in GitHub Desktop.
Raspberry Pi, DockerPi SensorHub, I2C, Circuits.I2C, Elixir
defmodule Reader do
defmodule SensorHub do
@moduledoc """
Opens the first I2C bus ("i2c-1") and reads from SensorHub device address (0x17).
Updates its internal state periodically (every second in the example below).
Below you can find a table of registers, that we found on their website:
https://wiki.52pi.com/index.php/DockerPi_Sensor_Hub_Development_Board_SKU:_EP-0106
Register Address Function Value
0x01 TEMP_REG Ext. Temperature [Unit:degC]
0x02 LIGHT_REG_L Light Brightness Low 8 Bit [Unit:Lux]
0x03 LIGHT_REG_H Light Brightness High 8 Bit [Unit:Lux]
0x04 STATUS_REG Status Function
0x05 ON_BOARD_TEMP_REG OnBoard Temperature [Unit:degC]
0x06 ON_BOARD_HUMIDITY_REG OnBoard Humidity [Uinit:%]
0x07 ON_BOARD_SENSOR_ERROR 0(OK) - 1(Error)
0x08 BMP280_TEMP_REG P. Temperature [Unit:degC]
0x09 BMP280_PRESSURE_REG_L P. Pressure Low 8 Bit [Unit:Pa]
0x0A BMP280_PRESSURE_REG_M P. Pressure Mid 8 Bit [Unit:Pa]
0x0B BMP280_PRESSURE_REG_H P. Pressure High 8 Bit [Unit:Pa]
0x0C BMP280_STATUS 0(OK) - 1(Error)
0x0D HUMAN_DETECT 0(No Active Body) - 1(Active Body)
## How to run this code
1. Place this code into fresh mix project (`mix new ...`), name it `lib/reader.ex`, for example.
2. Add `{:circuits_i2c, "~> 0.3"}` to the `deps` section in `mix.exs` file.
3. Add `mod: {Reader, []},` to the `application` section in `mix.exs` file.
4. Run `iex -S mix`.
If your Raspberry Pi has configured to use I2C bus, it should work. If not – google.
"""
alias Circuits.I2C
@bus_name "i2c-1"
@sensor_hub_addr 0x17
@timeout_interval 1000
use GenServer
def init(_initial) do
{:ok, bus} = I2C.open(@bus_name)
{:ok, data} = get_sensors_data(bus)
{:ok, {bus, data}, @timeout_interval}
end
def handle_info(:timeout, {bus, data}) do
new_data = get_sensors_data(bus)
# just for debugging purposes
IO.inspect({data, new_data})
{:noreply, {bus, new_data}, @timeout_interval}
end
defp get_sensors_data(bus) do
{:ok,
<<0, ext_temp, light_low, light_high, status, on_board_temp, on_board_humidity,
on_board_error, bpm280_temp, bpm280_pressure_low, bpm280_pressure_medium,
bpm280_pressure_high, bpm280_status,
human_detect>>} = I2C.write_read(bus, @sensor_hub_addr, <<0>>, 0x0E)
{:ok,
%{
external_temp: ext_temp,
light_low: light_low,
light_high: light_high,
status: status,
on_board_temp: on_board_temp,
on_board_humidity: on_board_humidity,
on_board_error: on_board_error,
bpm280_temp: bpm280_temp,
bpm280_pressure_low: bpm280_pressure_low,
bpm280_pressure_medium: bpm280_pressure_medium,
bpm280_pressure_high: bpm280_pressure_high,
bpm280_status: bpm280_status,
human_detect: human_detect
}}
end
end
use Application
def start(_type, _args) do
{:ok, _pid} = GenServer.start_link(Reader.SensorHub, %{})
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment