Skip to content

Instantly share code, notes, and snippets.

@bboyho
Last active December 15, 2021 05:57
Show Gist options
  • Save bboyho/0eb798aee9f0e1d3e43c0143a97ca373 to your computer and use it in GitHub Desktop.
Save bboyho/0eb798aee9f0e1d3e43c0143a97ca373 to your computer and use it in GitHub Desktop.
/*
HTU21D Humidity Sensor Example Code
By: Nathan Seidle
SparkFun Electronics
Date: September 15th, 2013
License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).
Uses the HTU21D library to display the current humidity and temperature
Open serial monitor at 9600 baud to see readings. Errors 998 if not sensor is detected. Error 999 if CRC is bad.
Hardware Connections (Breakoutboard to Arduino):
-VCC = 3.3V
-GND = GND
-SDA = A4 (use inline 330 ohm resistor if your board is 5V)
-SCL = A5 (use inline 330 ohm resistor if your board is 5V)
*/
#include <Wire.h>
#include "SparkFunHTU21D.h" // include HTU21D library
//Create an instance of the object
HTU21D myHumidity;
float humd = 0;
#include <SFE_MicroOLED.h> // Include the SFE_MicroOLED library
#define PIN_RESET 7
#define DC_JUMPER 1
MicroOLED oled(PIN_RESET, DC_JUMPER); // I2C declaration
#include "SparkFunBME280.h"
BME280 mySensor;
float temp_C = 0;
float temp_F = 0;
#include <SparkFunCCS811.h>
#define CCS811_ADDR 0x5B //Default I2C Address
CCS811 myCCS811(CCS811_ADDR);
#include "SparkFun_VL53L1X.h"
//Optional interrupt and shutdown pins.
#define SHUTDOWN_PIN 2
#define INTERRUPT_PIN 3
SFEVL53L1X distanceSensor(Wire, SHUTDOWN_PIN, INTERRUPT_PIN);
int distance = 0;
int prevDistance = 0;
int currentDistance = 0;
float distanceInches = 0;
float distanceFeet = 0;
///////////////////////////////
// Display Mode Page Control //
///////////////////////////////
// This enum defines all of our display modes and their order.
enum t_displayModes {
DISPLAY_HTU21D,
DISPLAY_BME280_1,
DISPLAY_BME280_2,
DISPLAY_CCS811,
DISPLAY_VL53L1X,
DISPLAY_CUBE
};
const int NUM_DISPLAY_MODES = 6; // Number of values defined in enum above
volatile int displayMode = NUM_DISPLAY_MODES - 1; // Keeps track of current display page
const unsigned long DISPLAY_UPDATE_RATE = 4000; // Cycle display every 5 seconds
unsigned long lastDisplayUpdate = 0; // Stores time of last display update
unsigned long currentMillis = 0; // Stores time of last display update
boolean activity = true; //used to keep track of movement or button press
const unsigned long noActivityMillis = NUM_DISPLAY_MODES * (DISPLAY_UPDATE_RATE + 1000); //used to compare amount of time when no activity to turn of screen
unsigned long lastActivityMillis = 0;
float percentage = 0; //store percent for progress bar
int progressWidth = 0; // Width of progress bar depends on the [% * (64 pixels wide)]
int progressY = 0; //location of the progress bar at the botton of the microOLED
int SCREEN_WIDTH = oled.getLCDWidth();
int SCREEN_HEIGHT = oled.getLCDHeight();
float d = 3;
float px[] = {
-d, d, d, -d, -d, d, d, -d
};
float py[] = {
-d, -d, d, d, -d, -d, d, d
};
float pz[] = {
-d, -d, -d, -d, d, d, d, d
};
float p2x[] = {
0, 0, 0, 0, 0, 0, 0, 0
};
float p2y[] = {
0, 0, 0, 0, 0, 0, 0, 0
};
float r[] = {
0, 0, 0
};
#define SHAPE_SIZE 600
// Define how fast the cube rotates. Smaller numbers are faster.
// This is the number of ms between draws.
//#define ROTATION_SPEED 0
void setup()
{
Serial.begin(9600);
Serial.println("HTU21D, BME280, CCS811, VL53lx, microOLED Example!");
delay(100);
myHumidity.begin();// Wire.begin() is in HTU21D library
delay(100);
mySensor.beginI2C();//join BME280
delay(100);
myCCS811.begin();//join CCS811
//Wire.setClock(400000); // Set clock speed to be the fastest for better communication (fast mode)
delay(100);
if (distanceSensor.init() == false) {
// Serial.println("Sensor online!");
}
oled.begin(); // Initialize the OLED
oled.clear(ALL); // Clear the display's internal memory
oled.display(); // Display what's in the buffer (splashscreen)
delay(1000); // Delay 1000 ms
oled.clear(PAGE); // Clear the buffer.
}
void loop()
{
humd = myHumidity.readHumidity();
temp_C = myHumidity.readTemperature();
temp_F = temp_C * (9.0 / 5.0) + 32.0;
distanceSensor.startRanging(); //Write configuration bytes to initiate measurement
distance = distanceSensor.getDistance(); //Get the result of the measurement from the sensor
distanceSensor.stopRanging();
currentDistance = distance;
distanceInches = distance * 0.0393701;
distanceFeet = distanceInches / 12.0;
//get time based on how long the Arduino has been running
currentMillis = millis();
// Displaying °C and °F with a scroll bar
// Another method of updating display:
// The display will cycle itself every DISPLAY_UPDATE_RATE seconds
if ( currentMillis >= (lastDisplayUpdate + DISPLAY_UPDATE_RATE + 1000) )
{
// Increment displayMode, next time through a new page will be displayed:
displayMode = (displayMode + 1) % NUM_DISPLAY_MODES;
// Update lastDisplayTime, so we don't come back for DISPLAY_UPDATE_RATE seconds
lastDisplayUpdate = currentMillis;
}
//check to see if something got in front of the ToF sensor,
if (abs(currentDistance - prevDistance) > 500) {
activity = true;
lastActivityMillis = currentMillis;
}
if(activity == true && (( currentMillis - lastActivityMillis ) < noActivityMillis)) {
// display
oled.clear(PAGE); // Clear the display
updateDisplay();
displayProgressBar(); // Draws a progress bar at the bottom of the screen
oled.display();
}
else
{
//if nothing got in front of the ToF sensor, don't display anything
oled.clear(PAGE); // Clear the display}
oled.display();
activity = false;
}
prevDistance = currentDistance;
Serial.print(F("Time:"));
Serial.print(millis());
Serial.print(F(" Temperature:"));
Serial.print(temp_C, 1);
Serial.print(F("C "));
Serial.print(temp_F, 1);
Serial.print(F("F"));
Serial.print(F(" Humidity:"));
Serial.print(humd, 1);
Serial.println("%");
Serial.print(F(" Pressure: "));
Serial.print(mySensor.readFloatPressure(), 0);
Serial.print(" Pa");
Serial.print(F(" Alt: "));
Serial.print(mySensor.readFloatAltitudeMeters(), 1);
Serial.print(mySensor.readFloatAltitudeFeet(), 1);
Serial.print(" Ft");
Serial.print(F(" Temp: "));
Serial.print(mySensor.readTempF(), 2);
Serial.print(F(" F "));
Serial.print(mySensor.readTempC(), 2);
Serial.print(F(" C "));
Serial.print(F("Humidity: "));
Serial.print(mySensor.readFloatHumidity(), 0);
Serial.print(" %");
Serial.print(F("Distance(mm): "));
Serial.print(distance);
Serial.print(F("\tDistance(ft): "));
Serial.print(distanceFeet, 2);
Serial.println();
//delay(1000);
}//end loop
void updateDisplay() {
switch (displayMode)
{
case DISPLAY_HTU21D:
displayHTU21D();
break;
case DISPLAY_BME280_1:
displayBME280_1();
break;
case DISPLAY_BME280_2:
displayBME280_2();
break;
case DISPLAY_CCS811:
displayCCS811();
break;
case DISPLAY_VL53L1X:
displayVL53L1X();
break;
case DISPLAY_CUBE:
drawCube();
break;
}
}
void displayHTU21D() {
oled.setCursor(0, 0); // Set cursor to top-left
oled.setFontType(0); // Smallest font
oled.print(F(" HTU21D")); // Print
oled.setFontType(1); // medium font
oled.setCursor(0, 8); // Set cursor to top-ish
oled.print(F(" C"));
oled.setCursor(0, 8); // Set cursor to top-ish
oled.print(String(temp_C, 2)); // Print temp, assuming that it is within room temp in tens
oled.setCursor(0, 21); // Set cursor to middle-ish
oled.print(F(" F"));
oled.setCursor(0, 21); // Set cursor to middle-ish
oled.print(String(temp_F, 2));// Print temp, assuming that it is within room temp in tens
oled.circle(50, 10, 1); //"degree" sign after output values
oled.circle(50, 22, 1); //"degree" sign after output values
oled.setCursor(0, 34); // Set cursor to bottom-ish
oled.print(F(" %RH"));
oled.setCursor(0, 34); // Set cursor to bottom-ish
oled.print(String(humd, 1)); // Print humid, assuming that it is within room temp in tens
}
void displayBME280_1() {
oled.setCursor(0, 0); // Set cursor to top-left
oled.setFontType(0); // Smallest font
oled.print(F(" BME280")); // Print
oled.setFontType(1); // medium font
oled.setCursor(0, 8); // Set cursor to middle-ish
oled.print(F(" C"));
oled.setCursor(0, 8); // Set cursor to top-ish
oled.print(String(mySensor.readTempC(), 2)); // Print temp, assuming that it is within room temp in tens
oled.setCursor(0, 21); // Set cursor to middle-ish
oled.print(F(" F"));
oled.setCursor(0, 21); // Set cursor to middle-ish
oled.print(String(mySensor.readTempF(), 2));// Print temp, assuming that it is within room temp in tens
oled.circle(50, 10, 1); //"degree" sign after output values
oled.circle(50, 22, 1); //"degree" sign after output values
oled.setCursor(0, 34); // Set cursor to bottom-ish
oled.print(F(" %RH"));
oled.setCursor(0, 34); // Set cursor to middle-ish
oled.print(String(mySensor.readFloatHumidity(), 1)); // Print humid, assuming that it is within room temp in tens
/*
oled.setCursor(0, 8); // Set cursor to top-left
oled.print(); // Print
oled.print("Pa"); // Print
oled.setCursor(0, 16); // Set cursor to middle-ish
oled.print(); // Print temp, assuming that it is within room temp in tens
oled.print(" ft"); // Print
*/
}
void displayBME280_2() {
oled.setCursor(0, 0); // Set cursor to top-left
oled.setFontType(0); // Smallest font
oled.print(F(" BME280")); // Print
oled.setFontType(1); // medium font
oled.setCursor(0, 8); // Set cursor to top-ish
oled.print(F(" Pa"));
oled.setCursor(0, 8); // Set cursor to top-ish
oled.print(String(mySensor.readFloatPressure(), 0)); // Print pressure, assuming that it is within room temp in tens
oled.setCursor(0, 21); // Set cursor to middle-ish
oled.print(F(" m"));
oled.setCursor(0, 21); // Set cursor to middle-ish
oled.print(String(mySensor.readFloatAltitudeMeters(), 1));// Print altitude, assuming that it is within room temp in tens
oled.setCursor(0, 34); // Set cursor to middle-ish
oled.print(F(" ft"));
oled.setCursor(0, 34); // Set cursor to middle-ish
oled.print(String(mySensor.readFloatAltitudeFeet(), 0));// Print altitude, assuming that it is within room temp in tens
}
void displayCCS811() {
if (myCCS811.dataAvailable())
{
//If so, have the sensor read and calculate the results.
//Get them later
myCCS811.readAlgorithmResults();
}
oled.setCursor(0, 0); // Set cursor to top-left
oled.setFontType(0); // Smallest font
oled.print(F(" CCS811")); // Print
oled.setCursor(0, 8); // Set cursor to middle-ish
oled.setFontType(1); // medium font
oled.print("CO2=" + String(myCCS811.getCO2())); // Print CO2, assuming that it is within room temp in tens
oled.setCursor(0, 21); // Set cursor to middle-ish
oled.print("tVOC=" + String(myCCS811.getTVOC()));// Print tVOC, assuming that it is within room temp in tens
}
void displayVL53L1X() {
oled.setCursor(0, 0); // Set cursor to top-left
oled.setFontType(0); // Smallest font
oled.print(F(" VL53L1X")); // Print
//assuming readings isn't bigger than 4 digits (5 digits if no decimal point)
oled.setFontType(1); // medium font
oled.setCursor(0, 8); // Set cursor to top-ish
oled.print(F(" mm")); // Print distance
oled.setCursor(0, 8); // Set cursor to top-ish
oled.print(distance); // Print distance
oled.setCursor(0, 21); // Set cursor to middle-ish
oled.print(F(" in")); // Print distance
oled.setCursor(0, 21); // Set cursor to middle-ish
if (distanceInches >= 100) {
oled.print(distanceInches, 1); // Print distance
}
else {
oled.print(distanceInches); // Print distance
}
oled.setCursor(0, 34); // Set cursor to bottom-ish
oled.print(F(" ft")); // Print distance
oled.setCursor(0, 34); // Set cursor to bottom-ish
oled.print(distanceFeet); // Print distance
}
void drawCube() {
r[0] = r[0] + 10 * PI / 180.0; // Add a degree
r[1] = r[1] + 10 * PI / 180.0; // Add a degree
r[2] = r[2] + 10 * PI / 180.0; // Add a degree
if (r[0] >= 360.0 * PI / 180.0) r[0] = 0;
if (r[1] >= 360.0 * PI / 180.0) r[1] = 0;
if (r[2] >= 360.0 * PI / 180.0) r[2] = 0;
for (int i = 0; i < 8; i++)
{
float px2 = px[i];
float py2 = cos(r[0]) * py[i] - sin(r[0]) * pz[i];
float pz2 = sin(r[0]) * py[i] + cos(r[0]) * pz[i];
float px3 = cos(r[1]) * px2 + sin(r[1]) * pz2;
float py3 = py2;
float pz3 = -sin(r[1]) * px2 + cos(r[1]) * pz2;
float ax = cos(r[2]) * px3 - sin(r[2]) * py3;
float ay = sin(r[2]) * px3 + cos(r[2]) * py3;
float az = pz3 - 150;
p2x[i] = SCREEN_WIDTH / 2 + ax * SHAPE_SIZE / az;
p2y[i] = SCREEN_HEIGHT / 2 + ay * SHAPE_SIZE / az;
}
for (int i = 0; i < 3; i++)
{
oled.line(p2x[i], p2y[i], p2x[i + 1], p2y[i + 1]);
oled.line(p2x[i + 4], p2y[i + 4], p2x[i + 5], p2y[i + 5]);
oled.line(p2x[i], p2y[i], p2x[i + 4], p2y[i + 4]);
}
oled.line(p2x[3], p2y[3], p2x[0], p2y[0]);
oled.line(p2x[7], p2y[7], p2x[4], p2y[4]);
oled.line(p2x[3], p2y[3], p2x[7], p2y[7]);
}
// This function draws a line at the very bottom of the screen showing how long
// it'll be before the screen updates.
// Based on Jim's micro OLED code used in the Photon SIK KIT => [ https://github.com/sparkfun/Inventors_Kit_For_Photon_Experiments/blob/master/11-OLEDApps/Code/02-WeatherForecast/WeatherApp.ino ]
void displayProgressBar() {
// Use lastDisplayUpdate's time, the time Arduino has been running
// (since we do not have an RTC, Internet, or GPS), and the total time
// per page (DISPLAY_UPDATE_RATE) to calculate what portion
// of the display bar needs to be drawn.
percentage = (float)(currentMillis - lastDisplayUpdate) / (float)DISPLAY_UPDATE_RATE;
//for debugging progress bar
//SerialUSB.println(currentMillis);
//SerialUSB.println(lastDisplayUpdate);
//SerialUSB.println(DISPLAY_UPDATE_RATE);
//SerialUSB.println(percentage);
//SerialUSB.println(oled.getLCDWidth());
// Mutliply that value by the total lcd width to get the pixel length of our line
progressWidth = percentage * oled.getLCDWidth();
// the y-position of our line should be at the very bottom of the screen:
progressY = oled.getLCDHeight() - 1;
// First, draw a blank line to clear any old lines out:
oled.line(0, progressY, oled.getLCDWidth(), progressY, BLACK, NORM);
// Next, draw our line:
oled.line(0, progressY, progressWidth, progressY);
//oled.display(); // Update the display, this is already called after we exit this function
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment