Перейти к содержанию
    

Общение МК с программой через COM в С++Builder

3 minutes ago, AlexDX740 said:

Ёмое, как же я это. Видать по запарке как в обработчике нажатия кнопки написал. Спасибо огромное. Почему же интересно на компе ошибки не было? 

Это уже второй вопрос.

Я только на один отвечаю.

Для получения второго ответа - угадайте под каким из трёх стаканчиков находится шарик ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, jcxz said:

Да ладно! Отсылалось-принималось с даже неинициализированным указателем TComPort *ComPort1 ? Не надо врать.

TComPort *ComPort1 инициализируется объектом application до того как форма открывается. Тут все чисто. 
Просто здесь приведена не вся программа. 

 

32 minutes ago, x893 said:


 

Как думаете, последний Close() что вызовет ?

Правильно - FormClose()

Вот и StackOverflow

FormClose ничего не закрывает, а  вызывает событие где надо подтвердить или отменить закрытие. 
Что точно будет с формой опредяеляется в свойствах формы.  

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

48 минут назад, AlexandrY сказал:

TComPort *ComPort1 инициализируется объектом application до того как форма открывается. Тут все чисто. 
Просто здесь приведена не вся программа.

Там и кроме этого куча ляпов. Начиная от:

KodTx[3]= 0x0D;//символ конца передачи

или:

float RA=sqrt((kx-cx) * (kx-cx)+(ky-cy) * (ky-cx));//находим радиус окружности точки клика

которое названо почему-то "радиусом", да и просто может вызвать exception при отрицательном аргументе в скобках.

По приходу символа из порта почему-то ожидается, что обязательно пришла строка с числом. И то что пришло из порта совсем не проверяется на валидность - автору пофиг на то, что StrToInt() может всю память перепахать на мусорных символах.

Событие OnRxChar хоть из контекста того же потока вызывается, в котором открыта TForm1? Чувствую что автор сего даже не задумывался об этом.

Множественное неоправданное использование глобальных переменных, неучёт влияния ошибок округления в ClickDegreeTX(), пути к файлам прописанные прям в коде и многое др.

Да и обращение к членам класса внутри его конструктора TForm::TForm() тоже мне кажется сомнительным, а проинициализированы ли они уже чтобы к ним можно было обращаться? Хоть утверждать не буду - давно не пользовался билдером, но по уму для такого используют TForm::FormCreate().

 

И это всё наделано в 3-х простейших функциях... мрак полный... багов больше чем "кода"  :unknw:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 3/8/2020 at 8:40 PM, jcxz said:

KodTx[3]= 0x0D;//символ конца передачи

По приходу этого символа МК выходит из прерывания и обрабатывает полученное число.

On 3/8/2020 at 8:40 PM, jcxz said:

float RA=sqrt((kx-cx) * (kx-cx)+(ky-cy) * (ky-cx));//

Это радиус окружности на которой находится точка клика.

 

On 3/8/2020 at 8:40 PM, jcxz said:

По приходу символа из порта почему-то ожидается, что обязательно пришла строка с числом. И то что пришло из порта совсем не проверяется на валидность - автору пофиг на то, что StrToInt() может всю память перепахать на мусорных символах.

Событие OnRxChar хоть из контекста того же потока вызывается, в котором открыта TForm1? Чувствую что автор сего даже не задумывался об этом.

Мне не пофигу, проверка на валидность будет. Это не окончательный код. По этой же причине почти все переменные глобальные, мне пока так удобнее, потом не нужные будут перемещены в свои функции. Ошибки округления игнорируются осознано, мне не нужна высокая точность, +- 5 градусов для меня не столь важно. Что касается пути к файлу в коде, то я пока по другому не могу, я ведь только учусь и знаком с С++ билдером всего с осени. Так что сильно не ругайтесь, а подскажите что не так и по возможности как это исправить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 

13 минут назад, AlexDX740 сказал:
В 08.03.2020 в 22:40, jcxz сказал:

KodTx[3]= 0x0D;//символ конца передачи 

По приходу этого символа МК выходит из прерывания и обрабатывает полученное число.

У вас массив KodTx объявлен как

 char KodTx[3];//буфер передачи

, поэтому запись в KodTx[3] производится за пределы массива.

А здесь:

RA=sqrt((kx-cx) * (kx-cx)+(ky-cy) * (ky-cx));//

тоже ошибка - последний множитель должен быть ky-cy.

Коллега @jcxz показал вам ошибки в коде, правда, как всегда, сделал это в, скажем так, довольно эксцентричной манере.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо. Опять забыл что запись идёт с 0, а объявление нормально. С радиусом я заметил ошибку. А подскажите, как файл картинки встроить в программу, а не подгружать отдельно? Несколько книг просмотрел, везде такой способ используют.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я уж не помню, как там в дельфи всё это делалось. Наверняка какой-нибудь TImage на форму бросить, и в его свойствах задать картинку.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я работаю в С++билдер, но примерно так же. Кидаю на форму Image, в его свойство Picture открываю файл. Поэтому файл должен находиться по этому пути, а как этого избежать я не знаю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, AlexDX740 сказал:

Мне не пофигу, проверка на валидность будет.

Дело не только в проверке валидности. COM-порт - это байтовый поток, он может возвращать байты как угодно, хоть сразу всю строку, хоть по-байтно, или ещё как угодно. А у Вас ожидается, что всегда будет возвращаться вся строка целиком. Сам алгоритм неправильный. Не говоря уже о проверке валидности.

Цитата

Ошибки округления игнорируются осознано, мне не нужна высокая точность, +- 5 градусов для меня не столь важно.

Опять не поняли. Я говорил не о точности. А о том, что при таком построении алгоритма как у вас, иногда в случайные моменты времени могут происходить сбои в программе. Потому что не учитываете ошибки округления. Например в:

     float RA=sqrt((kx-cx) * (kx-cx)+(ky-cy) * (ky-cx));//находим радиус окружности точки клика
     double ca=(kx-cx) / RA;//находим значение косинуса угла в радиантах

при определённых значениях kx,cx,ky,cy значение ca может получаться >1. Чуть-чуть, но больше. И последующий вызов acos(ca) тогда будет завершаться с ошибкой (или exception-ом).

Почему так будет - подумайте сами.

 

Цитата

Что касается пути к файлу в коде, то я пока по другому не могу, я ведь только учусь и знаком с С++ билдером всего с осени.

"С осени" прошло уже полгода. За это время можно было много раз успеть набрать в гугле "включение ресурсов в проект на Builder".

Кроме того у вас в проекте в com_1.dfm уже включён такой ресурс (картинка) - как-то же добавили?

 

PS: Builder уже много лет не пользуюсь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, AlexDX740 said:

Спасибо. Опять забыл что запись идёт с 0, а объявление нормально. С радиусом я заметил ошибку. А подскажите, как файл картинки встроить в программу, а не подгружать отдельно? Несколько книг просмотрел, везде такой способ используют.

Про компоненты в книгах не прочитаете. Про них надо читать в хэлпах самих компонентов. 
Очень хороший компонент для рисунков из набора от DevExpress VCL, называется TcxImage.
Умеет делать прозрачнось, анимацию, виджеты зуминга и редактирования в рантайме,  поддерживает стайлинг приложения, и еще куча фичей недоступных в штатном TImage.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Всем привет. Опять понадобился толчок в нужном направлении. Суть проблемы в следующем. Имеем программу с небольшим выбором настроек. Стало интересно использовать для сохранения настроек файл ini. Вроде проблем не должно было возникнуть,но... 

void __fastcall TForm1::Button2Click(TObject *Sender)
{
   Ini->WriteString("ComPort","ComPort1",ComPort1->Port);
   Ini->WriteString("Image","Image1",OpenPictureDialog1->FileName);
   ComPort1->Close();
   Close();
}

Запись проходит на ура, а вот чтение...

__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
   ComPort1->Port =Ini->ReadString("ComPort","ComPort1","COM4 ");
   Image1->Picture->Bitmap->LoadFromFile(Ini->ReadString("Image","Image1","OpenPictureDialog1->FileName "));
   Form1->Label2->Caption="Выберите карту";
   Form1->Label1->Caption="Выберите порт";
}

Запись используемого порта не происходит, хотя свойству Port компонента ComPort1 присваивается хранимое в ini значение.

[ComPort]
ComPort1=COM3
[Image]
Image1=F:\Povorot_antenny\PC\AzimuthalMap.bmp

Загрузка изображения первый раз выдает ошибку, но это понятно. Файл ini еще не создан и грузиться не с чего. Хотя не понятно как сделать селекцию, первый это запуск или нет. Но это пол беды. При перезапуске программы путь к изображению в ini файле пропадает, так как не использовался загрузчик изображений и OpenPictureDialog1->FileName не содержат инфо. Как со всем этим бороться? Файл с проектом во вложении.v1.0.rar

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

20 минут назад, AlexDX740 сказал:

Запись используемого порта не происходит, хотя свойству Port компонента ComPort1 присваивается хранимое в ini значение. 

Вероятно, порт к этому времени уже открыт? Попробуйте закрыть и открыть заново.

26 минут назад, AlexDX740 сказал:

Загрузка изображения первый раз выдает ошибку, но это понятно. Файл ini еще не создан и грузиться не с чего. Хотя не понятно как сделать селекцию, первый это запуск или нет. Но это пол беды. При перезапуске программы путь к изображению в ini файле пропадает, так как не использовался загрузчик изображений и OpenPictureDialog1->FileName не содержат инфо. Как со всем этим бороться?

Заведите переменную для имени файла:

class TForm1 : public TForm
{
...
private:
  String fileName;

При чтении из ini читайте в эту переменную:

  fileName = Ini->ReadString("Image","Image1","");
  if (fileName == "")
  {
      // здесь можно вызвать диалог выбора картинки
      fileName = ...
    
  }
  Image1->Picture->Bitmap->LoadFromFile(fileName);

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 hours ago, AHTOXA said:

Вероятно, порт к этому времени уже открыт? Попробуйте закрыть и открыть заново.

Нет, порт не открыт и не выбран. Я пробовал писать-читать значение порта в переменную, все то же самое.Screenshot-06_05.2020_8_17.32184.thumb.jpg.0aaf61a77dae4ed6f796a72fdbe877ce.jpg

Значение присваивается свойству порт, но не меняет сам порт. Я так подозреваю,что дело в самом компоненте ComPort.

По поводу изображения. Его путь пишется и читается, но... Когда открываю приложение второй раз путь считывается с ini файла, картинка грузится автоматом и соответственно файл с помощью 

OpenPictureDialog1->Execute();//открываем окно выбора файла
Image1->Picture->Bitmap->LoadFromFile( OpenPictureDialog1->FileName );

не открывался и OpenPictureDialog1->FileName не содержит инфо, поэтому при закрытии приложения эта строка 

Ini->WriteString("Image","Image1",OpenPictureDialog1->FileName);

в ini файл ничего не пишет. Вопрос. Как еще можно получить путь и имя файла, помещенного в контейнер Picture компонента Image?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, AlexDX740 said:

в ini файл ничего не пишет. Вопрос. Как еще можно получить путь и имя файла, помещенного в контейнер Picture компонента Image?

Насколько помню, для новичков особенно трудно разобраться в последовательности или очередности событий в движке VCL.
Поэтому они не знают в каком обработчике какие действия можно делать. 
Для того чтобы не запариваться с исследованием причинности в VCL придуманы компоненты автоматического сохранения-восстановления свойств компонентов.
Один из лучших -  TcxPropertiesStore из пакета DevExpress,  есть тоже неплохой и  более доступный в пакете RxLib

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...