Raspberry Pi에 ADC 추가: 알아야 할 사항
주요 시사점
- Raspberry Pi에는 아날로그 입력이 없지만 외부 ADC를 추가하여 실제 전압을 디지털 형식으로 변환하여 기록, 조작 및 제어할 수 있습니다.
- 널리 사용되는 ADC 옵션으로는 속도와 정밀도 절충을 위한 MCP3004/MCP3008 또는 느린 샘플링 속도에서 16비트 판독을 위한 ADS111x가 있습니다.
- Adafruit의 ADS1115는 프로그램 중에 작은 전압 차이를 감지하고 이득을 조정할 수 있는 PGA(프로그래밍 가능 이득 증폭기)가 포함된 간단한 옵션입니다. I2C를 사용하여 Raspberry Pi와 연결하는 것은 간단합니다.
기본적으로 Raspberry Pi에는 아날로그 입력이 없습니다. 이는 Arduino와 같은 마이크로컨트롤러 기반 보드에 비해 불리한 점입니다.
하지만 절망하지 마세요. 고려해야 할 옵션이 많이 있습니다. Raspberry Pi와 외부 ADC를 시작하고 실행해 보세요.
입력을 추가하는 이유는 무엇입니까?
현실 세계는 올바른 회로만 있다면 전압을 사용하여 쉽게 설명할 수 있는 현상으로 가득 차 있습니다. 이러한 전압을 디지털 형식으로 가져오면 이를 기록하고 조작하고 다른 매개변수와 장치를 제어하는 데 사용할 수 있습니다.
토양의 수분, 온실 온도 또는 햄스터의 무게를 모니터링할 수도 있습니다. Pi에 볼륨 컨트롤을 추가하거나, 전체 페이더 뱅크를 구축하거나, 조이스틱을 처음부터 디자인하려고 할 수도 있습니다. 가능성은 거의 무한합니다.
ADC 옵션
그렇다면 초보자에게 가장 적합한 ADC는 무엇입니까?
가장 인기 있고 간단한 옵션 중에는 Microchip의 MCP3004 (및 MCP3008 ) 칩이 있습니다. 각각 10비트의 채널 4개(또는 8개)를 갖게 되며 최대 200kSPS를 읽을 수 있습니다. 반면에 860SPS에서 16비트를 읽는 Texas Instruments의 ADS111x 장치가 있습니다. 따라서 속도와 정밀도(그리고 당연히 가격) 사이에는 상충 관계가 있습니다.
많은 마이크로컨트롤러에는 ADC가 내장되어 있습니다. 일반적인 Arduino에서 볼 수 있는 ATMega는 무엇보다도 여러 개의 10비트 채널을 제공합니다. 이를 통해 Arduino는 Raspberry Pi가 제공할 수 없는 아날로그 입력을 제공할 수 있습니다. 이미 설정에 Arduino가 포함되어 있고 10비트로 충실도가 충분하다면 실제로 이 방법이 가장 쉬운 방법일 수 있습니다.
여기서는 Adafruit의 ADS1115를 사용하여 간단하게 설명하겠습니다.
프로그래밍 가능 이득 증폭기란 무엇입니까?
이 칩에는 PGA(프로그래밍 가능 이득 증폭기)를 비롯한 몇 가지 흥미로운 기능이 포함되어 있습니다. 이를 통해 원하는 값 범위를 1볼트 단위까지 디지털 방식으로 설정할 수 있습니다. 16비트가 나타낼 수 있는 값의 수를 사용하면 단 몇 마이크로볼트의 차이도 감지할 수 있습니다.
여기서 장점은 프로그램 중간에 게인을 변경할 수 있다는 것입니다. MCP3004와 같은 다른 칩은 다른 접근 방식을 취합니다. 기준 전압을 공급할 수 있는 추가 핀이 함께 제공됩니다.
멀티플렉싱은 어떻습니까?
멀티플렉서(또는 mux)는 단일 ADC를 사용하여 많은 입력을 읽을 수 있는 스위치입니다. ADC 칩에 많은 입력 핀이 함께 제공되는 경우 내부 멀티플렉싱이 진행되고 있는 것입니다. ADS1115의 멀티플렉서는 내부 레지스터를 통해 선택할 수 있는 4개의 입력을 허용합니다.
레지스터 다루기
ADS1115는 이러한 옵션 외에도 몇 가지 옵션을 더 제공합니다. 멀티플렉서를 처리하고, 이득을 조정하고, 내장된 비교기를 활성화하고, 샘플링 속도를 변경하고, 장치를 저전력 절전 모드로 전환하는 작업을 모두 스위치 몇 개만 켜면 수행할 수 있습니다.
그런데 그 스위치는 어디에 있나요? 그들은 레지스터 라고 불리는 아주 작은 메모리 비트 형태로 패키지 안에 있습니다 . 특정 기능을 활성화하려면 관련 비트를 0이 아닌 1로 설정하면 됩니다.
ADS111x 데이터시트를 보면 이러한 모델에는 장치의 동작을 관리하는 구성 레지스터를 포함하여 4개의 레지스터가 함께 제공된다는 것을 알 수 있습니다.
예를 들어 비트 14~12는 멀티플렉서를 제어합니다. 이 3개의 비트를 사용하여 8개의 구성 중에서 선택할 수 있습니다. 여기서 원하는 것은 “100”입니다. 이는 입력 0과 접지 사이의 차이를 제공합니다. 반면에 비트 7~5는 샘플링 속도를 제어합니다. 초당 최대 860개의 샘플을 원하는 경우 이를 “111”로 설정할 수 있습니다.
어떤 옵션을 설정할지 알고 나면 ADC에 보낼 2바이트가 생깁니다. 나중에 여기나 저기에 단일 비트를 설정하려면 비트 연산자를 사용하여 개별적으로 처리할 수 있습니다.
여기서 혼란스러울 수 있습니다. 이 경우 바이너리는 값이 아니라 개별 스위치의 값을 나타냅니다. 이러한 변수를 하나의 큰 숫자, 10진수 또는 16진수로 표현할 수 있습니다. 하지만 골치 아픈 문제를 피하려면 읽기 쉬운 바이너리 버전을 사용해야 합니다.
배선하기
이 장치를 브레드보드에 직접 연결할 수 있습니다. 양의 전압 입력은 2~5.5v 사이에서 허용됩니다. 이는 Raspberry Pi의 3.3v 레일이 잘 작동한다는 것을 의미합니다.
SDA 및 SCL 입력을 RPi의 대응 부분에 연결하고 접지 및 3.3v에서도 동일한 작업을 수행합니다. 접지선과 전압선 사이에 전위차계를 설치하고 중간 리드를 ADC의 첫 번째 입력에 연결합니다. 시작하는 데 필요한 전부입니다!
I2C 다루기
다양한 ADC는 다양한 프로토콜을 통해 작동합니다. ADS1115의 경우 I2C를 사용할 예정입니다 .
다음 예에서는 Python을 사용하여 ADC와 상호 작용합니다. 하지만 그렇게 하기 전에 먼저 설정을 해야 합니다. 최신 버전의 Raspberry Pi OS를 사용하면 이 작업이 매우 간단해졌습니다. 환경 설정> Raspberry Pi 구성 으로 이동하십시오 . 그런 다음 인터페이스 탭 에서 I2C를 켭니다 .
모든 것이 작동하는지 확인하려면 터미널을 열고 다음을 실행하세요.
sudo i2cdetect -y 1
이 명령은 그리드를 출력합니다. 모든 것이 작동하고 올바르게 연결했다고 가정하면 그리드에 새 값이 나타나는 것을 볼 수 있습니다. 이것이 ADC의 주소입니다. 여기서는 16진수 값이므로 아래 코드에서 사용할 때 접두사 “0x” 를 붙여야 합니다. 여기는 0x48 입니다 :
주소가 있으면 SMBus 라이브러리를 사용하여 I2C 명령을 보낼 수 있습니다. 여기서는 두 가지 방법을 다루게 됩니다. 첫 번째는 write_word_data() 이며, 세 가지 인수(장치 주소, 쓰고 있는 레지스터, 쓰려는 값)를 받아들입니다.
결과를 약간 아름답게 만든 다음 인쇄할 수 있습니다. 루프의 시작으로 돌아가기 전에 짧은 지연을 도입하세요. 이렇게 하면 데이터가 너무 많아서 압도당하지 않게 됩니다.
from smbus import SMBusimport timeaddr = 0x48bus = SMBus(1)# set the registers for readingCONFIGREG = 1CONVERSIONREG = 0# set the address register to point to the config register# write to the config registersbus.write_word_data(addr, CONFIGREG, (0b00000100 << 8 | 0b10000010)) # define the top of the rangeTOP = 26300while True: # read the register b = bus.read_word_data(addr, CONVERSIONREG) # swap the two bytes b = ((b & 0xFF) << 8) | ((b >> 8) & 0xFF) # subtract half the range to set ground to zero b -= 0x8000 # divide the result by the range to give us a value between zero and one b /= TOP # cap at one b = min(b, 1) # bottom is zero b = max(b, 0) # two decimal places b = round(b, 2) print(b) time.sleep(.01)
이제 막 끝났습니다. 원하는 값의 범위를 매핑한 다음 원하는 소수 자릿수로 자릅니다. 마지막 값과 다른 경우에만 새 값을 인쇄하도록 인쇄 기능을 맞춤화할 수 있습니다.
소음 처리
이제 설정이 매우 훌륭하고 깔끔하고 깔끔하지 않으면 약간의 소음이 들릴 것입니다. 이는 10비트가 아닌 16비트를 사용하는 데 따른 본질적인 단점입니다. 즉, 약간의 노이즈가 더 잘 인식됩니다.
인접한 입력(입력 1)을 접지에 연결하고 입력 1과 2를 비교하도록 모드를 전환하면 훨씬 더 안정적인 결과를 얻을 수 있습니다. 긴 소음 수집 점퍼 케이블을 작은 케이블로 교체하고 그 동안 몇 개의 커패시터를 추가할 수도 있습니다. 전위차계의 값도 차이를 만들 수 있습니다.
소프트웨어 옵션도 있습니다. 이동 평균을 생성하거나 작은 변화를 무시할 수도 있습니다. 단점은 추가 코드로 인해 계산 비용이 발생한다는 것입니다. Python과 같은 고급 언어로 조건문을 작성하고 매초 수천 개의 샘플을 수집하는 경우 이러한 비용은 급격히 증가합니다.
가능한 많은 다음 단계를 통해 더 나아가세요
I2C를 통해 판독하는 것은 매우 간단하며 SPI와 같은 다른 방법에서도 마찬가지입니다. 사용 가능한 ADC 옵션 간에는 큰 차이가 있는 것처럼 보일 수 있지만 실제로는 그 중 하나가 작동하면 지식을 다른 옵션에 적용하기가 쉽습니다.
그렇다면 더 나아가는 것은 어떨까요? 여러 개의 전위차계를 함께 묶거나 빛, 소리 또는 온도를 읽어보세요. 방금 만든 컨트롤러를 확장하고 실제 실습이 가능한 Raspberry Pi 설정을 만드세요!
답글 남기기