Test

Dependencies:   mbed-dev-OS5_10_4

MySources/EcmTel.cpp

Committer:
kevman
Date:
2020-08-07
Revision:
0:014fad4dfb9d

File content as of revision 0:014fad4dfb9d:

/*
-------------------------------------------------------------------------------
Programm Name: EcmTel.CPP
Version:       1.0
Sprache:       C
Compiler:      MBED
Autor:         PS
Copyright:     PS
                 
Funktion:      Telegrammauswertung fuer EcmCom Programm auf LPC1768

Letzte Änderung für neue EcmWin Version 2.1 war
Ver.: 2.0.1.0


-------------------------------------------------------------------------------
*/
/*-------------------------------------------------------------------------------
-------------------------------------------------------------------------------*/
#include "Headers.h"




/*-------------------------------------------------------------------------------
Interne Prototypen
-------------------------------------------------------------------------------*/
extern int ScanNext(char *Line, int &Start, int Len);


/*-------------------------------------------------------------------------------
Variablen, die nur in EcmTel verwendet werden
-------------------------------------------------------------------------------*/
char TelCode[8];

int TelLen;

char *TelPos;


const char *CodeTab[11] = {"CN", "SK", "FR", "SW", "SC", "IC", "SI", "DI", "GD", "DY", "PA"
};
                               
/* Die Codefunktionen sind:
CN: Kanalnummern setzen     DecodeChannel()
SK: Kontakt Setzen          DecodeContact()
FR: Freigabe, keine Komm.   DecodeFreigabe()
SW: Set Watchdog            DecodeSetWd()
SC: Set Analogausgang       DecodeAnalogValue()
IC: Setzt den Ini Code     DecodeIniCode(char *Line);
SI: Sendet den Ini Code    SendIniCode(char *Line);

DI: Sendet die DevID Datei, damit EcmWin das angeschlossene Gerät erkennen kann
GD: Empfängt die DevID Datei, 
DY: Dummy Telegramm damit die Leitung in beide Richtungen angesprochen wird
PA: Schaltet die Pumpe ein.   SwitchPumpeOn

*/



int (*FktPtr[])(char *) = {DecodeChannel, DecodeContact, DecodeFreigabe, DecodeSetWd,DecodeAnalogValue, DecodeIniCode, \
                            SendIniCode, SendDevFile, GetDevFile, RequestDummy, SwitchPumpeOn
};

/*-------------------------------------------------------------------------------
    Funktion CheckSioTel prueft den gesamten String und fieselt die einzelenen
    Telegramme auseinander. Für jedes Telegramm wird separat DecodeTel aufgerufen,
    welches den Inhalt des Telegramms auswertet
    Der Telegrammanfang ist mit ! , das Ende mit $ gekennzeichnet
-------------------------------------------------------------------------------*/
int CheckTel()
{
    int i, Len;
    char OldSign;

    i=0;

    Len = HostIf.nAwTelLen;
#ifdef SIO_DEBUG    
//    printf("HostIf.strTelAwBuf: %s\r\n",HostIf.strTelAwBuf);
#endif
//    printf("%c#DG#HostIf.strTelAwBuf: %s%c\r\n",STX, HostIf.strTelAwBuf, ETX);

    while(i < Len)
    {
        if(HostIf.strTelAwBuf[i] == STX) // hat Startzeichen erkannt. sollten Zeichen vor dem STX sein, dann werden diese verworfen
        {
            HostIf.ptrTelPos = &HostIf.strTelAwBuf[i+1];
            HostIf.nTelLen = Len - i -1;  // das Existieren von ETX wurde verher schon geprueft
			
            OldSign = HostIf.strTelAwBuf[Len-1];
            HostIf.strTelAwBuf[Len-1] = 0x00;
            DecodeTel();
            HostIf.strTelAwBuf[Len-1] = OldSign;
            i = Len;
        }
        i++;
    }
    ChangeLedColor();
    HostIf.fIsConnected = true;
    return(0);
}
/*-------------------------------------------------------------------------------
    CompareTelCode: vergleicht den Inhalt des Telegramms mit der Tabelle
-------------------------------------------------------------------------------*/
int CompareTelCode()
{
    int i;

    for(i=0;i<ANZ_TEL_CODE;i++)
    {
        if( (HostIf.TelCode[0] == CodeTab[i][0]) && (HostIf.TelCode[1] == CodeTab[i][1]) )
        {
//            printf("%s\n", HostIf.strTelAwBuf);
            return(i);
        }
    }
    return(-1);
}


/*-------------------------------------------------------------------------------
    Funktion DecodeTel prueft Telegramme auf Inhalt und Befehl. Wird nur aufgerufen,
    wenn Telegramm vollständig.
    TelPos zeigt auf Anfang de Telegramms, TelLen ist die Länge bis zum TelEnde
------------------------------------------------------------------------------- */
int DecodeTel()
{
    int i, Ret;

    i =0;
    while( (*(HostIf.ptrTelPos+i) == '#') && (i < HostIf.nAwTelLen) )
        i++;

    if( (*(HostIf.ptrTelPos+i) > 0x40) && (*(HostIf.ptrTelPos+i) < 0x5B)) // ist ein Zeichen aus den Grossbuchstaben
    {
        if( (*(HostIf.ptrTelPos+i+1) > 0x40) && (*(HostIf.ptrTelPos+i+1) < 0x5B)) // auch das zweite Zeichen ist ein Grossbuchstabe
        {
            if(*(HostIf.ptrTelPos+i+2) == '#')   // erst kommen zwei Großbuchstaben und dann ein #
            {   // ist ein richtige Telegramm
                HostIf.TelCode[0] = *(HostIf.ptrTelPos+i);
                HostIf.TelCode[1] = *(HostIf.ptrTelPos+i+1);
                HostIf.TelCode[2] = 0x00;
                Ret = CompareTelCode();
                if(Ret >= 0)    // gütiger Wert
                {
                    (*FktPtr[Ret])((char *)(HostIf.ptrTelPos+i+3));
                }
                else    // findet keinen passenden Code
                {
                    sprintf(HostIf.strErrorBuf,"%c#ER#Unbekanntes Telegramm", STX);
					HostIf.fSendError = true;
//                    printf("%s",IdSendBuf);
                   
                }
            }
        }
    }
    return(0);
}
/*-------------------------------------------------------------------------------
RequestDummy: Nichts tun
-------------------------------------------------------------------------------*/
int RequestDummy(char *Line)
{
//   	MVars.m_fSendStatus = true;
    return(1);
}


//--------------------------------------------------------------------------
// Telegramm #IC#: Decode Ini File EcmWin sendet einen neuen IniFile
//--------------------------------------------------------------------------
int DecodeIniCode(char *Line)
{
    strcat(Line, "\r\n");
    clSdCard.WriteFile(FileNames.IniFileName, Line);
    OpenIni();
    return(true);
}
//--------------------------------------------------------------------------
// Telegramm #SI#: Send Ini File. EcmWin ruft den Inifile ab
//--------------------------------------------------------------------------
int SendIniCode(char *Line)
{
    int Ret, fEnde;
    
    Ret = clSdCard.OpenFile( (char *)FileNames.IniFileName, FileNames.FileReadMode);

    if(Ret == false)
    {
		sprintf(HostIf.strTempBuf, "%c#DG#Fehler beim Oeffnen der IniDatei %s  %s",STX, FileNames.IniFileName, FileNames.FileReadMode);
		SendTelToHost(false, false, 0);   // weitere Telegramme und kein EOF
		return(false);                // Fehler beim Öffnen der Datei    
    }
	SetTimerInterrupt(0);
    fEnde = false;
    sprintf(HostIf.strTempBuf, "%c#SI#",STX);
    SendTelToHost(true, false, 0);   // weitere Telegramme und kein EOF
    do
    {
        Ret = clSdCard.ReadLine(HostIf.strTempBuf, 512); // HostIf.strCommonTmpBuf hat 512 Zeichen, mehr sind in einer Zeile nicht drin
        if(Ret > 0)
        {
            SendTelToHost(true, false, 0);   // weitere Telegramme, kein EOF, LF durch # ersetzen
        }
        else    // wenn er mit Ret = 0 zurückkommt, dann sind die Fehler gecleart, Datei noch offen
        {
			HostIf.strTempBuf[0] = 0x00;  // ETX wird spaeter drangehaengt
            SendTelToHost(false, false, 0);   // Gesamtdatei kleiner 16384 Bytes, daher ohne EOF
            fEnde = true;
        }
    }
    while(fEnde == false);
    clSdCard.CloseFile();
    if(MVars.m_fMessDlgOpened == true)
		SetTimerInterrupt(1);
    return(true);
}
//--------------------------------------------------------------------------
// ScanNext: Such die nächste Stelle im Telegramm hinter dem #
//--------------------------------------------------------------------------
int ScanNext(char *Line, int &Start, int Len)
{
    while(*(Line+Start) != '#')
    {
        Start++;
        if(Start >= Len)
            return(false);
    }
    Start++;
    if(Start >= Len)
        return(false);
    return(true);
}
//--------------------------------------------------------------------------
// Telegramm #CN#: Kanalnummern, Anz. Messwerte und Gültige Kanäle werde uebertragen
// Kanalnummern, die uebertragen werden sollen
// Tel hat die Form: !#CN#0,1,2,3,4,5,6,7,4,5,6,7, 4,5,6,7,0,0|<CR><LF>
// Die ersten 8 Zahlen sind die Kanalnumern der Messkanaele, die naechste vier sind die Schaltkanaele
// die naechsten beiden sind Autorange
//--------------------------------------------------------------------------
int DecodeChannel(char *Line)
{
    int Start, Len,i;
    
//	printf("%c#DG#Decode Channel Line %s %c\n", STX, Line, ETX);
    MVars.m_fMessDlgOpened = true;
    MVars.fAdReInit = false;
    MVars.fEnableAuto = true;   // damit EnableAutoRange gesetzt wird
    MVars.nAktMittelAfter = 500;    // in Grundstellung alle 500ms

    Start = 0;
    Len = strlen(Line);
//	printf("%c#DG#LineLen Decode Channel %d %c\n", STX,Len, ETX);
    for(i=0;i<8;i++)
    {
        MVars.dbAdSum[i] = 0.;
        MVars.MwChn[i] = atoi(Line+Start);
        if(ScanNext(Line,Start, Len) == false)   return(false);
    }
//	printf("%c#DG#Decode Channel nach for i<8 %c\n", STX, ETX);
    
    MVars.m_nAnzChnSend = 3;

    for(i=0;i<3;i++)
        MVars.m_fChnValid[i] = true;

//	printf("%c#DG#Decode Channel nach fValid%c\n", STX, ETX);

    MVars.SendAnzWerte = 2;
    CalcSendAnzWerte();
    if(MVars.SendAnzWerte == 1000)
    {
        MVars.AdConvTime = 0x18; // Startwert, längste Wandlungszeit
    }
    else if(MVars.SendAnzWerte == 500)
    {
        MVars.AdConvTime = 0x28; // Startwert, längste Wandlungszeit
    }    
    else if(MVars.SendAnzWerte == 200)
    {
        MVars.AdConvTime = 0x58; // Startwert, längste Wandlungszeit
    }    
    else 
    {
        MVars.AdConvTime = 0x7F; // Startwert, längste Wandlungszeit
    }    
//	printf("%c#DG#Decode Channel nach CalcSendAnz%c\n", STX, ETX);
    
//    SetAdConversionTime();
//    wait(2.0);
    SetTimerInterrupt(1);  // wenn er schon laeuft, dann passiert nichts
    
    MVars.nAktMittelAfter = 500;    // in Grundstellung alle 500ms

    MVars.nSendAfter = 500;
    MVars.m_nAnzValue = 1;
    
    MVars.nDestCount = 0;
    MVars.nMittelTimer =0;
    MVars.nMessTimer = 0;
    MVars.m_fStartTel = 0x01;
    MVars.m_nSendValues = 1;
    STemp[0] = 0x00;

//    Ad7739Init();
    Ad7739Start(0, 0,1);
//    MVars.fAdReInit = true;
//	printf("%c#DG#Ende Decode Channel%c\n", STX, ETX);

    return(true);
}
//--------------------------------------------------------------------------
void CalcSendAnzWerte()
{
    if(MVars.SendAnzWerte >= 1000)   // 1000 Werte Pro Sekunden
        MVars.nMittelAfter = 1;
    else if(MVars.SendAnzWerte == 500)   // 500 Werte Pro Sekunden
        MVars.nMittelAfter = 2;
    else if(MVars.SendAnzWerte == 200)   // 200 Werte Pro Sekunden
        MVars.nMittelAfter = 5;
    else if(MVars.SendAnzWerte == 100)   // 100 Werte Pro Sekunden
        MVars.nMittelAfter = 10;
    else if(MVars.SendAnzWerte == 50)   // 50 Werte Pro Sekunden
        MVars.nMittelAfter = 20;
    else if(MVars.SendAnzWerte == 20)   // 20 Werte Pro Sekunden
        MVars.nMittelAfter = 50;
    else if(MVars.SendAnzWerte == 10)   // 10 Werte Pro Sekunden
        MVars.nMittelAfter = 100;
    else if(MVars.SendAnzWerte == 4)   // 4 Werte Pro Sekunden
        MVars.nMittelAfter = 250;
    else // if(MVars.SendAnzWerte == 2)   // 2 Werte Pro Sekunden
        MVars.nMittelAfter = 500;
}
//--------------------------------------------------------------------------
// #SK#  // beliebigen Kanal schalten
//--------------------------------------------------------------------------
int DecodeContact(char *Line)
{
    int Start,Len, SkChn;
    bool SkLevel;

    Start = 0;
    
    Len = strlen(Line);
    SkChn = atoi(Line);
    while( (*(Line+Start) != '#') && (Start < Len) )
        Start++;
    Start += 1;
    SkLevel = (bool)atoi(Line+Start);
    
    if(SkChn == 0) // Start Kommando, Motor laeuft los
    {
        if(SkLevel == 0)    
        	SwR0 = false;
        else
        {                
        	SwR0 = true;
        	MVars.m_fSendStatus = true;
        }
    }
    else if(SkChn == 1) // Direktion, wenn low, dann Gegenuhrzeigersinn
    {
        if(SkLevel == 0)    SwR1 = false;
        else                SwR1 = true;
    }
    

    return(true);
}
//--------------------------------------------------------------------------
//  #FR#  Pot. freigeben
//--------------------------------------------------------------------------
int DecodeFreigabe(char *Line)
{
    int i;

    MVars.nMessArt = 0;
    MVars.fSequenzMessung = false;
    IrComp.fMitIrValue = false;
    MVars.m_fMessDlgOpened = false;
    FrqValues.fImpedance = false;   // falls er auf Impedanzmessung war

    Ad7739Stop();
    for(i=0;i<ANZ_POT;i++)
        MVars.nMessZustand[i] = 0;
    IrComp.dbAOut[0] = 0.;
    CalcDa(IrComp.dbAOut[0], 0);
    MVars.m_nSendValues = 0;
    
    LedsOff();
    MVars.fEnableAuto = false;   // damit EnableAutoRange gesetzt wird
    nMyTimer = 0;
    return(true);
}
//--------------------------------------------------------------------------
//  #SW#   Set Watchdog
//--------------------------------------------------------------------------
int DecodeSetWd(char *Line)
{
    int Start,Len,i;

    Start = 0;
    Len = strlen(Line);
    WDog.fEnabled = (bool)atoi(Line);

    while( (*(Line+Start) != '#') && (Start < Len) )
        Start++;
    Start++;
    WDog.nTimeOut = atoi(Line+Start);
    WDog.nMsTimeOut = WDog.nTimeOut * 200;

    while( (*(Line+Start) != '#') && (Start < Len) )
        Start++;
    Start++;
    i=0;
    while( (*(Line+Start) != '#') && (Start < Len) )
    {
        WDog.cSign[i] = *(Line+Start);
        Start++;    i++;
        if(i > 7)   break;
    }
    Start++;
    WDog.fLogFile = (bool)atoi(Line+Start);
//        printf("WatchDog: %d,  %d,  %s,  %d",WDog.fEnabled, WDog.nTimeOut, WDog.cSign, WDog.fLogFile);
    return(true);
}
//--------------------------------------------------------------------------
 // #SC#  Analogausgang setzen
//--------------------------------------------------------------------------
int DecodeAnalogValue(char *Line)
{
    int Start,Chn;

    Start = 0;

//    return(true);
//    printf("Puffer:%s",Line);
#ifdef SIO_DEBUG    
        printf("MessZustand: %d Flag Sequenzmessung %d\n",MVars.nMessZustand[0], MVars.fSequenzMessung);
#endif    
    if(MVars.fSequenzMessung)   // nur wenn innerhalb der Sequenzmessung
        MVars.m_fScan = false;
    Chn = atoi(Line);
    if(Chn > 0) Chn--;  // bekommt 1 und 2, muss aber mit 0 und 1 arbeiten
    Start += 2;
//  printf("Ch:%d Val:%f\n",Channel,AOut);
    IrComp.dbAOut[Chn] = atof(Line+Start);
#ifdef SIO_DEBUG    
        printf("DaValue: %f \n",IrComp.dbAOut[Chn]);
#endif    
    CalcDa(IrComp.dbAOut[Chn], Chn);

    return(true);
}
/*-------------------------------------------------------------------------------
// SendIdTel: Sendet das ID-Telegramm
-------------------------------------------------------------------------------*/
int SendIdTel()
{
//    TcpClient.send( TcpSendBuf, strlen(TcpSendBuf));
    return(1);
}
//--------------------------------------------------------------------------
// Telegramm #CN#: Kanalnummern, Anz. Messwerte und Gültige Kanäle werde uebertragen
// Kanalnummern, die uebertragen werden sollen
// Tel hat die Form: !#CN#0,1,2,3,4,5,6,7,4,5,6,7, 4,5,6,7,0,0|<CR><LF>
// Die ersten 8 Zahlen sind die Kanalnumern der Messkanaele, die naechste vier sind die Schaltkanaele
// die naechsten beiden sind Autorange
//--------------------------------------------------------------------------
int SwitchPumpeOn(char *Line)
{
    int Start, Len,i;
    
    Start = 0;
    Len = strlen(Line);

    IrComp.dbAOut[0] = atof(Line+Start);
    CalcDa(IrComp.dbAOut[0], 0);
   	SwR0 = true;
   	MVars.m_fSendStatus = true;
	return(true);
}