OLED + VCNL4010 Proximity sensor over I2C

By Dan Chen, January 3, 2017

What is I2C

The I2C bus was designed by Philips in the early ’80s to allow easy communication between components which reside on the same circuit board. Only two bus lines are required and no strict baud rate requirements.

Parts List

VCNL4010 Proximity/Light sensor
https://www.adafruit.com/products/466

Monochrome 128×32 I2C OLED graphic display
https://www.adafruit.com/products/931

MicroController
Atmel ATSAMD21G18 ARM Cortex M0, Atmega328 or 32u4
Adafruit’s Feather, Arduino Uno …

 

Wiring I2C

  • GND goes to ground
  • Vin goes to 5V
  • SDA to I2C Data (on the Uno, this is A4 on the Mega it is 20 and on the Leonardo digital 2)
  • SCL  to I2C Clock(on the Uno, this is A5 on the Mega it is 21 and on the Leonardo digital 3)
  • RST any Digital Pin

Other Controllers
Uno, Ethernet A4 (SDA), A5 (SCL)
Mega2560 20 (SDA), 21 (SCL)
Leonardo 2 (SDA), 3 (SCL)
Due 20 (SDA), 21 (SCL), SDA1, SCL1

 

Code and Library

 

Library

I used the two library from the links below, add it to your Arduino Library.

I2c Reference for OLED https://github.com/adafruit/Adafruit_SSD1306

Code Reference for Adafruit_VCNL4010 https://github.com/adafruit/Adafruit_VCNL4010

 

Combine Code

I combine the OLED and VCNL4010 Proximity sensor code below

Download

#include 
#include 
#include 
#include 

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2
#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH  16

#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif


#include 
#include "Adafruit_VCNL4010.h"

Adafruit_VCNL4010 vcnl;

#if defined(ARDUINO_ARCH_SAMD)
// for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
#define Serial SerialUSB
#endif

int data[128];

void setup() {
  Serial.begin(9600);
  Serial.println("VCNL4010 test");

  if (! vcnl.begin()) {
    Serial.println("Sensor not found :(");
    while (1);
  }
  Serial.println("Found VCNL4010");
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x32)

}


void loop() {


  // text display tests
  display.setCursor(0, 0);
  display.setTextSize(1);
  display.setTextColor(WHITE);

  int pval = map(vcnl.readProximity(), 2093, 65535, 0, 128);
  int pval2 = map(vcnl.readProximity(), 2093, 65535, 1, 20);

  display.println(pval);

  // array push, shift entire array to left by one spot
  for (int i = 1; i < 128; i++) {
    data[i - 1] = data[i];
  }

  // add new data to the end of the array
  data[127] = pval2;

  // draw bar graph
  for (int i = 0; i < 128; i = i + 1) {
    display.fillRect(i, 32 - data[i], 1, 20, WHITE);
  }



  // shows the bar
  display.fillRect(0, 10, pval, 1, WHITE);
  display.display();

  delay(20);
  display.clearDisplay();


}





Code Explained

Push Array

To graph the data, the latest data-bar is displayed at the end of the screen column, that means we need to constantly push the array to the left when the new data comes in. Like this 0001, 0012, 0123, 1234.

This pushes array to left by one spot, doing it for the entire array
//128 is the size of the screen across
for (int i = 1; i < 128; i++) {
data[i – 1] = data[i];
}

// add new data to the end of the array
data[127] = pval2;

// draw bar graph
for (int i = 0; i < 128; i = i + 1) {
display.fillRect(i, 32 – data[i], 1, 20, WHITE);
}