This directory is intended for device bindings, sensors, displays, human interface devices and anything else that requires software to control. We want to establish a rich set of quality .NET bindings to make it straightforward to use .NET to connect devices together to produce weird and wonderful IoT applications.
Our vision: the majority of .NET bindings are written completely in .NET languages to enable portability, use of a single tool chain and complete debugability from application to binding to driver.
Alphabetical device index can be found here
- Adafruit Seesaw - extension board (ADC, PWM, GPIO expander)
- ADS1115 - Analog to Digital Converter
- INA219 - Bidirectional Current/Power Monitor
- Mcp3428 - Analog to Digital Converter (I2C)
- MCP3xxx family of Analog to Digital Converters
- TLC1543 - 10-bit ADC with 11 input channels
- ADXL345 - Accelerometer
- ADXL357 - Accelerometer
- BNO055 - inertial measurement unit
- LSM9DS1 - 3D accelerometer, gyroscope and magnetometer
- MPU6500/MPU9250 - Gyroscope, Accelerometer, Temperature and Magnetometer (MPU9250 only)
- Sense HAT
- Bh1745 - RGB Sensor
- BH1750FVI - Ambient Light Sensor
- MAX44009 - Ambient Light Sensor
- SensorHub - Environmental sensor
- TCS3472x Sensors
- TSL256x - Illuminance sensor
- BMP180 - barometer, altitude and temperature sensor
- BMxx80 Device Family
- LPS25H - Piezoresistive pressure and thermometer sensor
- Sense HAT
- SensorHub - Environmental sensor
- AHT10/15/20 - Temperature and humidity sensor modules
- BMP180 - barometer, altitude and temperature sensor
- BMxx80 Device Family
- Cpu Temperature
- DHTxx - Digital-Output Relative Humidity & Temperature Sensor Module
- HTS221 - Capacitive digital sensor for relative humidity and temperature
- LM75 - Digital Temperature Sensor
- LPS25H - Piezoresistive pressure and thermometer sensor
- Max31856 - cold-junction compensated thermocouple to digital converter
- MAX31865 - Resistance Temperature Detector Amplifier
- MCP9808 - Digital Temperature Sensor
- MLX90614 - Infra Red Thermometer
- MPU6500/MPU9250 - Gyroscope, Accelerometer, Temperature and Magnetometer (MPU9250 only)
- OpenHardwareMonitor client library
- Sense HAT
- SensorHub - Environmental sensor
- SHT3x - Temperature & Humidity Sensor
- SHTC3 - Temperature & Humidity Sensor
- Si7021 - Temperature & Humidity Sensor
- μFire ISE Probe - pH, ORP and temperature sensor
- BNO055 - inertial measurement unit
- LSM9DS1 - 3D accelerometer, gyroscope and magnetometer
- MPU6500/MPU9250 - Gyroscope, Accelerometer, Temperature and Magnetometer (MPU9250 only)
- Sense HAT
- 28BYJ-48 Stepper Motor 5V 4-Phase 5-Wire & ULN2003 Driver Board
- DC Motor Controller
- Explorer HAT Pro (Pimoroni)
- MotorHat
- Servo Motor
- BNO055 - inertial measurement unit
- LSM9DS1 - 3D accelerometer, gyroscope and magnetometer
- MPU6500/MPU9250 - Gyroscope, Accelerometer, Temperature and Magnetometer (MPU9250 only)
- Sense HAT
- AK8963 - Magnetometer
- BNO055 - inertial measurement unit
- HMC5883L - 3 Axis Digital Compass
- LSM9DS1 - 3D accelerometer, gyroscope and magnetometer
- MPU6500/MPU9250 - Gyroscope, Accelerometer, Temperature and Magnetometer (MPU9250 only)
- Sense HAT
- AHT10/15/20 - Temperature and humidity sensor modules
- BMxx80 Device Family
- DHTxx - Digital-Output Relative Humidity & Temperature Sensor Module
- HTS221 - Capacitive digital sensor for relative humidity and temperature
- Sense HAT
- SensorHub - Environmental sensor
- SHT3x - Temperature & Humidity Sensor
- SHTC3 - Temperature & Humidity Sensor
- Si7021 - Temperature & Humidity Sensor
- HC-SR04 - Ultrasonic Ranging Module
- LidarLiteV3 - LIDAR Time of Flight Sensor
- VL53L0X - distance sensor
- Adafruit Seesaw - extension board (ADC, PWM, GPIO expander)
- APA102 - Double line transmission integrated control LED
- Character LCD (Liquid Crystal Display)
- Max7219 (LED Matrix driver)
- PCD8544 - 48 × 84 pixels matrix LCD, famous Nokia 5110 screen
- RGBLedMatrix - RGB LED Matrix
- Segment display driver (HT16K33)
- Sense HAT
- Solomon Systech Ssd1306 OLED display
- Solomon Systech Ssd1351 - CMOS OLED
- TM1637 - Segment Display
- Ws28xx LED drivers
- Adafruit Seesaw - extension board (ADC, PWM, GPIO expander)
- Mcp23xxx - I/O Expander device family
- NXP/TI PCx857x
- Pca95x4 - I2C GPIO Expander
- Adafruit Seesaw - extension board (ADC, PWM, GPIO expander)
- MPR121 - Proximity Capacitive Touch Sensor Controller
- Adafruit Seesaw - extension board (ADC, PWM, GPIO expander)
- APA102 - Double line transmission integrated control LED
- Explorer HAT Pro (Pimoroni)
- On-board LED driver
- Segment display driver (HT16K33)
- Ws28xx LED drivers
- SPI, GPIO and I2C drivers for Arduino with Firmata
- SPI, GPIO and I2C drivers for FT4222
- STUSB4500 - Autonomous USB-C PD controller for Power Sinks / UFP
- Charlieplex Segment binding
- Digital liquid level switch
- Generic shift register
- GpioDriver for other boards
- Key Matrix
- MBI5027 -- 16-bit shift register with error detection
- Quadrature Rotary Encoder
- SN74HC595 -- 8-bit shift register
- 1-wire
- Adafruit Seesaw - extension board (ADC, PWM, GPIO expander)
- Board abstraction
- GpioDriver for other boards
- MotorHat
- Pca9685 - I2C PWM Driver
- Software PWM
- Software SPI
- SPI, GPIO and I2C drivers for Arduino with Firmata
- SPI, GPIO and I2C drivers for FT4222
- System.Device.Model - attributes for device bindings
These bindings are distributed via the Iot.Device.Bindings NuGet package. Daily builds with the latest bindings are available on MyGet. You can also consume the bindings as source.
Anyone can contribute a binding. Please do! Bindings should follow the model that is used for the Mcp23xxx or Mcp3xxx implementations. There is a Device Binding Template that can help you get started, as well.
Bindings must:
- include a .NET Core project file for the main library.
- include a descriptive README, with a fritzing diagram.
- Best if you include the coverage of the binding. If you did not implement all features, mention what has been implemented and what is not. It is ok not to implement every features but it's important to know what is missing
- Refer to multiple manufacturer and add links where the binding can be found. Sometimes, they have different names depending on where you can find them while it's the same chipset used or compatible ones
- include a buildable sample (layout will be described below).
- Best if you include a sample that covers usage of all available functions and properties
- Best if you create mutliple paths to show what the sensor can do
- use the System.Device API.
- (Optional) Include a unit test project that DOES NOT require hardware for testing. We will be running these tests as part of our CI and we won't have sensors plugged in to the microcontrollers, which is why test projects should only contain unit tests for small components in your binding.
Here is an example of a layout of a new Binding Foo from the top level of the repo:
iot/
src/
devices/
Foo/
Foo.csproj
Foo.cs
README.md
samples/
Foo.Sample.csproj
Foo.Sample.cs
tests/ <-- Tests are optional, but if present they should be layed out like this.
Foo.Tests.csproj
Foo.Tests.cs
When creating a new binding, please follow the recommendations from the C# Coding Syle and more generally the .NET Coding Guidelinhes. On top, we recommend to use very descriptive namings, self explanatory names. Please make sure you don't use abbreviation. Describe any unit a sensor may use as well as the usual range of values. Check as well the devices convention. You will find below couple of examples of do and don't.
Do | Don't |
---|---|
Always use UnitsNet when possible: | Don't implement your own: |
public void SetEnvironmentData(Temperature temperature, Ratio humidity) |
public void SetEnvironmentData(float temperature, float humidity) |
Temperature is a classic one, you have lots of available units available, check here if anything exists before starting | In this case, there are existing units, use the existing one |
Do | Don't |
---|---|
Decribe your unit if it does not exist in UnitsNet | Leave an unkonwn measurement element |
public bool TryGetMyUnit(out double myUnitInUnitDescription) |
public bool TryGetMyUnit(out double myUnit) |
In this case, you need to speciy in the variable name the unit used. Be as precise as possible | Never leave any unit without description in the naming if it's not an support UnitsNet unit. |
Do | Don't |
---|---|
Always add range of the units in the XML description | Never leave a unit without a full range description |
/// <param name="equivalentCO2">The equivalent CO2 (eCO2) output range for CCS811 is from 400ppm up to 29206ppm.</param> |
/// <param name="equivalentCO2">The equivalent CO2 (eCO2)</param> |
Even when using the UnitsNet, make sure you give the usual range of a sensor value. | This makes it difficult to understand which range the sensor is using. |
Do |
---|
When reading a sensor can fail prefix a method name with Try for example: |
public bool TryGetTemperature(out Temperature temperature) |
This makes it easy to understand that if you read and the returned value is false the reading is not correct. And this means as well this function should not raise an exception when trying to read the sensor data if the data is not valid for example. You still can get exceptions like IO Errors or user errors. For example if the function takes parameters with a specific range, and the user is out of this range, then an Argument Exception can be raised. |
Do |
---|
Use action verbs for any function that makes an action. |
public void SetEnvironmentData(Temperature temperature, Ratio humidity) |
In this example, the function Set the environement values of temperature and humidity. It makes it very easy to understand, on top of the XML comment what the function is doing. |
Do |
---|
Use properties for a single element Set and/or Get function |
public OperationMode OperationMode |
This function then can be implemented with a get and set: |
public OperationMode OperationMode
{
get
{
var mode = ReadRegister(Register.MEAS_MODE);
mode = (byte)((mode >> 4) & 0b0000_0111);
return (OperationMode)mode;
}
set
{
var mode = ReadRegister(Register.MEAS_MODE);
// Clear previous mode
mode = (byte)(mode & 0b1000_1111);
mode = (byte)(mode | (((byte)(value)) << 4));
WriteRegister(Register.MEAS_MODE, mode);
}
}
Do | Don't |
---|---|
Use full name like EquivalentTotalVolatileOrganicCompound |
Don't use the abbreviation eTVOC |
This makes it easy for non specialist to use a binding. | If you are not a specialist or depending of the context, the abbreviation is complicated to understand. |
You can use abbreviation for the very common ones like Html, Xml, Jpeg or any other very well known. But those abreviation has to be very common one and used like this everywhere |
Do |
---|
Use the <remarks> from the XML comments to add any important element regarding a function. |
/// <remarks>A previously stored value may be written back to this two byte
/// register and the Algorithms will use the new value in its
/// calculations(until it adjusts it as part of its internal Automatic
/// Baseline Correction). Please refer to documentation to understand when to restore a
/// previous baseline: https://www.sciosense.com/wp-content/uploads/2020/01/Application-Note-Baseline-Save-and-Restore-on-CCS811.pdf</remarks>
Do |
---|
Always reference specific elements with a pointer documentation/reference to a specific part of the documentation. This does including specific timing wait, initialization phase and anything that would trigger a question like why this wait? or Why this function has to be called 2 times in a row . If the documentation is the same for all the sensor implementation, refer the documentation once at the beginning and then mention the page. |
For example: |
_controller.Write(_pinWake, PinValue.Low);
// Doc says wait 50 micro seconds, page 58 https://urltothedoc
DelayHelper.DelayMicroseconds(50, true);
Do |
---|
In a constructor if you are using a GpioController make sure you are using as well a boolean _shouldDispose . Some platforms or some specific dongles like FT4222 does allow the creation of one controller so if used with multiple bindings, it can't be disposed just like that. In the Dispose function, make sure you close the possible open pins if _shouldDispose is false. |
Example of an correct implementation: |
private GpioController _controller;
private bool _shouldDispose;
private int _pinToUse;
public MyBinding(int pinToUse, GpioController controller = null, PinNumberingScheme pinNumberingScheme = PinNumberingScheme.Logical, bool shouldDispose = true)
{
_shouldDispose = gpioController is null || shouldDispose;
_controller = gpioController ?? new GpioController(pinNumberingScheme);
_pinToUse = pinToUse;
_controller.OpenPin(_pinToUse);
// Initialize the rest of initialization
}
public Dispose()
{
if (_shouldDispose)
{
_controller?.Dispose();
}
else
{
_controller?.ClosePin(_thePinToUse);
}
}
We are currently not accepting samples that rely on native libraries for hardware interaction. This is for two reasons: we want feedback on the System.Device API and we want to encourage the use of 100% portable .NET solutions. If a native library is used to enable precise timing, please file an issue so that we can discuss your proposed contribution further.
We will only accept samples that use the MIT or compatible licenses (BSD, Apache 2, ...). We will not accept samples that use GPL code or were based on an existing GPL implementation. It is critical that these samples can be used for commercial applications without any concern for licensing.