АЦП ADS1015 и измерение силы тока

forfrends
Offline
Зарегистрирован: 24.02.2015
Всем привет!
Делаю автономное устройство на базе ESP8266. Работать оно будет от аккумулятора 18650 и заряжаться от солнечной панели через схему заряда TP5000. Мне нужно измерять напряжение на аккумуляторе, напряжение на солнечной панели, а также ток заряда аккумулятора и ток разряда. Для этих целей решил использовать внешний АЦП ADS1015, так как у ESP8266 не достаточно аналоговых входов.
 
Как правильно организовать схему? В режиме дифференциального измерения ADS1015 использует 2 аналоговых входа. То есть получается А0 и А1 для измерения падения напряжения на шунте от солнечной панели и А2, А3 - на шунте "разряда" аккумулятора. При этом А1 и А2 соединены вместе в точке соединения шунтов и аккумулятора. То есть, вот так:
Может это неправильная схема подключения, я не знаю, прошу вашего совета. Может лучше поставить шунты в разрыв цепи GND?
 
У меня возникло несколько вопросов:
1) возможно ли использовать не 4 аналоговых входа, а 3? Ведь 1-й и 2-й все равно соединены вместе. Тогда останется один свободный Аналоговый вход для измерения напряжения на солнечной панели. То есть, вот так:
 
2) возможно ли одновременно (или поочередно) измерять и напряжение на аккумуляторе? То есть, сначала Аналоговыми входами А0 и А1 измерить падение напряжения на шунте, а потом через А1 измерить напряжение на аккумуляторе?
 
3) Достаточно ли разрядности ADS1015 для измерения падения напряжения на шунте? Или нужно использовать ОУ?
 
4) Какого номинала шунты лучше всего использовать? У меня есть на 0,033 Ом, с ноутбучных аккумуляторов могу достать других номиналов: R02, 005, 0075 и др. Или лучше по-больше поставить? На пример на 1 Ом?
forfrends
Offline
Зарегистрирован: 24.02.2015
Почитал более внимательно даташит: The ADS1015 contains an input multiplexer (MUX), as shown in Figure 10. Either four single-ended or two
differential signals can be measured. Additionally, AIN0 and AIN1 may be measured differentially to AIN3.
То есть можно для измерений в дифференциальном режиме использовать 3 вывода: А0, А1 и А3. А3 должен быть средним. Проверил, работает!
Так же проверил возможность переключения режимов работы пина А3 между дифференциальным измерением и одиночным - тоже все работает!
 
#include <Wire.h>
#include <Adafruit_ADS1015.h>
Adafruit_ADS1015 ads;     /* Use thi for the 12-bit version */

void setup(void)
{
  Serial.begin(9600);
  Serial.println("Hello!");
  
  Serial.println("Getting differential reading from AIN0 (P) and AIN1 (N)");
  Serial.println("ADC Range: +/- 6.144V (1 bit = 3mV/ADS1015, 0.1875mV/ADS1115)");
  
  // The ADC input range (or gain) can be changed via the following
  // functions, but be careful never to exceed VDD +0.3V max, or to
  // exceed the upper and lower limits if you adjust the input range!
  // Setting these values incorrectly may destroy your ADC!
  //                                                                ADS1015  ADS1115
  //                                                                -------  -------
  // ads.setGain(GAIN_TWOTHIRDS);  // 2/3x gain +/- 6.144V  1 bit = 3mV      0.1875mV (default)
  // ads.setGain(GAIN_ONE);        // 1x gain   +/- 4.096V  1 bit = 2mV      0.125mV
  // ads.setGain(GAIN_TWO);        // 2x gain   +/- 2.048V  1 bit = 1mV      0.0625mV
  // ads.setGain(GAIN_FOUR);       // 4x gain   +/- 1.024V  1 bit = 0.5mV    0.03125mV
  // ads.setGain(GAIN_EIGHT);      // 8x gain   +/- 0.512V  1 bit = 0.25mV   0.015625mV
  // ads.setGain(GAIN_SIXTEEN);    // 16x gain  +/- 0.256V  1 bit = 0.125mV  0.0078125mV
  
  ads.begin();
}

void loop(void)
{
  int16_t results;
  float   multiplier = 3.0F;    /* ADS1015 @ +/- 6.144V gain (12-bit results) */

  results = ads.readADC_Differential_0_3();  
  Serial.print("Differential 0-3: "); Serial.print(results); Serial.print("("); Serial.print(results * multiplier); Serial.println("mV)");
  
  results = ads.readADC_Differential_1_3();    
  Serial.print("Differential 1-3: "); Serial.print(results); Serial.print("("); Serial.print(results * multiplier); Serial.println("mV)");

  int16_t adc0, adc1;   //, adc2, adc3;
  adc0 = ads.readADC_SingleEnded(3);
  Serial.print("AIN3: "); Serial.print(adc0); Serial.print(" Voltage: "); Serial.println(float((adc0*3)/1000.0)); 
  adc0 = ads.readADC_SingleEnded(2);
  Serial.print("AIN2: "); Serial.print(adc0); Serial.print(" Voltage: "); Serial.println(float((adc0*3)/1000.0)); 
  Serial.println();

  delay(1000);
}

 

 

nik182
Offline
Зарегистрирован: 04.05.2015

Расставьте + и - питания по схеме и нарисуйте провода питания ESP, ADS. Сразу всё станет не так хорошо. У ADS есть ограничения по входному напряжению.  

forfrends
Offline
Зарегистрирован: 24.02.2015

То есть, то что я проверил и это работает, то это не играет роли? :)))))

И делителями напряжения я тоже умею пользоваться ;)

А вот так выглядит схема, вместе со всеми делителями (уровень усиления АЦП нужно ставить: ads.setGain(GAIN_FOUR);       // 4x gain   +/- 1.024V  1 bit = 0.5mV    0.03125mV):

nik182
Offline
Зарегистрирован: 04.05.2015

Если GND TP5000 и земля это один провод, то всё нормально. Я б ещё R16-R17 и R14-R15 перевернул, что бы сигнал тока был больше. Иначе при разбросе этих резисторов будет сигнал при отсутствии тока. Vcc c батареи?

forfrends
Offline
Зарегистрирован: 24.02.2015

Да, GND и земля соединены вместе. VCC - со стабилизатора на 3.3 вольта (с батареи). Делители сделаны именно так чтобы входное напряжение не превышало 1 вольт. Это ограничение усилителя АЦП:

ads.setGain(GAIN_FOUR);       // 4x gain   +/- 1.024V  1 bit = 0.5mV    0.03125mV

при этой настройке максимальное входное напряжение - 1,024 вольта, и 1 бит = 0,5 милливольт. Это позволить более точно измерять токи.

nik182
Offline
Зарегистрирован: 04.05.2015

Ограничение усилителя 6.144 В. Это максимальное значение на выходе усилителя внутри (!) АЦП. На любом входе может быть напряжение от 0-0.5V до Vcc+0.5V. Соответственно максимальное напряжение на диф. входе усилителя АЦП 6.144/Ку. Если Вы измеряете ток, то в дифф режиме между ногами в выбранном Вами режиме должно быть не более 1.024 вольта. Напряжение относительно земли может быть любым в пределах от 0-0.5V до Vcc+0.5V.  Это напряжение (1.024 вольта) в вашей схеме будет при 6 амперах через шунт 1.   

forfrends
Offline
Зарегистрирован: 24.02.2015

Так, после ваших слов у меня в голове каша...

Мне не все понятно из того что написано в даташите, а в тех примерах что я смотрел входное напряжение всегда подстраивали под уровень усилителя (в моем случае это 1.024 вольта). В тому же в самих примерах библиотек написано:

The ADC input range (or gain) can be changed via the following functions, but be careful never to exceed VDD +0.3V max, or to exceed the upper and lower limits if you adjust the input range! Setting these values incorrectly may destroy your ADC!

То есть не только нельзя превышать VDD +0.3V, но и уровни установленные усилителем.

Из даташита:

FSR Full-scale input voltage range(2) (VIN = V(AINP) – V(AINN))  от   ±0.256     до       ±6.144 V

(2) This parameter expresses the full-scale range of the ADC scaling. No more than VDD + 0.3 V must be applied to the analog inputs of the device. See Table 1 more information. (Этот параметр выражает полномасштабный диапазон масштабирования АЦП. На аналоговые входы устройства должно подаваться не более VDD + 0,3 В. Смотрите Таблицу 1 для дополнительной информации.)

Таблица:

The FSR of the ADS1013 is fixed at ±2.048 V.
Analog input voltages must never exceed the analog input voltage limits given in the Absolute Maximum Ratings. If a VDD supply voltage greater than 4 V is used, the ±6.144 V full-scale range allows input voltages to extend up to the supply. Although in this case (or whenever the supply voltage is less than the full-scale range, a full-scale ADC output code cannot be obtained. For example, with VDD = 3.3 V and FSR = ±4.096 V, only signals up to VIN = ±3.3 V can be measured. The code range that represents voltages |VIN| > 3.3 V is not used in this case.
 
В общем это все у меня никак не складывается в одну картину. Если:
входное напряжениеVDD + 0,3 В
или
VIN = V(AINP) – V(AINN) (разница между двумя пинами)
То тогда причем здесь эта таблица? Хотя в даташите прямо написано: Этот параметр выражает полномасштабный диапазон масштабирования АЦП. На аналоговые входы устройства должно подаваться не более VDD + 0,3 В. Смотрите Таблицу 1 для дополнительной информации.
А в таблица приведена выше, и в ней указаны пределы измерений...
nik182
Offline
Зарегистрирован: 04.05.2015

Это то же самое, что я написал. АЦП может измерить +- 6 вольт, но если столько подать, оно может сгореть. Поэтому надо выбрать напряжения на входах так, что при любых колебаниях они не выходили за 0-0.5V до Vcc+0.5V. А если поставить Ку большой, то возможна ситуация, когда внутри АЦП будет ограничение по превышению напряжения и результат оцифровки будет неправильный = потерян. К аварии это не приведёт.

forfrends
Offline
Зарегистрирован: 24.02.2015

Попробую как-то упорядочить все. Если я правильно понял то на вход можно подавать "любое" напряжение (в пределах VDD + 0,3 В) не зависимо от уровня усилителя.

Как тогда правильно подобрать усилитель? Если рассмотреть схему выше, но без делителей напряжения. Настройки усилителя стояли "по умолчанию":

ads.setGain(GAIN_TWOTHIRDS);  // 2/3x gain +/- 6.144V  1 bit = 3mV      0.1875mV (default)

Питание 5 вольт. При этом 1 бит был равен 3 милливольтам, а это не очень точно. Я тестировал на токе потребления обычного светодиода. Мультиметр показал ток 24,4 мА, АЦП выдавал 9 бит, то есть 27 мА потому что 0.4 ма - это уже следующий бит... Для увеличения точности я хочу использовать эту настройку:

ads.setGain(GAIN_FOUR);       // 4x gain   +/- 1.024V  1 bit = 0.5mV

где 1 бит будет равен 0,5 милливольт. Но при этом предел измерения +- 1.024V.

Вот как правильно это настроить? Как эти 1.024V относятся к VDD? Питание будет от 3.3 вольт. Аккумулятор может иметь максимум 4,25 вольт, солнечная панель максимум 7,3 вольт, шунты в расчет беру на 1 Ом... Если в дифференциальном режиме разница между двумя Аналоговыми входами на шунте будет минимальной, и значение напряжения будет входить в 1.024V, то нужно всего лишь входное напряжение делителями опустить до VDD? Это пины А0, А1 и А3. Как теперь правильно измерить напряжение на А3 который подключен к аккумулятору (при этом делитель напряжения стоит на 3.3 вольта, и Ку до 1,024V)? 

nik182
Offline
Зарегистрирован: 04.05.2015

С точностью вопрос решается подбором параметров. Если выбрано напряжение питания АЦП 3.3 вольта, то мы должны не превышать это напряжение на входах АЦП. С делителями напряжения всё просто. Берём 2.048 для настройки, делаем делители так, что бы при максимальном напряжении на входом и выходном делителе напряжение на входе АЦП было около 2 вольт. Получим измерение напряжений с точностью 1mV * Кд . Лучше не получится в данной схеме. Кстати. У меня солнечная панель дает до 12 вольт на солнце при заявленных 7.

С током сложнее. На резисторах шунта будет падение напряжения, которое желательно минимизировать для уменьшения потерь. Поэтому здесь выбираем дифф режим с максимальной чувствительностью 0.256 mV. Делители около шунтов уже определены в первом пункте по условию измерения напряжения. Кд у них около 2. Т.е. При максимальном токе падение напряжение на шунте будет 0.512 В . Соответственно сопротивление шунта 0.512/Imax . Как по мне это очень много. Но это условие максимальной точности. Ставить шунт с меньшим сопротивлением - уменьшать точность. Альтернатива - добавить м.с. из серии ina12X. 

1.024 к Vdd никак не относится. Это максимальное цифруемое напряжение в выбранном режиме 1.024 V при котором АЦП выдает максимальный код. Тот же код выдаст АЦП при подаче на вход 0.256 вольта в режиме 0.256.  В режиме 4.096 этот код АЦП выдать не сможет, т.к. больше 3.3 вольта на вход подать не получится.     

 

forfrends
Offline
Зарегистрирован: 24.02.2015

Продолжу тему.

Столкнулся небольшой трудностью. Я пытаюсь измерить ток при помощи шунта, пины А1 и А3 в дифференциальном режиме. Измеряю через делители напряжения, так как земля у ADS1015 и потребителя общая, ADS1015 питается от 3.3 вольт, а на шунте напряжение может подыматься до 4-х вольт. Делители вносят некоторую ошибку в точность измерений, но мне это не критично.

Проблема в том что потребление тока крайне не статично. Напряжение на шунте (1 Ом) прыгает 20-110 милливольт, и выглядит как синусоида с меняющейся частотой 7-50 КГц и размахом в 50 милливольт... Обычный мультиметр показывает силу тока 60-110 мА. А вот ADS1015 сходит с ума и показывает всего 35-40 мА. Я поставил элертролит на 10 мкф. на аналоговый вход, это немного уменьшило размах синусоиды и показания поднялись примерно до 70 мА. Что еще можно сделать для получения более точных показаний?

kez63
kez63 аватар
Offline
Зарегистрирован: 09.04.2013

Как  схема ? Оправдала задумки? Как по времени стабильность ?

Можно повторять ?

MASHUKOV.ANTON
Offline
Зарегистрирован: 20.01.2021

Эту схему делал и я в погодной станции именно оттуда автор выдернул эту схему, используя АЦП1015 погрешности в вычислениях будут минимальны. Для более точного получения данных нужно использовать АЦП1115 т.к оно более точно определяет показания примерно до 0.0000, а так как автор данной статьи взял эту схему у другого автора и не разобравшись во всем просил ответа здесь, поэтому и гусей за 7 лет не собрали. Но если вам не критичны разбеги 50-110млвольт то смело берите АЦП1015 и данную схему она полностью рабочая.