📄 iec61850.cpp
字号:
#include<pthread.h>#include<stdlib.h>#include<stdio.h>#include<unistd.h>#include<sys/types.h>#include <semaphore.h>#include<math.h>#include<string.h>#include<sys/time.h>#include<time.h>#include"ForeNet.h"#include"MyDb.h"#include"IEC61850.h"#define PI 3.14159267#define LOWSPEED 0#define MIDDLESPEED 1#define HIGHSPEED 2#define POINTNUM 5//一次数据送的点数#define head 0#define tag 22#define asdulength_l 27 #define asdulength_h 26#define lname 30#define dlength 29static FILE *fhandle;extern void IEC61850Loop(char *user, struct pcap_pkthdr * pkthdr, u_char * pkt);extern void ProcessCheckData(void );extern bool ether_send(UBYTE *buf,int length,int d);extern void SendSlaveCommand(UBYTE *buffer,int length);float vector_multiply(float *vector1,float *vector2,int real_imag);float vector_add(float *vector1,float *vector2,float *vector3);float cacl_negative(float *phase_A ,float *phase_B ,float *phase_C);void RecordWave(long curpoint,long num,UBYTE type);void RecordCfgFile();void SendCreateFile();void SendRecordWaveStart();void SendRecordWaveEnd();extern short ycbuf[YCCHANNEL][YCID];extern short nsycbuf[YCCHANNEL][YCID];extern UBYTE nsyxbuf[YXCHANNEL][YXID];extern YcChannelCfg m_YcChannelCfg[YCCHANNEL];extern YcChannelCfg m_NsYcChannelCfg[YCCHANNEL];extern YxChannelCfg m_NsYxChannelCfg[YXCHANNEL];extern int NsYcStart,NsYxStart;extern float activeyc[YCCHANNEL];extern float nsactiveyc[YCCHANNEL];extern UBYTE msg[6];extern pthread_mutex_t mutex ,nsmutex,acmutex,nsacmutex,pmutex ,pnsmutex;static long count,nscount;static long chkcount;static long chknscount;static long sharepoint;const char *StationName = "四川数字变电站 ";extern int GetYcNum();extern int GetNsYcNum();extern int GetNsYxNum();static long iid = 1;static long ltime = 0;static int startflag[100] ,startflag_dc,startflagall;static char cfg_file[100],dat_file[100];UBYTE m_year , m_month,m_day,m_hour,m_minute,m_second;extern sem_t sem;typedef struct _TimeStruct{ int year; int month; int day; int hour; int minute; int sec; long usec;}TimeStruct;short costb[32]={ 0x7fff,0x7d8a,0x7642,0x6a6e,0x5a82,0x471d,0x30fc,0x18f9, 0x0000,0xe707,0xcf04,0xb8e3,0xa57e,0x9592,0x89be,0x8276, 0x8001,0x8276,0x89bf,0x9593,0xa57e,0xb8e4,0xcf05,0xe708, 0x0000,0x18f9,0x30fc,0x471d,0x5a82,0x6a6e,0x7642,0x7d8a};short sintb[32]={ 0x0000,0x18f9,0x30fc,0x471d,0x5a82,0x6a6e,0x7642,0x7d8a, 0x7fff,0x7d8a,0x7642,0x6a6e,0x5a82,0x471d,0x30fc,0x18f9, 0x0000,0xe708,0xcf05,0xb8e4,0xa57e,0x9593,0x89bf,0x8276, 0x8001,0x8276,0x89bf,0x9593,0xa57e,0xb8e4,0xcf05,0xe708};//取得新宁当前采样点位置void GetCurPoint(long *pos){ pthread_mutex_lock(&pmutex); *pos = count; pthread_mutex_unlock(&pmutex);}//取得南自科技当前采样点位置void GetCurNsPos(long *pos){ pthread_mutex_lock(&pnsmutex); *pos = nscount; pthread_mutex_unlock(&pnsmutex);}//设置新宁公司通道有效值,seiral从1开始void SetActiveValue(int serial,float value){ if(serial<1 || serial >YCCHANNEL) return ; pthread_mutex_lock(&acmutex); activeyc[serial-1] = value; pthread_mutex_unlock(&acmutex);}//获得新宁公司通道有效值,seiral从1开始void GetActiveValue(int serial,float *value){ if(serial<1 || serial >YCCHANNEL) return ; pthread_mutex_lock(&acmutex); *value = activeyc[serial-1]; pthread_mutex_unlock(&acmutex);}//设置科技公司通道有效值,seiral从1开始void SetNsActiveValue(int serial,float value){ if(serial<1 || serial >YCCHANNEL) return ; pthread_mutex_lock(&nsacmutex); nsactiveyc[serial-1] = value; pthread_mutex_unlock(&nsacmutex); }//获得科技公司通道有效值,seiral从1开始void GetNsActiveValue(int serial,float *value){ if(serial<1 || serial >YCCHANNEL) return ; pthread_mutex_lock(&nsacmutex); *value = nsactiveyc[serial-1]; pthread_mutex_unlock(&nsacmutex); }//设置新宁公司规约数据void SetValueYc(int serial,long id ,short ucvalue){ if(serial<1 || serial >YCCHANNEL) return ; pthread_mutex_lock(&mutex); ycbuf[serial-1][id-1] = ucvalue; pthread_mutex_unlock(&mutex); return;}//设置科技公司规约数据void SetNsValueYc(int serial,long id,short ucvalue){ if(serial<1 || serial >YCCHANNEL) //这里应该是初始化时获得的实际的遥测通道数目 return ; pthread_mutex_lock(&nsmutex); nsycbuf[serial-1][id-1] = ucvalue; pthread_mutex_unlock(&nsmutex); return;}//获得新宁公司指定通道中的规约数据,seiral通道号,id采样点号,均从1开始void GetValueYc(int serial,long cur,long id,short *ucvalue){ long tmp; if(serial<1 || serial >YCCHANNEL) return ; pthread_mutex_lock(&mutex); tmp = (cur-1)-(id-1); if(tmp<0) tmp = (YCID-1)-((int)fabs(tmp)-1); *ucvalue = ycbuf[serial-1][tmp]; pthread_mutex_unlock(&mutex); return;}//获得科技公司指定通道中的规约数据,seiral通道号,id采样点号,均从1开始void GetNsValueYc(int serial,long cur,long id,short *ucvalue){ long tmp; if(serial<1 || serial >YCCHANNEL) //这里应该是初始化时获得的实际的遥测通道数目 return ; pthread_mutex_lock(&nsmutex); tmp = (cur-1)-(id-1); if(tmp<0) tmp = (YCID-1)-((int)fabs(tmp)-1); *ucvalue = nsycbuf[serial-1][cur-id-1]; pthread_mutex_unlock(&nsmutex); return;}void SetNsValueYx(int serial,long id,UBYTE ucvalue){ if(serial<1 || serial >YXCHANNEL) return ; pthread_mutex_lock(&nsmutex); nsyxbuf[serial-1][id-1] = ucvalue; pthread_mutex_unlock(&nsmutex); return;}//获得科技公司指定通道中的遥信规约数据,seiral通道号,id采样点号,均从1开始void GetNsValueYx(int serial,long cur,long id,UBYTE *ucvalue){ if(serial<1 || serial >YXCHANNEL) return ; pthread_mutex_lock(&nsmutex); *ucvalue = nsyxbuf[serial-1][cur-id-1]; pthread_mutex_unlock(&nsmutex); return;}bool CheckHead(UBYTE *buf){ UBYTE *tmp; tmp = buf; UBYTE i; for(i=0;i<6;i++) if(*(buf+i)!=0xff) return false; return true; }void GetCurrentTime(TimeStruct *timestruct){ time_t timep; struct tm *p; struct timeval tv; struct timezone tz; time(&timep); p=gmtime(&timep); timestruct->year = p->tm_year+1900; m_year = timestruct->year-2000; timestruct->month = p->tm_mon+1; m_month = timestruct->month; timestruct->day = p->tm_mday; m_day = timestruct->day; printf("%d\n",p->tm_hour); p->tm_hour+=8; if(p->tm_hour>=24) p->tm_hour = p->tm_hour-24; m_hour = p->tm_hour; timestruct->hour = p->tm_hour; timestruct->minute = p->tm_min; m_minute = timestruct->minute; timestruct->sec = p->tm_sec; m_second = timestruct->sec; gettimeofday (&tv , &tz); timestruct->usec = tv.tv_usec; return;}void IEC61850Loop(char *user, struct pcap_pkthdr * pkthdr, u_char * pkt){ int iasdu_len ; int m; UBYTE tmp; short tmp_value; /* 这段代码处理新宁数据*/ if(CheckHead(pkt) == false) return; if(pkt[tag+4] == 0x80 && pkt[dlength+4] == 0x2c && pkt[lname+4] == 0x02) { iasdu_len = pkt[asdulength_h+4]*256+pkt[asdulength_l+4]; #ifdef _DEBUG // printf("asdu length = %d\n",iasdu_len); // printf("count = %d\n",chkcount);#endif for(int point = 0;point<iasdu_len;point++) { pthread_mutex_lock(&pmutex); count++; pthread_mutex_unlock(&pmutex); if(count>YCID) { count = 1; msg[4] = 0x04; SendSlaveCommand(msg,6); } for(int i=1;i<28;i++) { tmp_value =((pkt[34+(i-1)*2+point*64+4])*256+pkt[35+(i-1)*2+point*64+4]); SetValueYc(i,count,tmp_value); } } } /* 这段代码处理南自科技故障录波数据*/ if(pkt[6] == 0x10 && pkt[7] == 0xaa && pkt[8] == 0xa5 && pkt[9] == 0x5a && pkt[10]==0x50 && pkt[11] ==0x41) { for(int nspoint = 0;nspoint<5;nspoint++) { pthread_mutex_lock(&pnsmutex); nscount++; pthread_mutex_unlock(&pnsmutex); if(nscount>YCID) { nscount = 1; count = 1; msg[4] = 0x05; SendSlaveCommand(msg,6); } for(int i=1;i<7;i++) { tmp_value =((pkt[23+(i-1)*2+nspoint*28])*256+pkt[22+(i-1)*2+nspoint*28]); SetNsValueYc(i,nscount,tmp_value); } for(int n = 0;n<16;n++) { for(m = 1;m<9;m++) { if(((pkt[34+n+nspoint*28]<<(8-m))&0x80)) tmp = 0; else tmp = 1; SetNsValueYx(n*8+m,nscount,tmp); } } } } return ;}void ProcessCheckData(){ int i,j; BYTE serial_new,id_new; short uclvalue_ns, uchvalue_ns; short value_h,nsvalue; /* int value_wave[32]; float value[96],value_p[24],value_n[24],value_dc[12]; int di[8]; int faulttime[32][8]; int faulttime_ns[12]; long sumdc ; int r,ptr,fft_ptr,iw,id,c1,c2,c3; long r_vector,i_vector; float qq1,qq2,qq3; int h; float sum ; long fft_r[32]; long fft_i[32]; long fft_ad_sample[32]; float fft_value[16]; float FFT_RI[96][2] ; float redress; float COEFFICIENT; */ short value_wave[32]; float value[96],value_p[24],value_n[24],value_dc[12]; short di[8]; short faulttime[32][8]; short faulttime_ns[12]; long sumdc ; short r,ptr,fft_ptr,iw,id,c1,c2,c3; int r_vector,i_vector; float qq1,qq2,qq3; short h; float sum ; int fft_r[32]; int fft_i[32]; int fft_ad_sample[32]; int fft_value[16]; float FFT_RI[96][2] ; int redress; float COEFFICIENT; long point,point_dc; double dmin; int old; int flag = 0; sleep(10);//等待数据充满缓存区 while(1) { GetCurPoint(&point); GetCurNsPos(&point_dc); #ifdef _DEBUG // printf("CURRENT POSITION IS %d\n",point);#endif for(j=0;j<GetYcNum() ;j++) { double v=0.0; float Re=0,Im=0; for(i=0;i<100;i++) { GetValueYc (j+1,point,i+1,&value_h); Re+=value_h*cos(PI*i/50); Im-=value_h*sin(PI*i/50); } dmin = sqrt((Re*Re+Im*Im)/2)/50; //dmin = dmin*0.00497;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -