Wrapping Library Into custom Class

Hi All,

I'm working on a larger project where I want to use a number of sensors and libraries, and in order to keep the code clean, I'd like to wrap certain libraries into my own classes. I'm trying this with the Adafruit SHT31 temperature sensor as an example:

main.ino

#include <Arduino.h>
#include <Wire.h>
#include "Adafruit_SHT31.h"
#include "ambientTemp.h"

ambientTemp ambienttemp();

void setup() {
  Serial.begin(9600);
}

void loop() {
  float t = ambienttemp.getTemp();
  Serial.println(0);
  delay(1000);
}

ambientTemp.h

#include <Arduino.h>
#include <Wire.h>
#include "Adafruit_SHT31.h"

class ambientTemp {
  public:
    // Constructor
    ambientTemp();
    // Methods
    float getTemp(void);

  private:
    // Sensor hardware class
    Adafruit_SHT31 sht31_;
};

ambientTemp.cpp

#include <Arduino.h>
#include <Wire.h>
#include "Adafruit_SHT31.h"
#include "ambientTemp.h"

// Ambient Temperature Sensor
ambientTemp::ambientTemp()
  : sht31_()  
{
    sht31_.begin(0x44);
}
    
float ambientTemp::getTemp() {
      float t = sht31_.readTemperature();
      if (! isnan(t)) return t;
      else return false;
}

But I get the following error:

main:17:25: error: request for member 'getTemp' in 'ambienttemp', which is of non-class type 'ambientTemp()'

I feel like I'm somehow not initializing the Adafruit_SHT31 correctly, which in their example code is done with Adafruit_SHT31 sht31 = Adafruit_SHT31();

Any thoughts how to fix this would be much appreciated!

That's a prototype for a function named 'ambienttemp' that takes no arguments and returns a value of type 'ambientTemp'.
Try:

ambientTemp ambienttemp;

Thanks, gfvalvo! This solved the error, and the code now compiles but when I run it on the Uno it seems to hang. I still assume I'm doing something wrong in the initializer list when creating an instance of the Adafruit_SHT31, but I can't figure out what it is.

currently you don't need a initializer list.

.begin() is a memberfunction of Adafruit_SHT31 .
All the examples show, that this member function gets called in setup.
But you call it in the constructor.
Don't call things in the constructor which might need hardware access. HW might not be ready at this point.

Create your own begin member function and call it in setup.

ps.: why this trailing _ in sht31_ ? just leave it away.

1 Like

Thanks so much noiasca! That solved it. I wrapped the begin() function and called it from my main process and it works! Posting the working code below for future reference if anybody needs it:

ambientTemp.h

#include <Arduino.h>
#include <Wire.h>
#include "Adafruit_SHT31.h"

class ambientTemp {
  public:
    // Constructor
    ambientTemp();
    // Methods
    float getTemp(void);
    void begin(void);

  private:
    // Sensor hardware class
    Adafruit_SHT31 sht31_;
};

ambientTemp.cpp

#include <Arduino.h>
#include <Wire.h>
#include "Adafruit_SHT31.h"
#include "ambientTemp.h"

// Ambient Temperature Sensor
ambientTemp::ambientTemp()
  : sht31_()  
{}

void ambientTemp::begin() {
  sht31_.begin(0x44);
}

float ambientTemp::getTemp() {
  float t = sht31_.readTemperature();
  if (! isnan(t)) return t;
  else return false;
}

main.ino

#include <Arduino.h>
#include <Wire.h>
#include "Adafruit_SHT31.h"
#include "ambientTemp.h"

ambientTemp ambienttemp;

void setup() {
  Serial.begin(9600);
  ambienttemp.begin();
}

void loop() {
  float t = ambienttemp.getTemp();
  Serial.println(t);
  delay(1000);
}

Get rid of the initializer list. You don't need it if the Adafruit_SHT31 class's constructor takes no parameters.

Use:

ambientTemp::ambientTemp() {
}

Now get rid of the constructor? :slight_smile:

Ya.

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