user have an adafruitssd1306 oled. The first few lines are yellow in the demo. --- assistant That’s expected behavior, not a fault. Many Adafruit SSD1306 OLED display modules are actually two-color displays: Top section (typically ~16 pixels high): yellow Rest of the screen: blue Why this happens The panel uses different organic compounds for different regions: Yellow-emitting OLED material at the top Blue-emitting OLED material for the rest It’s still driven by the same SSD1306 controller, so electrically it's identical to a normal monochrome display—just physically segmented in color. What it means for you You cannot change the colors in software—the color split is fixed in hardware. The display still behaves like a 1-bit framebuffer (on/off pixels). The color difference is purely visual. Typical use (why it exists) The yellow band is often used for: Headers / titles Status bars (battery, signal, etc.) Highlighted information If you didn’t expect this You might have bought a listing that said “monochrome” without mentioning “yellow/blue.” Common variants: Pure white Pure blue Yellow/blue (what you have) If you want uniform color, you’d need a single-color OLED variant, not this dual-color panel. If you want, I can show how to deliberately design your UI to take advantage of that yellow header area—it’s actually quite useful. --- user I have a BME280 on 0x77 and a screen on 0x3C (the oled), make a demo --- assistant Here’s a clean, working demo for your setup: BME280 at 0x77 Adafruit SSD1306 OLED display at 0x3C I’ll assume you’re using MicroPython on ESP32/ESP8266 (tell me if you’re on Arduino instead). 🔧 Wiring (quick sanity check) Device Pin BME280 + OLED VCC 3.3V GND GND SDA GPIO21 (ESP32 typical) SCL GPIO22 (ESP32 typical) 📦 Required libraries You’ll need: ssd1306.py bme280.py If you don’t have them, I can provide versions. 🧪 Demo Code Python Run from machine import Pin, I2C import ssd1306 import bme280 import time # I2C setup i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=100000) # Scan to confirm devices print("I2C devices:", i2c.scan()) # OLED setup (0x3C) oled = ssd1306.SSD1306_I2C(128, 64, i2c, addr=0x3C) # BME280 setup (0x77) sensor = bme280.BME280(i2c=i2c, address=0x77) while True: # Read sensor temp, pressure, humidity = sensor.values # Clear display oled.fill(0) # Header (this will appear in the yellow band) oled.text("ENV SENSOR", 0, 0) # Data oled.text("Temp: " + temp, 0, 16) oled.text("Hum: " + humidity, 0, 32) oled.text("Pres: " + pressure, 0, 48) # Show oled.show() # Debug output print(temp, humidity, pressure) time.sleep(2) 🧠 Notes (important details) sensor.values returns strings like: "23.5C" "1013.2hPa" "45.6%" The top 16px (yellow band) is perfect for the "ENV SENSOR" header. If nothing shows: Check i2c.scan() → should return [60, 119] (0x3C, 0x77) 🧪 Expected Output Screen layout: ENV SENSOR ← yellow section Temp: 23.5C Hum: 45.6% Pres: 1013hPa 🚀 Optional upgrades If you want to push this further: Add icons (small bitmaps) Smooth update (no flicker) Graph temperature over time Show dew point / altitude If you're actually using Arduino (C++) instead of MicroPython, say so—I’ll rewrite this using Adafruit libraries. --- assistant Got it! Here’s a fixed version of your original menu using: UP/DOWN on GPIO2/3 as before SELECT on GPIO20 with an internal pull-up so it no longer constantly triggers OLED menu as before Serial debug C++ #include #include #include #include #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_ADDR 0x3C Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); Adafruit_BME280 bme; // your SEN0236 sensor // Buttons / touch pins as digital inputs #define PIN_UP 2 #define PIN_DOWN 3 #define PIN_SELECT 20 // now with pull-up const int debounceDelay = 200; // ms unsigned long lastPress = 0; // Menu items const char* menuItems[] = {"Show Temp", "Show Humidity", "Show Pressure", "Test Output"}; const int menuLength = 4; int selected = 0; void setup() { Serial.begin(115200); Wire.begin(6, 7); // I2C SDA/SCL for OLED + BME280 // Buttons: UP/DOWN normal, SELECT with internal pull-up pinMode(PIN_UP, INPUT); pinMode(PIN_DOWN, INPUT); pinMode(PIN_SELECT, INPUT_PULLUP); // OLED init if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) { Serial.println("SSD1306 init failed"); while (1); } display.clearDisplay(); display.setTextColor(SSD1306_WHITE); // BME280 init if (!bme.begin(0x77)) { Serial.println("BME280 not found!"); while (1); } } void loop() { handleInput(); drawMenu(); delay(50); } void handleInput() { unsigned long now = millis(); if (now - lastPress < debounceDelay) return; // UP button if (digitalRead(PIN_UP)) { selected--; if (selected < 0) selected = menuLength - 1; Serial.println("UP pressed"); lastPress = now; } // DOWN button if (digitalRead(PIN_DOWN)) { selected++; if (selected >= menuLength) selected = 0; Serial.println("DOWN pressed"); lastPress = now; } // SELECT button (active LOW) if (digitalRead(PIN_SELECT) == LOW) { Serial.print("SELECT: "); Serial.println(menuItems[selected]); runAction(selected); lastPress = now; } } void drawMenu() { display.clearDisplay(); // Header display.setCursor(0, 0); display.setTextSize(1); display.println("MENU"); for (int i = 0; i < menuLength; i++) { int y = 16 + (i * 10); display.setCursor(0, y); if (i == selected) display.print("> "); else display.print(" "); display.println(menuItems[i]); } display.display(); } void runAction(int index) { display.clearDisplay(); display.setCursor(0, 0); display.setTextSize(1); switch (index) { case 0: Serial.println("Temp selected"); display.println("Temp selected"); break; case 1: Serial.println("Humidity selected"); display.println("Humidity selected"); break; case 2: Serial.println("Pressure selected"); display.println("Pressure selected"); break; case 3: Serial.println("Test output triggered"); display.println("Test OK"); break; } display.display(); delay(1000); } ✅ Key Fix PIN_SELECT now uses INPUT_PULLUP Check with digitalRead(PIN_SELECT) == LOW for a press Stops the flickering / repeated triggers you were seeing If you want, I can also combine this with your “big Temp / scroll Humidity/Pressure” display style, so you have a single large number and units for the sensor values while still scrolling with UP/DOWN. Do you want me to do that? --- user I want the display to have the layout (sample values and I don't have degree symbol on my keyboard): (LARGE ALL CAPS) TEMP: 20degC (small) HUM: 75% (small) etc. And pressing down, should make it: (small) TEMP: 20degC (LARGE ALL CAPS) HUM: 75% (small) etc. Instead of Menu, should just say Hello World Add an MQTT library so I can log to home assistant Show more --- assistant Good—this is a clean UI pattern and a sensible next step adding MQTT. You’ll get: 3 metrics always visible One “focused” (large) item UP/DOWN cycles focus Header: "Hello World" MQTT publishing for Home Assistant 📦 Libraries needed Adafruit SSD1306 Adafruit GFX Adafruit BME280 PubSubClient (MQTT) WiFi (built-in for ESP32) ⚡ Full Working Code C++ #include #include #include #include #include #include #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_ADDR 0x3C Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); Adafruit_BME280 bme; // Buttons #define BTN_UP 2 #define BTN_DOWN 3 // WiFi + MQTT const char* ssid = "YOUR_WIFI"; const char* password = "YOUR_PASS"; const char* mqtt_server = "192.168.1.100"; WiFiClient espClient; PubSubClient client(espClient); // State int selected = 0; // 0=temp,1=hum,2=pres unsigned long lastPress = 0; const int debounceDelay = 200; unsigned long lastMQTT = 0; void setup() { Serial.begin(115200); Wire.begin(6, 7); pinMode(BTN_UP, INPUT); pinMode(BTN_DOWN, INPUT); display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR); display.setTextColor(SSD1306_WHITE); if (!bme.begin(0x77)) { Serial.println("BME280 failed"); while (1); } setup_wifi(); client.setServer(mqtt_server, 1883); } void loop() { handleButtons(); drawDisplay(); mqttLoop(); delay(50); } void handleButtons() { unsigned long now = millis(); if (now - lastPress < debounceDelay) return; if (digitalRead(BTN_UP)) { selected--; if (selected < 0) selected = 2; lastPress = now; } if (digitalRead(BTN_DOWN)) { selected++; if (selected > 2) selected = 0; lastPress = now; } } void drawLine(int index, int y, float value) { bool isSelected = (index == selected); display.setCursor(0, y); if (isSelected) display.setTextSize(2); else display.setTextSize(1); switch (index) { case 0: display.print("TEMP: "); display.print(value, 1); display.print("C"); break; case 1: display.print("HUM: "); display.print(value, 0); display.print("%"); break; case 2: display.print("PRES: "); display.print(value, 0); display.print("hPa"); break; } } void drawDisplay() { display.clearDisplay(); // Header display.setTextSize(1); display.setCursor(0, 0); display.println("Hello World"); float t = bme.readTemperature(); float h = bme.readHumidity(); float p = bme.readPressure() / 100.0F; // Layout positions drawLine(0, 16, t); drawLine(1, 32, h); drawLine(2, 48, p); display.display(); } void setup_wifi() { delay(10); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); } } void reconnect() { while (!client.connected()) { client.connect("ESP32C3Client"); } } void mqttLoop() { if (!client.connected()) { reconnect(); } client.loop(); // Publish every 10s if (millis() - lastMQTT > 10000) { lastMQTT = millis(); float t = bme.readTemperature(); float h = bme.readHumidity(); float p = bme.readPressure() / 100.0F; char payload[16]; dtostrf(t, 4, 1, payload); client.publish("home/sensor/temp", payload); dtostrf(h, 4, 1, payload); client.publish("home/sensor/humidity", payload); dtostrf(p, 4, 1, payload); client.publish("home/sensor/pressure", payload); Serial.println("MQTT published"); } } 🧠 What you get Display behavior Hello World TEMP: 20.1C ← big when selected HUM: 75% PRES: 1013hPa Scroll ↓: Hello World TEMP: 20.1C HUM: 75% ← big now PRES: 1013hPa 📡 Home Assistant Integration You’ll get MQTT topics: home/sensor/temp home/sensor/humidity home/sensor/pressure Example HA config (manual) YAML sensor: - platform: mqtt name: "Room Temperature" state_topic: "home/sensor/temp" unit_of_measurement: "°C" - platform: mqtt name: "Room Humidity" state_topic: "home/sensor/humidity" unit_of_measurement: "%" - platform: mqtt name: "Room Pressure" state_topic: "home/sensor/pressure" unit_of_measurement: "hPa" 🔧 Small improvements you might want next Proper ° symbol (\xB0) Retained MQTT messages (important for HA restart) Auto-discovery for Home Assistant (no YAML needed) Smoother UI (no full redraw flicker) Highlight bar instead of just size change If you want, I can convert this to MQTT auto-discovery so it just appears in Home Assistant instantly without config. --- user write a function, that draws three variables to the screen, that I can call like: simpleScreen(t,h,p); where temp, humidity and pressure are passed --- assistant I'd make it a function that takes the values and the selected item, so your button handler can simply change selectedMetric and redraw. C++ // selected: // 0 = TEMP // 1 = HUM // 2 = PRES void simpleScreen(float t, float h, float p, int selected) { display.clearDisplay(); // Header in yellow area display.setTextSize(1); display.setCursor(0, 0); display.println("Hello World"); int y = 16; // TEMP display.setCursor(0, y); display.setTextSize(selected == 0 ? 2 : 1); display.print("TEMP: "); display.print(t, 1); display.println("C"); y += (selected == 0 ? 18 : 10); // HUM display.setCursor(0, y); display.setTextSize(selected == 1 ? 2 : 1); display.print("HUM: "); display.print(h, 0); display.println("%"); y += (selected == 1 ? 18 : 10); // PRESSURE display.setCursor(0, y); display.setTextSize(selected == 2 ? 2 : 1); display.print("PRES: "); display.print(p, 0); display.println("hPa"); display.display(); } Usage: C++ float t = bme.readTemperature(); float h = bme.readHumidity(); float p = bme.readPressure() / 100.0F; simpleScreen(t, h, p, selectedMetric); And your buttons simply do: C++ if (digitalRead(BTN_UP)) { selectedMetric--; if (selectedMetric < 0) selectedMetric = 2; } if (digitalRead(BTN_DOWN)) { selectedMetric++; if (selectedMetric > 2) selectedMetric = 0; } One thing to note: a 128×64 OLED is pretty cramped. When a line is TextSize(2), "PRES: 1013hPa" is likely too wide and may clip. I'd actually recommend abbreviating to: C++ TEMP: 20.1C HUM: 75% P: 1013hPa or C++ TEMP 20.1C HUM 75% PRES 1013 which looks much cleaner on a 128×64 display.