defmodule ExWindspeed do @moduledoc """ Functions for reading data from a windspeed sensor connected through an MCP3008 analog to digital chip. ## Hardware ExWindspeed was built to support a windspeed sensor purchased from Adafruit, [Anemometer Wind Speed Sensor w/Analog Voltage Output](https://www.adafruit.com/product/1733). To communicate with the device from a RaspberryPi the signal is required to be digital as there are no analog inputs on the RaspberryPi. Using a [MCP3008](https://www.adafruit.com/product/856) analog to digital chip allows communication with up to 8 channels of 10-bit analog input. Follow the wiring section ### Specifics - Output: 0.4V to 2V - Testing Range: 0.5m/s to 50m/s - Start wind speed: 0.2 m/s - Resolution: 0.1m/s - Accuracy: Worst case 1 m/s - Max Wind Speed: 70m/s ### Connector details: - Pin 1 - Power (brown wire) - Pin 2 - Ground (black wire) - Pin 3 - Signal (blue wire) - Pin 4 - Not connected The Signal wire should be connected to one of the `channels` described below. ### Wiring #### MCP3008 ADC (Analog to Digital Converter) ``` Channels Connections to PI ____ 0 -| |- 3.3V 1 -| |- 3.3V 2 -| |- Ground 3 -| |- Pin 18 4 -| |- Pin 23 5 -| |- Pin 24 6 -| |- Pin 25 7 -|____|- Ground ``` ## Configuration ExWindspeed supports local development by having the sensor implementation configurable. By default the Raspberry PI implementation is used and expects hardware to be connected. ### SPI Device The device to communicate with via SPI can be configured with the `device` key. If the `device` key is not configured the default SPI device will be `spidev0.0`. ### SPI Transmission Data Data is transmitted to the SPI device and tells the chip which channel to read from. The default bitstring will read from channel 0, if you are using another channel you can set the bitstring to use with the `spi_transfer_payload` key. ### Local Development If you wish to use ExWindspeed during local development the `ExWindspeed.Platform.Host.SensorImpl` should be used. ```elixir config :ex_windspeed, implementation: ExWindspeed.Platform.Host.SensorImpl ``` With the configuration shown above, all calls to `ExWindspeed.read/0` shall return the same windspeed with the current UTC DateTime for `read_at`. ### Example Configuration The defaults are used for this example. ```elixir config :ex_windspeed, implementation: ExWindspeed.Platform.RPI.SensorImpl, device: "spidev0.0", spi_transfer_payload: <<0x01, 0x80, 0x00>> ``` """ defstruct [:miles_per_hour, :meters_per_second, :read_at] @typedoc """ Windspeed in miles per hour. """ @type miles_per_hour :: float() @typedoc """ Windspeed in meters per second. """ @type meters_per_second :: float() @typedoc """ Date and time in UTC (using local device time) that the data was read from the sensor. If your nerves project doesn't use a means to sync local time this value will be useless. """ @type read_at :: DateTime.t() @typedoc """ Struct containing wind speed from the sensor. """ @type t :: %__MODULE__{ miles_per_hour: miles_per_hour, meters_per_second: meters_per_second, read_at: read_at } @spec read() :: {:ok, ExWindspeed.t()} | {:error, ExWindspeed.Error.t()} @doc """ Read current wind speed from sensor """ defdelegate read(), to: ExWindspeed.Sensor end