sagar saini
Published © GPL3+

Wi-Fi Server Based 6 Channel Tone Controller

PT2258 paired wih ESP8266 to get the maximum from a tone controller, PCB and code with video setup is shared in this tutorial.

IntermediateFull instructions provided2 hours32
Wi-Fi Server Based 6 Channel Tone Controller

Things used in this project

Hardware components

ESP8266 ESP-12E
Espressif ESP8266 ESP-12E
×1

Software apps and online services

Arduino IDE
Arduino IDE
Nextpcb

Story

Read more

Custom parts and enclosures

GERBER

BOM

Schematics

Circuit diagram

Code

PT2258 code

Arduino
// PT2258 6-Channel Audio Controller with Web Interface
// Platform: ESP8266 (e.g., NodeMCU, Wemos D1 Mini)

#include <Wire.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

// ===== WiFi Credentials =====
const char* ssid = "iPhone";
const char* password = "alpha5";

// ===== Global Variables =====
const char ic_address = 0b1000110;  // PT2258 Address (CODE1 = 1, CODE2 = 1)
int mas_vol = 50;
int ch_vol[6] = {50, 50, 50, 50, 50, 50};
bool mute_state = false;
bool master_mode = true;  // true = master, false = individual

ESP8266WebServer server(80);

// ===== I2C Functions =====
void pt2258_send(char d, char e) {
  Wire.beginTransmission(ic_address);
  Wire.write(d);
  Wire.write(e);
  Wire.endTransmission();
}

void set_mute(bool mute) {
  Wire.beginTransmission(ic_address);
  Wire.write(mute ? 0b11111001 : 0b11111000);
  Wire.endTransmission();
}

void set_master_volume(int vol) {    // set vol from 0 to 79, LET vol = 50
  int c = 79 - vol;                  // 79-50 = 29  // c = 29
  int a = c / 10;                    // 29/10 = 2.9 // a = 2  // assign this value to +10dB
  int b = c % 10;                    // 20 % 10 = 9  // b = 9 // assign this value to +1dB
  pt2258_send(0b11010000 + a, 0b11100000 + b); // 11010BBB +a , 1110AAAA +b  // A = 1dB, B = 10dB  // Total increment will be +29dB
}

void set_channel_volume(int ch, int vol) {
  int c = 79 - vol;
  int a = c / 10;
  int b = c % 10;
  switch (ch) {
    case 1: pt2258_send(0b10000000 + a, 0b10010000 + b); break;
    case 2: pt2258_send(0b01000000 + a, 0b01010000 + b); break;
    case 3: pt2258_send(0b00000000 + a, 0b00010000 + b); break;
    case 4: pt2258_send(0b00100000 + a, 0b00110000 + b); break;
    case 5: pt2258_send(0b01100000 + a, 0b01110000 + b); break;
    case 6: pt2258_send(0b10100000 + a, 0b10110000 + b); break;
  }
}

void apply_volume() {
  if (master_mode) {
    set_master_volume(mas_vol);
  } else {
    for (int i = 0; i < 6; i++) {
      set_channel_volume(i + 1, ch_vol[i]);
    }
  }
}

// ===== HTML PAGE =====
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>PT2258 Audio Controller</title>
  <style>
    body { font-family: Arial; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f0f0f0; margin: 0; }
    .container { width: 60%; text-align: center; background: #fff; padding: 40px; box-shadow: 0 0 10px rgba(0,0,0,0.1); border-radius: 10px; }
    h1 { margin-bottom: 20px; }
    h2 { margin-top: 40px; }
    .slider { width: 450px; }
    .slider-group { margin: 25px 0; }
    .label { display: inline-block; width: 80px; text-align: right; margin-right: 10px; font-weight: bold; }
  </style>
</head>
<body>
  <div class="container">
    <h1>PT2258 Audio Controller</h1>
    <button onclick="toggleMode()">Mode: <span id="mode">Master</span></button>
    <button onclick="toggleMute()">Mute: <span id="mute">OFF</span></button>

    <div id="master">
      <h2>Master Volume</h2>
      <div class="slider-group">
        <span class="label" id="masterLabel">63%</span>
        <input type="range" min="0" max="79" value="50" class="slider" id="masterSlider">
      </div>
    </div>

    <div id="channels" style="display:none;">
      <h2>Channel Volumes</h2>
      <div id="sliders"></div>
    </div>
  </div>

<script>
let mode = true;
let mute = false;

function toPercent(val) {
  return Math.round((val / 79) * 100);
}

function toggleMode() {
  mode = !mode;
  document.getElementById('mode').innerText = mode ? 'Master' : 'Channel';
  document.getElementById('master').style.display = mode ? 'block' : 'none';
  document.getElementById('channels').style.display = mode ? 'none' : 'block';
  fetch(`/mode?master=${mode ? 1 : 0}`);
}

function toggleMute() {
  mute = !mute;
  document.getElementById('mute').innerText = mute ? 'ON' : 'OFF';
  fetch(`/mute?state=${mute ? 1 : 0}`);
}

document.getElementById('masterSlider').addEventListener('input', function() {
  document.getElementById('masterLabel').innerText = toPercent(this.value) + "%";
  fetch(`/volume?master=${this.value}`);
});

for (let i = 1; i <= 6; i++) {
  let div = document.createElement('div');
  div.className = 'slider-group';
  div.innerHTML = `
    <span class='label' id='ch${i}Label'>63%</span>
    <input type='range' min='0' max='79' value='50' class='slider' id='ch${i}Slider'>
    <span>CH${i}</span>
  `;
  document.getElementById('sliders').appendChild(div);
  document.getElementById(`ch${i}Slider`).addEventListener('input', function() {
    document.getElementById(`ch${i}Label`).innerText = toPercent(this.value) + "%";
    fetch(`/channel?ch=${i}&vol=${this.value}`);
  });
}
</script>
</body>
</html>
)rawliteral";

// ===== SETUP =====
void setup() {
  Wire.begin();
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  Serial.print("Connecting to WiFi...");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("Connected!");
  Serial.println(WiFi.localIP());

  server.on("/", []() {
    server.send_P(200, "text/html", index_html);
  });

  server.on("/volume", []() {
    if (server.hasArg("master")) {
      mas_vol = server.arg("master").toInt();
      apply_volume();
    }
    server.send(200, "text/plain", "OK");
  });

  server.on("/channel", []() {
    if (server.hasArg("ch") && server.hasArg("vol")) {
      int ch = server.arg("ch").toInt();
      int vol = server.arg("vol").toInt();
      if (ch >= 1 && ch <= 6) {
        ch_vol[ch - 1] = vol;
        apply_volume();
      }
    }
    server.send(200, "text/plain", "OK");
  });

  server.on("/mute", []() {
    if (server.hasArg("state")) {
      mute_state = server.arg("state").toInt();
      set_mute(mute_state);
    }
    server.send(200, "text/plain", "OK");
  });

  server.on("/mode", []() {
    if (server.hasArg("master")) {
      master_mode = server.arg("master").toInt();
      apply_volume();
    }
    server.send(200, "text/plain", "OK");
  });

  server.begin();
  apply_volume();
  set_mute(false);
}

void loop() {
  server.handleClient();
}

Credits

sagar saini
88 projects • 98 followers
I am Sagar Saini an electronic hardware enthusiast

Comments