YOGYUI

ESP32 - Digilent Pmod DPOT (AD5160) 디지털 저항 제어 본문

Hardware/Espressif

ESP32 - Digilent Pmod DPOT (AD5160) 디지털 저항 제어

요겨 2023. 2. 17. 14:03
반응형

1. 목적

Digilent사의 Pmod DPOT 디지털 저항 (digital potentiometer)를 ESP32 칩셋을 이용해 제어하는 코드 구현

[개발 환경]
칩셋: ESP32-WROOM-32E
SDK: Espressif ESP-IDF v4.4.3, Vue 2.9.6
타겟 디바이스: Pmod DPOT (AD5160)
IDE: Visual Studio Code

2. 사전 조사

Pmod DPOT는 Analog Device의 AD5160 (256 position SPI 제어방식 디지털 저항) 칩을 탑재한 Evaluation Kit

AD5160 데이터시트: 링크

AD5160은 SPI(Serial Peripheral Interface) 방식의 시리얼 통신 인터페이스를 통해 출력 저항값을 제어할 수 있는데, 일반적인 SPI 디바이스와는 달리 Master(MCU 등)에서 Slave(AD5160) 방향으로의 단방향 통신만 구현하면 된다 - 실제로 IC의 핀아웃도 MOSI(Master Out Slave In)만 있으며, MISO(Master In Slave Out)은 없다

통신 프로토콜도 어드레스-데이터 방식이 아니라 단순히 저항 설정값 (8비트, 256단계)만 전송하기만 하면 되기 때문에 이중 통신 방식(duplex)나 인터럽트에 대한 고민없이 쉽게 MCU로 제어 코드를 구현할 수 있다 

출력단은 A, W, B 세개가 있으며, A-B 터미널간 저항은 AD5160 모델에 따라 5kΩ, 10kΩ, 50kΩ, 100kΩ 4가지의 고정된 값을 가지고, SPI로 설정한 값에 따라 A-W간 저항 / W-B간 저항값이 256단계로 변화하게 된다

※Digilent Pmod DPOT은 10kΩ 모델이 장착되어 있다

설정값(\(D\))에 따른 W-B간의 저항값(\(R_{WB}\))은 다음 공식을 통해 구할 수 있다 (단순한 선형 대수)

\( R_{WB}[D]= \cfrac {D}{256} \times R_{AB} + R_{W} \)

여기서 \(R_{W}\)는 Wiper contact resistance로, IC 내부의 출력 저항단 사이 연결 배선의 접촉 저항이며 50~120Ω 사이의 값을 가진다

3. 코드 구현

소스코드는 깃허브 저장소에 커밋

https://github.com/YOGYUI/esp32-pmod-dpot

 

GitHub - YOGYUI/esp32-pmod-dpot: Pmod DPOT (Digital Potentiometer, AD5160), SPI peripheral control using ESP-32

Pmod DPOT (Digital Potentiometer, AD5160), SPI peripheral control using ESP-32 - GitHub - YOGYUI/esp32-pmod-dpot: Pmod DPOT (Digital Potentiometer, AD5160), SPI peripheral control using ESP-32

github.com

ESP-32와의 연결 핀맵은 definition.h에 하드코딩 (HSPI, 즉 SPI2를 사용)

// SPI setting
#define DPOT_SPI_HOST       HSPI_HOST
#define PIN_DPOT_SPI_MOSI   13
#define PIN_DPOT_SPI_MISO   12
#define PIN_DPOT_SPI_SCLK   14
#define PIN_DPOT_SPI_CS     15

CDpotCtrl 클래스 인스턴스 생성 시 SPI 버스 초기화 및 인터페이스 초기화

※ 예외처리 및 로깅 코드는 블로그 포스트에서는 제외

bool CDpotCtrl::initialize()
{
    // SPI Bus 초기화    
    spi_bus_config_t cfg_bus;
    memset(&cfg_bus, 0, sizeof(cfg_bus));
    cfg_bus.mosi_io_num = PIN_DPOT_SPI_MOSI;
    cfg_bus.miso_io_num = PIN_DPOT_SPI_MISO;
    cfg_bus.sclk_io_num = PIN_DPOT_SPI_SCLK;
    cfg_bus.max_transfer_sz = 4092;
    cfg_bus.intr_flags = 0;
    spi_bus_initialize(DPOT_SPI_HOST, &cfg_bus, SPI_DMA_CH_AUTO);

    // SPI Bus에 디바이스 부착
    spi_device_interface_config_t cfg_dev_if;
    memset(&cfg_dev_if, 0, sizeof(cfg_dev_if));
    cfg_dev_if.clock_speed_hz = 10 * 1000 * 1000;    // Max 25MHz
    cfg_dev_if.mode = 0;
    cfg_dev_if.spics_io_num = PIN_DPOT_SPI_CS;
    cfg_dev_if.queue_size = 7;
    spi_bus_add_device(DPOT_SPI_HOST, &cfg_dev_if, &m_handle);

    return set_pot_value(DPOT_INIT_VALUE);
}
bool CDpotCtrl::set_pot_value(uint8_t value)
{
    m_value = value;
    m_spi_transaction.tx_buffer=&value;
    spi_device_polling_transmit(m_handle, &m_spi_transaction);
    return true;
}

AD5160의 저항값을 사용자가 외부에서 쉽게 제어할 수 있게 하기 위해 HTTP 서버를 함께 구현했는데, 사용된 기법들은 다음과 같다

  • Vue 프론트엔드 프레임워크로 웹 리소스 빌드
    - 최근 Vue 학습을 시작했는데, 실제 프로젝트에 적용해보면서 차근차근 사용법을 익혀나갈 계획
  • ESP-32의 WiFi Soft-AP 활성화
  • ESP-32의 NVS 플래시 메모리 중 일부 영역을 SPIFFS 파티션으로 구성
  • SPIFFS에 웹 리소스를 플래시한 뒤, HTTP 서버에서 I/O로 파일을 읽어 response 

자세한 내용은 깃허브 소스코드를 참고

4. 데모

0 ~ 255 사이의 값 몇개를 입력했을 때, W-B 단 사이의 저항값이 바뀌는 것을 멀티미터로 확인할 수 있다

(멀티미터가 싸구려 제품이라 반응 속도가 상당히 느리다)

5. 마무리

전압 분배기(Voltage divider)는 저항 2개로 쉽게 구현할 수 있는 간단한 회로인데, 출력 전압값 조정이 필요할 때마다 저항을 갈아끼우거나 아날로그 가변 저항을 드라이버로 돌리는 작업은 튜닝 회수가 많아질 수록 상당히 번거롭다

AD5160처럼 MCU를 통해 저항값을 디지털 인터페이스로 변경할 수 있다면 dimmable light 등 IoT 디바이스 개발에 상당히 유용하게 활용할 수 있다


최근 열심히 매진한 Matter 엔드포인트 디바이스 개발도 1차 마무리단계라 정리하는 차원에서 매터에 대한 내용을 블로그에 정리해보고자 이런저런 evaluation kit 사용법부터 블로그에 간단하게 정리하고 있다

개발은 재밌는데, 글 쓰는건 재미가 없어서 진도가 영 나가고 있지 않고 있지만 ㅠ..

누군가에겐 도움이 되지 않을까 싶으니 천천히 진행해나가보자 ㅎㅎ

반응형