<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.extremist.software/index.php?action=history&amp;feed=atom&amp;title=ESP8266%2FDHT</id>
	<title>ESP8266/DHT - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.extremist.software/index.php?action=history&amp;feed=atom&amp;title=ESP8266%2FDHT"/>
	<link rel="alternate" type="text/html" href="https://wiki.extremist.software/index.php?title=ESP8266/DHT&amp;action=history"/>
	<updated>2026-04-08T02:12:57Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.13</generator>
	<entry>
		<id>https://wiki.extremist.software/index.php?title=ESP8266/DHT&amp;diff=52677&amp;oldid=prev</id>
		<title>ESP8266: #0ff</title>
		<link rel="alternate" type="text/html" href="https://wiki.extremist.software/index.php?title=ESP8266/DHT&amp;diff=52677&amp;oldid=prev"/>
		<updated>2016-07-08T05:37:56Z</updated>

		<summary type="html">&lt;p&gt;#0ff&lt;/p&gt;
&lt;a href=&quot;https://wiki.extremist.software/index.php?title=ESP8266/DHT&amp;amp;diff=52677&amp;amp;oldid=52676&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>ESP8266</name></author>
	</entry>
	<entry>
		<id>https://wiki.extremist.software/index.php?title=ESP8266/DHT&amp;diff=52676&amp;oldid=prev</id>
		<title>ESP8266: lightened code + library mod #0ff</title>
		<link rel="alternate" type="text/html" href="https://wiki.extremist.software/index.php?title=ESP8266/DHT&amp;diff=52676&amp;oldid=prev"/>
		<updated>2016-07-08T03:56:37Z</updated>

		<summary type="html">&lt;p&gt;lightened code + library mod #0ff&lt;/p&gt;
&lt;a href=&quot;https://wiki.extremist.software/index.php?title=ESP8266/DHT&amp;amp;diff=52676&amp;amp;oldid=52649&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>ESP8266</name></author>
	</entry>
	<entry>
		<id>https://wiki.extremist.software/index.php?title=ESP8266/DHT&amp;diff=52649&amp;oldid=prev</id>
		<title>ESP8266: #0ff</title>
		<link rel="alternate" type="text/html" href="https://wiki.extremist.software/index.php?title=ESP8266/DHT&amp;diff=52649&amp;oldid=prev"/>
		<updated>2016-07-08T02:27:27Z</updated>

		<summary type="html">&lt;p&gt;#0ff&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Humidity/Temperature sensor with SD Card data logger.&lt;br /&gt;
&lt;br /&gt;
Note: Requires modified Nokia library.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;ESP8266WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;ESP8266mDNS.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFiUdp.h&amp;gt;&lt;br /&gt;
#include &amp;lt;ArduinoOTA.h&amp;gt;&lt;br /&gt;
#include &amp;lt;SPI.h&amp;gt;&lt;br /&gt;
#include &amp;lt;SD.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Adafruit_GFX.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Adafruit_PCD8544.h&amp;gt;&lt;br /&gt;
#include &amp;lt;DHT.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define DHTTYPE DHT11&lt;br /&gt;
&lt;br /&gt;
#define PIN_DHT   1&lt;br /&gt;
&lt;br /&gt;
#define PIN_CE    16  //Pin 2 on LCD&lt;br /&gt;
#define PIN_DC    15  //Pin 3 on LCD&lt;br /&gt;
&lt;br /&gt;
#define PIN_PUSH  0  // Push Button Switch&lt;br /&gt;
&lt;br /&gt;
#define PIN_SD_CS 10 // Make sure &amp;quot;DIO&amp;quot; is selected&lt;br /&gt;
&lt;br /&gt;
#define PIN_SOUND 3 // Piezo, overlapped with Serial Rx&lt;br /&gt;
&lt;br /&gt;
//You may find a different size screen, but this one is 84 by 48 pixels&lt;br /&gt;
#define LCD_X     84&lt;br /&gt;
#define LCD_Y     48&lt;br /&gt;
&lt;br /&gt;
#define LINE_INTERVAL 200&lt;br /&gt;
#define PING_INTERVAL 1000&lt;br /&gt;
&lt;br /&gt;
#define MODE_HUMIDITY 16&lt;br /&gt;
#define MODE_SOUND 1&lt;br /&gt;
#define MODE_PING 2&lt;br /&gt;
#define MODE_CARD 3&lt;br /&gt;
#define MODE_FILE 4&lt;br /&gt;
#define MODE_CONTRAST 5&lt;br /&gt;
#define MODE_FIRMWARE 6&lt;br /&gt;
#define MODE_INITIALIZE 255&lt;br /&gt;
&lt;br /&gt;
#define SWITCH_DEBOUNCE_TIME 50 // Timeout for debouncing presses&lt;br /&gt;
#define SWITCH_MULTI_TIME 300   // Timeout for detecting multiple clicks&lt;br /&gt;
#define SWITCH_HOLD_TIME 2000   // Timeout for detecting press and hold&lt;br /&gt;
&lt;br /&gt;
#define SWITCH_PRESS 1&lt;br /&gt;
#define SWITCH_RELEASE 2&lt;br /&gt;
#define SWITCH_MULTI 4&lt;br /&gt;
#define SWITCH_HOLD 8&lt;br /&gt;
&lt;br /&gt;
#define DISPLAY_ENABLED true&lt;br /&gt;
&lt;br /&gt;
// set up variables using the SD utility library functions:&lt;br /&gt;
Sd2Card card;&lt;br /&gt;
SdVolume volume;&lt;br /&gt;
SdFile root;&lt;br /&gt;
bool sdEnabled = false;&lt;br /&gt;
&lt;br /&gt;
unsigned long nextLineMillis = 0;&lt;br /&gt;
unsigned long nextPing = 0;&lt;br /&gt;
unsigned long pingMillis = 0;&lt;br /&gt;
unsigned long debounceMillis = 0;&lt;br /&gt;
unsigned long doubleMillis = 0;&lt;br /&gt;
unsigned long holdMillis = 0;&lt;br /&gt;
&lt;br /&gt;
int lastPing = 0;&lt;br /&gt;
&lt;br /&gt;
bool pushStateOn = false;&lt;br /&gt;
&lt;br /&gt;
uint8_t activeMode = MODE_INITIALIZE;&lt;br /&gt;
uint8_t clickCount = 0;&lt;br /&gt;
&lt;br /&gt;
WiFiClient client;&lt;br /&gt;
&lt;br /&gt;
#if defined(DISPLAY_ENABLED)&lt;br /&gt;
Adafruit_PCD8544 display = Adafruit_PCD8544(PIN_DC, PIN_CE, -1);&lt;br /&gt;
#else&lt;br /&gt;
Adafruit_PCD8544 display = Adafruit_PCD8544(4, 5, 2, -1);&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
bool wifiEnabled = false;&lt;br /&gt;
&lt;br /&gt;
DHT dht(PIN_DHT, DHTTYPE);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  pinMode(PIN_PUSH, INPUT_PULLUP);&lt;br /&gt;
&lt;br /&gt;
  pinMode(PIN_SOUND, OUTPUT);&lt;br /&gt;
  &lt;br /&gt;
  pinMode(4, OUTPUT);&lt;br /&gt;
  pinMode(5, OUTPUT);&lt;br /&gt;
&lt;br /&gt;
  if (DISPLAY_ENABLED) {&lt;br /&gt;
    display.begin();&lt;br /&gt;
    display.setContrast(55);&lt;br /&gt;
&lt;br /&gt;
    display.clearDisplay();&lt;br /&gt;
&lt;br /&gt;
    display.setTextSize(1);&lt;br /&gt;
    display.setTextColor(BLACK);&lt;br /&gt;
    display.setCursor(0, 0);&lt;br /&gt;
    display.println(&amp;quot;#0FF DHT&amp;quot;);&lt;br /&gt;
    display.setTextColor(WHITE, BLACK); // &amp;#039;inverted&amp;#039; text&lt;br /&gt;
    display.setTextSize(2);&lt;br /&gt;
    display.println(&amp;quot; void &amp;quot;);&lt;br /&gt;
    display.setTextSize(1);&lt;br /&gt;
    display.setTextColor(BLACK);&lt;br /&gt;
    display.println(&amp;quot;WiFi: &amp;quot; + String(ssid).substring(0, 7));&lt;br /&gt;
    display.display();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // WiFi.begin(ssid, password);&lt;br /&gt;
  WiFi.begin();&lt;br /&gt;
  unsigned long timeout = millis() + 10000;&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED){&lt;br /&gt;
    digitalWrite(5, HIGH);&lt;br /&gt;
    delay(50);&lt;br /&gt;
    digitalWrite(5, LOW);&lt;br /&gt;
    delay(450);&lt;br /&gt;
//    Serial.printf(&amp;quot;.\n&amp;quot;);&lt;br /&gt;
    if (millis() &amp;gt; timeout)&lt;br /&gt;
      break;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  wifiEnabled = WiFi.status() == WL_CONNECTED;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  if (wifiEnabled) {&lt;br /&gt;
  // Port defaults to 8266&lt;br /&gt;
  // ArduinoOTA.setPort(8266);&lt;br /&gt;
&lt;br /&gt;
  // Hostname defaults to esp8266-[ChipID]&lt;br /&gt;
  // ArduinoOTA.setHostname(&amp;quot;myesp8266&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // No authentication by default&lt;br /&gt;
  // ArduinoOTA.setPassword((const char *)&amp;quot;123&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  ArduinoOTA.onStart([]() {&lt;br /&gt;
//    Serial.println(&amp;quot;Start&amp;quot;);&lt;br /&gt;
    if (DISPLAY_ENABLED) {&lt;br /&gt;
      display.clearDisplay();&lt;br /&gt;
      display.setTextSize(1);&lt;br /&gt;
      display.setTextColor(BLACK);&lt;br /&gt;
      display.setCursor(0, 0);&lt;br /&gt;
      display.println(&amp;quot;*OTA Update*&amp;quot;);&lt;br /&gt;
      display.println(&amp;quot;&amp;quot;);&lt;br /&gt;
      display.setTextSize(2);&lt;br /&gt;
      display.display();&lt;br /&gt;
    }&lt;br /&gt;
  });&lt;br /&gt;
  ArduinoOTA.onEnd([]() {&lt;br /&gt;
//    Serial.println(&amp;quot;\nEnd&amp;quot;);&lt;br /&gt;
  });&lt;br /&gt;
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {&lt;br /&gt;
    static uint8_t lastProgress = 0;&lt;br /&gt;
    static unsigned long nextTime = 0;&lt;br /&gt;
    uint8_t p = (progress / (total / 100));&lt;br /&gt;
//    Serial.printf(&amp;quot;Progress: %u%%\r&amp;quot;, p);&lt;br /&gt;
    if (p == 100 || (p != lastProgress &amp;amp;&amp;amp; millis() &amp;gt; nextTime)) {&lt;br /&gt;
      nextTime = millis() + 100;&lt;br /&gt;
      if (p &amp;lt; 100) {&lt;br /&gt;
        if (DISPLAY_ENABLED) {&lt;br /&gt;
          display.clearDisplay();&lt;br /&gt;
          display.setTextSize(1);&lt;br /&gt;
          display.setCursor(0, 0);&lt;br /&gt;
          display.println(&amp;quot;*OTA Update*&amp;quot;);&lt;br /&gt;
          display.println(&amp;quot;&amp;quot;);&lt;br /&gt;
          display.setTextSize(2);&lt;br /&gt;
          display.setCursor(24, 24);&lt;br /&gt;
          display.println(String(p) + &amp;quot;%&amp;quot;);&lt;br /&gt;
          display.display();&lt;br /&gt;
        }&lt;br /&gt;
        lastProgress = p;&lt;br /&gt;
      } else {&lt;br /&gt;
//        Serial.println(&amp;quot;Start&amp;quot;);&lt;br /&gt;
        if (DISPLAY_ENABLED) {&lt;br /&gt;
          display.clearDisplay();&lt;br /&gt;
          display.setTextSize(1);&lt;br /&gt;
          display.setTextColor(BLACK);&lt;br /&gt;
          display.setCursor(0, 0);&lt;br /&gt;
          display.println(&amp;quot;*OTA Success*&amp;quot;);&lt;br /&gt;
          display.println(&amp;quot;&amp;quot;);&lt;br /&gt;
          display.println(&amp;quot;rebooting...&amp;quot;);&lt;br /&gt;
          display.display();&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  });&lt;br /&gt;
  ArduinoOTA.onError([](ota_error_t error) {&lt;br /&gt;
//    Serial.printf(&amp;quot;Error[%u]: &amp;quot;, error);&lt;br /&gt;
//    if (error == OTA_AUTH_ERROR) Serial.println(&amp;quot;Auth Failed&amp;quot;);&lt;br /&gt;
//    else if (error == OTA_BEGIN_ERROR) Serial.println(&amp;quot;Begin Failed&amp;quot;);&lt;br /&gt;
//    else if (error == OTA_CONNECT_ERROR) Serial.println(&amp;quot;Connect Failed&amp;quot;);&lt;br /&gt;
//    else if (error == OTA_RECEIVE_ERROR) Serial.println(&amp;quot;Receive Failed&amp;quot;);&lt;br /&gt;
//    else if (error == OTA_END_ERROR) Serial.println(&amp;quot;End Failed&amp;quot;);&lt;br /&gt;
    if (DISPLAY_ENABLED) {&lt;br /&gt;
      display.println(&amp;quot;ERROR: &amp;quot; + String(error));&lt;br /&gt;
      display.display();&lt;br /&gt;
      delay(1000);&lt;br /&gt;
    }&lt;br /&gt;
  });&lt;br /&gt;
  ArduinoOTA.begin();&lt;br /&gt;
&lt;br /&gt;
//  Serial.println(&amp;quot;Ready&amp;quot;);&lt;br /&gt;
//  Serial.print(&amp;quot;IP address: &amp;quot;);&lt;br /&gt;
//  Serial.println(WiFi.localIP());&lt;br /&gt;
  &lt;br /&gt;
  if (DISPLAY_ENABLED) {&lt;br /&gt;
    display.println(WiFi.localIP());&lt;br /&gt;
    display.display();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  for (int i = 0; i &amp;lt; 10; i++) {&lt;br /&gt;
    ArduinoOTA.handle();&lt;br /&gt;
    delay(100);&lt;br /&gt;
    yield();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//TODO - change delay to loop funtion&lt;br /&gt;
&lt;br /&gt;
if(!SD.begin(PIN_SD_CS)) {&lt;br /&gt;
  //no SD found&lt;br /&gt;
  display.clearDisplay();&lt;br /&gt;
  display.println(&amp;quot;No SD found&amp;quot;);&lt;br /&gt;
  display.display();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
  &lt;br /&gt;
  } else {&lt;br /&gt;
  //SD initialized&lt;br /&gt;
  sdEnabled = true;&lt;br /&gt;
  }&lt;br /&gt;
  dht.begin();&lt;br /&gt;
&lt;br /&gt;
  setMode(MODE_HUMIDITY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  if (wifiEnabled)&lt;br /&gt;
    ArduinoOTA.handle();&lt;br /&gt;
&lt;br /&gt;
  unsigned long now = millis();&lt;br /&gt;
  bool pushed = !digitalRead(PIN_PUSH);&lt;br /&gt;
  uint8_t buttonAction = 0;&lt;br /&gt;
&lt;br /&gt;
  if (client.connected()) {&lt;br /&gt;
    bool got = checkGet();&lt;br /&gt;
    if (got) {&lt;br /&gt;
      lastPing = millis() - pingMillis;&lt;br /&gt;
      nextPing = millis() + PING_INTERVAL;&lt;br /&gt;
    }&lt;br /&gt;
  } else if (millis() &amp;gt; nextPing) {&lt;br /&gt;
    sendGet();&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  // Handle switch state(s)&lt;br /&gt;
  if (now &amp;gt; debounceMillis &amp;amp;&amp;amp;  pushed != pushStateOn) {&lt;br /&gt;
    // Push switch state change&lt;br /&gt;
    debounceMillis = now + SWITCH_DEBOUNCE_TIME;&lt;br /&gt;
    if (pushed) {&lt;br /&gt;
      // Switch pushed&lt;br /&gt;
      pushStateOn = true;&lt;br /&gt;
      if (doubleMillis &amp;lt; now) {&lt;br /&gt;
        doubleMillis = now + SWITCH_MULTI_TIME;&lt;br /&gt;
        clickCount = 1;&lt;br /&gt;
        // string2Line(&amp;quot;Switch: ON&amp;quot;, 4);&lt;br /&gt;
        buttonAction = SWITCH_PRESS;&lt;br /&gt;
      } else {&lt;br /&gt;
        // Multi-click, goto next mode&lt;br /&gt;
        setMode(activeMode &amp;lt; 5 ? activeMode + 1 : 0);&lt;br /&gt;
        clickCount++;&lt;br /&gt;
        // string2Line(&amp;quot;Mode: &amp;quot; + String(activeMode), 2);&lt;br /&gt;
        // string2Line(&amp;quot;Click: &amp;quot; + String(clickCount), 4);&lt;br /&gt;
        buttonAction = SWITCH_MULTI;&lt;br /&gt;
      }&lt;br /&gt;
      holdMillis = now + SWITCH_HOLD_TIME;&lt;br /&gt;
    } else {&lt;br /&gt;
      // Switch released&lt;br /&gt;
      pushStateOn = false;&lt;br /&gt;
      // string2Line(&amp;quot;Switch: OFF&amp;quot;, 4);&lt;br /&gt;
      holdMillis = 0;&lt;br /&gt;
      buttonAction = SWITCH_RELEASE;&lt;br /&gt;
    }&lt;br /&gt;
  } else if (pushed &amp;amp;&amp;amp; holdMillis &amp;gt; 0 &amp;amp;&amp;amp; now &amp;gt; holdMillis) {&lt;br /&gt;
    // Long press&lt;br /&gt;
    // string2Line(&amp;quot;Switch: HOLD&amp;quot;, 4);&lt;br /&gt;
    holdMillis = 0;&lt;br /&gt;
    buttonAction = SWITCH_HOLD;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (activeMode == MODE_HUMIDITY) {&lt;br /&gt;
    handleHumidity();&lt;br /&gt;
  } else if (activeMode == MODE_PING) {&lt;br /&gt;
    handlePingMode(buttonAction);&lt;br /&gt;
  } else if (activeMode == MODE_CARD) {&lt;br /&gt;
    handleCardMode(buttonAction);&lt;br /&gt;
  } else if (activeMode == MODE_FILE) {&lt;br /&gt;
    handleFileMode(buttonAction);&lt;br /&gt;
  } else if (activeMode == MODE_FIRMWARE) {&lt;br /&gt;
    handleFirmwareMode(buttonAction);&lt;br /&gt;
  } else if (activeMode == MODE_CONTRAST) {&lt;br /&gt;
    handleContrastMode();&lt;br /&gt;
  } else if (activeMode == MODE_SOUND) {&lt;br /&gt;
    handleSoundMode(buttonAction);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  int a = analogRead(A0) / 4;&lt;br /&gt;
  if (a &amp;gt; 255)&lt;br /&gt;
    a = 255;&lt;br /&gt;
  analogWrite(4, a);&lt;br /&gt;
  // analogWrite(5, digitalRead(0) ? 0 : 127);&lt;br /&gt;
&lt;br /&gt;
  delay(50);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setMode(uint8_t newMode) {&lt;br /&gt;
  if (newMode != activeMode) {&lt;br /&gt;
&lt;br /&gt;
    if (DISPLAY_ENABLED) {&lt;br /&gt;
      display.clearDisplay();&lt;br /&gt;
      display.setTextSize(1);&lt;br /&gt;
      display.setTextColor(BLACK);&lt;br /&gt;
      display.setCursor(28, 0);&lt;br /&gt;
      display.println(&amp;quot;mode:&amp;quot;);&lt;br /&gt;
      display.setCursor(32, 12);&lt;br /&gt;
      display.setTextSize(3);&lt;br /&gt;
      display.println(newMode);&lt;br /&gt;
      display.display();&lt;br /&gt;
      delay(300);&lt;br /&gt;
      yield();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (newMode == MODE_PING) {&lt;br /&gt;
      handlePingMode(0);&lt;br /&gt;
    } else if (newMode == MODE_CARD) {&lt;br /&gt;
      handleCardMode(SWITCH_HOLD);&lt;br /&gt;
    } else if (newMode == MODE_FILE) {&lt;br /&gt;
      handleFileMode(SWITCH_PRESS);&lt;br /&gt;
    } else if (newMode == MODE_FIRMWARE) {&lt;br /&gt;
      handleFirmwareMode(0);&lt;br /&gt;
    } else if (newMode == MODE_CONTRAST) {&lt;br /&gt;
      handleContrastMode();&lt;br /&gt;
    } else if (newMode == MODE_SOUND) {&lt;br /&gt;
      handleSoundMode(SWITCH_RELEASE);&lt;br /&gt;
    }&lt;br /&gt;
    activeMode = newMode;&lt;br /&gt;
  } else {&lt;br /&gt;
    // Not a new mode selection&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleHumidity() {&lt;br /&gt;
  static unsigned long next = 5000;&lt;br /&gt;
  unsigned long now = millis();&lt;br /&gt;
&lt;br /&gt;
  if (now &amp;gt; next) {&lt;br /&gt;
    next = now + 2000;&lt;br /&gt;
    int h, c, f;&lt;br /&gt;
    h = dht.readHumidity();&lt;br /&gt;
    c = dht.readTemperature();&lt;br /&gt;
    f = dht.readTemperature(true);&lt;br /&gt;
&lt;br /&gt;
    display.clearDisplay();&lt;br /&gt;
    display.setCursor(0, 0);&lt;br /&gt;
    display.setTextSize(2);&lt;br /&gt;
    display.println(String(c) + &amp;quot;/&amp;quot; + String(f));&lt;br /&gt;
    display.setTextSize(3);&lt;br /&gt;
    display.println(String(h) + &amp;quot;%&amp;quot;);&lt;br /&gt;
    display.display();&lt;br /&gt;
&lt;br /&gt;
    if (sdEnabled) {&lt;br /&gt;
      String data = String(millis()) + &amp;quot;,&amp;quot;;&lt;br /&gt;
      data += String(h) + &amp;quot;,&amp;quot;;&lt;br /&gt;
      data += String(c) + &amp;quot;,&amp;quot;;&lt;br /&gt;
      data += String(f);&lt;br /&gt;
  &lt;br /&gt;
      File dataFile = SD.open(&amp;quot;humidity.txt&amp;quot;, FILE_WRITE);&lt;br /&gt;
  &lt;br /&gt;
      if (dataFile) {&lt;br /&gt;
        dataFile.println(data);&lt;br /&gt;
        dataFile.close();&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    digitalWrite(5, HIGH);&lt;br /&gt;
    delay(200);&lt;br /&gt;
    digitalWrite(5, LOW);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handlePingMode(uint8_t action) {&lt;br /&gt;
  if (client.connected()) {&lt;br /&gt;
    bool got = checkGet();&lt;br /&gt;
    if (got) {&lt;br /&gt;
      lastPing = millis() - pingMillis;&lt;br /&gt;
      nextPing = millis() + PING_INTERVAL;&lt;br /&gt;
//      Serial.println(&amp;quot;Ping: &amp;quot; + String(lastPing) + &amp;quot;ms&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  } else if (action == SWITCH_PRESS &amp;amp;&amp;amp; millis() &amp;gt; nextPing) {&lt;br /&gt;
    // Do new ping on switch press&lt;br /&gt;
    sendGet();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Check/show signal strength&lt;br /&gt;
  if (millis() &amp;gt; nextLineMillis) {&lt;br /&gt;
    int signalStrength = WiFi.RSSI() &amp;gt;= -50 ? 100 : 2 * (WiFi.RSSI() + 100);&lt;br /&gt;
    String signalBars = &amp;quot; &amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    nextLineMillis = millis() + LINE_INTERVAL;&lt;br /&gt;
&lt;br /&gt;
    if (DISPLAY_ENABLED) {&lt;br /&gt;
      display.clearDisplay();&lt;br /&gt;
      display.setTextSize(1);&lt;br /&gt;
      display.setTextColor(BLACK);&lt;br /&gt;
      display.setCursor(0, 0);&lt;br /&gt;
&lt;br /&gt;
      for (int i = 0; i &amp;lt; signalStrength / 10; i++)&lt;br /&gt;
        signalBars += &amp;quot;*&amp;quot;;&lt;br /&gt;
      display.println(signalBars);&lt;br /&gt;
      display.println(String(WiFi.RSSI()) + &amp;quot;db/&amp;quot; + String(signalStrength) + &amp;quot;%&amp;quot;);&lt;br /&gt;
      display.println();&lt;br /&gt;
      display.println(&amp;quot;Ping: &amp;quot; + String(lastPing) + &amp;quot;ms&amp;quot;);&lt;br /&gt;
      display.println();&lt;br /&gt;
      display.println(&amp;quot;#007 &amp;quot; + String(millis() / 1000));&lt;br /&gt;
&lt;br /&gt;
      display.display();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleCardMode(uint8_t action) {&lt;br /&gt;
  if (action == SWITCH_HOLD)&lt;br /&gt;
    testSD();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleFileMode(uint8_t action) {&lt;br /&gt;
  if (action == SWITCH_PRESS)&lt;br /&gt;
    getNextFile();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleFirmwareMode(uint8_t action) {&lt;br /&gt;
  digitalWrite(PIN_SD_CS, digitalRead(2));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleContrastMode() {&lt;br /&gt;
  static uint8_t contrast = 50;&lt;br /&gt;
  uint8_t analog = analogRead(A0) / 8;&lt;br /&gt;
&lt;br /&gt;
  if (!DISPLAY_ENABLED)&lt;br /&gt;
    return;&lt;br /&gt;
&lt;br /&gt;
  if (analog != contrast) {&lt;br /&gt;
    contrast = analog;&lt;br /&gt;
    display.clearDisplay();&lt;br /&gt;
    display.setCursor(0, 0);&lt;br /&gt;
    display.setTextSize(1);&lt;br /&gt;
    display.println(&amp;quot;  Contrast:&amp;quot;);&lt;br /&gt;
    display.setTextSize(3);&lt;br /&gt;
    display.println(contrast);&lt;br /&gt;
    display.setContrast(contrast);&lt;br /&gt;
    display.display();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  yield();&lt;br /&gt;
  delay(50);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleSoundMode(uint8_t action) {&lt;br /&gt;
  static bool soundOn = false;&lt;br /&gt;
  static int frequency = 1000;&lt;br /&gt;
  static int duty = 512;&lt;br /&gt;
&lt;br /&gt;
  bool refresh = action != 0;&lt;br /&gt;
  &lt;br /&gt;
  if (action == SWITCH_HOLD) {&lt;br /&gt;
    // Toggle sound on&lt;br /&gt;
    soundOn = !soundOn;&lt;br /&gt;
    if (soundOn) {&lt;br /&gt;
      analogWrite(PIN_SOUND, duty);&lt;br /&gt;
    } else {&lt;br /&gt;
      analogWrite(PIN_SOUND, 0);&lt;br /&gt;
    }&lt;br /&gt;
  } else if (action == SWITCH_PRESS) {&lt;br /&gt;
    frequency = analogRead(A0) * 4;&lt;br /&gt;
    // Crash if set to 0, espressif PWM defined as 100Hz-1Khz&lt;br /&gt;
    if (frequency &amp;lt; 10) frequency = 10;&lt;br /&gt;
    analogWriteFreq(frequency);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (!digitalRead(2)) {&lt;br /&gt;
    // Right switch pressed&lt;br /&gt;
    duty = analogRead(A0);&lt;br /&gt;
    if (soundOn)&lt;br /&gt;
      analogWrite(PIN_SOUND, duty);&lt;br /&gt;
    refresh = true;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (refresh) {&lt;br /&gt;
    display.clearDisplay();&lt;br /&gt;
    display.setCursor(0, 0);&lt;br /&gt;
    display.setTextSize(1);&lt;br /&gt;
    display.println(&amp;quot; Sound: &amp;quot; + String(soundOn ? &amp;quot;ON&amp;quot; : &amp;quot;OFF&amp;quot;) + &amp;quot;\r\n&amp;quot;);&lt;br /&gt;
    display.setTextSize(2);&lt;br /&gt;
    display.println((frequency &amp;lt; 100 ? &amp;quot; &amp;quot; : &amp;quot;&amp;quot;) + String(frequency) + &amp;quot;Hz&amp;quot;);&lt;br /&gt;
    display.println(&amp;quot;  &amp;quot; + String(int(duty / 10.24)) + &amp;quot;%&amp;quot;);&lt;br /&gt;
    display.display();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  yield();&lt;br /&gt;
  delay(50);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void sendGet() {&lt;br /&gt;
  pingMillis = millis();&lt;br /&gt;
&lt;br /&gt;
  if (!client.connect(&amp;quot;void-local.tablesugar.info&amp;quot;, 80)) {&lt;br /&gt;
    // Error&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  client.print(&amp;quot;GET /none.html HTTP/1.1\r\nHost: void-local.tablesugar.info\r\nConnection: close\r\n\r\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool checkGet() {&lt;br /&gt;
  if (client.available()) {&lt;br /&gt;
    // Got something&lt;br /&gt;
    client.stop();&lt;br /&gt;
    return true;&lt;br /&gt;
  } else if (millis() - pingMillis &amp;gt; 2000) {&lt;br /&gt;
    // Timeout&lt;br /&gt;
    client.stop();&lt;br /&gt;
    return true;&lt;br /&gt;
  }&lt;br /&gt;
  return false;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void testSD() {&lt;br /&gt;
//  Serial.print(&amp;quot;\nInitializing SD card...&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  if (DISPLAY_ENABLED) {&lt;br /&gt;
    display.clearDisplay();&lt;br /&gt;
    display.setTextSize(1);&lt;br /&gt;
    display.setTextColor(BLACK);&lt;br /&gt;
    display.setCursor(0, 0);&lt;br /&gt;
    display.println(&amp;quot;*Testing SD*&amp;quot;);&lt;br /&gt;
    display.display();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // we&amp;#039;ll use the initialization code from the utility libraries&lt;br /&gt;
  // since we&amp;#039;re just testing if the card is working!&lt;br /&gt;
  // if (!card.init(SPI_HALF_SPEED, PIN_SD_CS)) {&lt;br /&gt;
  if (!card.init(400000, PIN_SD_CS)) {&lt;br /&gt;
//    Serial.println(&amp;quot;initialization failed. Things to check:&amp;quot;);&lt;br /&gt;
//    Serial.println(&amp;quot;* is a card inserted?&amp;quot;);&lt;br /&gt;
//    Serial.println(&amp;quot;* is your wiring correct?&amp;quot;);&lt;br /&gt;
//    Serial.println(&amp;quot;* did you change the PIN_SD_CS pin to match your shield or module?&amp;quot;);&lt;br /&gt;
    if (DISPLAY_ENABLED) {&lt;br /&gt;
      display.println(&amp;quot;NO CARD!!!&amp;quot;);&lt;br /&gt;
      display.display();&lt;br /&gt;
    }&lt;br /&gt;
    return;&lt;br /&gt;
  } else {&lt;br /&gt;
//    Serial.println(&amp;quot;Wiring is correct and a card is present.&amp;quot;);&lt;br /&gt;
    // string2Line(&amp;quot;Card found&amp;quot;, 1);&lt;br /&gt;
    nextLineMillis = nextPing = 5000;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // print the type of card&lt;br /&gt;
//  Serial.print(&amp;quot;\nCard type: &amp;quot;);&lt;br /&gt;
  String cardType;&lt;br /&gt;
  switch (card.type()) {&lt;br /&gt;
    case SD_CARD_TYPE_SD1:&lt;br /&gt;
      cardType = &amp;quot;SD1&amp;quot;;&lt;br /&gt;
      break;&lt;br /&gt;
    case SD_CARD_TYPE_SD2:&lt;br /&gt;
      cardType = &amp;quot;SD2&amp;quot;;&lt;br /&gt;
      break;&lt;br /&gt;
    case SD_CARD_TYPE_SDHC:&lt;br /&gt;
      cardType = &amp;quot;SDHC&amp;quot;;&lt;br /&gt;
      break;&lt;br /&gt;
//    default:&lt;br /&gt;
//      Serial.println(&amp;quot;????&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Now we will try to open the &amp;#039;volume&amp;#039;/&amp;#039;partition&amp;#039; - it should be FAT16 or FAT32&lt;br /&gt;
  if (!volume.init(card)) {&lt;br /&gt;
//    Serial.println(&amp;quot;Could not find FAT16/FAT32 partition.\nMake sure you&amp;#039;ve formatted the card&amp;quot;);&lt;br /&gt;
//    Serial.println(cardType);&lt;br /&gt;
    if (DISPLAY_ENABLED) {&lt;br /&gt;
      display.println(&amp;quot;No partition\r\nFAT16/FAT32\r\nfmt needed.&amp;quot;);&lt;br /&gt;
      display.display();&lt;br /&gt;
    }&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // print the type and size of the first FAT-type volume&lt;br /&gt;
  uint32_t volumesize;&lt;br /&gt;
//  Serial.print(&amp;quot;\nVolume type is FAT&amp;quot;);&lt;br /&gt;
//  Serial.println(volume.fatType(), DEC);&lt;br /&gt;
//  Serial.println();&lt;br /&gt;
&lt;br /&gt;
//  Serial.println(cardType);&lt;br /&gt;
&lt;br /&gt;
  if (DISPLAY_ENABLED)&lt;br /&gt;
    display.println(cardType + &amp;quot;/FAT&amp;quot; + String(volume.fatType()));&lt;br /&gt;
&lt;br /&gt;
  volumesize = volume.blocksPerCluster();    // clusters are collections of blocks&lt;br /&gt;
  volumesize *= volume.clusterCount();       // we&amp;#039;ll have a lot of clusters&lt;br /&gt;
  volumesize *= 512;                            // SD card blocks are always 512 bytes&lt;br /&gt;
//  Serial.print(&amp;quot;Volume size (bytes): &amp;quot;);&lt;br /&gt;
//  Serial.println(volumesize);&lt;br /&gt;
//  Serial.print(&amp;quot;Volume size (Kbytes): &amp;quot;);&lt;br /&gt;
  volumesize /= 1024;&lt;br /&gt;
//  Serial.println(volumesize);&lt;br /&gt;
//  Serial.print(&amp;quot;Volume size (Mbytes): &amp;quot;);&lt;br /&gt;
  volumesize /= 1024;&lt;br /&gt;
//  Serial.println(volumesize);&lt;br /&gt;
&lt;br /&gt;
  if (volumesize &amp;lt; 1000) {&lt;br /&gt;
    if (DISPLAY_ENABLED)&lt;br /&gt;
      display.println(&amp;quot;Size: &amp;quot; + String(volumesize) + &amp;quot;MB&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    if (DISPLAY_ENABLED)&lt;br /&gt;
      display.println(&amp;quot;Size: &amp;quot; + String(round(volumesize / 100) / 10) + &amp;quot;GB&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (DISPLAY_ENABLED)&lt;br /&gt;
    display.display();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//  Serial.println(&amp;quot;\nFiles found on the card (name, date and size in bytes): &amp;quot;);&lt;br /&gt;
  root.openRoot(volume);&lt;br /&gt;
&lt;br /&gt;
  // list all files in the card with date and size&lt;br /&gt;
  root.ls(LS_R | LS_DATE | LS_SIZE);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void getNextFile() {&lt;br /&gt;
  static bool inited = false;&lt;br /&gt;
  static int fileCount = 0;&lt;br /&gt;
&lt;br /&gt;
//  Serial.println(&amp;quot;Get files...&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  if (DISPLAY_ENABLED) {&lt;br /&gt;
    display.clearDisplay();&lt;br /&gt;
    display.setTextSize(1);&lt;br /&gt;
    display.setTextColor(BLACK);&lt;br /&gt;
    display.setCursor(0, 0);&lt;br /&gt;
    display.print(&amp;quot;SD: &amp;quot; + String(fileCount) + &amp;quot; &amp;quot;);&lt;br /&gt;
    display.display();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (!inited &amp;amp;&amp;amp; !SD.begin(PIN_SD_CS)) {&lt;br /&gt;
//    Serial.println(&amp;quot;Initialization failed!&amp;quot;);&lt;br /&gt;
    if (DISPLAY_ENABLED) {&lt;br /&gt;
      display.println(&amp;quot;Initializat-\r\nion failed!&amp;quot;);&lt;br /&gt;
      display.display();&lt;br /&gt;
    }&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  inited = true;&lt;br /&gt;
&lt;br /&gt;
  File files = SD.open(&amp;quot;/&amp;quot;);&lt;br /&gt;
  File file;&lt;br /&gt;
  unsigned long fileSize;&lt;br /&gt;
&lt;br /&gt;
  int index = 0;&lt;br /&gt;
  while (true) {&lt;br /&gt;
    file = files.openNextFile();&lt;br /&gt;
    if (!file) {&lt;br /&gt;
      // end&lt;br /&gt;
//      Serial.println(&amp;quot;end of files&amp;quot;);&lt;br /&gt;
      if (DISPLAY_ENABLED)&lt;br /&gt;
        display.println(&amp;quot;end of files&amp;quot;);&lt;br /&gt;
        display.display();&lt;br /&gt;
      fileCount = 0;&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
    if (!file.isDirectory()) {&lt;br /&gt;
      if (index == fileCount) {&lt;br /&gt;
        // name of next file&lt;br /&gt;
//        Serial.print(String(file.name()));&lt;br /&gt;
        fileSize = file.size();&lt;br /&gt;
        if (fileSize &amp;lt; 1024) {&lt;br /&gt;
          if (DISPLAY_ENABLED)&lt;br /&gt;
            display.print(String(fileSize) + &amp;quot;Bytes&amp;quot;);&lt;br /&gt;
        } else if (fileSize &amp;lt; 100000) {&lt;br /&gt;
          if (DISPLAY_ENABLED)&lt;br /&gt;
            display.print(String(round(file.size() / 1024)) + &amp;quot;KB&amp;quot;);&lt;br /&gt;
        } else {&lt;br /&gt;
          if (DISPLAY_ENABLED)&lt;br /&gt;
            display.print(String(round(file.size() / 1024 / 10.24) / 100.0) + &amp;quot;MB&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        if (DISPLAY_ENABLED)&lt;br /&gt;
          display.println(&amp;quot;\r\n&amp;quot; + String(file.name()));&lt;br /&gt;
        fileCount++;&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
      index++;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  String fileContent = &amp;quot;&amp;quot;;&lt;br /&gt;
  while (file.available() &amp;amp;&amp;amp; fileContent.length() &amp;lt; 36) {&lt;br /&gt;
    fileContent += char(file.read());&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  while (fileContent.length() &amp;lt; 64)&lt;br /&gt;
    fileContent += &amp;quot; &amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  if (DISPLAY_ENABLED)&lt;br /&gt;
    display.println(fileContent);&lt;br /&gt;
&lt;br /&gt;
  display.display();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>ESP8266</name></author>
	</entry>
</feed>