diff --git a/Documentation/README.md b/Documentation/README.md new file mode 100644 index 0000000000000000000000000000000000000000..40ba4b5b5a89ea6f8a0a0a4863b0542365a764b2 --- /dev/null +++ b/Documentation/README.md @@ -0,0 +1,14 @@ +# Resources + +See the following resources to get started. + +## .NET Core + +* [.NET Core documentation](https://docs.microsoft.com/dotnet/) +* [Install .NET Core on Raspberry Pi](https://github.com/dotnet/core/blob/master/samples/RaspberryPiInstructions.md) +* [.NET Core ARM64 Status](https://github.com/dotnet/announcements/issues/82) + +## Raspberry Pi + +* [Enable SPI on Raspberry Pi](https://www.raspberrypi-spy.co.uk/2014/08/enabling-the-spi-interface-on-the-raspberry-pi/) +* [Enable headless Raspberry Pi](https://hackernoon.com/raspberry-pi-headless-install-462ccabd75d0) \ No newline at end of file diff --git a/README.md b/README.md index 6a7dd25e7fc3b8fe350baf8464fcf265fc4c238e..bce646ab1c353fe5f928b387fa7a99a989e880b2 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,26 @@ -# iot -This repo includes implementations for various boards, chips and PCBs to enable .NET to be used for IoT scenarios. +# .NET Core IoT Libraries + +.NET Core can be used to build applications for [IoT](https://en.wikipedia.org/wiki/Internet_of_things) devices and scenarios. IoT applications typically interact with sensors, displays and input devices that require the use of [GPIO pins](https://en.wikipedia.org/wiki/General-purpose_input/output), serial ports or similar hardware. + +This repository contains the [System.Devices.Gpio](https://dotnet.myget.org/feed/dotnet-corefxlab/package/nuget/System.Devices.Gpio) library and implementations for various boards like [Raspberry Pi](https://www.raspberrypi.org/) and [Hummingboard](https://www.solid-run.com/nxp-family/hummingboard/). + +It also contains a growing set of community-maintained bindings for IoT components, like the [Mcp3008](https://www.adafruit.com/product/856) ([bindings](src/Mcp3008/Mcp3008.cs)), for example. + +Note: System.Device.Gpio is in early preview. It is not yet supported and will continue to change. + +## Install .NET Core + +* [Official releases](https://www.microsoft.com/net/download) +* [Daily builds](https://github.com/dotnet/core/blob/master/daily-builds.md) + +## Contributing + +Please contribute. We are primarily interested in the following: + +* Improving quality and capability of the drivers for supported boards. +* Implementations for additional boards +* .NET bindings for a wide variety of sensors, chips, displays and other components. + +## License + +.NET Core (including the iot repo) is licensed under the [MIT license](LICENSE). diff --git a/src/Mcp3008/Mcp3008.cs b/src/Mcp3008/Mcp3008.cs new file mode 100644 index 0000000000000000000000000000000000000000..461ba3f7b671bdacf69d3892afd1f1f6ee92d299 --- /dev/null +++ b/src/Mcp3008/Mcp3008.cs @@ -0,0 +1,115 @@ +using System; +using System.Devices.Gpio; +using System.Devices.Spi; + +public class Mcp3008 +{ + + private SpiDevice _spiDevice; + private GpioPin _CLK; + private GpioPin _MISO; + private GpioPin _MOSI; + private GpioPin _CS; + + + public Mcp3008(SpiDevice spiDevice) + { + _spiDevice = spiDevice; + } + + public Mcp3008(GpioController controller, int CLK, int MISO, int MOSI, int CS) + { + _CLK = controller.OpenPin(CLK, PinMode.Output); + _MISO = controller.OpenPin(MISO, PinMode.Input); + _MOSI = controller.OpenPin(MOSI, PinMode.Output); + _CS = controller.OpenPin(CS, PinMode.Output); + } + + public int Read(int adc_channel) + { + if (adc_channel < 0 && adc_channel > 7) + { + throw new ArgumentException("ADC channel must be within 0-7 range."); + } + + if (_spiDevice != null) + { + return ReadSpi(adc_channel); + } + else + { + return ReadGpio(adc_channel); + } + } + + private int ReadGpio(int adc_channel) + { + //port of https://gist.github.com/ladyada/3151375 + + while (true) + { + var commandout = 0; + var trim_pot = 0; + + + _CS.Write(PinValue.High); + _CLK.Write(PinValue.Low); + _CS.Write(PinValue.Low); + + commandout |= 0x18; + commandout <<= 3; + + for (var i = 0; i < 5; i++) + { + if ((commandout & 0x80) > 0) + { + _MOSI.Write(PinValue.High); + } + else + { + _MOSI.Write(PinValue.Low); + } + + commandout <<= 1; + _CLK.Write(PinValue.High); + _CLK.Write(PinValue.Low); + } + + for (var i = 0; i < 12; i++) + { + _CLK.Write(PinValue.High); + _CLK.Write(PinValue.Low); + trim_pot <<= 1; + + if (_MISO.Read() == PinValue.High) + { + trim_pot |= 0x1; + } + } + + _CS.Write(PinValue.High); + + trim_pot >>= 1; + //var pot_adjust = Math.Abs(trim_pot - last_read); + return trim_pot; + } + } + + private int ReadSpi(int adc_channel) + { + // ported code from: + // https://github.com/adafruit/Adafruit_Python_MCP3008/blob/master/Adafruit_MCP3008/MCP3008.py + + int command = 0b11 << 6; //Start bit, single channel read + command |= (adc_channel & 0x07) << 3; // Channel number (in 3 bits) + var input = new Byte[] { (Byte)command, 0, 0 }; + var output = new Byte[3]; + _spiDevice.TransferFullDuplex(input, output); + + var result = (output[0] & 0x01) << 9; + result |= (output[1] & 0xFF) << 1; + result |= (output[2] & 0x80) >> 7; + result = result & 0x3FF; + return result; + } +} \ No newline at end of file