aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.DataCapture/Properties/Resources.resx
blob: af7dbebbacef595e3089c01c05671016c21a8304 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
</root>
e.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/************************************************************************************************************************
 **************************************************************************************************************************/

#include <DataDef.h>
#include "include.h"

#include "ids.h"
#include "ids_ex.h"

#include "control/control.h"

#include "drivers/Motors/Motor.h"
#include "drivers/valves/valve.h"
#include "PMR/EmbeddedParameters/DispenserRunningData.pb-c.h"
#include "PMR/EmbeddedParameters/DispenserData.pb-c.h"
#include "PMR/EmbeddedParameters/DispenserDataResponse.pb-c.h"
#include "Common/SWUpdate/FileSystem.h"
#include "drivers/Flash_Memory/fatfs/ff.h"

#include "drivers/Flash_ram/FlashProgram.h"

#include "StateMachines/Printing/PrintingSTM.h"

//extern uint32_t DispenserIdToMotorId[MAX_SYSTEM_DISPENSERS];
#define CloseValve MidTank_Dispenser
#define OpenValve Dispenser_Mixer

uint32_t CloseValveTimeout = 10;
uint32_t OpenValveTimeout = 10;
#define DISPENSER_BUILD_PRESSURE_SPEED 900
#define DISPENSER_BUILD_PRESSURE_LIMIT 1.5
#define DISPENSER_BUILD_PRESSURE_TIMEOUT 60000
#define DISPENSER_BUILD_PRESSURE_LAG 50
#define DEFAULT_NANOLITER_PER_PULSE 2.34
uint32_t DispenserPrepareSpeed = DISPENSER_BUILD_PRESSURE_SPEED;
double   DispenserPreparePressure = DISPENSER_BUILD_PRESSURE_LIMIT;
uint32_t DispenserPrepareTimeout = DISPENSER_BUILD_PRESSURE_TIMEOUT;
uint32_t DispenserPrepareTimeLag = DISPENSER_BUILD_PRESSURE_LAG;
uint32_t DispenserPrepareTime[MAX_SYSTEM_DISPENSERS] = {0,0,0,0,0,0,0,0};

int32_t CurrentDispenserSpeed[MAX_SYSTEM_DISPENSERS] = {0, 0, 0, 0, 0, 0, 0, 0,};

callback_fptr DispenserCallback[MAX_SYSTEM_DISPENSERS] = {0, 0, 0, 0, 0, 0, 0, 0,};
uint32_t DispenserControlId[MAX_SYSTEM_DISPENSERS] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

void IDS_Dispenser_SetPrepareValues(    uint32_t DispenserBuildPressureSpeed,   double DispenserBuildPressureLimit, uint32_t DispenserBuildPressureTimeout, uint32_t DispenserBuildPressureLag)
{
     DispenserPrepareSpeed = DispenserBuildPressureSpeed;
     DispenserPreparePressure = DispenserBuildPressureLimit;
     DispenserPrepareTimeout = DispenserBuildPressureTimeout;
     DispenserPrepareTimeLag = DispenserBuildPressureLag;
     Report("IDS_Dispenser_SetPrepareValues ",__FILE__,__LINE__,DispenserPrepareSpeed,RpWarning,(int)(DispenserPreparePressure*100),0);
     Report("IDS_Dispenser_SetPrepareValues ",__FILE__,__LINE__,DispenserPrepareTimeout,RpWarning,(int)DispenserPrepareTimeLag,0);
}
void IDS_Dispenser_SetTimeOutValues(uint32_t CloseTimeout, uint32_t OpenTimeout)
{
#ifndef SPECIAL_DISPENSERS
     CloseValveTimeout = CloseTimeout;
     OpenValveTimeout = OpenTimeout;
#endif
     Report("IDS_Dispenser_SetTimeOutValues ",__FILE__,__LINE__,OpenValveTimeout,RpWarning,(int)CloseValveTimeout,0);
}

//********************************************************************************************************************
int32_t IdsGetMotorSpeed(uint32_t DispenserId)
{
    return  CurrentDispenserSpeed[DispenserId];
}

uint32_t IDS_Dispenser_Build_Pressure_Callback(uint32_t DispenserId, uint32_t ReadValue)
 {
    uint32_t status;
    DispenserPrepareTime[DispenserId]+=DispenserPrepareTimeLag;
    double DispenserPressure = DispenserPreparePressure;

    if (DispenserId == LUBRICANT_DISPENSER)
    {
        DispenserPressure = DispenserPreparePressure/5;
		//lubricant lower pressure buildup
    }

     if ((GetDispenserPressure(DispenserId)>=DispenserPressure)||(DispenserPrepareTime[DispenserId]>=DispenserPrepareTimeout))
     {
         if (DispenserPrepareTime[DispenserId]>=DispenserPrepareTimeout)
             status = ERROR;
         else
             status = OK;
         if (SafeRemoveControlCallback(DispenserControlId[DispenserId], IDS_Dispenser_Build_Pressure_Callback )==OK)
             DispenserControlId[DispenserId] = 0xFF;
         else
             Report("Remove control callback failed",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)DispenserControlId[DispenserId],0);
         TimerMotors_t  HW_Motor_Id = DispenserIdToMotorId[DispenserId];
         MotorStop(HW_Motor_Id,Hard_Hiz);
         CurrentDispenserSpeed[DispenserId] = 0;

         if (DispenserCallback[DispenserId])
         {

             DispenserCallback[DispenserId](DispenserId,status);
             DispenserCallback[DispenserId] = 0;
         }
     }
     return status;
}

 uint32_t IDS_Dispenser_Build_Pressure(int DispenserId, callback_fptr callback)
{
    DispenserCallback[DispenserId] = callback;
    Report("IDS_Dispenser_Build_Pressure called  ",__FILE__,__LINE__,(int)DispenserPrepareSpeed,RpWarning,DispenserPrepareTimeLag,0);

    Control3WayValvesWithCallback ((Valves_t)DispenserId, CloseValve, NULL); //direction: MidTank_Dispenser or Dispenser_Mixer
    if (DispenserControlId[DispenserId] != 0xFF)
    {
        Report("Cannot Add control callback",__FILE__,(int)DispenserId,GetControlCallbackFuncPtr(DispenserControlId[DispenserId]),RpWarning,(int)DispenserControlId[DispenserId],0);
    }
    DispenserControlId[DispenserId] = AddControlCallback(NULL, IDS_Dispenser_Build_Pressure_Callback, DispenserPrepareTimeLag,TemplateDataReadCBFunction ,DispenserId, DispenserId, 0 );
    if (DispenserControlId[DispenserId] == 0xFF)
        Report("Add control callback failed",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)DispenserControlId[DispenserId],0);
    else
    {
        //Report("Add control callback",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)DispenserControlId[DispenserId],0);
        DispenserPrepareTime[DispenserId]=0;
        TimerMotors_t  HW_Motor_Id = DispenserIdToMotorId[DispenserId];
        MotorSetDirection(HW_Motor_Id,MotorsCfg[HW_Motor_Id].directionthreadwize);
        MotorSetSpeed(HW_Motor_Id, DispenserPrepareSpeed);
        CurrentDispenserSpeed[DispenserId] = DispenserPrepareSpeed;
    }

    return OK;
}

 uint32_t IDS_Dispenser_StopMotorCallback(uint32_t DispenserId, uint32_t ReadValue)
 {
     Report("IDS_Dispenser_Close_Valve_And_Stop_Motor callback",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)msec_millisecondCounter,0);
     if (SafeRemoveControlCallback(DispenserControlId[DispenserId], IDS_Dispenser_StopMotorCallback )==OK)
         DispenserControlId[DispenserId] = 0xFF;
     else
         Report("Remove control callback failed",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)DispenserControlId[DispenserId],0);

     TimerMotors_t  HW_Motor_Id = DispenserIdToMotorId[DispenserId];
     MotorStop(HW_Motor_Id,Hard_Hiz);
     CurrentDispenserSpeed[DispenserId] = 0;

     if (DispenserCallback[DispenserId])
     {
         DispenserCallback[DispenserId](DispenserId,ReadValue);
         DispenserCallback[DispenserId] = 0;
     }
     return OK;
}

 uint32_t IDS_Dispenser_Close_Valve_And_Stop_Motor(int DispenserId, callback_fptr callback)
{
    DispenserCallback[DispenserId] = callback;
    //Report("IDS_Dispenser_Close_Valve_And_Stop_Motor",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)msec_millisecondCounter,0);

    Control3WayValvesWithCallback ((Valves_t)DispenserId, CloseValve, NULL); //direction: MidTank_Dispenser or Dispenser_Mixer
    if (DispenserControlId[DispenserId] != 0xFF)
        Report("Cannot Add control callback",__FILE__,(int)DispenserId,GetControlCallbackFuncPtr(DispenserControlId[DispenserId]),RpWarning,(int)DispenserControlId[DispenserId],0);

    DispenserControlId[DispenserId] = AddControlCallback(NULL, IDS_Dispenser_StopMotorCallback, CloseValveTimeout, TemplateDataReadCBFunction,DispenserId, DispenserId, 0 );
    if (DispenserControlId[DispenserId] == 0xFF)
        Report("Add control callback failed",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)DispenserControlId[DispenserId],0);
    //else
    //    Report("Add control callback",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)DispenserControlId[DispenserId],0);

    return OK;
}

uint32_t IDS_Dispenser_OpenValveCallback(uint32_t DispenserId, uint32_t ReadValue)
{
    //Report("IDS_Dispenser_Start_Motor_and_Open_Valve Callback",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)msec_millisecondCounter,0);

    if (SafeRemoveControlCallback(DispenserControlId[DispenserId], IDS_Dispenser_OpenValveCallback )==OK)
        DispenserControlId[DispenserId] = 0xFF;
    else
        Report("Remove control callback failed",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)DispenserControlId[DispenserId],0);

    //Report("Control3WayValvesWithCallback called  ",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)0,0);
    Control3WayValvesWithCallback (DispenserId, OpenValve, NULL); //direction: MidTank_Dispenser or Dispenser_Mixer

    if (DispenserCallback[DispenserId])
    {
        DispenserCallback[DispenserId](DispenserId,ReadValue);
        DispenserCallback[DispenserId] = 0;
    }
    return OK;
}
uint32_t IDS_Dispenser_Start_Motor_and_Open_Valve(int DispenserId, int MotorSpeed, callback_fptr callback)
{
    DispenserCallback[DispenserId] = callback;

    TimerMotors_t  HW_Motor_Id = DispenserIdToMotorId[DispenserId];
    /*if (CurrentDispenserSpeed[DispenserId]) //motor already running
    {
        MotorSetSpeed(HW_Motor_Id, MotorSpeed);
        CurrentDispenserSpeed[DispenserId] = MotorSpeed;
        if (DispenserCallback[DispenserId])
        {
            DispenserCallback[DispenserId](DispenserId,0);
            DispenserCallback[DispenserId] = 0;
        }
    }
    else
    {*/
        MotorSetSpeed(HW_Motor_Id, MotorSpeed);
        CurrentDispenserSpeed[DispenserId] = MotorSpeed;
        if (DispenserControlId[DispenserId] != 0xFF)
            Report("Cannot Add control callback",__FILE__,(int)DispenserId,GetControlCallbackFuncPtr(DispenserControlId[DispenserId]),RpWarning,(int)DispenserControlId[DispenserId],0);
        //Report("IDS_Dispenser_Start_Motor_and_Open_Valve",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)msec_millisecondCounter,0);

        DispenserControlId[DispenserId] = AddControlCallback(NULL, IDS_Dispenser_OpenValveCallback, OpenValveTimeout, TemplateDataReadCBFunction,DispenserId, DispenserId, 0 );
        if (DispenserControlId[DispenserId] == 0xFF)
            Report("Add control callback failed",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)DispenserControlId[DispenserId],0);
        //else
        //    Report("Add control callback",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)DispenserControlId[DispenserId],0);
    //}

    return OK;
}
DispenserRunningData IDS_Dispenser_Data[MAX_SYSTEM_DISPENSERS];
DispenserData StoreDispenserData;
DispenserRunningData **dispenserdata;
char DispenserStorePath[50] = "0://SysInfo//DispStor.cfg";

void IDS_Dispenser_Content_Init (void)
{
    int i;
    //FRESULT Fresult = FR_OK;
    void* buffer = NULL;
    TimerMotors_t HW_Motor_Id;
    uint32_t Bytes = 0;
    dispenser_data__init(&StoreDispenserData);
    dispenserdata = (DispenserRunningData**)my_malloc(sizeof(DispenserRunningData *)*(MAX_SYSTEM_DISPENSERS));
    for(i=0;i<MAX_SYSTEM_DISPENSERS;i++)
    {
        HW_Motor_Id = DispenserIdToMotorId[i];
        dispenser_running_data__init(&IDS_Dispenser_Data[i]);
        dispenserdata[i] = &IDS_Dispenser_Data[i];
        IDS_Dispenser_Data[i].has_consumedinnanolitter = true;
        IDS_Dispenser_Data[i].has_direction = true;
        IDS_Dispenser_Data[i].has_microsteps = true;
        IDS_Dispenser_Data[i].has_nanolitterperpulse = true;
        IDS_Dispenser_Data[i].has_numberofrefills = true;
        IDS_Dispenser_Data[i].has_totalconsumedinnanolitter = true;
        IDS_Dispenser_Data[i].nanolitterperpulse = DEFAULT_NANOLITER_PER_PULSE;
        IDS_Dispenser_Data[i].microsteps = MotorsCfg[HW_Motor_Id].microstep;
    }
    //==================================

    memcpy(&Bytes,(void *)DISPENSERS_MAP_IN_FLASH,sizeof(Bytes));
    bool havedata = false;
    DispenserData* StoredDispenserData;
    if ((Bytes)&&(Bytes < 500))
    {
        buffer = my_malloc (Bytes);
        if (buffer)
        {
            memcpy(buffer, (void *)(DISPENSERS_MAP_IN_FLASH+4),Bytes);
            StoredDispenserData = dispenser_data__unpack(NULL,Bytes,buffer);
            havedata = true;
            free(buffer);
        }
    }
    /*else
    {
        Fresult = FileRead(DispenserStorePath, &Bytes, &buffer);
        if (Fresult == FR_OK)
        {
            StoredDispenserData = (DispenserRunningData*)buffer;
            havedata = true;
        }
    }*/
    if (havedata == true)
    {
        for(i=0;i<MAX_SYSTEM_DISPENSERS;i++)
        {
            //memcpy (&IDS_Dispenser_Data[i],&StoredDispenserData->dispenserinfo[i],sizeof(DispenserRunningData));
            IDS_Dispenser_Data[i].has_consumedinnanolitter = true;
            IDS_Dispenser_Data[i].has_totalconsumedinnanolitter = true;
            IDS_Dispenser_Data[i].has_direction = true;
            IDS_Dispenser_Data[i].has_microsteps = true;
            IDS_Dispenser_Data[i].has_numberofrefills = true;
            IDS_Dispenser_Data[i].has_nanolitterperpulse = true;
            IDS_Dispenser_Data[i].consumedinnanolitter = StoredDispenserData->dispenserinfo[i]->consumedinnanolitter;
            IDS_Dispenser_Data[i].totalconsumedinnanolitter = StoredDispenserData->dispenserinfo[i]->totalconsumedinnanolitter;
            IDS_Dispenser_Data[i].direction = StoredDispenserData->dispenserinfo[i]->direction;
            IDS_Dispenser_Data[i].microsteps = StoredDispenserData->dispenserinfo[i]->microsteps;
            IDS_Dispenser_Data[i].numberofrefills = StoredDispenserData->dispenserinfo[i]->numberofrefills;
            IDS_Dispenser_Data[i].nanolitterperpulse = StoredDispenserData->dispenserinfo[i]->nanolitterperpulse;
            Report("IDS_Dispenser load data ",__FILE__,i,(int)IDS_Dispenser_Data[i].totalconsumedinnanolitter,RpWarning,(int)IDS_Dispenser_Data[i].consumedinnanolitter,0);
        }
        dispenser_data__free_unpacked(StoredDispenserData,NULL);
    }
    //Report("IDS_Dispenser load data ",__FILE__,__LINE__,(int)Bytes,RpWarning,(int)IDS_Dispenser_Data[0].nanolitterperpulse*100,0);
    return;

    //==================================
}
uint16_t seconds_counter = 0;
bool DispenserDataUpdated = false;
uint32_t IDS_Dispenser_Store_Data (void)
{
    //uint32_t timing =  msec_millisecondCounter;
    FRESULT Status = FR_OK;
    StoreDispenserData.n_dispenserinfo = MAX_SYSTEM_DISPENSERS;
    StoreDispenserData.dispenserinfo = dispenserdata;
    uint8_t dispensers_container_buffer[500];


    size_t response_size;// = sizeof(DispenserRunningData)*8;
    int i;
    for(i=0;i<MAX_SYSTEM_DISPENSERS;i++)
    {
        StoreDispenserData.dispenserinfo[i] = &IDS_Dispenser_Data[i];
        Report("IDS_Dispenser store data ",__FILE__,i,(int)IDS_Dispenser_Data[i].totalconsumedinnanolitter,RpWarning,(int)IDS_Dispenser_Data[i].consumedinnanolitter,0);
    }

//    Report("IDS_Dispenser_Store_Data 0",__FILE__,(int)IDS_Dispenser_Data[0].totalconsumedinnanolitter,(int)IDS_Dispenser_Data[0].consumedinnanolitter,RpWarning,(int)IDS_Dispenser_Data[0].microsteps,0);
//    Report("IDS_Dispenser_Store_Data 4",__FILE__,(int)IDS_Dispenser_Data[4].totalconsumedinnanolitter,(int)IDS_Dispenser_Data[4].consumedinnanolitter,RpWarning,(int)IDS_Dispenser_Data[4].microsteps,0);

    if (JobIsActive()==false)
    {
        response_size = dispenser_data__pack(&StoreDispenserData, dispensers_container_buffer);
        EraseFlashSection(DISPENSERS_MAP_IN_FLASH,response_size+4);
        ReadAppAndProgram(DISPENSERS_MAP_IN_FLASH, 4,&response_size);
        ReadAppAndProgram(DISPENSERS_MAP_IN_FLASH+4, response_size, dispensers_container_buffer);
        //Report("IDS_Dispenser_Store ",__FILE__,__LINE__,(int)response_size,RpWarning,(int)StoreDispenserData.dispenserinfo[4]->nanolitterperpulse *100,0);

        /*Status = FileWrite(IDS_Dispenser_Data,response_size,DispenserStorePath,BIOS_NO_WAIT);
        if (Status == FR_OK)
        {
            DispenserDataUpdated = false;
            REPORT_MSG(msec_millisecondCounter - timing, "Updating dispensers file - time");
        }*/

    }

    return Status;
}
void IDS_Dispenser_Content_Calculation (char DispenserId)
{
    assert (DispenserId<MAX_SYSTEM_DISPENSERS);
    TimerMotors_t HW_Motor_Id = DispenserIdToMotorId[DispenserId];
    if (MotorsCfg[HW_Motor_Id].hardwaremotortype
            != DispenserIdToMotorId[DispenserId])
        return;

    //int dir = (IDS_Dispenser_Data[DispenserId].direction==1)?1:-1;
    //double consumedintimeframe = (double)(CurrentDispenserSpeed[DispenserId])*(double)(IDS_Dispenser_Data[DispenserId].microsteps)*
    //        IDS_Dispenser_Data[DispenserId].nanolitterperpulse ;//* dir;
    //double consumedintimeframe = (double)(CurrentDispenserSpeed[DispenserId]); //pulses only
    //consumedintimeframe = 10+DispenserId;
    IDS_Dispenser_Data[DispenserId].consumedinnanolitter += (CurrentDispenserSpeed[DispenserId]/10);//100 milliseconds ==> speed/10
    if (IDS_Dispenser_Data[DispenserId].consumedinnanolitter<0)
        IDS_Dispenser_Data[DispenserId].consumedinnanolitter = 0;
    if (CurrentDispenserSpeed[DispenserId]>0.1)
    {
        DispenserDataUpdated = true;
        IDS_Dispenser_Data[DispenserId].totalconsumedinnanolitter += (CurrentDispenserSpeed[DispenserId]/10);
        if (seconds_counter%6000 == 0)
        {
            Report("IDS_Dispenser_Data ",__FILE__,DispenserId,(int)IDS_Dispenser_Data[DispenserId].consumedinnanolitter,RpWarning,(int)CurrentDispenserSpeed[DispenserId],0);
        }
    }
    if (DispenserId == 0)
    {
        if ((seconds_counter++>=900)&&(DispenserDataUpdated == true))//9000)// - one hour)
        {
            seconds_counter = 0;
            if (IDS_Dispenser_Data[DispenserId].consumedinnanolitter)
            {
                REPORT_MSG(IDS_Dispenser_Data[DispenserId].consumedinnanolitter,"Saving Dispenser Data" );
            }
            IDS_Dispenser_Store_Data();
        }
    }
}
void DispensersCollectionCall(void)
{
    int i;
    for (i = 0; i<MAX_SYSTEM_DISPENSERS;i++)
    {
        IDS_Dispenser_Content_Calculation(i);
    }
}
void IDS_Dispenser_RefillStarted (char DispenserId,char  MicroSteps)
{
    assert (DispenserId<MAX_SYSTEM_DISPENSERS);
    /*IDS_Dispenser_Data[DispenserId].microsteps = MicroSteps;
    double assumedFlow = IDS_Dispenser_Data[DispenserId].microsteps*IDS_Dispenser_Data[DispenserId].nanolitterperpulse;
    IDS_Dispenser_Data[DispenserId].nanolitterperpulse = assumedFlow;
    IDS_Dispenser_Data[DispenserId].microsteps = 1;
    IDS_Dispenser_Data[DispenserId].direction = 0;*/
    Report("IDS_Dispenser_RefillStarted",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)(CurrentDispenserSpeed[DispenserId]),0);
}
void IDS_Dispenser_RefillEnded (char DispenserId,char  MicroSteps)
{
    assert (DispenserId<MAX_SYSTEM_DISPENSERS);
    //IDS_Dispenser_Data[DispenserId].microsteps = MicroSteps;
    IDS_Dispenser_Data[DispenserId].numberofrefills++;
    //IDS_Dispenser_Data[DispenserId].direction = 1;
    IDS_Dispenser_Data[DispenserId].consumedinnanolitter = 0;
    Report("IDS_Dispenser_RefillEnded",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)IDS_Dispenser_Data[DispenserId].numberofrefills,0);
}
void DispenserDataRequestFunc(MessageContainer* requestContainer)
{
    MessageContainer responseContainer;
    int i;
    //DisconnectRequest* request = disconnect_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);
    DispenserDataResponse response =   DISPENSER_DATA_RESPONSE__INIT;


    response.n_dispenserinfo = MAX_SYSTEM_DISPENSERS;
    response.dispenserinfo = (DispenserRunningData**)my_malloc(sizeof(DispenserRunningData *)*(MAX_SYSTEM_DISPENSERS));
    for(i=0;i<MAX_SYSTEM_DISPENSERS;i++)
    {
        response.dispenserinfo[i] = &IDS_Dispenser_Data[i];
        Report("DispenserDataRequestFunc",__FILE__,__LINE__,(int)response.dispenserinfo[i]->totalconsumedinnanolitter,RpWarning,(int)IDS_Dispenser_Data[i].totalconsumedinnanolitter,0);
    }
    responseContainer = createContainer(MESSAGE_TYPE__DispenserDataResponse, requestContainer->token, true, &response, &dispenser_data_response__pack, &dispenser_data_response__get_packed_size);

    //-------------------------------------------------------------------------------------------
    uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer));
    size_t container_size = message_container__pack(&responseContainer, container_buffer);
    my_free(responseContainer.data.data);
    SendChars((char*)container_buffer, container_size);

}