фотодиод и analogread

goha92
Offline
Зарегистрирован: 20.03.2013

Доброй всем ночи, Решил вот побаловаться с ардуиной, идея собрать нечто пульс-оксиметра, ардуина должна попеременно мигать светодиодиками, и мерить освещённость фотодиодом с ОУ в фотогальваническом режиме, и вроде бы всё неплохо, только значения скачут, +- 100 и более отсчетов, при этом если поставить переменный резистор, всё нормально и ардуина фиксирует напряжение на нем очень точно, так что грешу на схему. вот код частота считывания около 1000 герц.


 
 #include <LiquidCrystal.h>

// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

///////////////////////////////////////////////////////////////////////////////////////////
  int ledStateRED = LOW;  // этой переменной устанавливаем состояние светодиода
  int ledStateIR = LOW; 
  long previousMillis = 0;        // храним время последнего переключения светодиода
  int ledPinRED =2;   // светодиод подключается к digital pin 10
  int ledPinIR =3;   // IR светодиод подключается к digital pin 11 
  int photoPin = 2;  // фоторезистор подключен 0-му аналоговому входу
  long interval=10; //интервал между включениями светодиода
      int valRED = 0;       // переменная для хранения значения входного напряжения
      int valIR = 0;       // переменная для хранения значения входного напряжения
 /////////////////////////////////////////////////////////     

 ////////////////////////////////////////////////////////////////////////    
void setup() {
 lcd.begin(16, 2);              // start the library
lcd.setCursor(0,0);
lcd.print("light intensity"); // print a simple message
  Serial.begin(9600);
 pinMode(photoPin, INPUT); 
  pinMode(ledPinRED, OUTPUT); 
   pinMode(ledPinIR, OUTPUT);  
  
}
 
void loop()
{
  lcd.setCursor(9,1);            // move cursor to second line "1" and 9 spaces over
lcd.print(valRED);      // display seconds elapsed since power-up

  // здесь будет код, который будет работать постоянно
  // и который не должен останавливаться на время между переключениями свето
  unsigned long currentMillis = millis();
  
  //проверяем не прошел ли нужный интервал, если прошел то
  if(currentMillis - previousMillis > interval){ 
    // сохраняем время последнего переключения
    previousMillis = currentMillis; 
 
    // если светодиод не горит, то зажигаем, и наоборот
    if (ledStateRED == LOW){

      ledStateRED = HIGH;//взял код из мигания светодиодами без delay
      ledStateIR = LOW;//попеременно мигаем то красным то инфракрасным светодиодом
       valRED = analogRead(photoPin); //считываем значение с фотодиода при включенном красном
    
  }else
      {
        ledStateIR = HIGH;//теперь всё наоборот
        ledStateRED = LOW;
//       analogReference(INTERNAL);

        valIR = analogRead(photoPin);}
    // устанавливаем состояния выхода, чтобы включить или выключить светодиод

    digitalWrite(ledPinRED, ledStateRED);
    digitalWrite(ledPinIR, ledStateIR);
          
  Serial.print(valRED);//печатаем значения с фотодиода при включенном красном светодиоде
   Serial.print(" ");
    Serial.print(valIR);//печатаем значения с фотодиода при включенном инфракрасном светодиоде
     Serial.print(" ");
     Serial.println(millis());
       Serial.println();

     }}


goha92
Offline
Зарегистрирован: 20.03.2013

goha92
Offline
Зарегистрирован: 20.03.2013

фотодиод bpw 34
операционник сдвоенный используется только одна половина lm 358, не может ли быть причина в нем?

Клапауций
Offline
Зарегистрирован: 10.02.2013

goha92 пишет:

Доброй всем ночи, Решил вот побаловаться с ардуиной, идея собрать нечто пульс-оксиметра, ардуина должна попеременно мигать светодиодиками, и мерить освещённость фотодиодом с ОУ в фотогальваническом режиме, и вроде бы всё неплохо, только значения скачут, +- 100 и более отсчетов, при этом если поставить переменный резистор, всё нормально 

  int photoPin = 2;  // фоторезистор подключен 0-му аналоговому входу


Согласно скетчу и практической проверке - фоторезистор должен стоять, а не фотодиод.

Клапауций
Offline
Зарегистрирован: 10.02.2013

Здесь http://techdocs.fatal.ru/develop/hardware/komp_izm_komplex/6-4.html

рабоая схема желаемого...

goha92
Offline
Зарегистрирован: 20.03.2013

Спасибо за схемку, да переменник я втыкал чтобы проверить всё ли в порядке, с чтением аналоговых сигналов(боялся пин сжёг).
Косяки вылезли когда осцилограф сунул и увидел синусойду с лампы)
Еещё возник вопрос, есть ли простой сполоб находить минимальное значение за последние 100 ну или 500 отсчётов как это делают, со скользящим средним?

пример с этого форума

 

1 mean = 4/5 * mean + 1/5 * val; // скользящее среднее по 5 последним значениям
2 mean = 99/100 * mean + 1/100 * val; // скользящее среднее по 100 последним значениям

 

step962
Offline
Зарегистрирован: 23.05.2011

goha92 пишет:

Еещё возник вопрос, есть ли простой сполоб находить минимальное значение за последние 100 ну или 500 отсчётов как это делают, со скользящим средним?

int minmin=32767;
int maxmax=-32768;
while(1) {
// получили откуда-то текущее значение и сохранили его в curVal
  if(maxmax<curVal) maxmax=curVal;
  if(minmin>curVal) minmin=curVal;
}

В результате имеете минимальное и максимальное значения за последние стопицотмильёнов циклов.

inspiritus
Offline
Зарегистрирован: 17.12.2012

хм... а почему не используете фототранзистор? (обычно фототранзистор дает как более линейную характеристику, чем фото диод, так и некоторое начальное усиление, которое особенно ценно при большом усилении сигнала для минимизации шумов) соответственно с "подтяжкой " сенсор пина напрямую, или чувствительности нехватает без доп. усиления?

соответственно можно взять 2 одинаковых фототранзистора и подать от них сигналы на дифф входы ОУ. Причем один фототранзистор - рабочий а второй расположен на датчике, рядом с рабочим, всегда затенен и нужен для компенсации помех от первого, и провода. После дифф каскада остается полезная составляющая, которая усиливается вторым каскадом...

goha92
Offline
Зарегистрирован: 20.03.2013

Честно говоря, мне просто не удалось найти, подходящий транзистор)

inspiritus
Offline
Зарегистрирован: 17.12.2012

 

шариковая мышка РУЛИТ, их там аж два, и можно подключать параллельно для большей чувствительности...

а если в мышке похожий на этот

, то в нем тоже 2 фото транзистора должно быть, потому как толко с парой можно выловить направление вращения...

 

и еще вот фоторанзистор свими руками  http://www.kondratev-v.ru/samodelki/samodelnyj-fototranzistor.html

, и что тут радует это фраза "с большим коэффициентом усиления" только вот канфилью лучше не заливать, а использовать какой нить прозрачный (после отверждения)  "момент" или на крайняк суперклей тот же моментовский тонким слоем, чтобы не затемнить, а потом можно вклеить например линзочку из CD привода :)

вообще для pulse-метра  надо подбирать спектральнну характеристику излучателя и приемника, чтобы пробивало палец, но не насквозь :), а то реагировать на наполнение кровью капилляров не будет

 

goha92
Offline
Зарегистрирован: 20.03.2013

из мышки вряд ли пойдет, нужно чтобы он примерно одинаково воспринимал и 660 нм и 940нм)

ну и напаял я уже много)
 

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Дурью не майтесь. Купите фоторезистор и подцепите к АЦП.

Клапауций
Offline
Зарегистрирован: 10.02.2013

Что бы палец не пробивало наскрозь, нужно обратную ега сторону чёрным маркером закрасить. :D

goha92
Offline
Зарегистрирован: 20.03.2013

оказалость что и в моём коде, какой то косяк.

каждый светодиодик должен гореть допустим 10 милисекунд, а потом на те же 10 миллисекунд выключаться, когда включен один выключен второй, но оказываеться он банально моргает(увеличил задержку до секунды чтоб понять) тоесть при задекжке в одну секунду он горит секунду на мгновенье погасает и снова горит.