# Reading data from sensor through multiplexer

**URL:** <https://forum.arduino.cc/t/reading-data-from-sensor-through-multiplexer/1038153>\
**Category:** Programming\
**Created:** [October 4, 2022, 2:08am UTC](https://forum.arduino.cc/t/reading-data-from-sensor-through-multiplexer/1038153 "2022-10-04T02:08:42Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![MrDoggss](https://avatars.discourse-cdn.com/v4/letter/m/7ea924/32.png) [@MrDoggss](https://forum.arduino.cc/u/MrDoggss)\
**Post date:** [October 4, 2022, 2:08am UTC](https://forum.arduino.cc/t/reading-data-from-sensor-through-multiplexer/1038153/1 "2022-10-04T02:08:42Z")

</div>

I set this up to test my basic code, but I'm not sure if I have a coding problem, or a hardware issue. When I run this on my Mega2560, the display scrolls showing "angle 1" and "angle 2" but the reading are identical, and never change. I'm unsure if my readings are identical because the code is reading the same sensor (TCA9548A reading channel 1 for both, instead of 1 and 2) or if the code is correct, is my wiring faulty (very possible).  
Wanting to askw if my code looks right.

```cpp
#include <Wire.h>
#include <AS5600.h>

#define TCAADDR 0x70

int Actang1;
int Actang2;
int Actang3;
int Actang4;
int Actang5;
int Actang6;
int a1;
int a2;
AS5600 as5600;

void TCA9548A(uint8_t bus)
{
  Wire.beginTransmission(0x70);
  Wire.write(1 <<bus);
  Wire.endTransmission();
}
void setup() {
  Serial.begin(9600);
  //Wire.begin(TCAADDR);
  
}

void loop() {
    
  
  TCA9548A(1);
  float a1 = as5600.readAngle();
  Serial.print("Angle 1,");
  Serial.println(a1);

    TCA9548A(2);
  float a2 = as5600.readAngle();
  Serial.print("Angle 2,");
  Serial.println(a2);
delay(300);

}

```

---

<div class="post-metadata">

**Author:** ![alto777](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/alto777/32/317385_2.png) [@alto777](https://forum.arduino.cc/u/alto777)\
**Post date:** [October 4, 2022, 2:22am UTC](https://forum.arduino.cc/t/reading-data-from-sensor-through-multiplexer/1038153/2 "2022-10-04T02:22:34Z")

</div>

Can you run an example sketch you did not write or tinker with?

Adafruit have a scanner sketch, you shoukd be able to get that running.

Can you expand a little on that to basically write the same program only in different style?

If you can't get a scanner or scanner-lite type sketch going you are wise to pause here and consider the wiring &c.

HTH

a7

---

<div class="post-metadata">

**Author:** ![MrDoggss](https://avatars.discourse-cdn.com/v4/letter/m/7ea924/32.png) [@MrDoggss](https://forum.arduino.cc/u/MrDoggss)\
**Post date:** [October 4, 2022, 4:23am UTC](https://forum.arduino.cc/t/reading-data-from-sensor-through-multiplexer/1038153/3 "2022-10-04T04:23:22Z")

</div>

I can run an example sketch that I found on Github. However, it is only a simple read the sensor, and does not include anything about the multiplexer. All the multiplexer examples I can find are all output to things like 2 LCD screens. I ran the scan code from Adafruit and it shows the 2 sensors on ports 1 and 2. I guess that means my wiring is ok. So I'm left with my multiplexer code being faulty, which doesn't surprise me. lol Any ideas on what I should look at? The readings are always 3839.00

```cpp
//
// FILE: AS5600_demo.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo
// DATE: 2022-05-28

#include "AS5600.h"
#include "Wire.h"

AS5600 as5600; // use default Wire

void setup()
{
  Serial.begin(115200);
  Serial.println( __FILE__ );
  Serial.print("AS5600_LIB_VERSION: ");
  Serial.println(AS5600_LIB_VERSION);

  Wire.begin();

  as5600.begin(4); // set direction pin.
  as5600.setDirection(AS5600_CLOCK_WISE); // default, just be explicit.
}

void loop()
{
  Serial.print(millis());
  Serial.print("\t");
  Serial.print(as5600.readAngle());
  Serial.print("\t");
  Serial.println(as5600.rawAngle() * AS5600_RAW_TO_DEGREES);

  delay(1000);
}

// -- END OF FILE --

```

---

<div class="post-metadata">

**Author:** ![gilshultz](https://avatars.discourse-cdn.com/v4/letter/g/67e7ee/32.png) [@gilshultz](https://forum.arduino.cc/u/gilshultz)\
**Post date:** [October 4, 2022, 5:11am UTC](https://forum.arduino.cc/t/reading-data-from-sensor-through-multiplexer/1038153/4 "2022-10-04T05:11:56Z")

</div>

There are thousands of multiplexers which one are you using. Also post a schematic so we can determine how the system is configured and what else is there. Posting links to "Technical" information on the hardware would be a big help.

---

<div class="post-metadata">

**Author:** ![MrDoggss](https://avatars.discourse-cdn.com/v4/letter/m/7ea924/32.png) [@MrDoggss](https://forum.arduino.cc/u/MrDoggss)\
**Post date:** [October 4, 2022, 5:48am UTC](https://forum.arduino.cc/t/reading-data-from-sensor-through-multiplexer/1038153/5 "2022-10-04T05:48:23Z")

</div>

Ok, here is the current wiring, and components. All grounds are connected. The TCA9548A Multiplexer is a Chinese brand bought from Amazon. Here is a link to the best info I can find on the AS5600 sensor. [AS5600 Sensor Data](https://community.element14.com/challenges-projects/project14/sensors/b/blog/posts/hall-sensor-as5600-for-game-wheel)

 ![base wiring](https://europe1.discourse-cdn.com/arduino/original/4X/a/e/4/ae4ab79a132b23eadf3cd3b8a314cb3d17e0b6b6.jpeg)

---

<div class="post-metadata">

**Author:** ![alto777](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/alto777/32/317385_2.png) [@alto777](https://forum.arduino.cc/u/alto777)\
**Post date:** [October 4, 2022, 12:27pm UTC](https://forum.arduino.cc/t/reading-data-from-sensor-through-multiplexer/1038153/6 "2022-10-04T12:27:34Z")

</div>

> [@MrDoggss](#):
>
> However, it is only a simple read the sensor, and does not include anything about the multiplexer

There's an example on the product pages for the multiplexer over at [Adafruit.com](http://Adafruit.com):

> **[Adafruit TCA9548A 1-to-8 I2C Multiplexer Breakout](https://learn.adafruit.com/adafruit-tca9548a-1-to-8-i2c-multiplexer-breakout)**
>
> You just found the perfect I2C sensor, and you want to wire up two or three or more of them to your Arduino when you realize "Uh oh, this chip has a fixed I2C address, and from what I know about I2C, you cannot have two devices with the same address...

One of the test sketches implements an I2C multiplexer bus scan.

a7

---

<div class="post-metadata">

**Author:** ![Grumpy\_Mike](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/grumpy_mike/32/213521_2.png) [@Grumpy\_Mike](https://forum.arduino.cc/u/Grumpy_Mike)\
**Post date:** [October 4, 2022, 1:06pm UTC](https://forum.arduino.cc/t/reading-data-from-sensor-through-multiplexer/1038153/7 "2022-10-04T13:06:15Z")

</div>

> [@MrDoggss](#):
>
> and does not include anything about the multiplexer.

So how would you expect a multiplexer to work?  
A multiplexer needs pins to be wired up that select what channel your multiplexer is transferring to its output.

So those wires must be included in your circuit along with code to change those pins to the required values to select what you want to read.

---

<div class="post-metadata">

**Author:** ![TomGeorge](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/tomgeorge/32/215261_2.png) [@TomGeorge](https://forum.arduino.cc/u/TomGeorge)\
**Post date:** [October 4, 2022, 1:46pm UTC](https://forum.arduino.cc/t/reading-data-from-sensor-through-multiplexer/1038153/8 "2022-10-04T13:46:24Z")

</div>

Hi,  
I had at one stage 2 I2C devices with the same address and multiplexed them.  
The trick is to do the initialization, in your case with two sensors, TWICE.  
Each time with one of the sensors selected in the multiplexer.

I basically ran the setup of the I2C components twice and switch I2C comms for each device.  
Then you can command a read from either with the appropriate sensor selected.

So I believe you need to say;

```cpp
as5600.begin(4);
as5600.setDirection(AS5600_CLOCK_WISE);

```

Once with the first sensor selected, then again with the second selected.  
This is to wakeup the sensors for comms.

I am not familiar with those modules, so you may have to play a bit with waiting periods between select and command.

It was a long time ago, but I think that was the proceedure.

Tom... 😃 😃 👍 ☕ 🇦🇺

---

<div class="post-metadata">

**Author:** ![alto777](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/alto777/32/317385_2.png) [@alto777](https://forum.arduino.cc/u/alto777)\
**Post date:** [October 4, 2022, 2:02pm UTC](https://forum.arduino.cc/t/reading-data-from-sensor-through-multiplexer/1038153/9 "2022-10-04T14:02:22Z")

</div>

> [@TomGeorge](#):
>
> The trick is to do the initialization, in your case with two sensors, TWICE.

Once each.

Now conspicuously absent (!) from @MrDoggss' first sketch are those two lines we see in the simpler example

```arduino
  as5600.begin(4); // set direction pin.
  as5600.setDirection(AS5600_CLOCK_WISE); // default, just be explicit.

```

which need to be done for each sensor. However that is done through the I2C multiplexer. I take @TomGeorge's experience for that - _select_, _begin_ and _setDirection_ for every I2C device.

a7

---

<div class="post-metadata">

**Author:** ![MrDoggss](https://avatars.discourse-cdn.com/v4/letter/m/7ea924/32.png) [@MrDoggss](https://forum.arduino.cc/u/MrDoggss)\
**Post date:** [October 4, 2022, 4:43pm UTC](https://forum.arduino.cc/t/reading-data-from-sensor-through-multiplexer/1038153/10 "2022-10-04T16:43:46Z")

</div>

> **TomGeorge**  
> So I believe you need to say;
> 
> ```arduino
> as5600.begin(4);
> as5600.setDirection(AS5600_CLOCK_WISE);
> 
> ```
> 
> Once with the first sensor selected, then again with the second selected.  
> This is to wakeup the sensors for comms.

I added these lines for each sensor. It works! I get a good reading from each one now. Here is my current code. Thank you TomGeorge and Alto777 for the help. Now to the next step, programming the AS5600. I think...

```arduino
#include <Wire.h>
#include <AS5600.h>

#define TCAADDR 0x70

int Actang1;
int Actang2;
int Actang3;
int Actang4;
int Actang5;
int Actang6;
int a1;
int a2;
AS5600 as5600;

void TCA9548A(uint8_t bus)
{
  Wire.beginTransmission(0x70);
  Wire.write(1 <<bus);
  Wire.endTransmission();
}
void setup() {
  Serial.begin(9600);  
}

void loop() {
    
  
  TCA9548A(1);
  as5600.begin();
  as5600.setDirection(AS5600_CLOCK_WISE);
  float a1 = as5600.readAngle();
  Serial.print("Angle 1,");
  Serial.println(a1);

    TCA9548A(2);
    as5600.begin();
    as5600.setDirection(AS5600_CLOCK_WISE);
  float a2 = as5600.readAngle();
  Serial.print("Angle 2,");
  Serial.println(a2);
delay(300);

}

```

---

<div class="post-metadata">

**Author:** ![alto777](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/alto777/32/317385_2.png) [@alto777](https://forum.arduino.cc/u/alto777)\
**Post date:** [October 4, 2022, 4:50pm UTC](https://forum.arduino.cc/t/reading-data-from-sensor-through-multiplexer/1038153/11 "2022-10-04T16:50:03Z")

</div>

> [@MrDoggss](#):
>
> ```arduino
> TCA9548A(1);
> as5600.begin();
> as5600.setDirection(AS5600_CLOCK_WISE);
> 
> ```

I am sure enough to ask you to try placing those lines, and the ones that do the other sensor setup into your _setup_() function.

You'll still need just the

```
 TCA9548A(1);

```

to set the multiplexer later in you _loop_(), or wherever, but the initial stuff usually wants to be done just once.

```arduino
    TCA9548A(2); // select unit 2
    float a2 = as5600.readAngle();

```

I do not know how quickly the mux catches up with a change of address. My instinct is that it is without any need to delay in any way after selected a new I2C device to talk with.

a7

---

<div class="post-metadata">

**Author:** ![MrDoggss](https://avatars.discourse-cdn.com/v4/letter/m/7ea924/32.png) [@MrDoggss](https://forum.arduino.cc/u/MrDoggss)\
**Post date:** [October 4, 2022, 4:56pm UTC](https://forum.arduino.cc/t/reading-data-from-sensor-through-multiplexer/1038153/12 "2022-10-04T16:56:44Z")

</div>

> [@alto777](#):
>
> I am sure enough to ask you to try placing those lines, and the ones that do the other sensor setup into your _setup_() function.
> 
> You'll still need just the
> 
> ```arduino
> TCA9548A(1);
> 
> ```
> 
> to set the multiplexer later in you _loop_(), or wherever, but the initial stuff usually wants to be done just once.
> 
> ```arduino
> TCA9548A(2); // select unit 2
> float a2 = as5600.readAngle();
> 
> ```
> 
> I do not know how quickly the mux catches up with a change of address. My instinct is that it is without any need to delay in any way after selected a new I2C device to talk with.
> 
> a7

I see! I'll change the code and add those lines to the setup. Hopefully I can do that without any issues.

Thanks.

---

<div class="post-metadata">

**Author:** ![eriknor](https://avatars.discourse-cdn.com/v4/letter/e/ac8455/32.png) [@eriknor](https://forum.arduino.cc/u/eriknor)\
**Post date:** [January 31, 2023, 1:28pm UTC](https://forum.arduino.cc/t/reading-data-from-sensor-through-multiplexer/1038153/13 "2023-01-31T13:28:08Z")

</div>

I'm working on this for 3 as5600 for a 3D-printer. Could you share your code with me?  
I'm using the same multiplexer aswell.

---

<div class="post-metadata">

**Author:** ![eriknor](https://avatars.discourse-cdn.com/v4/letter/e/ac8455/32.png) [@eriknor](https://forum.arduino.cc/u/eriknor)\
**Post date:** [February 7, 2023, 1:37pm UTC](https://forum.arduino.cc/t/reading-data-from-sensor-through-multiplexer/1038153/14 "2023-02-07T13:37:16Z")

</div>

I managed to do it, and here's a working code for people with the same problem that end up in this thread.

```cpp
// include as5600 and wire libraries
#include <Wire.h>
#include <AS5600.h>

// Define three as5600 objects as X, Y and Z for further use
AS5600 stpA;
AS5600 stpB;
AS5600 stpC;

int I2CA=2;
int I2CB=3;
int I2CC=1;

float radA=0;
float radB=0;
float radC=0;

float newradA;
float newradB;
float newradC;

float initA;
float initB;
float initC;

float dradA=0,dradB=0,dradC=0;
float drevA=0,drevB=0,drevC=0;

float X=0,Y=0,Z=0;

// assign constants values
float pitch = 8 / (2*M_PI); // mm/radian of stepper motor
float radius = 12.73 / 2; //3D printer A and B stepper polley radius

void setup()
{

    // Start serial communication
    Serial.print("setup initializing");
    Serial.begin(115200);
    while (!Serial)
    {
        // wait for serial port to connect. Needed for native USB port only
    }
    Wire.begin();
    // Set up and check if X is connected
    Serial.println("X setup initializing");
    TCA9548(I2CA);
    stpA.begin(4);
    stpA.setDirection(AS5600_CLOCK_WISE);
    int b = stpA.isConnected();
    Serial.print("Connect: ");
    Serial.println(b);
    Serial.println("X setup done");
    initA=stpA.getCumulativePosition()*AS5600_RAW_TO_RADIANS;
    radA=0;
    delay(20);

    // Set up and check if Y is connected
    TCA9548(I2CB);
    stpB.begin(4);
    stpB.setDirection(AS5600_CLOCK_WISE);
    int c = stpB.isConnected();
    Serial.print("Connect: ");
    Serial.println(c);
    initB=stpB.getCumulativePosition()*AS5600_RAW_TO_RADIANS;
    radB=0;
    delay(20);

    // Set up and check if Z is connected
    TCA9548(I2CC);
    stpC.begin(4);
    stpC.setDirection(AS5600_CLOCK_WISE);
    int d = stpC.isConnected();
    Serial.print("Connect: ");
    Serial.println(d);
    initC=stpC.getCumulativePosition()*AS5600_RAW_TO_RADIANS;
    radC=0;
    delay(20);
   
    X = 0;
    Y = 0;
    Z = 0;
    
    delay(5000);
    Serial.println("setup done");

}

void loop()
{
   static uint32_t lastTime = 0;
   
   if (millis() - lastTime >= 5)
  {
    TCA9548(I2CA);
    newradA = stpA.getCumulativePosition()*AS5600_RAW_TO_RADIANS-initA;
    dradA=newradA-radA;
    radA=newradA;
    
    

    TCA9548(I2CB);
    newradB=stpB.getCumulativePosition()*AS5600_RAW_TO_RADIANS-initB;
    dradB=newradB-radB;
    radB=newradB;
    

    TCA9548(I2CC);
    newradC=stpC.getCumulativePosition()*AS5600_RAW_TO_RADIANS-initC;
    dradC = newradC-radC;
    radC=newradC;
    

    X = X + (dradA + dradB) * radius / 2; //specific kinematic equations for corexy 3dprinter
    Y = Y + (dradA - dradB) * radius / 2;
    Z = Z + dradC * pitch;

    //Serial.print("X: ");
    Serial.print(X, 3);
    Serial.print(" , ");
    // Serial.print(radA);

    //Serial.print(",Y: ");
    Serial.print(Y, 3);
    Serial.print(" , ");
    //Serial.print(radB);

    //Serial.print(",Z: ");
    Serial.println(Z, 3);
    // Serial.print(" : ");
    // Serial.println(radC);

  }
}

void TCA9548(int bus)
{
    Wire.beginTransmission(0x70);
    Wire.write(1 << bus);
    Wire.endTransmission();
}

```

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [August 6, 2023, 1:38pm UTC](https://forum.arduino.cc/t/reading-data-from-sensor-through-multiplexer/1038153/15 "2023-08-06T13:38:04Z")

</div>

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.
