Skip to content
Domostroi Строительство · Инженерия · Гарантия
+7 (495) 740-28-91 СРО · ГОСТ Р

How to display a clock on a 3.2 inch 256x64 OLED screen?

admin Автор · Domostroi
| | Domostroi

To display a clock on a 3.2 inch 256x64 OLED screen, you need to combine a microcontroller, a real-time clock module, and a graphic library to drive the display. The 3.2 inch 256x64 OLED display module is a monochrome panel with a resolution of 256 pixels horizontally and 64 pixels vertically, typically using SSD1322 or similar controller IC that supports SPI interface. This specific screen size and resolution are ideal for showing a clock with large digits, date, and even secondary information like temperature or seconds, because the 3.2-inch diagonal gives you a physical area of about 72.0mm by 18.0mm (assuming a typical pixel pitch of 0.28mm), which is spacious enough for readable text at a distance of 30-50 cm.

Let’s start with the hardware. You’ll need a microcontroller with enough RAM and flash to handle the frame buffer for 256x64 pixels. A monochrome OLED at 1 bit per pixel requires 256 * 64 / 8 = 2048 bytes for a full frame buffer. Most Arduino boards, like the Arduino Uno or Nano, have only 2KB of SRAM, which is tight but doable if you optimize memory usage. However, I recommend using an ESP32 or STM32, which have at least 32KB of SRAM and 4MB of flash, giving you room for fonts, graphics, and networking. For the clock source, a DS3231 RTC module is the standard choice because it has a temperature-compensated crystal oscillator with accuracy of ±2 ppm, meaning it drifts less than 1 minute per year. Alternatively, you can use a GPS module or NTP over Wi-Fi for higher accuracy, but for a standalone clock, the DS3231 is reliable and cheap—around $3 to $5 on average.

The 3.2 inch 256x64 oled display module typically uses a 4-wire SPI interface: CS, DC, SCK, and MOSI. Some modules also have a RESET pin. The SPI clock speed can go up to 10 MHz, which allows you to update the entire screen in about 1.6 milliseconds (2048 bytes * 8 bits / 10 MHz = 1.638 ms). This is fast enough for smooth animations like a sweeping second hand. The display’s contrast ratio is typically 2000:1, and the brightness is around 100 cd/m² for monochrome yellow or white OLEDs. The viewing angle is 160 degrees, so it’s readable from any direction. The power consumption is about 20 mA at full brightness, which is low enough for battery-powered projects if you use a deep sleep mode.

Now, let’s talk about the software stack. The most common library for SSD1322-based OLEDs is the U8g2 library by olikraus, which supports over 1000 display controllers and includes many fonts. For a 256x64 display, you can use fonts like “u8g2_font_logisoso32_tf” (32 pixel height) or “u8g2_font_fub30_tf” (30 pixel height) to display the time in large digits. For example, a 32-pixel font can show two digits (like “12”) with a width of about 40 pixels each, leaving room for colons and AM/PM. You can also use a 16-pixel font for the date and seconds. The U8g2 library uses a page buffer mode if you have limited RAM, but for the ESP32, you can use the full buffer mode for faster updates.

To display the clock, you need to read the time from the RTC every second and update the screen. The DS3231 communicates via I2C, so you connect SDA and SCL to the microcontroller. The I2C address is 0x68. The library for DS3231, like RTClib by Adafruit, provides functions like “now()” to get the current time. The typical code structure is: initialize the display, initialize the RTC, then in the loop, read the time, clear the buffer, draw the digits, and send the buffer to the display. For a 256x64 screen, you can split the display into sections: the top 32 pixels for the time (hours and minutes in large font), the middle 16 pixels for seconds, and the bottom 16 pixels for the date or temperature. This layout uses the full height efficiently.

Here’s a practical example of the pixel layout. The screen is 256 pixels wide and 64 pixels high. If you place the time at the center, you can calculate the position. For a 4-digit time like “12:34”, each digit is 40 pixels wide, and the colon is 20 pixels wide, so the total width is 40*4 + 20 = 180 pixels. The center is at x = (256 - 180) / 2 = 38 pixels. The y position for the top of the digits can be 0, so the digits occupy rows 0 to 31. The seconds can be displayed at x = 38, y = 32, using a 16-pixel font. The date at y = 48, using a 12-pixel font. This gives you a clear, readable layout.

For better readability, you can add a colon that blinks every second. This is a simple visual cue that the clock is running. You can also draw a border around the time or use inverse video for the background. The OLED’s contrast can be adjusted via software using the “setContrast()” function, which accepts values from 0 to 255. I recommend setting it to 128 for a balance between brightness and power consumption.

If you want to add temperature or humidity, you can connect a DHT22 sensor. The DHT22 has an accuracy of ±0.5°C for temperature and ±2% for humidity. You can display this data on the bottom line of the screen. The update rate for the sensor can be every 2 seconds, as the DHT22 requires a minimum 1-second interval between readings. This adds practical value to the clock, making it a weather station as well.

Another consideration is the power supply. The 3.2 inch OLED draws about 20 mA at 3.3V, the DS3231 draws about 200 µA, and the ESP32 draws about 80 mA when active. So the total current is around 100 mA. If you use a 2000 mAh Li-ion battery, the clock can run for about 20 hours continuously. To extend battery life, you can put the ESP32 into deep sleep between updates. For example, wake up every second, update the display, then go back to sleep. The deep sleep current of the ESP32 is about 10 µA, so the average current becomes (20 mA * 0.1 second + 10 µA * 0.9 second) / 1 second ≈ 2 mA. This gives you about 1000 hours of runtime, or 41 days, on a 2000 mAh battery. However, the OLED itself needs to be refreshed continuously, so you need to use a display with a built-in frame buffer that retains the image during sleep. The SSD1322 has internal RAM, so it can hold the image without the microcontroller.

For the enclosure, you can use a 3D-printed case with a cutout for the screen. The OLED module has a mounting hole pattern of 2.54 mm pitch, so you can use M3 screws to secure it. The thickness of the module is about 1.5 mm for the PCB and 2.0 mm for the glass, so total thickness is around 3.5 mm. The viewing area is 73.0 mm by 19.0 mm, so the cutout should be slightly larger, say 75 mm by 21 mm, to avoid pressure on the glass.

Let’s talk about the font rendering. The U8g2 library supports both fixed-width and proportional fonts. For a clock, proportional fonts look better because the digits have different widths. For example, the digit “1” is narrower than “8”. The library calculates the width of each character and positions them accordingly. You can also use the “drawStr()” function with a string like “12:34”. To center the string, you can use “getStrWidth()” to get the pixel width and then calculate the x offset. This is done in the code like this: “int width = u8g2.getStrWidth(timeStr); int x = (256 - width) / 2; u8g2.drawStr(x, 32, timeStr);”. This ensures the time is always centered regardless of the digit combination.

For the second hand, you can draw a line or a small circle. The SSD1322 supports drawing lines with the “drawLine()” function. The line width is 1 pixel by default, but you can draw multiple lines to simulate a thicker line. For example, to draw a second hand that moves every second, you can calculate the angle from the center of the screen. The center of the screen is at (128, 32). The length of the second hand can be 30 pixels. The angle is 6 * seconds, so the endpoint is (128 + 30 * sin(angle), 32 - 30 * cos(angle)). You draw a line from the center to the endpoint. However, the OLED has a slow response time of about 10 ms, so you don’t see ghosting. But you need to clear the previous second hand before drawing the new one. You can do this by redrawing the entire background or by using a separate buffer for the second hand.

Another approach is to use a digital clock with a large font and no second hand. This is simpler and uses less CPU time. The update rate is once per second, which is fine for most applications. The screen can be updated in about 2 ms, so the microcontroller spends most of its time idle. This is good for battery life.

If you want to add a network time protocol (NTP) feature, you can use the ESP32’s Wi-Fi to fetch the time from an NTP server. The ESP32 has a built-in RTC that can be synchronized with NTP. The accuracy is within a few milliseconds of the server. The NTP update can be done once per day to avoid drift. The code uses the “configTime()” function to set the time zone and NTP server. Then you can get the time using “getLocalTime()”. This eliminates the need for an external RTC, but it requires Wi-Fi. If the Wi-Fi is not available, the clock will still run using the internal RTC, which has a drift of about 10 ppm, or 0.86 seconds per day. This is acceptable for most users.

For the display’s color, the 3.2 inch 256x64 OLED is monochrome, but you can choose between white, yellow, or blue. White is the most readable and has the highest contrast. Yellow is often used for retro aesthetics. The brightness can be adjusted by the contrast setting. The typical lifetime of an OLED is about 50,000 hours at half brightness, which is about 5.7 years of continuous use. This is sufficient for a desk clock that runs 24/7.

Let’s look at a table of common components and their specifications for this project:

Component Specification Cost (USD)
3.2 inch 256x64 OLED SSD1322, SPI, 256x64, 3.2", monochrome $15-25
ESP32 Dev Board 240 MHz, 520KB SRAM, 4MB flash, Wi-Fi $5-10
DS3231 RTC Module ±2 ppm, I2C, battery backup $3-5
DHT22 Sensor ±0.5°C, ±2% RH, 1-wire $3-5
3.3V Power Supply 500 mA, USB or battery $2-10

Now, let’s discuss the code structure in more detail. The initialization sequence for the OLED is: reset the display, set the display off, set the multiplex ratio to 63 (since it’s 64 rows), set the display start line to 0, set the column address range to 0 to 127 (since the SSD1322 uses 128 columns per half, but the 256x64 mode uses two halves), set the contrast, set the segment remap, and then set the display on. The U8g2 library handles all of this automatically. You just need to call “u8g2.begin()”. Then you can set the font and draw text.

For the clock loop, you can use a timer interrupt to update the time every second. On the ESP32, you can use the “millis()” function and check if 1000 ms have passed. This is simpler than using an interrupt. The code looks like this:

if (millis() - lastUpdate >= 1000) {
lastUpdate = millis();
DateTime now = rtc.now();
char timeStr[6];
sprintf(timeStr, "%02d:%02d", now.hour(), now.minute());
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_logisoso32_tf);
u8g2.drawStr(centerX, 32, timeStr);
u8g2.sendBuffer();
}

This code reads the time, formats it, clears the buffer, draws the time, and sends it to the display. The centerX is calculated as described earlier. The “sendBuffer()” function sends the entire 2048 bytes to the display via SPI. This takes about 1.6 ms at 10 MHz, which is negligible.

If you want to display the seconds, you can add another line with a smaller font. For example, “u8g2.setFont(u8g2_font_fub14_tf);” and then “u8g2.drawStr(centerX, 48, secStr);”. The secStr is a 2-character string like “45”. This gives you a complete clock with hours, minutes, and seconds.

For the date, you can use “u8g2.setFont(u8g2_font_6x10_tf);” and draw the date at the bottom. The date string can be “2024-10-15” or “Oct 15, 2024”. The font size is 6x10 pixels, so it fits easily in the remaining 16 pixels of height.

One important detail: the OLED driver SSD1322 uses a 4-bit grayscale mode, but the U8g2 library usually treats it as monochrome. You can enable grayscale by setting the pixel mode to 4-bit, but this increases the buffer size to 2048 * 4 = 8192 bytes. This is still manageable on the ESP32, but it’s not necessary for a clock. The grayscale mode allows you to have anti-aliased fonts, which look smoother. However, the font rendering in U8g2 does not support anti-aliasing by default, so you would need to use a custom font or a library like Adafruit_GFX with grayscale support. For most clock applications, monochrome is sufficient.

Another practical aspect is the mounting of the display. The 3.2 inch OLED module has a PCB with a 2.54 mm pin header. You can solder wires directly or use a female header. The SPI pins are: CS (chip select), DC (data/command), SCK (clock), MOSI (data), and optionally RESET. The power pins are VCC (3.3V) and GND. The backlight is not needed because OLEDs are self-emissive. The module typically has a 10-pin connector, but only 6 pins are used for SPI. The other pins are for I2C or parallel interface, which are not used in this project.

If you want to use a different microcontroller, like an STM32F103C8T6 (Blue Pill), you can use the same U8g2 library. The STM32 has 20KB of SRAM, which is enough for the frame buffer. The SPI speed can be up to 18 MHz, so the update time is even faster. The code is similar, but you need to set up the SPI pins in the Arduino IDE or STM32CubeIDE. The DS3231 RTC works with I2C on any microcontroller.

For a more advanced clock, you can add a menu system to set the time, alarm, or brightness. The 256x64 resolution is enough to display a simple menu with 4 lines of text. Each line can be 16 pixels high, so you can have 4 lines of text on the screen. The menu can be navigated using buttons or a rotary encoder. The encoder can be connected to two GPIO pins and a button for selection. The code can use a state machine to handle the menu logic.

Let’s talk about the power consumption in more detail. The OLED display consumes about 20 mA at full brightness. The DS3231 consumes about 200 µA. The ESP32 consumes about 80 mA in active mode, 10 µA in deep sleep, and 0.5 mA in light sleep. If you update the clock every second, the ESP32 can be in deep sleep for 990 ms and active for 10 ms. The average current

Обсудим ваш проект?

Инженер Domostroi приедет на участок, проведёт замеры и подготовит прозрачную смету без скрытых доплат. Один менеджер — один договор — один срок.