I need your help. I want to create an array that is going to be populated with functions and those fuctions will take some arguments (each fuction may accept different argumants).
For example I have two function
int example1(int arg1);
float example2(int arg2);
I want to be able to populate the array base for example an IF statement
I've created a sketch that identifies the type of sensors that are connected each time on the board (I'm using ESP32 programming through Arduino IDE) ig ligth sensor, temperature sensor, oxygen etc.
So, when I run the sketch then are populated two arrays, the first one contains the sensor type and the second one the measurents units corresponding to each sensor type.
I want to populate a third array with functions corresponding to each sensor type..
So, when the code executes I want to be populated three array with sensor types,units and their associated functions.
This my sketch so far in case that it helps
[code]
#include <ArduinoJson.h>
#include "Nested_Json_example.h"
//*******************************************Arrays to store sensors data************************************
// LuxMeter -> pin33
// DHT22 Sensor -> pin 32
// SHT20 Sensor -> address 0x40 (this addres is given by default fromt the manufactures
char* SensorType[8] = {}; //Array that is populated with the type of sensors that are connected on the board
byte SensorsPinArray[] = {33, 32 , 0x40}; //Array that stores the pins and address that the sensors by default are connected
char *Units[16] = {}; //Array that is populated with sensors' units ,"Lux", "C", "%", "mg/L", "ppm"
//***********************************************************************************************************
void setup() {
Serial.begin(115200);
dht.begin();
sht20.initSHT20();
delay(100);
sht20.checkSHT20();
}
//***********************************************************************************************************
void loop() {
int pin = 0; //This is the first element/index=0 of SensorsPinArray
int sensorCounter = 0; // COUNT THE SENSORS CONNECTED ON THE MODULE (ESP32)
//***************************************CHECK FOR LUMINANCE SENSOR*****************************************
if (readLuminance(lux) > 0) {
identifySensor(SensorsPinArray[pin], sensorCounter);
Serial.print(SensorType[sensorCounter]); Serial.print(": "); Serial.print(readLuminance(lux)); Serial.print(" "); Serial.println(Units[sensorCounter]);
sensorCounter++;
} else if (readLuminance(lux) == 0) {
Serial.print("Lux Sensor sais: Sensor it's either broken or it's disconnected"); Serial.print(": "); Serial.println(readLuminance(lux));
}
pin++;
//***************************************CHECK FOR DHT SENSOR*****************************************
//INSIDE HERE AD THE IF STATEMENT FOR DHT22 SENSOR
pin++;
//***************************************CHECK FOR SHT20 SENSORS*****************************************
if (sht20.readTemperature() < 80 && sht20.readHumidity() < 120) {
identifySensor(SensorsPinArray[pin], sensorCounter);
Serial.print(SensorType[sensorCounter]); Serial.print(": "); Serial.print(sht20.readTemperature()); Serial.print(" "); Serial.println(Units[sensorCounter]);
Serial.print(SensorType[sensorCounter]); Serial.print(": "); Serial.print(sht20.readHumidity()); Serial.print(" "); Serial.println(Units[sensorCounter + 1]);
sensorCounter++;
} else {
Serial.print("SHT20 Sensor sais: Sensor it's either broken or it's disconnected"); Serial.print(": "); Serial.println(sht20.readTemperature());
Serial.print("SHT20 Sensor sais: Sensor it's either broken or it's disconnected"); Serial.print(": "); Serial.println(sht20.readHumidity());
}
pin++;
//AFTER THE ARRAY HAS BEEN POPULATED WITH THE SENSORS PRINT A MESSAGE WITH THE AMOUNT AND TYPE OF SENSORS
Serial.println();
Serial.println("Connected Sensors");
for (int i = 0; i < sensorCounter; i++) {
Serial.print(i + 1); Serial.print(". "); Serial.println(SensorType[i]);
}
Serial.println("");
delay(1000);
//***********************************************************************************************************
//DYNAMIC JSON OBJECT
StaticJsonDocument<300> doc;
for (int i = 0; i < sensorCounter; i++) {
JsonObject obj = doc.createNestedObject();
if (SensorType[i] == "DHT20" || SensorType[i] == "SHT22") {
obj["Label"] = SensorType[i] ;
obj["Reading1"] = "Reading1" ;
obj["Units1"] = Units[i];
obj["Reading2"] = "Reading2" ;
obj["Units2"] = Units[i+1];
} else {
obj["Label"] = SensorType[i] ;
obj["Reading"] = "Reading" ;
obj["Units"] = Units[i];
}
serializeJson(obj, Serial);
Serial.println();
}
Serial.println();
delay(5000);
}
//********************************************FUNCTIONS******************************************
//******************************SWITCH CASE TO IDENTIFY SENSOR TYPE******************************
int identifySensor(int pin, int sensorCounter) {
switch (pin) {
case 33:
SensorType[sensorCounter] = "LuxMeter";
Units[sensorCounter] = "Lux";
break;
case 32:
SensorType[sensorCounter] = "DHT20";
Units[sensorCounter] = "C";
Units[sensorCounter + 1] = "%";
break;
case 0x40:
SensorType[sensorCounter] = "SHT22";
Units[sensorCounter] = "C";
Units[sensorCounter + 1] = "%";
break;
case 30:
SensorType[sensorCounter] = "O2";
Units[sensorCounter] = "mg/L";
break;
}
}
As pointed out, if you want to put the function pointers in to an array, the functions must all have the same signature. You could force that by defining all of them the same way and have the individual ones only use the arguments they need. Then, I’d wrap everything up into a struct to keep the sensor information together. Something like this:
Nikosant03:
The final purpose is to publish JSON messages based on the aforementioned populated arrays
You do realize that a pointer to a function is just the physical memory location within your sketch where the code for the function is stored? Outside of this specific sketch, it will only be a number with no indication of which particular function it points to.
gfvalvo:
You could force that by defining all of them the same way and have the individual ones only use the arguments they need.
How about using a void pointer for the argument? That way you can pass anything to the functions (simple types, structs, ...); each function knows what to do with the argument.
Simple example
// function prototypes
bool funcWithFloat(void *params);
bool funcWithInt(void *params);
// array of function pointers
bool (*fp[])(void*)
{
funcWithFloat,
funcWithInt,
};
void setup()
{
Serial.begin(57600);
float pi = 3.14;
fp[0](&pi);
}
void loop()
{
static int cnt = 0;
fp[1](&cnt);
cnt++;
delay(500);
}
bool funcWithFloat(void *params)
{
float *f = (float*)params;
Serial.print("Printing a float: ");
Serial.println(*f);
return true;
}
bool funcWithInt(void *params)
{
int *i = (int*)params;
Serial.print("Printing an integer: ");
Serial.println(*i);
return true;
}
sterretje:
How about using a void pointer for the argument? That way you can pass anything to the functions (simple types, structs, ...); each function knows what to do with the argument.
That would undermine the entire type system. I think casting to void * like that indicates bad design.
I'm pretty sure there's a better way to achieve what OP wants to do.
Functions that operate on different types should not be in the same array.
It's too easy to call the wrong function with the wrong type. The code will have undefined behavior, and the compiler won't even tell you where it went wrong.
Even if you don't agree that they shouldn't be in the same array, there are better options, like std:: variant if you have access to the STL, or a tagged union. The compiler still can't really help you, but at least you can check the type at runtime.
Nikosant03:
What is I have different data types function, fo example int and float?
PieterP:
That would undermine the entire type system.
[...]
Functions that operate on different types should not be in the same array.
It's too easy to call the wrong function with the wrong type. The code will have undefined behavior, and the compiler won't even tell you where it went wrong.
Even if you don't agree that they shouldn't be in the same array, there are better options, like std:: variant if you have access to the STL, or a tagged union. The compiler still can't really help you, but at least you can check the type at runtime.
Nikosant03:
What is I have different data types function, fo example int and float?
gfvalvo:
As pointed out, if you want to put the function pointers in to an array, the functions must all have the same signature. You could force that by defining all of them the same way and have the individual ones only use the arguments they need.