Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Спец.символы, послать в сом порт 
:(
    Опции темы
Лена
Дата 21.4.2008, 10:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Я хочу посылать команду СОМ порту в своей программе из окна Edit. В окне Edit текст команды $ST+TEST=0000:
Код

void __fastcall TForm1::ButtonPoslatClick(TObject *Sender)
{
 AnsiString buf;
 int n;
 buf = Edit1->Text.Trim();
 FlushFileBuffers(port);
 try
 {
 WriteFile(port, buf.c_str(), strlen(buf.c_str()), &DWORD(n), NULL);
 }
 catch(...)
   {
    ShowMessage("Не удалось отправить команду " + Edit1->Text.Trim());
    return;
   }
 ShowMessage("Передана команда "+ Edit1->Text.Trim()+" всего " + IntToStr(n) + " байт");
}

Мне надо дополнить команду символом возврата коретки с переводом строки. Как отправить такую команду порту?
Так не правильно посылать в порт?: Edit1->Text = "$ST+TEST=0000\r\n"; 
PM MAIL   Вверх
ksili
Дата 21.4.2008, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



Я вот так посылал команду в порт:
Код

cmd = "ATZ\r";
WriteFile(port, cmd.c_str(), cmd.Length(), &dwWritten, &ovr);

Потом читал ответ (на порту находился GSM-модем), приходило: ATZ\r\r\nOK\r\n.

Я не знаю, что там у вас за устройство на порту, но у меня всё нормально работало, когда команда завершалась символом \r. При использовании \r\n то ли не работало, то ли было всё также как при \r. А  при \n вроде не работало. Но я уже плохо помню


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
Лена
Дата 21.4.2008, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Цитата(ksili @  21.4.2008,  10:36 Найти цитируемый пост)
cmd = "ATZ\r";


У меня так не работает.
Подскажите как преобразовать строку $ST+TEST=0000\r\n в массив байт и отправить его в порт?

PM MAIL   Вверх
orthrus
Дата 22.4.2008, 04:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 400
Регистрация: 30.10.2007
Где: г. Усть-Илимск(Ир кутская обл.)

Репутация: 4
Всего: 16



Цитата(Лена @  21.4.2008,  15:11 Найти цитируемый пост)
Подскажите как преобразовать строку $ST+TEST=0000\r\n в массив байт и отправить его в порт?

можно так:
Код

char* str;
int n;
strcpy(str,"$ST+TEST=0000\r\n");
WriteFile(port,str, strlen(str), &DWORD(n), NULL);

и так как ты делаешь тоже можно:
Код

AnsiString buf;
int n;
buf = Edit1->Text.Trim();
WriteFile(port, buf.c_str(), strlen(buf.c_str()), &DWORD(n), NULL);

ещё можно использовать сторонние компоненты для работы с com портом


--------------------
У того, кто ничего не делает, всегда много помощников.© Л.Н. Толстой
user posted image
PM MAIL ICQ   Вверх
ksili
Дата 22.4.2008, 05:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



Лена, почему вы считаете, что ваша строка не отправляется?


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
Лена
Дата 24.4.2008, 09:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Вот этот переделанный вариант, у меня заработал:
Код

HANDLE port = 0;
TDCB lpDCB;
TOverlapped Overlapp ;
AnsiString buf;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
//список портов
void __fastcall TForm1::FormActivate(TObject *Sender)
{
TRegistry* Reg = new TRegistry;
TStringList *List = new TStringList;
int i;
AnsiString w;

Reg->RootKey = HKEY_LOCAL_MACHINE;
Reg->OpenKey("HARDWARE\\DEVICEMAP\\SERIALCOMM", false);
Reg->GetValueNames(List);
for (i = 0; i< List->Count; i++)
{
 w= Reg->ReadString(List->Strings[i]).SetLength(3);
 if (w.SetLength(3) == "COM")
    ComboBox1->Items->Add(Reg->ReadString(List->Strings[i]));
}

delete List;
Reg->CloseKey();
delete Reg;
ComboBox1->ItemIndex = 0;
}

//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
 port = 0;
 Overlapp.hEvent = 0;
 Overlapp.Internal = 0;
 Overlapp.InternalHigh = 0;
 Overlapp.Offset = 0;
 Overlapp.OffsetHigh = 0;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
 if (port != 0)
   {
    CloseHandle(port);
   }

}
//---------------------------------------------------------------------------
//открыть порт
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 if (port == 0)
     port = CreateFile(ComboBox1->Text.c_str(),GENERIC_READ | GENERIC_WRITE, 0,
                  NULL, OPEN_EXISTING,FILE_FLAG_OVERLAPPED, 0);

 if(! GetCommState(port, &lpDCB))
  {
   ShowMessage("Не удалось открыть порт " + ComboBox1->Text);
   exit;
  }
 //комбобоксы
 CBBaudRate->ItemIndex = CBBaudRate->Items->IndexOf(IntToStr(lpDCB.BaudRate));
 CBParity->ItemIndex = lpDCB.Parity;
 CBByteSize->ItemIndex = lpDCB.ByteSize - 4;
 CBStopBits->ItemIndex = lpDCB.StopBits;
 Button2->Enabled = true;

}
//---------------------------------------------------------------------------

//запись парметров в порт
void __fastcall TForm1::Button2Click(TObject *Sender)
{

  lpDCB.BaudRate = StrToInt(CBBaudRate->Text);
  lpDCB.ByteSize = CBByteSize->ItemIndex + 4;
  lpDCB.Parity = CBParity->ItemIndex;
  lpDCB.StopBits = CBStopBits->ItemIndex;
if (!SetCommState(port, &lpDCB))
  {
   ShowMessage("Значения параметров недопустимые\n"
               "Установка не произведена");
   Button1Click(Sender);
   exit;
  }

 Button1Click(Sender);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ComboBox1CloseUp(TObject *Sender)
{
 Button2->Enabled = false;
 if (port != 0)
  {
   CBBaudRate->ItemIndex = -1;
   CBByteSize->ItemIndex = -1;
   CBParity->ItemIndex = -1;
   CBStopBits->ItemIndex = -1;

   CloseHandle(port);
   port = 0;
  }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonPoslatClick(TObject *Sender)
{
  AnsiString S = Edit1->Text;
  char Eol[3] = { 13, 10, 0 };
  char Command[128];
  strcpy(Command, S.c_str());
  strcat(Command, Eol);
  DWORD n;
  FlushFileBuffers(port);
  if(!WriteFile(port, Command, strlen(Command),&n, &Overlapp))
   {
    if(GetLastError() != ERROR_IO_PENDING)
        ShowMessage( "Ошибка: " + SysErrorMessage(GetLastError()) );
     else
        Timer1->Enabled = true;
   }
 else
    Label6->Caption = "Переданы новые данные - " + IntToStr(n) + " байт";


}
//---------------------------------------------------------------------------
char bufnew[255];
AnsiString rez;
//Признак того, что операция началась и продолжается
//— получение кода возврата ERROR_IO_PENDING.
void __fastcall TForm1::ButtonPolychitClick(TObject *Sender)
{
 DWORD n;
 if(!ReadFile(port, bufnew, 255, &n, &Overlapp) )
   {
      if(GetLastError() != ERROR_IO_PENDING)
      ShowMessage( "Ошибка: " + SysErrorMessage(GetLastError()) );
    else
      Timer1->Enabled = true;
   }
 else
    {
     Label6->Caption = "Получены новые данные - " + IntToStr(n) + " байт";
     Label7->Caption = bufnew;
    }

}
//---------------------------------------------------------------------------
//в процессе выполнения приложения следует периодически
//опрашивать систему, чтобы получить информацию о завершении записи или чтения
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
 DWORD n;
 if(GetOverlappedResult(port, &Overlapp, &n, false))
 {
  Label6->Caption = "Получены/переданы новые данные - " + IntToStr(n) + " байт";
  Timer1->Enabled = false;
 }
 else Label6->Caption = "Новых данных нет";

}
//---------------------------------------------------------------------------

PM MAIL   Вверх
xvr
Дата 24.4.2008, 14:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Цитата(Лена @ 24.4.2008,  09:17)
Вот этот переделанный вариант, у меня заработал:
Код


void __fastcall TForm1::ButtonPoslatClick(TObject *Sender)
{
  AnsiString S = Edit1->Text;
  char Eol[3] = { 13, 10, 0 };
  char Command[128];
  strcpy(Command, S.c_str());
  strcat(Command, Eol);
  DWORD n;
  FlushFileBuffers(port);
  if(!WriteFile(port, Command, strlen(Command),&n, &Overlapp))
   {
    if(GetLastError() != ERROR_IO_PENDING)
        ShowMessage( "Ошибка: " + SysErrorMessage(GetLastError()) );
     else
        Timer1->Enabled = true;
   }
 else
    Label6->Caption = "Переданы новые данные - " + IntToStr(n) + " байт";

}

Тебе очень повезло, что заработал - не должен был  smile 
У тебя массив  char Command[128];, который отсылается через WriteFile локальный в функции, т.е. память, занимаемая им будет переиспользованна сразу после выхода из функции. WriteFile вызывается в Overlapped режиме, т.е. содержимое этого, уже невалидного массива, будет по прежнему передаваться (в фоне). Результат непредсказуемый.
Цитата

Accessing the output buffer while a write operation is using the buffer may lead to corruption of the data written from that buffer. Applications must not write to, reallocate, or free the output buffer that a write operation is using until the write operation completes.

PM MAIL   Вверх
Лена
Дата 24.4.2008, 14:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Выход сделать char Command[128] глобальной переменной? Еще есть не дочеты? smile 
PM MAIL   Вверх
xvr
Дата 25.4.2008, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Цитата(Лена @ 24.4.2008,  14:16)
Выход сделать char Command[128] глобальной переменной?

Да. Либо вообще сделать запись в порт в не Overlapped режиме - запись в любом случае производится во внутренний буфер драйвера сериального порта и отправка будет происходить в фоновом режиме. Overlapped при записи в порт нужен только если в порт пишется непрерывный поток.
Цитата

 Еще есть не дочеты? smile
Есть. Если чтение из порта не произойдет сразу (ReadFile вернется с ошибкой ERROR_IO_PENDING) то пользователь так и не увидит, что именно прочлось из порта - Timer1Timer не выводит никуда принятые данные (если это был прием)

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.1246 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.