An mbed implementation of IEC 61850-9-2LE Sample Values. Creating using the rapid61850 library, available at: https://github.com/stevenblair/rapid61850.
An mbed implementation of IEC 61850-9-2LE Sample Values. Creating using the rapid61850 library, available at: https://github.com/stevenblair/rapid61850.
main.cpp@0:f09b7bb8bcce, 2012-10-02 (annotated)
- Committer:
- sblair
- Date:
- Tue Oct 02 21:31:05 2012 +0000
- Revision:
- 0:f09b7bb8bcce
converted library to folder
Who changed what in which revision?
User | Revision | Line number | New 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 | } |