I'm working on a project where I have to deal with several sensors, and print out error values to a textfile. Currently I'm doing random generators, to just generate some dummy values. The thing here is that the same errors are stored into the textfile, since the code is running fast and in loop. So I'm thinking of making a timer to handle the last stored data for the current sensor. I'm not sure if this is a good idea, since it doesn't sound easy, because in the end I will have to handle about 30 different sensors. Any idea how I can implement such a logic into my code?
struct arg_struct{ //store the these data into the textfile
char *sensorname;
double sensorvalue;
int faultcode;
};
//insert the data into the textfile with the arguments from detect_error
void *write_sens_error(void *arguments){
struct arg_struct *args = arguments;
struct tm *local;
time_t t;
t = time(NULL);
local = localtime(&t);
FILE *fp;
fp = fopen("/home/sal/Desktop/sensors.txt","a");
fprintf(fp, "%s %s %f %s %d %s %s", args -> sensorname, "\t",args -> sensorvalue, "\t", args -> faultcode,"\t",asctime(local));
fclose(fp);
pthread_exit(NULL);
return NULL;
}
//create a new thread, so the second thread will handle the errorvalue storage
void detect_error(char *sensorname, double sensorvalue, int faultcode){
pthread_t thread_error1;
struct arg_struct args;
args.sensorname = malloc(7);
strcpy(args.sensorname, sensorname);
args.sensorvalue = sensorvalue;
args.faultcode = faultcode;
pthread_create(&thread_error1, NULL, &write_sens_error, (void *)&args);
pthread_join(thread_error1, NULL);
free(args.sensorname);
}
//generate random values and check for error
void rand_temperature_sensor(double EXTS[8], int FTS, int CTS, int OTS){
int i;
for (i = 0; i < 8; i++){
EXTS[i] = rand() % 10 + 820;
if(EXTS[i]>800){
char name[6];
sprintf(name, "EXTS%d", i+1);
detect_error(name,EXTS[i],((EXTS[i]>850) ? 2 : 1));
}
}
printf("%s,%f,%f,%f,%f,%f,%f,%f,%f\n","Temp",EXTS[0],EXTS[1],EXTS[2],EXTS[3],EXTS[4],EXTS[5],EXTS[6],EXTS[7];
}
And here is a snippet of the log this code is generating. As seen from the log, the same sensors are stored three times in one second. That is what I want to avoid, so the error from sensors are only stored after let's say 5 seconds after the previous error catch.
EXTS0 823.000000 1 Tue Apr 28 23:43:57 2015
EXTS1 820.000000 1 Tue Apr 28 23:43:57 2015
EXTS2 826.000000 1 Tue Apr 28 23:43:57 2015
EXTS3 827.000000 1 Tue Apr 28 23:43:57 2015
EXTS4 829.000000 1 Tue Apr 28 23:43:57 2015
EXTS5 826.000000 1 Tue Apr 28 23:43:57 2015
EXTS6 820.000000 1 Tue Apr 28 23:43:57 2015
EXTS7 823.000000 1 Tue Apr 28 23:43:57 2015
EXTS0 827.000000 1 Tue Apr 28 23:43:57 2015
EXTS1 828.000000 1 Tue Apr 28 23:43:57 2015
EXTS2 822.000000 1 Tue Apr 28 23:43:57 2015
EXTS3 826.000000 1 Tue Apr 28 23:43:57 2015
EXTS4 822.000000 1 Tue Apr 28 23:43:57 2015
EXTS5 822.000000 1 Tue Apr 28 23:43:57 2015
EXTS6 829.000000 1 Tue Apr 28 23:43:57 2015
EXTS7 826.000000 1 Tue Apr 28 23:43:57 2015
EXTS0 821.000000 1 Tue Apr 28 23:43:57 2015
EXTS1 823.000000 1 Tue Apr 28 23:43:57 2015
EXTS2 822.000000 1 Tue Apr 28 23:43:57 2015
EXTS3 824.000000 1 Tue Apr 28 23:43:57 2015
EXTS4 826.000000 1 Tue Apr 28 23:43:57 2015
EXTS5 826.000000 1 Tue Apr 28 23:43:57 2015
EXTS6 821.000000 1 Tue Apr 28 23:43:57 2015
EXTS7 824.000000 1 Tue Apr 28 23:43:57 2015
I really not hope this question was confusing. Please let me know if I have to clear out something. The full code is pasted here.
I suggest you add a "pthread_mutex_t" to handle file writing:
1. declare mutex_writing as global variable
2. is_writing[EXTS_LIMIT] as global variable //for each sensor:boolean indicating writing status
3. writingtime[EXTS_LIMIT]//store the last writing time for a given sensor
4. index //added to arg_struct in order to identify the sensor and modify is_writing
5. at writing time lock mutex_writing then unlock
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#define EXTS_limit 1000
#define CPS_limit 200
#define MAF1_limit 700
#define MAF2_limit 130
#define KS_limit 20
#define FTS_limit 100
#define CTS_limit 105
#define OTS_limit 100
#define OPS_limit 11
#define FPS_limit 11
#define MAP_limit 5
/****/
#define MILLISECONDES 1000
#define FIVESECS 5000*MILLISECONDES
pthread_mutex_t mutex_writing = PTHREAD_MUTEX_INITIALIZER;
int is_writing[EXTS_limit];
clock_t writingtime[EXTS_limit];
/***/
struct arg_struct{
char *sensorname;
double sensorvalue;
int faultcode;
int index;
};
void *write_sens_error(void *arguments)
{
pthread_mutex_lock(&mutex_writing);
struct arg_struct *args = arguments;
struct tm *local;
time_t t;
t = time(NULL);
local = localtime(&t);
FILE *fp;
fp = fopen("/home/sal/Desktop/sensor_data.txt","a"); //PATH TO THE TEXTFILE.
fprintf(fp, "%s %s %f %s %d %s %s", args -> sensorname, "\t",args -> sensorvalue, "\t", args -> faultcode,"\t",asctime(local));
fclose(fp);
is_writing[args->index]=0;
pthread_mutex_unlock(&mutex_writing);
pthread_exit(NULL);
return NULL;
}
void detect_error(char *sensorname, double sensorvalue, int faultcode, int index){
pthread_t thread_error1;
struct arg_struct args;
args.sensorname = malloc(7);
strcpy(args.sensorname, sensorname);
args.sensorvalue = sensorvalue;
args.faultcode = faultcode;
args.index=index;
clock_t t=clock();
if(is_writing[index]==0 && ((float)t-(float)writingtime[index])>FIVESECS)
{
is_writing[index]=1;
writingtime[index]=clock();
pthread_create(&thread_error1, NULL, &write_sens_error, (void *)&args);
pthread_join(thread_error1, NULL);
}
free(args.sensorname);
}
void rand_temperature_sensor(double EXTS[8], int FTS, int CTS, int OTS){
int i;
for (i = 0; i < 8; i++){
EXTS[i] = rand() % 10 + 820;
if(EXTS[i]>EXTS_limit){
char name[6];
sprintf(name, "EXTS%d", i+1);
detect_error(name,EXTS[i],((EXTS[i]>1050) ? 2 : 1),i);
}
}
FTS = rand() % 30 + 91;
if(FTS > FTS_limit) detect_error("FTS",FTS,((FTS>120) ? 2 : 1),8);
CTS = rand() % 3 + 90;
if(CTS > CTS_limit) detect_error("CTS",CTS,((CTS>110) ? 2 : 1),9);
OTS = rand() % 30 + 91;
if(OTS > OTS_limit) detect_error("OTS",OTS,((OTS>120) ? 2 : 1),10);
printf("%s,%f,%f,%f,%f,%f,%f,%f,%f,%d,%d,%d\n","Temp",EXTS[0],EXTS[1],EXTS[2],EXTS[3],EXTS[4],EXTS[5],EXTS[6],EXTS[7],FTS,CTS,OTS);
}
void rand_CPS_LS_KS_ACC(int CPS[8], int LS[2], int KS[2],int TS[2]){
int i;
for (i = 0; i < 8; i++){
CPS[i] = rand() % 2 + 20;
}
for(i=0; i < 2; i++){
LS[i] = rand() % 3 + 30;
KS[i] = rand() % 3 + 40;
TS[i] = rand() % 40 + 100;
}
printf("%s,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n","CPS_LS_KS_TS", CPS[0],CPS[1],CPS[2],CPS[3],CPS[4],CPS[5],CPS[6],CPS[7],LS[0],LS[1],KS[0],KS[1],TS[0],TS[1]);
}
void rand_CAM_ACC(int CAM[4], int ACC_[2]){
int i;
for (i = 0; i < 4; i++){
CAM[i] = rand() % 7 + 10;
}
ACC_[1] = rand() % 3 + 20;
ACC_[2] = rand() % 1 + 1;
printf("%s,%d,%d,%d,%d,%d,%d\n","CAM_ACC", CAM[0],CAM[1],CAM[2],CAM[3],ACC_[1],ACC_[2]);
}
void rand_MAP_MAF_FFS_CRANK(int dash_kmt, int MAP, int MAF, int FFS, int CRANK, int OPS, int FPS){
dash_kmt = rand() % 6 + 60;
MAP = rand() % 10 + 30;
MAF = rand() % 5 + 20;
FFS = rand() % 2 + 20;
CRANK = rand() % 3 + 2;
OPS = rand() % 3 + 2;
FPS = 25;
printf("%s,%d,%d,%d,%d,%d,%d,%d\n","dash", dash_kmt,MAP,MAF,FFS,CRANK,OPS,FPS);
}
int main() {
/*Init global variables*/
int count=0;
for(count=0;count<EXTS_limit;count++)
{
is_writing[count]=0;
writingtime[count]=0;
}
/****/
int i;
setbuf(stdout, NULL); // Disable output buffering.
//setbuf(stdin, NULL); //Disable input buffering
srand ( time(NULL) ); //generate different random values
double EXTS[8]; int CPS[8],CAM[4],LS[2],KS[2],TS[2],ACC_[2],FTS, CTS, OTS;
int dash_kmt,MAP,MAF,FFS,CRANK,OPS,FPS;
int state = 1;
while(state == 1){
rand_temperature_sensor(EXTS,FTS,CTS,OTS);
rand_CPS_LS_KS_ACC(CPS,LS,KS,TS);
rand_CAM_ACC(CAM,ACC_);
rand_MAP_MAF_FFS_CRANK(dash_kmt,MAP,MAF,FFS,CRANK,OPS,FPS);
usleep(600);
}
//pthread_join(thread_error1, NULL);
return 0;
}