|
|
#define LOG_TAG "main"
|
|
|
#include "main.h"
|
|
|
#include "elog.h"
|
|
|
#include "modbus_rtu_slave.h"
|
|
|
#include "sjzd.h"
|
|
|
#include <time.h>
|
|
|
#include "iec61850_process.h"
|
|
|
|
|
|
#define APP_VERSION "SV01.003"
|
|
|
#define DEVICE_NUM 3
|
|
|
|
|
|
|
|
|
|
|
|
static uint8_t START_SMP_HOUR=1; //北京时间0点开始采样
|
|
|
static uint8_t SMP_INV= 60;//60分钟采样一次
|
|
|
static int doit=0;
|
|
|
uint8_t dev_par[18];
|
|
|
uint16_t sjzd_modbus_data[MODBUS_REGS_NUM];
|
|
|
|
|
|
#define SJZD_PORT "RS485_2"
|
|
|
#define SJZD_BAUD "38400"
|
|
|
#define SJZD_PARITY "no"
|
|
|
#define Modbus_Enable 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ctrlCfun(int i)
|
|
|
{
|
|
|
doit = 1;
|
|
|
}
|
|
|
|
|
|
int log_init(void)
|
|
|
{
|
|
|
/* close printf buffer */
|
|
|
setbuf(stdout,NULL);
|
|
|
/* initialize EasyLogger */
|
|
|
elog_init();
|
|
|
/* set EasyLogger log format */
|
|
|
elog_set_fmt(ELOG_LVL_ASSERT, ELOG_FMT_ALL);//设置assert级别的输出内容格式
|
|
|
elog_set_fmt(ELOG_LVL_ERROR, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);//错误日志输出消息级别,标签,时间
|
|
|
// elog_set_fmt(ELOG_LVL_WARN, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);//警告日志输出格式设置
|
|
|
// elog_set_fmt(ELOG_LVL_INFO, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
|
|
|
// elog_set_fmt(ELOG_LVL_DEBUG, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
|
|
|
// elog_set_fmt(ELOG_LVL_VERBOSE, ELOG_FMT_ALL & ~ELOG_FMT_FUNC);
|
|
|
#ifdef ELOG_COLOR_ENABLE
|
|
|
elog_set_text_color_enabled(true);
|
|
|
#endif
|
|
|
/* start EasyLogger */
|
|
|
elog_start();
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
char *make_file_name(uint32_t sn,uint8_t addr)
|
|
|
{
|
|
|
static char data_file_name[128];
|
|
|
struct tm *p;
|
|
|
memset(data_file_name,0,sizeof(data_file_name));
|
|
|
p=localtime((time_t *)&sn);
|
|
|
sprintf(data_file_name,"/home/debian/my_task/data/%04d%02d%02d%02d%02d%02d_%d.dat",p->tm_year+1900,p->tm_mon+1,p->tm_mday,p->tm_hour,p->tm_min,p->tm_sec,addr);
|
|
|
return data_file_name;
|
|
|
}
|
|
|
|
|
|
char *make_file_name_all(uint32_t sn)
|
|
|
{
|
|
|
static char data_file_name[64];
|
|
|
struct tm *p;
|
|
|
memset(data_file_name,0,sizeof(data_file_name));
|
|
|
p=localtime((time_t *)&sn);
|
|
|
sprintf(data_file_name,"/home/debian/my_task/comtrade/days_7/A500_260_08_%04d%02d%02d%02d%02d%02d.dat",p->tm_year+1900,p->tm_mon+1,p->tm_mday,p->tm_hour,p->tm_min,p->tm_sec);
|
|
|
return data_file_name;
|
|
|
}
|
|
|
char *make_file_name_temp(uint32_t sn)
|
|
|
{
|
|
|
static char data_file_name[64];
|
|
|
struct tm *p;
|
|
|
memset(data_file_name,0,sizeof(data_file_name));
|
|
|
p=localtime((time_t *)&sn);
|
|
|
sprintf(data_file_name,"/home/debian/my_task/comtrade/temp/A500_260_08_%04d%02d%02d%02d%02d%02d.dat",p->tm_year+1900,p->tm_mon+1,p->tm_mday,p->tm_hour,p->tm_min,p->tm_sec);
|
|
|
return data_file_name;
|
|
|
}
|
|
|
//1.串口轮询线程,
|
|
|
//2.通讯协议AA+55+addr(2byte)+data_len(2bytes)+data(n)+crc_val+##
|
|
|
int main(int argc,char **args)
|
|
|
{
|
|
|
int32_t ret;
|
|
|
SLAVE_REG_TYPE slave_regs[DEVICE_NUM];
|
|
|
uint32_t tmp_reg;
|
|
|
uint8_t rlt,slave_addr;
|
|
|
int32_t i;
|
|
|
time_t now;
|
|
|
struct tm *p;
|
|
|
uint32_t last_smp_time=0;
|
|
|
char *curr_file;
|
|
|
char first_smp=0;
|
|
|
char relay_satus=0;
|
|
|
char dev_fault=0;
|
|
|
|
|
|
char start_smp_flag=0;
|
|
|
uint8_t *all_device_file;
|
|
|
uint8_t *effective_channel_file;
|
|
|
uint8_t *buf;
|
|
|
char sensor_err=0;
|
|
|
char START_SMP_HOUR_UTC=0;
|
|
|
char HOUR_UTC=0;
|
|
|
|
|
|
//uint8_t effective_channel_file[14*20*1024];
|
|
|
//memset(buf_test,0x11,24*20*1024);
|
|
|
//memset(all_device_file,0xFF,DEVICE_NUM*160*1024);
|
|
|
signal(SIGINT,ctrlCfun);
|
|
|
|
|
|
log_init();
|
|
|
|
|
|
elog_raw("Application Version:%s\r\n",APP_VERSION);
|
|
|
log_e("Application restart!");
|
|
|
|
|
|
//if(read_dev_cfg(&dev_cfg)!=0)
|
|
|
//{
|
|
|
// log_e("load device config failed");
|
|
|
//}
|
|
|
start_scl_mem();
|
|
|
if(sjzd_master_init(SJZD_PORT,SJZD_BAUD,SJZD_PARITY)!=0)
|
|
|
{
|
|
|
log_e("sjzd master init failed");
|
|
|
return -1;
|
|
|
}
|
|
|
relay_init();
|
|
|
//modbus_rtu_slave_init();//初始化modbus
|
|
|
memset(sjzd_modbus_data,0,sizeof(sjzd_modbus_data));
|
|
|
sjzd_modbus_data[0]=TYPE_MONITOR;
|
|
|
|
|
|
//iec61850_rx_init();//启动61850接收线程
|
|
|
//重启应用时加载配置文件,更新所有参数
|
|
|
if(Modbus_Enable==0)
|
|
|
{
|
|
|
ret=load_from_file("/home/debian/my_task/scl_srvr/device_par.dat",0 ,dev_par,18*sizeof(uint8_t));
|
|
|
if(ret>0)
|
|
|
{
|
|
|
START_SMP_HOUR=dev_par[2];
|
|
|
SMP_INV=dev_par[1]*60;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
START_SMP_HOUR=8;
|
|
|
SMP_INV=1*60;
|
|
|
log_e("load device config failed");
|
|
|
}
|
|
|
|
|
|
printf("SAMP_FRE=%d\n",dev_par[0]);
|
|
|
printf("SAMP_INTERVAL=%d\n",dev_par[1]);
|
|
|
printf("START_TIME=%d\n",dev_par[2]);
|
|
|
printf("SMP_ENABLE=%d\n",dev_par[3]);
|
|
|
printf("NOISE_CHANNEL_NUM=%d,NEU_CHANNEL_NUM=%d\n",dev_par[4],dev_par[5]);
|
|
|
for(i=0;i<(DEVICE_NUM-1)*6;i++)
|
|
|
printf("ACC_SENSOR_%d=%d\n",i,dev_par[i+6]);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
printf("SAMP_FRE=%d\n",sjzd_modbus_data[221]);
|
|
|
printf("SAMP_INTERVAL=%d\n",sjzd_modbus_data[222]);
|
|
|
printf("START_TIME=%d\n",sjzd_modbus_data[223]);
|
|
|
printf("SMP_ENABLE=%d\n",sjzd_modbus_data[224]);
|
|
|
printf("NOISE_CHANNEL_NUM=%d,NEU_CHANNEL_NUM=%d\n",sjzd_modbus_data[225],sjzd_modbus_data[226]);
|
|
|
for(i=0;i<(DEVICE_NUM-1)*6;i++)
|
|
|
printf("ACC_SENSOR_%d=%d\n",i,sjzd_modbus_data[i+227]);
|
|
|
|
|
|
START_SMP_HOUR=sjzd_modbus_data[223];
|
|
|
SMP_INV=sjzd_modbus_data[222]*60;
|
|
|
|
|
|
/* code */
|
|
|
}
|
|
|
|
|
|
relay_on();
|
|
|
|
|
|
now=time(NULL);
|
|
|
p=localtime((time_t *)&now);
|
|
|
|
|
|
|
|
|
if(p->tm_hour<START_SMP_HOUR)//START_SMP_HOUR UTC
|
|
|
{
|
|
|
last_smp_time=now-(now%86400)+(START_SMP_HOUR)*3600-(((START_SMP_HOUR)*3600-(now%86400))/(SMP_INV*60))*(SMP_INV*60);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
last_smp_time=now-(now%86400)+((START_SMP_HOUR)*3600)+(((now%86400)-(START_SMP_HOUR)*3600)/(SMP_INV*60))*(SMP_INV*60);
|
|
|
}
|
|
|
|
|
|
while(!doit)
|
|
|
{
|
|
|
usleep(5000*1000);
|
|
|
now=time(NULL);
|
|
|
// 定时读配置文件,更新采样间隔
|
|
|
if(Modbus_Enable==0)
|
|
|
{
|
|
|
ret=load_from_file("/home/debian/my_task/scl_srvr/device_par.dat",0 ,dev_par,18*sizeof(uint8_t));
|
|
|
if(ret>0)
|
|
|
{
|
|
|
SMP_INV=dev_par[1]*60;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
SMP_INV=1;
|
|
|
log_e("load device config failed");
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
START_SMP_HOUR=sjzd_modbus_data[223];
|
|
|
SMP_INV=sjzd_modbus_data[222]*60;
|
|
|
|
|
|
/* code */
|
|
|
}
|
|
|
|
|
|
//SMP_INV = 15; // 测试使用
|
|
|
//发送心跳包检测通讯是否正常
|
|
|
heartbeat(DEVICE_NUM);
|
|
|
|
|
|
//判断是否需要启动采样
|
|
|
if ((first_smp?1:(p->tm_hour >= START_SMP_HOUR)) & dev_par[3])//第一次到定时时间且使能
|
|
|
//if( (p->tm_hour >= START_SMP_HOUR)&&(first_smp == 0) || (first_smp == 1))
|
|
|
{
|
|
|
//log_d("now-last_smp_time=%d",now-last_smp_time);
|
|
|
//if(now>=(last_smp_time+SMP_INV*60-4*60)) //SMP_INV 时间间隔
|
|
|
if(now>=(last_smp_time+SMP_INV*60-2*60)) //SMP_INV 时间间隔 提前给传感器上电(120s)应该在这里计时
|
|
|
{
|
|
|
//log_d("now-last_smp_time=%d",now-last_smp_time);
|
|
|
relay_off(); // 闭合继电器给传感器上电
|
|
|
//if(now>=(last_smp_time+SMP_INV*60-2*60)) //传感器通电120s后,开始采样
|
|
|
if(now>=(last_smp_time+SMP_INV*60)) //传感器已经通电大约120s,可以直接开始采样
|
|
|
{
|
|
|
first_smp=1;
|
|
|
for(i=0;i<DEVICE_NUM;i++)
|
|
|
{
|
|
|
slave_addr=i+1;
|
|
|
//发送启动采样命令
|
|
|
tmp_reg=1;
|
|
|
if(sjzd_reg_wr(slave_addr,16,(uint8_t *)&tmp_reg,1,&rlt)!=FRM_ERR_NONE) // 下发第一次采集命令
|
|
|
{
|
|
|
if(sjzd_reg_wr(slave_addr,16,(uint8_t *)&tmp_reg,1,&rlt)!=FRM_ERR_NONE) // 下发第二次采集命令
|
|
|
log_e("clear slave %d data failed",slave_addr);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
log_d("start slave %d sample succeed",slave_addr);
|
|
|
}
|
|
|
}
|
|
|
last_smp_time=now;
|
|
|
start_smp_flag=1;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
if(start_smp_flag==1 & (now>=(last_smp_time+2*60)))
|
|
|
{
|
|
|
//分配缓冲区
|
|
|
all_device_file=(uint8_t *)malloc(DEVICE_NUM*8*20*1024);
|
|
|
if(all_device_file==NULL)
|
|
|
{
|
|
|
log_e("alloc all_device_file failed");
|
|
|
return -3;
|
|
|
}
|
|
|
memset(all_device_file,0xff,DEVICE_NUM*8*20*1024);
|
|
|
|
|
|
effective_channel_file=(uint8_t *)malloc((DEVICE_NUM-1)*6*20*1024);
|
|
|
if(effective_channel_file==NULL)
|
|
|
{
|
|
|
log_e("alloc effective_channel_file failed");
|
|
|
return -3;
|
|
|
}
|
|
|
memset(effective_channel_file,0xff,(DEVICE_NUM-1)*6*20*1024);
|
|
|
|
|
|
buf=(uint8_t *)malloc(8*20*1024);
|
|
|
if(buf==NULL)
|
|
|
{
|
|
|
log_e("alloc buf failed");
|
|
|
return -3;
|
|
|
}
|
|
|
memset(buf,0xff,8*20*1024);
|
|
|
|
|
|
|
|
|
for(i=0;i<DEVICE_NUM;i++)
|
|
|
{
|
|
|
//读寄存器
|
|
|
slave_addr=i+1;
|
|
|
ret=sjzd_reg_rd(slave_addr,0,(uint8_t *)&slave_regs[i],sizeof(SLAVE_REG_TYPE));
|
|
|
// log_d("ret=%d",ret);
|
|
|
if(FRM_ERR_NONE==ret)
|
|
|
{
|
|
|
log_d("slave %d ,has_new_data = %d",i+1,slave_regs[i].has_new_data);
|
|
|
if(slave_regs[i].has_new_data)//判断是否有新数据
|
|
|
{
|
|
|
sensor_err=0;
|
|
|
//读数据文件
|
|
|
curr_file=make_file_name(now,slave_addr);
|
|
|
if(sjzd_file_rd(slave_addr,"dummy_file",curr_file)>0)
|
|
|
{
|
|
|
log_d("read data from slave %d ok",slave_addr);
|
|
|
//分析数据文件curr_file
|
|
|
SJZD_file_analysis(slave_addr,curr_file,250.0);//传感器量程,100mv/g
|
|
|
log_d("slave %d upload 61850 data ok",slave_addr);
|
|
|
ret=load_from_file(curr_file,0 ,buf,160*1024);
|
|
|
if(ret>0)
|
|
|
{
|
|
|
//log_d("77777777777777777777777");
|
|
|
memcpy(all_device_file+(i*160*1024),buf,160*1024);
|
|
|
//log_d("888888888888888888");
|
|
|
}
|
|
|
// int h;
|
|
|
// for(h=0;h<30;h++)
|
|
|
// log_d("buf[%d]=0x%x,all_device_file[%d]=0x%x",h,buf[h],h+(i*160*1024),all_device_file[h+(i*160*1024)]);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
log_e("read data from slave %d failed",slave_addr);
|
|
|
}
|
|
|
// log_d("99999999999999999");
|
|
|
sensor_fault(slave_addr,sensor_err);
|
|
|
// log_d("111111111111111111111111");
|
|
|
//清数据标志
|
|
|
tmp_reg=0;
|
|
|
if(sjzd_reg_wr(slave_addr,0,(uint8_t *)&tmp_reg,sizeof(tmp_reg),&rlt)!=FRM_ERR_NONE)
|
|
|
{
|
|
|
log_e("clear slave %d data failed",slave_addr);
|
|
|
}
|
|
|
// log_d("22222222222222222222222222222");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//memset(all_device_file+(i*160*1024),0xff,160*1024);
|
|
|
log_w("%d no data",slave_addr);
|
|
|
sensor_err=1;
|
|
|
SJZD_file_analysis_nodata(slave_addr);
|
|
|
/* code */
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
SJZD_file_analysis_nodata(slave_addr);
|
|
|
/* code */
|
|
|
}
|
|
|
}
|
|
|
// log_d("3333333333333333");
|
|
|
curr_file=make_file_name_all(now);
|
|
|
// log_d("4444444444444444444");
|
|
|
|
|
|
//根据通道配置,提取有效通道
|
|
|
for(i=0;i<(DEVICE_NUM-1)*6;i++)
|
|
|
{
|
|
|
if((dev_par[6+i]>=1)&(dev_par[6+i]<=(DEVICE_NUM*8)))
|
|
|
memcpy(effective_channel_file+(i*20*1024),all_device_file+((dev_par[6+i]-1)*20*1024),20*1024);//device_par配置文件中从第6个字节开始是振动信号的通道信息
|
|
|
//log_d("channel %d memcpy to alldata sucessful!",i);
|
|
|
}
|
|
|
ret=save_to_file(curr_file,0,effective_channel_file,(DEVICE_NUM-1)*6*20*1024);//返回保存的长度
|
|
|
curr_file=make_file_name_temp(now);
|
|
|
ret=save_to_file(curr_file,0,effective_channel_file,(DEVICE_NUM-1)*6*20*1024);//返回保存的长度
|
|
|
|
|
|
// int h;
|
|
|
// for(h=0;h<30;h++)
|
|
|
// log_d("all_device_file[%d]=0x%x,,effective_channel_file[%d]=0x%x",h,all_device_file[8*20*1024+h],h,effective_channel_file[h]);
|
|
|
//释放内存空间
|
|
|
free(all_device_file);
|
|
|
free(effective_channel_file);
|
|
|
free(buf);
|
|
|
|
|
|
start_smp_flag=0;
|
|
|
relay_on();
|
|
|
}
|
|
|
|
|
|
}//end while(!doit)
|
|
|
stop_scl_mem();
|
|
|
return 0;
|
|
|
}
|
|
|
|