Home Posts Tags Post Search Tag Search

Post 63

Weather App 10 - Using Acurate Temp Humidity values.

Published on: 2025-08-20 Tags: elixir, Blog, State, Nerves, Weather App, Poncho
For this we will work on getting the correct values for the Temp and Humidity for the SGP40 sensor to get the most accurate sensor reading. This will center around starting the BME280 sensor with the Module name as its pid ID and then adding in the lib for BME280 to the SGP40 sensor.

First I added the {:bme280, path: "../bme280"} to the mix for the SGP40.

Then making sure that I have the correct lib imported
Alias Bme280

With that I was able to now get the values from the Bme280 sensor.

Now these will be human readable value and we need tuples for the converter

I created the following to convert from one to the other.
  import Bitwise
  @moduledoc """
  Converts temperature and humidity from human-readable values
  to SGP40 ticks for VOC compensation.
  """

  @doc """
  Convert temperature in °C to SGP40 ticks.
  Formula from SGP40 datasheet: T_ticks = ((T[°C] + 45) * 65535) / 175
  """
  def temperature_to_ticks(temp_c) when is_number(temp_c) do
    round((temp_c + 45) * 65_535 / 175)
  end

  @doc """
  Convert relative humidity %RH to SGP40 ticks.
  Formula from datasheet: RH_ticks = RH[%] * 65535 / 100
  """
  def humidity_to_ticks(humidity_rh) when is_number(humidity_rh) do
    round(humidity_rh * 65_535 / 100)
  end

  @doc """
  Convert a {temperature_c, humidity_rh} tuple to SGP40 ticks map
  """
  def from_bme({temp_c, humidity_rh}) do
    %{
      temperature_ticks: temperature_to_ticks(temp_c),
      humidity_ticks: humidity_to_ticks(humidity_rh)
    }
  end

  @doc """
  Convert raw ticks to {msb, lsb} tuple for the SGP40 CRC frame.
  """
  def to_tuple(ticks) when is_integer(ticks) do
    msb = ticks >>> 8 &&& 0xFF
    lsb = ticks &&& 0xFF
    {msb, lsb}
  end

  @doc """
  Convenience function: convert human-readable values directly to tuples
  for SGP40 measurement frame.
  """
  def human_to_tuple(temp_c, humidity_rh) do
    temp_tuple = temp_c |> temperature_to_ticks() |> to_tuple()
    hum_tuple = humidity_rh |> humidity_to_ticks() |> to_tuple()
    {temp_tuple, hum_tuple}
  end

It goes from human > ticks > tuple.

This can now be set to the crc in order to get the most accurate values.

The thing that Im having issues with right now is that I'm getting far higher values for the PPM. Will work on that next session.