Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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