2

I am working on a C# net micro framework project, in particular an I2C bus class.

I have several different I2C devices each defined in separate classes which contain all of the devices' unique methods. In my case, I can only have ONE I2CDevice object defined and to switch to another I2C device, I have to change the I2CDevice.Config = DeviceConfig.

For example (pseudo-code):

Class Device1 
-DeviceConfig1
-Method 1
-Method 2
-Method 3

Class Device2
-DeviceConfig2
-Method 1
-Method 2
-Method 3


Main Program
{
I2cBus = new I2CDevice(configuration)
Device1.Method1
Device2.Method3
}

When switching between devices, I need to change the I2CDevice.Config property. I'm looking for an elegant way such that whenever I call a Method for a device, that the I2CBus.Config is automatically changed. Is there a way that I don't need to re-type this config code in each method? Have a separate internal method that's called each time I access any of those methods?

I hope my description is clear.

Update, As an alternative, is there a way I can have my make my I2C Bus class and then ADD the devices to the this class? Then To access The Devices, I would Do something like

I2CBus.AddDevice(Device1ObjectClass)
I2CBus.AddDevice(Device2ObjectClass)
I2CBus.Device1.Method1
I2CBus.Device2.Method2

I still have the same problem that I need to "automatically" switch the I2C configuration between Different Device calls.

marked as duplicate by yannis Apr 9 '14 at 8:53

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

migrated from stackoverflow.com Apr 9 '14 at 8:50

This question came from our site for professional and enthusiast programmers.

  • 1
    So when you call Device1.Method1, I2cBus uses DeviceConfig1, and when you call Device2.Method3, I2cBus uses DeviceConfig2? I don't understand what you're trying to do – Brandon Mar 20 '14 at 20:39
  • I have edited your title. Please see, "Should questions include “tags” in their titles?", where the consensus is "no, they should not". – John Saunders Mar 20 '14 at 20:41
  • @Brandon I think he is talking about setting the I2C configuration depending on the latest method called. If it was class 1, the configuration in I2C must be the class1 configuration – rpax Mar 20 '14 at 20:41
  • @rpax I kind of figured that might be it. – Brandon Mar 20 '14 at 20:44
  • If configuration is a reference type (i.e. an object) then Device1.Method1 and Device2.Method3 can both manipulate properties in it if they are passed (or have access to) a reference of it. For example: Device2.Method3(I2cBus.Configuration) – slugster Mar 20 '14 at 20:44
1

Maybe:

class DeviceWrapper
{
   private Device1 _device1;
   public Device1 device1
   {
      get
      {
           happensEveryTimeDeviceIsAccessed();
           return _device1;

       }
   } 
}
  • Thanks! I'm trying to make it a little more automatic with how that works. For example, Device1.Method1(); Device2.Method3(); will the the only calls. Without adding duplicate code in each method, something, ideally "automatic", should check the I2Cbus Configuration and make it correct if there's a device change. – GisMofx Apr 8 '14 at 14:13
  • do device1 and device2 share a base class or are they the same class? – RadioSpace Apr 8 '14 at 18:36
0

This is the best I could come up with, and I'm not afraid to admit that it's garbage because you're still not able to have your I2CBus intrinsically know what to do. It kind of works but, as I mentioned, it's all I have.

public interface IDevice
{
    string Name { get; set; }
    DeviceConfiguration GetConfiguration();
}

public abstract class DeviceParent : IDevice
{
    public DeviceParent(DeviceConfiguration aConfig)
    {
        myConfig = aConfig; 
    }

    #region IDevice Members

    public string Name { get; set; }

    public virtual DeviceConfiguration GetConfiguration() //This could also simply be a property, not sure what you want to do with it.
    {
        return myConfig;
    }

    #endregion

    protected DeviceConfiguration myConfig;

}

public class DeviceConfiguration
{
    public DeviceConfiguration()
    {

    }
}

public class Device : DeviceParent
{
    public Device(DeviceConfiguration aConfig) : base(aConfig) { }

    public void SomeMethod()
    {

    }
}

public class Device2 : DeviceParent
{
    public Device2(DeviceConfiguration aConfig) : base(aConfig) { }

    public void SomeMethod2()
    {

    }
}

public class I2CBus : IEnumerable<IDevice>
{

    private List<IDevice> myDevices;
    private DeviceConfiguration currentConfiguration;

    public enum NonExistantDeviceBehaviour
    {
        ReturnNull,
        AddToOurselves
    }

    public NonExistantDeviceBehaviour NoDeviceBehaviour; //Defines what should happen in the event that we're indexed by a device that we don't contain yet.

    public IDevice this[IDevice index]
    {
        get
        {
            if (!myDevices.Exists(d => d.Name == index.Name))
            {
                switch (NoDeviceBehaviour)
                {
                    case NonExistantDeviceBehaviour.ReturnNull:
                        return null;
                    case NonExistantDeviceBehaviour.AddToOurselves:
                        myDevices.Add(index);
                        break;
                }
            }

            currentConfiguration = index.GetConfiguration();

            return myDevices.Find(d => d.Name == index.Name);

        }
    }


    public I2CBus()
    {
        currentConfiguration = null;
        myDevices = new List<IDevice>(); //Ensures our list is never null
    }


    #region IEnumerable<IDevice> Members

    public IEnumerator<IDevice> GetEnumerator()
    {
        return myDevices.GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    #endregion
}

So all I did pretty much was add the index to the I2CBus class, which allows you to use this syntax:

I2CBusInstance[Device1]

However, you still have to cast to the type you're passing to that index to get access to that type's methods anyway, which is why this solution isn't ideal. Here is the usage:

I2CBus i2cb = new I2CBus();

Device device = new Device(new DeviceConfiguration());
Device2 device2 = new Device2(new DeviceConfiguration());

i2cb.NoDeviceBehaviour = I2CBus.NonExistantDeviceBehaviour.AddToOurselves;

(i2cb[device] as Device).SomeMethod();

Hope that helps a little... I'll be watching this question a while because I'm incredibly intrigued now.

  • Thanks for this solution! Unfortunately, I cannot use this specific example because the netMF framework doesn't support Generics... yet. I'm still looking for another solution and have been tossing this around in my head. I like your idea of having a base class..maybe a State Pattern approach or something similar could accomplish this. Still thinking. What if each device class had an instance of the I2C bus class in it?..hmm – GisMofx Apr 8 '14 at 13:42

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