ESP32

Sensor de luminosidade GY-30 – leitura bruta

sensor de luminosidade GY-30

Nesse outro artigo mostrei como fazermos a leitura do sensor de luminosidade GY-30 através da biblioteca BH1750, que implementa todas as instruções do sensor e devolve o resultado em lux. Dessa vez, vamos ver algo mais básico ainda, mas escrevendo nossa própria comunicação baseado no datasheet.

Sensor de luminosidade GY-30

Esse sensor tem bastante precisão e velocidade, mas nesse artigo não vamos converter a leitura para lux, apenas pegar o valor raw e usar como gatilho. Usando esse pretexto, não precisarei implementar todos os recursos e consigo mostrar e discorrer sobre a comunicação I2C com um pouco mais de detalhamento. Vamos lá?

Sensor de luminosidade GY-30 – datasheet

Tudo tem datasheet. Quando precisamos de dados técnicos, é o melhor lugar a recorrer, sem chance de pegar uma informação errada ou mal interpretada. O problema é que não se trata de uma informação trivial, diversos conceitos podem ser necessários, conforme a complexidade do elemento em questão. Por exemplo, o primeiro driver I2C que escrevi foi para o BMP180 no Raspberry. Na época eu não sei se já tinha biblioteca pronta, mas não fiz questão também porque pude aprender com meu ex-chefe como usar o datasheet. Para o Raspberry, escrevi em Python.

O datasheet desse sensor de luminosidade GY-30 pode ser pego diretamente nesse link, tratando-se do CI BH1750.

Por se tratar de um módulo pronto para uso, não li diversas partes do datasheet. Fui direto à parte Instructions Set Architecture.

Achei interessante que nesse datasheet os registradores foram colocados em binário invés de hexa. O set de instruções está na página 5.

Nessa mesma página, estão as recomendações do modo de operação (apesar de existirem modos alternativos) e comando reset (necessário).

Depois de implementar os endereços, no código através de um enumerador, pulei para a página 7, onde tem um exemplo de comunicação com o dispositivo. Também tem a fórmula para fazer a conversão do dado bruto para lux, mas me interessava apenas ler o dado bruto.

A leitura deve ser de 2 Bytes, sendo o Byte alto [15:8] e o Byte baixo [7:0]. No código vai ficar claro, está inclusive comentado.

Comunicação I2C

A comunicação I2C é feita através da biblioteca Wire, que implementa algumas características que nos deixam livres de mais implementações ainda. Mas o que quero deixar claro aqui é a forma que fazemos essa comunicação com um periférico, assimq uando você ver o código de alguém, já conseguirá separar automaticamente o que pertence à comunicação e o que pertence à lógica do programa.

Inicialização do barramento i2c

Sempre que formos utilizar I2C, o primeiro passo é incluir a biblioteca:

Depois em setup(), inicializar o barramento:

A partir daí temos 2 funções principais, que é leituraescrita. Devemos ter em mente que o barramento I2C suporta até 127 dispositivos endereçáveis. Logo, quando queremos fazer uma comunicação com qualquer dispositivo I2C, o primeiro passo é saber seu endereço.

Se você tem um dispositivo e não sabe qual endereço ele está usando, pode descobrir através de um scanner I2C. Aqui tem o código de um.

Escrever no barramento I2C

Para escrever dados para um dispositivo, precisamos da sequência:

  • inicialização da transmissão
  • envio da mensagem
  • finalização da transmissão

Alguns dispositivos podem requerer um intervalo de tempo para leitura, devido a processamento interno. O datasheet deixará isso claro, quando for necessário.

Considerando o formato da comunicação de escrita, o código resultante deve ser algo como:

O valor 0x40 é hipotético, se não escrever informações conforme o protocolo, não vai obter resultados.

Outra coisa importante de citar é que os dados de comunicação são Bytes, não strings literais. A informação é sucinta no barramento, pois no final das contas devemos considerar velocidade não só de processamento, mas de tempo de ocupação do barramento. Minha recomendação é que acostume-se a pensar nesse formato. Inclusive, por essa razão escrevi um exemplo de comunicação com LoRa, criando um protocolo básico e sem CRC.

Ler dados do barramento I2C

A leitura é um pouco mais elaborada, mas vai ficar muito claro nas próximas linhas, não se preocupe.

Existe processamento de modo continuo e “single shot”. Isto é, alguns sensores oferecem o recurso de processamento contínuo, bastando pegar o resultado ao fazer uma leitura. Em alguns casos isso é bom, principalmente quando se trata de economizar energia. Mas tudo tem contrapartida; em alguns casos o barramento ficará integralmente ocupado, não sendo possível interagir com outros dispositivos I2C. Então nessas condições é melhor fazer uma requisição de processamento e uma de leitura. O tempo de resposta e ocupação da MCU variará um pouco, mas isso é significativo em dispositivos de missão crítica. Por exemplo, em uma estação meteorológica não haveria problema de esperar 200ms para ter uma resposta.

Seguindo a linha de raciocínio “single shot”, teriamos então a seguinte sequência:

  • fazer escrita como supracitado
  • requisitar os dados a um dispositivo, de tamanho determinado
  • aguardar que os dados estejam prontos para leitura
  • fazer a leitura

A forma de escrita já deve estar clara. A requisição de dados tem alguns detalhes importantes a citar.

Quando requisitamos os dados, passamos o endereço e o número de Bytes desejados. Esse número variável de dados depende da resposta do dispositivo em questão. Por exemplo, o datasheet do sensor de luminosidade GY-30 mostra que a resposta tem 2 Bytes de tamanho e esses Bytes devem ser tratados.

Após solicitarmos os Bytes de resposta, devemos aguardar a disponibilidade desses dados. Não é uma boa ideia colocar o processamento em loop, pois a MCU pode ter outras tarefas. Dispositivos que não oferecem interrupção poderão ser lidos em polling, por exemplo. Se for no ESP32 (como é o caso desse artigo), pode-se criar uma tarefa exclusiva pra cada sensor, pode-se criar timers de leitura e mais um monte de possibilidades diferentes. Nesse artigo estou escrevendo uma comunicação pífia, sem nenhum propósito que não exemplificar o uso do I2C com dispositivos que tenham processamento independente.

Após fazer a leitura, o resto é lógica do programa principal. Vejamos agora um código para esse sensor.

Código para o sensor de luminosidade GY-30

O código está todo comentado. Subindo esse sketch,  você verá no monitor serial o valor de leitura, daí pode testar o gatilho que seja interessante para seu projeto conforme a luminosidade.

Vídeo

Esse não vai ter vídeo, mas estou com 2 vídeos atrasados porque preciso reinstalar meu sistema no Notebook. Em breve subo os vídeos relacionados aos artigos anteriores, não deixe de se inscrever em nosso canal DobitaobyteBrasil no Youtube!

Onde comprar o sensor de luminosidade GY-30?

Esse sensor está disponível na Curto Circuito, que tem uma variedade bem significativa de sensores de diversos barramentos, dê uma conferida!