K22F Power Conditioner

Dependencies:   NetworkServices W5500Interface

main.cpp

Committer:
dgriffin65
Date:
2017-06-15
Revision:
2:ab7e8b9c7903
Parent:
1:f857c10c3cd2

File content as of revision 2:ab7e8b9c7903:

#include "mbed.h"
#include "W5500Interface.h"
#include "Websocket.h"
#include "SNTPClient.h"
#include "DHCPClient.h"
#include "DNSClient.h"
#include "HTTPD.h"
#include "config.h"


//** prototypes ****************************************************************
int getCuspp(const char* cmd, char* out);

//******************************************************************************

#define READBUFFERSIZE (32)

RawSerial pc(USBTX, USBRX);
char pcRxBuffer[32]; //port C RX Buffer

DigitalIn sw2(SW2);
DigitalIn sw3(SW3);
InterruptIn zeroCross(A2);//Arduino A2
Timer halfCycle;
Ticker freqGen;
Ticker sampler;
DigitalOut do1(D7);//Arduino D7
DigitalOut do2(D6);//Arduino D6
AnalogIn Vrms(A0);
AnalogIn Arms(A1);
//LocalFileSystem local("local");
//FlashIAP flash;

int    flip = 0;
int    halfPeriod = 16600;
float  freq = 60;
float  period = 0;
double setFreq = 50.00;
double periodFreqGen;
float  Vsample[32];
float  Asample[32];
int    sample = 0;
int    sampleMax = 0;
float  Vhold[32];
float  Ahold[32];
int    cycleFlag = 0;
double VsumSq = 0;
double Vmean = 0;
double Vroot = 0;
double AsumSq = 0;
double Amean = 0;
double Aroot = 0;
float  VA;
int    PercentLoad = 0;

char k = 0;
char c;
int i;
int j;

//*****************************************************************************

//** NETWORKING ***************************************************************

DHCPClient dhcp;
DNSClient  dns;
HTTPD      httpd;
NetworkStack* ns;

void httpdJson (int id) {
    httpd.hprintf(id, "{\n");
    httpd.hprintf(id, "\"UID.MANUF\":\"%s\",\n",   "AMETEK-POWERVAR");
    httpd.hprintf(id, "\"UID.MODEL\":\"%s\",\n",   MODEL);
    httpd.hprintf(id, "\"UID.ULMODEL\":\"%s\",\n", "ABC");
    httpd.hprintf(id, "\"UID.SERNUM\":\"%s\",\n",  SERIALNO);
    httpd.hprintf(id, "\"UID.FAMILY\":\"%s\",\n",  "Power Conditioner");
    httpd.hprintf(id, "\"OUT.FREQ\":%3.1f,\n",     freq);
    httpd.hprintf(id, "\"OUT.VOLT\":%3.1f,\n",     Vroot);
    httpd.hprintf(id, "\"OUT.AMP\":%3.1f,\n",      Aroot);
    httpd.hprintf(id, "\"OUT.PWR\":%.0f,\n",       VA);
    httpd.hprintf(id, "\"OUT.PERCNT\":%d,\n",      PercentLoad);
    httpd.hprintf(id, "\"SYS.INVOLT\":%d,\n",      NOMV);
    httpd.hprintf(id, "\"SYS.INFRQ\":%d,\n",       NOMF);
    httpd.hprintf(id, "\"SYS.OUTVLT\":%d,\n",      NOMV);
    httpd.hprintf(id, "\"SYS.OUTFRQ\":%d,\n",      NOMF);
    httpd.hprintf(id, "\"SYS.OUTVA\":%d,\n",       NOMVA);
    httpd.hprintf(id, "\"SYS.OUTPWR\":%d,\n",      NOMVA);
    httpd.hprintf(id, "}\n");
}

void httpdCuspp (int id) {
    const char* qs = httpd.getQueryString(id);
    char out[256];
    
    if (qs == NULL) {
        getCuspp("PID.FORMAT", out);
        httpd.hprintf(id, out);

        getCuspp("PID", out);
        httpd.hprintf(id, out);

        getCuspp("UID.FORMAT", out);
        httpd.hprintf(id, out);

        getCuspp("UID", out);
        httpd.hprintf(id, out);

        getCuspp("OUT.FORMAT", out);
        httpd.hprintf(id, out);

        getCuspp("OUT", out);
        httpd.hprintf(id, out);

        getCuspp("SYS.FORMAT", out);
        httpd.hprintf(id, out);

        getCuspp("SYS", out);
        httpd.hprintf(id, out);
        
        return;
    }
    
    if (!strcmp(qs, "JSON")) {
        httpdJson(id);
    } else {
        getCuspp(qs, out);
        httpd.hprintf(id, out);
    }
}

int startNetworking() {

#if defined(TARGET_K22F)
    SPI *spi = new SPI(D11, D12, D13); // mosi, miso, sclk
    //eth = new W5500Interface(D11, D12, D13, D10, D9);
    W5500Interface* eth = new W5500Interface(spi, D10, D9);//D10 CS, D9 Reset
    ns = eth;

    spi->format(8,0); // 8bit, mode 0
    spi->frequency(7000000); // 7MHz
    wait(1); // 1 second for stable state
#endif

    printf("\r\n");  
    printf("DHCP Started, waiting for IP...\r\n");  
    int timeout_ms = 15*1000;
    int err = dhcp.setup(eth, timeout_ms);
    if (err == (-1)) {
        printf("Timeout.\n");
        return -1;
    }
    
    printf("Connected, IP: %d.%d.%d.%d\r\n", dhcp.yiaddr[0], dhcp.yiaddr[1], dhcp.yiaddr[2], dhcp.yiaddr[3]);
    
    char ip[24], gateway[24], netmask[24], dnsaddr[24];
    sprintf(ip,      "%d.%d.%d.%d", dhcp.yiaddr[0],  dhcp.yiaddr[1],  dhcp.yiaddr[2],  dhcp.yiaddr[3]);
    sprintf(gateway, "%d.%d.%d.%d", dhcp.gateway[0], dhcp.gateway[1], dhcp.gateway[2], dhcp.gateway[3]);
    sprintf(netmask, "%d.%d.%d.%d", dhcp.netmask[0], dhcp.netmask[1], dhcp.netmask[2], dhcp.netmask[3]);
    sprintf(dnsaddr, "%d.%d.%d.%d", dhcp.dnsaddr[0], dhcp.dnsaddr[1], dhcp.dnsaddr[2], dhcp.dnsaddr[3]);
    
    eth->init(ip, netmask, gateway);
    eth->connect();
    printf("IP Address is %s\r\n", eth->get_ip_address());
    printf("DNS Address is %s\r\n", dnsaddr);

    dns.setup(eth);
    dns.set_server(dnsaddr);
    
    httpd.attach ("/CUSPP", &httpdCuspp);
    httpd.attach ("/cuspp", &httpdCuspp);
    httpd.attach ("/JSON",  &httpdJson);
    httpd.attach ("/json",  &httpdJson);
    httpd.start(eth);
    return 0;
}

//** NETWORKING ***************************************************************

Thread *_thdCuspp = NULL;

void pcRxCallback()
{
    static char tempBuffer[32];
    do1 = 1;
    c = pc.getc();
    do1 = 0;
    tempBuffer[k] = c;
    k++;
    do1 = 1;
    if ( c == '\n' )
    {
        k = 0;
        strncpy(pcRxBuffer,tempBuffer,sizeof(tempBuffer));
        memset(tempBuffer,0,sizeof(tempBuffer));
        //signal the CUSPP thread to process the command
        if (_thdCuspp) _thdCuspp->signal_set(1);
    }
    //pc.printf("\n%s\n", pcRxBuffer); //echo back to terminal
    do1 = 0;
}

void sampleTimer()
{
    do2 = 1;
    Asample[sample] = ( 1 / 0.34286 ) * 3.3 * Arms.read();
    Vsample[sample] = 64.7519 * 3.3 * Vrms.read();
    sample++;
    if ( sample == 33 ) //In case there is no zero cross signal
    {
        sample = 0;
        cycleFlag = 1;
    }
    do2 = 0;
}

void startMeasFreq()
{
    halfCycle.start();
    sampler.detach();
    sampler.attach(&sampleTimer, (periodFreqGen / 32) );
    for (j = 0; j < 32; j++) {
        Vhold[j] = Vsample[j];
        Ahold[j] = Asample[j];
    }
    cycleFlag = 1;
    sampleMax = sample;
    sample = 0; //Reset the sample counter
}

void stopMeasFreq()
{
    halfPeriod = ( halfPeriod + halfCycle.read_us() ) /2;
    halfCycle.stop();
    halfCycle.reset();
}  

int getCuspp(const char* cmd, char* out) {  
    if (strncmp (cmd, "PID.FORMAT",10) == 0) 
    {
        sprintf(out, "PID.FORMAT=PROT;VER;UID;BAT;BTM;INP;OUT;ALM;TST;SET;PDU;SYS;OEM;BUZ\n");
    } else if (strncmp (cmd,"PID",3) == 0) 
    {
        sprintf(out, "PID=CUSPP;1.13;1;0;0;0;1;0;0;0;0;1;0;0\n");
    } else if (strncmp (cmd, "UID.FORMAT",10) == 0) 
    {
        sprintf(out, "UID.FORMAT=MANUF.N;MODEL.N;ULMODEL.N;FAMILY.N;SWVER.N;CSWVER.N;NAME.W;SERNUM.P;MFGDT.P\n");
    } else if (strncmp (cmd,"UID",3) == 0) 
    {
        sprintf(out, "UID=AMETEK-POWERVAR;%s;ABC;PowerCond;0;0;%s;%s;20150715\n", MODEL, "Power Conditioner", SERIALNO);
    } else if (strncmp (cmd,"SYS.FORMAT",10) == 0) 
    {
        sprintf(out, "SYS.FORMAT=TOPLGY.N;INVOLT.N;INFRQ.N;INPHS.N;OUTVLT.N;OUTFRQ.N;OUTVA.N;OUTPWR.N;OUTPHS.N;HITEMP.W;OUTQTY.N;OVRLOD.W\n");
    } else if (strncmp (cmd,"SYS",3) == 0) 
    {
        sprintf(out, "SYS=0;%d;%d;1;%d;%d.%d;%d;1;35;1;100\n", NOMV, NOMF, NOMV, NOMF, NOMVA, NOMVA);
    } else if (strncmp (cmd,"OUT.FORMAT",10) == 0) 
    {
        sprintf(out, "OUT.FORMAT=SOURCE.N;FREQ.N;VOLT.N;AMP.N;PWR.N;PERCNT.N\n");
    } else if (strncmp (cmd,"OUT",3) == 0) 
    {
        sprintf(out, "OUT=0;%3.1f;%3.1f;%3.1f:%.0f;%d\n", freq, Vroot, Aroot, VA, PercentLoad);
    } else if ((cmd[0]) != 0) 
    {
        sprintf(out, "?\n");
    } else {
        return -1;
    }
    return 0;
}

void thdCuspp () {
    static char out[256];
    do1 = 0;
    do2 = 0;

    //wait for the serial port to become readable
    while(pc.readable()) {
        //char e = pc.getc();
        wait(0.1);
    }

    //initialize the rx buffer
    memset(pcRxBuffer,0,sizeof(pcRxBuffer));

    pc.attach(&pcRxCallback, pc.RxIrq);//Serial::RxIrq);
    
    //wait for a cuspp command
    while(true) {
        //wait for signal from interrupt handler
        printf("thdCuspp waiting for a signal from interrupt handler\n");
        Thread::signal_wait(1);
        printf("thdCuspp got a signal from interrupt handler\n");
        if (getCuspp(pcRxBuffer, out) == 0) {
            pc.printf(out);
            memset(pcRxBuffer,0,sizeof(pcRxBuffer));
        }
    }
}

int main()
{
    //NVIC_SetPriority(PORTC_IRQn, 2);
    pc.baud(115200);
    pc.printf("\n\nFRDM-K22F Power Conditioner.\n\n");

    //start the networking services
    startNetworking();

    //start the CUSPP protocol thread
    _thdCuspp = new Thread(osPriorityNormal, 1024);
    _thdCuspp->start(thdCuspp);

    wait(2.0);
 
    periodFreqGen = ( ( 1 / freq ) );
    sampler.attach(&sampleTimer, (periodFreqGen / 32) );
    zeroCross.fall(&startMeasFreq);
    zeroCross.rise(&stopMeasFreq);
    
    while(1) 
    {
        period = halfPeriod * 2;
        freq = 0.5 * ( 1000000 / halfPeriod );

        if (cycleFlag == 1) 
        {
            for (i=0; i<32; i++) 
            {
                VsumSq = VsumSq + (Vhold[i] * Vhold[i]);
                AsumSq = AsumSq + (Ahold[i] * Ahold[i]);
            }
            Vmean = VsumSq / 32;
            Amean = AsumSq / 32;
            Vroot = ( Vroot + sqrt(Vmean) ) / 2;
            Aroot = ( Aroot + sqrt(Amean) ) / 2;
            VA = Vroot * Aroot;
            PercentLoad = (int)(100 * ( VA / NOMVA ));

            VsumSq = 0;
            AsumSq = 0;
            cycleFlag = 0;
        }
        
        wait(1.0);
    }
}