본문 바로가기
Embedded/Raspberry PI

ADC with SPI

by kjy1010 2024. 1. 3.

라즈베리파이에서는 Analog signal 를 이용한 작업이 가능합니다, 

우선 Analog signalDigital signal에 대해 소개하고 실습을 진행 하도록 하겠습니다.

 

Analog signal

  • 값과 시간 모두 연속적인 특성을 가집니다.
  • 정보 손실 없이 풍부한 정보를 포함합니다.
  • 노이즈에 의한 왜곡이 발생할 수 있습니다.
  • 예시: 소리, 빛, 온도

Digital signal

  • 값과 시간이 이산적인 특성을 가집니다.
  • 일부 정보의 연속성이 손실될 수 있습니다.
  • 저장 및 전송이 쉽습니다.
  • 노이즈에 강건합니다.

Analog signal와  Digital signal 의 비교

 

ADC(Analog-to-Digital Converter)

  • 아날로그 신호를 디지털 신호로 변환하는 시스템입니다.
  • 핵심 아이디어는 시간에 따라 아날로그 신호를 이산 값으로 샘플링하는 것입니다.
  • 샘플링 속도: 신호를 얼마나 자주 샘플링하는가
  • 해상도: 신호를 얼마나 정확하게 표현하는가(몇 비트를 사용할 것인가)

MCP3208

 

실습에 사용한 ADC인 MCP3208에 대해 소개해드리겠습니다.

  • MCP3208: 12비트 ADC
  • 아날로그 신호의 진폭을 12비트 정수로 변환합니다.
  • CH0 ~ CH7: 8개의 아날로그 채널
  • VDD: VCC
  • AGND/DGND: GND
  • VREF: 최대 아날로그 입력 값
  • LK, DIN, DOUT, CS/SHDN: 각각 SCLK, MOSI, MISO, CS에 해당 (SPI를 위한)

  • MCP3208에게 특정 채널의 ADC 데이터를 보내도록 요청
    - D0, D1 및 D2 비트를 활용합니다.
  • 그런 다음 MCP3208은 ADC 값을 응답합니다.

  • 3바이트 버퍼를 활용합니다
  • MCP3208에게 요청을 위한 처음 10비트
  • MCP3208에서 응답을 받기 위한 마지막 12비트

MCP3206 실습

이제 위에서 소개한 MCP3206와 조이스틱을 이용해 실습을 진행하겠습니다.

ADC는 SPI를 이용하여 라즈베리파이와 통신합니다.

따라서 SPI를 라즈베리파이에서 사용 할 수 있도록 setting후 실습을 진행합니다.

SPI를 이용하기 위한 설정 방법은 <Serial Interfaces> 포스팅을 참고하시면 됩니다.

실습에 사용할 조이스틱을 살펴보겠습니다.

 

조이스틱은 화면에서 어떤 물체를 이동시키기 위한 직관적인 입력 장치입니다.

실습에서 사용할 조이스틱의 Pinout에 대해 알아보겠습니다.

조이스틱 Pinout

  • 5V: 전원 공급(VCC)
  • Gnd: 접지(GND)
  • VRx: X축 입력용 아날로그 신호
  • VRy: Y축 입력용 아날로그 신호
  • SW: 버튼 클릭을 나타내는 디지털 신호

실습에 사용한 회로에 대해 알아보겠습니다.

 

 

다음과 같이 라즈베리파이와 ADC, 조이스틱을 연결해줍니다.

joystick.c라는 c파일을 생성해 코드를 작성해보겠습니다.

 

#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <wiringPiSPI.h>
#define CS_MCP3208 10 // BCM_GPIO 8 ,24pin
#define SPI_CHANNEL 0 // one slave SPI
#define SPI_SPEED 1000000 // 1MHz
int read_mcp3208_adc(unsigned char adcChannel)
{
    unsigned char buff[3];
    int adcValue = 0;
    buff[0] = 0x06|((adcChannel & 0x07) >> 2); //d2 on the last bit
    buff[1] = (adcChannel & 0x07) << 6; //d1 and d0 on the first two bits
    buff[2] = 0x00;
    digitalWrite(CS_MCP3208, 0); // Low : CS Active
    wiringPiSPIDataRW(SPI_CHANNEL, buff, 3);
    buff[1] = 0x0f & buff[1];
    adcValue = ( buff[1] << 8) | buff[2];
    digitalWrite(CS_MCP3208, 1); // High : CS Inactive, finish read data
    return adcValue;
}
int main (void)
{
    int adcValX, adcValY;
    wiringPiSetup();
    wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED);
    pinMode(CS_MCP3208, OUTPUT);
    while (1)
    {
        adcValX = read_mcp3208_adc(0);
        adcValY = read_mcp3208_adc(1);
        printf("X-axis: %u, Y-axis: %u\n", adcValX, adcValY);
        delay (500);
    }
    return 0;
}

 

코드를 작성하였다면 gcc를 이용해 컴파일 해보겠습니다.

 

pi@raspberrypi:~ $ gcc -o joy joystick.c -lwiringPi
pi@raspberrypi:~ $ sudo ./joy

 

위의 명령어를 통해 프로그램을 실행시켜 조이스틱을 움직이면 아날로그 신호로 좌표값을 읽어와 메시지를 출력함을 확인 할 수 있습니다.

'Embedded > Raspberry PI' 카테고리의 다른 글

OpenCV  (0) 2024.01.04
PWM 실습  (4) 2024.01.03
Serial Interfaces  (2) 2023.12.28
Raspberry PI GPIO 실습(3)  (2) 2023.12.27
Raspberry PI GPIO 실습(2)  (0) 2023.12.22