// Draw humidity and temperature traces
// Full trace takes 3.5 minutes at 2 seconds per reading (fastest) with 100 readings
// Increase "timeout" to lengthen DHT history: 30 minutes trace use "timeout = 17000"
#include <DHT.h> // https://github.com/adafruit/DHT-sensor-library
#include <Adafruit_SSD1306.h> // https://github.com/adafruit/Adafruit_SSD1306
// #include "bitmap.h" // local graphic objects
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define I2C_ADDRESS 0x3C
#define DHTTYPE DHT22 // DHT22, AM2302, AM2321
#define DHTpin 11
DHT dht(DHTpin, DHTTYPE); // create DHT object
float h, c, f;
int oldH = -1, oldC;
int traceStart = 26, traceEnd = 125, trace = traceStart; // line trace
unsigned long timer, timeout = 2000; // time between DHT reading. 17000 takes about 30 minutes
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); // create OLED object
void setup() {
Serial.begin(115200); // initialize serial communications
dht.begin(); // initialize DHT
display.begin(SSD1306_SWITCHCAPVCC, I2C_ADDRESS);
// checkOLED(); // initialize and verify OLED object
display.clearDisplay();
display.display();
drawDisplay();
}
void loop() {
if (millis() - timer > timeout) { // time between DHT reading
timer = millis();
h = dht.readHumidity();
c = dht.readTemperature();
f = dht.readTemperature(true);
checkDHThcf();
if (trace > traceEnd) // keep traces inside box
trace = traceStart; // restart traces
int hMap = map(h, 100, 0, 2, 29); // DHT humidity HI/LO range to OLED LO/HI range
int cMap = map(c, 80, -40, 35, 61); // DHT temperature HI/LO range to OLED LO/HI range
if (oldH != h) // erase oldH, write h
displayHC(oldH, h, 'h');
if (oldC != c)
displayHC(oldC, c, 'c'); // erase oldC, write c
display.drawLine(trace, 2, trace, 29, 0); // erase h trace
display.drawLine(trace, 35, trace, 61, 0); // erase c trace
display.display();
display.drawPixel(trace, hMap, WHITE); // plot mapped h trace
display.drawPixel(trace, cMap, WHITE); // plot mapped c trace
display.display();
oldH = h; // store current readings
oldC = c;
trace++; // move trace right
}
}
void displayHC (int oldHC, int newHC, char hc) {
int value; // incoming data
int row; // OLED row for data
if (hc == 'h')
row = 12;
else
row = 45;
for (int color = 0; color < 2; color++) {
if (color == 0)
value = oldHC;
else
value = newHC;
display.setTextColor(color);
display.setCursor(2, row);
if (value >= -10 && value < 0) display.print(F(" "));
if (value >= 0 && value < 10) display.print(F(" "));
if (value >= 10 && value < 100) display.print(F(" "));
display.print(value);
}
}
void drawDisplay() {
display.setTextSize(1); // smallest font
display.setTextColor(WHITE);
display.drawRect(0, 0, 128, 32, WHITE); // upper box
display.drawRect(0, 33, 128, 31, WHITE); // lower box
// int x = 26, ytop = 1, ybot = 63; // verify text alignment only
// display.drawLine(x, ytop, x, ybot, WHITE); // right-alignment
display.setCursor(8, 2); display.print(F("100"));
display.setCursor(20, 12); display.print(F("%"));
display.setCursor(20, 22); display.print(F("0"));
display.setCursor(14, 35); display.print(F("80"));
display.setCursor(20, 45); display.print(F("C"));
display.setCursor(8, 55); display.print(F("-40"));
display.display();
}
void checkDHThcf() {
if (isnan(h) || isnan(c) || isnan(f)) {
Serial.println(F("Failed to read DHT."));
while (1); // hold here after device failure
}
}
void checkOLED() {
if (!display.begin(SSD1306_SWITCHCAPVCC, I2C_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
while (1); // hold here after device failure
}
}
/*
display.drawLine(StartX, StartY, EndX, EndY, WHITE);
display.drawRect(StartX, StartY, Width in Pixels, Height in Pixels, WHITE);
display.drawCircle(CenterX, CenterY, Radius in Pixels, WHITE);
display.drawTriangle(FirstX , FirstY, SecondX, SecondY, ThirdX, ThirdY, WHITE);
*/