Passing an I2C object to a library

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
SithDude
 
Posts: 8
Joined: Wed Sep 23, 2015 7:03 am

Passing an I2C object to a library

Post by SithDude »

I've been trying to get this to work for quite some time now, and still don't see the light at the end of the tunnel. And since i'm not the sharpest tool in the shed, i'm happy to ask the silly questions as i'm sure i'm not the only tool needing help ;)

quick overview:
I'm trying to make my arduino do everything over I2C. I'm using the LiquidCrystal_I2C library for the display (working fine). But now I want to use a TC74A* temperature sensor to get the temp. Since I want a few of them I decided to write a little library for them. And I want to initialize them in the main program using something like

Code: Select all

TC74A_Control tSens = TC74A_Control(??, address)

Oh yeah, I haven't decided if I would use it in the constructor or a method of the library. If I were to use a method it would be something like:

Code: Select all

int TC74A_Control::readTemp(??)
{
  ??.beginTransmission(sensorAddress);
  ??.write(0);
  ??.endTransmission();
  ??.requestFrom(sensorAddress, 1);

  while(??.available() == 0);

  int t = ??.read();

  return t;
}
So how should I do this? What should I change the question marks for... I'm sure it has something to do with pointers and alls that jazz, but I can't put my finger on it...

User avatar
SithDude
 
Posts: 8
Joined: Wed Sep 23, 2015 7:03 am

Re: Passing an I2C object to a library

Post by SithDude »

I would love to have it look something like this:

the TC74A_Control.h file

Code: Select all

#ifndef TC74A_Control_h
#define TC74A_control_h

#include "Arduino.h"
#include "Wire.h"
#include "Stream.h"

class TC74A_Control
{
  public:
    //TC74A_Control(Stream& s, int sensAdr):draad(s){}
    TC74A_Control(Stream& s, int sensAdr);
    int readTemp();

  private:
    int _SENSOR_ADDRESS;
    Stream& draad;

};

#endif

and the TC74A_Control.cpp file:

Code: Select all

#include "Arduino.h"
#include "Wire.h"
#include "Stream.h"

#include "TC74A_Control.h"


TC74A_Control::TC74A_Control(Stream& s, int sensAdr)
{
  draad(s);
  _SENSOR_ADDRESS = sensAdr;
}

/*
 * Publieke functies
 */

int TC74A_Control::readTemp()
{
  draad.beginTransmission(_SENSOR_ADDRESS);
  draad.write(0);
  draad.endTransmission();
  draad.requestFrom(_SENSOR_ADDRESS, 1);

  while(draad.available() == 0);

  int t = draad.read();

  return t;
}
but when i compile this, well, it all goes pear shaped.
trying to figure out the error messages, but if anyone has any input, it would be greatly appreciated...

User avatar
adafruit_support_bill
 
Posts: 88136
Joined: Sat Feb 07, 2009 10:11 am

Re: Passing an I2C object to a library

Post by adafruit_support_bill »

What library are you using? I don't believe we have a TC74A_Control_h.

User avatar
SithDude
 
Posts: 8
Joined: Wed Sep 23, 2015 7:03 am

Re: Passing an I2C object to a library

Post by SithDude »

Ah no, I'm using a library I created myself, hence me posting it. So rest assured, it's all me :)

User avatar
adafruit_support_bill
 
Posts: 88136
Joined: Sat Feb 07, 2009 10:11 am

Re: Passing an I2C object to a library

Post by adafruit_support_bill »

The PWM Servo library is a good example of an addressable class. The I2C address is passed in the constructor.

https://github.com/adafruit/Adafruit-PW ... er-Library

User avatar
SithDude
 
Posts: 8
Joined: Wed Sep 23, 2015 7:03 am

Re: Passing an I2C object to a library

Post by SithDude »

Ah, I will defiantly be taking a good look at that one, thanks!

User avatar
SithDude
 
Posts: 8
Joined: Wed Sep 23, 2015 7:03 am

Re: Passing an I2C object to a library

Post by SithDude »

I see what you did there, you just passed the address and started the wire comm inside the library. This is definitely another way of doing it. Any reason why only the address and not the entire object? I'm guessing it's cleaner that way? Maybe I was just making it too complicated for myself...

User avatar
adafruit_support_mike
 
Posts: 67485
Joined: Thu Feb 11, 2010 2:51 pm

Re: Passing an I2C object to a library

Post by adafruit_support_mike »

The big question is "where does the object need to be visible?"

In OOP, you want to watch out for a code property called 'linkage': how many other classes does an object need to know about in order to work, and by extension, how many header files you you need to include in the header for that class?

Linkage makes problems with one chunk of code propagate to another, so you generally want as little as you can get.

As an example, let's say we have two classes named Foo and Bar, and we want Foo to use some feature that Bar provides.

One solution is to create an instance of Bar in the main code and pass it to an instance of Foo. That means we have linkage from Bar to the main code (which creates the object) and the Foo class (which uses the object). We also have linkage from the main code to Foo.

Another solution is to let the Foo class create a Bar object internally. That gives us linkage from the main code to Foo, and from Foo to Bar. The main code doesn't need to know anything about Bar, so that way of arranging the code has less linkage. If you decide you don't really need Bar and want to merge the features it provides into the Foo class, your main code doesn't need to know or care about it.

To make things more complicated, let's add a class named Bazz that supplies information necessary to create the Bar object, and let's assume that it needs to be created in the main code. There are several ways to organize that:

We could have the main code create a Bazz object, use that to create a Bar object, then pass the Bar object to Foo.

We could have the main code create a Bazz object, pass that to Foo, and let Foo configure the Bar object.

We could have the main code create a Bazz object, pull simple values from that (ints, strings, etc) and pass those values to Foo so it can configure the Bar object it creates internally.

That last option sounds more complicated, but it eliminates any linkage from Bazz to the Foo or Bar classes, and that's a good thing. It means you can create and configure a Foo object without actually using a Bazz object, just feeding the config methods values of the appropriate type. You can also create a fake class with the same configuration methods as Foo to see if your main code is doing the setup properly.

There are times when it's appropriate to pass an instance of one class to another, usually to simplify communication between widely separated sections of code. If you can replace an object parameter with a simpler type of parameter though, it's usually a good idea to do so.

User avatar
adafruit_support_bill
 
Posts: 88136
Joined: Sat Feb 07, 2009 10:11 am

Re: Passing an I2C object to a library

Post by adafruit_support_bill »

Linkage makes problems with one chunk of code propagate to another, so you generally want as little as you can get.
I'm with Mike here. Tight coupling between classes can create major problems - and these problems tend to compound exponentially. What makes for frustration and hair-pulling in an Arduino-scale project can be complete show-stoppers in larger systems.

User avatar
SithDude
 
Posts: 8
Joined: Wed Sep 23, 2015 7:03 am

Re: Passing an I2C object to a library

Post by SithDude »

Aha, I see what you are getting at. I guess I was getting a bit overboard with making my own classes. I was using one of your touchscreens, the tft lcd shield with touch screen (great board btw!), and making different kinds of buttons to use in another project. And since it worked wonders simplifying the main program there, I went on using it here. But it'll just end up making too much linkage between the different parts of the program. I'll end up only passing the address along, like you suggested in a previous answer. I also had this weird idea that once a Wire instance was created, it should be passed around the entire program... Anyway, thanks for making this very clear, and keep up the good work (and good products)!

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”