1

Тема: І знову Com

Доброго вечора, проблема із читанням з com порта, справа у тому, що коли і як би я не починав читати , читається з моменту запуску пристрою(наразі з ардуїнки), дуже багато перечитав, про роботу ком порта , та все одно не можу збагнути-якщо якісь дані зчитані, вони повинні знищуватись із буферу? то чому кожного разу я отримую все з початку?
Не допомагає і примусове очищення буферу

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{   char *buff=new char[50];
if (ComPort.m_bOpened)
{


 if(ComPort.ReadData(buff,50))
 {PurgeComm (ComPort.m_hIDComDev,PURGE_TXCLEAR);
 PurgeComm (ComPort.m_hIDComDev,PURGE_RXCLEAR);
 Memo1->Lines->Insert(0,AnsiString(buff));
 Memo1->GoToTextEnd();
 }

}
delete buff;
}

, та і де такий буфер на 100 мб, якщо ардуінка вже працює 5 годин?

2 Востаннє редагувалося lucas-kane (19.02.2023 22:31:51)

Re: І знову Com

ijonhson написав:
void __fastcall TForm1::Timer1Timer(TObject * Sender) {
  char * buff = new char[50];
  if (ComPort.m_bOpened) {  // <-- ?
    if (ComPort.ReadData(buff, 50)) {
      PurgeComm(ComPort.m_hIDComDev, PURGE_TXCLEAR);
      PurgeComm(ComPort.m_hIDComDev, PURGE_RXCLEAR);
      Memo1 -> Lines -> Insert(0, AnsiString(buff));
      Memo1 -> GoToTextEnd();
    }
  }
  delete buff;
}

if (ComPort.m_bOpened) - Можливо тому, що ви звертаєтесь до m_bOpened напряму, а не через метод. Не знаю, що за бібліотека, але перевірте чи там є якийсь код який перевіряє режими роботи КОМ-порту. Можливо є якісь біти, котрі задаються при ініціалізації об'єкту.

Прихований текст

І форматуйте код. Потім і вам буде легше працювати з ним...

Ще хотілося б побачити принципову схему підключення, цього вашого проекту (можна намальовану від руки на листочку). Так людям буде легше розуміти про, що мова. А то все якесь настільки абстрактне, що потрібно самому додумувати, як то воно у вас, там все має працювати.

Так, ще є запитання про кабель підключення, якщо пристрій до КОМ-порту у вас підключається фізично? Це нуль-модемний кабель, якийсь перехідник на USB... ? З нову ж таки, дуже багато потрібно додумувати самому.

Подякували: ijonhson1

3 Востаннє редагувалося lucas-kane (19.02.2023 22:41:17)

Re: І знову Com

ijonhson написав:

та і де такий буфер на 100 мб, якщо ардуінка вже працює 5 годин?

Ви про що? Який на вашу думку має бути буфер? Більшим? Це ви про цей буфер char * buff = new char[50];?

Якщо ж таки про цей буфер, то він і не повинен бути більшим. Інша справа, що його може бути недостатньо для вхідних даних.
Він існує для тимчасового зберігання, а в подальшому переносу з нього даних у файл чи БД, або як у вашому випадку Memo1, щоб потім можна було обробити ці дані. І якщо таки "важити" об'єм вхідних даних, то Memo1 чи файл куди ви будете записувати.

Подякували: ijonhson1

4

Re: І знову Com

Я про буфер ком порта

5

Re: І знову Com

А той Memo1 десь хтось очищує?
Бо у наведеному коді лише Insert-и взятого з COM. Тобто накопичується в Memo1, а не в буфері ком-порта.

Подякували: ijonhson1

6

Re: І знову Com

До речі, чого Insert(0, xxx) а не Add(xxx)?

Можна завести десь лічильник рядків, вже доданих до Memo1, і якщо він перевищує ліміт, то робити Delete(0) і Add(xxx)

p.s[0] = "А взагалі яка це бібліотека/система програмування?"
p.s[1] = "Ні, я не ChatGPT"

Подякували: ijonhson1

7

Re: І знову Com

Вибачте, я правильно зрозумів, що ви
1) запускаєте ардуїно, під'єднаний до com-порта
2) за певний час запускаєте цю програму, що читає з com-порта
3) програма відображає сигнали з ардуїно, відіслані до запуску програми?
Усе правильно? Чи, наприклад, програма запускається раніше, а ви натискаєте кнопку пізніше?

Подякували: ijonhson1

8 Востаннє редагувалося lucas-kane (21.02.2023 00:12:19)

Re: І знову Com

ijonhson написав:

Я про буфер ком порта

Чудово. І звідки на вашу думку я міг про це знати? І напевне воно зветься не буфер, а скоріш за все log, report. Коли говорите БУФЕР, то це має інше значення.

Перше, не множте однакових тем. Перенесу сюди вашу частину коду:

".h"
#include <windows.h>

#ifndef __SERIAL_H__
#define __SERIAL_H__

#define FC_DTRDSR 0x01
#define FC_RTSCTS 0x02
#define FC_XONXOFF 0x04
#define ASCII_BEL 0x07
#define ASCII_BS 0x08
#define ASCII_LF 0x0A
#define ASCII_CR 0x0D
#define ASCII_XON 0x11
#define ASCII_XOFF 0x13

class CSerial
{
public:
  CSerial();
  ~CSerial();

  bool Open(wchar_t *szPort, int nBaud = 9600, int nDataBids = 8, float nStopBits = 2);
  bool Close(void);

  int ReadData(void *, int);
  int SendData(const char *, int);
  int ReadDataWaiting(void);

  bool IsOpened(void)
  {
    return (m_bOpened);
  }
  void GetComList(TStringList list);

  struct ComPort
  {
    ComPort(LPSTR name, LPSTR key);
    ~ComPort();
    LPSTR name;
    LPSTR key;
  };

protected:
  bool WriteCommByte(unsigned char);

  HANDLE m_hIDComDev;
  OVERLAPPED m_OverlappedRead, m_OverlappedWrite;
  bool m_bOpened;
};

#endif
".hpp"
CSerial::CSerial()
{
  memset(&m_OverlappedRead, 0, sizeof(OVERLAPPED));
  memset(&m_OverlappedWrite, 0, sizeof(OVERLAPPED));
  m_hIDComDev = NULL;
  m_bOpened = false;
}

CSerial::~CSerial()
{
  Close();
}

bool CSerial::Open(wchar_t *szPort, int nBaud, int nDataBids, float nStopBits)
{
  if (m_bOpened)
    return (TRUE);

  char szComParams[50];
  DCB dcb;

  m_hIDComDev = CreateFile(szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
  if (m_hIDComDev == NULL)
    return (FALSE);

  memset(&m_OverlappedRead, 0, sizeof(OVERLAPPED));
  memset(&m_OverlappedWrite, 0, sizeof(OVERLAPPED));

  COMMTIMEOUTS CommTimeOuts;
  CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
  CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
  CommTimeOuts.ReadTotalTimeoutConstant = 0;
  CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
  CommTimeOuts.WriteTotalTimeoutConstant = 5000;
  SetCommTimeouts(m_hIDComDev, &CommTimeOuts);

  m_OverlappedRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  m_OverlappedWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

  dcb.DCBlength = sizeof(DCB);
  GetCommState(m_hIDComDev, &dcb);
  dcb.BaudRate = nBaud;
  dcb.ByteSize = nDataBids;
  dcb.StopBits = nStopBits;

  unsigned char ucSet;
  ucSet = (unsigned char)((FC_RTSCTS & FC_DTRDSR) != 0);
  ucSet = (unsigned char)((FC_RTSCTS & FC_RTSCTS) != 0);
  ucSet = (unsigned char)((FC_RTSCTS & FC_XONXOFF) != 0);
  if (!SetCommState(m_hIDComDev, &dcb) ||
      !SetupComm(m_hIDComDev, 10000, 10000) ||
      m_OverlappedRead.hEvent == NULL ||
      m_OverlappedWrite.hEvent == NULL)
  {
    DWORD dwError = GetLastError();
    if (m_OverlappedRead.hEvent != NULL)
      CloseHandle(m_OverlappedRead.hEvent);
    if (m_OverlappedWrite.hEvent != NULL)
      CloseHandle(m_OverlappedWrite.hEvent);
    CloseHandle(m_hIDComDev);
    return (FALSE);
  }

  m_bOpened = TRUE;

  return (m_bOpened);
}
ijonhson написав:

та робота з ком портом , це подія. ComPort- обєкт CSerial , StopBitsCBox -комбобокс, LStatus- лейбл

І у мене виникає питання. Як ви ініціалізуєте цей об'єкт? Тобто, де в коді ви пишете ComPort.Open( ... );

Має бути, щось типу:

CSerial ComPort;
ComPort.Open( ... );
if (!ComPort.IsOpened())
  exit;

Якщо ви так зробили, тоді у мене наступне питання про підключення кабелем. Який у вас тип підключення, тобто що за кабель? Бо від розпіновки кабелю залежить режим передавання даних.

Третє питання полягає в коректності даних. Тобто, чи збігаються ваші вхідні дані на ПК і вихідними даними Ардуіно чи там сміття яке не має відношення до потрібного вам результату. Бо дивлячись на те як ви відкрили КОМ-порт, я сумніваюсь в істинності цих даних.

Подякували: ijonhson1

9

Re: І знову Com

І скажу напевно вже втретє чи четверте. Ці ваші бібліотеки - це оболонки над WinAPI, посилання на які я давав.

"Російська мова"
Подякували: ijonhson1

10

Re: І знову Com

lucas-kane написав:
ijonhson написав:

Я про буфер ком порта

Чудово. І звідки на вашу думку я міг про це знати? І напевне воно зветься не буфер, а скоріш за все log, report. Коли говорите БУФЕР, то це має інше значення.

Мені здається, що він правильно каже «буфер», і має на увазі буфер драйвера ком-порта.
З якого він читає за допомогою .ReadData і в якому він думає залишається все від сотворення світу, незважаючи на його виклики PurgeComm з параметром PURGE_RXCLEAR

Подякували: ijonhson1

11 Востаннє редагувалося Droid 77 (20.02.2023 22:10:31)

Re: І знову Com

Піпли, ви що тут понапоносили?
Першочергово:
що плює в порт контролер?,
які мітки в плюванні початку та кінці транслювання даних?
в якому форматі то всьо блюється?
... ююю ... ? ББА 198

Так?
Чи якісь іні мітки?
Мікроконтролери це не просто бездумно фігачити машинний код, то тре дофіга подумати що саме той контролер повинен робити та за якими командами.

Подякували: ijonhson1

12

Re: І знову Com

lucas-kane написав:

Можливо тому, що ви звертаєтесь до m_bOpened напряму, а не через метод. Не знаю, що за бібліотека, але перевірте чи там є якийсь код який перевіряє режими роботи КОМ-порту. Можливо є якісь біти, котрі задаються при ініціалізації об'єкту.

Ні , перевірки там нема, але відкриває начебто.
Вибачте, дещо виявилось методом втика, справа в тому, що я в коді для ардуінки прописав на вихід дані з датчиків, через кому, але першим аргументом був таймінг, тобто кожні дві секунди ардуїнка видає в ком таку

2,1.36,4.51,-0.06,0.02,5.83

строку
де перший аргумент це час .
В коді це виглядає так

delay(2000);
time=time+2;// arduino ide це спрощений с++

і кожного разу , коли я зупиняв звязок(закривав ком і відкривав) відлік починався з нуля, хоча до цього я використовував інші бібліотеки і такого не було, через це я зробив неправильний висновок

13 Востаннє редагувалося ijonhson (20.02.2023 22:47:03)

Re: І знову Com

koala написав:

Вибачте, я правильно зрозумів, що ви
1) запускаєте ардуїно, під'єднаний до com-порта
2) за певний час запускаєте цю програму, що читає з com-порта
3) програма відображає сигнали з ардуїно, відіслані до запуску програми?
Усе правильно? Чи, наприклад, програма запускається раніше, а ви натискаєте кнопку пізніше?

Все вірно але... я тупанув трохи

14

Re: І знову Com

Тут вже інше питання, можливо для іншої гілки , чому ардуїнка обнуляється?

15

Re: І знову Com

Про всяк випадок , я прочитав два підручника.... із с++ не бийте боляче

16

Re: І знову Com

Droid 77 написав:

Піпли, ви що тут понапоносили?
Першочергово:
що плює в порт контролер?,
які мітки в плюванні початку та кінці транслювання даних?
в якому форматі то всьо блюється?
... ююю ... ? ББА 198

Так?
Чи якісь іні мітки?
Мікроконтролери це не просто бездумно фігачити машинний код, то тре дофіга подумати що саме той контролер повинен робити та за якими командами.

ТОВЧЕМО ВОДУ В СТУПІ.

Тут не такий рівень абстракції блювання та плювання. Чомусь, автор не дає всієї повноти своєї думки і усе потрібно додумувати самому - "вангувати". До кінця не розібрались із самою схемою підключення контролера до порту, та як ті дані по ньому "бігають". Не відомо, чи підключення є фізичним (підключений пристрій на пряму до інтерфейсу), чи імітовано програмно. Може ви поясните і нам буде цікаво?

А на рахунок "поносу", того що ми понаписували полягає у наступному. Автор завантажив з мережі бібліотеку, назвемо її ну нехай "ЯКАСЬ_ФІГНЯ". У цій бібліотеці є визначення типу CSerial, котрий описує, який вигляд буде мати кінцевий об'єкт - comPort. Однією із закритих властивостей цього типу - є m_bOpened та метод IsOpened(), який є публічним. І от в попередній темі у автора не вийшло звернутись до цього публічного методу. Не спрацьовує чомусь. І щоб розібратись, чому воно не спрацьовує, автор робить закриту властивість m_bOpened відкритою. І от "ВУАЛЯ", Працює. і здається мені, буде воно зчитувати дані, але які?
Далі виникає наступне питання. Чи ці дані є істинними, тобто чи те що відправляє контролер із зчитаних датчиків збігається з даними що прийшли до ПК. Як вам такий перебіг подій?

P.S. Я бачу, що продовження цього "екшена" буде, бо

ijonhson написав:

Тут вже інше питання, можливо для іншої гілки , чому ардуїнка обнуляється?

як вам таке?

ijonhson написав:

Про всяк випадок , я прочитав два підручника.... із с++ не бийте боляче

Будь ласка, прочитайте ще раз!

Подякували: leofun011

17

Re: І знову Com

ijonhson написав:

Тут вже інше питання, можливо для іншої гілки , чому ардуїнка обнуляється?

Тому що ця бібліотека смикає ніжку COM-порта (RTS чи DTR — забув), яка ресетить процесор ардуінки. Там по дорозі послідовно конденсатор, тому будь-який стабільний рівень норм, головне не смикати з високого у низький рівень. Використовує IDE щоб законектитися з програматором.
Якщо цій бібліотеці можна пояснити, що не треба використовувати ті ноги (відбити hardware flow control), то це має припинитися.

Подякували: wander, leofun012