16 janeiro 2016

Lux Meter - Medidor de intensidade de luz com Arduino e sensor TSL2561

O ambiente onde estou está sendo iluminado adequadamente ? Tenho bastante luz para trabalhar ou estudar ? Essas e outras questões podem ser respondidas com a ajuda do Sensor de luz TSL2561 lux luminosidade, que vamos utilizar juntamente com o Arduino e display Oled para montar um medidor de luz.

Sensor de lux luminosidade TSL2561 Arduino

O sensor de luminosidade TSL2561 (datasheet) é um sensor avançado que detecta não só a faixa de luz normal, captada pelo olho humano, como também a luz infravermelha, em uma faixa de 0.1 à 40.000 lux. É um módulo extremamente econômico em termos de energia, consumindo apenas 0,5mA quando está recebendo luz, e 15µA em modo de espera (standby).

O que o sensor TSL2561 faz ?


Já falamos aqui do LDR (no post Controle de Luz utilizando LDR), que é um componente cuja resistência varia de acordo com a incidência de luz. Apesar de conseguirmos realizar algum tipo de medição com ele, não temos precisão na leitura.

O módulo TSL2561, por sua vez, é muito mais preciso, podendo detectar luz desde a faixa do infravermelho até a faixa total de luz (espectro) percebida pelo olho humano. Com o TSL2561, é possível calcular a quantidade exata de luz que atinge um certo ponto (lux), já que ele é um conversor que transforma a intensidade de luz em um sinal digital que pode ser interpretado por um microcontrolador.

Saber a quantidade de luz em um ponto/ambiente é importante pois, segundo os especialistas, luz demais causa uma sensação de desconforto, e pouca luz pode prejudicar (e geralmente prejudica) não só a sua visão mas também atrapalhar o desempenho das suas tarefas diárias. Assim, temos a seguinte recomendação de iluminância nos ambiente mais comuns, segundo as normas da ABNT:

  • Escritório e biblioteca - 300 lux
  • Cozinha e banheiro - 200 lux
  • Sala estar, jantar e dormitório - 150 lux
  • Hall, escada, despensa e garagem - 100 lux

Utilizando o módulo TSL2561 ligado em um Arduino, você pode conferir se as especificações de luminosidade na sua casa ou escritório estão corretas.

Pinagem do módulo TSL2561


Abaixo podemos ver a disposição dos pinos do módulo, tanto de alimentação e sinal, como também da seleção de endereço I2C (Addr). Se você preferir, pode setar o endereço I2C de forma permanente, soldando os terminais na parte de trás da placa.

TSL2561 Lux Sensor

  • Vcc - Alimentação 3.3 ou 5V
  • GND - GND
  • 3vo - Saída 3.3V do regulador de tensão do módulo. Suporta até 100mA
  • Addr - Seleção do endereço I2C: 0x29 (pino em nível 0), 0x49 (nível 1) ou 0x39 (desligado / floating)
  • Int -  Interrupt Output - é um pino específico, acionado quando a luminosidade alcança um determinado nível (threshold)
  • SDA - I2C - Data
  • SCL - I2C - Clock

Conexão do sensor de luminosidade TSL2561 ao Arduino


Para ligar o TSL2561 ao Arduino Uno vamos utilizar somente os pinos de alimentação e interface I2C (portas analógicas A4 e A5), deixando o pino ADDR sem conexão (floating), utilizando assim o endereço 0x39.

O módulo pode ser ligado diretamente aos pinos SCL e SDA do Arduino, pois ele é compatível tanto com nível de sinal de 3.3V como de 5V.

Arduino Uno - Oled - Sensor TSL2561

O display que usamos é um display OLED 0.96" com interface I2C, ligado em 3.3V assim como o módulo TSL2561. Esse display tem uma pequena faixa na parte superior com os pixels em amarelo, e o restante do display tem os pixels na cor azul.

Programa módulo sensor de luz TSL2561


Para esse programa vamos precisar de 3 bibliotecas, sendo duas para o sensor de luz e uma para o display Oled:

Adafruit TSL2561 V2 (download)
Adafruit Sensor Library (download)
U8Glib (download)

Baixe as três bibliotecas, descompacte e coloque-as na pasta LIBRARIES da IDE do Arduino.

O programa utiliza como base o programa de exemplo sensorapi da biblioteca Adafruit TSL2561 para ler os dados do sensor e converter em lux. Essas informações são exibidas no display Oled utilizando as funções da biblioteca gráfica U8Glib.

Na linha 13 do programa você define qual endereço I2C usar, substituindo TSL2561_ADDR_FLOAT por TSL2561_ADDR_HIGH (para o endereço 0x49) ou TSL2561_ADDR_LOW (para o endereço 0x29). Não se esqueça, claro, de enviar o sinal adequado para o pino ADDR.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
//Programa: Medidor de Luminosidade Lux com TSL2561
//Autor: Arduino e Cia

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_TSL2561_U.h>
#include <U8glib.h>

//Definicoes do display Oled
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK);

//Definicoes do sensor TSL2561
Adafruit_TSL2561_Unified tsl=Adafruit_TSL2561_Unified(TSL2561_ADDR_FLOAT,12345);

int valor = 0;
String str;
int tamanho;

void draw()
{
  //Comandos graficos para o display devem ser colocados aqui
  u8g.drawRFrame(0, 16, 128, 48, 4);
  u8g.drawRFrame(0, 0, 128, 16, 4);
  u8g.setFont(u8g_font_8x13B);
  u8g.setColorIndex(0);
  u8g.setColorIndex(1);
  u8g.drawStr( 30, 13, "Lux Meter");
  u8g.setFont(u8g_font_fur25);
  str = String(valor);
  tamanho = str.length();
  u8g.setPrintPos(64-(tamanho*10), 53);
  u8g.print(valor);
}

void displaySensorDetails(void)
{
  //Informacoes basicas do sensor TSL2561
  sensor_t sensor;
  tsl.getSensor(&sensor);
  Serial.println("------------------------------------");
  Serial.print  ("Sensor:     "); Serial.println(sensor.name);
  Serial.print  ("Driver Ver: "); Serial.println(sensor.version);
  Serial.print  ("Unique ID:  "); Serial.println(sensor.sensor_id);
  Serial.print  ("Max Value:  "); Serial.print(sensor.max_value);
  Serial.println(" lux");
  Serial.print  ("Min Value:  "); Serial.print(sensor.min_value); 
  Serial.println(" lux");
  Serial.print  ("Resolution: "); Serial.print(sensor.resolution); 
  Serial.println(" lux");
  Serial.println("----------------------------------");
  Serial.println("");
  delay(500);
}

/**************************************************************************/
/*
    Configures the gain and integration time for the TSL2561
*/
/**************************************************************************/
void configureSensor(void)
{
  /* You can also manually set the gain or enable auto-gain support */
  /* No gain. use in bright light to avoid sensor saturation */
  // tsl.setGain(TSL2561_GAIN_1X); 
  /* 16x gain. use in low light to boost sensitivity */
  // tsl.setGain(TSL2561_GAIN_16X); 
  /* Auto-gain. switches automatically between 1x and 16x */
  tsl.enableAutoRange(true);         

  /* Changing the integration time gives you better
      sensor resolution (402ms = 16-bit data) */
  /* fast but low resolution */
  tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_13MS);     
  /* medium resolution and speed */
  // tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_101MS); 
  /* 16-bit data but slowest conversions */
  // tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_402MS); 

  /* Update these values depending on what you've set above! */
  Serial.println("------------------------------------");
  Serial.print  ("Gain:         "); Serial.println("Auto");
  Serial.print  ("Timing:       "); Serial.println("13 ms");
  Serial.println("------------------------------------");
}

void setup(void)
{
  Serial.begin(9600);
  Serial.println("Light Sensor Test"); Serial.println("");

  //Inicializa o sensor TSL
  if (!tsl.begin())
  {
    Serial.print("TSL2561 nao detectado,verifique a conexao e o endereco I2C");
    while (1);
  }
  //Exibe as informacoes basicas do sensor TSL
  displaySensorDetails();
  //Configura o sensor TSL
  configureSensor();
  Serial.println("");

  if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
    u8g.setColorIndex(255);     // white
  }
  else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
    u8g.setColorIndex(3);         // max intensity
  }
  else if ( u8g.getMode() == U8G_MODE_BW ) {
    u8g.setColorIndex(1);         // pixel on
  }
  else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    u8g.setHiColorByRGB(255, 255, 255);
  }
}

void loop(void)
{
  Calcula_Lux();
  //Chama a rotina de desenho na tela
  u8g.firstPage();
  do
  {
    draw();
  }
  while ( u8g.nextPage() );
  delay(150);
}

void Calcula_Lux()
{
  sensors_event_t event;
  tsl.getEvent(&event);
  //Mostra os resultados no serial monitor
  //Intensidade da Luz medida em Lux
  if (event.light)
  {
    valor = event.light;
    Serial.print(event.light); Serial.println(" lux");
  }
  else
  {
    Serial.println("Sensor overload");
  }
  delay(250);
}

Caso você não possua ou não queira utilizar o display, pode conferir a medição da luminosidade e também outras informações do sensor, como ganho (gain) e nível de resolução, no Serial Monitor:

TSL2561 - Serial Monitor

Abaixo você confere um vídeo do circuito em funcionamento:


9 comentários:

  1. poderia ser montado 7 tsl2531 em um Arduíno mega com 1 lcd?

    ResponderExcluir
    Respostas
    1. Oi Leonardo,

      Infelizmente não, pq esse módulo só aceita 3 endereços I2C, logo esse é o número máximo de sensores em apenas um Arduino.

      Abraço!

      Excluir
  2. olá, poderia fazer uma experiencia com esses sensores para comparação de luminosidade? me ajudaria muito em um projeto que estou fazendo, mas não sei como fazer, se puder me ajudar, ficarei grato.

    ResponderExcluir
    Respostas
    1. Bom dia,

      Que tipo de projeto/programação vc precisa ? Se preferir, entre em contato utilizando o formulário de contato no lado direito da página. Combinamos por email.

      Abraço!

      Excluir
  3. olá, pode ser usado um sensor BH1750 no lugar do TSL2561? obg

    ResponderExcluir
    Respostas
    1. Boa noite,

      Eu já usei o BH1750, mas não com essa biblioteca. Tente essa:

      https://github.com/claws/BH1750

      Abraço!

      Excluir
    2. qual é mais preciso, o sensor BH1750 ou o TSL2561?

      Excluir
  4. Boa tarde !
    Muda muito eu usando um display LCD 16x2 ?
    Como ficaria o Sketch ?
    Sou muito novo, nesse trabalho com Arduino, mas pelo menos o meu display já esta funcionando.
    Agradeço a ajuda.
    Abraço

    ResponderExcluir
    Respostas
    1. Oi Ferraz,

      Muda bastante, mas fica até mais fácil, porque no final basta você imprimir o valor da variável event.light.

      Coloque no programa os parâmetros para utilização do display LCD que você já usou (include, lcd.begin, etc), depois, dentro do loop, coloque o comando abaixo:

      lcd.print(valor);

      É mais ou menos isso. veja se consegue adaptar.

      Abraço!


      Excluir