mcp3208C语言程序,Potentiometer sensor

Potentiometer sensor

08/19/2019

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.

Parts needed

Parts Review

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.

MCP3002

MCP3008 or MCP3208

68a60745e2ebbd13aee5c4864310cab8.png

fcf88218910129f9845a801fdfad8264.png

Raspberry Pi

Raspbery Pi 2 and 3 Pinout

3ffa6a9c503a12fb00f8f67afb9b6906.png

Wiring & Connections

MCP3002

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.

Detailed connection:

24e238cedc9ba8ed1f9565adf63ec256.png

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.

Detailed connection:

01a936a6103fc21880ee06394d53d21f.png

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

MCP3208: DGND - GND on Raspberry Pi 2 or 3

MCP3208: CH0 - Potentiometer wiper pin

DragonBoard 410c

For the DragonBoard 410c, you will require a Voltage-Level Translator Breakout.

DragonBoard Pinout

e6bf1cabc762eb32e8c23adb93bd296c.png

Wiring & Connections

MCP3208

Connect the MCP3208 to the Voltage-Level Translator breakout as follows:

Connect Vdd to VccB on the Translator breakout(5 V)

Connect Vref to VccB on the Translator breakout(5 V)

Connect AGND to GND on the Translator breakout

Connect CLK to B1 on the Translator breakout

Connect DOUT to B3 on the Translator breakout

Connect DIN to B2 on the Translator breakout

Connect CS to B4 on the Translator breakout

Connect DGND to GND

Connect channel 0 to the potentiometer wiper pin (leg 2)

Connect leg 1 of the potentiometer to GND

Connect leg 3 of the potentiometer to VccB (5 V)

Connect leg 3 of the potentiometer to a 330 Ω resistor

Connect the 330 Ω resistor to the cathode of the LED

Connect the anode of the LED to pin 24 (GPIO 12) on the DragonBoard

Connect A1 on the Translator breakout to pin 8 (SPI0 SCLK)

Connect A3 on the Translator breakout to pin 10 (SPI0 MISO)

Connect A2 on the Translator breakout to pin 14 (SPI0 MOSI)

Connect A4 on the Translator breakout to pin 12 (SPI CS N)

Connect VccA on the Translator breakout to pin 35 (1.8 V) on the DragonBoard

Connect VccB on the Translator breakout to pin 37 (5 V) on the DragonBoard

Here is an illustration of what your breadboard might look like with the circuit assembled:

breadboard_db410c.png

Finally, the LED_PIN variable of the MainPage.xaml.cs file of the sample code will need the following modification:

private const int LED_PIN = 12;

{: .language-c#}

MCP3008

If you chose to use the MCP3008, you can switch the MCP3208 for the MCP3008 in the above diagram.

Building and running the sample

Download a zip of all of our samples here.

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.

| ----------------------------------------------------------------------------------------- |-| ---------------------------------------------------------------------------------- |

|

AppRunning-LEDOff.png | |

AppRunning-LEDOn.png |

|

Breadboard-LEDOff.png | |

Breadboard-LEDOn.png |

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().

private void InitGpio()

{

var gpio = GpioController.GetDefault();

/* Show an error if there is no GPIO controller */

if (gpio == null)

{

throw new Exception("There is no GPIO controller on this device");

}

ledPin = gpio.OpenPin(LED_PIN);

/* GPIO state is initially undefined, so we assign a default value before enabling as output */

ledPin.Write(GpioPinValue.High);

ledPin.SetDriveMode(GpioPinDriveMode.Output);

}

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.

private async Task InitSPI()

{

try

{

var settings = new SpiConnectionSettings(SPI_CHIP_SELECT_LINE);

settings.ClockFrequency = 500000; /* 0.5MHz clock rate */

settings.Mode = SpiMode.Mode0; /* The ADC expects idle-low clock polarity so we use Mode0 */

string spiAqs = SpiDevice.GetDeviceSelector(SPI_CONTROLLER_NAME);

var deviceInfo = await DeviceInformation.FindAllAsync(spiAqs);

SpiADC = await SpiDevice.FromIdAsync(deviceInfo[0].Id, settings);

}

/* If initialization fails, display the exception and stop running */

catch (Exception ex)

{

throw new Exception("SPI Initialization Failed", ex);

}

}

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.

private async void InitAll()

{

// ...

/* Now that everything is initialized, create a timer so we read data every 500mS */

periodicTimer = new Timer(this.Timer_Tick, null, 0, 100);

StatusText.Text = "Status: Running";

}

This timer calls the Timer_Tick() function. Which starts by reading from the ADC:

public void ReadADC()

{

byte[] readBuffer = new byte[3]; /* Buffer to hold read data*/

byte[] writeBuffer = new byte[3] { 0x00, 0x00, 0x00 };

/* Setup the appropriate ADC configuration byte */

switch (ADC_DEVICE)

{

case AdcDevice.MCP3002:

writeBuffer[0] = MCP3002_CONFIG;

break;

case AdcDevice.MCP3208:

writeBuffer[0] = MCP3208_CONFIG;

break;

}

SpiADC.TransferFullDuplex(writeBuffer, readBuffer); /* Read data from the ADC */

adcValue = convertToInt(readBuffer); /* Convert the returned bytes into an integer value */

/* UI updates must be invoked on the UI thread */

var task = this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>

{

textPlaceHolder.Text = adcValue.ToString(); /* Display the value on screen */

});

}

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

/* Turn on/off the LED depending on the potentiometer position */

private void LightLED()

{

int adcResolution = 0;

switch (ADC_DEVICE)

{

case AdcDevice.MCP3002:

adcResolution = 1024;

break;

case AdcDevice.MCP3208:

adcResolution = 4096;

break;

}

/* Turn on LED if pot is rotated more halfway through its range */

if (adcValue > adcResolution / 2)

{

ledPin.Write(GpioPinValue.Low);

}

/* Otherwise turn it off */

else

{

ledPin.Write(GpioPinValue.High);

}

}

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.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值