This sample shows how to connect a rotary potentiometer and LED to a Raspberry Pi 2 or 3 or a DragonBoard 410c. We use a SPI-based ADC (Analog to Digital Converter) to read values from the potentiometer
and control an LED based on the knob position.
Raspberry Pi 2 or 3 or DragonBoard 410c single board computer
1 breadboard and a couple of wires
HDMI Monitor and HDMI cable
In this sample, you have the option of using either the MCP3002, MCP3008, or MCP3208 ADC (Analog to Digital Converter).
The differences between the chips are the number of input channels and resolution. 12-bit resolution is more accurate than the 10-bit options, and the number of channels determines how many different inputs you can read. Any of these options will work fine for this sample.
Below are the pinouts of the MCP3002 and MCP3208 ADCs.
MCP3008 or MCP3208
Raspbery Pi 2 and 3 Pinout
Wiring & Connections
If you chose to use the MCP3002, assemble the circuit as follows. Note that the wiper pin (the middle pin on the 10k potentiometer) should be connected to CH0 on MCP3002. You can also refer to the datasheet for more information.
The MCP3002 should be connected as follows:
MCP3002: VDD/VREF - 3.3V on Raspberry Pi 2 or 3
MCP3002: CLK - “SPI0 SCLK” on Raspberry Pi 2 or 3
MCP3002: Dout - “SPI0 MISO” on Raspberry Pi 2 or 3
MCP3002: Din - “SPI0 MOSI” on Raspberry Pi 2 or 3
MCP3002: CS/SHDN - “SPI0 CS0” on Raspberry Pi 2 or 3
MCP3002: Vss - GND on Raspberry Pi 2 or 3
MCP3002: CH0 - Potentiometer wiper pin
MCP3208 or MCP3008
If you chose to use the MCP3208 or MCP3008, assemble the circuit as follows. Note that the wiper pin (the middle pin on the 10k potentiometer) should be connected to CH0 on MCP3208. You can also refer to the MCP3208 datasheet or the MCP3008 datasheet for more information.
The MCP3208 should be connected as follows:
MCP3208: VDD - 3.3V on Raspberry Pi 2 or 3
MCP3208: VREF - 3.3V on Raspberry Pi 2 or 3
MCP3208: AGND - GND on Raspberry Pi 2 or 3
MCP3208: CLK - “SPI0 SCLK” on Raspberry Pi 2 or 3
MCP3208: Dout - “SPI0 MISO” on Raspberry Pi 2 or 3
MCP3208: Din - “SPI0 MOSI” on Raspberry Pi 2 or 3
MCP3208: CS/SHDN - “SPI0 CS0” on Raspberry Pi 2 or 3
Open samples-develop\PotentiometerSensor\CS\PotentiometerSensor.csproj in Visual Studio.
Find the ADC_DEVICE variable in MainPage.xaml.cs and change it to either AdcDevice.MCP3002, AdcDevice.MCP3208 or AdcDevice.MCP3008 depending on the ADC you wired up above
Verify the GPIO pin number is correct for your board. (GPIO 5 for Raspberry Pi 2 or 3 and MinnowBoard Max. GPIO 12 for DragonBoard)
Select ARM for the target architecture if you are using a Raspberry Pi 2 or 3 or a DragonBoard. Select x86 for MinnowBoard Max.
Go to Build -> Build Solution
Select Remote Machine from the debug target
Hit F5 to deploy and debug. Enter the IP address of your device
and select Universal for the authentication type
When you turn the potentiometer knob, you will see the number change on the screen indicating the potentiometer knob position.
When the number is larger than half the ADC resolution (For MCP3002, this number is 512. For MCP3008 or MCP3208, it’s 2048) the LED will turn ON. Otherwise, it turns OFF.
Let’s look at the code
The code here performs two main tasks:
First the code initializes the SPI bus and LED GPIO pin.
Secondly, we read from the ADC at defined intervals and update the display accordingly.
Let’s start by digging into the initializations. The first thing we initialize is the GPIO LED pin in InitGPIO().
We start by retrieving the default GPIO controller on the device with the GpioController.GetDefault() function.
Since we connected the LED to GPIO 4, we open this pin on the GPIO controller.
Finally we write a default value to the pin before setting it as output.
Next, we initialize the SPI bus. This allows the RPi2 or RPi3 to communicate with the ADC to read in potentiometer positions.
We start by specifying some configuration settings for our SPI bus:
We specify which chip select line we want to use. We wired the ADC into chip select line 0, so that’s what we use here.
The clock frequency is conservatively set to 0.5MHz, which is well within the ADC capabilities.
settings.Mode is set to SpiMode.Mode0. This configures clock polarity and phase for the bus.
Next, we get the class selection string for our SPI controller. This controller controls the SPI lines on the exposed pin header. We then use the selection string to get the SPI bus controller matching our string name.
Finally, we create a new SpiDevice with the settings and bus controller obtained previously.
After the initializations are complete, we create a periodic timer to read data every 100mS.
This timer calls the Timer_Tick() function. Which starts by reading from the ADC:
We first setup the writeBuffer with some configuration data to send to the ADC
Next we call SpiADC.TransferFullDuplex() to write the configuration data and read back the ADC results
Inside the convertToInt() function, we convert the returned byte array into a integer
Finally, we update the UI with the ADC result
Next, we control the LED based on the ADC result
If the potentiometer is rotated more than halfway through its range, we turn on the LED. Otherwise it’s turned off.
That’s it! Now that you’ve learned how to use an ADC, you can hook up a variety of analog sensors to your Raspberry Pi 2 or 3.