[image]

Программа для работы со стендом ТРД-2, Среда Builder C++ 6.0

 
1 2 3

kirya

втянувшийся

kirya>> Да, все правильно. Там стоит то, что пользователь выбирает.
Mishka> Ы? Если устройство определено как 5, то зачем выбирать 2?

Вот как у меня на самом деле.
port=CreateFile(ComboBox1->Items->Strings[ComboBox1->ItemIndex].c_str(),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);

А приводил я пример из интернета, на оснве которого все делал.
   6.06.0

kirya

втянувшийся

Хоть и не разобрался в чем было дело, но вставил код настройки порта в другное место программы и все заработало. А если работат, то лучше не трогать.
   6.06.0

kirya

втянувшийся

Как сделать так чтобы моя программа запускалась на других компах? Сейчас мой проект сотоит из папки в которой куча всяких файлов в том чиле и один exe файл. Если его взять (и БД тоже) и перенести на другой комп, то он не запуститься. Может мне нужно как-то создать установочный файл, который произведет все нужные операции для запуска проги. Только не знаю как это делается и есть ли у Builder C++ 6.0 такая возможность.
   6.06.0

kirya

втянувшийся

kirya> Как сделать так чтобы моя программа запускалась на других компах?

Разобрался, отличный ресурс есть, который раз уже выручает C++ Builder. Перенос приложения на другой компьютер
   6.06.0

kirya

втянувшийся

Хочется программу для стенда использовать на ноутбуке. А сейчас на всех ноутах Windows7 стоит. Я установил драйвер - виртуальный СОМ порт появился. Установил утилитку фирменную для работы с СОМ портом, все нормально, работает. Думал и моя прога заработает. Запустил, но доступных СОМ портов не появилось, т.е. моя прога не видит их. Что можно в этом случае сделать с программой? Посоветуйте что почитать и с чего начинать.
   

Mishka

модератор
★★★
kirya> Что можно в этом случае сделать с программой? Посоветуйте что почитать и с чего начинать.

В районе совместимости старых приложений. На exe-шник правой кнопкой мыши и там есть такой таб. ИМХО, где-то там надо указать, что доступны устройства и программа может управлять ими.

PS С 7 работаю крайне эпизодически, даже на ноуте переползаю на линь.
   4.0.14.0.1

kirya

втянувшийся

Mishka> В районе совместимости старых приложений. На exe-шник правой кнопкой мыши и там есть такой таб. ИМХО, где-то там надо указать, что доступны устройства и программа может управлять ими.

Там есть такое - запустить программу в режиме совместимости с WinXp SP2. Я поробовал. Также СОМ порты не видит. Все остальное исправно работает, графики строятся.
   

Mishka

модератор
★★★
kirya> Там есть такое - запустить программу в режиме совместимости с WinXp SP2. Я поробовал. Также СОМ порты не видит. Все остальное исправно работает, графики строятся.

Какой драйвер установил? Он какое имя устройству создаёт? Точно COMx? Нет там других символов?

Скажем, у меня на системе простая проверка такое выдаёт:

code text
  1. C:\>echo 1 >COM1
  2.  
  3. C:\>echo 1 >COM2
  4. The system cannot find the file specified.
  5.  
  6. C:\>
   4.0.14.0.1

kirya

втянувшийся

Mishka> Какой драйвер установил? Он какое имя устройству создаёт? Точно COMx? Нет там других символов?

Драйвер на PL2303 с сайта производителя. Это конвертер USB COM эммулирует работу СОМ порта. Создает СОМ порт - СОМ11. С драйвером нет проблем, поскольку сторонняя утилита Comport ToolKit исправно находит СОМ порт и общается с ним.
   

Mishka

модератор
★★★
kirya> Драйвер на PL2303 с сайта производителя. Это конвертер USB COM эммулирует работу СОМ порта. Создает СОМ порт - СОМ11. С драйвером нет проблем, поскольку сторонняя утилита Comport ToolKit исправно находит СОМ порт и общается с ним.

Из ДОС окна запусти echo 1>COM11 и скажи, что получилось.
   

kirya

втянувшийся

Кажется разобрался, точнее нашел пример кода где все написано как у меня но немного полнее.
Я бы хотел продолжить эту тему для того чтобы программисты объяснили мне некоторые фундаментальные моменты в этой программе. Я никогда не учился программировать и вопросы буду задавать из самых начал, типа как правильно сказать...
Вот объявление
HANDLE COMport;

Что это!? Я объявил переменную типа HANDLE?
Что особенного в этой новой переменной, чем она например отличается от int или float?
После такого объвлния я могу использовать такую функцию:
char p[5];
COMport=CreateFile(p,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);

Видимо CreateFile как-то завязана с HANDLE. Где например узнать какие функции еще в HANDLE есть, и вообще правильно ли я выражаюсь!? Как назвать HANDLE правильно - структура,тип,класс,дескриптор!?
Только просьба не посылать читать литературу, я исследую конкретный пример, по нему буду учится. Если нет желания и возможности ответить, не отвечайте.
   6.06.0

Mishka

модератор
★★★
kirya> HANDLE COMport;
kirya> Что это!? Я объявил переменную типа HANDLE?
Это объявление переменной COMport типа HANDLE. И даже знать не нужно, чо именно она представляет. Определается тип набором операций. Точно так же, как и int или char. Внутри же это указатель на некоторый объект, с которым работает ОС.

kirya> Что особенного в этой новой переменной, чем она например отличается от int или float?

Тип другой. Соответственно, другие операции. Вот int, к примеру, отличается от float хотя бы по операции деления. Но эти два типа более привычны. А указатель уже менее привычен и операции другие.

kirya> После такого объвлния я могу использовать такую функцию:
kirya> char p[5];

kirya> COMport=CreateFile(p,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
1. Пропущена операция инициализации p. Без неё не будет работать.
2. ОС создала файл (в более широком смысле, чем файл на диске). Чтобы знать, с каким файлом программа хочет работать, надо этому файлу присвоить какой-то ID. Вот CreateFile этот ID и возвращает. И он присваивается в переменную COMport.
3. Программы ввода-вывода работают одинаково для разных файлов. Поэтому они должны знать с каким именно файлом работать. Для этого у них есть параметр такого же типа HANDLE.

kirya> Видимо CreateFile как-то завязана с HANDLE. Где например узнать какие функции еще в HANDLE есть, и вообще правильно ли я выражаюсь!? Как назвать HANDLE правильно - структура,тип,класс,дескриптор!?

В HANDLE нет функций (здесь не ООП). Есть операции с типом и/или функции с параметром такого типа. Какие функции в int?

kirya> Только просьба не посылать читать литературу, я исследую конкретный пример, по нему буду учится. Если нет желания и возможности ответить, не отвечайте.

Это дорога в оба конца. Без чтения не обойтись. Никто не будет разжёвывать все-все подробности. Нет столько времени.
   

kirya

втянувшийся

Что может быть? При приеме нулевого байта моим устройством от такой функиции все работает, т.е. устройство принимает нулевой байт
TransmitCommChar(port,0x00);
А при такой функции принимает все кроме нулей.Хотя настройки порта одинаковые.все байты отличные от нуля принимаются устройством и в первом и во втором случае правильно.
//главная функция потока, выполняет передачу байтов из буфера в COM-порт
DWORD WINAPI WriteThread(LPVOID)
{
DWORD temp, signal; //temp - переменная-заглушка

overlappedwr.hEvent = CreateEvent(NULL, true, true, NULL); //создать событие
while(1)
{WriteFile(COMport, bufwr, strlen(bufwr), &temp, &overlappedwr); //записать байты в порт (перекрываемая операция!)
signal = WaitForSingleObject(overlappedwr.hEvent, INFINITE); //приостановить поток, пока не завершится перекрываемая операция WriteFile

if((signal == WAIT_OBJECT_0) && (GetOverlappedResult(COMport, &overlappedwr, &temp, true))) //если операция завершилась успешно
{
Form1->StatusBar1->Panels->Items[0]->Text = "Передача прошла успешно"; //вывести сообщение об этом в строке состояния
}
else {Form1->StatusBar1->Panels->Items[0]->Text = "Ошибка передачи";} //иначе вывести в строке состояния сообщение об ошибке

SuspendThread(writer);

}
}
   

kirya

втянувшийся

Кажется нашел проблему. Нулевые байты программа даже не пытается передавать. Вот с чем связано.
unsigned char bufwr[BUFSIZE];
bufwr[0]=0x2;
bufwr[1]=0x1;
bufwr[2]=0x10;
bufwr[3]=0x2;
bufwr[4]=0x2;
Form1->Edit6->Text = strlen(bufwr);

В итоге выдает длину 5.

unsigned char bufwr[BUFSIZE];
bufwr[0]=0x2;
bufwr[1]=0x0;/////!!!!!!!!!
bufwr[2]=0x10;
bufwr[3]=0x2;
bufwr[4]=0x2;
Form1->Edit6->Text = strlen(bufwr);

Если так то длина буфера 1.
   
Это сообщение редактировалось 25.08.2011 в 23:25

kirya

втянувшийся

В итоге объявляю глобальную переменную, в которой будет содержаться кол-во байт для передачи. Правильно ли я делаю с точки зрения высокоуровнего программирования? Просто читал где-то что гобаль.переменные не есть гуд и нужно обходится без них. Как правильней с делать в моей конкретной ситуации?
   

kirya

втянувшийся

Посоветуйте как сделать. Мне нужно принять определенное число байтов допустим 1000Б. Они принимаются в течении 30сек ±. Как определить что все байты пришли? Пока в голове только одно, кинуть на форму таймер и каждую секунду опрашивать изменение счетчика байт (counter). Но мне кажется это не правильно и нужно искать какой-то другой способ.
   

kirya

втянувшийся

kirya> Посоветуйте как сделать.

Разобрался. Есть функция которая может приостановить поток на определенной мной время WaitForSingleObject(overlapped.hEvent, 1000);
Эта функция как раз используется в потоке. Поэтому как только в течении 1000 мсек я байтов не получаю и счетчик counter>0 значит я все байты уже принял и можно вызывать функцию сохроанения в файл и постройки графика.
Такой подход наверно более правильный.
   

Mishka

модератор
★★★
kirya> {WriteFile(COMport, bufwr, strlen(bufwr), &temp, &overlappedwr); //записать байты в порт (перекрываемая операция!)

strlen считает байты до первого нуля. В С (в С++ при использовании С ф-ций) 0 признак окончания строки. Поэтому длину буфера надо задавать ручками — ровно столько байт, сколько есть.
   6.06.0

Mishka

модератор
★★★
kirya> В итоге объявляю глобальную переменную, в которой будет содержаться кол-во байт для передачи. Правильно ли я делаю с точки зрения высокоуровнего программирования? Просто читал где-то что гобаль.переменные не есть гуд и нужно обходится без них. Как правильней с делать в моей конкретной ситуации?

Я бы сделал класс с буфером и текущей длиной и операциями-манипуляциями над буфером. Тогда можно иметь много независимых буферов, создавать/уничтожать легче. Можно вводить максимальный размер буфера и создавать очереди из буферов.
   6.06.0

Mishka

модератор
★★★
kirya> Посоветуйте как сделать. Мне нужно принять определенное число байтов допустим 1000Б. Они принимаются в течении 30сек ±. Как определить что все байты пришли? Пока в голове только одно, кинуть на форму таймер и каждую секунду опрашивать изменение счетчика байт (counter). Но мне кажется это не правильно и нужно искать какой-то другой способ.


WaitForSingleObject(overlappedwr.hEvent, INFINITE) — поставь не бесконечное ожидание, а 30 секунд. После того, как получил управление назад, проверь, получил ли по ивенту, если по нему, то можно и число байтов пришедших проверить, и время.
   6.06.0

TEvg

аксакал

админ. бан
kirya> unsigned char bufwr[BUFSIZE];
kirya> bufwr[0]=0x2;
kirya> bufwr[1]=0x0;/////!!!!!!!!!
kirya> bufwr[2]=0x10;
kirya> bufwr[3]=0x2;
kirya> bufwr[4]=0x2;
kirya> Form1->Edit6->Text = strlen(bufwr);
kirya> Если так то длина буфера 1.

Ну дык! Строки в Це заканчиваются нулем. Вот strlen доходит до нуля и на этом закругляется.

>Что это!? Я объявил переменную типа HANDLE?

Ага.

>Что особенного в этой новой переменной, чем она например отличается от int или float?

Это дескриптор. Такая технология - устройству, с которым работаешь, присваивается некое число (дескриптор), которое надо передавать всем функциям работающим с этим устройством, дабы они по ошибке не забрели на другое устройство. Физически это как правило двухбайтное целое беззнаковое число. Да, да, да - вы можете использовать любой целый двухбайтовый беззнаковый тип - и вас таки не пошлют. Можете присваивать такой переменной ваш дескриптор и возвращать всё взад - проблем не будет. В Паскале например таким типом является word.

kirya> В итоге объявляю глобальную переменную, в которой будет содержаться кол-во байт для передачи. Правильно ли я делаю с точки зрения высокоуровнего программирования?

Правильно.

>Просто читал где-то что гобаль.переменные не есть гуд и нужно обходится без них.

А ещё пугают страшным словом goto. На самом деле нет ничего неправильного. Нужно писать так чтобы был понятен свой собственный код.

>Как правильней с делать в моей конкретной ситуации?

Да глобальная переменная, а ещё лучше константа - самое простое и не нужно заходить в дебри.

ЗЫ А чем рисуете графики?
   3.6.133.6.13

TEvg

аксакал

админ. бан
Я вот всю жизнь пользовался для портов Async Pro (кстати рекомендую в рамках задачи)
А теперь портируюсь на люникс и надо писать код сначала..
   3.6.133.6.13

kirya

втянувшийся

Mishka> Я бы сделал классв.

Спасибо. Я попробую хотя бы ради интереса и чтобы отложилось у меня. Пока что не создавал своих классов. Теперь уже немного доходит о чем речь идет. Действительно кажется что применение классов менее запутано- вот тебе класс, а в нем буфер и его длиной...
   

kirya

втянувшийся

Mishka> WaitForSingleObject(overlappedwr.hEvent, INFINITE) — поставь не бесконечное ожидание, а 30 секунд.

Я так и сделал, только не 30 сек нужно ставить, а то получится что после приема последнего байта нужно ждать 30сек чтобы проверить... Я поставил 1000мсек.
   

kirya

втянувшийся

TEvg> ЗЫ А чем рисуете графики?

:-) Да, вопрос не для меня. Я все делаю в лоб. Рисую например так:

Image->Canvas->Pen->Width = 1;
Image->Canvas->MoveTo(os4-h_shtrih/2,os2-step_y*i);
Image->Canvas->LineTo(os4+h_shtrih/2,os2-step_y*i);

Искал как лучше рисовать, в итоге только так научился. Тоже нужно будет как-то систематизировать кучу переменных которую я использую для построения графика.
В итоге у меня получились функции которые везде можно использовать, они сами определяют размер холста и рисуют графики. Хочется отображать сразу больше одного графика, но пока над этим не думал.
   
1 2 3

в начало страницы | новое
 
Поиск
Настройки
Твиттер сайта
Статистика
Рейтинг@Mail.ru