Skip to content

Instantly share code, notes, and snippets.

@bboyho
Last active May 29, 2020 20:08
Show Gist options
  • Save bboyho/3d53e3dee5a571d3ec8d9b499b019525 to your computer and use it in GitHub Desktop.
Save bboyho/3d53e3dee5a571d3ec8d9b499b019525 to your computer and use it in GitHub Desktop.
/******************************************************************************
Digital Indoor Temperature Monitor with the TMP102
Written by: Ho Yun "Bobby" Chan
@ SparkFun Electronics
Date: Mar 26, 2020
Description: This sketch configures temperature sensors and prints the
temperature in degrees celsius and fahrenheit to the Qwiic microOLED.
Simply adjust the `output_select` to view the °C, °F, or both. You can
also output the values to the Serial Monitor or Plotter at 115200 baud
to view the data. There is also a demo mode that displays each output
on the microOLED with a progress bar at the bottom.
Resources/Libraries:
Wire.h (included with Arduino IDE)
SparkFunTMP102.h (included in the src folder) http://librarymanager/All#SparkFun_TMP102
SFE_MicroOLED.h (included in the src folder) http://librarymanager/All#SparkFun_micro_OLED
Development Environment Specifics:
Arduino 1.8.10+
License:
This code is released under the MIT License (http://opensource.org/licenses/MIT)
Distributed as-is; no warranty is given.
******************************************************************************/
#include <Wire.h> // Used to establish SerialUSB communication on the I2C bus
#include <SparkFunTMP102.h> // Used to send and recieve specific information from our sensor
#include <SFE_MicroOLED.h> // Include the SFE_MicroOLED library
//#define SerialUSB Serial //Uncomment if you are not using a native USB like the Atmega32U4 or SAMD21
///////////////////////////////
///////// micro OLED //////////
///////////////////////////////
#define PIN_RESET 7 // A pin needs to be declared even though we are not physically connecting to the Qwiic micro OLED via I2C
#define DC_JUMPER 1
MicroOLED oled(PIN_RESET, DC_JUMPER); // I2C declaration
///////////////////////////////
/////////// TMP102 ////////////
///////////////////////////////
// The default address of the device is 0x48 = (GND)
TMP102 sensor; // Initalize sensor
//Set up variables to hold temperature
float tempC = 0;
float tempF = 0;
//0 = output degrees °C
//1 = output degrees °F
//2 or any other number = output degrees °C and °F
int output_select = 3; //select output
///////////////////////////////
// Display Mode Page Control //
///////////////////////////////
// This enum defines all of our display modes and their order.
enum t_displayModes {
DISPLAY_BIG_C,
DISPLAY_BIG_F,
DISPLAY_CUBE,
DISPLAY_C_F
};
const int NUM_DISPLAY_MODES = 4; // 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
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
///////////////////////////////
/////// Initialize Cube ///////
///////////////////////////////
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() {
delay(100);
Wire.begin();
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.
SerialUSB.begin(115200); // Start SerialUSB communication at 115200 baud
Wire.setClock(400000); // Set clock speed to be the fastest for better communication (fast mode)
if (sensor.begin() == true ) // Function to check if the sensor will correctly self-identify with the proper Device ID/Address
{
//SerialUSB.println("Begin");
if (output_select == 0 ) {
SerialUSB.println("TMP102[°C]");
}
else if (output_select == 1) {
SerialUSB.println("TMP102[°F]");
}
else {
SerialUSB.print("TMP102[°C]");
SerialUSB.print(",");
SerialUSB.println("TMP102[°F]");
}
}
else
{
SerialUSB.println("Device failed to setup- Freezing code.");
while (1); // Runs forever
}
sensor.wakeup(); // wake the sensor up, we do not care about low power mode since we will constantly be reading the temperature
}//end setup
void loop() {
//get TMP102 sensor readings
tempC = sensor.readTempC();
tempF = sensor.readTempF();
//get time based on how long the Arduino has been running
currentMillis = millis();
if (output_select == 0 ) {
oled.clear(PAGE); // Clear the display
displayC();
oled.display();
// Print temperature in °C
//SerialUSB.print("Temperature in Celsius: ");
SerialUSB.println(tempC);//TMP102 temperature
}
else if (output_select == 1) {
oled.clear(PAGE); // Clear the display
displayF();
oled.display();
// Print temperature in °F
//SerialUSB.print("Temperature in Fahrenheit: ");
SerialUSB.println(tempF);
}
else if (output_select == 2) {
//Display both temperatures as °C and °F
oled.clear(PAGE); // Clear the display
oled.setCursor(0, 0); // Set cursor to top-left
oled.setFontType(0); // Smallest font
oled.print(" Room Temp "); // Print
oled.setCursor(0, 16); // Set cursor to middle-ish
oled.setFontType(1); // medium font
oled.print(String(tempC, 2) + " C"); // Print temp, assuming that it is within room temp in tens
oled.print(String(tempF, 2) + " F");// Print temp, assuming that it is within room temp in tens
oled.circle(50, 17, 1); //"degree" sign after output values
oled.circle(50, 33, 1); //"degree" sign after output values
oled.display();
//TMP102 temperature with comma delimiter for graphing or datalogging
SerialUSB.print(tempC);
SerialUSB.print(","); //seperator
SerialUSB.println(tempF);
}
else {
// 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;
}
oled.clear(PAGE); // Clear the display
updateDisplay();
displayProgressBar(); // Draws a progress bar at the bottom of the screen
oled.display();
//TMP102 temperature with comma delimiter for graphing or datalogging
SerialUSB.print(tempC);
SerialUSB.print(","); //seperator
SerialUSB.println(tempF);
}
//delay(5); // Delay added for easier readings
}//end loop
//This function updates the display if we are scrolling through all displays with a progress bar.
void updateDisplay() {
switch (displayMode)
{
case DISPLAY_BIG_C:
displayC();
break;
case DISPLAY_BIG_F:
displayF();
break;
case DISPLAY_CUBE: //used as a screensaver
drawCube();
break;
case DISPLAY_C_F:
displayC_F();
break;
}
}
// This function displays the temperature in °C as big digits.
void displayC() {
//oled.clear(PAGE); // Clear the display, this is already called before we enter this function
oled.setCursor(0, 0); // Set cursor to top-left
oled.setFontType(0); // Smallest font
oled.print(" Room Temp "); // Print
oled.setCursor(0, 16); // Set cursor to middle-ish
oled.print(" "); // Print
oled.setFontType(2); // medium font
oled.print(tempC); // Print temp, assuming that it is within room temp in tens
oled.setCursor(0, 38); // Set cursor to middle-ish
oled.setFontType(0); // Smallest font
oled.print(" deg C"); // Print
//oled.display(); // Update the display, this is already called after we exit this function
}
// This function displays the temperature in °F as big digits.
void displayF() {
//oled.clear(PAGE); // Clear the display, this is already called before we enter this function
oled.setCursor(0, 0); // Set cursor to top-left
oled.setFontType(0); // Smallest font
oled.print(" Room Temp "); // Print
oled.setCursor(0, 16); // Set cursor to middle-ish
oled.print(" "); // Print
oled.setFontType(2); // medium font
oled.print(tempF); // Print temp, assuming that it is within room temp in tens
oled.setCursor(0, 38); // Set cursor to middle-ish
oled.setFontType(0); // Smallest font
oled.print(" deg F"); // Print
//oled.display(); // Update the display, this is already called after we exit this function
}
// This function animates a cube. This is used as a quick screensaver.
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 displays both °C and °F on the microOLED
void displayC_F() {
//oled.clear(PAGE); // Clear the display, this is already called before we enter this function
oled.setCursor(0, 0); // Set cursor to top-left
oled.setFontType(0); // Smallest font
oled.print(" Room Temp "); // Print
oled.setCursor(0, 16); // Set cursor to middle-ish
oled.setFontType(1); // medium font
oled.print(String(tempC, 2) + " C"); // Print temp, assuming that it is within room temp in tens
oled.print(String(tempF, 2) + " F");// Print temp, assuming that it is within room temp in tens
oled.circle(50, 17, 1); //"degree" sign after output values
oled.circle(50, 33, 1); //"degree" sign after output values
//oled.display(); // Update the display, this is already called after we exit this function
}
// 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