Test
Dependencies: mbed-dev-OS5_10_4
Diff: MySources/EcmTel.cpp
- Revision:
- 0:014fad4dfb9d
diff -r 000000000000 -r 014fad4dfb9d MySources/EcmTel.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MySources/EcmTel.cpp Fri Aug 07 07:24:21 2020 +0000 @@ -0,0 +1,485 @@ +/* +------------------------------------------------------------------------------- +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); +}