We need to connect below three I2C devices to an Arduino UNO (master).
The I2C communication frequency is set to 100 kHz, as all slave devices support this rate.
Voltage Level Compatibility
Let's go through the hardware connections step by step:
Note: When connecting multiple devices, ensure that the total current draw does not exceed the controller's maximum sourcing or sinking capability to avoid overloading.
Adafruit's SSD1306 library
(available on GitHub) for the OLED, Adafruit_BMP085.h
for the BMP180 sensor module, and RTClib.h b
y Adafruit for the RTC DS1307.Note: Adafruit_BMP085.h can be used for both the BMP085 and BMP180 Barometric Pressure sensor breakout boards.
#include <Wire.h>
#include <RTClib.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_BMP085.h>
#define oled_address 0x3C // Define the I2C address of the OLED display
// Create an object to interface with the RTC module
RTC_DS1307 rtc;
// Create an object to interface with the BMP180 sensor
Adafruit_BMP085 bmp;
// Create an object for OLED display (128x64 size)
#define SCREEN_WIDTH 128 // Width of the display in pixels
#define SCREEN_HEIGHT 64 // Height of the display in pixels
#define OLED_RESET -1 // Define the reset pin for the OLED (not used in this case)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // Initialize OLED display object
void setup() {
Serial.begin(115200);
// Initialize BMP180 sensor
Serial.print("BMP180 sensor initializing...");
// Wait until BMP180 sensor is initialized
while (!bmp.begin()) {
Serial.print(" .");
delay(100);
}
Serial.println(" ");
Serial.println("BMP180 sensor initialization complete.");
// Check RTC DS1307 is successfully connected or not
Serial.print("RTC Device scanning...");
// Wait until RTC DS1307 is not found
while (!rtc.begin()) {
Serial.print(" .");
delay(100);
}
Serial.println(" ");
Serial.println("RTC device found");
// Check if the OLED display is connected
Serial.print("OLED display scanning...");
Wire.beginTransmission(oled_address); // Start I2C communication with OLED
while (Wire.endTransmission()) { // Check if the OLED responds
Serial.print(".");
delay(100);
}
Serial.println(" ");
Serial.println("OLED display found");
// Initialize OLED display
Serial.print("OLED display initializing.....");
// Initialize OLED display
while (!display.begin(SSD1306_SWITCHCAPVCC, oled_address)) {
Serial.print(" .");
delay(100);
}
Serial.println(" ");
Serial.println("OLED display initialization complete.");
delay(2000); // Pause for 2 seconds after the initial setup
// Clear the display and set up text parameters
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE); // Set text color to white
// Uncomment the line below to set time on RTC initially (if needed)
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); //Initialize the RTC with the compile-time date and time
}
void loop() {
// Get the current time and date from RTC
DateTime now = rtc.now();
// Clear the display and start updating it
display.clearDisplay();
display.setCursor(0, 0); //Set the cursor to the top-left corner (column 0, row 0) of the OLED display
// display date top-left corner (Date/Month/Year)
display.print(now.day(), DEC);
display.print("/");
display.print(now.month(), DEC);
display.print("/");
display.print(now.year(), DEC);
display.setCursor(71, 0); //Set the cursor to the top-left corner (column 71, row 0) of the OLED display
// Display the current time(dec value) on top-right corner (hours:minutes:seconds)
display.print(now.hour(), DEC);
display.print(':');
if (now.minute() < 10) { // Add leading zero for minutes less than 10
display.print('0');
}
display.print(now.minute(), DEC);
display.print(':');
if (now.second() < 10) { // Add leading zero for seconds less than 10
display.print('0');
}
display.print(now.second(), DEC);
// Display atmospheric pressure value from BMP180 sensor (Unit = "Pa")
display.setCursor(0, 16); // Set the cursor to the (column 0, row 16) of the OLED display
display.print("Pressure = ");
display.print(bmp.readPressure()); // Read and display pressure in Pascals
display.print(" Pa");
// Display temperature value from BMP180 sensor(degree celcius(°C))
display.setCursor(0, 32); // Set the cursor to the (column 0, row 32) of the OLED display
display.print("Temp = ");
display.print(bmp.readTemperature());
display.print(" ");
display.write(248);
display.print("C");
// Calculate altitude(meter) assuming 'standard' barometric
// pressure of 1013.25 millibar = 101325 Pascal
display.setCursor(0, 48); // Set the cursor to the (column 0, row 48) of the OLED display
display.print("Altitude = ");
display.print(bmp.readAltitude());
display.print(" m");
display.display(); // Update the OLED display with the new content
// Wait for 1 second before updating again
delay(1000);
}
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
__DATE__
and __TIME__
are predefined macros in Arduino that represent the compile date and time of the code.rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
sets the RTC to the time and date of the sketch compilation.rtc.adjust(DateTime(2025, 1, 16, 12, 0, 0));
// to set the RTC to a specific date and time.DateTime now = rtc.now();
now
object stores the current time and date (hour, minute, second, day, month, and year). bmp.readPressure();
bmp.readAltitude();
bmp.readTemperature();
display.display();