[RPi]MCP3008 vs MCP3208

라즈베리파이의 GPIO에는 아날로그 신호를 처리하는 것이 없다. 그래서 아날로그 신호를 내보내는 대부분의 센서를 처리하기 위해서는 ADC(analog-to-digital converter)가 필요하다. ADC 중에는 MCP3008와 MCP3208 등이 있다. 라즈베리파이와 ADC 간의 통신은 SPI를 이용한다.

MCP3008, MCP3004, MCP3208, MCP3204

다음 웹페이지에는 MCP3008, MCP3004, MCP3208, MCP3204 에 대한 데이터시트에 가까운 정보를 제공하고 있다.

Raspberry PI – Adding analogue inputs using MCP3008, MCP3004, MCP3208, MCP3204

그리고 여기는 spidev 라이브러리를 이용하였다. ADC에서 읽은 값이 해상도가 10비트이면 0~1023, 12비트이면 0~4095라는 것을 알 수 있다.

spidev 라이브러리를 이용하여 https://kalten.tistory.com/46 처럼, 통신 여부를 검토하였더니 잘 작동하지 않아서 RPi.GPIO 라이브러리를 이용하였다.

MCP3008에서 센서의 신호처리(SPI통신)

다음은 신호처리를 위해 작성한 파이썬 코드이다. RPi.GPIO 라이브러리를 이용하였다.

import RPi.GPIO as GPIO
 
GPIO.setmode(GPIO.BCM)
 
# MCP3008 칩으로부터 SPI 신호를 읽는다. 8개 센서를 둘 수 있다.(adcnum은 0번부터 7번까지)
def readadc(adcnum, clockpin, mosipin, misopin, cspin):
        if ((adcnum > 7) or (adcnum < 0)):
                return -1
        GPIO.output(cspin, True)      # CS핀을 high로 만든다.
 
        GPIO.output(clockpin, False)  # clock핀을 low로 만든다. 
        GPIO.output(cspin, False)     # CS핀을 low로 만든다.
 
        commandout = adcnum
        commandout |= 0x18  # start bit + single-ended bit
        commandout <<= 3    # we only need to send 5 bits here
        for i in range(5):
                if (commandout & 0x80):
                        GPIO.output(mosipin, True)
                else:
                        GPIO.output(mosipin, False)
                commandout <<= 1
                GPIO.output(clockpin, True)
                GPIO.output(clockpin, False)
 
        adcout = 0
        # MCP3008은 10비트의 해상도를 갖고 있다.
        # MCP3008에서 총 12비트을 읽는다. (=one empty bit, one null bit and 10 ADC bits)
        for i in range(12):
                GPIO.output(clockpin, True)
                GPIO.output(clockpin, False)
                adcout <<= 1
                if (GPIO.input(misopin)):
                        adcout |= 0x1
 
        GPIO.output(cspin, True)
         
        adcout >>= 1       # first bit is 'null' so drop it
        return adcout      # adcout는 0부터 1023까지 값을 갖는다.
#end of def

MCP3208에서 센서의 신호처리

import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)

# MCP3208 칩으로부터 SPI 신호를 읽는다. 8개 센서를 둘 수 있다.(adcnum은 0번부터 7번까지)
def readadc(adcnum, clockpin, mosipin, misopin, cspin):
        if ((adcnum > 7) or (adcnum < 0)):
                return -1
        GPIO.output(cspin, True)      # CS핀을 high로 만든다.
        GPIO.output(clockpin, False)  # clock핀을 low로 만든다. 시작한다.
        GPIO.output(cspin, False)     # CS핀을 low로 만든다.
        commandout = adcnum
        commandout |= 0x18  # start bit + single-ended bit
        commandout <<= 3    # we only need to send 5 bits here
        for i in range(5):
                if (commandout & 0x80):
                        GPIO.output(mosipin, True)
                else:
                        GPIO.output(mosipin, False)
                commandout <<= 1
                GPIO.output(clockpin, True)
                GPIO.output(clockpin, False)
        adcout = 0
        # MCP3208은 12비트의 해상도를 갖고 있다.
        # MCP3208에서 총 14비트을 읽는다. (=one empty bit, one null bit and 12 ADC bits)
        for i in range(14):
                GPIO.output(clockpin, True)
                GPIO.output(clockpin, False)
                adcout <<= 1
                if (GPIO.input(misopin)):
                        adcout |= 0x1
        GPIO.output(cspin, True)
        
        adcout <<= 1       # first bit is 'null' so drop it
        return adcout      # adcout는 0부터 4095까지 값을 갖는다.
#end of def

SPI at Rasberry Pi GPIO Pinout

SPI통신을 위한 라즈베리 파이의 GPIO 핀 배치는 다음과 같다.

SPI – Serial Peripheral Interface at Raspberry Pi

참고문헌

https://github.com/RaresPlescan/daisypi/blob/master/sense/mcp3208/adc_3.py

Print Friendly, PDF & Email
%d bloggers like this: