.. note::
Hello, welcome to the SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts Community on Facebook! Dive deeper into Raspberry Pi, Arduino, and ESP32 with fellow enthusiasts.
**Why Join?**
- **Expert Support**: Solve post-sale issues and technical challenges with help from our community and team.
- **Learn & Share**: Exchange tips and tutorials to enhance your skills.
- **Exclusive Previews**: Get early access to new product announcements and sneak peeks.
- **Special Discounts**: Enjoy exclusive discounts on our newest products.
- **Festive Promotions and Giveaways**: Take part in giveaways and holiday promotions.
π Ready to explore and create with us? Click [|link_sf_facebook|] and join today!
.. _2.1.4_py_pi5_mcp3008:
2.1.4 Potentiometer(MCP3008)
=============================
.. note::
.. image:: ../img/mcp3008_and_adc0834.jpg
:width: 25%
:align: left
Depending on your kit version, please identify whether you have **ADC0834** or **MCP3008** and proceed with the matching section.
Introduction
------------
The ADC function is used to convert analog signals into digital values.
In this experiment, we use the MCP3008 ADC chip to perform this conversion.
A potentiometer is used to generate a variable voltage, which changes the physical quantity.
The MCP3008 then converts this analog voltage into a digital value that can be read and processed by the Raspberry Pi.
Required Components
------------------------------
In this project, we need the following components.
.. image:: ../python_pi5/img/list2_2.1.4_potentiometer.png
Schematic Diagram
-----------------
.. list-table::
:widths: 30 30 30 30
:header-rows: 1
* - T-Board Name
- physical
- WiringPi
- BCM
* - SPICE0
- pin24
- 10
- 8
* - SPIMOSI
- pin19
- 12
- 10
* - SPIMISO
- pin21
- 13
- 9
* - SPISCLK
- pin23
- 14
- 11
* - GPIO22
- pin15
- 3
- 22
.. image:: ../python_pi5/img/schematic_2.1.7_potentiometer_mcp3008.png
Experimental Procedures
-----------------------
**Step 1:** Build the circuit.
.. image:: ../python_pi5/img/july24_2.1.7_potentiometer_mcp3008.png
.. note::
Please place the chip by referring to the corresponding position
depicted in the picture. Note that the grooves on the chip should be on
the left when it is placed.
**Step 2:** Set up the SPI interface and install the ``spidev`` library (see :ref:`spi_configuration` for detailed instructions). If you have already completed these steps, you can skip this.
**Step 3:** Open the code file
.. raw:: html
.. code-block::
cd ~/davinci-kit-for-raspberry-pi/python-pi5
**Step 4:** Run.
.. raw:: html
.. code-block::
sudo python3 2.1.4-2_Potentiometer_zero.py
After the code runs, rotate the knob on the potentiometer, the intensity
of LED will change accordingly.
.. warning::
If there is an error prompt ``RuntimeError: Cannot determine SOC peripheral base address``, please refer to :ref:`faq_soc`
**Code**
.. note::
You can **Modify/Reset/Copy/Run/Stop** the code below. But before that, you need to go to source code path like ``davinci-kit-for-raspberry-pi/python-pi5``. After modifying the code, you can run it directly to see the effect.
.. raw:: html
.. code-block:: python
#!/usr/bin/env python3
import spidev
import time
from gpiozero import PWMLED
# Initialize PWM LED on GPIO22
led = PWMLED(22)
# Initialize SPI
spi = spidev.SpiDev()
spi.open(0, 0) # Bus 0, CS0 (CE0)
spi.max_speed_hz = 1000000
def read_adc(channel):
"""
Read analog value from MCP3008
:param channel: ADC channel (0-7)
:return: 10-bit integer (0-1023)
"""
if channel < 0 or channel > 7:
return -1
# MCP3008 protocol
adc = spi.xfer2([1, (8 + channel) << 4, 0])
value = ((adc[1] & 3) << 8) | adc[2]
return value
def MAP(x, in_min, in_max, out_min, out_max):
"""
Map a value from one range to another
"""
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
try:
while True:
# Read from MCP3008 channel 0
res = read_adc(0)
print('res = %d' % res)
# Map 0β1023 to 0β100%
R_val = MAP(res, 0, 1023, 0, 100)
# Set LED brightness
led.value = R_val / 100.0
time.sleep(0.2)
except KeyboardInterrupt:
led.value = 0 # Turn off the LED
**Code Explanation**
#. ``gpiozero`` for PWM LED control, ``spidev`` for SPI communication with MCP3008, and ``time`` for implementing delays.
.. code-block:: python
#!/usr/bin/env python3
import spidev
import time
from gpiozero import PWMLED
#. Initialize a PWMLED object connected to GPIO pin 22 and configure SPI communication (Bus 0, CE0) with MCP3008.
.. code-block:: python
# Initialize PWM LED on GPIO22
led = PWMLED(22)
# Initialize SPI
spi = spidev.SpiDev()
spi.open(0, 0) # Bus 0, CS0 (CE0)
spi.max_speed_hz = 1000000
#. Define a function named ``read_adc`` to communicate with MCP3008 and read analog values from the specified channel (0β7).
.. code-block:: python
def read_adc(channel):
"""
Read analog value from MCP3008
:param channel: ADC channel (0-7)
:return: 10-bit integer (0-1023)
"""
if channel < 0 or channel > 7:
return -1
adc = spi.xfer2([1, (8 + channel) << 4, 0])
value = ((adc[1] & 3) << 8) | adc[2]
return value
#. Define a function named ``MAP`` to convert one range of values to another, useful for mapping ADC values to appropriate LED brightness levels.
.. code-block:: python
def MAP(x, in_min, in_max, out_min, out_max):
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
#. Continuously read the ADC value in a loop, mapping the 10-bit ADC value (0β1023) to a brightness level (0β100) for the LED. Adjust the LEDβs brightness accordingly. Wait 0.2 seconds between each read.
.. code-block:: python
try:
while True:
# Read from MCP3008 channel 0
res = read_adc(0)
print('res = %d' % res)
# Map 0β1023 to 0β100%
R_val = MAP(res, 0, 1023, 0, 100)
# Set LED brightness
led.value = R_val / 100.0
time.sleep(0.2)
except KeyboardInterrupt:
led.value = 0 # Turn off the LED