VCNL4000, Tarjeta de sensor de proximidad y luz ambiental

El siguiente tutorial tiene como objetivo mostrar el funcionamiento del sensor proximidad y luz ambiental  (VCNL 4000).

El sensor VCNL4000 es un integrado totalmente de proximidad y  de luz ambiental. Es un sensor óptico que combina un emisor de luz infrarrojo y un fotodiodo para la medición de proximidad y un detector de luz ambiental (en lux) con una resolución de 16 bits y una interfaz de comunicación  I2C.

Con un alcance de 20cm (7,9”) de alcance, este componente en gran medida simplifica el uso y el diseño de un sensor de proximidad en aplicaciones industriales. Tiene comunicación con el arduino usando el protocolo I2C, mediante  de los pines analógicos de la placa.

Las siguientes imágenes contienen el nombre de las terminales del VCNL4000 y se ha obtenido de la hoja de datos del componente.

Imagen 1. Componentes del sensor VCNL4000

Imagen 1. Componentes del sensor VCNL4000

Imagen 1. Terminales del sensor VCNL4000

Imagen 2. Terminales del sensor VCNL4000

Material necesario

Teniendo en cuenta lo anterior se continúa con la conexión de la tarjeta con la placa de ARDUINO y se muestra a continuación la conexión del componente con la tarjeta programable.

Imagen 3. Conexión simulada

Imagen 3. Conexión simulada del sensor VCNL4000

Imagen 4. Conexión en fisico

Imagen 4. Conexión en fisico del sensor VCNL4000

Imagen 5. Conexión en fisico

Imagen 5. Conexión en fisico del sensor VCNL4000

Las conexiones entre el sensor y el arduino son de la siguiente manera:

Imagen 8. Tabla de conexion

Imagen 8. Tabla de conexión

EXPLICACION DE CODIGO
Comenzamos agregando la librería que realiza la comunicación I2C  y se establece la dirección de I2C y los comandos y constantes que utilizaremos en el programa.

#include <Wire.h>

#define VCNL4000_ADDRESS 0x13
#define VCNL4000_Comando 0x80
#define VCNL4000_IDSensor 0x81
#define VCNL4000_IRLED 0x83
#define VCNL4000_ParametroLAmbiente 0x84
#define VCNL4000_DatoLAmbiente 0x85
#define VCNL4000_DatoAproximidadA 0x87
#define VCNL4000_SenalFreq 0x89
#define VCNL4000_AjusteAproximidad 0x8A

#define VCNL4000_3M125 0
#define VCNL4000_1M5625 1
#define VCNL4000_781K25 2
#define VCNL4000_390K625 3

#define VCNL4000_MedicionLAmbiente 0x10
#define VCNL4000_MedicionAproximidad 0x08
#define VCNL4000_LAmbienteLista 0x40
#define VCNL4000_AproximidadLista 0x20

Y declaramos de igual forma para los LED que indicaran el estado de ambos sensores.

const int LEDAPROX =13;
const int LEDLUZA =12;

La siguiente declaración nos dice los parámetros que establezcamos para ambos sensores lo que nos permitirá manipular sus variables según sea nuestra necesidad de aplicación.

//ESTABLECIMIENTO de umbral para aproximidad en mm
const int minAprox = 1500;

//ESTABLECIMIENTO de umbral para brillo
const int minLAmbient = 200;
int EstadoLED = LOW;

–Terminada la declaración de lo anterior proseguimos con la sección de void setup:

Declarando la velocidad inicial y mostrando un mensaje.

void setup (){
 Serial.begin(9600);
 Serial.println("SENSOR VCNL4000 LUZ AMBIENTAL Y PROXIMIDAD - HETPRO");
 Wire.begin();

Dentro de esta sección se comienza a utilizar arreglos y declarando como 8 bits pero de una manera distinta a lo usual y verificamos que se encuentre disponible nuestro sensor.

uint8_t rev = read8(VCNL4000_IDSensor);
if ((rev & 0xF0) != 0x10){
     Serial.println("Sensor no encontrado ");
     while(1);
  }

Continuando, se configura, establece y se muestra en la pantalla serial la corriente de LED IR, la frecuencia para el sensor de proximidad y su ajuste. Establecemos los LED como salida con sus variables a utilizar.

write8(VCNL4000_IRLED, 20); //establece, a 20 x 10mA = 200mA
  Serial.print("Corriente de LED IR = ");
  Serial.print(read8(VCNL4000_IRLED) * 10, DEC);
  Serial.println(" mA");

  Serial.print("Configuracion de frecuencia de proximidad = ");
  uint8_t freq = read8(VCNL4000_SenalFreq);
  if (freq == VCNL4000_3M125) Serial.println("3.125 MHz");
  if (freq == VCNL4000_1M5625) Serial.println("1.5625 MHz");
  if (freq == VCNL4000_781K25) Serial.println("781.25 KHz");
  if (freq == VCNL4000_390K625) Serial.println("390.625 Khz");

  write8(VCNL4000_AjusteAproximidad, 0x81);
  Serial.print("Registro de ajuste de aproximidad = ");
  Serial.println(read8(VCNL4000_AjusteAproximidad), HEX);

  pinMode(LEDAPROX, OUTPUT);
  pinMode(LEDLUZA, OUTPUT);
}

Termina aquí la sección de void setup e inicia void loop, lo primero es obtener los datos de nuestros sensores y mostrarlos en nuestra pantalla.

write8(VCNL4000_Comando, VCNL4000_MedicionLAmbiente | VCNL4000_MedicionAproximidad);
   while (1){
     uint8_t result = read8(VCNL4000_Comando);
    if ((result & VCNL4000_LAmbienteLista)&&(result & VCNL4000_AproximidadLista)) {

      Serial.print("Luz de Ambiente = ");
      unsigned int ambient = read16(VCNL4000_DatoLAmbiente);
      Serial.print(ambient);
      Serial.print("\t\tProximidad = ");
      unsigned int prox = read16(VCNL4000_DatoAproximidadA);
      Serial.println(prox);

Lo siguiente es colocar nuestra condiciones para lo que deseamos que realice si rebaza o queda por debajo los parámetros que se establecieron al inicio. Dejando en un solo estado a los LED de cada sensor.

if(ambient > minLAmbient){
        digitalWrite(LEDLUZA, LOW);
      if (prox > minAprox) {
          EstadoLED = HIGH;
        }
      }
      else
      {

    digitalWrite(LEDLUZA, HIGH);
    EstadoLED= LOW;
    delay(1000);
      }
      break;
    }
    delay(1000);
   }

    digitalWrite(LEDAPROX, EstadoLED);
    delay(50);
}

La última parte del código es la combinación de condiciones con los arreglos que contiene nuestras variables y constantes, para que estos se puedan mostrar en la pantalla haciendo uso de 8bits y 16bits ya sea el caso de lectura. Leyendo y regresando los bits que lea nuestro ARDUINO  del sensor VCNL4000.

uint16_t readProximity() {
  write8(VCNL4000_Comando, VCNL4000_MedicionAproximidad);
  while (1) {
    uint8_t result = read8(VCNL4000_Comando);
      if (result & VCNL4000_AproximidadLista) {
      return read16(VCNL4000_DatoAproximidadA);
    }
    delay(1000);
  }
}
    //lee un byte desde la direccion de VCNL4000
uint8_t read8(uint8_t address)
{
  uint8_t data;
  Wire.beginTransmission(VCNL4000_ADDRESS);
#if ARDUINO >= 100
  Wire.write(address);
#else
  Wire.send(address);
#endif
  Wire.endTransmission();
  delayMicroseconds(170);  // delay requerido
  Wire.requestFrom(VCNL4000_ADDRESS, 1);
  while(!Wire.available());
 #if ARDUINO >= 100
  return Wire.read();
#else
  return Wire.receive();
#endif
}
 // lee 2 byte desde la direccion de VCNL4000
uint16_t read16(uint8_t address)
{
  uint16_t data;
   Wire.beginTransmission(VCNL4000_ADDRESS);
#if ARDUINO >= 100
  Wire.write(address);
#else
  Wire.send(address);
#endif
  Wire.endTransmission();
   Wire.requestFrom(VCNL4000_ADDRESS, 2);
  while(!Wire.available());
#if ARDUINO >= 100
  data = Wire.read();
  data <<= 8;
  while(!Wire.available());
  data |= Wire.read();
#else
  data = Wire.receive();
  data <<= 8;
  while(!Wire.available());
  data |= Wire.receive();
#endif
   return data;
}
 // escribe 1 byte
void write8(uint8_t address, uint8_t data)
{
  Wire.beginTransmission(VCNL4000_ADDRESS);
#if ARDUINO >= 100
  Wire.write(address);
  Wire.write(data);
#else
  Wire.send(address);
  Wire.send(data);
#endif
  Wire.endTransmission();
}

Siguiendo con el tutorial a continuación  se muestra cómo es que debe verse la información en la terminal, en este caso la terminal de la placa ARDUINO MEGA.

En esta imagen vemos los valores que nos retorno el sensor para mostrar en la pantalla serial, en este caso vemos que los valores de proximidad son altos por eso el sensor manda un estado alto al LED que indica su distancia con el objeto.

serialdos

Imagen 7. Monitor serial con datos de sensor VCNL4000 – proximidad

En la segunda imagen vemos el mismo caso pero para el sensor de luz ambiental lo que nos indica si los valores están cerca el valor definido, este mandara un cambio de estado al LED dando a entender si no encuentra luz encenderá al LED y en caso contrario lo enciende.

serialuno

Imagen 8. Monitor serial con datos de sensor VCNL4000 – luz ambiental

Imágenes demostrativas de cambio de estado de los sensores

En esta primer imagen vemos que esta encendido el LED verde puesto a que los parámetros que se estableció y en la segunda vemos el caso contrario para sensor siendo afectados por las variables.

demostrativa1

Imagen 9. Demostración en físico de funcionamiento de sensor VCNL4000

Imagen 10. Demostración en físico de funcionamiento de sensor VCNL4000

Imagen 10. Demostración en físico de funcionamiento de sensor VCNL4000

Sitios de interes

Código completo de sensor VCNL4000

//TUTORIAL de comunicacion con sensor de proximidad y luz ambiental
//(VCNL4000) - HETPRO.
//conexion:
//SENSOR - ARDUINO(MEGA)
//VDD -- 3.3-5V
//GDN -- GND
//SCL -- 21 (RELOJ DE I2C )
//SDA -- 20 (DATO DE I2C)
//3.3V -- NC

//LED -- ARDUINO
//ESTADO DE SENSOR DE APROXIMIDAD / PIN13
//ESTADO DE SENSOR DE LUZ AMBIENTAL / PIN12

#include <Wire.h> //agregando libreria de I2C

//ESTABLECIENDO LA DIRECCION DE I2C PARA COMUNICACION CON SENSOR
#define VCNL4000_ADDRESS 0x13

//ESTABLECIENDO COMANDOS Y CONSTANTES
#define VCNL4000_Comando 0x80
#define VCNL4000_IDSensor 0x81
#define VCNL4000_IRLED 0x83
#define VCNL4000_ParametroLAmbiente 0x84
#define VCNL4000_DatoLAmbiente 0x85
#define VCNL4000_DatoAproximidadA 0x87
#define VCNL4000_SenalFreq 0x89
#define VCNL4000_AjusteAproximidad 0x8A

#define VCNL4000_3M125 0
#define VCNL4000_1M5625 1
#define VCNL4000_781K25 2
#define VCNL4000_390K625 3

#define VCNL4000_MedicionLAmbiente 0x10
#define VCNL4000_MedicionAproximidad 0x08
#define VCNL4000_LAmbienteLista 0x40
#define VCNL4000_AproximidadLista 0x20

//parpadear led a cierta distancia
const int LEDAPROX =13;

//led que dira si hay luz de ambiente
const int LEDLUZA =12;

//el scipt le da brillo y el valor de distancia tambien
//son regresados al monitor serie por lo que
//los valores de limite pueden ser determinados (distancia y luz-brillo)

//ESTABLECIMIENTO de umbral para aproximidad en mm
const int minAprox = 1500;

//ESTABLECIMIENTO de umbral para brillo
const int minLAmbient = 200;

//estado actual de LED
int EstadoLED = LOW;

void setup (){
Serial.begin(9600);
Serial.println("SENSOR VCNL4000 LUZ AMBIENTAL Y PROXIMIDAD - HETPRO");
Wire.begin();

uint8_t rev = read8(VCNL4000_IDSensor);

if ((rev & 0xF0) != 0x10){
Serial.println("Sensor no encontrado ");
while(1);
}

write8(VCNL4000_IRLED, 20); //establece, a 20 x 10mA = 200mA
Serial.print("Corriente de LED IR = ");
Serial.print(read8(VCNL4000_IRLED) * 10, DEC);
Serial.println(" mA");

Serial.print("Configuracion de frecuencia de proximidad = ");
uint8_t freq = read8(VCNL4000_SenalFreq);
if (freq == VCNL4000_3M125) Serial.println("3.125 MHz");
if (freq == VCNL4000_1M5625) Serial.println("1.5625 MHz");
if (freq == VCNL4000_781K25) Serial.println("781.25 KHz");
if (freq == VCNL4000_390K625) Serial.println("390.625 Khz");

write8(VCNL4000_AjusteAproximidad, 0x81);
Serial.print("Registro de ajuste de aproximidad = ");
Serial.println(read8(VCNL4000_AjusteAproximidad), HEX);

//ESTABLECIENDO LOS DOS LED COMO SALIDA
pinMode(LEDAPROX, OUTPUT);
pinMode(LEDLUZA, OUTPUT);
}

void loop(){
//obteniendo dato de luz de ambiente
write8(VCNL4000_Comando, VCNL4000_MedicionLAmbiente | VCNL4000_MedicionAproximidad);
while (1){
uint8_t result = read8(VCNL4000_Comando);
if ((result & VCNL4000_LAmbienteLista)&&(result & VCNL4000_AproximidadLista)) {

Serial.print("Luz de Ambiente = ");
unsigned int ambient = read16(VCNL4000_DatoLAmbiente);
Serial.print(ambient);
Serial.print("\t\tProximidad = ");
unsigned int prox = read16(VCNL4000_DatoAproximidadA);
Serial.println(prox);

//si el valor de brillo es mas que el valor establecido
//el pin debe de estar en estado bajo.
if(ambient > minLAmbient){
digitalWrite(LEDLUZA, LOW);
//si el valor de distancia es por encima de los establecido
//el pin estara en estado alto.
if (prox > minAprox) {
EstadoLED = HIGH;
}
}
else
{
//Si a su vez el brillo es menor de lo establecido, entonces
//el pin de reset debe esperar por un seg el estado bajo del pin de parpadeo
digitalWrite(LEDLUZA, HIGH);
EstadoLED= LOW;
delay(1000);
}
break;
}
delay(1000);
}

//envia el estado al led
digitalWrite(LEDAPROX, EstadoLED);
delay(50);
}

uint16_t readProximity() {
write8(VCNL4000_Comando, VCNL4000_MedicionAproximidad);
while (1) {
uint8_t result = read8(VCNL4000_Comando);
if (result & VCNL4000_AproximidadLista) {
return read16(VCNL4000_DatoAproximidadA);
}
delay(1000);
}
}
//lee un byte desde la direccion de VCNL4000
uint8_t read8(uint8_t address)
{
uint8_t data;
Wire.beginTransmission(VCNL4000_ADDRESS);
#if ARDUINO >= 100
Wire.write(address);
#else
Wire.send(address);
#endif
Wire.endTransmission();
delayMicroseconds(170);  // delay requerido
Wire.requestFrom(VCNL4000_ADDRESS, 1);
while(!Wire.available());
#if ARDUINO >= 100
return Wire.read();
#else
return Wire.receive();
#endif
}
// lee 2 byte desde la direccion de VCNL4000
uint16_t read16(uint8_t address)
{
uint16_t data;
Wire.beginTransmission(VCNL4000_ADDRESS);
#if ARDUINO >= 100
Wire.write(address);
#else
Wire.send(address);
#endif
Wire.endTransmission();
Wire.requestFrom(VCNL4000_ADDRESS, 2);
while(!Wire.available());
#if ARDUINO >= 100
data = Wire.read();
data <<= 8;
while(!Wire.available());
data |= Wire.read();
#else
data = Wire.receive();
data <<= 8;
while(!Wire.available());
data |= Wire.receive();
#endif
return data;
}
// escribe 1 byte
void write8(uint8_t address, uint8_t data)
{
Wire.beginTransmission(VCNL4000_ADDRESS);
#if ARDUINO >= 100
Wire.write(address);
Wire.write(data);
#else
Wire.send(address);
Wire.send(data);
#endif
Wire.endTransmission();
}

4 Comments

  1. Israel octubre 26, 2015
    • Saul Diaz octubre 27, 2015
  2. Carlos noviembre 25, 2017
    • Administrador noviembre 25, 2017

Escríbenos tus dudas o comentarios

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Usamos Cookies en nuestro sitio WEB

Por favor confirma, si aceptas nuestras cookies de rastreo. También puedes negar el uso de cookies de rastreo y seguir navegando sin que ninguna información sea enviada a servicios de terceros.