提交新代码

main
jxjajs 6 months ago
parent 7298bd64ff
commit 98c4e7d1cc

@ -7,23 +7,24 @@
#include "iec61850_process.h"
#define APP_VERSION "SV01.002"
#define START_SMP_HOUR 8 //8点开始采样
#define SMP_INV 60 //60分钟采样一次
#define DEVICE_NUM 3
#define SJZD_PORT "/dev/ttySZ3"
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
typedef struct
{
uint32_t has_new_data;
uint32_t new_data_len;
uint32_t data_timestamp;
uint32_t rsv;
} SLAVE_REG_TYPE;
static int doit=0;
void ctrlCfun(int i)
{
@ -39,10 +40,10 @@ int log_init(void)
/* 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);
// 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
@ -57,115 +58,317 @@ char *make_file_name(uint32_t sn,uint8_t addr)
struct tm *p;
memset(data_file_name,0,sizeof(data_file_name));
p=localtime((time_t *)&sn);
sprintf(data_file_name,"%04d%02d%02d_%02d%02d%02d_%d",p->tm_year+1900,p->tm_mon+1,p->tm_mday,p->tm_hour,p->tm_min,p->tm_sec,addr);
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[3];
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;
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;
signal(SIGINT,ctrlCfun);
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;
log_init();
//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);
elog_raw("Application Version:%s\r\n",APP_VERSION);
log_init();
//if(read_dev_cfg(&dev_cfg)!=0)
//{
// log_e("load device config failed");
//}
elog_raw("Application Version:%s\r\n",APP_VERSION);
if(sjzd_master_init(SJZD_PORT,SJZD_BAUD,SJZD_PARITY)!=0)
{
//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;
}
now=time(NULL);
p=localtime((time_t *)&now);
if(p->tm_hour<START_SMP_HOUR)
{
last_smp_time=now-(now%86400)+START_SMP_HOUR*3600-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);
}
modbus_rtu_slave_init();
iec61850_rx_init();
while(!doit)
{
usleep(500*1000);
now=time(NULL);
p=localtime((time_t *)&now);
for(i=0;i<3;i++)
{
//读寄存器
slave_addr=i+1;
ret=sjzd_reg_rd(slave_addr,0,(uint8_t *)&slave_regs[i],sizeof(SLAVE_REG_TYPE));
if(FRM_ERR_NONE==ret)
}
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)
{
if(slave_regs[i].has_new_data)//判断是否有新数据
{
//读数据文件
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
}
else
{
log_e("read data from slave %d failed",slave_addr);
}
//清数据标志
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);
}
}
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();
//判断是否需要启动采样
if(p->tm_hour>=START_SMP_HOUR)
now=time(NULL);
p=localtime((time_t *)&now);
if(p->tm_hour<START_SMP_HOUR)//START_SMP_HOUR UTC
{
if(now>=(last_smp_time+SMP_INV*60))
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))
{
for(i=0;i<3;i++)
//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可以直接开始采样
{
slave_addr=i+1;
//发送启动采样命令
tmp_reg=1;
if(sjzd_reg_wr(slave_addr,16,(uint8_t *)&tmp_reg,1,&rlt)!=FRM_ERR_NONE)
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)//判断是否有新数据
{
if(sjzd_reg_wr(slave_addr,16,(uint8_t *)&tmp_reg,1,&rlt)!=FRM_ERR_NONE)
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
{
log_d("start slave %d sample succeed",slave_addr);
//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 */
}
}
last_smp_time=now;
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)
return 0;
}//end while(!doit)
stop_scl_mem();
return 0;
}

@ -14,6 +14,7 @@
#define REG_ADDR (header_length+1)
#define REG_NUM (header_length+3)
#define REG_VAL (header_length+3)
#define device_id 2
enum {
TCP,
@ -23,7 +24,7 @@ enum {
static pthread_mutex_t modbus_rtu_slave_mutex;
static modbus_mapping_t *mb_mapping = NULL;
//YSP_MODBUS_REGS ysp_modbus_data;
//extern uint16 sjzd_modbus_data;
static uint32_t coil_arr[4];//128个线圈
static void modbus_rtu_slave_lock(void)
@ -70,14 +71,40 @@ void modbus_rtu_slave_routine(void *arg)
uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH];//接收缓冲区
int header_length;
uint16_t *ptr;
int use_backend=RTU;
//int use_backend=TCP;
char temp[18]={10,0,8,1,2,3,0,9,11,12,0,14,0,17,19,20,0,18};
//int use_backend=RTU;
int use_backend=TCP;
uint16_t reg_addr,reg_val,reg_num;
if(use_backend == TCP) {
ctx = modbus_new_tcp("127.0.0.1",1502);
if(use_backend == TCP)
{
// switch(device_id)
// {
// case 1:
// ctx = modbus_new_tcp("192.168.1.51",1502);
// log_d("libmodbus server 192.168.1.51");
// break;
// case 2:
// ctx = modbus_new_tcp("192.168.1.52",1502);
// log_d("libmodbus server 192.168.1.52");
// break;
// case 3:
// ctx = modbus_new_tcp("192.168.1.53",1502);
// log_d("libmodbus server 192.168.1.53");
// break;
// case 4:
// ctx = modbus_new_tcp("192.168.1.54",1502);
// log_d("libmodbus server 192.168.1.54");
// break;
// default:
// break;
// }
ctx = modbus_new_tcp("0.0.0.0",1502);
}
else if (use_backend == TCP_PI) {
else if (use_backend == TCP_PI)
{
ctx = modbus_new_tcp_pi("::0","1502");
}
else
@ -93,17 +120,23 @@ void modbus_rtu_slave_routine(void *arg)
modbus_set_debug(ctx,TRUE);
/*mb_mapping = modbus_mapping_new_start_address(UT_BITS_ADDRESS,UT_BITS_NB,UT_INPUT_BITS_ADDRESS,UT_INPUT_BITS_NB,UT_REGISTERS_ADDRESS,UT_REGISTERS_NB_MAX,UT_INPUT_REGISTERS_ADDRESS,UT_INPUT_REGISTERS_NB);*/
/*mb_mapping = modbus_mapping_new_start_address(UT_BITS_ADDRESS,UT_BITS_NB,UT_INPUT_BITS_ADDRESS,UT_INPUT_BITS_NB,UT_REGISTERS_ADDRESS,UT_REGISTERS_NB_MAX,UT_INPUT_REGISTERS_ADDRESS,UT_INPUT_REGISTERS_NB);*/
//油色谱总共24个寄存器
mb_mapping = modbus_mapping_new(128,0,MODBUS_MAX_READ_REGISTERS,0);
mb_mapping = modbus_mapping_new(MODBUS_MAX_READ_BITS,0,MODBUS_MAX_READ_REGISTERS,0);
if(mb_mapping == NULL) {
log_e("Failed to allocate the mapping: %s\n",modbus_strerror(errno));
modbus_free(ctx);
return ;
}
//初始化寄存器
modbus_rtu_slave_lock();
//mb_mapping->tab_registers[0] = 0x000f;
for(i=0;i<18;i++)
sjzd_modbus_data[221+i]=temp[i];
modbus_rtu_slave_unlock();
@ -114,138 +147,148 @@ void modbus_rtu_slave_routine(void *arg)
//for(i=0; i < UT_INPUT_REGISTERS_NB; i++) {
// mb_mapping->tab_input_registers[i] = UT_INPUT_REGISTERS_TAB[i];
//}
while(1)
{
if(use_backend == TCP)
{
//log_d("listening........");
s = modbus_tcp_listen(ctx,1);
modbus_tcp_accept(ctx,&s);
if(use_backend == TCP)
{
s = modbus_tcp_listen(ctx,1);
modbus_tcp_accept(ctx,&s);
}
else if(use_backend == TCP_PI)
{
s = modbus_tcp_pi_listen(ctx,1);
modbus_tcp_pi_accept(ctx,&s);
}
else
{
//建立连接
rc = modbus_connect(ctx);
if (rc == -1)
}
else if(use_backend == TCP_PI)
{
log_e("unable to connect %s\n",modbus_strerror(errno));
modbus_free(ctx);
return ;
s = modbus_tcp_pi_listen(ctx,1);
modbus_tcp_pi_accept(ctx,&s);
}
}
while (1)
{
do{
memset(query,0,sizeof(query));
rc = modbus_receive(ctx,query);
} while (rc == 0);
if(rc ==-1&&errno!=EMBBADCRC) {
log_e("parse modbus frame error: %s\n",modbus_strerror(errno));
//break;
continue;
else
{
//建立连接
rc = modbus_connect(ctx);
if (rc == -1)
{
log_e("unable to connect %s\n",modbus_strerror(errno));
modbus_free(ctx);
return ;
}
log_d("libmodbus connected");
}
switch(query[header_length])
log_d("libmodbus inited successful");
log_d("###########################################################################");
while (1)
{
case MODBUS_FC_READ_COILS://Read Coils in mb_mapping->tab_bitsIO输出
//读继电器
/*coil_arr[0]=relay_get_all(NULL);
memcpy(mb_mapping->tab_bits,coil_arr,4);*/
break;
case MODBUS_FC_READ_DISCRETE_INPUTS://Read Discrete Inputs in mb_mapping->tab_input_bitsIO输入
log_e("unsurported function 2\n");
//否定应答
modbus_reply_exception(ctx,query,MODBUS_EXCEPTION_ILLEGAL_FUNCTION);
continue;
do{
memset(query,0,sizeof(query));
rc = modbus_receive(ctx,query);
} while (rc == 0);
if(rc ==-1&&errno!=EMBBADCRC)
{
log_e("parse modbus frame error: %s\n",modbus_strerror(errno));
break;
case MODBUS_FC_READ_HOLDING_REGISTERS://Read Holding Registers in mb_mapping->tab_registers:REG输出
//读寄存器
/*if((MODBUS_GET_INT16_FROM_INT8(query,REG_ADDR)+MODBUS_GET_INT16_FROM_INT8(query,REG_NUM))>(sizeof(YSP_MODBUS_REGS)/2))
{
log_e("reply to this special register address by an exception\n");
//否定应答
modbus_reply_exception(ctx,query,MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS);
continue;
}*/
//更新寄存器
modbus_rtu_slave_lock();
/*ptr=(uint16_t *)&ysp_modbus_data;
for(i=0;i<(sizeof(YSP_MODBUS_REGS)/2);i++)
{
mb_mapping->tab_registers[i] = ptr[i];
}*/
modbus_rtu_slave_unlock();
break;
case MODBUS_FC_READ_INPUT_REGISTERS://Read Input Registers in mb_mapping->tab_input_registers:REG输入
//可用于读取测量值等不可上位机修改的量
break;
case MODBUS_FC_WRITE_SINGLE_COIL://Write Single Coil:slave_addr+cmd+reg_addr+[FF 00 or 00 00]+crc corresponding to mb_mapping->tab_bits
//写单个继电器
reg_addr=MODBUS_GET_INT16_FROM_INT8(query,REG_ADDR);
reg_val=MODBUS_GET_INT16_FROM_INT8(query,REG_VAL);
/*if(reg_addr<32)
//continue;
}
switch(query[header_length])
{
relay_set(reg_addr,(reg_val==0xFF00?1:0),1);
case MODBUS_FC_READ_COILS://Read Coils in mb_mapping->tab_bitsIO输出
//读继电器
/*coil_arr[0]=relay_get_all(NULL);
memcpy(mb_mapping->tab_bits,coil_arr,4);*/
break;
case MODBUS_FC_READ_DISCRETE_INPUTS://Read Discrete Inputs in mb_mapping->tab_input_bitsIO输入
log_e("unsurported function 2\n");
//否定应答
modbus_reply_exception(ctx,query,MODBUS_EXCEPTION_ILLEGAL_FUNCTION);
continue;
break;
case MODBUS_FC_READ_HOLDING_REGISTERS://Read Holding Registers in mb_mapping->tab_registers:REG输出
//读寄存器
/*if((MODBUS_GET_INT16_FROM_INT8(query,REG_ADDR)+MODBUS_GET_INT16_FROM_INT8(query,REG_NUM))>(sizeof(YSP_MODBUS_REGS)/2))
{
log_e("reply to this special register address by an exception\n");
//否定应答
modbus_reply_exception(ctx,query,MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS);
continue;
}*/
//更新寄存器
modbus_rtu_slave_lock();
for(i=0;i<(sizeof(sjzd_modbus_data)/2);i++)
{
mb_mapping->tab_registers[i] = sjzd_modbus_data[i];
}
//memset(&mb_mapping->tab_registers[0],sjzd_modbus_data,sizeof(sjzd_modbus_data));
modbus_rtu_slave_unlock();
break;
case MODBUS_FC_READ_INPUT_REGISTERS://Read Input Registers in mb_mapping->tab_input_registers:REG输入
//可用于读取测量值等不可上位机修改的量
break;
case MODBUS_FC_WRITE_SINGLE_COIL://Write Single Coil:slave_addr+cmd+reg_addr+[FF 00 or 00 00]+crc corresponding to mb_mapping->tab_bits
//写单个继电器
reg_addr=MODBUS_GET_INT16_FROM_INT8(query,REG_ADDR);
reg_val=MODBUS_GET_INT16_FROM_INT8(query,REG_VAL);
/*if(reg_addr<32)
{
relay_set(reg_addr,(reg_val==0xFF00?1:0),1);
}
else
{
switch(reg_addr)
{
case 32:
break;
case 33:
break;
default:
break;
}
}*/
break;
case MODBUS_FC_WRITE_SINGLE_REGISTER://Write Single Register:slave_addr+cmd+reg_addr+reg_val+crc corresponding to mb_mapping->tab_registers
//写单个寄存器
reg_addr=MODBUS_GET_INT16_FROM_INT8(query,REG_ADDR);
reg_val=MODBUS_GET_INT16_FROM_INT8(query,REG_VAL);
break;
case MODBUS_FC_WRITE_MULTIPLE_COILS://Write Multiple Coils:slave_addr+cmd+reg_addr+coil_num+bit_arr+crc corresponding to mb_mapping->tab_bits
//写多个继电器
break;
case MODBUS_FC_WRITE_MULTIPLE_REGISTERS://Write Multiple Registers:slave_addr+cmd+reg_addr+reg_num+reg_val_arr+crc corresponding to mb_mapping->tab_registers
//写多个寄存器
reg_addr=MODBUS_GET_INT16_FROM_INT8(query,REG_ADDR);
reg_num=MODBUS_GET_INT16_FROM_INT8(query,REG_NUM);
break;
default://
break;
}
else
{
switch(reg_addr)
{
case 32:
break;
case 33:
break;
default:
break;
}
}*/
break;
case MODBUS_FC_WRITE_SINGLE_REGISTER://Write Single Register:slave_addr+cmd+reg_addr+reg_val+crc corresponding to mb_mapping->tab_registers
//写单个寄存器
reg_addr=MODBUS_GET_INT16_FROM_INT8(query,REG_ADDR);
reg_val=MODBUS_GET_INT16_FROM_INT8(query,REG_VAL);
break;
case MODBUS_FC_WRITE_MULTIPLE_COILS://Write Multiple Coils:slave_addr+cmd+reg_addr+coil_num+bit_arr+crc corresponding to mb_mapping->tab_bits
//写多个继电器
break;
case MODBUS_FC_WRITE_MULTIPLE_REGISTERS://Write Multiple Registers:slave_addr+cmd+reg_addr+reg_num+reg_val_arr+crc corresponding to mb_mapping->tab_registers
//写多个寄存器
reg_addr=MODBUS_GET_INT16_FROM_INT8(query,REG_ADDR);
reg_num=MODBUS_GET_INT16_FROM_INT8(query,REG_NUM);
break;
default://
//正常应答
rc = modbus_reply(ctx,query,rc,mb_mapping);
if(rc==-1)
{
log_e("reply modbus frame error: %s\n",modbus_strerror(errno));
break;
}
}
//正常应答
rc = modbus_reply(ctx,query,rc,mb_mapping);
if(rc==-1){
log_e("reply modbus frame error: %s\n",modbus_strerror(errno));
//break;
}
}
if(use_backend==TCP)
{
if(s != -1)
if(use_backend==TCP)
{
close(s);
if(s != -1)
{
close(s);
}
}
}
log_e("quit the loop: %s\n",modbus_strerror(errno));
modbus_mapping_free(mb_mapping);
log_e("quit the loop: %s\n",modbus_strerror(errno));
}
log_d("********modbus end************");
// For RTU
modbus_mapping_free(mb_mapping);
modbus_close(ctx);
modbus_free(ctx);
}
int modbus_rtu_slave_init(void)
{
pthread_t modbus_rtu_slave_thread;

@ -1,6 +1,7 @@
#define LOG_TAG "serial"
#include "serial.h"
#include "elog.h"
#include <sys/time.h>
/*
TTU使4UARTRS485RS232/RS485:
UART GPIO
@ -169,36 +170,74 @@ int SerialRead(int m_comFd,unsigned char *buf,int sz,int timeout)
return (rxlen > 0) ? rxlen : 0;
}
long long get_msec(void)
{
struct timeval tv;
long long time_in_msec = 0;
gettimeofday(&tv, NULL);
time_in_msec = tv.tv_sec;
time_in_msec *= 1000;
time_in_msec += tv.tv_usec / 1000;
return time_in_msec;
}
#if 0
//timeout is in 100ms
int SerialReadEx(int m_comFd,unsigned char *buf,int sz,int timeout)
{
int curr_length=0,last_length=0,rx_length=0;
//int rx_tick=0;
//tcflush(m_comFd,TCIFLUSH);
while(timeout--)
int curr_length=0,last_length=0,rx_length=0;
//int rx_tick=0;
//tcflush(m_comFd,TCIFLUSH);
while(timeout--)
{
usleep(100000);//wait 100ms
curr_length=read(m_comFd,buf+rx_length,sz-rx_length);
if(curr_length>0)
{
rx_length+=curr_length;
last_length=curr_length;
if(rx_length>=sz)
{
return rx_length;
}
}
else
{
if(last_length>0)//上次读取到了字节本次没有,认为读完了一帧
{
return rx_length;
}
last_length=0;
//rx_length=0;
}
}
return rx_length;
}
#endif
int SerialReadEx(int m_comFd,unsigned char *buf,int sz,int timeout)
{
int curr_length=0/*,last_length=0*/,rx_length=0;
long long t0, t1;
t0 = get_msec();
for(;;)
{
usleep(100000);//wait 100ms
curr_length=read(m_comFd,buf+rx_length,sz-rx_length);
if(curr_length>0)
{
rx_length+=curr_length;
last_length=curr_length;
if(rx_length>=sz)
{
return rx_length;
}
}
else
{
if(last_length>0)//上次读取到了字节本次没有,认为读完了一帧
{
return rx_length;
}
last_length=0;
//rx_length=0;
}
rx_length += curr_length;
usleep(5000);
curr_length = read(m_comFd,buf+rx_length, 1040-rx_length);/* 在串口读取字符串 */
t1 = get_msec();
if(t1-t0 >= 350)
break;
}
return rx_length;
if (rx_length < 1)
return rx_length;
return rx_length;
}
/**

@ -17,6 +17,18 @@
#define LOG_TAG "sjzd"
#include "sjzd.h"
#include "elog.h"
#include "scl_shm.h"
#include "iec61850_process.h"
#include "string.h"
#include "sys/stat.h"
#include "unistd.h"
#include "fcntl.h"
#include "stdlib.h"
#include "stdio.h"
#include "modbus_rtu_slave.h"
#include "single_Amp_Extra.h"
extern uint8_t dev_par[18];
//2.通讯协议AA+addr(1byte)+data_len(2bytes)+data(n)+crc_val(2byte)+0x55
/*
*********************************************************************************************************
@ -36,6 +48,8 @@
* Note(s) : none.
*********************************************************************************************************
*/
int32_t sjzd_make_frm(uint8_t *enc_buf,uint8_t slave_addr,uint8_t cmd,uint8_t *data,uint16_t data_len)
{
int i=0;
@ -71,42 +85,47 @@ int32_t sjzd_make_frm(uint8_t *enc_buf,uint8_t slave_addr,uint8_t cmd,uint8_t *d
int32_t sjzd_chk_frm(uint8_t *buf,uint16_t len,uint8_t slave_addr,uint8_t cmd)
{
uint8_t crc_val[2];
uint16_t i;
uint16_t rx_len;
if(buf[0]!=0xAA)
{
memcpy(&buf[0],&buf[1],len-1);
uint8_t crc_val[2];
uint16_t rx_len;
if(buf[0]!=0xAA)
{
return FRM_ERR_START;
memcpy(&buf[0],&buf[1],len-1);
if(buf[0]!=0xAA)
{
log_e("chk:buf[0]=%02X, !=0xAA error!",buf[0]);
return FRM_ERR_START;
}
len-=1;
}
len-=1;
}
if(buf[1]!=slave_addr)//
if(buf[1]!=slave_addr)//
{
log_e("chK:buf[1]=%d, slave_addr=%d error!",buf[1], slave_addr);
return FRM_ERR_SLAVE_ADDR;
}
rx_len=(uint16_t)buf[3]*256+buf[2];
rx_len=(uint16_t)buf[3]*256+buf[2];
if((rx_len+6)>len)
{
log_e("chk:b2+b3*256+6=%d, recvlen=%d error!",rx_len+6, len);
return FRM_ERR_BYTE_COUNT;
}
if((rx_len+6)>len)
{
return FRM_ERR_BYTE_COUNT;
}
if(buf[4]!=cmd)//
{
log_e("chk:buf[4]=%d, cmd=%d error!",buf[4], cmd);
return FRM_ERR_FC;
}
if(buf[4]!=cmd)//
{
return FRM_ERR_FC;
}
crc16_ex(buf,rx_len+4,crc_val);//
crc16_ex(buf,rx_len+4,crc_val);//
if((crc_val[0]==(buf[rx_len+4]))&&(crc_val[1]==(buf[rx_len+5])))
return FRM_ERR_NONE;
if((crc_val[0]==(buf[rx_len+5]))&&(crc_val[1]==(buf[rx_len+4])))
return FRM_ERR_NONE;
return FRM_ERR_CRC;
if((crc_val[0]==(buf[rx_len+4]))&&(crc_val[1]==(buf[rx_len+5])))
return FRM_ERR_NONE;
if((crc_val[0]==(buf[rx_len+5]))&&(crc_val[1]==(buf[rx_len+4])))
return FRM_ERR_NONE;
log_e("chk:buf[rx_len+4][rx_len+5]=%02X%02X,crc_val=%02X%02X error!",buf[rx_len+4], buf[rx_len+5], crc_val[0],crc_val[1]);
return FRM_ERR_CRC;
}
static int32_t sjzd_swp_uint16(uint8_t *buf,uint32_t len)
@ -174,6 +193,7 @@ int32_t sjzd_reg_rd(uint8_t slave_node,uint32_t reg_addr,uint8_t *reg_tbl,uint32
//读应答,应答格式cmd+data
sjzd_serial_read(sjzd_rx_buf,nbr_reg+8,&sjzd_rx_len);
if(sjzd_rx_len<(nbr_reg+8))
{
ret=FRM_ERR_BYTE_COUNT;
@ -202,7 +222,7 @@ int32_t sjzd_reg_wr(uint8_t slave_node,uint32_t reg_addr,uint8_t *reg_tbl,uint32
uint8_t sjzd_rx_buf[FRM_MAX_LEN];
uint16_t sjzd_rx_len=0;
int32_t ret;
uint32_t i=0;
uint32_t i=0,m=0;
//发送请求命令reg_addr[4bytes]+reg_num[4bytes]+data
memcpy(&sjzd_rx_buf[i],&reg_addr,sizeof(uint32_t));
@ -212,7 +232,10 @@ int32_t sjzd_reg_wr(uint8_t slave_node,uint32_t reg_addr,uint8_t *reg_tbl,uint32
memcpy(&sjzd_rx_buf[i],reg_tbl,nbr_reg);
i+=nbr_reg;
sjzd_tx_len=sjzd_make_frm(sjzd_tx_buf,slave_node,SJZD_WR_REGS,(uint8_t *)sjzd_rx_buf,i);
sjzd_serial_write(sjzd_tx_buf,sjzd_tx_len);
// for(m=0;m<sjzd_tx_len;m++)
// log_d("sjzd_tx_buf[m]=0x%x",sjzd_tx_buf[m]);
if(slave_node==0xFF)
return FRM_ERR_NONE;
@ -256,8 +279,11 @@ static int32_t sjzd_read_file_info(uint8_t slave_node,char *in_file,int *info)
sjzd_serial_write(sjzd_tx_buf,sjzd_tx_len);
//读取应答
sjzd_serial_read(sjzd_rx_buf,4+1+4+2+2,&sjzd_rx_len);
if(sjzd_rx_len<13)
//sjzd_serial_read(sjzd_rx_buf,4+1+4+2+2,&sjzd_rx_len);
//if(sjzd_rx_len<13)
sjzd_serial_read(sjzd_rx_buf,4+1+4+2+1,&sjzd_rx_len);
// log_d("sjzd_rx_len = %d",sjzd_rx_len);
if(sjzd_rx_len<12)
{
//log_e("mb_rx_len=%d,mb_tx_len=%d",mb_rx_len,mb_tx_len);
ret= FRM_ERR_BYTE_COUNT;
@ -293,10 +319,13 @@ static int32_t sjzd_read_file_content(uint8_t slave_node,uint32_t ofs,uint8_t *b
sjzd_serial_write(sjzd_tx_buf,sjzd_tx_len);//发送命令
//读取应答
//sjzd_serial_read(sjzd_rx_buf,16+len,&sjzd_rx_len);
//if(sjzd_rx_len<16+len)
sjzd_serial_read(sjzd_rx_buf,8+len,&sjzd_rx_len);
if(sjzd_rx_len<8)
if(sjzd_rx_len<8+len)
{
//log_e("mb_rx_len=%d,mb_tx_len=%d",mb_rx_len,mb_tx_len);
log_e("read:sjzd_rx_len=%d ofs=%d",sjzd_rx_len, ofs);
ret= FRM_ERR_BYTE_COUNT;
goto EXIT;
}
@ -306,10 +335,11 @@ static int32_t sjzd_read_file_content(uint8_t slave_node,uint32_t ofs,uint8_t *b
//elog_hexdump("modbus_rx",16,mb_rx_buf,mb_rx_len);
if(ret_len!=NULL)
*ret_len=sjzd_rx_len-8;
memcpy(buf,&sjzd_rx_buf[5],sjzd_rx_len-8);
return FRM_ERR_NONE;
}
EXIT:
log_e("%d",ret);
log_e("%d sjzd_rx_len=%d",ret, sjzd_rx_len);
if(sjzd_rx_len)
elog_hexdump("sjzd_read_file_content",16,sjzd_rx_buf,sjzd_rx_len);
return ret;
@ -343,7 +373,6 @@ static int32_t sjzd_read_file_end(uint8_t slave_node,char *in_file)
return FRM_ERR_NONE;
}
EXIT:
log_e("%d",ret);
if(sjzd_rx_len)
elog_hexdump("sjzd_read_file_end",16,sjzd_rx_buf,sjzd_rx_len);
return ret;
@ -374,7 +403,7 @@ int32_t sjzd_file_rd(uint8_t slave_node,char *in_file,char *out_file)
}
//分配缓冲区
file_content=(uint8_t *)malloc(file_tot_len);
file_content=(uint8_t *)malloc(file_tot_len);
if(file_content==NULL)
{
log_e("alloc file buf failed");
@ -405,6 +434,7 @@ int32_t sjzd_file_rd(uint8_t slave_node,char *in_file,char *out_file)
}
}while(i<file_tot_len);
//保存文件
ret=save_to_file(out_file,0,file_content,file_tot_len);//返回保存的长度
@ -423,3 +453,541 @@ EXIT:
free(file_content);
return ret;
}
void SJZD_file_analysis_nodata(uint8_t slave_addr)
{
USR_MV tmp1,tmp2,tmp3;
USR_MV fft_value[19];
char k;
char m;
char n;
switch(slave_addr)
{
case 1:
tmp1.v.f=0;
tmp1.q = 1;
tmp1.t.secs=time(NULL);
tmp1.t.ms = tmp1.t.secs*1000;
lock_scl_mem();
for(k=0;k<15;k++)
{
put_mv_data(0,k*46+19,&tmp1,1);
put_mv_data(0,k*46+20,&tmp1,1);
}
unlock_scl_mem();
break;
case 2:
for(m=0;m<6;m++)
{
for(n=0;n<19;n++)
{
fft_value[n].v.f=0;
fft_value[n].q=0;
fft_value[n].t.secs=time(NULL);
fft_value[n].t.ms = fft_value[n].t.secs*1000;
sjzd_modbus_data[21+19*m+n]=0;//单位换算为g,保留两位小数
}
put_mv_data(0,m*46,fft_value,19);
}
break;
case 3:
for(m=6;m<12;m++)
{
for(n=0;n<19;n++)
{
fft_value[n].v.f=0;
fft_value[n].q=0;
fft_value[n].t.secs=time(NULL);
fft_value[n].t.ms = fft_value[n].t.secs*1000;
sjzd_modbus_data[21+19*m+n]=0;//单位换算为g,保留两位小数
}
put_mv_data(0,m*46,fft_value,19);
for(n=0;n<7;n++)
sjzd_modbus_data[135+7*m+n]=0;//单位换算为g,保留两位小数
}
break;
default:
log_d("default");
break;
}
}
void SJZD_file_analysis(uint8_t slave_addr,char *curr_file,float sensor_range)
{
uint8_t buf[160*1024];
int16_t data[8][10240];
double dv0[10000];
int32_t ret;
float sum;
float num=0;
float noise=0;
float neu=0;
double code=0;
double amp_data[19];
float amp_temp[19];
int amp_size[2]={0,0};
int k,n,m;
FILE *fp;
LN_SVBR_TYPE ln_svbr;
USR_MV tmp1,tmp2,tmp3;
USR_MV fft_value[19];
memset(&tmp1, 0x00, sizeof(USR_MV));
memset(&tmp2, 0x00, sizeof(USR_MV));
memset(&tmp3, 0x00, sizeof(USR_MV));
memset(fft_value, 0x00, 19*sizeof(USR_MV));
double pri_max[]={196000,196000,196000,196000,196000,196000,196000,196000,196000,196000,196000,196000,196000,196000,196000,196000,96000,196000,196000};
double sec_max[]={196000,196000,196000,196000,196000,196000,196000};
double offset[]={1.2626,0.3597,0,0,0,0,0,0,0,0,0,0};
int channel_num=0;
double noise_max=150;
double neu_max=50;
char noise_warning=0;
char neu_warning=0;
char amp_warning[19];
memset(amp_warning,0,19);
ret=load_from_file(curr_file,0 ,buf,160*1024);
tmp3.v.stVal=1;
tmp3.q = 1;
if(ret>0)
{
memcpy(data,buf,160*1024);
// for(k=0;k<8;k++)
// for(m=0;m<100;m++)
// log_d("data[%d][%d]=%d",k,m,data[k][m]);
// int16_t tt[]={7000,20000,30000,8000,24000,9000,16000};
// sum=0;
// qsort(tt,7, sizeof(int16_t), cmp);
// for(k=2;k<5;k++)
// sum+=(tt[k]*5.0f/32768-1)*22.5f+30.0f;
// log_d("sum=%f",sum);
// noise=sum/3.0;
// log_d("noise=%f",noise);
switch(slave_addr)
{
case 1:
sum=0;
channel_num=dev_par[4]-1;
qsort(data[channel_num],10000, sizeof(int16_t), cmp);
// log_d("channel_num=%d",channel_num);
if((channel_num+1)>0)
{
for(k=1000;k<9000;k++)
{
if((data[channel_num][k]-(offset[0]*32768.0/5.0))>0)//小于0去掉
{
sum+=(data[channel_num][k]*5.0f/32768-offset[0])*18.0f+30.0f;
num=num+1.0;
}
}
//log_d("sum=%f",sum);
noise=sum/num;
num=0;
}
else
{
noise=0;
/* code */
}
sum=0;
qsort(data[2],10000, sizeof(int16_t), cmp);
channel_num=dev_par[5]-1;
if((channel_num+1)>0)
{
for(k=1000;k<9000;k++)
sum+=(data[channel_num][k]*5.0f/32768-offset[1])*40.0f;
//log_d("sum=%f",sum);
neu=sum/8000.0;
//log_d("noise=%f,neu=%f",noise,neu);
}
else
{
neu=0;
}
tmp1.v.f=noise;
tmp1.q = 1;
tmp1.t.secs=time(NULL);
tmp1.t.ms = tmp1.t.secs*1000;
tmp2.v.f=neu;
tmp2.q = 1;
tmp2.t.secs=time(NULL);
tmp2.t.ms = tmp2.t.secs*1000;
if(noise>=noise_max)
noise_warning=1;
else
noise_warning=0;
if(neu>=neu_max)
neu_warning=1;
else
neu_warning=0;
tmp3.t.secs=time(NULL);
tmp3.t.ms = tmp3.t.secs*1000;
lock_scl_mem();
for(k=0;k<15;k++)
{
put_mv_data(0,k*46+19,&tmp1,1);
put_mv_data(0,k*46+20,&tmp2,1);
//put_mv_data(0,k*46+21,&tmp3,1);
tmp3.v.stVal=noise_warning;
put_mv_data(0,k*46+25,&tmp3,1);
tmp3.v.stVal=neu_warning;
put_mv_data(0,k*46+26,&tmp3,1);
}
unlock_scl_mem();
sjzd_modbus_data[11]=(uint16_t)(noise*100.0);
sjzd_modbus_data[12]=(uint16_t)(neu*100.0);
sjzd_modbus_data[206]=(uint16_t)noise_warning;
sjzd_modbus_data[207]=(uint16_t)neu_warning;
break;
case 2:
lock_scl_mem();
tmp3.t.secs=time(NULL);
tmp3.t.ms = tmp3.t.secs*1000;
for(m=0;m<6;m++)
{
channel_num=dev_par[m+6]-8-1;
// log_d("channel_num=%d",channel_num);
if((channel_num+1)>0)
{
for(k=0;k<10000;k++)
dv0[k]=data[channel_num][k]-(offset[m+2]*32768.0/5.0);
single_Amp_Extra(dv0, 10000.0f, 1.0f, &code, amp_data,amp_size);
for(n=0;n<19;n++)
{
amp_temp[n]=(float)amp_data[n]/(sensor_range/100.0);
fft_value[n].v.f=amp_temp[n];
fft_value[n].q=0;
fft_value[n].t.secs=time(NULL);
fft_value[n].t.ms = fft_value[n].t.secs*1000;
sjzd_modbus_data[21+19*m+n]=(uint16_t)(fft_value[n].v.f/1000.0*100);//单位换算为g,保留两位小数
if(amp_temp[n]>=pri_max[n])
{
amp_warning[n]=1;//modbus 每个分量报警
tmp3.v.stVal=1;
put_mv_data(0,m*46+27+n,&tmp3,1);//61850实时更新报警,每个传感器每个分量告警
}
else
{
tmp3.v.stVal=0;
put_mv_data(0,m*46+27+n,&tmp3,1);
}
}
}
else
{
for(n=0;n<19;n++)
{
fft_value[n].v.f=0;
fft_value[n].q=0;
fft_value[n].t.secs=time(NULL);
fft_value[n].t.ms = fft_value[n].t.secs*1000;
sjzd_modbus_data[21+19*m+n]=0;//单位换算为g,保留两位小数
//amp_warning[n]=0;//modbus 每个分量报警
tmp3.v.stVal=0;
for(k=0;k<6;k++)
put_mv_data(0,k*46+27+n,&tmp3,1);//61850实时更新报警,每个传感器每个分量告警
}
/* code */
}
put_mv_data(0,m*46,fft_value,19);
}
unlock_scl_mem();
for(m=0;m<19;m++)
sjzd_modbus_data[180+m]=(uint16_t)amp_warning[n];//单位换算为g,保留两位小数
break;
case 3:
lock_scl_mem();
tmp3.t.secs=time(NULL);
tmp3.t.ms = tmp3.t.secs*1000;
for(m=6;m<12;m++)
{
channel_num=dev_par[m+6]-16-1;
//log_d("channel_num=%d",channel_num);
if((channel_num+1)>0)//判断通道是否使能
{
for(k=0;k<10000;k++)
dv0[k]=data[channel_num][k]-(offset[m+2]*32768.0/5.0);
single_Amp_Extra(dv0, 10000.0f, 1.0f, &code, amp_data,amp_size);
for(n=0;n<19;n++)
{
amp_temp[n]=(float)(amp_data[n])/(sensor_range/100.0);
fft_value[n].v.f=amp_temp[n];
fft_value[n].q=1;
fft_value[n].t.secs=time(NULL);
fft_value[n].t.ms = fft_value[n].t.secs*1000;
if(amp_temp[n]>=sec_max[n])
{
amp_warning[n]=1;//modbus 每个分量报警
tmp3.v.stVal=1;
put_mv_data(0,m*46+27+n,&tmp3,1);//61850实时更新报警,每个传感器每个分量告警
}
else
{
tmp3.v.stVal=0;
put_mv_data(0,m*46+27+n,&tmp3,1);
}
}
}
else
{
for(n=0;n<19;n++)
{
fft_value[n].v.f=0;
fft_value[n].q=0;
fft_value[n].t.secs=time(NULL);
fft_value[n].t.ms = fft_value[n].t.secs*1000;
sjzd_modbus_data[21+19*m+n]=0;//单位换算为g,保留两位小数
memset(amp_temp,0,sizeof(amp_temp));
//amp_warning[n]=0;//modbus 每个分量报警
tmp3.v.stVal=0;
for(k=6;k<12;k++)
put_mv_data(0,k*46+27+n,&tmp3,1);//61850实时更新报警,每个传感器每个分量告警
}
/* code */
}
for(n=0;n<7;n++)
sjzd_modbus_data[135+7*m+n]=(uint16_t)(amp_temp[2*n+1]/1000.0*100);//单位换算为g,保留两位小数
put_mv_data(0,m*46,fft_value,19);
}
unlock_scl_mem();
for(m=0;m<7;m++)
sjzd_modbus_data[199+m]=(uint16_t)amp_warning[2*m+1];//单位换算为g,保留两位小数
break;
default:
log_d("default");
break;
}
}
// fp = fopen("/home/debian/my_task/data/time_5.txt", "r");
// for(m = 0; m<10000; m++)
// {
// for(n = 0; n < 14; n++)
// {
// fscanf(fp, "%d ", &a[n][m]);
// }
// }
}
//其中cmp函数
int cmp(const void *a, const void *b)
{
return *(int16_t*)a - *(int16_t*)b; //由小到大排序
//return *(int *)b - *(int *)a; 由大到小排序
}
//通讯异常上传 MoDevConf MoDevDetF
void fault_up(char dev_fault)
{
USR_MV tmp3;
int k;
tmp3.q = 1;
tmp3.t.secs=time(NULL);
tmp3.t.ms = tmp3.t.secs*1000;
tmp3.v.stVal=(char) dev_fault&0x01;
lock_scl_mem();
for(k=0;k<15;k++)
put_mv_data(0,k*46+22,&tmp3,1);
unlock_scl_mem();
tmp3.v.stVal=(char) (dev_fault&0x02)>>1;
lock_scl_mem();
for(k=0;k<6;k++)
put_mv_data(0,k*46+21,&tmp3,1);
unlock_scl_mem();
tmp3.v.stVal=(char) (dev_fault&0x04)>>2;
lock_scl_mem();
for(k=6;k<12;k++)
put_mv_data(0,k*46+21,&tmp3,1);
unlock_scl_mem();
}
void sensor_fault(char slave_addr,char sensor_err)
{
USR_MV tmp3;
int k;
tmp3.q = 1;
tmp3.t.secs=time(NULL);
tmp3.t.ms = tmp3.t.secs*1000;
tmp3.v.stVal=sensor_err;
lock_scl_mem();
if(slave_addr == 1)
{
for(k=0;k<15;k++)
put_mv_data(0,k*46+24,&tmp3,1);
}
else
{
for(k=(slave_addr-1)*6;k<(slave_addr-1)*6+6;k++)
put_mv_data(0,k*46+23,&tmp3,1);
/* code */
}
unlock_scl_mem();
}
void heartbeat(char dev_num)
{
int32_t ret;
SLAVE_REG_TYPE slave_regs[3];
uint32_t tmp_reg;
uint8_t rlt,slave_addr;
int32_t i;
char dev_fault=0x7;
for(i=0;i<dev_num;i++)
{
//读寄存器
slave_addr=i+1;
ret=sjzd_reg_rd(slave_addr,0,(uint8_t *)&slave_regs[i],sizeof(SLAVE_REG_TYPE));
if(FRM_ERR_NONE==ret)
dev_fault&=~(1<<i);
else
dev_fault|=1<<i;
}
//start_scl_mem();
sjzd_modbus_data[1]=(uint16_t)dev_fault;
fault_up(dev_fault);
//stop_scl_mem();
}
int relay_init(void)
{
int fd;
int i=0;
char dir[]="/sys/class/gpio/gpio1/direction";
char val[]="/sys/class/gpio/gpio1/value";
char index[]={'1','2','3','4'};
for(i=0;i<4;i++)
{
dir[20]=index[i];
val[20]=index[i];
fd = open("/sys/class/gpio/export", O_WRONLY);
if(fd < 0)
return 1 ;
write(fd, &dir[20], 1);
close(fd);
fd = open(dir, O_WRONLY);
if(fd < 0)
return 1 ;
write(fd, "out", strlen("out"));
close(fd);
fd = open(val, O_WRONLY);
if(fd < 0)
return 1 ;
write(fd, "1", 1);
close(fd);
}
return 0;
}
int relay_on(void)
{
int fd;
int i=0;
char val[]="/sys/class/gpio/gpio1/value";
char index[]={'1','2','3','4'};
for(i=0;i<4;i++)
{
val[20]=index[i];
fd = open(val, O_WRONLY);
if(fd < 0)
return 1 ;
write(fd, "0", 1);
close(fd);
}
return 0;
}
int relay_off(void)
{
int fd;
int i=0;
char val[]="/sys/class/gpio/gpio1/value";
char index[]={'1','2','3','4'};
for(i=0;i<4;i++)
{
val[20]=index[i];;
fd = open(val, O_WRONLY);
if(fd < 0)
return 1 ;
write(fd, "1", 1);
close(fd);
}
return 0;
}
// #define size 6000//数组大小
// #define N 12//滑动平均滤波计算平均值时所取的点数
// /*上面两句在使用下面这个函数的时候加到程序的开头*/
// void Smooth(float data[],int 32,int32_t size)
// {
// Sum1=0;
// for(int j=0;j<size;j++)
// {
// if(j<N/2)
// {
// for(int k=0;k<N;k++)
// {
// Sum1+=data[j+k];
// }
// data[j]=Sum1/N;
// }
// else
// if(j<size -N/2)
// {
// for(int k=0;k<N/2;k++)
// {
// Sum1+=(data[j+k]+data[j-k]);
// }
// data[j]=Sum1/N;
// }
// else
// {
// for(int k=0;k<size-j;k++)
// {
// Sum1+=data[j+k];
// }
// for(int k=0;k<(N-size+j);k++)
// {
// Sum1+=data[j-k];
// }
// data[j]=Sum1/N;
// }
// Sum1=0;
// }
// }

@ -1,6 +1,7 @@
#define LOG_TAG "sjzd_serial"
#include "sjzd_serial.h"
#include "elog.h"
#include "crc.h"
typedef struct
{
@ -11,14 +12,10 @@ typedef struct
SERIAL_MAP_TYPE serial_map_tbl[]={
{"RS485_1","/dev/ttySZ3"},
{"RS485_2","/dev/ttySZ4"},
{"RS485_3","/dev/ttySZ5"},
{"RS485_4","/dev/ttySZ6"},
{"RS232_1","/dev/ttySZ5"},
{"RS232_2","/dev/ttySZ6"},
{"RS485_1","/dev/ttymxc1"},
{"RS485_2","/dev/ttymxc2"},
{"RS485_3","/dev/ttymxc3"},
};
static int sjzd_serial_fd = -1;//串口句柄
static char *sjzd_get_port_by_name(char *vname)
@ -66,10 +63,143 @@ int32_t sjzd_serial_close(void)
return 0;
}
int sjzd_recv_data(SJZD_SERIAL_DEF *pPortParam, u_char *buf, int len, uint16_t usNBytes)
{
int i, flag = -1;
uint8_t crc_val[2];
static int fault=0;
for (i = 0; i < len; i++)
{
switch (pPortParam->m_iRevStatus)
{
case 0: // 0xAA
pPortParam->m_iRecvLen = 0;
pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
if (0xAA == buf[i])
pPortParam->m_iRevStatus++;
else
{
pPortParam->m_iRevStatus = 18;
log_e("1:[%d]%02X != AA", i+1, buf[i]);
}
break;
case 1: // addr
if((0<buf[i]) && (3 >= buf[i]))
{
pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
pPortParam->m_iRevStatus++;
}
else
{
log_e("2:[%d]addr=%d-----", i+1, buf[i]);
pPortParam->m_iRevStatus = 18;
}
break;
case 2: // len低字节
pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
pPortParam->m_iRevStatus++;
break;
case 3: // len高字节
pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
pPortParam->m_iRevStatus++;
pPortParam->m_iNeedRevLength = pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen - 2] + buf[i] * 256 + 3;
if(pPortParam->m_iNeedRevLength > usNBytes+10)
{
log_e("3:[%d]m_iNeedRevLength=%d > %d(usNBytes%d+8) %02X%02X -----", i+1,pPortParam->m_iNeedRevLength, usNBytes+8, usNBytes, pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen-2], buf[i]);
pPortParam->m_iRevStatus = 18;
}
break;
case 4: // cmd
pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
pPortParam->m_iNeedRevLength--;
if(4 == buf[i])
{
if(fault == 5)
{
log_e("test error,fault=%d", fault);
fault = 0;
return 0;
}
else
fault++;
}
if ((0 < buf[i]) && (6 > buf[i]))
pPortParam->m_iRevStatus++;
else
{
log_e("4:buf[%d]cmd=%d-----", i+1, buf[i]);
pPortParam->m_iRevStatus = 18;
}
break;
case 5: // 正确接收数据
pPortParam->m_iNeedRevLength--;
pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
if (pPortParam->m_iNeedRevLength > 0)
break;
if (buf[i] != 0x55)
{
log_e("5:[%d]%02X != 55", i+1, buf[i]);
pPortParam->m_iRevStatus = 18;
break;
}
crc16_ex(pPortParam->m_au8RecvBuf,pPortParam->m_iRecvLen-3,crc_val);//
if((crc_val[0]==(pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen - 2]))&&(crc_val[1]==pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen - 3]))
flag = 1;
if((crc_val[0]==(pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen - 3]))&&(crc_val[1]==pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen - 2]))
flag = 1;
if (1 == flag)
{
memmove(buf, pPortParam->m_au8RecvBuf, pPortParam->m_iRecvLen);
return pPortParam->m_iRecvLen;
}
else
{
log_e("6:%02X%02X %02X%02X -----", crc_val[0], crc_val[1], pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen - 2], pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen - 3]);
pPortParam->m_iRevStatus = 18;
pPortParam->m_iRecvLen = 0;
}
break;
case 255:// 错误接收数据
default:
if (buf[i] == 0xAA)
{
pPortParam->m_iRevStatus = 1;
pPortParam->m_iRecvLen = 1;
pPortParam->m_au8RecvBuf[0] = buf[i];
}
else if (buf[i] == 0x55)
{
pPortParam->m_iRevStatus = 0;
pPortParam->m_iRecvLen = 0;
}
else
{
pPortParam->m_iRecvLen = 0;
}
break;
}
}
return 0;
}
int32_t sjzd_serial_read(uint8_t *pucBuffer,uint16_t usNBytes,uint16_t *usNBytesRead)
{
int rx_len;
SJZD_SERIAL_DEF *sjzdport;
rx_len=SerialReadEx(sjzd_serial_fd,pucBuffer,usNBytes,MODBUS_TIMEOUT);
sjzdport=(SJZD_SERIAL_DEF *)malloc(sizeof(SJZD_SERIAL_DEF));
if(sjzdport==NULL)
{
log_e("sjzdport alloc file buf failed");
return 0;
}
memset(sjzdport, 0, sizeof(SJZD_SERIAL_DEF));
log_e("rx_len=%d", rx_len);
rx_len = sjzd_recv_data(sjzdport, pucBuffer, rx_len, usNBytes);
if(usNBytesRead!=NULL)
{
if(rx_len>0)
@ -82,6 +212,11 @@ int32_t sjzd_serial_read(uint8_t *pucBuffer,uint16_t usNBytes,uint16_t *usNBytes
*usNBytesRead=0;
}
}
if(NULL != sjzdport)
{
free((void*)sjzdport);
sjzdport = NULL;
}
return rx_len;
}

Loading…
Cancel
Save