#include <SPI.h>                           // Include SPI library for communication
#include <Wire.h>                         // Include Wire library for I2C communication
#include <Adafruit_GFX.h>                 // Include Adafruit GFX library for graphics support
#include <Adafruit_SSD1306.h>            // Include Adafruit SSD1306 library for OLED display

#define SCREEN_WIDTH 128                 // Define OLED display width in pixels
#define SCREEN_HEIGHT 64                  // Define OLED display height in pixels

                                          // Declaration for SSD1306 display connected using I2C
#define OLED_RESET -1                     // Reset pin (not used)
#define SCREEN_ADDRESS 0x3C                  // I2C address for the OLED display

                                              // Create display object from Adafruit SSD1306 library
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup()
{
  Serial.begin(9600);                              // Initialize serial communication at 9600 baud rate
  
  // Initialize the OLED display
  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));                     // Print error message if display fails
    for (;;);                                                         // Halt execution if display initialization fails
  }

  // Clear display buffer
  display.clearDisplay();

  // Display simple text
  display.setTextSize(1);                                                   // Set text size to 1
  display.setTextColor(WHITE);                                            // Set text color to white
  display.setCursor(0, 28);                                               // Set text position
  display.println("Hello world!");                                         // Print text to the buffer
  display.display();                                                      // Display the buffer content on the screen
  delay(2000);                                                            // Wait for 2 seconds
  display.clearDisplay();                                                  // Clear the display
  
  // Display inverted text
  display.setTextColor(BLACK, WHITE);                                       // Set text color to black with a white background (inverted)
  display.setCursor(0, 28);                                                // Set text position
  display.println("Hello world!");                                           // Print text to the buffer
  display.display();                                                        // Display the buffer content on the screen
  delay(2000);                                                                // Wait for 2 seconds
  display.clearDisplay();                                                     // Clear the display

  // Changing font size
  display.setTextColor(WHITE);                                                // Set text color to white
  display.setCursor(0, 24);                                                         // Set text position
  display.setTextSize(2);                                                    // Set text size to 2
  display.println("Hello!");                                                  // Print text
  display.display();                                                          // Show on OLED
  delay(2000);                                                               // Wait for 2 seconds
  display.clearDisplay();                                                   // Clear display

  // Display numbers
  display.setTextSize(1);                                                           // Set text size to 1
  display.setCursor(0, 28);                                                    // Set cursor position
  display.println(123456789);                                                   // Print a number
  display.display();                                                           // Show on OLED
  delay(2000);                                                                  // Wait for 2 seconds
  display.clearDisplay();                                                       // Clear display

  // Display numbers with different bases
  display.setCursor(0, 28);                                                    // Set cursor position
  display.print("0x"); display.print(0xFF, HEX);                               // Print 0xFF in HEX format
  display.print("(HEX) = ");
  display.print(0xFF, DEC);                                                    // Print 255 in DEC format
  display.println("(DEC)"); 
  display.display();                                                          // Show on OLED
  delay(2000);                                                                // Wait for 2 seconds
  display.clearDisplay();                                                      // Clear display

  // Display ASCII character
  display.setCursor(0, 24);                                                     // Set cursor position
  display.setTextSize(2);                                                       // Set text size to 2
  display.write(3);                                                             // Print ASCII character with code 3
  display.display();                                                              // Show on OLED
  delay(2000);                                                                    // Wait for 2 seconds
  display.clearDisplay();                                                          // Clear display

  // Full-screen scrolling
  display.setCursor(0, 0);                                                      // Set cursor position
  display.setTextSize(1);                                                        // Set text size to 1
  display.println("Full");                                                        // Print text
  display.println("screen"); 
  display.println("scrolling!");
  display.display(); // Show on OLED

  display.startscrollright(0x00, 0x07);                                     // Start scrolling right
  delay(2000);                                                                // Wait for 2 seconds
  display.stopscroll();                                                           // Stop scrolling
  delay(1000);                                                                     // Wait for 1 second
  
  display.startscrollleft(0x00, 0x07);                                              // Start scrolling left
  delay(2000);                                                                      // Wait for 2 seconds
  display.stopscroll();                                                             // Stop scrolling
  delay(1000);                                                                 // Wait for 1 second    

  display.startscrolldiagright(0x00, 0x07);                                      // Start diagonal scrolling right
  delay(2000);                                                            // Wait for 2 seconds
  display.startscrolldiagleft(0x00, 0x07);                                  // Start diagonal scrolling left
  delay(2000);                                                             // Wait for 2 seconds
  display.stopscroll();                                                      // Stop scrolling
  display.clearDisplay();                                                       // Clear display

  // Scroll part of the screen
  display.setCursor(0, 0);                                                      // Set cursor position
  display.setTextSize(1);                                                          // Set text size to 1
  display.println("Scroll");                                                       // Print text
  display.println("some part");
  display.println("of the screen.");
  display.display(); // Show on OLED

  display.startscrollright(0x00, 0x00);                                       // Start scrolling part of the screen
}

void loop() {
                                                                  // The loop function is empty as everything is handled in the setup()
}
esp:0
esp:2
esp:4
esp:5
esp:12
esp:13
esp:14
esp:15
esp:16
esp:17
esp:18
esp:19
esp:21
esp:22
esp:23
esp:25
esp:26
esp:27
esp:32
esp:33
esp:34
esp:35
esp:3V3
esp:EN
esp:VP
esp:VN
esp:GND.1
esp:D2
esp:D3
esp:CMD
esp:5V
esp:GND.2
esp:TX
esp:RX
esp:GND.3
esp:D1
esp:D0
esp:CLK
oled1:GND
oled1:VCC
oled1:SCL
oled1:SDA