1

I have an application which reads temperature from a BPM180 sensor with C#.

I found this device that would allow to connect multiple devices: Adafruit TCA9548A 1-to-8 I2C Multiplexer Breakout.

However I could not find any documentation on how to read data from multiple sensors connected to this multiplexer in C#.

Any idea?

  • well, I am an MVP, but in another subject area not in raspberry development, otherwise I wouldnt be asking here in a community where people are supposed to help, so stop being an idiot and help the community, and not its not open house there at MS, I worked for 5 years to get it, so grow up and move on. – Luis Valencia Nov 16 '16 at 12:39
  • @ppumkin I don't know whether or not it is C# related -- I thought you could do everything with C#! ;) -- but to be fair, we do field questions like this in python often enough. There is some gray area there. As to whether it would be better off asking on S.O., I dunno about that either, but again, to be fair, if asking about how to read a BMP180 in python on Raspbian is okay, then asking about the same thing in C# on Win IoT for the Pi should be okay (even if it turns out to be misguided). – goldilocks Nov 16 '16 at 13:04
  • You can do everything with C# :) the issue is that reading this sensor is I2C. Well covered topic. I think the op is asking how to covert the actual data from the sensor. So is that Raspberry Pi related ? – Piotr Kula Nov 16 '16 at 13:08
  • thank you, probably stackoverflow would be a good choice to ask, but I doubt that there are many experts about C# with I2C there, I however found this: github.com/Microsoft/Windows-universal-samples/tree/master/…, so that is a starting point, (If I had only one I2C sensor), but with the multiplexer thats the issue. – Luis Valencia Nov 16 '16 at 13:21
  • To be honest there seems to be a missing Q&A for programming/embedded questions in general. But this topic was raised before on various occasions. These Q&A are meant to be very specific so opening a general Q&A leads to a more forum styled approach with many suggestions etc etc. This multiplexer is only required if you have I2C devices with the same address. You can chain as many I2C devices as you like, as long as they have unique addresses. I suggest wiring 1 sensor up first and doing a simple C# app. There are tons of examples on the MS site. Then try to add more sensor – Piotr Kula Nov 16 '16 at 15:35
7

A code sample is right there on Adafruit website (in Python, but it's very simple).

The TCA9548A multiplexer is interesting in that it has an I2C address (0x70 by default) - and you basically send it a command to tell it which I2C multiplexed output you want to talk to, then you can address the board you want to address.

So, you'll need to select the right sensor by writing the channel ID to address 0x70, then read the data from the sensor as if it was connected directly.

Another possiblity, as suggested by @joan is to activate i2c-mux overlay by adding the line dtoverlay=i2c-mux,pca9548 to /boot/config.txt. This will bring up additional buses /dev/i2c-3, /dev/i2c-4 and so on, which correspond to multiplexed devices. In that case, your software will only need to open the right bus, and sending the channel ID to address 0x70 will be performed for you by the overlay.

  • its not python its C, and because I am running Windows IoT Core, I need C# sample or instructions in how to embed a C program in a C# application if possible at al – Luis Valencia Nov 15 '16 at 18:21
  • @LuisValencia-MVP Yeah right, it's that Arduino-style C++. Still, why do you need to embed existing code? Can't you write your own function in C# which writes a single byte to a particular i2c address? – Dmitry Grigoryev Nov 15 '16 at 21:53
  • 1
    Hey Dmitry - Why don't you write the entire application and post the compiled binary to Luis. (sarcasm) This looks like simple I2C - I dont get what the problem is?? :) – Piotr Kula Nov 15 '16 at 23:15
  • my expertise is not raspberry pi or i2c programming, never done it before, my expertise is another area, dont need to Sarcasm, and yes I need a full sample code working even if it sounds sarcasm – Luis Valencia Nov 16 '16 at 12:38
  • @LuisValencia-MVP No offence, but if you have never done i2c and now you have a project with 8 i2c sensors and a multiplexer, it's about time you learn the basics. Here's an example using an i2c C# library designed specially for the RPi, you'll have to fly solo beyond this point. – Dmitry Grigoryev Nov 16 '16 at 13:04
0

I know its a little late but here's a nice C# solution that i use for my raspberry pi 3 running windows iot. Its a static class as I found you want all your devices to be able to call the methods.

Instructions: 1) Initiate the chip with its address 2) Select the Sdx/Scx you want

Usage:

 await Tca9548a.Initialize(0x70);
 Tca9548a.SelectAddress(0x70, 0x01);
 // Make any calls to your device on SC1/SD1

And then the source code:

 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Threading.Tasks;
 using Windows.Devices.Enumeration;
 using Windows.Devices.I2c;

 namespace Devices
 {
     /// <summary>
     /// This class wraps the functionality of the TCA9548A I2C Multiplexer. 
     /// It was created with the intention of being used on the Raspberry Pi 3 on Windows IoT.
     /// </summary>
     public static class Tca9548a
     {
    const string I2CControllerName = "I2C1";

    static readonly Dictionary<byte, I2cDevice> multiplexers = new Dictionary<byte, I2cDevice>();

    /// <summary>
    /// Attempts to initialize the multiplexer
    /// </summary>
    /// <param name="multiplexerAddress">The address of the multiplexer. Default for Tca9548a is 0x70.</param>
    public static async Task Initialize(byte multiplexerAddress = 0x70)
    {
        Debug.WriteLine($"Initiating Multiplexer at address {multiplexerAddress}");

        try
        {
            // Error checking
            if (multiplexers.ContainsKey(multiplexerAddress))
            {
                Debug.WriteLine($"A Tca9548a multiplexer has already been initiated at that address ({multiplexerAddress})");
                return;
            }                

            // Create a I2C settings object
            var settings = new I2cConnectionSettings(multiplexerAddress)
            {
                BusSpeed = I2cBusSpeed.FastMode
            };

            // Get the device information for the I2C controller
            var aqs = I2cDevice.GetDeviceSelector(I2CControllerName);
            var dis = await DeviceInformation.FindAllAsync(aqs);

            // Initiate the sensor
            var tca9548a = await I2cDevice.FromIdAsync(dis[0].Id, settings);
            // Add it to the dictionary
            multiplexers.Add(multiplexerAddress, tca9548a);

            Debug.WriteLine($"Successfully initiated the Tca9548a multiplexer at address: {multiplexerAddress}");
        }
        catch (Exception e)
        {
            Debug.WriteLine($"Unable to initiate the Tca9548a multiplexer: {e}");
        }            
    }

    /// <summary>
    /// Select a multiplex id on a multiplexer.
    /// </summary>
    /// <param name="multiplexerAddress">The adress of the multiplexer to change (0x70 - 0x77)</param>
    /// <param name="multiplexId">The multiplex id to connect to (0 off, 1 - 7 for SCx/SDx)</param>
    public static void SelectAddress(byte multiplexerAddress, byte multiplexId)
    {
        try
        {
            Debug.WriteLine($"Setting multiplexer {multiplexerAddress} to id {multiplexId}.");
            if (!multiplexers.ContainsKey(multiplexerAddress))
            {
                Debug.WriteLine($"Multiplexer at {multiplexerAddress} not found. Please initialize the multiplexer before using it.");
                return;
            }
            if (multiplexId > 0x07)
            {
                Debug.WriteLine(
                    $"Tca9548a.SelectAddress({multiplexId}) is not valid. Only 0 - 7 is supported by this device.");
                return;
            }
            var writeBuffer = new byte[] { multiplexId };
            multiplexers[multiplexerAddress].Write(writeBuffer);
        }
        catch (Exception e)
        {
            Debug.WriteLine($"Unable to select ({multiplexerAddress}, {multiplexId}): {e}");
            throw;         
        }
    }
}

}

  • The benefit of passing the address as a parameter is that you could hook up many multiplexers this way if needed. – Mr Wood Aug 11 '17 at 1:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.