지난 글에서 ESP32 Feather V2를 선택한 이유에 대해 이야기했다. 오늘은 본격적으로 4개의 로드셀 데이터를 어떻게 정확하게 동시에 읽어왔는지, 하드웨어 측면에서 이야기해보겠다.

ESP32 내장 ADC도 있지 않나요?

프로젝트를 시작하면서 가장 먼저 고민했던 부분이 바로 로드셀 데이터를 어떻게 읽을 것인가였다.

“ESP32에 ADC 있잖아? 그냥 연결하면 되는 거 아니야?”

단순한 프로젝트라면 내장 ADC를 써도 되지만, 연구용이기 때문에 정확도와 정밀도 두 가지 모두 중요했다.

ESP32 내장 ADC의 한계:

  • 12비트 분해능: 0~4095 단계로만 구분 — 정밀 측정에는 부족
  • 정확도 부족: 오차범위가 ±5% 수준
  • 차동 입력 불가: 로드셀은 차동 신호인데 단일 입력만 지원

ADS123X가 뭔가

ADS123X는 Texas Instruments에서 만든 로드셀/압력센서 전용 24비트 ADC다.

모델입력 채널
ADS12311채널
ADS12322채널
ADS12344채널

주요 스펙:

항목사양
분해능24비트 (16,777,216 단계)
입력 방식차동 입력
내장 PGA신호 증폭 기능 내장
최대 샘플링80 SPS
노이즈정밀 측정에 최적화

왜 ADS1232를 4개나 쓴 건가

나는 ADS1232를 총 4개 사용했다.

ADS1232는 2채널 차동 입력을 갖고 있어서, 이론상 ADS1232 2개로 4개의 로드셀 데이터를 얻을 수 있다.

그런데 여기에 문제가 있었다.

ADS1232는 내부 멀티플렉서로 채널을 전환하는데, 이 전환에 시간이 걸린다.

1
채널 1 측정 → 채널 전환 → 안정화 대기 → 채널 2 측정

데이터시트를 확인하면 채널 전환 후 안정화에 수 ms가 필요하다는 걸 알 수 있다. 두 채널이 정확히 같은 시점에 측정되지 않는 것이다.

코끼리 재활자전거처럼 팔과 다리에서 발생하는 힘을 동시에 측정해야 하는 경우, 이 수 ms의 시간차가 치명적이다. 환자가 힘을 주는 순간을 정확히 잡아내야 하기 때문이다.

그래서 ADS1232를 4개, 각 채널마다 하나씩 배치하는 방식을 택했다.

오실레이터로 동기화

ADS1232는 내부 클럭으로 자동 측정이 가능하다. 그러나 내부 클럭을 각자 쓰면 4개가 정확히 같은 타이밍에 샘플링한다는 보장이 없다.

이를 해결하기 위해 4.9152 MHz 외부 오실레이터를 하나 두고, 4개의 ADS1232 CLKIN 핀에 동시에 클럭을 공급했다.

1
2
3
4
5
[4.9152 MHz 오실레이터]
  ┌─────┼─────┬─────┐
ADS1232  ADS1232  ADS1232  ADS1232
 (우측팔) (좌측팔) (우측다리) (좌측다리)

같은 클럭 소스를 공유하면 4개의 ADC가 동시에 샘플링을 진행하므로 채널 간 시간차를 없앨 수 있다.

회로도 채널 1,2 채널 1, 2 (우측팔, 좌측팔) + ESP32 회로도

회로도 채널 3,4 채널 3, 4 (우측다리, 좌측다리) + 오실레이터 회로도

회로도를 보면 SPI 통신을 하는 것처럼 생겼는데, 핀 연결이 조금 독특하다. 간단히 설명하면 SCLK의 Falling Edge마다 인터럽트를 발생시켜 DOUT 핀에서 1비트씩 데이터를 읽고, 이를 24번 반복해 4개 채널의 데이터를 동시에 수집한다. 이 부분은 다음 글인 소프트웨어 편에서 자세히 다루겠다.

참고로 당시에 구할 수 있는 소자가 ADS1232 모듈이었기 때문에, ADS1231 4개가 아닌 ADS1232 4개를 사용했다.

AS5600으로 크랭크 각도 측정

로드셀이 힘을 측정한다면, AS5600은 자전거 크랭크의 회전 각도를 측정한다.

AS5600은 12비트 자기식 회전 위치 센서다.

항목사양
분해능12비트 (0~4095, 즉 360° ÷ 4096 단계)
통신I2C
측정 범위0~360° 연속 측정
방식비접촉 자기식

왜 AS5600인가

각도를 측정하는 방법은 여러 가지가 있다. 기계식 엔코더, 광학식 엔코더, 자기식 엔코더 등.

기계식이나 광학식은 접촉하거나 슬릿 디스크가 필요해서 마모나 오염에 취약하다. 반면 AS5600은 샤프트 끝에 작은 자석 하나만 붙이면 된다. 구조가 단순하고, 비접촉이라 마모가 없다.

자전거 크랭크처럼 연속 회전하는 구조에서는 비접촉 방식이 신뢰성 면에서 훨씬 낫다.

I2C로 연결

AS5600은 I2C로 ESP32와 통신한다. Wire.h와 AS5600 라이브러리(Rob Tillaart)를 사용했다.

1
2
3
4
5
6
7
#include <Wire.h>
#include <AS5600.h>

AS5600 as5600;

// 각도 읽기
uint16_t rawAngle = as5600.readAngle(); // 0~4095

각도 오프셋은 영점 보정 시 EEPROM에 저장해두고, 부팅 시 자동으로 불러온다.

1
2
3
// EEPROM에서 오프셋 로드 후 AS5600에 적용
short savedOffset = EEPROM.readShort(EEPROM_AngleOffset);
as5600.setOffset(-savedOffset * AS5600_RAW_TO_DEGREES);

이렇게 하면 재부팅해도 캘리브레이션 값이 유지된다.

완성된 하드웨어

하드웨어 보드 최대한 노이즈를 줄이기 위해 작은 보드에 직접 납땜했다. 캐패시터와 저항도 모두 올라가 있다.

시스템 다이어그램 전체 시스템 구성도

최대한 노이즈를 줄이기 위해 작은 보드에 손납땜으로 제작했다. 손납땜으로 만든 이유는 테스트 단계에서 저항값, Gain 설정 등을 언제든지 바꿀 수 있게 하기 위해서였다. 이 작은 보드 하나에 ADS1232 4개, 오실레이터, 각종 필터 캐패시터가 다 들어가 있다.

마무리

정리하면:

  • 내장 ADC 대신 ADS1232: 24비트 분해능과 차동 입력이 필요했기 때문
  • ADS1232 4개: 채널 전환 없이 4채널을 완전히 동시에 샘플링하기 위해
  • 외부 오실레이터: 4개의 ADS1232를 동일 클럭으로 동기화하기 위해
  • AS5600: 비접촉 자기식 센서로 크랭크 각도 연속 측정

다음 글에서는 이 하드웨어에서 실제로 데이터를 어떻게 읽어오는지, ISR 기반 24비트 동시 수집과 2의 보수 부호 처리 코드를 설명하겠다.