您好我在使用以下脚本连续将数据记录到.csv文件时出现问题
int ddm(void)
{
// 96 Temp MSB, 97 Temp LSB, 98 Vcc MSB, 99 Vcc LSB
// 100 TX_BIA MSB, 101 TX_BIA LSB,
// 102 TX MSB, 103 TX LSB, 104 RX MSB, 105 RX LSB
FILE *focat;
float temperature, vcc, tx_bias, optical_tx, optical_rx, RAW_tx, RAW_rx;
char temp[10], vccc[10], txbi[10], optx[10], oprx[10], rwtx[30], rwrx[30];
int i;
//Open (or create) the csv file and write the heading row
focat=fopen("fcatdata.csv", "w");
if(focat == NULL)
{
printf("error openining file\n");
exit(1);
}
fprintf(focat,"Temp, Vcc, Tx_Bias, Tx, Rx, RAWTx, RAWRx\n");
fclose(focat);
focat=fopen("fcatdata.csv", "a+");
i=0;
//start infinite loop
for(;;)
{
if(!read_eeprom(0x51));
else exit(EXIT_FAILURE);
i=i+1;
//Taking MSB and LSB data and converting
temperature = (A51[96]+(float) A51[97]/256);
vcc = (float)(A51[98]<<8 | A51[99]) * 0.0001;
tx_bias = (float)(A51[100]<<8 | A51[101]) * 0.002;
optical_tx = 10 * log10((float)(A51[102]<<8 | A51[103]) * 0.0001);
optical_rx = 10 * log10((float)(A51[104]<<8 | A51[105]) * 0.0001);
RAW_tx = ((float)(A51[102]<<8 | A51[103]) * 0.0001);
RAW_rx = ((float)(A51[104]<<8 | A51[105]) * 0.0001);
//Display Diagnostics Monitoring Data in Terminal
printf ("SFP Temperature = %4.4fC\n", temperature);
printf ("Vcc, Internal supply = %4.4fV\n", vcc);
printf ("TX bias current = %4.4fmA\n", tx_bias);
printf ("Tx, Optical Power = %4.4f dBm", optical_tx);
printf (", %6.6f mW\n", RAW_tx);
printf ("Rx, Optical Power = %4.4f dBm", optical_rx);
printf (", %6.6f mW\n", RAW_rx);
printf ("iteration %d \n", i);
//Change the integers into strings for appending to file
sprintf(temp, "%4.4f", temperature);
sprintf(vccc, "%4.4f", vcc);
sprintf(txbi, "%4.4f", tx_bias);
sprintf(optx, "%4.4f", optical_tx);
sprintf(oprx, "%4.4f", optical_rx);
sprintf(rwtx, "%6.6f", RAW_tx);
sprintf(rwrx, "%6.6f", RAW_rx);
//Appends DDM Data into a new row of a csv file
//focat=fopen("fcatdata.csv", "a");
fprintf(focat, "%s,%s,%s,%s,%s,%s,%s\n",temp,vccc,txbi,optx,oprx,rwtx,rwrx);
//fclose(focat);
}
fclose(focat);
return 0;
}
当我设置代码以在进入循环之前打开.csv文件时,我在第1020次迭代时收到以下错误:
SFP温度= 31.9258C
Vcc,内部供应= 3.1374V
TX偏置电流= 8.0540mA
Tx,光功率= -1.8006 dBm,0.660600 mW
Rx,光功率= -40.0000 dBm,0.000100 mW
无法打开I2C设备:打开的文件太多
当我将注释更改为代码底部时,其内容如下:
//Appends DDM Data into a new row of a csv file
focat=fopen("fcatdata.csv", "a");
fprintf(focat, "%s,%s,%s,%s,%s,%s,%s\n",temp,vccc,txbi,optx,oprx,rwtx,rwrx);
fclose(focat);
然后在循环之前注释掉文件打开,随后在1021st循环迭代中出现以下错误:
SFP温度= 31.8906C
Vcc,内部电源= 3.1372V
TX偏置电流= 8.0620mA
Tx,光功率= -1.8006 dBm,0.660600 mW
Rx,光功率= -40.0000 dBm,0.000100 mW
细分错误
我认为这与ulimit - n
显示1024
的结果有某种关系,但我需要能够连续运行这个脚本一周,因此更改ulimit不是解决问题的真正解决方案。 / p>
我通过制作一个无休止循环的脚本并将整数i附加到csv文件并且远远超过1021行数据来测试这个理论。这一直困扰我一个星期。任何帮助表示赞赏。
批评格式等欢迎,我不经常在这里(或任何地方)发布
int read_eeprom(unsigned char address)
{
int xio,i,fd1;
xio = wiringPiI2CSetup (address);
if (xio < 0)
{
fprintf (stderr, "xio: Can't initialise I2C: %s\n",
strerror (errno));
return 1;
}
for(i=0; i <128; i++)
{
fd1 = wiringPiI2CReadReg8 (xio,i);
if (address == 0x50)
{
A50[i] = fd1;
}
else
{
A51[i] = fd1;
}
if (fd1 <0)
{
fprintf (stderr, "xio: Can't read i2c address 0x%x: %s\n",
address, strerror (errno));
return 1;
}
}
return 0;
}
编辑1:澄清了文件打开和关闭的两种情况
修改2:添加了有关read_eeprom
修改3 :在close(fp);
read_eeprom
解决
编辑4 在close(xio);
末尾添加read_eeprom
,正确解决 - 致@JohnH
答案 0 :(得分:0)
您只需在此过程中拨打wiringPiI2CSetup()
一次。通过为xio
使用静态变量可以实现这一点,这样它就可以保留调用之间的值:
int read_eeprom(unsigned char address)
{
int i, value;
static int xio = -1;
if( xio == -1 ) {
xio = wiringPiI2CSetup (address);
if (xio < 0) {
fprintf (stderr, "xio: Can't initialise I2C: %s\n",
strerror (errno));
return 1;
}
}
for(i=0; i <128; i++) {
value = wiringPiI2CReadReg8 (xio,i);
if( value > 0 ) {
if (address == 0x50)
A50[i] = value;
else
A51[i] = value;
}
else {
fprintf (stderr, "xio: Can't read i2c address 0x%x: %s\n",
address, strerror (errno));
return 1;
}
}
return 0;
}
另一种方法是每次进入路由时调用wiringPiI2CSetup()
,然后在每次调用之间关闭它:
int read_eeprom(unsigned char address)
{
int xio, i, value;
xio = wiringPiI2CSetup (address);
if (xio < 0) {
fprintf (stderr, "xio: Can't initialise I2C: %s\n",
strerror (errno));
return 1;
}
for(i=0; i <128; i++) {
value = wiringPiI2CReadReg8 (xio,i);
if( value > 0 ) {
if (address == 0x50)
A50[i] = value;
else
A51[i] = value;
}
else {
fprintf (stderr, "xio: Can't read i2c address 0x%x: %s\n",
address, strerror (errno));
close(xio);
return 1;
}
}
close(xio);
return 0;
}
答案 1 :(得分:0)
通过在close(fd1);
末尾添加read_eeprom
解决问题,如下所示:
int read_eeprom(unsigned char address)
{
int xio,i,fd1;
xio = wiringPiI2CSetup (address);
if (xio < 0)
{
fprintf (stderr, "xio: Can't initialise I2C: %s\n",
strerror (errno));
return 1;
}
//loop through addresses and extract data from eeprom
for(i=0; i <128; i++)
{
fd1 = wiringPiI2CReadReg8 (xio,i);
if (address == 0x50)
{
A50[i] = fd1;
}
else
{
A51[i] = fd1;
}
if (fd1 <0)
{
fprintf (stderr, "xio: Can't read i2c address 0x%x: %s\n",
address, strerror (errno));
return 1;
}
}
//close fd1 to prevent segfault and "too many files open" errors
close(fd1);
return 0;
}
致@Mat确认 FD泄漏