使用Arduino驅動 ADS1115 ADC採樣芯片
如圖,這是這顆ADC採樣芯片的內部結構圖,能夠看到, 從芯片引腳到芯片內部的ADC模塊,還有幾個部分: MUX,PGA, 這兩個分別叫作多路複用器、和增益放大器, MUX用來切換採樣引腳,而PGA則用來切換測量量程。oop
我參照芯片官方的數據手冊寫出了這個簡易的測試程序,只用到了最基本的IIC的通信, 使用功能也比較有限,高級一些的功能都須要使用基於IIC通信的SMBUS協議, 這個就沒有繼續深究了。測試
#include <Wire.h> const int8_t ADS1115_address = 0x48; enum ADS1115Conf{ AIN0_2AIN1 = 0b000, // << 12, AIN0_2AIN3 = 0b001, // << 12, AIN1_2AIN3 = 0b010, // << 12, AIN2_2AIN3 = 0b011, // << 12, AIN0_2GND = 0b100, // << 12, AIN1_2GND = 0b101, // << 12, AIN2_2GND = 0b110, // << 12, AIN3_2GND = 0b111, // << 12, FSR_6_144V = 0b000, // << 9, FSR_4_096V = 0b001, // << 9, FSR_2_048V = 0b010, // << 9, FSR_1_024V = 0b011, // << 9, FSR_0_512V = 0b100, // << 9, FSR_0_256V = 0b101, // << 9, CONTINU_CONV = 0, //<<8 SINGLE_SHOT = 1, SPS_8 = 0b000, // << 5, SPS_16 = 0b001, // << 5, SPS_32 = 0b010, // << 5, SPS_64 = 0b011, // << 5, SPS_128 = 0b100, // << 5, SPS_250 = 0b101, // << 5, SPS_475 = 0b110, // << 5, SPS_860 = 0b111, // << 5, }typedef ADS1115Conf; /** * [ADS1115Configure description] * @Author 葉鵬程 * @DateTime 2019-08-19T20:44:30+0800 * @discrption : 芯片初始化配置 * * @param mux [輸入通道配置] * @param pga [量程設置] * @param mode [單次或持續轉換模式] * @param dr [採樣速率設置] */ void ADS1115Configure(ADS1115Conf mux, ADS1115Conf pga, ADS1115Conf mode, ADS1115Conf dr){ uint16_t conf; Wire.beginTransmission(ADS1115_address); Wire.write(0x01); //set Address Pointer Register as conf Register Wire.endTransmission(); /*read chip's conf register data */ Wire.requestFrom(ADS1115_address, 2); conf = 0; conf = Wire.read(); conf = conf<<8; conf |= Wire.read(); /*change it*/ conf = 0x8000; conf &= (~(0x0007<< 12)); conf |= mux << 12; conf &= (~(0x0007<< 9 )); conf |= pga << 9; conf &= (~(0x0007<< 8 )); conf |= mode << 8; conf &= (~(0x0007<< 5 )); conf |= dr << 5; // conf = 0xf483; /* trans back*/ Wire.beginTransmission(ADS1115_address); Wire.write(0x01); //set Address Pointer Register as conf Register Wire.write(uint8_t(conf>>8)); //conf MSB Wire.write(uint8_t(conf)); //conf LSB Wire.endTransmission(); /**/ Wire.beginTransmission(ADS1115_address); Wire.write(0x00); //set Address Pointer Register as conf Register Wire.endTransmission(); } /** * [ADS1115SetChannel description] * @Author 葉鵬程 * @DateTime 2019-08-19T20:43:57+0800 * @discrption :芯片輸入通道設置 * * @param mux [description] */ void ADS1115SetChannel(ADS1115Conf mux){ uint16_t conf; Wire.beginTransmission(ADS1115_address); Wire.write(0x01); //set Address Pointer Register as conf Register Wire.endTransmission(); /*read chip's conf register data */ Wire.requestFrom(ADS1115_address, 2); conf = 0; conf = Wire.read(); conf = conf<<8; conf |= Wire.read(); /*change it*/ conf = conf & (~(0x0007<< 12)); conf |= mux << 12; /* trans back*/ Wire.beginTransmission(ADS1115_address); Wire.write(0x01); //set Address Pointer Register as conf Register Wire.write(uint8_t(conf>>8)); //conf MSB Wire.write(uint8_t(conf)); //conf LSB Wire.endTransmission(); /**/ Wire.beginTransmission(ADS1115_address); Wire.write(0x00); //set Address Pointer Register as conf Register Wire.endTransmission(); } int16_t ADS1115ReadResult(void){ int16_t ret; Wire.requestFrom(ADS1115_address, 2); ret = 0; ret = Wire.read(); ret = ret<<8; ret |= Wire.read(); return ret; } void setup() { // put your setup code here, to run once: Wire.begin(); Serial.begin(115200); while (!Serial); // Leonardo: wait for serial monitor Serial.println("Arduino Running!"); Serial.println("configing ADS1115."); delay(200); ADS1115Configure(AIN3_2GND, FSR_6_144V, CONTINU_CONV, SPS_250); Serial.println("configed."); Wire.beginTransmission(ADS1115_address); Wire.write(0x00); //set Address Pointer Register as conv Register Wire.write(0x00); Wire.write(0x00); Wire.endTransmission(); } void loop() { int16_t adc_result; double v; Serial.print("adc conversion result: "); ADS1115SetChannel(AIN0_2GND); delay(10); adc_result = ADS1115ReadResult(); v = adc_result * 6.144 / 0x7fff; Serial.print("\tA0: "); Serial.print(v); Serial.print('V'); ADS1115SetChannel(AIN1_2GND); delay(10); adc_result = ADS1115ReadResult(); v = adc_result * 6.144 / 0x7fff; Serial.print("\tA1: "); Serial.print(v); Serial.print('V'); ADS1115SetChannel(AIN2_2GND); delay(10); adc_result = ADS1115ReadResult(); v = adc_result * 6.144 / 0x7fff; Serial.print("\tA2: "); Serial.print(v); Serial.print('V'); ADS1115SetChannel(AIN3_2GND); delay(10); adc_result = ADS1115ReadResult(); v = adc_result * 6.144 / 0x7fff; Serial.print("\tA3: "); Serial.print(v); Serial.print('V'); Serial.println(); delay(100); // put your main code here, to run repeatedly: }