You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

376 lines
12 KiB
C

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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;
}