Программа для чтения UDP сообщений от модема Enfora с использованием Indy компонента C++ Builder 6

Введение

Модем на основе модуля Enfora GSM0308

Программа для чтения UDP сообщений с исползованием компанента Indy C++ Builder

Управление модемом Enfora через СМС

Пишите автору сайта ganatol2000@mail.ru

 

Воспользуемся C++ Builder 6. В него входят как раз нужный нам Indy компонент: IdUDPServer.

В параметре DefaultPort компонента IdUDPServer не забудьте выставить порт, который был введен в модем командой AT$UDPAPI. У меня это 40000. А также проверьте, чтобы свойство: Active имело значение true Основное событие OnUDPRead, оно генерируется всякий раз в момент приема UDP сообщения. Вот функция, которая реализует обработку этого события

void __fastcall TForm1::IdUDPServer1UDPRead(TObject *Sender,
TStream *AData, TIdSocketHandle *ABinding)
{
char My[200];
TDateTime DateMy;
TDateTime TimeMy;
AnsiString MyDump;

AData->ReadBuffer(My, AData->Size);
My[AData->Size]=0;
MyDump=Dump(My, AData->Size, 0, true, "");

DateMy = Date();
AnsiString strDate = DateToStr(DateMy);
TimeMy = Time(); // store the current date and time
AnsiString strTime = TimeToStr(TimeMy);

Memo1->Lines->Add(strDate+" "+strTime+":"+
"IP:"+ABinding->PeerIP+":"+"Port:"+ABinding->PeerPort+":"+"Size:"+AData->Size+":"+"Data:"+MyDump);
if(AData->Size==42)
{
int a= DataGrammAnalogValie(My).ToInt();
float b=a*0.001709;
Memo2->Lines->Add(DataGrammMessageID(My)+" "+DataGrammModemID(My)+" "+CurrToStr(b));

Series1->Add(b*koefficient, strTime, clRed);

FILE* MyAnalogValue;
char* h=" ";
char* u="U=";
MyAnalogValue=fopen("analog_value.log","a");
fprintf(MyAnalogValue,"%s %s %s %s %s %s %s %s %s %s \n",strDate.c_str(), h, strTime.c_str(),
h, DataGrammMessageID(My).c_str(), h, DataGrammModemID(My).c_str(),
h, u, CurrToStr(b*koefficient).c_str());
fclose(MyAnalogValue);

}
else
{
Memo2->Lines->Add("The format of the datagram is not supported");
}


}

Здесь
AData->ReadBuffer(My, AData->Size); считывает принятую датаграмму в char My[200]
, далее функцией Dump:
AnsiString __fastcall Dump(void *data, int size, int col,
bool hex, const AnsiString &pref)
{
AnsiString s;
for (int i = 0; i < size; ++i) {
if (!i)
s += pref;
else if (col && !(i % col)) {
s += "\n";
s += pref;
}
if (hex)
s += IntToHex(((unsigned char*)data)[i], 2) + " ";
else {
AnsiString s1 = int(((unsigned char*)data)[i]);
while (s1.Length() < 3)
s1 = " " + s1;
s += s1 + " ";
}
}
return s;
}
 
формируется дамп. Потом считывается дата и время и все эти данные отправляются в компонент
Memo1 для отображения. Обратите внимания, что используя ABinding->PeerIP и ABinding->PeerPort мы так же отображаем IP адрес и порт откуда пришло UDP сообщение.



 

Но сам дамп не очень информативен. Можно конечно используя таблицу ASСII символов попытаться понять что же мы получили...

Но все-таки наверное следует обработать данные и отобразить в более приемлемом для человека виде. Поэтому проверяем размер
UDP сообщения, который должен составлять в выбранном нами формате 42 байта. И если размер сообщения совпадает с ожидаемым, то функциями:
AnsiString __fastcall DataGrammMessageID(char *data)
{
AnsiString s;
for (int i = 4; i < 14; ++i) {
s += AnsiString::StringOfChar(data[i], 1);
}
return s;
}

AnsiString __fastcall DataGrammModemID(char *data)
{
AnsiString s;
for (int i = 15; i < 36; ++i) {
s += AnsiString::StringOfChar(data[i], 1);
}
return s;
}


AnsiString __fastcall DataGrammAnalogValie(char *data)
{
AnsiString s;
for (int i = 37; i < 41; ++i) {
s += AnsiString::StringOfChar(data[i], 1);
}
return s;
}
разберем
UDP сообщение на составляющие, и используя коэффициент 0,001709 вычислим значение напряжения подаваемого на аналоговый вход. Потом всю эту информацию подадим на компонент Memo2 для отображения. Также используя
Series1->Add(b*koefficient, strTime, clRed); выведем значение аналоговой величины на график(компонент TChart), чтобы можно было наблюдать её изменение с течением времени. Здесь koefficient переменная параметризации, записываемая кнопкой Save (функции реализующие работу с переменной koefficient найдете в исходниках программы или придумаете сами). В заключении расшифрованное UDP сообщение регистрируется в log файле.

Управление модемом Enfora через СМС

Hosted by uCoz