Hello,
I'm trying to create a little room temperature sensor with a OLED display.
I'm using a:
Arduino Nano
BMP280
OLED, SD1306
My menu function and push button works fine, but when I try to add the BMP280 to the code, my OLED fails to initialize, and I get the serial print "SSD1306 allocation failed".
As you can see I also tried to add a delay before initializing the BMP280, which didn't do any difference.
I also tried to initialize the BMP280 before the OLED, but this didn't help either.
When I run the below code with all BMP280 stuff commented, the sketch runs fine.
But if I just try to remove the comments for the initializing of the BMP280 I get the error in the serial monitor, and the display is not initializing (the code compiles fine).
I tried running this sketch, LINK, which works fine (with adjusted addresses). So I conclude my BMP and OLED can work together.
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Button.h>
//#include <Adafruit_BMP280.h>
// OLED-konfiguration
#define OLED_ADDR 0x3C
#define OLED_RESET 4
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
//#define BMP280_I2C_ADDRESS 0x76 // I2C address, Address for BMP280 is usually 0x76 or 0x77
//Adafruit_BMP280 bmp280; // initialize Adafruit BMP280 library
// Buttons pin-no.
#define SELECT_PIN 2
Button upBtn(3); // Pin 3
Button downBtn(5); // Pin 5
// Define default setpoints
float roomSetpoint = 21.0; // Setpoint for room temperature
float floorSetpoint = 25.0; // Setpoint for floor temperature
int devAdr = 5; // Value for RS485 address (1-254)
unsigned long selectPressStart = 0; // Time the select-btn were pressed
unsigned long buttonHoldTime = 5000; // 5 sec for going to the settings menu
unsigned long lastActivityTime = 0; // Time for last activity in the menu
unsigned long inactivityTimeout = 60000; // 60 sec timeout for returning to the main menu
bool inMenu = false; // State if we are in the main- or settings menu
// For temperature measurement
// Create a BMP280-object
//unsigned long lastTempMeasurement = 0;
//unsigned long tempMeasurementInterval = 5000; // Temperate measurement every 5 sec
//char tempString[7]; // Buffer for a en negative temp with one decimal and degree-symbol (°)
byte menuCount = 1; // Actual menupoint
void setup() {
// Initialize seriel monitor and buttons
Serial.begin(9600);
pinMode(SELECT_PIN, INPUT);
upBtn.begin();
downBtn.begin();
// Initialize OLED-display
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
Serial.println(F("SSD1306 allocation failed"));
while (true); // Stops, ifs the display fails
}
// Clear display
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 10);
display.println("OLED OK");
display.display();
delay(2000);
// Wait 2 sec before BMP280 initialize
// delay(2000); // Wait 2 sec
/* if (!bmp280.begin(BMP280_I2C_ADDRESS)) {
//Serial.println("Kunne ikke finde BMP280 sensor!");
while (1);
}
*/
/*
// Setup BMP280
bmp280.setSampling(Adafruit_BMP280::MODE_NORMAL, // Measure continuously
Adafruit_BMP280::SAMPLING_X2, // Temperature sampling
Adafruit_BMP280::SAMPLING_X16, // Pressure sampling
Adafruit_BMP280::FILTER_X16, // Filter
Adafruit_BMP280::STANDBY_MS_500); // Standby time
*/
}
void loop() {
// If we are in the settings menu, show settings menu and handle input
if (inMenu) {
handleSettingsMenu();
} else {
// If we are in the main menu, show main menu and scan for long button press
displayMainMenu();
handleMainMenuLongPress();
}
}
void handleMainMenuLongPress() {
// Cehck if select-btn is pushed (HIGH)
if (digitalRead(SELECT_PIN) == HIGH) {
if (selectPressStart == 0) {
selectPressStart = millis(); // Start timer, when btn is pushed
Serial.println("Select button pressed");
}
// If select btn is hold for 5 sec
if (millis() - selectPressStart >= buttonHoldTime) {
Serial.println("Select button held for 5 seconds, entering Settings menu");
inMenu = true; // Go to settings Menu
selectPressStart = 0; // Zero timer
lastActivityTime = millis(); // Start inactivity timeren
menuCount = 1; // Clear to Menu point 1, when the menu is accessed
}
} else if (selectPressStart != 0) {
// If Select-btn is released before 5 sec
Serial.println("Select button released before 5 seconds");
selectPressStart = 0; // Zero timeren
}
}
void displayMainMenu() {
// Main Menu Screen
display.clearDisplay();
display.setTextSize(1);
display.setCursor(10, 0);
display.println("Main");
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(10, 20);
display.println("T: C");
display.setCursor(10, 40);
display.println("H: P");
display.display();
}
void handleSettingsMenu() {
// Show Settings menu and handle inputs
display.clearDisplay();
// change text display here
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(10, 0);
// menu title
display.println("Settings");
//---------------------------------
display.setTextSize(1);
// edit menu item 1 here
display.setCursor(10, 20);
display.println("Set Rum");
display.setCursor(80, 20);
display.println(roomSetpoint);
// edit menu item 2 here
display.setCursor(10, 30);
display.println("Set Gulv");
display.setCursor(80, 30);
display.println(floorSetpoint);
// edit menu item 3 here
display.setCursor(10, 40);
display.println("Set Adr");
display.setCursor(80, 40);
display.println(devAdr);
// edit menu item 4 here
display.setCursor(10, 50);
display.println("Tilbage");
display.setCursor(45, 50);
// Draw marker to show the actual menu point
display.setCursor(2, (menuCount * 10) + 10);
display.println(">");
display.display();
// Check buttons for activity and zero the inactivity timer
if (upBtn.pressed()) {
lastActivityTime = millis(); // Zero inactivity timer
if (menuCount <= 1)
menuCount = 4;
else
menuCount--;
}
if (downBtn.pressed()) {
lastActivityTime = millis(); // Zero inactivity timer
if (menuCount >= 4)
menuCount = 1;
else
menuCount++;
}
// When select-btn is pressed short in the menu
if (digitalRead(SELECT_PIN) == HIGH) {
Serial.println("Select button pressed in menu");
lastActivityTime = millis(); // Zero inactivity timer
executeMenuFunction(); // Execute the chossen function
}
// If 60 sec have passed without activity, return to Main Menu
if (millis() - lastActivityTime >= inactivityTimeout) {
Serial.println("No activity for 60 seconds, returning to main menu");
inMenu = false;
}
}
/*
// Function to update the temperature
void updateTemperature() {
// Read the temperature from the BMP280
float temperature = bmp.readTemperature();
// Convert temperature to a string
dtostrf(temperature, 4, 1, tempString); // 4 is the min. width, 1 is the decimals
strcat(tempString, "\xB0\C"); // add degree sign (°) and "C" to the string
Serial.print("Display Temp = ");
Serial.println(tempString); // Print the Display temp string to the Serial Monitor
}
*/
void executeMenuFunction() {
switch (menuCount) {
case 1:
Serial.println("Executing Set Rum");
break;
case 2:
Serial.println("Executing Set Gulv");
break;
case 3:
Serial.println("Executing Set Adr");
break;
case 4:
Serial.println("Executing Tilbage");
inMenu = false; // Return to the main menu
break;
}
}
// END