본문 바로가기

만들기 / making/sensing workshop

Day 9: Lux Sensor

Day 9: Lux Sensor

BS120 조도 센서 Datasheet
http://media.digikey.com/pdf/Data%20Sheets/Sharp%20PDFs/BS120.pdf



회로도

BS120 Pin 넘버

센서사용법

BS120 조도 센서는 가시광선 영역을 센싱한다.
BS120은 포토 다이오드인데 말하자면 LED와 반대 기능을 하는것이다.
LED는 전류가 공급되면 빛을 내보내는데 포토다이오드는 빛을 받으면 전류를 만들어 낸다.

포토 다이오드에도 여러가지 종류가 있는데 어떤 종류의 빛을 주로 받아서 전류로 바꿔주냐에 따라 달라진다.

포토다이오드 중에 가장 많이 쓰이는데 적외선의 빛을 전류로 바꿔주는 것인데 리모콘등에 활용된다.

또 다른 포토다이오드로는 가시광선 영역을 주로 센싱하는 포토다이오드가 있다.
BS120은 가격도 저렴하면서 가장 대표적인 가시광선 포토 다이오드이다.

BS120의 파장과 민감도 도표는 다음과 같다.
560nm 를 중심으로 센싱영역이 펼쳐져 있다. 

다음 표를 보면

BS120은 빛이 100Lux일때 0.16uA 가 흐른다 (Isc = 0.16 at 100Lux)

그리고 다음표를 보면 조도에 비례하여 전류가 흐르므로 
10Lux일때는 0.16uA / 10 의 전류가 흐르고
1000Lux일때는 0.16uA *10의 전류가 흐른다는 것을 알 수 있다.



하지만
우리는 ADC를 이용해 전류값을 바로 측정할 수 없다.
ADC는 전압만을 디지털값으로 바꿔주기 때문이다


따라서 전류 -> 전압으로 바꿔주는 뭔가를 만들어야 하는데 이는 Op-Amp를 사용하면 가능하다.

그 회로도가 위의 회로도이고 I-V Converter라고 한다.
BS120센서 부분에 전류를 내보내는 센서를 달아주고 
R6 저항을 통해 전류가 전압으로 바뀌는 레인지를 결정해준다.

센서 Calibration

보통 실내의 조도는 0~ 2500Lux 이므로 이번시간에는 0~10240Lux를 측정하는 센서를 만들어본다

저번에 10bit ADC를 쓰면 0~5V 를 1024 단계로 나누어 디지털 값으로 변환한다고 했다.

10240 Lux를 측정하고자 하는데 이를 1024로 나누어 주면 한단계당 10Lux 씩 측정할 수 있다는 말이다. 

그럼 5V 를 1024로 나누면 약 4.89mV 가 나오는데 1단계는 4.89mV 이고 이 값이 10Lux에 해당하는 값이다.

자그럼 R6의 값을 결정해 보자 
데이터 시트에 보면 100Lux 일때 센서에서 0.16uA가 나오는 것을 알 수 있다, 

옴의 법칙 V=I*R을 이용해서 R6의 값을 구해보자

옴의 법칙을 다시쓰면 R = V / I 가 된다.

1단계당 R 값을 구하려면 V 위해서 구한 4.89mV 를 넣고

I 는 10Lux 일때 전류를 넣으면 되는데 이를 구하기 위해서는 
100Lux: 10Lux = 0.16uA: 10Lux일때 전류의 비례식을 이용하자

10Lux일때 전류는 0.016uA이다.

다시 옴의 법칙으로 돌아오면

R = 4.89mV / 0.016uA = 305625옴 즉 약 305k옴이된다.

계산은 이와 같이 하면 되나 상황에 맞게 쓰기위해서는  R이 클수록 재려는 범위가 커진다고 생각하면된다.






MCU Code

//-----------------------------------------------------------------------------
//  ATmega168
//  Internal 16 MHz RC Osc.
//  (1/16M = 62.5 ns)
//-----------------------------------------------------------------------------

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "hhjjj168.h"

#define output_low(port,pin) port &= ~(1<<pin)
#define output_high(port,pin) port |= (1<<pin)
#define set_input(portdir,pin) portdir &= ~(1<<pin)
#define set_output(portdir,pin) portdir |= (1<<pin)


#define FOSC 16000000
#define BAUD 9600
#define UBRR FOSC/16/BAUD-1


//-----------------------------------------------------------------------------
//  Main
//-----------------------------------------------------------------------------
int main()
{
ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // Set ADC prescalar to 128 - 125KHz sample rate @ 16MHz 
  ADMUX |= (1 << REFS0); // Set ADC reference to AVCC 
  //ADMUX |= (1 << ADLAR); // Left adjust ADC result to allow easy 8 bit reading 
  ADMUX &= ~(1 << ADLAR); // right adjust ADC result to allow easy 10 bit reading 

  // No MUX values needed to be changed to use ADC0 
  ADCSRA |= (1 << ADATE); // Set ADC to Free-Running Mode
  ADCSRA |= (1 << ADEN); // Enable ADC
  ADCSRA |= (1 << ADSC); // Start A2D Conversions 

init_USART0(UBRR); //initialize USART0

    while (1) 
{

transmit_digit_USART0(ADCW);
  transmit_1byte_USART0('\n');

    }

    return 0;
}




Processing Code

import processing.serial.*;
Serial myPort;  // Create object from Serial class
String myString = null;
int cnt = 0;
void setup() 
{
  //size(200, 200);
  
  // List all the available serial ports
  println(Serial.list());
  String portName = Serial.list()[1];
  myPort = new Serial(this, portName, 9600);
}

void draw() 
{

  while (myPort.available() > 0) 
  {  
    myString = myPort.readStringUntil('\n');
    if (myString != null) 
    {
      println(myString);
      
    }
  }
}

processing_바탕화면 색깔 바꾸기 코드
//========================================

import processing.serial.*;
Serial myPort;  // Create object from Serial class
String myString = null;
float bs = 0.0;
void setup() 
{
  size(200, 200);
  
  // List all the available serial ports
  println(Serial.list());
  String portName = Serial.list()[1];
  myPort = new Serial(this, portName, 9600);
}

void draw() 
{

  while (myPort.available() > 0) 
  {  
    myString = myPort.readStringUntil('\n');
    if (myString != null) 
    {
      bs = float(myString);
      bs = (255./735.)*bs;
      background(bs);
      smooth();
      println(bs);
      //println(myString);
      
    }
  }
}




'만들기 / making > sensing workshop' 카테고리의 다른 글

Distributed Sensor Data Processing  (0) 2009.08.31
Day 10: EEG / EKG / Galvanic Sensor  (0) 2009.08.31
Day 8: Touch Sensor  (0) 2009.08.31
serial communication  (0) 2009.08.31
multi sensor arduino / processing  (0) 2009.08.31