diff --git a/samples/README.md b/samples/README.md index 2d3caee7fe503b85ffdba7862b605a964c11d4ce..a347110cb96574fbf047cca1b6020984da1a9067 100644 --- a/samples/README.md +++ b/samples/README.md @@ -12,13 +12,13 @@ The following samples demonstrate various scenarios: ## Libraries -These samples use the [System.Devices.Gpio](https://dotnet.myget.org/feed/dotnet-corefxlab/package/nuget/System.Devices.Gpio) library. It will be supported on Linux and Windows IoT Core. At present, the library works on Linux. The library is currently in early preview, based on [source in dotnet/corefxlab](https://github.com/dotnet/corefxlab/tree/master/src/System.Devices.Gpio). +These samples use the [System.Device.Gpio](https://dotnet.myget.org/feed/dotnet-corefxlab/package/nuget/System.Devices.Gpio) library. It will be supported on Linux and Windows IoT Core. At present, the library works on Linux. The library is currently in early preview, based on [source in dotnet/corefxlab](https://github.com/dotnet/corefxlab/tree/master/src/System.Devices.Gpio). There are many libraries that are important beyond GPIO, I2C and related fundamental protocols. We are working on a plan where the .NET Team and the community can work together to build up a shared repository of implementations. ## Breadboard layouts -The samples expect the device pins to be connected in particular way to function, typically on a breadboard. Each example includes a [Fritzing](http://fritzing.org/home/) diagram of the required breadboard layout, such as the following one (taken from the [More blinking lights](led-more-blinking-lights/README.md) sample). +The samples expect the device pins to be connected in particular way to function, typically on a breadboard. Each example includes a [Fritzing](http://fritzing.org/home/) diagram of the required breadboard layout, such as the following one (taken from the [More blinking lights](led-more-blinking-lights/README.md) sample). ![Rasperry Pi Breadboard diagram](led-more-blinking-lights/rpi-more-blinking-lights_bb.png) diff --git a/samples/led-more-blinking-lights/nuget.config b/samples/led-more-blinking-lights/nuget.config deleted file mode 100644 index e2f430168fca7db6d611416b08071582efec16bc..0000000000000000000000000000000000000000 --- a/samples/led-more-blinking-lights/nuget.config +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/samples/led-blink/nuget.config b/samples/nuget.config similarity index 100% rename from samples/led-blink/nuget.config rename to samples/nuget.config diff --git a/samples/trimpot/Mcp3008.cs b/samples/trimpot/Mcp3008.cs deleted file mode 100644 index f4e0a8ab1af797e12d54cd50044c1d5a13da3123..0000000000000000000000000000000000000000 --- a/samples/trimpot/Mcp3008.cs +++ /dev/null @@ -1,114 +0,0 @@ -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 diff --git a/samples/trimpot/Program.cs b/samples/trimpot/Program.cs index 513fd891c6b5677aab8bf2e63b081fef220c0954..9ee010c922c84aa3abbb191fa25b34003883788f 100644 --- a/samples/trimpot/Program.cs +++ b/samples/trimpot/Program.cs @@ -2,6 +2,7 @@ using System.Devices.Gpio; using System.Devices.Spi; using System.Threading; +using Iot.Device; namespace trimpot { diff --git a/samples/trimpot/nuget.config b/samples/trimpot/nuget.config deleted file mode 100644 index 5a5e169638205c956503a4b1fc068d91cbf35e17..0000000000000000000000000000000000000000 --- a/samples/trimpot/nuget.config +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/samples/trimpot/trimpot.csproj b/samples/trimpot/trimpot.csproj index 349cea9623b75e6047178ed26934a1fee549e7ca..56966880af906456b18200ce2a286f2c39a0c898 100644 --- a/samples/trimpot/trimpot.csproj +++ b/samples/trimpot/trimpot.csproj @@ -3,11 +3,14 @@ Exe netcoreapp2.1 - led_pwm - + + + + + diff --git a/src/Mcp3008/Mcp3008.cs b/src/Mcp3008/Mcp3008.cs deleted file mode 100644 index 461ba3f7b671bdacf69d3892afd1f1f6ee92d299..0000000000000000000000000000000000000000 --- a/src/Mcp3008/Mcp3008.cs +++ /dev/null @@ -1,115 +0,0 @@ -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 diff --git a/src/devices/Mcp3008/Mcp3008.cs b/src/devices/Mcp3008/Mcp3008.cs new file mode 100644 index 0000000000000000000000000000000000000000..c05db688d2cc322ede1e3bee16b983d31225010f --- /dev/null +++ b/src/devices/Mcp3008/Mcp3008.cs @@ -0,0 +1,114 @@ +using System; +using System.Devices.Gpio; +using System.Devices.Spi; + +namespace Iot.Device +{ +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); + } + } + + // port of https://gist.github.com/ladyada/3151375 + private int ReadGpio(int adc_channel) + { + 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; + return trim_pot; + } + } + + // ported code from: + // https://github.com/adafruit/Adafruit_Python_MCP3008/blob/master/Adafruit_MCP3008/MCP3008.py + private int ReadSpi(int adc_channel) + { + 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; + } + } +} diff --git a/src/devices/Mcp3008/Mcp3008.csproj b/src/devices/Mcp3008/Mcp3008.csproj new file mode 100644 index 0000000000000000000000000000000000000000..e8f08ed5366129be5ffc10c4cb4d70d0cb6caef1 --- /dev/null +++ b/src/devices/Mcp3008/Mcp3008.csproj @@ -0,0 +1,11 @@ + + + + netcoreapp2.1 + + + + + + + diff --git a/src/devices/Mcp3008/README.md b/src/devices/Mcp3008/README.md new file mode 100644 index 0000000000000000000000000000000000000000..7454f54c7860728a4f11d516194b07af004121e7 --- /dev/null +++ b/src/devices/Mcp3008/README.md @@ -0,0 +1,9 @@ +# Using MCP3008 + +Some devices like the Rasperry Pi cannot read analog values directly so rely on [analog to digital converters](https://en.wikipedia.org/wiki/Analog-to-digital_converter), like the [MCP3008 ADC](https://www.adafruit.com/product/856). The MCP3008 supports the SPI interface. The 10-bit chip can be accessed as an [SPI device](https://en.wikipedia.org/wiki/Serial_Peripheral_Interface) or manually via raw GPIO pins. + + You can use [Mcp3008.cs](Mcp3008.cs) in your project to access analog devices. [Reading Analog Input from a Potentiometer](../../samples/trimpot/README.md) demonstrates a concrete example using this class. + +The following fritzing diagram illustrates one way to wire up the Mcp3008, with a Raspberry Pi and a potentiometer. + +![Raspberry Pi Breadboard diagram](../../samples/trimpot/rpi-trimpot_spi.png) \ No newline at end of file