이번에는 전류 측정 센서에 대해 이야기하려고 한다.
전류를 측정하는 센서는 다양하게 있고 AC, DC를 따로 측정하는 센서, 둘 다 측정이 가능한 센서 등 측정 종류, 범위에 따라서도 선택의 폭이 넓게 있다.
이런 센서 중에서 우리가 접하기 쉬우면서 정밀도도 나쁘지 않은 센서에 대해 이야기 해보고자 한다.
그 센서는 바로 INA 219 센서다.
DC 전류, 전압을 측정할 수 있고 특히 낮은 전류도 꽤 정밀하게 측정이 가능한 센서라 개인적으론 추천하는 센서라고 할 수 있다.
데이터시트를 보면 알겠지만 대표 오차율은 0.5%이고 전류 측정 오차는 0.3%, 전압 측정 오차는 0.5%로 표기하고 있다.
그리고 여기에 온도 영향을 추가 하면 전류가 0.5%, 전압이 1% 정도 오차가 발생할 수 있다고 한다.
간단히 접할 수 있는 센서 치고는 정밀도가 나쁘지 않다고 할 수 있다.
거기에 측정 범위도 DC 치고는 나쁘지 않다.
전압은 최대 26V까지 측정이 가능하고 전류는 3.2A 까지 측정이 가능하다.
우리가 일반적으로 접할 수 있는 전자회로를 생각해보면 꽤 높은 전류까지 측정이 가능하다는 말이다.
그럼 센서의 모습을 보자.

센서는 그림과 같은 모듈의 형태로 판매가 된다.
이때 보면 알 수 있지만 센서의 데이터는 SCL, SDA 즉, I2C 통신을 통해 주고 받을 수 있고 Vin+ Vin- 핀을 통해 전류나 전압을 측정할 수 있게 된다.
그리고 그림의 경우처럼 보통은 납땜이 되지 않은 상태로 판매되는 경우가 많으니 사용하는 환경에 맞춰 구입을 잘 하자.

참고로 그림에 표시한 곳처럼 Vin+ Vin-가 두 군데 있는데 사용하기 편한 곳에 납땜 해서 사용하면 된다.
아래쪽의 경우 핀헤더를 보통 납땜에서 사용하고 위쪽은 터미널을 납땜해서 사용하는 형식이다.
간단하게는 이렇게 모듈이 구성되어 있고 가운데 있는 반도체 칩이 INA 219 센서에 해당한다.
추가로 이 센서의 경우 전류를 측정하는 방식이 특이한데 Vin+와 Vin- 사이에 저항을 놓고 그 저항을 통해 흘러오는 전류를 측정하는 방식이다.
모듈에선 그 저항이 R100(0.1Ω)에 해당하고 이 저항을 데이터시트에선 션트 저항(Shunt Resistor)이라고 부른다.
좀 더 정확히 말하면 션트 저항에 전류가 흐르면 션트 저항 양단에 미세한 전압 강하가 발생하는데 INA 219는 이 전압 강하를 측정하여 전류값으로 환산하는 것이다.
그래서 이 션트 저항이 중요하고 앞서 이야기한 최대 전류 측정 값도 이 션트 저항에 맞춰서 구성된다.
우리가 흔히 사용하는 모듈에 부착된 것이 0.1Ω이라 이걸 토대로 계산했을 때 최대 측정 전류가 3.2A인 것이다.
그리고 전압의 측정 방식도 특이하다.
전압은 Vin- 단자와 GND 사이의 전압값을 측정하게 되는데 이로 인해 굳이 전압 측정을 위해 측정 부위를 변경할 필요가 없다.
우리가 흔히 아는 전압, 전류를 측정하는 장치인 멀티미터를 떠올려보면 멀티미터의 경우 전류를 측정하기 위해선 회로에 직렬로 연결해야 하고 전압을 측정하기 위해선 병렬로 연결해야 한다.
거기에 보통 전류 측정 방식과 전압 측정 방식이 다르기 때문에 멀티미터의 프로브의 위치를 변경해서 꽂아야 하기도 한다.
그런데 여기서는 전류 측정 방식으로만 연결해 둬도 회로에 걸리는 전압을 측정할 수 있는 것이다.
(다만, 이렇게 되면 소자 하나에 걸리는 전압을 측정하는 것은 어렵다. 그래서 데이터시트에서 칩을 소개할 때도 전원과 부하 사이에 연결하여 부하에 공급되는 전압, 전류 및 소비전력을 모니터링하는 센서라고 표현하고 있다.)

자, 그럼 여기까지 간단하게 알아봤으니 테스트를 해보자.
테스트는 간단하게 저항(220Ω)과 LED를 AA건전지 2개로 동작하는 회로의 전류와 전압을 측정하는 방식으로 해보자.

위의 그림과 같이 연결해보자.
센서의 경우 I2C 통신이 기본이기 때문에 데이터 핀도 SCL(A5), SDA(A4)핀만 연결하면 된다.
자, 그럼 코드도 작성해보자.
코드는 원래 I2C 통신에 맞춰 작성을 해야 하지만 모듈 제조사인 Adafruit에서 라이브러리를 제공해주고 있다.

위의 그림처럼 라이브러리 매니저에서 INA 219를 검색하고 설치를 진행하자.
이때 설치를 할 때 라이브러리 종속성 설치 창이 나타나는데 모두 설치를 해주면 되겠다.
Adafruit 라이브러리들은 서로 연계되는 라이브러리가 많기 때문에 같이 설치한다는 내용이다.
설치가 완료됬다면 코드를 작성해보자.
#include <Adafruit_INA219.h>
Adafruit_INA219 ina219;
void setup() {
Serial.begin(115200);
ina219.begin();
}
void loop(){
float shuntvoltage = 0;
float busvoltage = 0;
float current_mA = 0;
float loadvoltage = 0;
float power_mW = 0;
shuntvoltage = ina219.getShuntVoltage_mV();
busvoltage = ina219.getBusVoltage_V();
current_mA = ina219.getCurrent_mA();
power_mW = ina219.getPower_mW();
loadvoltage = busvoltage + (shuntvoltage / 1000);
Serial.print("Bus Voltage: ");
Serial.print(busvoltage);
Serial.println(" V");
Serial.print("Shunt Voltage: ");
Serial.print(shuntvoltage);
Serial.println(" mV");
Serial.print("Load Voltage: ");
Serial.print(loadvoltage);
Serial.println(" V");
Serial.print("Current: ");
Serial.print(current_mA);
Serial.println(" mA");
Serial.print("Power: ");
Serial.print(power_mW);
Serial.println(" mW");
Serial.println("");
delay(2000);
}코드를 업로드하고 시리얼 모니터를 보면 현재 측정되고 있는 값이 나타난다.
하지만 시리얼 모니터를 보면 우리가 기대하던 것과는 조금 다른 값이 나오는 것을 볼 수 있다.
AA 배터리 2개를 연결했으니 우리가 기대한 값은 3V 안 밖의 값을 기대할 것이다.
그런데 시리얼 모니터에 측정되는 전압값을 보면 값이 좀 다르다.

전압이 왜 이렇게 나올까.
이건 바로 위의 우리가 연결한 회로가 잘못 되었기 때문이다.
위에서 설명할 때 INA 219 센서는 전압을 측정할 때 Vin-와 GND 사이의 전압을 측정한다고 했다.
그리고 이 전압을 데이터시트에선 버스 전압(Bus Voltage)이라고 부른다.
이 버스 전압을 측정할 때 기준이 되는 것이 GND인데 위의 회로를 생각해보면 이 GND가 이상하다라는 것을 알 수 있다.
측정하려고 하는 회로의 전원과 센서 동작에 사용되는 전원이 서로 분리되어 있는데 이때 GND도 서로 별도의 GND를 사용하고 있다.
우리가 흔히 아두이노를 다루는 전자 회로에서 GND라고 하면 전원 중에 낮은 전위를 가진 곳을 말하게 되는데 이 낮은 전위라고 하는 것을 조금 생각해 볼 부분이 있다.
간단히 표현해서 전압이라고 하는 것은 +극과 -극의 전기적 위치에너지 즉, 전위의 차이를 표시한 것이다.
그래서 다 같은 5V라고 하더라도 기준이 되는 -극에는 차이가 존재한다.
예를 들어 서로 독립된 두 개의 5V 전원이 있다면 각각의 +극과 -극 사이의 전압은 모두 5V이지만 두 전원의 -극이 서로 같은 전위를 가지고 있다고 볼 수는 없다.
이걸 표시하자면 이런 V+ – V– = 5V라는 것이다.
(아두이노와 같은 디지털 회로에서는 전원을 표시할 때 V+ 쪽을 5V, 3.3V 이렇게 표기하고 V– 를 GND로 표시하게 된다.)
그래서 이 차이를 메꾸기 위해 전압을 판단하는 기준인 낮은 전위를 하나로 맞춰줄 필요가 있다.
이것이 보통 우리가 말하는 접지의 개념 중 하나다.
접지라고 하면 보통 GND라고 표현하고 땅을 많이 떠올리게 되는데 일반적으로 전자회로들이 모두 땅에 연결하긴 힘들기 때문에 보통은 회로 상의 -극을 모두 하나로 연결하는 방식을 사용하게 된다.
그것을 공통 접지 또는 신호 접지라고 부른다.
아무튼 이 INA 219도 마찬가지다.
서로 다른 전원의 값을 측정해야 하기 때문에 기준 전위를 맞춰줘야 하는 것이다.
그런데 보통 많이 알려진 회로가 위의 그림과 같은 회로여서 한 번 가져와 봤다.
실제로 저렇게 전원을 분리한 상태로 측정을 많이 하고 측정값이 정확하지 않아 문의를 넣는 경우가 많이 발생해서 Adafruit의 가이드 페이지에 들어가보면 공통 접지를 하라는 문구가 주의사항으로 적혀있다.
참고로 전류만 측정한다면 위의 회로와 같이 공통 접지가 없어도 측정이 된다.
전류 측정은 션트 저항의 양단의 전압차만을 이용하기 때문에 가능하다.
그래서 만약 나는 전류만 필요하다라고 생각한다면 위의 회로를 사용해도 좋다.
아무튼 전압 측정을 위해 위의 회로를 수정해보면 이렇게 된다.

배터리의 -극을 아두이노의 GND와 연결해둔 회로다.
이렇게 선을 하나만 추가해도 측정되는 전압 값이 달라지는 것을 볼 수 있다.(전류는 동일하다.)

자, 이렇게 측정 방법에 대해 정리했으니 이번에는 시리얼 모니터에 나오는 값들을 확인해보자.
먼저 Bus Voltage는 앞서 이야기한 것과 같이 Vin-와 GND 사이의 전압을 말하는 것으로 지금 회로에선 LED가 동작하고 있는 전체 회로의 전압을 뜻한다.
Shunt Voltage은 지금 션트 저항(현재 모듈에서 0.1Ω)에 걸리고 있는 전압을 이야기하고 이 전압을 바탕으로 전류(Current)가 계산되어 진다.
위의 값으로 계산을 해보면 션트 전압이 0.72mV이고 저항이 0.1Ω이니 옴의 법칙으로 계산해보면 대략 7.2mA 정도가 되는 것을 알 수 있다.
아마 소수점 아래로 값이 더 있을테니 조금 차이 나는 것은 그 부분 오차일 것이다.
다음으로 Load Voltage가 있는데 이것은 지금 회로에 공급되는 전체 전압을 말한다.
그래서 코드에서 Load Voltage를 Shunt Voltage와 Bus Voltage의 합으로 표현했다.
마지막으로 Power는 지금 사용되는 전력을 말한다.
다음은 코드를 살펴보자.
코드는 라이브러리에 정의된 함수들로 구성되어 있고 그 이름이 직관적이어서 크게 어렵지 않다.
Adafruit_INA219 ina219
처음 나오는 부분은 라이브러리를 사용할 때 항상 등장하는 객체를 생성하는 부분이다.
모르겠다면 간단하게 앞으로 사용할 센서의 이름을 지우준다고 생각해도 괜찮다.
그래서 표현하자면 이렇게 표현할 수도 있다.
Adafruit)INA219 Name와 같은 형태로 Name 자리에 내가 넣고 싶은 이름을 넣으면 그 이름대로 앞으로의 함수들도 사용하면 되는 것이다.
그런데 아마 센서를 많이 사용한 사람들은 알겠지만 보통 I2C 통신 기반의 센서들은 이 객체를 생성할 때 I2C 통신에 필요한 주소도 많이 설정을 한다는 것을 알고 있을 것이다.
만약 I2C 통신이 뭔지 잘 모르겠다면 이전 포스트를 참고하자.
( https://polnalab.com/arduino/intermediate/322/ )
아무튼 이 센서를 사용한 코드에선 이 주소를 설정하는 부분이 보이지 않는다.
그 이유는 보통 이 센서를 사용할 때 기본 주소를 사용하는 경우가 많아서 그럴 것이다.
센서의 기본 주소는 0x40으로 설정되어 있다.
그런데 당연히 이 센서를 여러개 사용해야 할 일도 발생할 것이다.
그럴경우엔 센서의 주소를 변경할 수 있는데 변경하는 방법으론 센서의 A0, A1번 핀을 사용하게 된다.
모듈에서는 이 부분을 납땜에서 사용하게 설정해두었다.

A0번만 남땜하여 사용하면 0x41, A1번만 납땜하여 사용하면 0x42, A0 A1번 둘 다 납땜하여 사용하면 0x43으로 주소가 변경된다.
그리고 변경된 주소를 사용한다면 위의 코드에서 뒤에 주소 값을 입력해주어야 한다.
Adafruit_INA219 ina219(0x41)
추가로 동일한 센서를 여러개 사용한다면 당연히 객체도 여러개 생성하면된다.
Adafruit_INA219 ina219_A(0x41)
Adafruit_INA219 ina219_B(0x42)
이렇게 객체 생성에 대해 이야기를 해보았고 이번에는 Setup으로 가보자.
Name.begin( )
여기는 begin 함수가 사용되었는데 Serial.begin과 마찬가지로 센서를 사용하기 위새 초기화 하는 함수라고 생각하면 된다.
여기서는 객체를 이름에 비유해서 ina219대신 Name으로 변경해서 표시했다.
다음은 loop로 넘어가보자.
Name.getShuntVoltage_mV();
Name.getBusVoltage_V();
Name.getCurrent_mA();
Name.getPower_mW();
위의 함수들은 각각 션트 전압(mV), 버스 전압(V), 전류(mA), 전력(mW)을 불러오는 함수들이다.
우리가 직접 계산할 수도 있긴 하지만 센서에서 처리된 결과 값을 받아보는 것이다.
이때 받아오는 값의 단위가 다르니 잘 확인하자.
그리고 여기서 측정 범위를 제한할 수 있는 캘리브레이션 함수를 제공하는데 이것을 통해서 최대 측정 범위를 제한할 수도 있다.
Name.setCalibration_32V_1A();
Name.setCalibration_16V_400mA();
기본 디폴트 설정값은 32V 2A로 되어 있는데 이 말대로라면 최대 32V 전압에 전류는 2A까지 측정이 가능하다라는 것이다.
다만, 말은 그렇게 할 수 있는데 센서의 최대 측정값은 26V이니 그 이상을 넣진 말자.
데이터시트나 함수에서 32V라고 표시한 것은 데이터 전송을 위해 2진수로 표시할 때 나타낼 수 있는 최대 값이 32라 그런 것이니 참고하자.
그리고 위의 함수를 이용하면 32V, 1A로 변경하거나 16V 400mA로 변경이 가능하다.
그런데 이렇게 범위를 변경했을 때 라이브러리 설명에는 정밀도가 변경된다는 말이 있는데 INA219의 데이터시트를 보면 전류는 정밀도 즉 분해능이 더 좋아지지만 버스 전압의 경우엔 두 설정 모두에서 4mV/bit라고 표현되어 있어 전압은 분해능이 더 좋아지지 않는다는 것을 기억하자.
이번에는 간단하게 멀티미터와 측정되는 전류 값을 비교해보자.

LED 하나를 동작하는 회로의 전류를 측정했다.
INA 219 센서는 LCD에 전류값을 표시했고 멀티미터로 측정되는 값과 비교할 수 있게 배치했다.
서로 보면 꽤 비슷하게 전류 값이 측정되는 것을 볼 수 있다.
그럼 다음으론 전류 값을 좀 낮추어보자.

동일한 저항으로 직렬로 하나 추가했다.
전류가 대략 절반으로 줄어들었는데 지금도 꽤 비슷하게 나온다.
한 번더 전류를 줄여보자.

이번엔 저항 3개를 직렬로 연결했다.
전류가 또 줄었고 측정되는 값은 여전히 비슷한 것을 알 수 있다.
이게 정확한 성능 테스트라고 할 순 없겠지만 사실 이 정도만 나와줘도 웬만한 상황에선 사용하기 좋을 것이라고 할 수 있을 것이다.
