#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <WiFi.h>
#include <HTTPClient.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define SDA_PIN 9
#define SCL_PIN 10
#define POT_PIN 3
#define BUTTON_PIN 1
#define BUZZER_PIN 0
#define MENU_BUTTON_PIN 2
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const char* ssid = "your_SSID"; // Your Wi-Fi SSID
const char* password = "your_PASSWORD"; // Your Wi-Fi Password
const char* HEOS_IP = "192.168.1.100"; // Replace with your HEOS speaker's IP address
int scaledValue = 0;
bool changing = false;
unsigned long lastButtonPressTime = 0;
const unsigned long debounceDelay = 200;
unsigned long lastBlinkTime = 0;
const unsigned long blinkInterval = 320;
bool displayBlinkState = false;
int menuLevel = 0;
void setup() {
Serial.begin(115200);
delay(1000);
Wire.begin(SDA_PIN, SCL_PIN);
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(MENU_BUTTON_PIN, INPUT_PULLUP);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("SSD1306 allocation failed");
for (;;);
}
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(2);
displayLoadingAnimation();
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
}
void loop() {
checkButton();
updateDisplay();
}
void checkButton() {
if (digitalRead(BUTTON_PIN) == LOW) {
if (millis() - lastButtonPressTime > debounceDelay) {
changing = !changing;
Serial.print("State: ");
Serial.println(changing);
lastButtonPressTime = millis();
}
}
if (digitalRead(MENU_BUTTON_PIN) == LOW) {
if (millis() - lastButtonPressTime > debounceDelay) {
menuLevel = (menuLevel + 1) % 2;
changing = false;
Serial.print("State: ");
Serial.println(changing);
Serial.print("Menu Level: ");
Serial.println(menuLevel);
lastButtonPressTime = millis();
}
}
}
void updateDisplay() {
scaledValue = map(analogRead(POT_PIN), 0, 4095, 0, 100);
display.clearDisplay();
if (menuLevel == 0) {
displayVolumeMenu();
} else {
displayTextMenu();
}
display.display();
}
void displayVolumeMenu() {
int digitCount = (scaledValue == 0) ? 1 : (log10(scaledValue) + 1);
if (changing && millis() - lastBlinkTime >= blinkInterval) {
displayBlinkState = !displayBlinkState;
lastBlinkTime = millis();
if (!displayBlinkState) {
makeBuzzerSound(680, 100); // Call with specific note and duration
}
}
if (changing) {
display.setTextSize(1);
display.setCursor(0, 55);
display.print(F("Save Menu"));
} else {
display.setTextSize(1);
display.setCursor(0, 55);
display.print(F("Change Menu"));
}
display.setTextSize(2);
display.setCursor(20, 15);
display.println(F("Volume:"));
int valueWidth = digitCount * 12;
int totalWidth = valueWidth + 12;
int volumeX = (SCREEN_WIDTH - totalWidth) / 2;
display.setCursor(volumeX, 35);
if (changing && displayBlinkState) {
for (int i = 0; i < digitCount; i++) {
display.setTextSize(2);
display.print("_"); // Print underscores for blinking
}
display.print("%");
} else {
display.setTextSize(2);
display.print(scaledValue);
display.print("%");
}
// Update volume on the HEOS speaker
if (!changing) {
changeVolume(scaledValue);
}
}
void displayTextMenu() {
display.setTextSize(1);
display.setCursor(0, 0);
display.println(F("Menu 1:"));
display.println(F("Placeholder text"));
display.setCursor(0, 55);
display.print(F(" Menu"));
}
void makeBuzzerSound(int note, unsigned long duration) {
tone(BUZZER_PIN, note);
delay(duration);
noTone(BUZZER_PIN);
}
void playBuzzerSequence() {
const int notes[] = {180, 300, 400};
for (int i = 0; i < 2; i++) {
for (int note : notes) {
makeBuzzerSound(note, 100);
delay(200);
}
}
}
void displayLoadingAnimation() {
unsigned long startTime = millis();
const char* loadingTexts[] = { "Loading...", "Loading.", "Loading.." };
int loadingState = 0;
while (millis() - startTime < 10500) {
if (millis() % 800 < 100) {
loadingState = (loadingState + 1) % 3;
}
display.clearDisplay();
display.setCursor((SCREEN_WIDTH - strlen(loadingTexts[loadingState]) * 12) / 2, SCREEN_HEIGHT / 2 - 12);
display.println(loadingTexts[loadingState]);
display.display();
delay(100);
}
display.clearDisplay();
display.display();
playBuzzerSequence();
}
void changeVolume(int volume) {
if (volume < 0 || volume > 100) {
Serial.println("Volume must be between 0 and 100.");
return;
}
// Create the HTTP client
HTTPClient http;
String url = String("http://") + HEOS_IP + "/heos/v1/command/set_volume?volume=" + String(volume);
http.begin(url); // Specify the URL
int httpResponseCode = http.GET(); // Send the request
// Check for the response code
if (httpResponseCode > 0) {
String response = http.getString(); // Get the response
Serial.println("Response: " + response);
} else {
Serial.println("Error on HTTP request: " + String(httpResponseCode));
}
http.end(); // Free resources
}