Smart glasses with location address and translation DIY Edith specs

1. Project folder(App, code and circuit diagram)- https://drive.google.com/drive/folders/1DIOnyDH0AMn6cNU-bptEGlkgNnT4GoUG



2. Final project-
Features-
Date and time
Live location address 
Translation to english
Message communication
Audio output on earphones
Rechargeable with all battery protection
Auto reconnect to Bluetooth App 

     









3. Follow circuit diagram-
*Components list-

>ESP32 wroom
>0.96 inch OLED display 
>3.7v lipo or 18650 lithium ion battery 600mah >to 2600mah
>134n3p Charging module with 5v boost
Switch







4. Upload code to ESP32-

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "BluetoothSerial.h"


#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define G_MESSAGE_TIMEOUT 30000 // 30 seconds


Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
BluetoothSerial SerialBT;


String inputString = "";
bool readingMessage = false;
String formattedTimeWithDay = "Waiting time...";
String fullAddress = "Waiting address...";


unsigned long lastGMessageTime = 0;
bool showingAddressInMessageArea = false;


unsigned long lastScrollTime = 0;
const unsigned long scrollInterval = 1500;
int addressScrollIndex = 0;


void setup() {
  Serial.begin(115200);
  SerialBT.begin("ESP32_BT");
  Serial.println("ESP32 Bluetooth Ready. Waiting for data...");


  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    while (true);
  }


  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.println(formattedTimeWithDay);
  display.setCursor(0, 56);
  display.println(fullAddress);
  display.display();


  lastGMessageTime = millis();
}


void loop() {
  while (SerialBT.available()) {
    char inChar = SerialBT.read();


    if (inChar == '#') {
      readingMessage = true;
      inputString = "";
    } else if (inChar == '&') {
      readingMessage = false;
      processMessage(inputString);
    } else if (readingMessage) {
      inputString += inChar;
    }
  }


  unsigned long currentMillis = millis();


  if (currentMillis - lastGMessageTime > G_MESSAGE_TIMEOUT) {
    showingAddressInMessageArea = true;
  }


  if (showingAddressInMessageArea && currentMillis - lastScrollTime > scrollInterval) {
    showAddressScroll();
    lastScrollTime = currentMillis;
  }
}


String getShortDay(String fullDay) {
  fullDay.trim();
  if (fullDay.length() >= 3) {
    return fullDay.substring(0, 3);
  }
  return fullDay;
}


void clearTopRow() {
  display.fillRect(0, 0, SCREEN_WIDTH, 8, SSD1306_BLACK);
}


void clearBottomRow() {
  display.fillRect(0, 56, SCREEN_WIDTH, 8, SSD1306_BLACK);
}


void drawFixedHeaderFooter() {
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.println(formattedTimeWithDay);
  display.setCursor(0, 56);
  display.println(fullAddress);
}


void processMessage(String msg) {
  Serial.println("Full inputString: " + msg);


  if (msg.startsWith("T")) {
    String timeStr = msg.substring(1);
    String month = timeStr.substring(0, 2);
    String day = timeStr.substring(3, 5);
    String year = timeStr.substring(6, 10);
    String timePart = timeStr.substring(11, 19);
    String dayOfWeek = timeStr.substring(22);
    String shortDay = getShortDay(dayOfWeek);


    formattedTimeWithDay = day + "/" + month + "/" + year.substring(2) + " " + timePart + " " + shortDay;


    clearTopRow();
    display.setTextSize(1);
    display.setTextColor(SSD1306_WHITE);
    display.setCursor(0, 0);
    display.println(formattedTimeWithDay);
    display.display();
  }


  else if (msg.startsWith("A")) {
    fullAddress = msg.substring(1);


    clearBottomRow();
    display.setTextSize(1);
    display.setTextColor(SSD1306_WHITE);
    display.setCursor(0, 56);
    display.println(fullAddress);
    display.display();
  }


  else if (msg.startsWith("G")) {
    lastGMessageTime = millis();
    showingAddressInMessageArea = false;
    addressScrollIndex = 0;


    String gTranslateStr = msg.substring(1);


    int lineHeight = 16;
    int maxLines = SCREEN_HEIGHT / lineHeight;
    int usableLines = maxLines - 2;
    int charsPerLine = 10;


    int totalChars = gTranslateStr.length();
    int totalLines = (totalChars + charsPerLine - 1) / charsPerLine;


    for (int i = 0; i < totalLines; i++) {
      display.clearDisplay();


      display.setTextSize(1);
      drawFixedHeaderFooter();


      display.setTextSize(2);
      for (int j = 0; j < usableLines; j++) {
        int lineIndex = i + j;
        if (lineIndex >= totalLines) break;


        int startIdx = lineIndex * charsPerLine;
        int endIdx = startIdx + charsPerLine;
        if (endIdx > totalChars) endIdx = totalChars;


        String line = gTranslateStr.substring(startIdx, endIdx);
        display.setCursor(0, (j + 1) * lineHeight);
        display.println(line);
      }


      display.display();
      delay(3000);
    }
  }
}


void showAddressScroll() {
  display.clearDisplay();


  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.println(formattedTimeWithDay);


  int lineHeight = 16;
  int charsPerLine = 10;
  int usableLines = (SCREEN_HEIGHT / lineHeight) - 2;


  int totalChars = fullAddress.length();
  int totalLines = (totalChars + charsPerLine - 1) / charsPerLine;


  display.setTextSize(2);
  for (int j = 0; j < usableLines; j++) {
    int lineIndex = addressScrollIndex + j;
    if (lineIndex >= totalLines) break;


    int startIdx = lineIndex * charsPerLine;
    int endIdx = startIdx + charsPerLine;
    if (endIdx > totalChars) endIdx = totalChars;


    String line = fullAddress.substring(startIdx, endIdx);
    display.setCursor(0, (j + 1) * lineHeight);
    display.println(line);
  }


  display.setTextSize(1);
  display.setCursor(0, 56);
  display.println(fullAddress);


  display.display();


  int scrollLimit = max(1, totalLines - usableLines + 1);
  if (++addressScrollIndex >= scrollLimit) {
    addressScrollIndex = 0;
  }
}




































6. Explanation and photos-






Here's a detailed line-by-line explanation of your code for the ESP32-based Bluetooth OLED message display system:

---

### **1. Library Inclusions**

```cpp
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "BluetoothSerial.h"
```

* `Wire.h`: I2C communication (used by the OLED).
* `Adafruit_GFX.h` & `Adafruit_SSD1306.h`: For drawing graphics and text on the OLED.
* `BluetoothSerial.h`: Enables Bluetooth SPP communication with ESP32.

---

### **2. Display Configuration**

```cpp
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define G_MESSAGE_TIMEOUT 30000 // 30 seconds
```

Defines display resolution and a timeout for displaying a "G" (translated) message.

---

### **3. Object Initialization**

```cpp
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
BluetoothSerial SerialBT;
```

Initializes OLED display and Bluetooth communication.

---

### **4. Global Variables**

```cpp
String inputString = "";
bool readingMessage = false;
String formattedTimeWithDay = "Waiting time...";
String fullAddress = "Waiting address...";
unsigned long lastGMessageTime = 0;
bool showingAddressInMessageArea = false;
unsigned long lastScrollTime = 0;
const unsigned long scrollInterval = 1500;
int addressScrollIndex = 0;
```

These are used to manage Bluetooth input, message parsing, and OLED display scrolling.

---

### **5. `setup()`**

```cpp
void setup() {
  Serial.begin(115200);
  SerialBT.begin("ESP32_BT");
```

Starts serial monitor and Bluetooth under the name `ESP32_BT`.

```cpp
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    while (true);
  }
```

Initializes OLED; halts if initialization fails.

```cpp
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.println(formattedTimeWithDay);
  display.setCursor(0, 56);
  display.println(fullAddress);
  display.display();
```

Displays default “Waiting…” messages for time and address.

```cpp
  lastGMessageTime = millis();
}
```

Stores the current time to track message timeout later.

---

### **6. `loop()`**

```cpp
while (SerialBT.available()) {
  char inChar = SerialBT.read();
```

Reads Bluetooth data byte-by-byte.

```cpp
  if (inChar == '#') {
    readingMessage = true;
    inputString = "";
  } else if (inChar == '&') {
    readingMessage = false;
    processMessage(inputString);
  } else if (readingMessage) {
    inputString += inChar;
  }
}
```

* `#` starts a new message.
* `&` ends it and sends it for processing.
* Other characters get appended to `inputString`.

```cpp
unsigned long currentMillis = millis();

if (currentMillis - lastGMessageTime > G_MESSAGE_TIMEOUT) {
  showingAddressInMessageArea = true;
}
```

If more than 30s passed since last "G" message, show address again.

```cpp
if (showingAddressInMessageArea && currentMillis - lastScrollTime > scrollInterval) {
  showAddressScroll();
  lastScrollTime = currentMillis;
}
```

Scroll the address on display if it's in scroll mode and scroll interval has passed.

---

### **7. Helper Functions**

#### `getShortDay()`

```cpp
String getShortDay(String fullDay) {
  fullDay.trim();
  return fullDay.length() >= 3 ? fullDay.substring(0, 3) : fullDay;
}
```

Returns a 3-letter abbreviation of the day (e.g., "Sunday" → "Sun").

---

#### `clearTopRow()` and `clearBottomRow()`

```cpp
void clearTopRow() { display.fillRect(0, 0, SCREEN_WIDTH, 8, SSD1306_BLACK); }
void clearBottomRow() { display.fillRect(0, 56, SCREEN_WIDTH, 8, SSD1306_BLACK); }
```

Clears the rows reserved for date/time (top) and address (bottom).

---

#### `drawFixedHeaderFooter()`

```cpp
void drawFixedHeaderFooter() {
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0); display.println(formattedTimeWithDay);
  display.setCursor(0, 56); display.println(fullAddress);
}
```

Redraws the static top and bottom rows.

---

### **8. `processMessage()`**

Handles message types:

#### **Time message (starts with 'T')**

```cpp
String timeStr = msg.substring(1);
// Extract MM/DD/YYYY and time from input
```

Parses and formats the date-time string from the message.

#### **Address message ('A')**

```cpp
fullAddress = msg.substring(1);
// Updates address and redraws bottom row
```

#### **Translated message ('G')**

```cpp
lastGMessageTime = millis();
showingAddressInMessageArea = false;
addressScrollIndex = 0;
```

Prepares for displaying translation message.

```cpp
// Break long message into lines
for (int i = 0; i < totalLines; i++) {
  display.clearDisplay();
  drawFixedHeaderFooter();
  // Show up to usableLines lines per screen
  display.display();
  delay(3000);
}
```

* Splits long text into 10-char lines.
* Displays a few lines at a time (like slides).
* Waits 3s before moving to next group.

---

### **9. `showAddressScroll()`**

```cpp
display.clearDisplay();
display.setCursor(0, 0); display.println(formattedTimeWithDay);
```

Shows the time at the top, then scrolls the address like a marquee.

```cpp
for (...) {
  // Draw part of address
}
```

```cpp
display.setCursor(0, 56); display.println(fullAddress);
```

Shows full address at the bottom for reference.

```cpp
if (++addressScrollIndex >= scrollLimit) {
  addressScrollIndex = 0;
}
```

Keeps scrolling from start after reaching the end.

---

Would you like a blog post draft based on this full explanation next?




DIY Smart Glasses Project with ESP32 and OLED Display: Circuit, Setup, and Application
Smart wearable devices are revolutionizing the way we interact with technology. In this blog post, we dive into a DIY Smart Glasses Project built using an ESP32 microcontroller, an OLED display, and a custom-designed circuit. These smart glasses are capable of displaying real-time information such as date, time, and translated messages sent from a smartphone via Bluetooth. Let’s explore the components, the working principle, and the full setup.

Overview of the Smart Glasses
This DIY project involves integrating a lightweight display system onto eyewear, controlled by the powerful ESP32 microcontroller. The OLED screen acts as the main interface to show:

Live date and time

Short text messages sent from a mobile app (e.g., translation results or alerts)

The communication between the smart glasses and the Android app is handled via Bluetooth Serial communication.

Components Used
ESP32 Development Board: The brain of the system with built-in Bluetooth and Wi-Fi support.

0.96" OLED Display (I2C): Displays the date, time, and received messages.

Rechargeable Battery or USB Power Bank: For portable power supply.

Push Buttons (optional): To switch display modes or refresh time.

Wires, resistors, and a custom PCB or perfboard to connect everything securely.

Circuit Diagram
Explanation:

The OLED display is connected to the ESP32 via the I2C interface (SDA and SCL pins).

Power is supplied to both the ESP32 and OLED via a 3.3V/5V regulated source.

Optional push buttons may be connected to digital GPIO pins to toggle modes.

The Bluetooth Serial is used to receive messages from the mobile app and display them on the screen.

Assembly and Mounting


The OLED is mounted in front of the glasses using a 3D-printed holder or a lightweight bracket. The ESP32 board and battery are mounted on the side arm of the glasses using tape or clips. Wiring is minimized and neatly arranged to maintain comfort and appearance.

Working Principle
Startup: On boot, the ESP32 initializes the OLED and Bluetooth.

Display Time/Date: It begins by showing the current date and time, which may be programmed or synced.

Receive Messages: When a message is sent from the mobile app over Bluetooth, the ESP32 receives it using SoftwareSerial and displays it on the OLED.

Mode Switching: If buttons are added, users can switch between display modes (Time/Message) manually.

Applications and Future Scope
Language translation display for travelers.

Notification alerts from mobile apps (e.g., WhatsApp, SMS).

Real-time weather or navigation cues.

Accessibility support for hearing-impaired users.

In the future, you could integrate:

A microphone for voice commands.

A camera module for visual input.

Wi-Fi connectivity for web-based notifications.

Conclusion
This Smart Glasses DIY project is an innovative example of wearable tech powered by open-source hardware. With simple components like an ESP32 and an OLED screen, you can create a powerful, portable device that enhances human-computer interaction.

Whether you're building it for fun, for a tech demo, or as part of a larger product prototype, this project is a great step into the world of IoT and wearable devices.



Comments