чтение данных ADS1115

igorlab
Offline
Зарегистрирован: 11.11.2015

Доброго дня!

C помощью ADS1115 пытаюсь считывать показания с фотодиода, но получается очень большой шум, порядка 10-15 мВ, питание 3.3 В беру со стабилизаитора ардуины, на фотодиод свечу ЛЭДом, который питается через стабилизатор тока на LM317, все элементы фотоячейки изолированы от внешних источников света.

Подскажите пожалуйста:

1) как можно исправить ситуацию с шумами

2) при увеличении переменной arrayLenth хотя бы до 50 - измерения становятся сильно тормознутыми; к примеру, если увеличить яркость свечения светодиода, то на показателях это отобразится только секунд через 5. функцию avergearray() нашел в каком-то примере, но я так понимаю она не очень подходит для ADS1115, по даташиту АЦП имеет 128 преобразований в секунду - т.о. делать паузу (samplingInterval 5) при считывании наверное не очень нужно, вот только как это все связать до кучи не очень понятно...

сегодня получил платку стабилизатора 3.3 В, если на светодиод подавать питание с этой платы, удастся ли хоть как-то подавить шум?

 

#include <Adafruit_ADS1015.h>

Adafruit_ADS1115 ads(0x48); //Здесь указываем адрес устройства

#define samplingInterval 5         //sample values every 10 milliseconds
#define arrayLenth 50             //times of collection
int meterage_Array[arrayLenth];    //store the average value of the sensor feedback
int meterage_ArrayIndex=0;

float Voltage = 0.0;
float Zero  = 0.0;
float D_abs = 0.0;
float T_abs = 0.0;

void setup() {
  Serial.begin(9600);
  ads.setGain(GAIN_EIGHT);      // 8x gain   +/- 0.512V  1 bit = 0.015625mV
  ads.begin();  
}

void loop() {
  if (Serial.available()) // проверяем, поступают ли какие-то команды
  {
    int val = Serial.read();
    if (val == '1') {Zero = Voltage;}
  }
   static unsigned long meterage_samplingTime = millis();
    if(millis()-meterage_samplingTime > samplingInterval) //read an analog value every samplingInterval ms
    {
      meterage_Array[meterage_ArrayIndex++] = ads.readADC_Differential_2_3();
      if(meterage_ArrayIndex==arrayLenth) 
      {
        meterage_ArrayIndex=0;
      }
      Voltage = (avergearray(meterage_Array, arrayLenth) * 0.015625) / 1000;
      meterage_samplingTime = millis() + 10;
    }
    
    T_abs = (Voltage/Zero);
    D_abs = log10(1/T_abs);

    Serial.println("Voltage = " + String(Voltage) );
    Serial.println("T_abs = " + String(T_abs) );
    Serial.println("D_abs = " + String(D_abs) );
}

double avergearray(int* arr, int number){
 int i;
 int max,min;
 double avg;
 long amount=0;
 if(number<=0)
 {
   Serial.println("Error number for the array to avraging!/n");
   return 0;
 }

if(number<5) //less than 5, calculated directly statistics
 {
  for(i=0;i<number;i++)
  {
    amount+=arr[i];
  }
  avg = amount/number;
  return avg;
 }
else
 {
  if(arr[0]<arr[1])
  {
    min = arr[0];max=arr[1];
  }
  else
  {
    min=arr[1];max=arr[0];
  }
  for(i=2;i<number;i++)
  {
    if(arr[i]<min)
    {
      amount+=min;  //arr<min
      min=arr[i];
    }
     else 
     {
      if(arr[i]>max)
      {
        amount+=max;  //arr>max
        max=arr[i];
      }
      else
      {
        amount+=arr[i]; //min<=arr<=max
      }
     }//if
   }//for
   avg = (double)amount/(number-2);
 }//if
 return avg;
}

заранее спасибо!

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

igorlab пишет:

получил платку .... удастся ли 

Ну, ты, бли, даёшь! Плата у тебя есть, всё остальное тоже. быстренько попробовал сам и нам рассказал.

igorlab пишет:

получается очень большой шум, порядка 10-15 мВ

Совершенно нормальный шум при таком зверском (в режиме изнасилования) влючении диода. Открой даташит на него и посмотри какие у него токи при полном освещении. А потом посчитай как ты его включил.

Что касается усреднения массива - это очень странное решение. Зачем? Чтобы словить тормоза?
 
Погугли "программный фильтр низких частот". Тебе это надо, а не осреднение.

 

igorlab
Offline
Зарегистрирован: 11.11.2015

Плату сегодня утром забрал на почте, приду домой конечно буду пробовать, перепробовал уже кучу всего, до этого использовал кадмий-сульфидный фоторезистор, но у него не очень линейная зависимость и у него "память", проковырялся месяц, и перешел на фотодиод

Ворота, тут еще не понятно кто кого насилует, я его или он меня) открыл, почитал... но если бы я в этом разбирался, то на форум не писал бы, я химик и от электроники далек, но есть желание поковыряться и разобраться

за подсказку о ФНЧ спасибо, очень интересно 

const byte potPin = A5;
const float K = 0.1;

float val = 0;

void setup() {
    Serial.begin(9600);
    pinMode( potPin, INPUT );
}

void loop() {
    int pot = analogRead( potPin );
    val = val*(1-K) + pot*K;
    Serial.println(int(val));
    delay(20);
}

sadman41
Offline
Зарегистрирован: 19.10.2016

igorlab пишет:

ADS1115, по даташиту АЦП имеет 128 преобразований в секунду 

До 860 samples / sec. Вообще, на таком фотодиоде делают показометры для уровня радиации. Я схемки смотрел как-то - там резисторы адских номиналов стоят последовательно.

 

2039141417237142592.png

 

5N62V
Offline
Зарегистрирован: 25.02.2016

igorlab пишет:

 но если бы я в этом разбирался, то на форум не писал бы, я химик и от электроники далек, но есть желание поковыряться и разобраться

Токоограничивающий резистор надо срочно поставить хотя бы пару мегоом.

igorlab пишет:

А чем Вы рисовали сей график?

igorlab
Offline
Зарегистрирован: 11.11.2015

спасибо, т.е. мой резистор на 500 Ом заменить на мегаомный?

это не я рисовал - это со статьи о ФНЧ,

нашел прикольную статью как строить такой график

#include <ADXL345.h>

ADXL345 accelerometer;
Vector araw;

void setup() {
    Serial.begin(115200);
    accelerometer.begin();
    accelerometer.setRange(ADXL345_RANGE_16G);
}

void loop() {
    araw = accelerometer.readRaw();
    Serial.println( araw.XAxis );
    delay(20);
}

 

 

sadman41
Offline
Зарегистрирован: 19.10.2016

igorlab пишет:

спасибо, т.е. мой резистор на 500 Ом заменить на мегаомный?

Если честно - я не в курсе, пусть специалисты прокомментируют. Самому интересно - можно ли для такого фотодиода два ОУ и обвес заменить на ADS-1115. 

Я тоже хочу на BPW собрать детектор частиц (просто посмотреть как оно), но это нужно на плате всех жуков распаивать... Если на одном модуле можно сделать то же самое, я буду счастлив.

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

igorlab пишет:

спасибо, т.е. мой резистор на 500 Ом заменить на мегаомный?

Я же тебе писал, посмотри токи в даташите и посчитай резистор. Ты закон Ома знаешь?

Так вот, падение напржения на Вашем диоде - 350мВ, стало быть на резисторе падает 3,3В - 0,35В = 2,95В

Каков максимальный ток через диод при полном освещении? Смотрим даташит - самый наимаксимальный - 75 микроамер. Делим напряжение на ток 2,95 / 0,000075 = 39,4К - т.е. 43 килоома.

Но, если хочешь реальный совет, я бы вместо диода поставил копеечный фототранзистор L-32P3C. Он, конечно, заметно медленнее, чем твой диод, но тебе хватит скорости. Расчёт его включения здесь кто-то приводил совсем подробный, для детей написанный, поищи. Не найдёшь, скажи, я пороюсь в сохранённых ссылках.

Кстати о скоростях, что ты там за фоторезистор пытался использовать для такой частоты измерений? У них обычно скорость срабатывания - десятки миллисекунд.

sadman41
Offline
Зарегистрирован: 19.10.2016

... на резисторе падает 3,3В - 0,35В = 2,95В ?

igorlab
Offline
Зарегистрирован: 11.11.2015

мне надо измерять оптическую плотность, если изначально какое-то значение принять за 100% потом, ослабить световой поток до 50% и потом обратно вернуть до 100% то фоторезистор (с набора ардуино :) ) покажет 96% и только постояв мин 5 таки дойдет до 100, вот этот эффект памяти мне и не понравился, если я правильно понял все происходящее

BPW34 уже есть, а L-32P3C надо ждать пока доставят (заказал)... 

спасибо за расчет

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

sadman41 пишет:

... на резисторе падает 3,3В - 0,35В = 2,95В ?

спасибо

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

igorlab пишет:

L-32P3C ... (заказал)... 

А я нашёл ссылку на расчёт для его включения, написано для детей и явно часть какого-то большого материала (отсылки есть), но расчёт простой и понятный. Я бы может с коллектора снимал бы, а не с эмиттера, но автору, видимо, хотелось неинвертированный сигнал иметь - https://drive.google.com/open?id=0B9r7cRXQ4DU4dGlHRmFOT0V0emc

igorlab
Offline
Зарегистрирован: 11.11.2015

Спасибо за ссылку, многое проясняется

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Хороший расчет и прост. Но, все равно, между входом АЦП и выходом с резистора стоит воткнуть ОУ по схеме повторителя сигнала для повышения точности результатов.

Кстати, зачем тут внешний АЦП .. осталось непонятным.. :)

sadman41
Offline
Зарегистрирован: 19.10.2016

Arhat109-2 пишет:

Кстати, зачем тут внешний АЦП .. осталось непонятным.. :)

А энто чтобы усилитель не ставить. Конечно еще хорошо, что оцифровку можно переложить на ADS, но тут вроде темпы такие не требуются...

igorlab
Offline
Зарегистрирован: 11.11.2015

так в ADS1115 есть же свой ОУ, или он по каким-то параметрам не подходит?...

вчера подключил платку-стабилизатор на 3.3 В, результат странный - если не ставить конденсатор паралельно резистору то порт показывает такое (минимумы это закрытый пальцем светодиод):

синий - значения без ФНЧ, красный с ФНЧ, 

если поставить конденсатор, то картинка улучшается:

а это картинка просто измерения напряжения на стабилизаторе, видно что качество стабилизации хорошее:

Обнаружил еще одну проблему - несмотря на то что измерительная часть питается от платы стабилизатора 3.3 В, а ардуино от юсб - при нажатии на кнопку (пин подтянут к земле 10кОм, кнопка к пину и к +5 В через 10 кОм) на фотодиоде (или правильней сказать на резисторе фотодиода) происходит просадка напряжения, около 10 мВ, как такое может быть?