ESP8266/DHT: Difference between revisions
Jump to navigation
Jump to search
#0ff |
lightened code + library mod #0ff |
||
| Line 20: | Line 20: | ||
#define PIN_CE 16 //Pin 2 on LCD | #define PIN_CE 16 //Pin 2 on LCD | ||
#define PIN_DC 15 //Pin 3 on LCD | #define PIN_DC 15 //Pin 3 on LCD | ||
#define PIN_SD_CS 10 // Make sure "DIO" is selected | #define PIN_SD_CS 10 // Make sure "DIO" is selected | ||
#define DISPLAY_ENABLED true | #define DISPLAY_ENABLED true | ||
bool sdEnabled = false; | bool sdEnabled = false; | ||
WiFiClient client; | WiFiClient client; | ||
| Line 87: | Line 40: | ||
void setup() { | void setup() { | ||
pinMode(4, OUTPUT); | pinMode(4, OUTPUT); | ||
pinMode(5, OUTPUT); | pinMode(5, OUTPUT); | ||
| Line 109: | Line 58: | ||
display.setTextSize(1); | display.setTextSize(1); | ||
display.setTextColor(BLACK); | display.setTextColor(BLACK); | ||
display.display(); | display.display(); | ||
} | } | ||
| Line 121: | Line 69: | ||
digitalWrite(5, LOW); | digitalWrite(5, LOW); | ||
delay(450); | delay(450); | ||
if (millis() > timeout) | if (millis() > timeout) | ||
break; | break; | ||
| Line 127: | Line 74: | ||
wifiEnabled = WiFi.status() == WL_CONNECTED; | wifiEnabled = WiFi.status() == WL_CONNECTED; | ||
if (wifiEnabled) { | if (wifiEnabled) { | ||
ArduinoOTA.onStart([]() { | ArduinoOTA.onStart([]() { | ||
if (DISPLAY_ENABLED) { | if (DISPLAY_ENABLED) { | ||
display.clearDisplay(); | display.clearDisplay(); | ||
| Line 152: | Line 89: | ||
} | } | ||
}); | }); | ||
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { | ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { | ||
static uint8_t lastProgress = 0; | static uint8_t lastProgress = 0; | ||
static unsigned long nextTime = 0; | static unsigned long nextTime = 0; | ||
uint8_t p = (progress / (total / 100)); | uint8_t p = (progress / (total / 100)); | ||
if (p == 100 || (p != lastProgress && millis() > nextTime)) { | if (p == 100 || (p != lastProgress && millis() > nextTime)) { | ||
nextTime = millis() + 100; | nextTime = millis() + 100; | ||
| Line 176: | Line 111: | ||
lastProgress = p; | lastProgress = p; | ||
} else { | } else { | ||
if (DISPLAY_ENABLED) { | if (DISPLAY_ENABLED) { | ||
display.clearDisplay(); | display.clearDisplay(); | ||
| Line 191: | Line 125: | ||
}); | }); | ||
ArduinoOTA.onError([](ota_error_t error) { | ArduinoOTA.onError([](ota_error_t error) { | ||
if (DISPLAY_ENABLED) { | if (DISPLAY_ENABLED) { | ||
display.println("ERROR: " + String(error)); | display.println("ERROR: " + String(error)); | ||
| Line 204: | Line 132: | ||
}); | }); | ||
ArduinoOTA.begin(); | ArduinoOTA.begin(); | ||
if (DISPLAY_ENABLED) { | if (DISPLAY_ENABLED) { | ||
| Line 221: | Line 145: | ||
} | } | ||
if(!SD.begin(PIN_SD_CS)) { | if(!SD.begin(PIN_SD_CS)) { | ||
| Line 228: | Line 151: | ||
display.println("No SD found"); | display.println("No SD found"); | ||
display.display(); | display.display(); | ||
//TODO - change delay to loop w/yield | |||
delay(1000); | delay(1000); | ||
} else { | } else { | ||
//SD initialized | |||
sdEnabled = true; | |||
} | } | ||
dht.begin(); | dht.begin(); | ||
delay(100); | |||
} | } | ||
| Line 243: | Line 167: | ||
ArduinoOTA.handle(); | ArduinoOTA.handle(); | ||
handleHumidity(); | |||
delay(50); | delay(50); | ||
} | } | ||
void handleHumidity() { | void handleHumidity() { | ||
static unsigned long next = | static unsigned long next = 15000; | ||
unsigned long now = millis(); | unsigned long now = millis(); | ||
if (now > next) { | if (now > next) { | ||
next = now + | next = now + 10000; | ||
int h, c, f; | int h, c, f; | ||
h = dht.readHumidity(); | h = dht.readHumidity(); | ||
| Line 378: | Line 197: | ||
data += String(f); | data += String(f); | ||
File dataFile = SD.open(" | File dataFile = SD.open("HUMIDITY.TXT", FILE_WRITE); | ||
if (dataFile) { | if (dataFile) { | ||
| Line 387: | Line 206: | ||
digitalWrite(5, HIGH); | digitalWrite(5, HIGH); | ||
delay( | delay(100); | ||
digitalWrite(5, LOW); | digitalWrite(5, LOW); | ||
} | } | ||
} | } | ||
</pre> | |||
Slightly modified version of Adafruit Nokia Display library (Adafruit_PCD8544.cpp)... | |||
<pre> | |||
/********************************************************************* | |||
This is a library for our Monochrome Nokia 5110 LCD Displays | |||
Pick one up today in the adafruit shop! | |||
------> http://www.adafruit.com/products/338 | |||
These displays use SPI to communicate, 4 or 5 pins are required to | |||
interface | |||
Adafruit invests time and resources providing this open source code, | |||
please support Adafruit and open-source hardware by purchasing | |||
products from Adafruit! | |||
Written by Limor Fried/Ladyada for Adafruit Industries. | |||
BSD license, check license.txt for more information | |||
All text above, and the splash screen below must be included in any redistribution | |||
Hacked for ESP8266 by thex #0ff | |||
*********************************************************************/ | |||
//#include <Wire.h> | |||
#if defined(ESP8266) | |||
#include <pgmspace.h> | |||
#else | |||
#include <avr/pgmspace.h> | |||
#endif | |||
#if defined(ARDUINO) && ARDUINO >= 100 | |||
#include "Arduino.h" | |||
#else | |||
#include "WProgram.h" | |||
#endif | |||
#ifdef __AVR__ | |||
#include <util/delay.h> | |||
#endif | |||
#ifndef _BV | |||
#define _BV(x) (1 << (x)) | |||
#endif | |||
#include <stdlib.h> | |||
#include <Adafruit_GFX.h> | |||
#include "Adafruit_PCD8544.h" | |||
// the memory buffer for the LCD | |||
uint8_t pcd8544_buffer[LCDWIDTH * LCDHEIGHT / 8] = { | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFC, 0xFE, 0xFF, 0xFC, 0xE0, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, | |||
0xF8, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0x80, 0xC0, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x7F, | |||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0xFF, | |||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC7, 0xC7, 0x87, 0x8F, 0x9F, 0x9F, 0xFF, 0xFF, 0xFF, | |||
0xC1, 0xC0, 0xE0, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC, 0xFC, 0xFE, 0xFE, 0xFE, | |||
0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xE0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x80, 0xC0, 0xE0, 0xF1, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0x0F, 0x0F, 0x87, | |||
0xE7, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0x3F, 0xF9, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xFD, 0xFF, | |||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x0F, 0x07, 0x01, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0xF0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, | |||
0x7E, 0x3F, 0x3F, 0x0F, 0x1F, 0xFF, 0xFF, 0xFF, 0xFC, 0xF0, 0xE0, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, | |||
0xFF, 0xFC, 0xF0, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, | |||
0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0F, 0x1F, 0x3F, 0x7F, 0x7F, | |||
0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x1F, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
}; | |||
// reduces how much is refreshed, which speeds it up! | |||
// originally derived from Steve Evans/JCW's mod but cleaned up and | |||
// optimized | |||
//#define enablePartialUpdate | |||
#ifdef enablePartialUpdate | |||
static uint8_t xUpdateMin, xUpdateMax, yUpdateMin, yUpdateMax; | |||
#endif | |||
static void updateBoundingBox(uint8_t xmin, uint8_t ymin, uint8_t xmax, uint8_t ymax) { | |||
#ifdef enablePartialUpdate | |||
if (xmin < xUpdateMin) xUpdateMin = xmin; | |||
if (xmax > xUpdateMax) xUpdateMax = xmax; | |||
if (ymin < yUpdateMin) yUpdateMin = ymin; | |||
if (ymax > yUpdateMax) yUpdateMax = ymax; | |||
#endif | |||
} | } | ||
Adafruit_PCD8544::Adafruit_PCD8544(int8_t SCLK, int8_t DIN, int8_t DC, | |||
int8_t CS, int8_t RST) : Adafruit_GFX(LCDWIDTH, LCDHEIGHT) { | |||
_din = DIN; | |||
_sclk = SCLK; | |||
_dc = DC; | |||
_rst = RST; | |||
_cs = CS; | |||
} | } | ||
Adafruit_PCD8544::Adafruit_PCD8544(int8_t SCLK, int8_t DIN, int8_t DC, | |||
int8_t RST) : Adafruit_GFX(LCDWIDTH, LCDHEIGHT) { | |||
_din = DIN; | |||
_sclk = SCLK; | |||
_dc = DC; | |||
_rst = RST; | |||
_cs = -1; | |||
} | } | ||
Adafruit_PCD8544::Adafruit_PCD8544(int8_t DC, int8_t CS, int8_t RST): | |||
Adafruit_GFX(LCDWIDTH, LCDHEIGHT) { | |||
// -1 for din and sclk specify using hardware SPI | |||
_din = -1; | |||
_sclk = -1; | |||
_dc = DC; | |||
_rst = RST; | |||
_cs = CS; | |||
} | } | ||
if ( | // the most basic function, set a single pixel | ||
void Adafruit_PCD8544::drawPixel(int16_t x, int16_t y, uint16_t color) { | |||
if ((x < 0) || (x >= _width) || (y < 0) || (y >= _height)) | |||
return; | return; | ||
int16_t t; | |||
switch(rotation){ | |||
case 1: | |||
t = x; | |||
x = y; | |||
y = LCDHEIGHT - 1 - t; | |||
break; | |||
case 2: | |||
x = LCDWIDTH - 1 - x; | |||
y = LCDHEIGHT - 1 - y; | |||
break; | |||
case 3: | |||
t = x; | |||
x = LCDWIDTH - 1 - y; | |||
y = t; | |||
break; | |||
} | } | ||
if ((x < 0) || (x >= LCDWIDTH) || (y < 0) || (y >= LCDHEIGHT)) | |||
return; | |||
// x is which column | |||
if (color) | |||
pcd8544_buffer[x+ (y/8)*LCDWIDTH] |= _BV(y%8); | |||
else | |||
pcd8544_buffer[x+ (y/8)*LCDWIDTH] &= ~_BV(y%8); | |||
updateBoundingBox(x,y,x,y); | |||
} | |||
// the most basic function, get a single pixel | |||
uint8_t Adafruit_PCD8544::getPixel(int8_t x, int8_t y) { | |||
if ((x < 0) || (x >= LCDWIDTH) || (y < 0) || (y >= LCDHEIGHT)) | |||
return 0; | |||
return (pcd8544_buffer[x+ (y/8)*LCDWIDTH] >> (y%8)) & 0x1; | |||
} | } | ||
if ( | void Adafruit_PCD8544::begin(uint8_t contrast, uint8_t bias) { | ||
// | if (isHardwareSPI()) { | ||
// Setup hardware SPI. | |||
SPI.begin(); | |||
#ifdef ESP8266 | |||
// Datasheet says 4 MHz is max SPI clock speed | |||
SPI.setFrequency(400000); | |||
#else | |||
SPI.setClockDivider(PCD8544_SPI_CLOCK_DIV); | |||
#endif | |||
SPI.setDataMode(SPI_MODE0); | |||
SPI.setBitOrder(MSBFIRST); | |||
} | } | ||
else { | |||
// Setup software SPI. | |||
// Set software SPI specific pin outputs. | |||
pinMode(_din, OUTPUT); | |||
pinMode(_sclk, OUTPUT); | |||
#ifndef ESP8266 | |||
// Set software SPI ports and masks. | |||
// | clkport = portOutputRegister(digitalPinToPort(_sclk)); | ||
clkpinmask = digitalPinToBitMask(_sclk); | |||
mosiport = portOutputRegister(digitalPinToPort(_din)); | |||
mosipinmask = digitalPinToBitMask(_din); | |||
#endif | |||
} | } | ||
// Set common pin outputs. | |||
pinMode(_dc, OUTPUT); | |||
if (_rst > 0) | |||
pinMode(_rst, OUTPUT); | |||
if (_cs > 0) | |||
pinMode(_cs, OUTPUT); | |||
if ( | // toggle RST low to reset | ||
if (_rst > 0) { | |||
digitalWrite(_rst, LOW); | |||
delay(500); | |||
digitalWrite(_rst, HIGH); | |||
} | } | ||
// | // get into the EXTENDED mode! | ||
command(PCD8544_FUNCTIONSET | PCD8544_EXTENDEDINSTRUCTION ); | |||
// | // LCD bias select (4 is optimal?) | ||
command(PCD8544_SETBIAS | bias); | |||
// | // set VOP | ||
if ( | if (contrast > 0x7f) | ||
contrast = 0x7f; | |||
command( PCD8544_SETVOP | contrast); // Experimentally determined | |||
// | // normal mode | ||
command(PCD8544_FUNCTIONSET); | |||
// Set display to Normal | |||
command(PCD8544_DISPLAYCONTROL | PCD8544_DISPLAYNORMAL); | |||
// initial display line | |||
// set page address | |||
// set column address | |||
// write display data | |||
// | |||
// set up a bounding box for screen updates | |||
updateBoundingBox(0, 0, LCDWIDTH-1, LCDHEIGHT-1); | |||
// Push out pcd8544_buffer to the Display (will show the AFI logo) | |||
display(); | |||
} | |||
// | inline void Adafruit_PCD8544::spiWrite(uint8_t d) { | ||
if (isHardwareSPI()) { | |||
// Hardware SPI write. | |||
SPI.transfer(d); | |||
} | |||
else { | |||
#ifdef ESP8266 | |||
// Software SPI write with bit banging. | |||
for(uint8_t bit = 0x80; bit; bit >>= 1) { | |||
digitalWrite(_sclk, LOW); | |||
if (d & bit) digitalWrite(_din, HIGH); | |||
else digitalWrite(_din, LOW); | |||
digitalWrite(_sclk, HIGH); | |||
} | |||
#else | |||
// Software SPI write with bit banging. | |||
for(uint8_t bit = 0x80; bit; bit >>= 1) { | |||
*clkport &= ~clkpinmask; | |||
if(d & bit) *mosiport |= mosipinmask; | |||
else *mosiport &= ~mosipinmask; | |||
*clkport |= clkpinmask; | |||
} | |||
#endif | |||
} | |||
} | |||
bool Adafruit_PCD8544::isHardwareSPI() { | |||
return (_din == -1 && _sclk == -1); | |||
} | } | ||
void | void Adafruit_PCD8544::command(uint8_t c) { | ||
digitalWrite(_dc, LOW); | |||
if (_cs > 0) | |||
digitalWrite(_cs, LOW); | |||
spiWrite(c); | |||
if (_cs > 0) | |||
digitalWrite(_cs, HIGH); | |||
} | |||
void Adafruit_PCD8544::data(uint8_t c) { | |||
digitalWrite(_dc, HIGH); | |||
if (_cs > 0) | |||
digitalWrite(_cs, LOW); | |||
spiWrite(c); | |||
if (_cs > 0) | |||
digitalWrite(_cs, HIGH); | |||
} | |||
void Adafruit_PCD8544::setContrast(uint8_t val) { | |||
if (val > 0x7f) { | |||
val = 0x7f; | |||
} | } | ||
command(PCD8544_FUNCTIONSET | PCD8544_EXTENDEDINSTRUCTION ); | |||
command( PCD8544_SETVOP | val); | |||
command(PCD8544_FUNCTIONSET); | |||
} | |||
if ( | |||
// | |||
if ( | void Adafruit_PCD8544::display(void) { | ||
uint8_t col, maxcol, p; | |||
for(p = 0; p < 6; p++) { | |||
#ifdef enablePartialUpdate | |||
// check if this page is part of update | |||
if ( yUpdateMin >= ((p+1)*8) ) { | |||
continue; // nope, skip it! | |||
} | |||
if (yUpdateMax < p*8) { | |||
break; | |||
} | } | ||
#endif | |||
command(PCD8544_SETYADDR | p); | |||
#ifdef enablePartialUpdate | |||
col = xUpdateMin; | |||
maxcol = xUpdateMax; | |||
#else | |||
// start at the beginning of the row | |||
col = 0; | |||
maxcol = LCDWIDTH-1; | |||
#endif | |||
command(PCD8544_SETXADDR | col); | |||
digitalWrite(_dc, HIGH); | |||
if ( | if (_cs > 0) | ||
digitalWrite(_cs, LOW); | |||
for(; col <= maxcol; col++) { | |||
spiWrite(pcd8544_buffer[(LCDWIDTH*p)+col]); | |||
} | } | ||
if (_cs > 0) | |||
digitalWrite(_cs, HIGH); | |||
} | } | ||
command(PCD8544_SETYADDR ); // no idea why this is necessary but it is to finish the last byte? | |||
#ifdef enablePartialUpdate | |||
xUpdateMin = LCDWIDTH - 1; | |||
xUpdateMax = 0; | |||
yUpdateMin = LCDHEIGHT-1; | |||
yUpdateMax = 0; | |||
#endif | |||
} | |||
// clear everything | |||
void Adafruit_PCD8544::clearDisplay(void) { | |||
memset(pcd8544_buffer, 0, LCDWIDTH*LCDHEIGHT/8); | |||
updateBoundingBox(0, 0, LCDWIDTH-1, LCDHEIGHT-1); | |||
cursor_y = cursor_x = 0; | |||
} | |||
/* | |||
// this doesnt touch the buffer, just clears the display RAM - might be handy | |||
void Adafruit_PCD8544::clearDisplay(void) { | |||
uint8_t p, c; | |||
for(p = 0; p < 8; p++) { | |||
st7565_command(CMD_SET_PAGE | p); | |||
for(c = 0; c < 129; c++) { | |||
//uart_putw_dec(c); | |||
//uart_putchar(' '); | |||
st7565_command(CMD_SET_COLUMN_LOWER | (c & 0xf)); | |||
st7565_command(CMD_SET_COLUMN_UPPER | ((c >> 4) & 0xf)); | |||
st7565_data(0x0); | |||
} | |||
} | |||
} | } | ||
*/ | |||
</pre> | </pre> | ||
Revision as of 20:56, 7 July 2016
Humidity/Temperature sensor with SD Card data logger.
Note: Requires modified Nokia library.
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <SPI.h>
#include <SD.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
#include <DHT.h>
#define DHTTYPE DHT11
#define PIN_DHT 1
#define PIN_CE 16 //Pin 2 on LCD
#define PIN_DC 15 //Pin 3 on LCD
#define PIN_SD_CS 10 // Make sure "DIO" is selected
#define DISPLAY_ENABLED true
bool sdEnabled = false;
WiFiClient client;
#if defined(DISPLAY_ENABLED)
Adafruit_PCD8544 display = Adafruit_PCD8544(PIN_DC, PIN_CE, -1);
#else
Adafruit_PCD8544 display = Adafruit_PCD8544(4, 5, 2, -1);
#endif
bool wifiEnabled = false;
DHT dht(PIN_DHT, DHTTYPE);
void setup() {
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
if (DISPLAY_ENABLED) {
display.begin();
display.setContrast(55);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(0, 0);
display.println("#0FF DHT");
display.setTextColor(WHITE, BLACK); // 'inverted' text
display.setTextSize(2);
display.println(" void ");
display.setTextSize(1);
display.setTextColor(BLACK);
display.display();
}
// WiFi.begin(ssid, password);
WiFi.begin();
unsigned long timeout = millis() + 10000;
while (WiFi.status() != WL_CONNECTED){
digitalWrite(5, HIGH);
delay(50);
digitalWrite(5, LOW);
delay(450);
if (millis() > timeout)
break;
}
wifiEnabled = WiFi.status() == WL_CONNECTED;
if (wifiEnabled) {
ArduinoOTA.onStart([]() {
if (DISPLAY_ENABLED) {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(0, 0);
display.println("*OTA Update*");
display.println("");
display.setTextSize(2);
display.display();
}
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
static uint8_t lastProgress = 0;
static unsigned long nextTime = 0;
uint8_t p = (progress / (total / 100));
if (p == 100 || (p != lastProgress && millis() > nextTime)) {
nextTime = millis() + 100;
if (p < 100) {
if (DISPLAY_ENABLED) {
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.println("*OTA Update*");
display.println("");
display.setTextSize(2);
display.setCursor(24, 24);
display.println(String(p) + "%");
display.display();
}
lastProgress = p;
} else {
if (DISPLAY_ENABLED) {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(0, 0);
display.println("*OTA Success*");
display.println("");
display.println("rebooting...");
display.display();
}
}
}
});
ArduinoOTA.onError([](ota_error_t error) {
if (DISPLAY_ENABLED) {
display.println("ERROR: " + String(error));
display.display();
delay(1000);
}
});
ArduinoOTA.begin();
if (DISPLAY_ENABLED) {
display.println(WiFi.localIP());
display.display();
}
for (int i = 0; i < 10; i++) {
ArduinoOTA.handle();
delay(100);
yield();
}
}
if(!SD.begin(PIN_SD_CS)) {
//no SD found
display.clearDisplay();
display.println("No SD found");
display.display();
//TODO - change delay to loop w/yield
delay(1000);
} else {
//SD initialized
sdEnabled = true;
}
dht.begin();
delay(100);
}
void loop() {
if (wifiEnabled)
ArduinoOTA.handle();
handleHumidity();
delay(50);
}
void handleHumidity() {
static unsigned long next = 15000;
unsigned long now = millis();
if (now > next) {
next = now + 10000;
int h, c, f;
h = dht.readHumidity();
c = dht.readTemperature();
f = dht.readTemperature(true);
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(2);
display.println(String(c) + "/" + String(f));
display.setTextSize(3);
display.println(String(h) + "%");
display.display();
if (sdEnabled) {
String data = String(millis()) + ",";
data += String(h) + ",";
data += String(c) + ",";
data += String(f);
File dataFile = SD.open("HUMIDITY.TXT", FILE_WRITE);
if (dataFile) {
dataFile.println(data);
dataFile.close();
}
}
digitalWrite(5, HIGH);
delay(100);
digitalWrite(5, LOW);
}
}
Slightly modified version of Adafruit Nokia Display library (Adafruit_PCD8544.cpp)...
/*********************************************************************
This is a library for our Monochrome Nokia 5110 LCD Displays
Pick one up today in the adafruit shop!
------> http://www.adafruit.com/products/338
These displays use SPI to communicate, 4 or 5 pins are required to
interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, check license.txt for more information
All text above, and the splash screen below must be included in any redistribution
Hacked for ESP8266 by thex #0ff
*********************************************************************/
//#include <Wire.h>
#if defined(ESP8266)
#include <pgmspace.h>
#else
#include <avr/pgmspace.h>
#endif
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#ifdef __AVR__
#include <util/delay.h>
#endif
#ifndef _BV
#define _BV(x) (1 << (x))
#endif
#include <stdlib.h>
#include <Adafruit_GFX.h>
#include "Adafruit_PCD8544.h"
// the memory buffer for the LCD
uint8_t pcd8544_buffer[LCDWIDTH * LCDHEIGHT / 8] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFC, 0xFE, 0xFF, 0xFC, 0xE0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8,
0xF8, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0x80, 0xC0, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x7F,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC7, 0xC7, 0x87, 0x8F, 0x9F, 0x9F, 0xFF, 0xFF, 0xFF,
0xC1, 0xC0, 0xE0, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC, 0xFC, 0xFE, 0xFE, 0xFE,
0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xE0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0xC0, 0xE0, 0xF1, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0x0F, 0x0F, 0x87,
0xE7, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0x3F, 0xF9, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xFD, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x0F, 0x07, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xF0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
0x7E, 0x3F, 0x3F, 0x0F, 0x1F, 0xFF, 0xFF, 0xFF, 0xFC, 0xF0, 0xE0, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFC, 0xF0, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01,
0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0F, 0x1F, 0x3F, 0x7F, 0x7F,
0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x1F, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
// reduces how much is refreshed, which speeds it up!
// originally derived from Steve Evans/JCW's mod but cleaned up and
// optimized
//#define enablePartialUpdate
#ifdef enablePartialUpdate
static uint8_t xUpdateMin, xUpdateMax, yUpdateMin, yUpdateMax;
#endif
static void updateBoundingBox(uint8_t xmin, uint8_t ymin, uint8_t xmax, uint8_t ymax) {
#ifdef enablePartialUpdate
if (xmin < xUpdateMin) xUpdateMin = xmin;
if (xmax > xUpdateMax) xUpdateMax = xmax;
if (ymin < yUpdateMin) yUpdateMin = ymin;
if (ymax > yUpdateMax) yUpdateMax = ymax;
#endif
}
Adafruit_PCD8544::Adafruit_PCD8544(int8_t SCLK, int8_t DIN, int8_t DC,
int8_t CS, int8_t RST) : Adafruit_GFX(LCDWIDTH, LCDHEIGHT) {
_din = DIN;
_sclk = SCLK;
_dc = DC;
_rst = RST;
_cs = CS;
}
Adafruit_PCD8544::Adafruit_PCD8544(int8_t SCLK, int8_t DIN, int8_t DC,
int8_t RST) : Adafruit_GFX(LCDWIDTH, LCDHEIGHT) {
_din = DIN;
_sclk = SCLK;
_dc = DC;
_rst = RST;
_cs = -1;
}
Adafruit_PCD8544::Adafruit_PCD8544(int8_t DC, int8_t CS, int8_t RST):
Adafruit_GFX(LCDWIDTH, LCDHEIGHT) {
// -1 for din and sclk specify using hardware SPI
_din = -1;
_sclk = -1;
_dc = DC;
_rst = RST;
_cs = CS;
}
// the most basic function, set a single pixel
void Adafruit_PCD8544::drawPixel(int16_t x, int16_t y, uint16_t color) {
if ((x < 0) || (x >= _width) || (y < 0) || (y >= _height))
return;
int16_t t;
switch(rotation){
case 1:
t = x;
x = y;
y = LCDHEIGHT - 1 - t;
break;
case 2:
x = LCDWIDTH - 1 - x;
y = LCDHEIGHT - 1 - y;
break;
case 3:
t = x;
x = LCDWIDTH - 1 - y;
y = t;
break;
}
if ((x < 0) || (x >= LCDWIDTH) || (y < 0) || (y >= LCDHEIGHT))
return;
// x is which column
if (color)
pcd8544_buffer[x+ (y/8)*LCDWIDTH] |= _BV(y%8);
else
pcd8544_buffer[x+ (y/8)*LCDWIDTH] &= ~_BV(y%8);
updateBoundingBox(x,y,x,y);
}
// the most basic function, get a single pixel
uint8_t Adafruit_PCD8544::getPixel(int8_t x, int8_t y) {
if ((x < 0) || (x >= LCDWIDTH) || (y < 0) || (y >= LCDHEIGHT))
return 0;
return (pcd8544_buffer[x+ (y/8)*LCDWIDTH] >> (y%8)) & 0x1;
}
void Adafruit_PCD8544::begin(uint8_t contrast, uint8_t bias) {
if (isHardwareSPI()) {
// Setup hardware SPI.
SPI.begin();
#ifdef ESP8266
// Datasheet says 4 MHz is max SPI clock speed
SPI.setFrequency(400000);
#else
SPI.setClockDivider(PCD8544_SPI_CLOCK_DIV);
#endif
SPI.setDataMode(SPI_MODE0);
SPI.setBitOrder(MSBFIRST);
}
else {
// Setup software SPI.
// Set software SPI specific pin outputs.
pinMode(_din, OUTPUT);
pinMode(_sclk, OUTPUT);
#ifndef ESP8266
// Set software SPI ports and masks.
clkport = portOutputRegister(digitalPinToPort(_sclk));
clkpinmask = digitalPinToBitMask(_sclk);
mosiport = portOutputRegister(digitalPinToPort(_din));
mosipinmask = digitalPinToBitMask(_din);
#endif
}
// Set common pin outputs.
pinMode(_dc, OUTPUT);
if (_rst > 0)
pinMode(_rst, OUTPUT);
if (_cs > 0)
pinMode(_cs, OUTPUT);
// toggle RST low to reset
if (_rst > 0) {
digitalWrite(_rst, LOW);
delay(500);
digitalWrite(_rst, HIGH);
}
// get into the EXTENDED mode!
command(PCD8544_FUNCTIONSET | PCD8544_EXTENDEDINSTRUCTION );
// LCD bias select (4 is optimal?)
command(PCD8544_SETBIAS | bias);
// set VOP
if (contrast > 0x7f)
contrast = 0x7f;
command( PCD8544_SETVOP | contrast); // Experimentally determined
// normal mode
command(PCD8544_FUNCTIONSET);
// Set display to Normal
command(PCD8544_DISPLAYCONTROL | PCD8544_DISPLAYNORMAL);
// initial display line
// set page address
// set column address
// write display data
// set up a bounding box for screen updates
updateBoundingBox(0, 0, LCDWIDTH-1, LCDHEIGHT-1);
// Push out pcd8544_buffer to the Display (will show the AFI logo)
display();
}
inline void Adafruit_PCD8544::spiWrite(uint8_t d) {
if (isHardwareSPI()) {
// Hardware SPI write.
SPI.transfer(d);
}
else {
#ifdef ESP8266
// Software SPI write with bit banging.
for(uint8_t bit = 0x80; bit; bit >>= 1) {
digitalWrite(_sclk, LOW);
if (d & bit) digitalWrite(_din, HIGH);
else digitalWrite(_din, LOW);
digitalWrite(_sclk, HIGH);
}
#else
// Software SPI write with bit banging.
for(uint8_t bit = 0x80; bit; bit >>= 1) {
*clkport &= ~clkpinmask;
if(d & bit) *mosiport |= mosipinmask;
else *mosiport &= ~mosipinmask;
*clkport |= clkpinmask;
}
#endif
}
}
bool Adafruit_PCD8544::isHardwareSPI() {
return (_din == -1 && _sclk == -1);
}
void Adafruit_PCD8544::command(uint8_t c) {
digitalWrite(_dc, LOW);
if (_cs > 0)
digitalWrite(_cs, LOW);
spiWrite(c);
if (_cs > 0)
digitalWrite(_cs, HIGH);
}
void Adafruit_PCD8544::data(uint8_t c) {
digitalWrite(_dc, HIGH);
if (_cs > 0)
digitalWrite(_cs, LOW);
spiWrite(c);
if (_cs > 0)
digitalWrite(_cs, HIGH);
}
void Adafruit_PCD8544::setContrast(uint8_t val) {
if (val > 0x7f) {
val = 0x7f;
}
command(PCD8544_FUNCTIONSET | PCD8544_EXTENDEDINSTRUCTION );
command( PCD8544_SETVOP | val);
command(PCD8544_FUNCTIONSET);
}
void Adafruit_PCD8544::display(void) {
uint8_t col, maxcol, p;
for(p = 0; p < 6; p++) {
#ifdef enablePartialUpdate
// check if this page is part of update
if ( yUpdateMin >= ((p+1)*8) ) {
continue; // nope, skip it!
}
if (yUpdateMax < p*8) {
break;
}
#endif
command(PCD8544_SETYADDR | p);
#ifdef enablePartialUpdate
col = xUpdateMin;
maxcol = xUpdateMax;
#else
// start at the beginning of the row
col = 0;
maxcol = LCDWIDTH-1;
#endif
command(PCD8544_SETXADDR | col);
digitalWrite(_dc, HIGH);
if (_cs > 0)
digitalWrite(_cs, LOW);
for(; col <= maxcol; col++) {
spiWrite(pcd8544_buffer[(LCDWIDTH*p)+col]);
}
if (_cs > 0)
digitalWrite(_cs, HIGH);
}
command(PCD8544_SETYADDR ); // no idea why this is necessary but it is to finish the last byte?
#ifdef enablePartialUpdate
xUpdateMin = LCDWIDTH - 1;
xUpdateMax = 0;
yUpdateMin = LCDHEIGHT-1;
yUpdateMax = 0;
#endif
}
// clear everything
void Adafruit_PCD8544::clearDisplay(void) {
memset(pcd8544_buffer, 0, LCDWIDTH*LCDHEIGHT/8);
updateBoundingBox(0, 0, LCDWIDTH-1, LCDHEIGHT-1);
cursor_y = cursor_x = 0;
}
/*
// this doesnt touch the buffer, just clears the display RAM - might be handy
void Adafruit_PCD8544::clearDisplay(void) {
uint8_t p, c;
for(p = 0; p < 8; p++) {
st7565_command(CMD_SET_PAGE | p);
for(c = 0; c < 129; c++) {
//uart_putw_dec(c);
//uart_putchar(' ');
st7565_command(CMD_SET_COLUMN_LOWER | (c & 0xf));
st7565_command(CMD_SET_COLUMN_UPPER | ((c >> 4) & 0xf));
st7565_data(0x0);
}
}
}
*/