1. 16 bit ADC
ADC 는 Analog to Digital Converter 의 약자로서, 입력받는 값에 대해 digital 로 표현해 줍니다.
Arduino 에는 이 ADC 가 장착되어 있어서 analog input 에 입력받은 신호에 대해 digital 로 leveling 을 해서 보여줍니다.
즉, analog 값을 digital 로 변환해서 보여주는 것이죠.
참고로, arduino nano 에는 10 bit ADC 가 장착되어 있어서 10 bit (0 ~ 1023) 값으로 표현해 줍니다.
다 좋은데, 민감한 sensor 를 다룰 때에는, 이 10 bit ADC 가 아쉬울 때가 있습니다.
좀더 정밀한 값을 들여다 보고 싶은데, 값과 값의 사이값을 알수가 없는거죠.
이 때 등장하는 것이 외부 ADC 모듈 입니다.
AliExpress 와 arduino 를 사랑하는 사람들의 blog 를 보니 ADS1115 라는 것을 많이 사용하는 군요.
ADS1115 는 Texas Instruments 사의 chip 을 사용한 16 bit ADC 입니다.
- Resolution: 16 Bits
- Programmable Sample Rate: 8 to 860 Samples/Second
- Power Supply/Logic Levels: 2.0V to 5.5V
- Low Current Consumption: Continuous Mode: Only 150µA Single-Shot Mode: Auto Shut-Down
- Internal Low-Drift Voltage Reference
- Internal Oscillator
- Internal PGA: up to x16
- I2C Interface: 4-Pin-Selectable Addresses
- Four Single-Ended or 2 Differential Inputs
- Programmable Comparator
아래 link 의 제품이 적당해 보이네요. 구매합니다.
* I2C ADS1115 16 Bit ADC 4 channel Module with Programmable Gain Amplifier 2.0V to 5.5V for Arduino RPi
- https://www.aliexpress.com/item/32850495005.html
2. 도착
그간 업무로 정신 없었는데, 어느샌가 도착했습니다.
블로그 내용을 부풀리기 위해서라도 항상 도착샷을 올리는건 필수 입니다.
저렇코롬 생겼구요.
ALERT 와 ADDR 에 pinheader 는 남겨 놓고 납땜하기로 합니다. 그 덕에 2 pinheader 하나 득템.
그 이유는 이 밑에 설명.
3. Addressing
이 ADS1115 는 I2C 통신을 하는데, 하나의 arduino 와 4개까지 연결할 수 있다 보니, I2C 접근 주소가 겹치지 않게 할 수 있습니다.
방법은 ADDR pin 을 어디로 연결하느냐로 address 를 결정할 수 있습니다.
* Adafruit 4-Channel ADC Breakouts
- https://learn.adafruit.com/adafruit-4-channel-adc-breakouts
- 0x48 (1001000) ADR -> GND
- 0x49 (1001001) ADR -> VDD
- 0x4A (1001010) ADR -> SDA
- 0x4B (1001011) ADR -> SCL
회로를 꾸밀 때 마다, address 정의를 위한 연결을 해도 되지만, 귀찮겠죠?
또한, addressing 을 위해 I2C 용 핀이나, VCC 로 연결하면 왠지 껄끄럽습니다.
그래서 ground 로 연결하여, 기본 0x48 을 가지게 합니다.
또한, 아래 새다리님의 블로그를 보면, 이 연결을 가장 깔끔하게 처리하셨더군요. 따라쟁이는 바로 따라해 봅니다.
* 16비트, 4채널 ADC ADS1115 아두이노 Test
- https://m.blog.naver.com/twophase/220801664646
예전에 파손된 멀티탭 전원선에서 동선 한가닥을 짧게 잘라 내어 아래와 같이 납땜 해 주섰습니다.
캡톤 테이프로 혹시 모를 쇼트를 방지했구요.
i2cdetect 로 addressing 이 잘 되었나 확인해 봅니다.
0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
흠흠. 잘 되었네요.
4. Layout
* Arduino ADS1115 Module Getting Started Tutorial
위의 tutorial 사이트에서 보면 ADS1115 를 활용하여, arduino 자체 3.3V 출력을 세밀하게 검증해 보는 소스가 있습니다.
따라쟁이는 당연 따라서 검증해 봅니다.
연결은 I2C 용 연결 2가닥과 VCC/GND 그리고, 입력용에 arduino 3.3V output 을 연결합니다.
ADS1115 | Arduino Nano ------------------------ VCC | 5V GND | GND SCL | A5 SDA | A4 A0 | 3.3V ------------------------
그림으로 그려보면 다음과 같습니다.
5. Sketch
이미 관련한 library 가 나와 있기 때문에, library 를 설치합니다.
역시 God Adafruit. 없는게 없습니다.
ads1115 로 검색하면 나오지 않고, ads1x 로 검색해야 나옵니다.
이제 HENRY'S BENCH 에서 Henry 아저씨가 arduino 3.3V output 에 대해, ADS1115 를 검증해 놓은 소스를 사용해 봅니다.
#include "Wire.h" #include "Adafruit_ADS1015.h" Adafruit_ADS1115 ads(0x48); float Voltage = 0.0; void setup(void) { Serial.begin(9600); ads.begin(); } void loop(void) { int16_t adc0; // we read from the ADC, we have a sixteen bit integer as a result adc0 = ads.readADC_SingleEnded(0); Voltage = (adc0 * 0.1875)/1000; Serial.print("AIN0: "); Serial.print(adc0); Serial.print("\tVoltage: "); Serial.println(Voltage, 7); delay(1000); }
이 소스에서 가장 중요한 것은 PGA (Programmable Gain Amplifier) 값 입니다.
이 ADS1115 의 default output 최대값이 6.144V 이므로, 이를 15 bit (16 bit 이지만, 부호를 표시하는 1 bit 를 빼면 15 bit 만 활용 가능) 인 32767 로 나누면, 출력 1 에 대해 0.1875mV 라는 계산이 나옵니다.
In the default mode, the setting is +/-6.144 volts.
Thus the value of 32767 would represent a value of 6.144 volts.
Dividing 6.144 volts by 32767 yields a scale factor of 0.1875 mV per bit. This is a significant improvement over the Arduino ADC which resolution of approximately 5 mV per bit. In fact, its about 26 times better!
위의 로직이 소스에 활용되었습니다.
6. 결과
지금까지 구성한 layout 과 위의 소스를 가지고 실행해 보면 다음과 같이 결과가 나옵니다.
3.3V 이지만, 미세하게 값이 변하고 있다는 것을 알 수 있습니다.
이게 USB 를 통해서 연결하지 않고 Power source 를 통해서 입력 받으면 좀더 정확하고 잘 변하지 않는 3.3V 를 얻을 수 있다고 해요.
7. 비교
Arduino nano 의 자체 3.3V 를 16 bit ADC 를 거치지 않은 채로, anlogRead (10 bit ADC) 를 하면 어떨까?
참고로 Arduino 의 AnalogReference 의 정의는 다음과 같습니다.
--------------------------------
Arduino AVR Boards (Uno, Mega, Leonardo, etc.)
- DEFAULT: the default analog reference of 5 volts (on 5V Arduino boards) or 3.3 volts (on 3.3V Arduino boards)
- INTERNAL: an built-in reference, equal to 1.1 volts on the ATmega168 or ATmega328P and 2.56 volts on the ATmega32U4 and ATmega8 (not available on the Arduino Mega)
- INTERNAL1V1: a built-in 1.1V reference (Arduino Mega only)
- INTERNAL2V56: a built-in 2.56V reference (Arduino Mega only)
- EXTERNAL: the voltage applied to the AREF pin (0 to 5V only) is used as the reference.
--------------------------------
AnalogReference(DEFAULT) 를 사용하여, 5V 기준으로 입력값을 leveling 하게 했으며,
arduino nano 에는 PGA 가 없으므로, 단순히 5V 를 10 bit ADC 해상도를 감안하여, 1024 로 나누어, 한 level 당, 0.0049 V 로 계산하도록 했습니다.
최종 소스는 다음과 같습니다.
#include "Wire.h" #include "Adafruit_ADS1015.h" Adafruit_ADS1115 ads(0x48); float Voltage = 0.0; float Voltage2 = 0.0; // analogRead(A2) void setup(void) { analogReference(DEFAULT); Serial.begin(9600); ads.begin(); } void loop(void) { int16_t adc0; // we read from the ADC, we have a sixteen bit integer as a result adc0 = ads.readADC_SingleEnded(0); Voltage = (adc0 * 0.1875)/1000; Serial.print("AIN0: "); Serial.print(adc0); Serial.print("\tVoltage: "); Serial.print(Voltage, 7); // analogRead(A2) start int16_t adc2; adc2 = analogRead(A2); Voltage2 = (adc2 * 0.0049); Serial.print("\tAIN2: "); Serial.print(adc2); Serial.print("\tVoltage2: "); Serial.println(Voltage2, 7); // analogRead(A2) end delay(1000); }
결과값은 이렇게 나왔네요. 많이 부정확 합니다.
그 원인으로는,
- 5V reference 전압이 USB 를 통해 공급받으며, USB 전원은 불안하게 공급받습니다.
- PGA 가 없이, 단순히 5V reference 전압을 10 bit 로 나눈 값을 기준값으로 정했습니다.
- 16 bit 하고는 비교도 안되는 10 bit 해상도 차이가 납니다.
ADS1115 16 bit ADC 를 이용한 센서값 입력은 보다 정확한 값을 보장해 주네요.
향후 자주 사용해야 겠습니다.
'Hardware' 카테고리의 다른 글
Hardware | ESP-01 or ESP8266 사용기 - 5 (2) | 2019.08.14 |
---|---|
Hardware | ZP07-MP901 공기질 측정 센서 (0) | 2019.08.13 |
Hardware | Digital Compass - HMC5883L 사용기 - 3 (0) | 2019.08.10 |
Hardware | Arduino 를 DIY 해보자 - 2 (0) | 2019.08.04 |
Hardware | 납땜 주변 용품 (0) | 2019.08.02 |