Работа с СОМ-портом на ПК

Тема в разделе "Схемотехника, компоненты, модули", создана пользователем Mihay, 21 сен 2016.

  1. Mihay

    Mihay Гик

    Здравствуйте!
    У меня давно висит проблема с приемом данных с Ардуино на ПК с помощью СОМ-порта.
    Вот код на скетче Ардуино
    Код (C++):
       
         val0 = analogRead(SENSOR_PIN0); // Получаю данные с аналогового канала
          Send = N|0x4000; //     Кодирую номер канала                  
          Serial.println(Send); //   отправляю номер канала
          Serial.println(val0); //  отправляю уровень сигнала в этом канале
     
    В предыдущем коде я для наглядности убрал проверку на изменение уровня сигнала и ардуино не молотит в порт постоянно данные, а только в момент изменения значения val0.

    На ПК создал поток который принимает данные из COM-порта:

    Код (C++):

    char c;
    char prev_c = '\n';
    int gResult;
    HANDLE hCom;
    DWORD bytesWritten;
    int Work = 0;
    HANDLE hThread = NULL;
    int Sensor[100];

    int __fastcall ThreadProc(void *pData)
    {
       int Num_Datch;
       while(Work == 1)
       {
              bytesWritten = 0;
              Sleep(1);
              if (Work == 1)
              gResult = ReadFile(hCom, &c, 1, &bytesWritten, NULL);
              if (gResult != 0)
              {
                 if ((prev_c == '\n')&&(c != '\r')&&(c != '\n'))
                 {
                    unsigned int num = 0;
                    while (c != '\r')
                    {
                       num = num * 10 + (c - '0');
                       ReadFile(hCom, &c, 1, &bytesWritten, NULL);
                    }

                    int Flag = num&0x4000;
                    if (Flag == 0x4000)
                    {
                        Num_Datch = num&0x3fff;  // Номер канала
                    }
                    else
                    {
                      Sensor[Num_Datch] = num;  // Значение канала
                     }
                  }  //   if ((prev_c == '\n')&&(c != '\r')&&(c != '\n'))
               }  // if (gResult != 0)
               prev_c = c;
       }
       if (Work == 0)
       {
          int s = 2;
          gResult = WriteFile(hCom, &s, sizeof(s), &bytesWritten, NULL);
          CloseHandle(hCom);
          WaitForSingleObject(hThread, INFINITE);   hThread = NULL;
       }
       return 0;
    }
     
    Здесь все работает за исключением одного. Когда с Ардуино данных нет, поток зависает на цикле
    while (c != '\r')
    {
    }
    И я не могу ничего отправить в порт с ПК на Адруино функцией
    WriteFile(hCom, &s, sizeof(s), &bytesWritten, NULL),
    до тех пор пока не придут какие нибудь данные с Ардуино.
    Есть ли другое решение (другой код) приема данных с Ардуино на ПК через СОМ-порт? Подскажите как переписать данный код? Буду благодарен за советы.

    PS: Проблема решается если в порт из Ардуино постоянно что-то писать (левые данные, не относящиеся к задаче). Но это не выход. Зачем Ардуино постоянно молотить в порт что-то левое?
     
    Последнее редактирование: 21 сен 2016
  2. Onkel

    Onkel Гуру

    если у вас нет аналога прерывания по поступлению данных, просто проверяйте (c != '\r') через раз, за время выполнения петли программы ведь не проскочит принятый байт, буфер небось на килобайты?
    что -то вроде
    Код (C++):
     while (c != '\r'    &&   _t)
                    {
                       num = num * 10 + (c - '0');
                       ReadFile(hCom, &c, 1, &bytesWritten, NULL);
                    }
    if(_t)
    _t=0;
    else
    _t=1;
     
  3. Mihay

    Mihay Гик

    можно ли здесь поподробней?
     
  4. Onkel

    Onkel Гуру

    программа на чем? Я на С для винды давно последний раз писал, смутно помню нужен обработчик событий типа вот тут описанного http://microsin.net/programming/pc/visual-studio-sharp-dot-net-com-port.html
    И что делать надо? Я , например, пишу в файл либо терминалом, либо гуем на питоне, но это только когда нужна графика. Но для себя просто терминалом - запускаю терминал, и он все потом в файл пишет, может писать и с метками.
     
  5. Mihay

    Mihay Гик

    Как раз проскакивают нужные байты - результат вообще не предсказуемый и не поддается никакой логике. Что послала Ардуино - ПК принимает через байт - результат плачевный
     
  6. Onkel

    Onkel Гуру

    а терминал что видит? Все в порядке?
     
  7. Mihay

    Mihay Гик

    В терминале данные в порядке.