Hey guys,
My project is a basic home temperature monitor with a NodeMCU, a BME280 sensor, and an OLED screen. For a while I was happy to log the data to Thingspeak and update the OLED at the same time. However, having the OLED permanently on started to disturb me, so I added a button to the project, so the OLED would only show the latest data on demand, and only for a few seconds.
The problem is that the NodeMCU sends the data every 5 minutes. A millis() function with a 60 second delay assures it doesn’t send the data more than once at each period. However, during this delay, the code for the button is blocked and I cannot use it. Is there a way to have the two functions (Thingspeak update and screen) going on at the same time?
Code below:
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <BME280I2C.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "arduino_secrets.h"
#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET LED_BUILTIN // OLED reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // OLED setup
BME280I2C bme;
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password
WiFiClient client;
unsigned long myChannelNumber = SECRET_CH_ID;
const char * myWriteAPIKey = SECRET_WRITE_APIKEY;
// Initialize our values
int number1 = 0;
int number2 = 0;
int statuscode = 0;
String myStatus = "";
float tmp = 0;
float hmd = 0;
int buttonPin = 10;
int buttonState = 0;
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", 0 ,60000);
void setup() {
// Start everything
pinMode(buttonPin, INPUT_PULLUP); // declare pushbutton as input
Serial.begin(115200);
Wire.begin();
while(!bme.begin()) {
Serial.println("Could not find BME280 sensor!");
delay(1000);
}
ThingSpeak.begin(client);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
// Get NTP
timeClient.begin();
// Awake display
display.clearDisplay();
display.setCursor(0,0);
display.setTextSize(2);
display.setTextColor(WHITE);
display.println("Konichiwa!");
display.display();
// Ok to Serial
Serial.println("Setup completed.");
delay(5000);
display.clearDisplay();
display.display();
}
void loop() {
tmp = bme.temp();
hmd = bme.hum();
// Connect or reconnect to WiFi
if(WiFi.status() != WL_CONNECTED){
Serial.print("Attempting to connect to SSID: ");
Serial.println(SECRET_SSID);
while(WiFi.status() != WL_CONNECTED){
WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network
Serial.print(".");
delay(5000);
}
Serial.println("\nWifi connected.");
}
buttonState = digitalRead(buttonPin);
if (buttonState == LOW) {
Serial.println("clicked");
display.clearDisplay();
display.setCursor(0,0);
display.println("Now:");
display.print(tmp);
display.print(char(167));
display.println("C");
display.print(hmd);
display.println("%H");
display.display();
delay(5000);
display.clearDisplay();
display.display();
}
// Get the time and update if the time is right
timeClient.update();
int mm = timeClient.getMinutes();
if (mm % 5 == 0) {
// Set Thingspeak fields
ThingSpeak.setField(1, tmp);
ThingSpeak.setField(2, hmd);
// Set Thingspeak status
ThingSpeak.setStatus(myStatus);
// Write to ThingSpeak channelw
statuscode = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
// Get status
if(statuscode == 200){
Serial.println("Channel update successful.");
}
else{
Serial.println("Problem updating channel. HTTP error code " + String(statuscode));
}
delay(60000);
}
}