Страница 1 из 2

ADS1115

Добавлено: 02 сен 2023, 13:25
Rovki
Столкнулся с несоответствием нумерации аналоговых входов. Проверил даташит и разводку платы - все правильно.
Плата https://aliexpress.ru/item/32817162654. ... 4aa6ZJhYEo
проект-
проект.jpg
схема-
схема ацп.jpg
а вот результат-
результат.jpg
Это передача на панель по модбасу. Пробовал и в уарт передавать - результат тот же .
Пробовал штатный блок и от экойнса - результат тот же .
У кого такой же результат? :smile453:

ADS1115

Добавлено: 02 сен 2023, 19:09
nic103
Испытывал подобный девайс но косяка не заметил. Хотел миллиамперметр запилить но падение на шунте 0,1 ом оказалось маловато. Заказал MAX4372TEUK ( Усилители считывания тока) жду, буду дальше экспериментировать. На неделе перепроверю ADS1115, отпишусь.

ADS1115

Добавлено: 02 сен 2023, 19:19
ivansidor012
Rovki писал(а): 02 сен 2023, 13:25 Плата https://aliexpress.ru/item/32817162654. ... 4aa6ZJhYEo

если почитать отзывы, то там фуфло перемаркированное:

Модуль получен упакованным в запаянном электростатическом пакете. Но на плате вместо ADS1115 (официальная маркировка BOGI) установлен какой-то китайский чип с маркировкой ADX111A. В сети о нем данных нет! Подключил этот модуль к тестовой Ардуине - вроде показывает правильно при работе с библиотекой Adafruit_ADS1X15 - задействованы все 16 бит. Отмечен в 2 раза больший шум по сравнению с оригиналом. Походу китайцы и ADS1115 научились как-то импортозамещать

ADS1115

Добавлено: 02 сен 2023, 20:36
Александр
Rovki писал(а): 02 сен 2023, 13:25 Столкнулся с несоответствием нумерации аналоговых входов. Проверил даташит и разводку платы - все правильно.
Настройте блок на получение значения только! одного канала, другие выключите - предполагаю(судя по даташиту и библиотеке), что получите правильные данные. Иначе какая-то дичь...

ADS1115

Добавлено: 02 сен 2023, 20:56
Rovki
Александр писал(а): 02 сен 2023, 20:36
Rovki писал(а): 02 сен 2023, 13:25 Столкнулся с несоответствием нумерации аналоговых входов. Проверил даташит и разводку платы - все правильно.
Настройте блок на получение значения только! одного канала, другие выключите - предполагаю(судя по даташиту и библиотеке), что получите правильные данные. Иначе какая-то дичь...
мне нужно получать данные с 16 каналов (4 ADS)

Отправлено спустя 44 секунды:
ivansidor012 писал(а): 02 сен 2023, 19:19
Rovki писал(а): 02 сен 2023, 13:25 Плата https://aliexpress.ru/item/32817162654. ... 4aa6ZJhYEo

если почитать отзывы, то там фуфло перемаркированное:

Модуль получен упакованным в запаянном электростатическом пакете. Но на плате вместо ADS1115 (официальная маркировка BOGI) установлен какой-то китайский чип с маркировкой ADX111A. В сети о нем данных нет! Подключил этот модуль к тестовой Ардуине - вроде показывает правильно при работе с библиотекой Adafruit_ADS1X15 - задействованы все 16 бит. Отмечен в 2 раза больший шум по сравнению с оригиналом. Походу китайцы и ADS1115 научились как-то импортозамещать
есть данные https://datasheet.lcsc.com/lcsc/2302211 ... 359372.pdf
там все аналогично с ads1115

Отправлено спустя 6 минут 34 секунды:
Похоже тут найдена причина (библиотека) и решение .Почему то зависит от процессора (быстродействие его), из-за буферизации в ADS :smile37: .У меня ЕСП32
https://forums.adafruit.com/viewtopic.php?t=137450

ADS1115

Добавлено: 02 сен 2023, 21:48
Александр
Rovki писал(а): 02 сен 2023, 20:56 мне нужно получать данные с 16 каналов (4 ADS)
Речь шла об эксперименте.
Rovki писал(а): 02 сен 2023, 20:56 Похоже тут найдена причина (библиотека) и решение .Почему то зависит от процессора (быстродействие его), из-за буферизации в ADS .У меня ЕСП32
Как я и предполагал, проблема в библиотеке.
У микросхемы один регистр данных, и считывать его нужно после окончания преобразования. Когда Вы будете считывать только одним канал, проблемы не будет с адресом входа, т.к. запрос и считывание будет по одному входу. Подход, желателен, как у 18B20 - отправили запрос, спустя время, гарантированно большее времени преобразования, считали и отправили новый адрес канала. ИМХО.

ADS1115

Добавлено: 02 сен 2023, 21:57
Rovki
Только как узнать ,что преобразование окончено ? Тем более мне нужна скорость опроса 200гц. :smile453:

Отправлено спустя 6 минут 34 секунды:
а закономерность видна четко- всегда читаются данные с прошлого канала 0-3,1-0,2-1,3-2 и так по кругу.. :smile427:

ADS1115

Добавлено: 02 сен 2023, 21:58
Александр
Вариантов несколько, но под Ваши требования подходит несколько - работа на 400 и опрос регистра готовности или использование выхода 1115:
Еще одной полезной функцией компаратора является оповещение по окончании преобразования, для включения которого необходимо установить старший бит регистра Hi_thresh в 1, а старший бит регистра Lo_thresh в 0. В этом случае бит активного уровня COMP_POL, а также бит управления компаратором COMP_QUE продолжают действовать, биты COMP_MODE и COMP_LAT не влияют на выход компаратора.

Если функция оповещения включена, то в режиме непрерывного преобразования, после окончания каждого измерения на выходе компаратора появляется импульс длительностью 8 мкс. В режиме одиночного преобразования на выходе компаратора устанавливается низкий логический уровень по окончании преобразования, если бит COMP_POL установлен в 0. Тем самым эту функцию удобно использовать в качестве прерывания для управляющего устройства, чтобы не опрашивать постоянно бит OS, а сразу считывать результат преобразования.
Rovki писал(а): 02 сен 2023, 21:57 а закономерность видна четко- всегда читаются данные с прошлого канала 0-3,1-0,2-1,3-2 и так по кругу..
С одним каналом будет ок.

ADS1115

Добавлено: 02 сен 2023, 22:04
Rovki
Там очень много модификаций ads - разные скорости преобразования , на чипе надпись не разобрать

Отправлено спустя 4 минуты 13 секунд:
А как задать (узнать) частоту опроса ? (Программируемая частота образцов: от 8 до 860 образцов/сек)

Отправлено спустя 1 минуту 30 секунд:
Александр писал(а): 02 сен 2023, 21:58 Вариантов несколько, но под Ваши требования подходит несколько - работа на 400 и опрос регистра готовности или использование выхода 1115:
Еще одной полезной функцией компаратора является оповещение по окончании преобразования, для включения которого необходимо установить старший бит регистра Hi_thresh в 1, а старший бит регистра Lo_thresh в 0. В этом случае бит активного уровня COMP_POL, а также бит управления компаратором COMP_QUE продолжают действовать, биты COMP_MODE и COMP_LAT не влияют на выход компаратора.

Если функция оповещения включена, то в режиме непрерывного преобразования, после окончания каждого измерения на выходе компаратора появляется импульс длительностью 8 мкс. В режиме одиночного преобразования на выходе компаратора устанавливается низкий логический уровень по окончании преобразования, если бит COMP_POL установлен в 0. Тем самым эту функцию удобно использовать в качестве прерывания для управляющего устройства, чтобы не опрашивать постоянно бит OS, а сразу считывать результат преобразования.
Rovki писал(а): 02 сен 2023, 21:57 а закономерность видна четко- всегда читаются данные с прошлого канала 0-3,1-0,2-1,3-2 и так по кругу..
С одним каналом будет ок.
Для одного канала я бы использовал АЦП ЕСП32

ADS1115

Добавлено: 02 сен 2023, 22:29
Александр
Rovki писал(а): 02 сен 2023, 20:56 мне нужно получать данные с 16 каналов (4 ADS)
Rovki писал(а): 02 сен 2023, 21:57 Тем более мне нужна скорость опроса 200гц.
Блок с использованием вывода ADS ALERT/RDY должен быть примерно таким:
один раз: настраиваются конф. регистры, разрешается работа по n каналу прерывания, отправляется запрос на считывание канала - запоминается адрес(индекс).
далее по прерыванию:
считываются данные в массив по индексу, при этом мс выключит сигнал окончания преобразования, адрес(индекс) увеличивается, отправляется новый запрос.
Для опроса след. мс после окончания предыдущей, обработка прерывания на одном входе отключаются, на другом вкл.
Остальное по ходу.
Но конкретно в Вашем случае, много каналов, я бы обратил внимание на работу с микросхемами, работающими по SPI, существенно быстрей и проще.
Главный вопрос - разрядность и частота обновления, есть ещё stm32 с двумя 12 бит ацп.

ADS1115

Добавлено: 03 сен 2023, 07:10
Rovki
Только где взять такой блок? :smile427:

Отправлено спустя 2 минуты 47 секунд:
Скорости работы интерфейса I2C (100/400) более чем достаточно .Все определяется быстродействием самого АЦП :smile37:. Использую 4х4 АЦП

Отправлено спустя 5 минут 5 секунд:
На всякий случай заказал и такие https://aliexpress.ru/item/400075184832 ... 7122621001
8 каналов по 24 бита разрядность

ADS1115

Добавлено: 03 сен 2023, 14:11
Александр
Rovki писал(а): 03 сен 2023, 07:10 Скорости работы интерфейса I2C (100/400) более чем достаточно .Все определяется быстродействием самого АЦП . Использую 4х4 АЦП
Примем алгоритм следующего формата для четырёх мс -
считываем данные предыдущего запроса мс1;
отправка данных для следующего канала мс1;
считываем данные предыдущего запроса мс2;
отправка данных для следующего канала мс2;
и т.д.
Рассчитаем время, ориентировочно, на один канал: пять байт на считывание + четыре байта на запись = 9 байт.
При 100к 9 байт займут примерно, округлим, 1мс.
Соответственно, спустя "круг" в мс 1115 будут уже готовые данные при Data rate 860SPS, беспокоится не о чем.
Но, при 1 мс мы получим на все каналы 1000SPS - соответственно, о 16 каналах и 200"Гц" говорить не приходится.
Увеличив до 400k - будет, возможно, но на пределе.
Это так, рассуждения выходного дня...

ADS1115

Добавлено: 03 сен 2023, 14:36
Rovki
Может не точно выразился, меня не заботит задержка получения данных. Через 5 мс получим данные с одного АЦП ( 4 канала) , через ещё 5 со второго, итд.. Тогда на 4ацп будет 20мс ... Пойдёт. Мне достаточно снимать с переменных резисторов 1000 значений на канал за время 10 сек. И так по 16 каналам пусть с задержкой ... Это для испытательного стенда подстроечных резисторов. На каждый резистор 2 канала. Один мерит и расчитывает номинал, второй снимает характеристику при вращении.

ADS1115

Добавлено: 03 сен 2023, 15:30
ivansidor012
[ref=#ff8000]Rovki[/ref],
Александр писал(а): 03 сен 2023, 14:11 соответственно, о 16 каналах и 200"Гц" говорить не приходится
Rovki писал(а): 03 сен 2023, 15:30 Скорости работы интерфейса I2C (100/400) более чем достаточно
останется только библиотеку переписать - вопрос кто возьмется и во сколько обойдется

ADS1115

Добавлено: 03 сен 2023, 16:23
Rovki
Для знающих час работы :smile225:

Отправлено спустя 3 минуты 57 секунд:
Есть биб-ки для работы по прерываниям
https://github.com/GolinskiyKonstantin/ ... /README.md

ADS1115

Добавлено: 03 сен 2023, 18:03
Александр
Rovki писал(а): 03 сен 2023, 16:23 Для знающих час работы
Немного было времени на даче, код никак не тестировался, вообще, возможны недочёты!

Код: Выделить всё

#include <Wire.h>
uint16_t config_1115 = 0xC3E3;  // первичная конфигурация, AI-0, 4,096 В

void setup(){         
  Wire.begin();         
  for(int16_t a=0; a<4; a++){ // Первичная инициализация, не обязательна.
    Wire.beginTransmission(0x48 | a);
    Wire.write(0x01);
    Wire.write((uint8_t)(config_1115 >> 8));
    Wire.write((uint8_t)(config_1115 & 0xFF));
    Wire.endTransmission();
  }
}
void loop(){

  int16_t data_array[16]; // данные без конверсии, чистые данные АЦП, 1 = 0,000125v, 
  // конвертировать во float (real) перед непосредственным использованием
  int16_t adr1115;
  int16_t chanel1115;
  // цикл для 100k
  for (int16_t i=0; i<16; i++){
    adr1115 = 0x48 | (i & 0x03);  // готовим адрес
    // читаем данные из предыдущего запроса
    Wire.beginTransmission(adr1115);
    Wire.write(0x00);
    Wire.endTransmission();
    Wire.requestFrom(adr1115, 2);
    data_array[i] =  (Wire.read() << 8) | Wire.read(); // данные без конверсии!!!
    // даём команду на следующее преобразование, изменив номер канала в конф. регистре
    chanel1115 = (i>>2 + 1) & 0x03;
    config_1115 = 0xC3E3 | chanel1115 << 12;
    Wire.beginTransmission(adr1115);
    Wire.write(0x01);
    Wire.write((uint8_t)(config_1115 >> 8));
    Wire.write((uint8_t)(config_1115 & 0xFF));
    Wire.endTransmission();   
  }

}

ADS1115

Добавлено: 03 сен 2023, 20:34
Rovki
Спасибо, Александр. Попробую, отпишусь :smile9:

Отправлено спустя 12 минут 34 секунды:
[ref]Александр[/ref], ,будьте добры, добавьте вывод на монитор значений каналов 1-4 (номер канала+ значение). Компиляция проходит без ошибок

ADS1115

Добавлено: 03 сен 2023, 21:08
Александр
[ref=#ff8000]Rovki[/ref], Какие каналы, с какой мс/адреса. Код для 16 каналов, 4х4.

ADS1115

Добавлено: 03 сен 2023, 21:22
Rovki
Александр писал(а): 03 сен 2023, 21:08 [ref=#ff8000]Rovki[/ref], Какие каналы, с какой мс/адреса. Код для 16 каналов, 4х4.
Для одной ADS(4 канала-А0, А1,А2,А3), адрес 48. Что бы проверить код визуально
Подключить можно только 4 ADS (48,49,50,51)

Отправлено спустя 8 минут 27 секунд:
Вот код работает правильно со штатной библиотекой
#include <Adafruit_ADS1X15.h>

Adafruit_ADS1115 ads; /* Use this for the 16-bit version */
//Adafruit_ADS1015 ads; /* Use this for the 12-bit version */

void setup(void)
{
Serial.begin(115200);
Serial.println("Hello!");

Serial.println("Getting single-ended readings from AIN0..3");
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

if (!ads.begin()) {
Serial.println("Failed to initialize ADS.");
while (1);
}
}

void loop(void)
{
int16_t adc0, adc1, adc2, adc3;
float volts0, volts1, volts2, volts3;

adc0 = ads.readADC_SingleEnded(0);
adc1 = ads.readADC_SingleEnded(1);
adc2 = ads.readADC_SingleEnded(2);
adc3 = ads.readADC_SingleEnded(3);

volts0 = ads.computeVolts(adc0);
volts1 = ads.computeVolts(adc1);
volts2 = ads.computeVolts(adc2);
volts3 = ads.computeVolts(adc3);

Serial.println("-----------------------------------------------------------");
Serial.print("AIN0: "); Serial.print(adc0); Serial.print(" "); Serial.print(volts0); Serial.println("V");
Serial.print("AIN1: "); Serial.print(adc1); Serial.print(" "); Serial.print(volts1); Serial.println("V");
Serial.print("AIN2: "); Serial.print(adc2); Serial.print(" "); Serial.print(volts2); Serial.println("V");
Serial.print("AIN3: "); Serial.print(adc3); Serial.print(" "); Serial.print(volts3); Serial.println("V");

delay(1);
}

ADS1115

Добавлено: 03 сен 2023, 21:24
Александр

Код: Выделить всё



#include <Wire.h>
uint16_t config_1115 = 0xC3E3;  // первичная конфигурация, AI-0, 4,096 В

void setup(){         
  Wire.begin();         
  for(int16_t a=0; a<4; a++){ // Первичная инициализация, не обязательна.
    Wire.beginTransmission(0x48 | a);
    Wire.write(0x01);
    Wire.write((uint8_t)(config_1115 >> 8));
    Wire.write((uint8_t)(config_1115 & 0xFF));
    Wire.endTransmission();
  }
  Serial.begin(38400);
}
void loop(){

  int16_t data_array[16]; // данные без конверсии, чистые данные АЦП
  int16_t adr1115;
  int16_t chanel1115;
  // цикл для 100k
  for (int16_t i=0; i<16; i++){
    adr1115 = 0x48 | (i & 0x03);  // готовим адрес
    // читаем данные из предыдущего запроса
    Wire.beginTransmission(adr1115);
    Wire.write(0x00);
    Wire.endTransmission();
    Wire.requestFrom(adr1115, 2);
    data_array[i] =  (Wire.read() << 8) | Wire.read(); // данные без конверсии!!!
    // даём команду на следующее преобразование, изменив номер канала в конф. регистре
    chanel1115 = (i>>2 + 1) & 0x03;
    config_1115 = 0xC3E3 | chanel1115 << 12;
    Wire.beginTransmission(adr1115);
    Wire.write(0x01);
    Wire.write((uint8_t)(config_1115 >> 8));
    Wire.write((uint8_t)(config_1115 & 0xFF));
    Wire.endTransmission();   
  }
  for( int16_t s=0; s<4; s++){
	Serial.println("Chanel " + String(s*4) + " = " + String(float(data_array[s*4] * 0,000125),6));	// *4 для данных из 1 мс
  }
  // delay(500);

}
Возможно так?