How to pass ADS1115 an adress within a class if used twice

HI

I use two ADS1115 and two MCP23008, paired on two little PCB which drives and measures an transimpedance amplifier device.

My issue is, that i can pass an adress to class MCP23008 through my UDT_TRAMP class on initialisation. BUT i cannot pass an adress to ADS1115, it always takes the default 0x48. Somehow it should be possible to pass an other adress to the ADS1115 class through UDT_TRAMP class exp. 0x49. The two MCP23008 already work.

I tried a lot but it seems that the ADS1115 libraray has not the same support as the MCP23008 on initialisation. For all i know it only supports two different adresses on ADS1115 if i make the object in the main code and not in the class. But my hope is that i can keep the class UDT_TRAMP and hand over the adress like for the MCP23008. Unfortunately i dont know how to write the proper code to do so.

Could you please help and give me the idea or even better a snippet or code please? Thanks a lot for your help.

main code:

#include "UDT_TRAMP.h"


UDT_TRAMP udt;
UDT_TRAMP udt2;

void setup() {
  udt.begin(0); //first MCP23008 adress
  udt2.begin(1); //second MCP23008 adress
}

void loop() {
udt.autoRange();
Serial.println(udt.getMeasure(20));
udt2.autoRange();
Serial.println(udt2.getMeasure(20));
delay(2000);
}

UDT_TRAMP.cpp

#include "UDT_TRAMP.h"
#include <math.h>  



void UDT_TRAMP::begin() 
{
	begin(0);
}
void UDT_TRAMP::begin(uint8_t adrr_mcp23008)
{
	_mcp.begin(adrr_mcp23008);
	_ads.begin();

	_mcp.pinMode(0, OUTPUT);	//Range 3
	_mcp.pinMode(1, OUTPUT);	//Range 2
	_mcp.pinMode(2, OUTPUT);	//Range 1
	_mcp.pinMode(7, INPUT);		//OVLD

	_mcp.digitalWrite(0, LOW);
	_mcp.digitalWrite(1, LOW);
	_mcp.digitalWrite(2, LOW);
	_exponent = 3;
}

//Overload, udt reached OVLD, which means that analog voltage is over a certain output level and it is necessary to switch to an other amplification factor
bool UDT_TRAMP::getOVLD()
{
	return !_mcp.digitalRead(7);
}

//set udt to a certain amplification factor
void UDT_TRAMP::setRange(uint8_t r)
{
	if (r < 3) { r = 3; }
	if (r > 10) { r = 10; }
	_exponent = r;

	switch (r) 
	{
		case 3: _mcp.digitalWrite(2, LOW); _mcp.digitalWrite(1, LOW); _mcp.digitalWrite(0, LOW); break;
		case 4: _mcp.digitalWrite(2, HIGH); _mcp.digitalWrite(1, LOW); _mcp.digitalWrite(0, LOW); break;
		case 5: _mcp.digitalWrite(2, LOW); _mcp.digitalWrite(1, HIGH); _mcp.digitalWrite(0, LOW); break;
		case 6: _mcp.digitalWrite(2, HIGH); _mcp.digitalWrite(1, HIGH); _mcp.digitalWrite(0, LOW); break;
		case 7: _mcp.digitalWrite(2, LOW); _mcp.digitalWrite(1, LOW); _mcp.digitalWrite(0, HIGH); break;
		case 8: _mcp.digitalWrite(2, HIGH); _mcp.digitalWrite(1, LOW); _mcp.digitalWrite(0, HIGH); break;
		case 9: _mcp.digitalWrite(2, LOW); _mcp.digitalWrite(1, HIGH); _mcp.digitalWrite(0, HIGH); break;
		case 10: _mcp.digitalWrite(2, HIGH); _mcp.digitalWrite(1, HIGH); _mcp.digitalWrite(0, HIGH); break;
	}

}

//read analoge voltage and set range according to incoming voltage in a optimal range
void UDT_TRAMP::autoRange() 
{
	bool zuKlein = false;
	double mv = getMiliVolt(5);

	//Wenn weniger als 0.5V gemessen wird soll die Verstaerkung um 10 erhoeht werden
	if (mv < 500.0) { zuKlein = true; }
	// Ebenfalls soll die Verstaerkung erhoeht werden, wenn mehr als 10V (bei ganz kleinen Spannungen macht der ADC einen Feheler und gibt nicht 0 sondern 65534 aus) gemessen werden aber kein Overload ausgegeben wird
	if ((mv > 10000.0 && !getOVLD())) { /*Serial.println("ADC_Error -> Gain++");*/ zuKlein = true; }
	

	while (zuKlein) 
	{
		zuKlein = false;
		mv = getMiliVolt(5);
		if (mv < 500.0) { zuKlein = true; }
		if (mv > 10000.0 && !getOVLD()) { /*Serial.println("ADC_Error -> Gain++");*/ zuKlein = true; }
		setRange(_exponent + 1);
		if(_exponent==10){ zuKlein = false; } //Verstaerkung kann nicht weiter erhaerht werden -> Abbruch
		delay(100);
	}
	
	while (getOVLD() && (_exponent > 3)) {
    Serial.println("Overload");
		setRange(_exponent - 1);
    delay(100);
	}
}

//returns current range
uint8_t  UDT_TRAMP::getRange()
{
	return _exponent;
}

//reads ADC
uint16_t UDT_TRAMP::getADC()
{
	_ads.readADC_SingleEnded(0);
	delay(10);
	return _ads.readADC_SingleEnded(0);
}

//makes a certain amount of measurements of ADC in ADC steps
double UDT_TRAMP::getADC(uint8_t anzahlMessungen) 
{
	_ads.readADC_SingleEnded(0);
	delay(10); 
	int32_t summe = 0;
	for (int i = 0; i < anzahlMessungen; i++) { summe = summe + _ads.readADC_SingleEnded(0); delay(10); }//100 didnt help
	double r = (double)summe / (double)anzahlMessungen;
	return r;
}

//makes a certain amount of measurements of ADC in miliVolt
double UDT_TRAMP::getMiliVolt(uint8_t anzahlMessungen)
{
	double mV = getADC(anzahlMessungen);
	mV = mV*0.1875;
  Serial.print("GetMiliVolt = ");
  Serial.println(mV);
	return mV;
}

//calculates out of ADC value the measured value
double UDT_TRAMP::getMeasure()
{
	double resultat;

	resultat = getADC()*(pow(10, (7 - _exponent)));
  //resultat = getADC()*(pow(10, (7 - (_exponent-3))));
  //resultat = getADC()*(pow(10, (_exponent-3)));

	return resultat;
}
double UDT_TRAMP::getMeasure(uint8_t anzahlMessungen)
{
	double r = 0;
	for (int i = 0; i < anzahlMessungen; i++) {
		r = r + getMeasure();
	}
	r=r/ anzahlMessungen;

	return r;
}

UDT_TRAMP.h

#ifndef _UDT_TRAMPLib_h
#define _UDT_TRAMPLib_h

#include <Wire.h>
#include <Adafruit_ADS1015.h>
#include <Adafruit_MCP23008.h>
#include <math.h> 

#if defined(ARDUINO) && ARDUINO >= 100
	#include "arduino.h"
#else
	#include "WProgram.h"
#endif
class UDT_TRAMP
{
private:

	Adafruit_MCP23008 _mcp;
  Adafruit_ADS1115 _ads;
  
	uint8_t _exponent;
	double _nullabgleich;


public:
  
	void begin();
	void begin(uint8_t adrr_mcp23008);

	bool getOVLD();

	void setRange(uint8_t r);
	uint8_t getRange();
	double getMeasure(); //used to be uint64
	double getMeasure(uint8_t anzahlMessungen);
	void autoRange();

	uint16_t getADC();
	double getADC(uint8_t anahlMessungen);
	double getMiliVolt(uint8_t anzahlMessungen);

	void nullabgleich();


};


#endif

libs.zip (19.6 KB)

Hello,

Try

Adafruit_ADS1115 * _ads;

And add a parameter "adrr_ads1115" in your begin method, then

_ads = new Adafruit_ADS1115(adrr_ads1115);
_ads->begin();

Instead of dynamic allocation, you can also fix it with an initializer list in your constructor (which your UDT_TRAMP class doesn't seem to have at the moment). See Case #3 here: When do we use Initializer List in C++? - GeeksforGeeks

class UDT_TRAMP
{
private:

	Adafruit_MCP23008 _mcp;
  Adafruit_ADS1115 * _ads;
  udt.begin(0,0x48);
  udt2.begin(1,0x49);
void UDT_TRAMP::begin() 
{
	begin(0,0x48);
}
void UDT_TRAMP::begin(uint8_t adrr_mcp23008,uint8_t adrr_ads1115)
{
	_mcp.begin(adrr_mcp23008);
	//_ads.begin();

  _ads = new Adafruit_ADS1115(adrr_ads1115);
  _ads->begin();

	_mcp.pinMode(0, OUTPUT);	//Range 3
	_mcp.pinMode(1, OUTPUT);	//Range 2
	_mcp.pinMode(2, OUTPUT);	//Range 1
	_mcp.pinMode(7, INPUT);		//OVLD

	_mcp.digitalWrite(0, LOW);
	_mcp.digitalWrite(1, LOW);
	_mcp.digitalWrite(2, LOW);
	_exponent = 3;
}

Threw me the following error:
request for member 'readADC_SingleEnded' in '((UDT_TRAMP*)this)->UDT_TRAMP::_ads', which is of pointer type 'Adafruit_ADS1115*' (maybe you meant to use '->' ?)
With my current programming skills i couldnt unerstand what you did but i tried and will continue later with this "dynamic allocation" concept. Thank you for a suggestion.

@gfvalvo
I will study your suggestion and i'll try a solution. I may post further when i fail with your "initializer list constructor" solution. Thank you.

gfvalvo:
Instead of dynamic allocation, you can also fix it with an initializer list in your constructor (which your UDT_TRAMP class doesn't seem to have at the moment). See Case #3 here: When do we use Initializer List in C++? - GeeksforGeeks

HI
Thank you this was the solution. To make it complete here:

UDT_TRAMP udt;
UDT_TRAMP udt2{ADS1015_ADDRESS2};

In UDT_TRAMP.h

#define ADS1015_ADDRESS2 (0x49)
public:  
UDT_TRAMP(uint8_t addr = ADS1015_ADDRESS): _ads{addr}
  {
    // Constructor
  }

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