Working version

Dependencies:   mbed mbed-rtos SDFileSystem EthernetInterface DS1820

main.cpp

Committer:
soren51929277
Date:
2019-11-22
Revision:
1:dce8f2a2d706
Parent:
0:ad2d0aa4726b

File content as of revision 1:dce8f2a2d706:

/*Current regulator software----------------------------------------------------
Project: TTEM2 current regulator
Date: 16/05-17
Name: Søren Møller Dath
Target: NXP FRDM-K64F rev E3 MBED platform
Description: 
Input: temperature, voltage from PAPC program thrugh UDP protocol
Input: Setup file through UDP protocol send from PC. Values are stored on 
microSD card and read at startup
Output: Spi signal controlling digital potentiometer for changing gate voltage 
for a MOSFET controlling the current for the TTEM2 TX system
Output: PWM control of fan and pump for cooling system, and buzzer alarm for low 
voltage and high temperature.
Output: Debug information through terminal
------------------------------------------------------------------------------*/
/*
mbed
PWM ALARM OG FAN SKAL BYTTES OM
Nyt pin til ds1822 temp sensor
*/

//INCLUDES----------------------------------------------------------------------
#include "mbed.h"
#include "EthernetInterface.h"
#include "SDFileSystem.h"
#include "DS1820.h"
#include <stdint.h>

//DEFINES-----------------------------------------------------------------------
#define Debug 0         //Set to 1 for debug mode, 0 for normal

//CONSTANTS---------------------------------------------------------------------
const int board_PORT = 20;
const int pc_PORT = 30;


static const char* SERVER_IP = "192.168.1.5"; //IP of server (pc)
static const char* CLIENT_IP = "192.168.1.4"; //IP of client (MBED board) 0.102
static const char* MASK = "255.255.255.0";    //mask
static const char* GATEWAY = "192.168.1.1";   //gateway

//STRUCTS-----------------------------------------------------------------------
typedef struct {                                    //Data received from PAPC through UDP Ethernet
    char CtrlType;                                  //Must be 1
    float Temperature;                              //Measured temperature for MOSFETs
    float SetOutput;                                //output from controller (Not used)
    float Error;                                    //Error between Iset and Current (Not used)
    float Iset;                                     //Setpoint value for current (Not used)
    float Voltage;                                  //Measured voltage over the H-bridge for thr coil
    float Current;                                  //Measured current through the H-bridge
}  __attribute__ ((packed)) Setting1;
Setting1 status;

typedef struct {                                    //Data from tTEM regulator application on pc to microcontroller board
    char CtrlType;                                  //Must be 2
    float SetCurrent;                               //Setpoint value for current (same as Iset)
    float SetTemp;                                  //Setpoint value for temperature
    float SetSmallCurrentStepsize;                  //Current small stepsize for proportional regulator
    float SetLargeCurrentStepsize;                  //Current large stepsize for proportional regulator
    float SetStartupCurrentAbove50;                 //Startup current if temperature above 50 deg
    float SetStartupCurrent35to50;                  //Startup current if temperature between 35-50 deg   
    float SetStartupCurrent25to35;                  //Startup current if temperature between 25-35 deg
    float SetStartupCurrent15to25;                  //Startup current if temperature between 15-25 deg
    float SetStartupCurrent5to15;                   //Startup current if temperature between  5-15 deg
    float SetStartupCurrentBelow5;                  //Startup current if temperature below 5 deg
    float SetLowVoltAlarm;                          //Define when the alarm will sound
    float SetHighTempAlarm;                         //Define when the alarm will sound
    float SetPumpLowSpeed;                          //Lowest possible pump speed
    float SetPumpHighSpeed;                         //Highest possible pump speed
    float SetFanLowSpeed;                           //Fixed speed for then fan
    float SetFanMidSpeed;                           //Fixed speed for then fan
    float SetFanHighSpeed;                          //Fixed speed for then fan
    float SetStartupTime;                           //Number of seconds for startup
    float SetLowMoment;                             //Current above this value is defined as High Moment and regulator is only active if above                      
    float SetLowestCurrent;                         //The lowest value the current can be set to 0-1023
    float SetResetCurrentTime;                      //Reset setupCurrent if no data has been received from PAPC within this time
    float PumpUpdateValue;                          //How much should the pump PWM value be changed pr interval                      
    float PumpUpdateInterval;                       //How often should the pump PWM value be change
    float PumpTempTolerance;                        //Temp tolerance for changing between regulator state and high/low state 
    
   }  __attribute__ ((packed)) Setting2; 
Setting2 setup;

typedef struct {
    float Temperature;                              //Measured voltage over the H-bridge for thr coil
    float Voltage;                                  
    float Current; 
    float RegTemp;                                  //Measured temperature for MOSFETs
    bool DataReceived;
    int CurrentStep;
}  __attribute__ ((packed)) Data;
Data reply;

//INITS-------------------------------------------------------------------------
Serial pc(USBTX, USBRX);        //create PC interface for terminal
EthernetInterface eth;          //create ethernet
UDPSocket server, sock;         //creat Ethernet socket
Endpoint DataIn, pserver;       //create endpoint

DigitalOut red(LED_RED);        //debug led
DigitalOut statusGreen(PTC10);  //Lights up when active regulating NOT USED
DigitalOut statusRed(PTC11);    //Lights up when reatch upper limit for a while NOT USED
SPI spi(PTD2, NC, PTD1);        //mosi, miso(not used), sclk (reset+rdy not used) for DAC
DigitalOut cs(PTC12);           //SYNC SPI
SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd"); // mosi, miso, sclk, cs, name
AnalogIn BattVolt(A0);          //ADC for the battery voltage resistordivider = 10k/(36k+10k) = 0.217. Measered voltage = (BattVolt*3.3V)/0.217
AnalogIn CoilVolt(A1);          //ADC for the coil voltage. Measered voltage = (CoilVolt*3.3V)/0.217 NOT USED
AnalogIn Current(A2);           //ADC for the current measurement. Measered current = ((Current/3)-(9/2))/(0.05*N) Number of turns of wire throuth current sensor. NOT USED
DS1820 probe(D15);            //PTE24 Data from DS1822+ digital temp. sensor TJEK AT DEN VIRKER PÅ DENNE NYE PLACERING I STEDET FOR A3
DigitalIn FillWater(D2);        //Input for pushbutton for filling water on to the system
PwmOut PwmSpare(D3);            //Extra PWM output NOT USED
PwmOut PwmAlarm(D7);            //PWM for the alarm output set value = 1 for 100% PWM signal NOT USED
PwmOut PwmPump(D6);             //PWM output for pump
PwmOut PwmFan(D5);              //PWM output for fan

Timer t, PumpTimer, DataReceivedTimer;             //Timer for resetting startup current and pump

float SetValue = 0.0f;          //Set value for the current regulator
float tempProbe = 0.0f;
bool firstRun = 0;              //Just to check if data has been received for the first time
float PumpValue = 0.0f;

enum states { 
    PUMP_HIGH,
    PUMP_LOW,
    PUMP_REG
};
enum states state = PUMP_REG;

//Char arrays for storing ini variables on SD card
char A[50], B[50], C[50], D[50], E[50], F[50], G[50], H[50], I[50], J[50], K[50], L[50], M[50], N[50], O[50], P[50], Q[50], R[50], S[50], T[50], U[50], V[50], W[50], X[50];

//FUNCTION DECLARATIONS---------------------------------------------------------
void InitUSB(void);
void InitEth(void);
void ReadFile(void); //For SD card
void WriteFile(void); //For SD card
float Map(float, float, float, float, float);
void InitPot(void);
void SetPot(int);
float GetBattVolt(void);
//float GetCoilVolt(void);
//float GetCurrent(void);
void Alarm(void);
void UpdateTemp(void);
void UpdateStartupCurrent(void);
void UpdateCurrent(void);
void ReadSocketDate(void const *args);
void ReturnUDPData(void);
int main(void);

//InitUSB-----------------------------------------------------------------------TESTED
void InitUSB(void) //UART is only used for debug with a terminal
{
    pc.baud(9600);    //baud
}

//InitEth-----------------------------------------------------------------------TESTED
void InitEth(void)
{    
    if (Debug) 
        eth.init();
    else    
        eth.init(CLIENT_IP, MASK, GATEWAY);                                     //set up IP
    eth.connect(60000);                                                         //connect ethernet timeout = 60s
    pc.printf("\nBoard IP Address is %s\r\n", eth.getIPAddress());              //get client IP address
    pc.printf("\nBoard Gateway Address is %s\r\n", eth.getGateway());
    pc.printf("\nBoard Network Mask is %s\r\n", eth.getNetworkMask());
    pc.printf("\nBoard MAC address is %s\r\n", eth.getMACAddress());
    sock.init();
    server.bind(board_PORT);
    pserver.set_address(SERVER_IP,pc_PORT);
}  
//ReadFile----------------------------------------------------------------------TESTED
void ReadFile (void) {
    FILE *set = fopen("/sd/ini.txt", "r");  // Open "ini.txt" on the SD file system for read
    fscanf(set,"%s %f",A,&setup.SetCurrent);
    fscanf(set,"%s %f",B,&setup.SetTemp);   
    fscanf(set,"%s %f",C,&setup.SetSmallCurrentStepsize);   
    fscanf(set,"%s %f",D,&setup.SetLargeCurrentStepsize);   
    fscanf(set,"%s %f",E,&setup.SetStartupCurrentAbove50);
    fscanf(set,"%s %f",F,&setup.SetStartupCurrent35to50); 
    fscanf(set,"%s %f",G,&setup.SetStartupCurrent25to35); 
    fscanf(set,"%s %f",H,&setup.SetStartupCurrent15to25); 
    fscanf(set,"%s %f",I,&setup.SetStartupCurrent5to15); 
    fscanf(set,"%s %f",J,&setup.SetStartupCurrentBelow5); 
    fscanf(set,"%s %f",K,&setup.SetLowVoltAlarm);   
    fscanf(set,"%s %f",L,&setup.SetHighTempAlarm);  
    fscanf(set,"%s %f",M,&setup.SetPumpLowSpeed);   
    fscanf(set,"%s %f",N,&setup.SetPumpHighSpeed);   
    fscanf(set,"%s %f",O,&setup.SetFanLowSpeed);   
    fscanf(set,"%s %f",P,&setup.SetFanMidSpeed);   
    fscanf(set,"%s %f",Q,&setup.SetFanHighSpeed);   
    fscanf(set,"%s %f",R,&setup.SetStartupTime);   
    fscanf(set,"%s %f",S,&setup.SetLowMoment);   
    fscanf(set,"%s %f",T,&setup.SetLowestCurrent);   
    fscanf(set,"%s %f",U,&setup.SetResetCurrentTime); 
    fscanf(set,"%s %f",V,&setup.PumpUpdateValue); 
    fscanf(set,"%s %f",W,&setup.PumpUpdateInterval); 
    fscanf(set,"%s %f",X,&setup.PumpTempTolerance); 
    fclose(set);
}

//WriteFile---------------------------------------------------------------------TESTED
void WriteFile(void) { // write to SD memory
    FILE *fp = fopen("/sd/ini.txt", "w");  // Open "ini.txt" on the SD file system for write
    fprintf(fp,"SetCurrent %f\r\n",setup.SetCurrent);  
    fprintf(fp,"SetTemp %f\r\n",setup.SetTemp);   
    fprintf(fp,"SetSmallCurrentStepsize %f\r\n",setup.SetSmallCurrentStepsize); 
    fprintf(fp,"SetLargeCurrentStepsize %f\r\n",setup.SetLargeCurrentStepsize);   
    fprintf(fp,"SetStartupCurrentAbove50 %f\r\n",setup.SetStartupCurrentAbove50);
    fprintf(fp,"SetStartupCurrent35to50 %f\r\n",setup.SetStartupCurrent35to50);
    fprintf(fp,"SetStartupCurrent25to35 %f\r\n",setup.SetStartupCurrent25to35);
    fprintf(fp,"SetStartupCurrent15to25 %f\r\n",setup.SetStartupCurrent15to25);
    fprintf(fp,"SetStartupCurrent5to15 %f\r\n",setup.SetStartupCurrent5to15);
    fprintf(fp,"SetStartupCurrentBelow5 %f\r\n",setup.SetStartupCurrentBelow5);
    fprintf(fp,"SetLowVoltAlarm %f\r\n",setup.SetLowVoltAlarm);   
    fprintf(fp,"SetHighTempAlarm %f\r\n",setup.SetHighTempAlarm); 
    fprintf(fp,"SetPumpLowSpeed %f\r\n",setup.SetPumpLowSpeed);   
    fprintf(fp,"SetPumpHighSpeed %f\r\n",setup.SetPumpHighSpeed); 
    fprintf(fp,"SetFanLowSpeed %f\r\n",setup.SetFanLowSpeed);   
    fprintf(fp,"SetFanMidSpeed %f\r\n",setup.SetFanMidSpeed); 
    fprintf(fp,"SetFanHighSpeed %f\r\n",setup.SetFanHighSpeed);   
    fprintf(fp,"SetStartupTime %f\r\n",setup.SetStartupTime);   
    fprintf(fp,"SetLowMoment %f\r\n",setup.SetLowMoment);   
    fprintf(fp,"SetLowestCurrent %f\r\n",setup.SetLowestCurrent); 
    fprintf(fp,"SetResetCurrentTime %f\r\n",setup.SetResetCurrentTime);   
    fprintf(fp,"PumpUpdateValue %f\r\n",setup.PumpUpdateValue);   
    fprintf(fp,"PumpUpdateInterval %f\r\n",setup.PumpUpdateInterval);   
    fprintf(fp,"PumpTempTolerance %f\r\n",setup.PumpTempTolerance);   
    fclose(fp);
}

//InitPot-----------------------------------------------------------------------TESTED POT = digital potentiometer (DAC)
//Setup digital potentiometer
void InitPot(void) {
    cs = 1;                 //Deselect the device
    spi.format(16,1);       //Setup the spi for 16 bit data, SPI mode = 1 
    spi.frequency(1000000); //1MHz clock
    cs = 0;                 //Select the device
    spi.write(0x1803);      //Send 0x1803 to enable updating of RDAC register for changing potentiometer values
    cs = 1;                 //Deselect the device
}

//SetPot------------------------------------------------------------------------TESTED
//Update of potentiometer value
void SetPot(int value) {    //Values from 0-1023 are allowed
    cs = 0;                 //Select the device
    spi.write(0x400+value); //Values from 0x0400 to 0x7FF for digital potentiometer 
    cs = 1;                 //Deselect the device   
}

//GetBattVolt-------------------------------------------------------------------TESTED
float GetBattVolt(void) {
    float result; 
    result = (BattVolt.read()*15.207f+0.2f);
    return result;     
} 

//Alarm check for low battery or high temperature-------------------------------TESTED NOT USED
void Alarm(void) {      
    if ((status.Temperature>setup.SetHighTempAlarm)) {
        pc.printf("Water temperature high\r\n");
        PwmAlarm = 1.0f;
        wait(0.5);
        PwmAlarm = 0.0f;
        wait(0.5);   
    }
    else {
        PwmAlarm = 0.0f;                                //Turn off the alarm
    }
}

//UpdateTemp--------------------------------------------------------------------TESTED
void UpdateTemp(void) {

    switch(state) {
    case PUMP_HIGH:
        //pc.printf("State = PUMP_HIGH\n\r");
        PwmFan = setup.SetFanHighSpeed;
        PwmPump = setup.SetPumpHighSpeed;
        if(status.Temperature < setup.SetTemp) { //Temp is lower than setpoint go to PUMP_REG state
            state = PUMP_REG;
        }
    break;
    case PUMP_LOW:
        //pc.printf("State = PUMP_LOW\n\r");
        PwmFan = setup.SetFanLowSpeed;
        PwmPump = setup.SetPumpLowSpeed;
        if(status.Temperature > setup.SetTemp) { //Temp is higher than setpoint go to PUMP_REG state
            state = PUMP_REG;
        }
    break;
    case PUMP_REG:
        //pc.printf("State = PUMP_REG\n\r");
        //PwmFan = setup.SetFanMidSpeed;
        if(PumpTimer.read()>setup.PumpUpdateInterval){                        
        
            if(status.Temperature>setup.SetTemp){       //Temp too high turn up pump
                PumpValue = PumpValue + setup.PumpUpdateValue;     //0.05f;
                if(PumpValue>0.3f){
                    PumpValue = 0.3;        
                }
                //pc.printf("Turn pump up\n\r");
            }
            else if(status.Temperature<setup.SetTemp) { //Temp too low turn down pump
                PumpValue = PumpValue - setup.PumpUpdateValue*10;
                //pc.printf("Turn pump down\n\r");
            }
            else {
                PumpValue = PumpValue;
            }
            //Restart timer used for making the cooling system run a little time after PAPC has stopped
            PumpTimer.stop();
            PumpTimer.reset();
            PumpTimer.start();
        }  
        //Make sure the value can not be lower than lowest value or higher than higest.
        if(PumpValue<setup.SetPumpLowSpeed){
            PumpValue = setup.SetPumpLowSpeed;    
        }
        if(PumpValue>setup.SetPumpHighSpeed){
            PumpValue = setup.SetPumpHighSpeed;    
        }
        PwmPump = PumpValue;
        PwmFan = PumpValue;
        //pc.printf("PumpValue: %3.3f%\n\r",PumpValue);
    
        if(status.Temperature-setup.SetTemp >= setup.PumpTempTolerance) { //Temp is higher than tolerance go to PUMP_HIGH state 
            state = PUMP_HIGH;    
        }
        if(setup.SetTemp-status.Temperature >= setup.PumpTempTolerance) { //Temp is lower than tolerance go to PUMP_LOW state
            state = PUMP_LOW;    
        }
    break;
    }    
}

//UpdateStartupCurrent----------------------------------------------------------TESTED
void UpdateStartupCurrent(void) {
    probe.convertTemperature(true, DS1820::all_devices);
    
    float output = 0.0f;
    float tempC = 0.0f;
    
    tempC = probe.temperature();
    wait_ms(10);
    pc.printf("Temp: %3.1f%\n\r",tempC);
    //reply.ReturnTemp = tempC;                   //TEST FOR SENDIND DATA BACK TO PC
       
    if (tempC>=50.0f) {
        output = setup.SetStartupCurrentAbove50; //500
    }
    else if (50.0f>tempC && tempC>=35.0f) {
        output = setup.SetStartupCurrent35to50; //600
    }
    else if (35.0f>tempC && tempC>=25.0f) {
        output = setup.SetStartupCurrent25to35; //700   
    }
    else if (25.0f>tempC && tempC>=15.0f) {
        output = setup.SetStartupCurrent15to25; //800        
    }
    else if (15.0f>tempC && tempC>=5.0f) {
        output = setup.SetStartupCurrent5to15; //900
    }
    else {
        output = setup.SetStartupCurrentBelow5; //1023
    }
    SetPot(output);                    //Startup current in order to slowly startup 
    SetValue = output;                 //The currentUpdate function needs to know where it should start to regulate from   
    pc.printf("StartupCurrent: %3.3f%\n\r",output);
}

//UpdateCurrent-----------------------------------------------------------------TESTED
void UpdateCurrent(void) {
probe.convertTemperature(true, DS1820::all_devices);
    
    if(status.Current >= setup.SetLowMoment) {
        if (probe.temperature()<50.0f) {  //Only regulate if temp measured on regulator mosfet is below 50 degree
            
            //Voltage must be above a defined level or it should not be possible to turn more down
            //Implement large step if big error and small step if small error
            statusGreen = 1; //LED not used
            //Current too high turn it down but only if voltage is not to low!
            if((setup.SetCurrent < status.Current) && (status.Voltage > setup.SetLowVoltAlarm)) {  
                float error = status.Current-setup.SetCurrent;
                if (error>=0.5f) { //large step  0.5f = 0.5A
                    SetValue = SetValue - setup.SetLargeCurrentStepsize;
                    pc.printf("Turn down large\n\r");
                    if (SetValue < setup.SetLowestCurrent) { //FitPC shuts down if value is below this number
                        SetValue = setup.SetLowestCurrent;
                    }
                }
                else { //small step
                    SetValue = SetValue - setup.SetSmallCurrentStepsize;         
                    pc.printf("Turn down small\n\r");
                    if (SetValue < setup.SetLowestCurrent) { //FitPC shuts down if value is below this number
                        SetValue = setup.SetLowestCurrent;
                    }
                }
                SetPot(SetValue);
                pc.printf("SetValue: %3.3f%\n\r",SetValue);
            }
            //Current too low turn it up
            else if(setup.SetCurrent > status.Current) { 
                float error = setup.SetCurrent-status.Current;
                if (error>=1.0f) { //large step
                    SetValue = SetValue + setup.SetLargeCurrentStepsize;
                    pc.printf("Turn up large\n\r");
                    if (SetValue > 1023) {
                        SetValue = 1023;
                    } 
                }
                else { //small step
                    SetValue = SetValue + setup.SetSmallCurrentStepsize;  
                    pc.printf("Turn up small\n\r");  
                    if (SetValue > 1023) {
                        SetValue = 1023;
                    }    
                }
                if (SetValue >= 1023) {
                    pc.printf("Unable to turn up higher, change battery\n\r");  
                    statusRed = 1;
                    PwmAlarm = 1.0f;
                    wait(0.25);
                    PwmAlarm = 0.0f;
                    wait(0.25);
                }
                SetPot(SetValue);
                pc.printf("SetValue: %3.3f%\n\r",SetValue);
            }
        }
        //else go to safe state if regulator mosfet temperature is above 50 deg.
        else {
            //pc.printf("SetValue: %3.3f%\n\r",SetValue);
            SetPot(setup.SetStartupCurrentBelow5);
        }
    }
}

//ReadSocketData----------------------------------------------------------------TESTED
void ReadSocketDate(void const *args) {
    char in_buffer[1024];
    while(true) {
        int n = server.receiveFrom(DataIn, in_buffer, sizeof(in_buffer));     
        
        if (in_buffer[0]==1) {                 //Receiving from PAPC, copy to status struct
            memcpy(&status,&in_buffer[0],sizeof(status));  
            UpdateCurrent();                    //Turn up/down the current
            UpdateTemp();                       //Control speed of pump based on temperature 
            firstRun = 1;                       
            //pc.printf("Data modtaget\r\n");
            pc.printf("Temperatur: %3.1f%\r\n",status.Temperature);
            pc.printf("Voltage:    %3.3f%\r\n",status.Voltage);
            pc.printf("Current:    %3.3f%\r\n\r\n",status.Current);
        } 
        else if (in_buffer[0]==2) {            //Receiving from tTEM regulator application, copy to setup struct
            memcpy(&setup,&in_buffer[0],sizeof(setup));
            //Acustic alarm to confirm data has been received 
            reply.DataReceived = true;         //Sends a boolean to the tTEM regulation software confirming data has been received
            DataReceivedTimer.stop();
            DataReceivedTimer.reset();
            DataReceivedTimer.start();
            
            PwmAlarm = 1.0f; // NOT USED
            wait(0.05);
            PwmAlarm = 0.0f;
            wait(0.05);
            PwmAlarm = 1.0f;
            wait(0.05);
            PwmAlarm = 0.0f;
            
            WriteFile();            //Write data to SD card   
            
            pc.printf("Data has been received from setup file\r\n");
            //Print the received data to terminal
            /*pc.printf("SetCurrent:               %3.2f%\r\n",setup.SetCurrent);
            pc.printf("SetTemp:                  %3.2f%\r\n",setup.SetTemp);
            pc.printf("SetSmallStepsize:         %3.2f%\r\n",setup.SetSmallCurrentStepsize);
            pc.printf("SetLargeStepsize:         %3.2f%\r\n",setup.SetLargeCurrentStepsize);
            pc.printf("SetStartupCurrentAbove50: %3.2f%\r\n",setup.SetStartupCurrentAbove50);
            pc.printf("SetStartupCurrent35to50:  %3.2f%\r\n",setup.SetStartupCurrent35to50);
            pc.printf("SetStartupCurrent25to35:  %3.2f%\r\n",setup.SetStartupCurrent25to35);
            pc.printf("SetStartupCurrent15to25:  %3.2f%\r\n",setup.SetStartupCurrent15to25);
            pc.printf("SetStartupCurrent5to15:   %3.2f%\r\n",setup.SetStartupCurrent5to15);
            pc.printf("SetStartupCurrentBelow5:  %3.2f%\r\n",setup.SetStartupCurrentBelow5);
            pc.printf("SetLowVoltAlarm:          %3.2f%\r\n",setup.SetLowVoltAlarm);
            pc.printf("SetHighTempAlarm:         %3.2f%\r\n",setup.SetHighTempAlarm);
            pc.printf("SetPumpLowSpeed:          %3.2f%\r\n",setup.SetPumpLowSpeed);
            pc.printf("SetPumpHighSpeed:         %3.2f%\r\n",setup.SetPumpHighSpeed);
            pc.printf("SetFanLowSpeed:           %3.2f%\r\n",setup.SetFanLowSpeed);
            pc.printf("SetFanMidSpeed:           %3.2f%\r\n",setup.SetFanMidSpeed);
            pc.printf("SetFanHighSpeed:          %3.2f%\r\n",setup.SetFanHighSpeed);
            pc.printf("SetStartupTime:           %3.2f%\r\n",setup.SetStartupTime);
            pc.printf("SetLowMoment:             %3.2f%\r\n",setup.SetLowMoment);
            pc.printf("SetLowestCurrent:         %3.3f%\r\n",setup.SetLowestCurrent);
            pc.printf("SetResetCurrentTime:      %3.3f%\r\n",setup.SetResetCurrentTime);
            pc.printf("PumpUpdateValue:          %3.3f%\r\n",setup.PumpUpdateValue);
            pc.printf("PumpUpdateInterval:       %3.3f%\r\n",setup.PumpUpdateInterval);
            pc.printf("PumpTempTolerance:        %3.3f%\r\n",setup.PumpTempTolerance);
            */
        }
        else {                              //Error
            pc.printf("Invalid CrtlType, must be 1 for status or 2 for setup\r\n"); 
        }
        t.reset();                          //Reset and start the timer for measure if PAPC has been stopped
        t.start();
    }
}

void ReturnUDPData(void) {
    char out_buffer[sizeof(reply)];
    //Send data back through UDP
    probe.convertTemperature(true, DS1820::all_devices);
    tempProbe = probe.temperature(); 
    //wait_ms(750);
    while(tempProbe==-1000) {
        //pc.printf("Temp probe crc error\n\r");
        tempProbe = probe.temperature();
        //wait_ms(750);   
    }
        
    reply.Temperature = status.Temperature;  //Data received from PAPC is send to tTEM regulator application
    reply.Voltage = status.Voltage;
    reply.Current = status.Current;
    reply.RegTemp = tempProbe;  //Data measured by the microcontroller
    reply.CurrentStep = SetValue;
    //pc.printf("RegTemp: %3.3f%\n\r",tempProbe);
        
    memcpy(&out_buffer[0],&reply, sizeof(reply));
    sock.sendTo(pserver, out_buffer, sizeof(out_buffer)); //reply 
    wait_ms(550);
        
    if(DataReceivedTimer.read()>5) {
        reply.DataReceived = false;
        DataReceivedTimer.stop();
        DataReceivedTimer.reset();
    }
}

//MAIN--------------------------------------------------------------------------
int main(void)
{                   
    PwmFan   = 0.0f; 
    PwmPump  = 0.0f; 
    PwmSpare = 0.0f;                        //Do not use this PWM output 


    InitUSB();                              //initialize the PC interface 
    pc.printf("Init USB done\r\n");                                               
    InitEth();                              //Init ethernet connection
    pc.printf("Init Ethernet done\r\n");                                               
    InitPot();                              //setup potentiometer
    pc.printf("Init POT done\r\n");                                               
    
    
    ReadFile();                             //Read ini values from SD card that was last received from UDP.
    pc.printf("Read MicroSD card done\r\n");                                               
    UpdateStartupCurrent();                 //Set the startup current at a value dependent of the measured temperature     
    wait(setup.SetStartupTime);             //Wait a while for everything to startup  
    PumpValue = (setup.SetPumpLowSpeed+setup.SetPumpHighSpeed)*0.5f;
    //FanValue = setup.SetFanMidSpeed;
    PumpTimer.reset();
    PumpTimer.start();
    Thread DbThread(ReadSocketDate, NULL, osPriorityNormal, (DEFAULT_STACK_SIZE * 2.25));
    FillWater.mode(PullUp);                 //Enable pull-up resister on bushbutton input
    statusGreen = 0;
    statusRed = 0;
    wait_ms(10);
    
    while(true)                                                                            
    {   
        red = !red;    
        Alarm();                            //Check if battery is running low          
        
        if (firstRun == 0) {                //No data has been received so manual overwrite of pwmpump is allowed, if data has been received it can not be changed manual
            if(FillWater == 0) {            //Button has been pushed
               PwmPump = 1.0f;              //Run pump at half speed to fill system
            }
            else {
                PwmPump = 0.0f;    
            }
        }
        
        //Reset setvalue for current regulator if PAPC has been stopped for a given time
        if (setup.SetResetCurrentTime==0) {
            t.stop();                       //If Time= 0, disable the resetting function
            t.reset();
                 
        }
        else if(t.read()>setup.SetResetCurrentTime) {
            //No data received for 10 sek. reset the current
            UpdateStartupCurrent(); 
            PwmPump = 0.0f; //Pump and fan should not run if no data has been received from papc
            PwmFan = 0.0f;  
            PwmAlarm = 0.0f; //Stop the alarm
            firstRun = 0;
            statusGreen = 0;  
            statusRed = 0; 
            status.Temperature = 0;
            status.Voltage = 0;
            status.Current = 0;
            //pc.printf("Resetting start value\n\r");
            t.stop();
            t.reset();
        }
        ReturnUDPData();
    }
    
}