An mbed implementation of IEC 61850-9-2LE Sample Values. Creating using the rapid61850 library, available at: https://github.com/stevenblair/rapid61850.
main.cpp
00001 /** 00002 * IEC 61850-9-2LE Sampled Values demonstration 00003 * 00004 * Copyright (c) 2012 Steven Blair 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 */ 00020 00021 #include "mbed.h" 00022 #include "iec61850.h" 00023 00024 #include <stdio.h> 00025 00026 #define NUMBER_OF_SIGNALS 8 00027 #define NUMBER_OF_SIGNALS_PHASES 6 00028 #define NUMBER_OF_SAMPLES 80 00029 00030 #define PI 3.1415926535897932384626433832795f 00031 #define TWO_PI 6.283185307179586476925286766559f 00032 #define TWO_PI_OVER_THREE 2.0943951023931954923084289221863f 00033 00034 00035 CTYPE_INT32 signal[NUMBER_OF_SIGNALS_PHASES][NUMBER_OF_SAMPLES] = {0}; 00036 00037 float phi = 0.1 * PI; // phase angle between voltage and current (rad) 00038 float freq = 50.0; // frequency of waveforms (Hz) 00039 float w = 2.0 * PI * freq; 00040 float Ts = 250e-6; // timestep; should equal 1 / (freq * NUMBER_OF_SAMPLES) 00041 float V = 8981.462390205; // voltage magnitude; equals 11 kV * sqrt(2) / sqrt(3) 00042 float Zmag = 15.0; // impedance magnitude - defines the current magnitude 00043 float harmonic = 7; // harmonic number 00044 float harmonicMagPu = 0.03; // harmonic magnitude (p.u.); set to zero to ignore 00045 00046 unsigned char buf[1024] = {0}; 00047 int len = 0; 00048 00049 DigitalOut watchdogLED(LED1); 00050 DigitalOut ethLink(p29); 00051 DigitalOut ethAct(p30); 00052 Ethernet eth; 00053 Ticker sv; 00054 00055 /** 00056 * Pre-calculate all voltage and current samples (only possible if exactly 50 Hz frequency is used). 00057 */ 00058 void preCalculate() { 00059 int t = 0; 00060 for (t = 0; t < NUMBER_OF_SAMPLES; t++) { 00061 double theta = w * (((float) t) * Ts); 00062 00063 signal[0][t] = (CTYPE_INT32) (V * sin(theta) / ((float) LE_IED.S1.MUnn.IEC_61850_9_2LETVTR_1.Vol.sVC.scaleFactor) + (V * harmonicMagPu * sin(theta * harmonic) / ((float) LE_IED.S1.MUnn.IEC_61850_9_2LETVTR_1.Vol.sVC.scaleFactor))); 00064 signal[1][t] = (CTYPE_INT32) (V * sin(theta - TWO_PI_OVER_THREE) / LE_IED.S1.MUnn.IEC_61850_9_2LETVTR_2.Vol.sVC.scaleFactor) + (V * harmonicMagPu * sin(theta * harmonic - TWO_PI_OVER_THREE) / ((float) LE_IED.S1.MUnn.IEC_61850_9_2LETVTR_1.Vol.sVC.scaleFactor)); 00065 signal[2][t] = (CTYPE_INT32) (V * sin(theta + TWO_PI_OVER_THREE) / LE_IED.S1.MUnn.IEC_61850_9_2LETVTR_3.Vol.sVC.scaleFactor) + (V * harmonicMagPu * sin(theta * harmonic + TWO_PI_OVER_THREE) / ((float) LE_IED.S1.MUnn.IEC_61850_9_2LETVTR_1.Vol.sVC.scaleFactor)); 00066 00067 signal[3][t] = (CTYPE_INT32) ((V / Zmag) * sin(theta - phi) / LE_IED.S1.MUnn.IEC_61850_9_2LETCTR_1.Amp.sVC.scaleFactor) + ((harmonicMagPu * V / Zmag) * sin(theta * harmonic - phi) / LE_IED.S1.MUnn.IEC_61850_9_2LETCTR_1.Amp.sVC.scaleFactor); 00068 signal[4][t] = (CTYPE_INT32) ((V / Zmag) * sin(theta - phi - TWO_PI_OVER_THREE) / LE_IED.S1.MUnn.IEC_61850_9_2LETCTR_2.Amp.sVC.scaleFactor) + ((harmonicMagPu * V / Zmag) * sin(theta * harmonic - phi - TWO_PI_OVER_THREE) / LE_IED.S1.MUnn.IEC_61850_9_2LETCTR_2.Amp.sVC.scaleFactor); 00069 signal[5][t] = (CTYPE_INT32) ((V / Zmag) * sin(theta - phi + TWO_PI_OVER_THREE) / LE_IED.S1.MUnn.IEC_61850_9_2LETCTR_3.Amp.sVC.scaleFactor) + ((harmonicMagPu * V / Zmag) * sin(theta * harmonic - phi + TWO_PI_OVER_THREE) / LE_IED.S1.MUnn.IEC_61850_9_2LETCTR_3.Amp.sVC.scaleFactor); 00070 } 00071 } 00072 00073 /** 00074 * Transmit the next set of samples. 00075 */ 00076 void svSnapshot() { 00077 static int t = 0; 00078 00079 LE_IED.S1.MUnn.IEC_61850_9_2LETVTR_1.Vol.instMag.i = signal[0][t]; 00080 LE_IED.S1.MUnn.IEC_61850_9_2LETVTR_2.Vol.instMag.i = signal[1][t]; 00081 LE_IED.S1.MUnn.IEC_61850_9_2LETVTR_3.Vol.instMag.i = signal[2][t]; 00082 LE_IED.S1.MUnn.IEC_61850_9_2LETVTR_4.Vol.instMag.i = 0; 00083 00084 LE_IED.S1.MUnn.IEC_61850_9_2LETCTR_1.Amp.instMag.i = signal[3][t]; 00085 LE_IED.S1.MUnn.IEC_61850_9_2LETCTR_2.Amp.instMag.i = signal[4][t]; 00086 LE_IED.S1.MUnn.IEC_61850_9_2LETCTR_3.Amp.instMag.i = signal[5][t]; 00087 LE_IED.S1.MUnn.IEC_61850_9_2LETCTR_4.Amp.instMag.i = 0; 00088 00089 len = sv_update_LE_IED_MUnn_MSVCB01(buf); 00090 00091 if (len > 0) { 00092 ethAct = 1; 00093 eth.write((const char *) buf, len); 00094 eth.send(); 00095 ethAct = 0; 00096 } 00097 00098 if (++t >= NUMBER_OF_SAMPLES) { 00099 t = 0; 00100 } 00101 } 00102 00103 /** 00104 * Overriding this function sets the MAC address. 00105 * Set to the destination MAC of all received SV or GOOSE packets to simplify hardware MAC filtering. 00106 */ 00107 extern "C" void mbed_mac_address(char *s) { 00108 char mac[6]; 00109 00110 mac[0] = 0x01; 00111 mac[1] = 0x0C; 00112 mac[2] = 0xCD; 00113 mac[3] = 0x04; 00114 mac[4] = 0x00; 00115 mac[5] = 0x00; 00116 00117 memcpy(s, mac, 6); 00118 } 00119 00120 int main() { 00121 initialise_iec61850(); 00122 00123 // enable hardware MAC address filtering 00124 LPC_EMAC->RxFilterCtrl = 1 << 5; 00125 00126 eth.set_link(eth.FullDuplex100); 00127 while (!eth.link()) { 00128 wait(1); 00129 } 00130 ethLink = 1; 00131 00132 wait(1); 00133 00134 preCalculate(); 00135 00136 sv.attach_us(&svSnapshot, 250); // create 250 us (for 50 Hz, 80 samples/cycle) periodic timer 00137 00138 // loop forever, toggling LED 00139 while(1) { 00140 watchdogLED = 1; 00141 wait(0.01); 00142 watchdogLED = 0; 00143 wait(2); 00144 } 00145 }
Generated on Sat Jul 23 2022 01:15:10 by 1.7.2