/**************************************************************************
This is an example for our Monochrome OLEDs based on SSD1306 drivers
Pick one up today in the adafruit shop!
------> http://www.adafruit.com/category/63_98
This example is for a 128x64 pixel display using I2C to communicate
3 pins are required to interface (two I2C and one reset).
Adafruit invests time and resources providing this open
source code, please support Adafruit and open-source
hardware by purchasing products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries,
with contributions from the open source community.
BSD license, check license.txt for more information
All text above, and the splash screen below must be
included in any redistribution.
**************************************************************************/
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library.
// On an arduino UNO: A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO: 2(SDA), 3(SCL), ...
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define NUMFLAKES 10 // Number of snowflakes in the animation example
#define LOGO_HEIGHT 16
#define LOGO_WIDTH 16
static const unsigned char PROGMEM logo_bmp[] =
{ 0b00000000, 0b11000000,
0b00000001, 0b11000000,
0b00000001, 0b11000000,
0b00000011, 0b11100000,
0b11110011, 0b11100000,
0b11111110, 0b11111000,
0b01111110, 0b11111111,
0b00110011, 0b10011111,
0b00011111, 0b11111100,
0b00001101, 0b01110000,
0b00011011, 0b10100000,
0b00111111, 0b11100000,
0b00111111, 0b11110000,
0b01111100, 0b11110000,
0b01110000, 0b01110000,
0b00000000, 0b00110000 };
void setup() {
Serial.begin(9600);
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
// Show initial display buffer contents on the screen --
// the library initializes this with an Adafruit splash screen.
display.display();
delay(2000); // Pause for 2 seconds
// Clear the buffer
display.clearDisplay();
// display.display() is NOT necessary after every single drawing command,
// unless that's what you want...rather, you can batch up a bunch of
// drawing operations and then update the screen all at once by calling
// display.display(). These examples demonstrate both approaches...
displayPhrase();
delay(3000);
display.setTextSize(1);
display.clearDisplay();
heartAnimation();
}
void loop() {
}
void displayPhrase(void){
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.cp437(true); // Use full 256 char 'Code Page 437' font
String messages[] = {"Hello", "World"};
for(int i = 0; i < 2; i++){
display.println(messages[i]);
display.display(); // Update the display with the new text
delay(2000);
}
// display.display();
delay(2000);
}
// Function to draw a heart shape and animate it
void heartAnimation() {
int heartSize = 20; // Fixed size of the heart
int heartX = SCREEN_WIDTH / 2; // Initial X position of the heart
int heartY = SCREEN_HEIGHT / 2; // Initial Y position of the heart
// Speed and movement range for bouncing effect
int deltaX = 1; // Horizontal speed (left and right)
int deltaY = 1; // Vertical speed (up and down)
// Animation loop: The heart will bounce around the screen
while (true) {
// Move the heart based on deltaX and deltaY
heartX += deltaX;
heartY += deltaY;
// Check for collisions with screen edges and reverse direction when needed
if (heartX - heartSize / 2 <= 0 || heartX + heartSize / 2 >= SCREEN_WIDTH) {
deltaX = -deltaX; // Reverse direction on X-axis if it hits left or right edge
}
if (heartY - heartSize / 2 <= 0 || heartY + heartSize / 2 >= SCREEN_HEIGHT) {
deltaY = -deltaY; // Reverse direction on Y-axis if it hits top or bottom edge
}
display.clearDisplay(); // Clear the screen before each frame
drawHeart(heartX, heartY, heartSize); // Draw the heart at the new position
display.display(); // Update the display
delay(10); // Delay for animation smoothness (adjust for speed)
}
}
// Function to draw a more refined heart shape at a specified location and size
void drawHeart(int x, int y, int size) {
int offset = size / 2;
// Draw the top-left and top-right lobes of the heart
display.fillCircle(x - offset, y - offset, size / 2, SSD1306_WHITE); // Left lobe
display.fillCircle(x + offset, y - offset, size / 2, SSD1306_WHITE); // Right lobe
// Draw the bottom triangle part of the heart (more rounded)
display.fillTriangle(x - size / 2, y, x + size / 2, y, x, y + size, SSD1306_WHITE);
// Optional: Refine the lower part of the heart for a smoother transition
display.fillRect(x - offset, y, size / 2, size / 2, SSD1306_WHITE); // Create bottom transition to smooth curve
// Optional: You can play around with adding additional curves to the heart bottom
}