An mbed implementation of IEC 61850-9-2LE Sample Values. Creating using the rapid61850 library, available at: https://github.com/stevenblair/rapid61850.

Dependencies:   mbed

An mbed implementation of IEC 61850-9-2LE Sample Values. Creating using the rapid61850 library, available at: https://github.com/stevenblair/rapid61850.

Committer:
sblair
Date:
Tue Oct 02 21:31:05 2012 +0000
Revision:
0:f09b7bb8bcce
converted library to folder

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sblair 0:f09b7bb8bcce 1 /**
sblair 0:f09b7bb8bcce 2 * IEC 61850-9-2LE Sampled Values demonstration
sblair 0:f09b7bb8bcce 3 *
sblair 0:f09b7bb8bcce 4 * Copyright (c) 2012 Steven Blair
sblair 0:f09b7bb8bcce 5 *
sblair 0:f09b7bb8bcce 6 * This program is free software; you can redistribute it and/or
sblair 0:f09b7bb8bcce 7 * modify it under the terms of the GNU General Public License
sblair 0:f09b7bb8bcce 8 * as published by the Free Software Foundation; either version 2
sblair 0:f09b7bb8bcce 9 * of the License, or (at your option) any later version.
sblair 0:f09b7bb8bcce 10
sblair 0:f09b7bb8bcce 11 * This program is distributed in the hope that it will be useful,
sblair 0:f09b7bb8bcce 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
sblair 0:f09b7bb8bcce 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
sblair 0:f09b7bb8bcce 14 * GNU General Public License for more details.
sblair 0:f09b7bb8bcce 15
sblair 0:f09b7bb8bcce 16 * You should have received a copy of the GNU General Public License
sblair 0:f09b7bb8bcce 17 * along with this program; if not, write to the Free Software
sblair 0:f09b7bb8bcce 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
sblair 0:f09b7bb8bcce 19 */
sblair 0:f09b7bb8bcce 20
sblair 0:f09b7bb8bcce 21 #include "mbed.h"
sblair 0:f09b7bb8bcce 22 #include "iec61850.h"
sblair 0:f09b7bb8bcce 23
sblair 0:f09b7bb8bcce 24 #include <stdio.h>
sblair 0:f09b7bb8bcce 25
sblair 0:f09b7bb8bcce 26 #define NUMBER_OF_SIGNALS 8
sblair 0:f09b7bb8bcce 27 #define NUMBER_OF_SIGNALS_PHASES 6
sblair 0:f09b7bb8bcce 28 #define NUMBER_OF_SAMPLES 80
sblair 0:f09b7bb8bcce 29
sblair 0:f09b7bb8bcce 30 #define PI 3.1415926535897932384626433832795f
sblair 0:f09b7bb8bcce 31 #define TWO_PI 6.283185307179586476925286766559f
sblair 0:f09b7bb8bcce 32 #define TWO_PI_OVER_THREE 2.0943951023931954923084289221863f
sblair 0:f09b7bb8bcce 33
sblair 0:f09b7bb8bcce 34
sblair 0:f09b7bb8bcce 35 CTYPE_INT32 signal[NUMBER_OF_SIGNALS_PHASES][NUMBER_OF_SAMPLES] = {0};
sblair 0:f09b7bb8bcce 36
sblair 0:f09b7bb8bcce 37 float phi = 0.1 * PI; // phase angle between voltage and current (rad)
sblair 0:f09b7bb8bcce 38 float freq = 50.0; // frequency of waveforms (Hz)
sblair 0:f09b7bb8bcce 39 float w = 2.0 * PI * freq;
sblair 0:f09b7bb8bcce 40 float Ts = 250e-6; // timestep; should equal 1 / (freq * NUMBER_OF_SAMPLES)
sblair 0:f09b7bb8bcce 41 float V = 8981.462390205; // voltage magnitude; equals 11 kV * sqrt(2) / sqrt(3)
sblair 0:f09b7bb8bcce 42 float Zmag = 15.0; // impedance magnitude - defines the current magnitude
sblair 0:f09b7bb8bcce 43 float harmonic = 7; // harmonic number
sblair 0:f09b7bb8bcce 44 float harmonicMagPu = 0.03; // harmonic magnitude (p.u.); set to zero to ignore
sblair 0:f09b7bb8bcce 45
sblair 0:f09b7bb8bcce 46 unsigned char buf[1024] = {0};
sblair 0:f09b7bb8bcce 47 int len = 0;
sblair 0:f09b7bb8bcce 48
sblair 0:f09b7bb8bcce 49 DigitalOut watchdogLED(LED1);
sblair 0:f09b7bb8bcce 50 DigitalOut ethLink(p29);
sblair 0:f09b7bb8bcce 51 DigitalOut ethAct(p30);
sblair 0:f09b7bb8bcce 52 Ethernet eth;
sblair 0:f09b7bb8bcce 53 Ticker sv;
sblair 0:f09b7bb8bcce 54
sblair 0:f09b7bb8bcce 55 /**
sblair 0:f09b7bb8bcce 56 * Pre-calculate all voltage and current samples (only possible if exactly 50 Hz frequency is used).
sblair 0:f09b7bb8bcce 57 */
sblair 0:f09b7bb8bcce 58 void preCalculate() {
sblair 0:f09b7bb8bcce 59 int t = 0;
sblair 0:f09b7bb8bcce 60 for (t = 0; t < NUMBER_OF_SAMPLES; t++) {
sblair 0:f09b7bb8bcce 61 double theta = w * (((float) t) * Ts);
sblair 0:f09b7bb8bcce 62
sblair 0:f09b7bb8bcce 63 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)));
sblair 0:f09b7bb8bcce 64 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));
sblair 0:f09b7bb8bcce 65 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));
sblair 0:f09b7bb8bcce 66
sblair 0:f09b7bb8bcce 67 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);
sblair 0:f09b7bb8bcce 68 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);
sblair 0:f09b7bb8bcce 69 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);
sblair 0:f09b7bb8bcce 70 }
sblair 0:f09b7bb8bcce 71 }
sblair 0:f09b7bb8bcce 72
sblair 0:f09b7bb8bcce 73 /**
sblair 0:f09b7bb8bcce 74 * Transmit the next set of samples.
sblair 0:f09b7bb8bcce 75 */
sblair 0:f09b7bb8bcce 76 void svSnapshot() {
sblair 0:f09b7bb8bcce 77 static int t = 0;
sblair 0:f09b7bb8bcce 78
sblair 0:f09b7bb8bcce 79 LE_IED.S1.MUnn.IEC_61850_9_2LETVTR_1.Vol.instMag.i = signal[0][t];
sblair 0:f09b7bb8bcce 80 LE_IED.S1.MUnn.IEC_61850_9_2LETVTR_2.Vol.instMag.i = signal[1][t];
sblair 0:f09b7bb8bcce 81 LE_IED.S1.MUnn.IEC_61850_9_2LETVTR_3.Vol.instMag.i = signal[2][t];
sblair 0:f09b7bb8bcce 82 LE_IED.S1.MUnn.IEC_61850_9_2LETVTR_4.Vol.instMag.i = 0;
sblair 0:f09b7bb8bcce 83
sblair 0:f09b7bb8bcce 84 LE_IED.S1.MUnn.IEC_61850_9_2LETCTR_1.Amp.instMag.i = signal[3][t];
sblair 0:f09b7bb8bcce 85 LE_IED.S1.MUnn.IEC_61850_9_2LETCTR_2.Amp.instMag.i = signal[4][t];
sblair 0:f09b7bb8bcce 86 LE_IED.S1.MUnn.IEC_61850_9_2LETCTR_3.Amp.instMag.i = signal[5][t];
sblair 0:f09b7bb8bcce 87 LE_IED.S1.MUnn.IEC_61850_9_2LETCTR_4.Amp.instMag.i = 0;
sblair 0:f09b7bb8bcce 88
sblair 0:f09b7bb8bcce 89 len = sv_update_LE_IED_MUnn_MSVCB01(buf);
sblair 0:f09b7bb8bcce 90
sblair 0:f09b7bb8bcce 91 if (len > 0) {
sblair 0:f09b7bb8bcce 92 ethAct = 1;
sblair 0:f09b7bb8bcce 93 eth.write((const char *) buf, len);
sblair 0:f09b7bb8bcce 94 eth.send();
sblair 0:f09b7bb8bcce 95 ethAct = 0;
sblair 0:f09b7bb8bcce 96 }
sblair 0:f09b7bb8bcce 97
sblair 0:f09b7bb8bcce 98 if (++t >= NUMBER_OF_SAMPLES) {
sblair 0:f09b7bb8bcce 99 t = 0;
sblair 0:f09b7bb8bcce 100 }
sblair 0:f09b7bb8bcce 101 }
sblair 0:f09b7bb8bcce 102
sblair 0:f09b7bb8bcce 103 /**
sblair 0:f09b7bb8bcce 104 * Overriding this function sets the MAC address.
sblair 0:f09b7bb8bcce 105 * Set to the destination MAC of all received SV or GOOSE packets to simplify hardware MAC filtering.
sblair 0:f09b7bb8bcce 106 */
sblair 0:f09b7bb8bcce 107 extern "C" void mbed_mac_address(char *s) {
sblair 0:f09b7bb8bcce 108 char mac[6];
sblair 0:f09b7bb8bcce 109
sblair 0:f09b7bb8bcce 110 mac[0] = 0x01;
sblair 0:f09b7bb8bcce 111 mac[1] = 0x0C;
sblair 0:f09b7bb8bcce 112 mac[2] = 0xCD;
sblair 0:f09b7bb8bcce 113 mac[3] = 0x04;
sblair 0:f09b7bb8bcce 114 mac[4] = 0x00;
sblair 0:f09b7bb8bcce 115 mac[5] = 0x00;
sblair 0:f09b7bb8bcce 116
sblair 0:f09b7bb8bcce 117 memcpy(s, mac, 6);
sblair 0:f09b7bb8bcce 118 }
sblair 0:f09b7bb8bcce 119
sblair 0:f09b7bb8bcce 120 int main() {
sblair 0:f09b7bb8bcce 121 initialise_iec61850();
sblair 0:f09b7bb8bcce 122
sblair 0:f09b7bb8bcce 123 // enable hardware MAC address filtering
sblair 0:f09b7bb8bcce 124 LPC_EMAC->RxFilterCtrl = 1 << 5;
sblair 0:f09b7bb8bcce 125
sblair 0:f09b7bb8bcce 126 eth.set_link(eth.FullDuplex100);
sblair 0:f09b7bb8bcce 127 while (!eth.link()) {
sblair 0:f09b7bb8bcce 128 wait(1);
sblair 0:f09b7bb8bcce 129 }
sblair 0:f09b7bb8bcce 130 ethLink = 1;
sblair 0:f09b7bb8bcce 131
sblair 0:f09b7bb8bcce 132 wait(1);
sblair 0:f09b7bb8bcce 133
sblair 0:f09b7bb8bcce 134 preCalculate();
sblair 0:f09b7bb8bcce 135
sblair 0:f09b7bb8bcce 136 sv.attach_us(&svSnapshot, 250); // create 250 us (for 50 Hz, 80 samples/cycle) periodic timer
sblair 0:f09b7bb8bcce 137
sblair 0:f09b7bb8bcce 138 // loop forever, toggling LED
sblair 0:f09b7bb8bcce 139 while(1) {
sblair 0:f09b7bb8bcce 140 watchdogLED = 1;
sblair 0:f09b7bb8bcce 141 wait(0.01);
sblair 0:f09b7bb8bcce 142 watchdogLED = 0;
sblair 0:f09b7bb8bcce 143 wait(2);
sblair 0:f09b7bb8bcce 144 }
sblair 0:f09b7bb8bcce 145 }