Bird
Raised Fist0
Raspberry Piprogramming~20 mins

MCP3008 ADC over SPI in Raspberry Pi - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
MCP3008 SPI Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Reading MCP3008 Channel Output
What is the output of this Python code snippet that reads from channel 0 of the MCP3008 ADC using SPI on a Raspberry Pi?
Raspberry Pi
import spidev
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1350000

# Function to read channel 0
adc = spi.xfer2([1, (8 + 0) << 4, 0])
data = ((adc[1] & 3) << 8) + adc[2]
print(data)
AA runtime error due to incorrect SPI command format
BA list of three integers representing raw SPI bytes
CA string showing the SPI device name
DAn integer between 0 and 1023 representing the analog value on channel 0
Attempts:
2 left
💡 Hint
The MCP3008 returns a 10-bit value from 0 to 1023 for each channel read.
🧠 Conceptual
intermediate
1:30remaining
Understanding MCP3008 SPI Command Structure
Which part of the SPI command byte sequence selects the MCP3008 channel to read?
AThe second byte's bits 4 to 6 (shifted by 4) specify the channel number
BThe channel is selected by the SPI clock speed
CThe third byte contains the channel number
DThe first byte always selects the channel
Attempts:
2 left
💡 Hint
Look at how the channel number is shifted and combined in the command bytes.
🔧 Debug
advanced
2:30remaining
Fixing Incorrect MCP3008 SPI Read Output
This code attempts to read channel 3 from MCP3008 but always returns 0. What is the cause?
Raspberry Pi
import spidev
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1350000

adc = spi.xfer2([1, (3 << 4), 0])
data = ((adc[1] & 3) << 8) + adc[2]
print(data)
AThe channel number is not offset by 8 in the command byte, causing wrong channel selection
BThe SPI device is not opened correctly
CThe max_speed_hz is too high causing communication errors
DThe bitwise AND operation on adc[1] is incorrect
Attempts:
2 left
💡 Hint
Check how the channel number is combined with the start bit in the command byte.
📝 Syntax
advanced
1:30remaining
Identify Syntax Error in MCP3008 SPI Read Code
Which option contains a syntax error that prevents the MCP3008 SPI read code from running?
A
adc = spi.xfer2([1, (8 + 2) &lt;&lt; 4, 0])
data = ((adc[1] &amp; 3) &lt;&lt; 8) + adc[2]
print(data)
B
adc = spi.xfer2([1, (8 + 2) &lt;&lt; 4 0])
data = ((adc[1] &amp; 3) &lt;&lt; 8) + adc[2]
print(data)
C
)atad(tnirp
]2[cda + )8 &lt;&lt; )3 &amp; ]1[cda(( = atad
)]0 ,4 &lt;&lt; )2 + 8( ,1[(2refx.ips = cda
D
dc = spi.xfer2([1, (8 + 2) &lt;&lt; 4, 0])
data = ((adc[1] &amp; 3) &lt;&lt; 8) + adc[2]
print(data)
Attempts:
2 left
💡 Hint
Look carefully at the commas separating list elements.
🚀 Application
expert
2:00remaining
Calculate Voltage from MCP3008 ADC Reading
Given a 3.3V reference and a 10-bit MCP3008 ADC reading stored in variable data, which formula correctly converts data to voltage?
Avoltage = (data / 1023) * 5.0
Bvoltage = (data / 1024) * 3.3
Cvoltage = (data / 1023) * 3.3
Dvoltage = (data / 1024) * 5.0
Attempts:
2 left
💡 Hint
The MCP3008 outputs values from 0 to 1023 for 10 bits, and the reference voltage is 3.3V.

Practice

(1/5)
1. What is the main purpose of using the MCP3008 chip with a Raspberry Pi?
easy
A. To read analog signals by converting them to digital values
B. To provide additional digital output pins
C. To increase the Raspberry Pi's processing speed
D. To connect multiple Raspberry Pis together

Solution

  1. Step 1: Understand MCP3008 function

    The MCP3008 is an analog-to-digital converter (ADC) chip that converts analog signals into digital values readable by the Raspberry Pi.
  2. Step 2: Identify Raspberry Pi limitation

    The Raspberry Pi does not have built-in analog input pins, so MCP3008 is used to read analog sensors.
  3. Final Answer:

    To read analog signals by converting them to digital values -> Option A
  4. Quick Check:

    MCP3008 = Analog to Digital Converter [OK]
Hint: MCP3008 converts analog sensor signals to digital for Pi [OK]
Common Mistakes:
  • Thinking MCP3008 adds digital outputs
  • Confusing it with a processor speed booster
  • Assuming it connects multiple Pis
2. Which Python library is commonly used to communicate with the MCP3008 over SPI on Raspberry Pi?
easy
A. RPi.GPIO
B. smbus
C. serial
D. spidev

Solution

  1. Step 1: Identify SPI communication library

    The spidev library is designed for SPI communication on Raspberry Pi.
  2. Step 2: Match library to MCP3008 usage

    MCP3008 uses SPI protocol, so spidev is the correct library to communicate with it.
  3. Final Answer:

    spidev -> Option D
  4. Quick Check:

    SPI communication = spidev library [OK]
Hint: Use spidev for SPI devices like MCP3008 on Pi [OK]
Common Mistakes:
  • Using RPi.GPIO which is for GPIO pins, not SPI
  • Choosing smbus which is for I2C devices
  • Selecting serial which is for UART communication
3. Given the following Python code snippet reading channel 0 from MCP3008, what is the output if the analog input corresponds to a digital value of 512?
import spidev
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1350000
adc = spi.xfer2([1, (8 + 0) << 4, 0])
data = ((adc[1] & 3) << 8) + adc[2]
print(data)
medium
A. 512
B. 0
C. 1023
D. 256

Solution

  1. Step 1: Understand SPI transfer and data extraction

    The spi.xfer2 sends 3 bytes and receives 3 bytes. The returned adc list contains the 10-bit ADC value split across adc[1] and adc[2].
  2. Step 2: Calculate the 10-bit value from response

    The code extracts the 10-bit value by combining bits: ((adc[1] & 3) << 8) + adc[2]. If the analog input corresponds to 512, the printed value will be 512.
  3. Final Answer:

    512 -> Option A
  4. Quick Check:

    Extracted ADC value = 512 [OK]
Hint: Combine bits from adc[1] and adc[2] to get 10-bit value [OK]
Common Mistakes:
  • Not masking adc[1] with & 3
  • Shifting bits incorrectly
  • Confusing channel bits with data bits
4. Identify the error in this MCP3008 SPI read code snippet:
import spidev
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1350000
channel = 1
adc = spi.xfer2([1, (8 + channel) << 4, 0])
data = (adc[1] << 8) + adc[2]
print(data)
medium
A. Wrong shift amount for channel bits
B. Incorrect SPI bus number in spi.open()
C. Missing mask to extract only 2 bits from adc[1]
D. Using xfer2 instead of xfer

Solution

  1. Step 1: Review data extraction from SPI response

    The MCP3008 returns a 10-bit value where only the last 2 bits of adc[1] are part of the data. The code incorrectly uses adc[1] << 8 without masking.
  2. Step 2: Identify correct masking

    Correct extraction requires masking with adc[1] & 3 before shifting to keep only the 2 relevant bits.
  3. Final Answer:

    Missing mask to extract only 2 bits from adc[1] -> Option C
  4. Quick Check:

    Mask adc[1] with & 3 before shifting [OK]
Hint: Always mask adc[1] with & 3 before shifting bits [OK]
Common Mistakes:
  • Skipping bit masking on adc[1]
  • Incorrect SPI bus or device numbers
  • Confusing xfer and xfer2 usage
5. You want to read all 8 channels of the MCP3008 and store their values in a dictionary with keys as channel numbers. Which code snippet correctly implements this using spidev?
hard
A. values = {ch: ((spi.xfer2([1, (8 + ch) << 4, 0])[1] & 3) << 8) + spi.xfer2([1, (8 + ch) << 4, 0])[2] for ch in range(8)}
B. values = {} for ch in range(8): adc = spi.xfer2([1, (8 + ch) << 4, 0]) values[ch] = ((adc[1] & 3) << 8) + adc[2]
C. values = [spi.xfer2([1, (8 + ch) << 4, 0]) for ch in range(8)]
D. values = {ch: spi.xfer2([1, (8 + ch) << 4, 0])[1] << 8 + spi.xfer2([1, (8 + ch) << 4, 0])[2] for ch in range(8)}

Solution

  1. Step 1: Understand correct SPI read and bit extraction

    Each channel read requires one SPI transfer. The 10-bit value is extracted by masking adc[1] with 3 and shifting before adding adc[2].
  2. Step 2: Check code correctness

    values = {} for ch in range(8): adc = spi.xfer2([1, (8 + ch) << 4, 0]) values[ch] = ((adc[1] & 3) << 8) + adc[2] uses a for loop to read each channel once, extracts the value correctly, and stores it in a dictionary with channel keys.
  3. Final Answer:

    Option B code snippet -> Option B
  4. Quick Check:

    Loop + mask adc[1] & 3 + shift + store in dict [OK]
Hint: Use a loop with masking and shifting to read all channels [OK]
Common Mistakes:
  • Calling spi.xfer2 twice per channel (Option A)
  • Not masking adc[1] bits (Option D)
  • Storing raw SPI response without processing (Option C)
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard