Maker Pro
Maker Pro

Using arduino and I2C to control an AX2358 6 channel volume control chip

Hi there,

I recently got a second hand 5.1 surround sound system (Paid £20). Unfortunately I didn't realise at the time that it should have come with a remote control. Even more unfortunately this remote control was basically necessary to control the system in any meaningful way e.g changing from 2.1 to 5.1 output! It doesn't appear possible either to get a replacement remote or to get a universal remote and program it to control the speakers (they are a cheap obscure brand called sumvision).

However, being determined to get them working in 5.1 I took the back off to look at the chips etc inside.

It appears to me that the key chips inside are an AX2358 6 channel volume control/input selector chip (Data sheet only in Chinese as far as I can tell so had to translate with google translate! http://www.datasheetcafe.com/ax2358f-datasheet-ax-sop-28/ ) and an Amtel 128 chip with 8 pins which i'm assuming the manufacturer programmed with their own code to run the volume/input chip in response to the physical volume controls on the front of the subwoofer and also the received commands from the remote control.

Looking at the data sheet for the AX2358 it is controlled through I2c which I think means i could use and arduino to send it commands instead of the already present Amtel 128 chip. I hoping I can solder two wires onto the SDA and SCL pins of the AX2358 and plug them into an arduino and just send I2c data to the AX2358 to control it.

I have a few questions therefore which I'm hoping some might be able to help me with.

1. Have I got the right end of the stick, at least in theory or have I got it all wrong
2. Would just adding my own control chip in the form of an arduino work or would it not play well with the existing Amtel chip. For example I know that the I2c protocol has the slave device send a confirmation bit to show it has received the instruction. Would the existing AMtel chip also get this and somehow get confused and mess up the communication between the arudino and the AX2358?
3. IF this does all sound possible, Where would be best to attach my arduino? on the SCL and SDA pins of the existing Amtel 128 chip or somewhere else? (Maybe hard to answer without a schematic?) Should the arduino be powered by the same power supply as the rest of the existing circuitry or can it be externally powered?

As you'll probably have guessed, I'm boldly going and pushing myself into an area of electronics i've not really been before so any help will be much appreciated even if it is just 'yes your going in the right direction, go and give it a go and see what happens'.

'EDIT': The other option I guess might be to (if possible) try and extract the coding from the Amtel 128 and work out what commands it is expecting to receive via the remote control (that I don't have) and then create my own remote that would send out these commands - possible??

Thanks in advance!

Bob
 
Last edited:
You seem to be on the right track.

Extracting the code only depends on whether or not they implemented any code protection on the device - it may even be a OTP device (mask programmed) and potentially unreadable.... only you will know!

Does the AX2385 datasheet reveal the full code set for control? Can you get them if it doesn't?

Seems like an awful lot of time and trouble to me. I'd be looking to find a direct audio input point and inject the input there (via pre-amps or whatever is required). There may even be some cheap'n'cheerful remote control audio system you can hack to put the audio signal where you want and use the remote control 'it' comes with.
 
Hi thanks for getting back to me.

Yes I can get what seems to be a full list of codes from the AX2385 datasheet for example the address, the code to send to mute different speakers, the volume controls etc.

I've hooked up my arduino to the SDA and SCL lines of the AX chip and using the wire library in arduino I have the following code:
Code:
#include <Wire.h>

void setup() {
  Wire.begin(); // join i2c bus (address optional for master)
}

void loop() {
  delay(3000);
  
  Wire.beginTransmission(94); // transmit to device #94 (AX2358 chip)
  Wire.write(11000100);// This is a 'reset/clear' byte which the data sheet seems to suggest I need to send first when the speakers are turned on
  Wire.endTransmission();    // stop transmitting
  delay(500);


   Wire.beginTransmission(94); // transmit to device #94
  Wire.write(11001111);// This should be the code to switch to 5.1 from the 2.1 input.
  Wire.endTransmission();    // stop transmitting
  delay(500);
}

However this doesn't appear to be doing anything at all. I've got an old oscilloscope which I also hooked up to the scl and sda lines and it seems like change was happening on them with a pause of three seconds each time (see 3000ms delay in my code). So i seems like the arduino is indeed transmitting but the chip doesn't seem to be responding.

Is there a way to get the arduino serial monitor to tell me if the AX2358 chip is sending out acknowledgements of receiving my data from the arduino?

Thanks for your help so far.
 
Last edited by a moderator:
Aha, i'm making progress.

I found this Git hub page: https://github.com/myopensourceprojects/ax2358f For future reference if anyone else ever tries to do a mad thing like this as well.

I think I may have got the address of the AX chip incorrect because of the 7 bit plus read/write bit thing.

I've now managed to set it to use the 5.1 rather than stereo input. Now to try and get it to use all 6 speakers to output.
 
Final update. Got the speakers working and controllable from the arduino. When I get a chance I can put in volume control etc etc. Hooray!
 
[mod edit: put the code into a code box for better readability in the forum]
Code:
#include <Wire.h>
#include <IRremote.h>

//List of remote control hex codes by button
//Encodning RC5
//Power 1 84c
//Power 2 4c
//Source 878
//Mute 1 84c Mute all
//Mute 2 4c Unmute all
//Menu 1 870 6 Channel
//Menu 2 70 2.1 channel
//Return 1 4a Surround on
//Return 2 84a Surround off
//EPG 1 86f 6 channel mix on
//EPG 2 6f 6 channel mix off
// Vol + 850 Volume reset
// Vol - 51 Volume down

//IR reciever code
int RECV_PIN = 11; //data out of IR receiver connects to pin 11
IRrecv irrecv(RECV_PIN);
decode_results results;
//IR reciever code

void setup() {
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600); //Start serial monitor
while (! Serial); // Wait untilSerial is ready - Leonardo

//IR reciever code
irrecv.enableIRIn();
//IR reciever code

for (int x = 0; x < 1; x++){
Serial.println("Enter command or press remote to control speakers"); // Invites input to control speakers
}
}

void loop() {


// I2C control codes
int inputs [2] = {0xcf, 0xcb}; // Creates array this includes input selection codes: 6ch, st1
int outputs [4] = {0xd0, 0xd1, 0x90, 0x91}; // Creates array for output options: Surround on, surround off, 6 chan mix 0db, 6 chan mix 6db
int mutes [7] = {0xf1, 0xf3, 0xf9, 0xfb, 0xf5, 0xf7, 0xff}; // Creates array for muting speakers: FL, FR, RL, RR, CEN, SW, All
int unmutes [8] = {0xf0, 0xf2, 0xf8, 0xfa, 0xf4, 0xf6, 0xfe, 0xc4}; //Creates array for unmuting speakers: FL, FR, RL, RR, CEN, SW, All, CLEAR ALL VOLUME CHANGES
int vol10 [7] = {0x81, 0x41, 0x1, 0x21, 0x61, 0xa1, 0xd1}; // Creates array for 10db stage volume control: FL, FR, Rl, RR, CEN, SW, ALL
int vol1 [7] = {0x91, 0x51, 0x11, 0x31, 0x71, 0xb1, 0xe1}; // Creates array for 1db stage volume control: FL, FR, Rl, RR, CEN, SW, ALL


// If statement commands

//Basic command
char bas = 'bas'; //Defines the standard setup to run (6 channel input and surround active)

//Input choices
char in6 = 'in6'; // Defines the command which will be used to activate 6ch input
char st1 = 'st1'; // Defines the command which will be used to activate 2ch input

//Output choices
char su1 = 'su1'; //Defines the command which will be used to activate surround sound
char su0 = 'su0'; //Defines the command which will be used to turn off surround sound
char mi0 = 'mi0'; //Defines the command which will be used to activate 6 channel mixing a 0db
char mi6 = 'mi6'; //Defines the command which will be used to activate 6 channel mixing at -6db



int command = 0; // Creates a holder for incoming serial data

if (Serial.available() > 0) { // Tells arduino to look out for serial data
command = Serial.read(); // Stores serial data in the command holder
Serial.println (command); // Reports what it has recieved
}

//IR remote commands
 if (irrecv.decode(&results)) {


if (results.value==0x870){ //menu1 button on remote to activate 6 Channel
int x = inputs[0]; // Sets the x variable to the correct hex code which matches the desired command
sendcode (x); // Uses the sendcode function to send the selected hex code
Serial.println ("5.1  input active"); // Reports that the command has been recognised and carried out
}

if (results.value==0x70){ //menu2 button on remote to activate 2 Channel
int x = inputs[1];
sendcode (x);
Serial.println ("2.1 input active");}

if (results.value==0x4a){ //Return 1 button on remote to activate surround
int x = outputs[0];
sendcode (x);
Serial.println ("Surround on");}

if (results.value==0x84a){ //Return 2 button on remote to deactivate surround
int x = outputs[1];
sendcode (x);
Serial.println ("Surround off");}

if (results.value==0x86f){ //EPG 1 button on remote to turn on 6 channel 0DB
int x = outputs[2];
sendcode (x);
Serial.println ("6 Channel 0DB");}

if (results.value==0x6f){ //EPG 2 button on remote to turn on 6 channel 6DB
int x = outputs[3];
sendcode (x);
Serial.println ("6 Channel 6DB");}

if (results.value==0x84c){ //Mute 1 button on remote to mute all
int x = mutes[6];
sendcode (x);
Serial.println ("Mute all");}

if (results.value==0x4c){ //Mute 2 button on remote to unmute all
int x = unmutes[6];
sendcode (x);
Serial.println ("Unmute all");}

if (results.value==0x51){ //Volume down button
int x = vol10 [6];
int y = vol1 [6];
sendvolcode (x,y);
Serial.println ("Volume down");}

if (results.value==0x850){ //Volume up button
int x = unmutes [7];
sendcode (x);
Serial.println ("Volume reset");}


irrecv.resume();
}




//Basic command
if (command == bas){
  int x = inputs [0];
  int y = outputs [0];
  sendcode (x);
  sendcode (y);
  Serial.println ("Basic set up");
}


// Input commands
if (command == in6){ // Checks the recieved command to see if it matches the 6 channel command
int x = inputs[0]; // Sets the x variable to the correct hex code which matches the desired command
sendcode (x); // Uses the sendcode function to send the selected hex code
Serial.println ("5.1  input active"); // Reports that the command has been recognised and carried out
}

if (command == st1){
int x = inputs[1];
sendcode (x);
Serial.println ("2.1 input active");
}

//Output commands
if (command == su1){ //
int x = outputs[0];
sendcode (x);
Serial.println ("surround active");
}

if (command == su0){
int x = outputs[1];
sendcode (x);
Serial.println ("surround off");
}

if (command == mi0){
int x = outputs[2];
sendcode (x);
Serial.println ("6 channel mix 0db");
}

if (command == su1){
int x = outputs[3];
sendcode (x);
Serial.println ("6 channel mix =6db");
}
}


  void sendcode (int x){ //Creates function to transmit given code to speakers
Wire.beginTransmission(0x4a); // transmit to AX2358 chip
Wire.write (x);
Wire.endTransmission();    // stop transmitting
}

void sendvolcode (int x, int y){ //Creates function to transmit given code to speakers
Wire.beginTransmission(0x4a); // transmit to AX2358 chip
Wire.write (x);
Wire.write (y);
Wire.endTransmission();    // stop transmitting
}
 
Last edited by a moderator:
I have a 5.1 john barrel home theater.The problem is, main display board is burn out.with out the board its not working.In the 5.1 chennal board they using the ax2358f ic.The connections from the main display board to 5.1 channel borad are SCL,SDA,ADC,5V+,GND

I have a Arduino nano.Is this code really help me
 
Last edited by a moderator:
Top