Hi
I'm trying to create a program that gathers data from some ADC connected and do some averaging on the data.
It's build up around classes containing systeminterface and sensors making a datamodel.
The program is pretty big, but has worked intil implemention of pthreads
I wanted to create a thread maintaining the sensors an averaging a couple of samples.
I ran into the problem about callback, and classes, googled and found a workaround :)
But i'm getting this linker error and I cannot figure out where.
h2SystemInterface.o: In function `H2SystemInterface::H2SystemInterface()':
h2SystemInterface.cpp:(.text+0x665): undefined reference to `H2SystemInterface::threadCaller(void*)'
h2SystemInterface.cpp:(.text+0x66c): undefined reference to `pthread_create'
h2SystemInterface.o: In function `H2SystemInterface::H2SystemInterface()':
h2SystemInterface.cpp:(.text+0x7f5): undefined reference to `H2SystemInterface::threadCaller(void*)'
h2SystemInterface.cpp:(.text+0x7fc): undefined reference to `pthread_create'
collect2: ld returned 1 exit status
make: *** [h2] Error 1
H2SystemInterface.h
class H2SystemInterface
{
private:
//removed to strip it down
double avgDataCurrentSensor[MAX_NUMBER_OF_SENSORS];
double avgDataVoltageSensor[MAX_NUMBER_OF_SENSORS];
double avgDataFlowSensor[MAX_NUMBER_OF_SENSORS];
int latestCurrentData[MAX_NUMBER_OF_SENSORS];
int latestVoltageData[MAX_NUMBER_OF_SENSORS];
int latestFlowData[MAX_NUMBER_OF_SENSORS];
static void *threadCaller(void * ptr); //needed to avoid callback issues
public:
H2SystemInterface();
~H2SystemInterface();
int startProduction(int prodId);
int stopProduction(int prodId);
int getSensorData(int sensorId, int &data);
int createDbRelayIf(const char *serverIp, int port);
void removeDbRelayIf();
void calcSensorData();
};
H2SystemInterface.cpp
H2SystemInterface::H2SystemInterface()
{
electrolyzer = new ProductionSystem(ELECTROLYZER_ID);
fuelcell = new ProductionSystem(FUEL_CELL_ID);
//instantiates all Sensors to NULL
for(int i = 0;i < MAX_NUMBER_OF_SENSORS;i++)
{
currentSensorList[i] = NULL;
voltageSensorList[i] = NULL;
flowSensorList[i] = NULL;
}
currentSensorList[CURRENT_IN_SENSOR_ID] = new CurrentSensor(CURRENT_IN_SENSOR_ID);
currentSensorList[CURRENT_OUT_SENSOR_ID] = new CurrentSensor(CURRENT_OUT_SENSOR_ID);
voltageSensorList[VOLTAGE_IN_SENSOR_ID] = new VoltageSensor(VOLTAGE_IN_SENSOR_ID);
voltageSensorList[VOLTAGE_OUT_SENSOR_ID] = new VoltageSensor(VOLTAGE_OUT_SENSOR_ID);
flowSensorList[FLOW_IN_SENSOR_ID] = new FlowSensor(FLOW_IN_SENSOR_ID);
flowSensorList[FLOW_OUT_SENSOR_ID] = new FlowSensor(FLOW_OUT_SENSOR_ID);
pthread_t AVG;
pthread_create(&AVG, NULL, &H2SystemInterface::threadCaller, this);
/**************************************************************************//**
* Function to work around callback.
*
*
*****************************************************************************/
void *threadCaller(void *ptr)
{
//static_cast<H2SystemInterface*>(ptr)->calcSensorData();
H2SystemInterface *new_object = (H2SystemInterface *)ptr;
new_object->calcSensorData();
return NULL;
}
/**************************************************************************//**
* Private function to gather sensordata.
*
* Never returns anything
*****************************************************************************/
void H2SystemInterface::calcSensorData()
{
int numberOfFetchings = 0;
int result; //stores the lastest errorcode
int currentData[MAX_NUMBER_OF_SENSORS][SAMPLES];
int voltageData[MAX_NUMBER_OF_SENSORS][SAMPLES];
int flowData[MAX_NUMBER_OF_SENSORS][SAMPLES];
int i = 0;
//Fetch data from sensors
for(int sensorId=0; i <=MAX_NUMBER_OF_SENSORS; i++)
{
if (currentSensorList[sensorId])
{
result = currentSensorList[sensorId]->getSensorData(sensorId, latestCurrentData[sensorId]);
//avgDataCurrentSensorList[sensorId] = (int)(data * SCALE_CURRENT);
}
else if (voltageSensorList[sensorId])
{
result = voltageSensorList[sensorId]->getSensorData(sensorId, latestVoltageData[sensorId]);
}
else if (flowSensorList[sensorId])
{
result = flowSensorList[sensorId]->getSensorData(sensorId, latestFlowData[sensorId]);
}
}
//put data into average array
for(int sensorId=0; i <=MAX_NUMBER_OF_SENSORS; i++)
{
if (currentSensorList[sensorId])
{
currentData[sensorId][i] = latestCurrentData[sensorId];
}
else if (voltageSensorList[sensorId])
{
voltageData[sensorId][i] = latestVoltageData[sensorId];
}
else if (flowSensorList[sensorId])
{
flowData[sensorId][i] = latestFlowData[sensorId];
}
if (numberOfFetchings < SAMPLES)
{
numberOfFetchings++;
}
}
//sets the next number in the "wheel buffer"
if (i == 9)
{
i = 0;
}
else
{
i++;
}
//calculate the average
if (numberOfFetchings == SAMPLES) // only if SAMPLES number of samples has been collected we do something
{
for(int sensorId=0; i <=MAX_NUMBER_OF_SENSORS; i++)
{
int temp;
if (currentSensorList[sensorId])
{
temp = 0;
for(int ii=0;ii < SAMPLES; ii++)
{
temp =+ currentData[sensorId][ii];
}
avgDataCurrentSensor[sensorId] = temp / SAMPLES;
}
if (voltageSensorList[sensorId])
{
temp = 0;
for(int ii=0;ii < SAMPLES; ii++)
{
temp =+ voltageData[sensorId][ii];
}
avgDataVoltageSensor[sensorId] = temp / SAMPLES;
}
if (flowSensorList[sensorId])
{
temp = 0;
for(int ii=0;ii < SAMPLES; ii++)
{
temp =+ flowData[sensorId][ii];
}
avgDataFlowSensor[sensorId] = temp / SAMPLES;
}
}
}
}
/**************************************************************************//**
* Public function to a retrieve sensordata.
*
* @param sensorId : Id of the sensor.
*
*
*
* Returns sensordata from the sensor
*
* @retval result : The data held by the sensor, 0 if nonsuccess
*****************************************************************************/
int H2SystemInterface::getSensorData(int sensorId, int &data)
{
int result = -FAILURE;
char buf[10];
if (sensorId >= MAX_NUMBER_OF_SENSORS)
{
//returns here else you'll try to read out of memory when testing
return -UNKNOWN_ID;
}
if (currentSensorList[sensorId])
{
//test start
//result = currentSensorList[sensorId]->getSensorData(sensorId, data);
data = int (avgDataCurrentSensor[MAX_NUMBER_OF_SENSORS]);
result = SUCCESS;
//test slut
data = (int)(data * SCALE_CURRENT);
}
else if (voltageSensorList[sensorId])
{
result = voltageSensorList[sensorId]->getSensorData(sensorId, data);
data = (int)(data * SCALE_VOLTAGE);
}
else if (flowSensorList[sensorId])
{
result = flowSensorList[sensorId]->getSensorData(sensorId, data);
data = (int)(data * SCALE_FLOW);
}
else
{
//sensor didn't exist return
result = -UNKNOWN_ID;
}
// Check if data should also be sent to database relay server.
if (dbRelayIfCreated)
{
printf("Sending packet: %d %d\n", sensorId, data);
sprintf(buf, "%d %d\n", sensorId, data);
if (sendto(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&dbRelayAddress, sizeof(dbRelayAddress)) == -1)
{
// The provided errno will be interpretted and appended.
perror("sendto()");
return -SEND_FAILED;
}
}
return result;
}