Connect with us

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

Discussion in 'Microcontrollers, Programming and IoT' started by Robert Hill, Oct 21, 2017.

Scroll to continue with content
  1. Robert Hill

    Robert Hill

    112
    12
    Mar 5, 2015
    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: Oct 21, 2017
  2. kellys_eye

    kellys_eye

    4,275
    1,146
    Jun 25, 2010
    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.
     
  3. Robert Hill

    Robert Hill

    112
    12
    Mar 5, 2015
    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: Oct 10, 2020
  4. Robert Hill

    Robert Hill

    112
    12
    Mar 5, 2015
    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.
     
  5. Robert Hill

    Robert Hill

    112
    12
    Mar 5, 2015
    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!
     
  6. Anandhan J

    Anandhan J

    3
    0
    Oct 8, 2020
    Could you please upload the code
     
  7. Robert Hill

    Robert Hill

    112
    12
    Mar 5, 2015
    [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: Oct 9, 2020
  8. Anandhan J

    Anandhan J

    3
    0
    Oct 8, 2020
    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: Oct 10, 2020
  9. Anandhan J

    Anandhan J

    3
    0
    Oct 8, 2020
    Hello
     
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day

-