Skip to content
My Favourite GameMy Favourite GameEst. 2017

How to use a 1.54 inch 128x64 OLED with a flow sensor?

admin · · My Favourite Game Editorial · Our standards

How to Use a 1.54 Inch 128x64 OLED with a Flow Sensor

To answer the question directly: you connect a 1.54 inch 128x64 oled display to a flow sensor by wiring the SPI interface of the OLED to a microcontroller (like Arduino or ESP32) and the flow sensor’s pulse output to a digital input pin, then write code to read the sensor’s frequency and display live flow rate and total volume on the OLED. The OLED runs at 3.3V logic (5V tolerant on some boards) and draws about 20-25mA during operation, while most flow sensors like the YF-S201 or FS300A output a 5V pulse train at 5-7Hz per liter per minute. This setup is common in water monitoring systems, coffee machines, or irrigation controllers where you need both real-time data logging and a compact display.

The 1.54 inch 128x64 oled display has a resolution of 128x64 pixels, uses a monochrome white or blue OLED panel, and communicates via SPI (or I2C, but SPI is faster for updating data). The driver chip is typically the SH1106 or SSD1306, though the 1.54 inch variant often uses SH1106 because it natively supports 128x64 without internal RAM mapping issues. The SPI interface requires four pins: CS (chip select), DC (data/command), MOSI (master out slave in), and SCK (serial clock). You also need VCC (3.3V) and GND. Some breakout boards include a RESET pin, but you can tie it to VCC if not used. The display’s refresh rate can exceed 10 frames per second when updating partial areas, which is more than enough for flow data that changes every 100-500 milliseconds.

For the flow sensor, common models include the Hall-effect type like the YF-S201 (rated for 1-30 L/min, with a 5-18V input range) or the FS300A (0.3-6 L/min, 3.5-12V). The sensor outputs a square wave whose frequency is proportional to flow rate. For example, the YF-S201 has a K-factor of 450 pulses per liter (some variants use 588), meaning at 1 L/min you get 7.5 Hz. The pulse width is typically 50% duty cycle, and the output is open-collector, so you need a pull-up resistor (e.g., 10kΩ to 5V) if your microcontroller’s input doesn’t have one built-in. The sensor’s power supply can be 5V, but the output logic level is also 5V, so you must use a voltage divider (two resistors, like 1kΩ and 2kΩ) to drop it to 3.3V if your OLED and MCU run at 3.3V logic. Alternatively, use a level shifter module.

Wiring example for Arduino Uno (5V logic) or ESP32 (3.3V logic):
- OLED VCC to 3.3V (never 5V on most OLED modules, check datasheet)
- OLED GND to GND
- OLED CS to digital pin 10 (or any available)
- OLED DC to digital pin 9
- OLED MOSI to digital pin 11 (SPI MOSI on Uno) or pin 23 on ESP32
- OLED SCK to digital pin 13 (SPI SCK on Uno) or pin 18 on ESP32
- Flow sensor VCC to 5V (or 3.3V if rated, but most need 5V for accurate pulses)
- Flow sensor GND to GND
- Flow sensor output to digital pin 2 (interrupt-capable pin on Uno) or pin 4 on ESP32
- Add a 10kΩ pull-up resistor from flow sensor output to 5V (if open-collector)
- Add a voltage divider (2.2kΩ series, 3.3kΩ to GND) between flow sensor output and MCU pin if using 3.3V logic.

Code example in Arduino IDE (using the Adafruit_SSD1306 library, but you need to configure for SH1106 if that’s your driver):

```cpp
#include
#include
#include

#define OLED_MOSI 11
#define OLED_CLK 13
#define OLED_DC 9
#define OLED_CS 10
#define OLED_RESET -1 // no reset pin

Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_CS, OLED_RESET);

#define FLOW_SENSOR_PIN 2
volatile unsigned long pulseCount = 0;
unsigned long lastTime = 0;
float flowRate = 0.0;
float totalVolume = 0.0;
const float K_FACTOR = 450.0; // pulses per liter for YF-S201

void setup() {
Serial.begin(115200);
pinMode(FLOW_SENSOR_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(FLOW_SENSOR_PIN), countPulse, RISING);
if(!display.begin(SSD1306_SWITCHCAPVCC)) { // or use SH1106_SWITCHCAPVCC
Serial.println("OLED init failed");
while(1);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0,0);
display.println("Flow Meter");
display.display();
delay(2000);
}

void loop() {
unsigned long currentTime = millis();
if (currentTime - lastTime >= 1000) { // every second
detachInterrupt(digitalPinToInterrupt(FLOW_SENSOR_PIN));
flowRate = (pulseCount / K_FACTOR) * 60.0; // L/min
totalVolume += (pulseCount / K_FACTOR); // liters
pulseCount = 0;
lastTime = currentTime;
attachInterrupt(digitalPinToInterrupt(FLOW_SENSOR_PIN), countPulse, RISING);
updateDisplay();
}
}

void countPulse() {
pulseCount++;
}

void updateDisplay() {
display.clearDisplay();
display.setCursor(0,0);
display.print("Flow: ");
display.print(flowRate, 2);
display.print(" L/min");
display.setCursor(0,16);
display.print("Total: ");
display.print(totalVolume, 3);
display.print(" L");
display.display();
}
```

This code uses interrupts to count pulses accurately, updates the display every second, and shows both flow rate and cumulative volume. The OLED’s 128x64 resolution lets you display two lines of text with 16-pixel font height, or you can use larger fonts for fewer lines. If you need more data fields, like peak flow or time, you can adjust the layout. The 1.54 inch 128x64 oled display is available from various suppliers, and you can find a reliable module at 1.54 inch 128x64 oled display that includes the SH1106 driver and SPI interface, which simplifies wiring.

One common issue is voltage mismatch. The OLED’s logic voltage is 3.3V, but many flow sensors output 5V. If you connect the sensor directly to a 3.3V MCU pin, you risk damaging the pin. Use a voltage divider with two resistors: calculate R1 (series) and R2 (to GND) such that Vout = Vin * R2 / (R1 + R2). For 5V to 3.3V, use R1=2.2kΩ and R2=3.3kΩ, which gives about 3.0V (safe for 3.3V logic). Alternatively, use a logic level converter module like the BSS138-based one. For 5V MCUs like Arduino Uno, you can connect the sensor directly, but the OLED still needs 3.3V. Some OLED modules have a built-in 3.3V regulator, but check the datasheet—if it says “5V tolerant,” you can power it from 5V, but the logic pins remain 3.3V only.

Another detail: the flow sensor’s pulse output can be noisy, especially in environments with pumps or solenoids. Add a 0.1µF ceramic capacitor between the sensor output and GND, and a 100Ω resistor in series with the signal line to the MCU. This filters high-frequency noise that could cause false interrupts. Also, use a pull-up resistor to 5V (or 3.3V if using voltage divider) to ensure clean transitions. The YF-S201’s internal Hall sensor has a weak pull-up, so external pull-up is recommended.

Power consumption: the OLED draws about 20mA with all pixels on, but you can reduce it by using the display’s sleep mode (send a command 0xAE to turn off, 0xAF to turn on). The flow sensor draws 5-15mA depending on the model. Total system current is around 50-100mA including the MCU, which is fine for USB power or a 9V battery with a regulator. If you’re using battery power, consider using the OLED’s partial display mode to update only the changed area, which reduces power consumption by 30-40%.

Data accuracy: flow sensors have a typical accuracy of ±5% to ±10% of reading, depending on the model and calibration. The YF-S201’s K-factor can vary by ±15% between units, so you should calibrate it by measuring a known volume (e.g., 1 liter) and adjusting the K_FACTOR in code. For example, if you collect 1 liter and the sensor counts 480 pulses, set K_FACTOR to 480. You can automate this by adding a calibration mode that stores the value in EEPROM. The OLED’s display refresh rate doesn’t affect accuracy, but the interrupt service routine must be fast—keep it minimal (just increment a counter) to avoid missing pulses at high flow rates. At 30 L/min, the YF-S201 outputs 225 Hz, which is well within the interrupt handling capacity of any modern MCU.

For the 1.54 inch 128x64 oled display, the SPI clock speed can be set up to 10 MHz, but the SH1106’s maximum is typically 8 MHz. Use 4 MHz for reliability. The display’s contrast is adjustable via command 0x81 followed by a byte (0x00 to 0xFF, default 0x7F). You can store the contrast value in EEPROM and let the user adjust it with a button. The OLED’s viewing angle is 160 degrees, and it’s readable in direct sunlight if you set the brightness high, but it’s not as bright as a TFT LCD. The 128x64 resolution gives you 1024 pixels, enough for a bar graph of flow rate, a numeric readout, and a small status icon. For example, you can draw a horizontal bar representing 0-100% of the sensor’s range, updated every second.

If you’re using an ESP32, the code is similar but you need to adjust SPI pins and use the ESP32’s interrupt handling. The ESP32 has two cores, so you can run the display update on core 1 and the sensor reading on core 0. Use the FreeRTOS tasks to avoid blocking. For example, create a task that reads the flow sensor every 100ms and updates a shared variable, while another task updates the OLED every 500ms. This prevents the display from slowing down the sensor reading. The ESP32’s deep sleep mode can reduce power to 5µA, but the OLED will turn off. You can wake up periodically to record data and update the display.

Common pitfalls: forgetting to set the OLED’s SPI mode. The SH1106 expects SPI mode 0 (CPOL=0, CPHA=0) or mode 3 (CPOL=1, CPHA=1), but most libraries use mode 0. If the display shows garbage, check the SPI mode. Also, the OLED’s CS pin must be pulled low during communication. If you’re using multiple SPI devices, ensure each has a unique CS line. The flow sensor’s interrupt pin must be capable of detecting rising edges; on some MCUs, only specific pins support interrupts (e.g., pins 2 and 3 on Arduino Uno). Use the digitalPinToInterrupt() function to map correctly.

Real-world example: a water flow meter for a home garden irrigation system. The sensor is placed in the main water line, and the OLED is mounted on a control box. The MCU logs total volume to an SD card every hour, and the OLED shows current flow rate and daily total. The system runs on a 12V battery with a 5V regulator, and the OLED’s power is switched via a MOSFET to save battery when not in use. The code includes a button to reset the daily total, and the OLED displays a small battery icon. The total cost is under $20 for the display and sensor, plus the MCU.

For troubleshooting, use a multimeter to check the OLED’s VCC pin—it should be 3.3V. If it’s 0V, check the wiring. The flow sensor’s output should show a square wave on an oscilloscope; if it’s stuck high or low, the sensor might be blocked or the magnet inside may be stuck. The OLED’s contrast can be adjusted in software, but if the display is too dim, increase the contrast value. The SPI wiring is critical: long wires (over 10cm) can cause signal degradation. Use twisted-pair wires or shielded cables for the SPI lines, especially if the sensor is far from the MCU. The flow sensor’s cable can be extended up to 10 meters with 22AWG wire, but the pulse signal may need a buffer if longer.

Advanced tip: use the OLED’s graphics capabilities to draw a real-time graph of flow rate over the last 10 seconds. The 128x64 resolution allows a 128-pixel wide graph with 64 pixel height. Map the flow rate range (0-30 L/min) to 0-63 pixels, and shift the graph left every second. This gives a visual trend that’s more intuitive than numbers alone. The code for this is straightforward: store an array of 128 bytes for the graph, shift it each update, and draw lines using the Adafruit_GFX library’s drawLine() function. The OLED’s update speed is fast enough for this.

Finally, note that the 1.54 inch 128x64 oled display is not the same as the 0.96 inch version. The 1.54 inch has a larger physical size (about 36x24mm active area) and uses the SH1106 driver, which has 128x64 pixels of RAM. The 0.96 inch often uses SSD1306 with 128x64 pixels but a smaller die. The SPI pinout is similar, but the initialization commands differ slightly. For the SH1106, you need to set the segment remap and COM scan direction to match the layout. The library’s begin() function usually handles this, but if the display is upside-down, add a command: display.setRotation(2).

a

admin

Staff Writer · My Favourite Game

Part of the 14-person editorial team. Get to know the rest of the desk on the community page.

Keep reading

Find your next favourite game

Long-form reviews, lore explainers and the kind of build theorycrafting that turns a game you like into a game you love.

Find Your Next Favourite