Работа с COM-портом в С++.

Работа с COM-портом в С++.

Сообщение Waik » 27 июн 2014, 18:14

Здравствуйте, уважаемые форумчане.

Введение/
К Arduino Uno подключен RFID модуль RС522. Arduino читает данные с карты и по COM порту передает их, с помощью программы на С++ нужно читать данные.
Использовал http://robocraft.ru/blog/arduino/76.html для изучения работы с COM портами.

Проблема/
Проект компилируется без ошибок, но сама программа выдает такое-вот сообщение:
ERROR: Handle was not attached. Reason: COM3 not available.

Если мониторить порт с помощью Arduino IDE то все ок, видно как данные идут.
Номер порта указываю верно, потому-что:
1.В диспетчере задач он инициализируется как Arduino Uno(Com3)
2. В Arduino IDE слушаю COM3 и все ок.

Что имеем/
ОС:Windows 7
Среда разработки:VS C++ 2010
Плата: китайский клон Arduino UNO

Коды/

Код Arduino:
Код: Выделить всё
/**
* Read a card using a mfrc522 reader on your SPI interface
* Pin layout should be as follows (on Arduino Uno):
* MOSI: Pin 11 / ICSP-4
* MISO: Pin 12 / ICSP-1
* SCK: Pin 13 / ISCP-3
* SS: Pin 10
* RST: Pin 9
*
* Script is based on the script of Miguel Balboa.
* New cardnumber is printed when card has changed. Only a dot is printed
* if card is the same.
*
* @version 0.1
* @author Henri de Jong
* @since 06-01-2013
*/

#include <SPI.h>
#include <RFID.h>

#define SS_PIN 10
#define RST_PIN 9

RFID rfid(SS_PIN, RST_PIN);

// Setup variables:
    int serNum0;
    int serNum1;
    int serNum2;
    int serNum3;
    int serNum4;

void setup()
{
  Serial.begin(9600);
  SPI.begin();
  rfid.init();
 
}

void loop()
{
   
    if (rfid.isCard()) {
        if (rfid.readCardSerial()) {
            if (rfid.serNum[0] != serNum0
                && rfid.serNum[1] != serNum1
                && rfid.serNum[2] != serNum2
                && rfid.serNum[3] != serNum3
                && rfid.serNum[4] != serNum4
            ) {
                /* With a new cardnumber, show it. */
                Serial.println(" ");
                Serial.println("Card found");
                serNum0 = rfid.serNum[0];
                serNum1 = rfid.serNum[1];
                serNum2 = rfid.serNum[2];
                serNum3 = rfid.serNum[3];
                serNum4 = rfid.serNum[4];
               
                //Serial.println(" ");
                Serial.println("Cardnumber:");
                Serial.print("Dec: ");
      Serial.print(rfid.serNum[0],DEC);
                Serial.print(", ");
      Serial.print(rfid.serNum[1],DEC);
                Serial.print(", ");
      Serial.print(rfid.serNum[2],DEC);
                Serial.print(", ");
      Serial.print(rfid.serNum[3],DEC);
                Serial.print(", ");
      Serial.print(rfid.serNum[4],DEC);
                Serial.println(" ");
             } else {
               /* If we have the same ID, just write a dot. */
               Serial.print(".");
             }
          }
    }
   
    rfid.halt();
}



Основная функция с++
Код: Выделить всё
// Arduino_Test_Console.cpp: определяет точку входа для консольного приложения.
//

#include "stdafx.h"
#include <iostream>
#include "SerialClass.h"
#define COM_PORT "COM4"
#define BUF_SIZE 256

int _tmain(int argc, _TCHAR* argv[])
{
      Serial com1("COM3");
      // обнуляем буфер
        char buf[BUF_SIZE];
        for(int i=0;i<BUF_SIZE;i++)
                        buf[i]='\0';
        // считываем и выводим данные из порта
        com1.ReadData(buf,BUF_SIZE-1);
        std::cout <<buf<< std::endl;
      //puts(buf);
      system("pause");
        return 0;
}




SerialClass.cpp
Здесь мню была изменена строка:
this->hSerial = CreateFile(portName, на this->hSerial = CreateFile((LPCWSTR) portName,
Код: Выделить всё
#include "stdafx.h"
#include "SerialClass.h"

Serial::Serial(char *portName)
{
    // пока ещё не подключились
    this->connected = false;

    // пытаемся подключиться к порту посредством CreateFile
    this->hSerial = CreateFile((LPCWSTR) portName,
            GENERIC_READ | GENERIC_WRITE,
            0,
            NULL,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            NULL);

    // проверяем – было ли соединение успешным
    if(this->hSerial==INVALID_HANDLE_VALUE)
    {
        //если не было – выводим ошибку
        if(GetLastError()==ERROR_FILE_NOT_FOUND){

            // печатаем ошибку
            printf("ERROR: Handle was not attached. Reason: %s not available.\n", portName);

        }
        else
        {
            printf("ERROR!!!");
        }
    }
    else
    {
        // подключились – теперь устанавливаем параметры
        DCB dcbSerialParams = {0};

        // считываем текущие параметры
        if (!GetCommState(this->hSerial, &dcbSerialParams))
        {
            // если невозможно – говорим о неудаче
            printf("failed to get current serial parameters!");
        }
        else
        {
            // устанавливаем параметры для соединения с Arduino
            dcbSerialParams.BaudRate=CBR_9600;
            dcbSerialParams.ByteSize=8;
            dcbSerialParams.StopBits=ONESTOPBIT;
            dcbSerialParams.Parity=NOPARITY;

             // применяем параметры
             if(!SetCommState(hSerial, &dcbSerialParams))
             {
                printf("ALERT: Could not set Serial Port parameters");
             }
             else
             {
                 // отлично! Мы успешно подлючились :)
                 this->connected = true;
                 //ждём пока Arduino перезагрузится
                 Sleep(ARDUINO_WAIT_TIME);
             }
        }
    }

}

Serial::~Serial()
{
    // проверяем статус подключение
    if(this->connected)
    {
        // отключаемся
        this->connected = false;
        // закрываем дескриптор порта
        CloseHandle(this->hSerial);
    }
}

int Serial::ReadData(char *buffer, unsigned int nbChar)
{
    // число считываемых байт
    DWORD bytesRead;
    // число байт, которое мы действительно хотим считать
    unsigned int toRead;

    // используем ClearCommError для получения информации о статусе последовательного порта
    ClearCommError(this->hSerial, &this->errors, &this->status);

    // проверяем – есть ли информация для считывания
    if(this->status.cbInQue>0)
    {
        // если количество данных меньше требуемого – считываем
        // столько, сколько есть
        if(this->status.cbInQue>nbChar)
        {
            toRead = nbChar;
        }
        else
        {
            toRead = this->status.cbInQue;
        }

        // Пытаемся считать нужное количество данных и
        //возвращаем число считанных байт при удачном завершении.
        if(ReadFile(this->hSerial, buffer, toRead, &bytesRead, NULL) && bytesRead != 0)
        {
            return bytesRead;
        }

    }

    // ничего не считали или где-то была ошибка – возвращаем -1
    return -1;

}


bool Serial::WriteData(char *buffer, unsigned int nbChar)
{
    DWORD bytesSend;

    // пытаемся записать значение буфера buffer в COM-порт
    if(!WriteFile(this->hSerial, (void *)buffer, nbChar, &bytesSend, 0))
    {
        // если не получилось – получаем код ошибки и возвращаем false
        ClearCommError(this->hSerial, &this->errors, &this->status);

        return false;
    }
    else
        return true;
}

bool Serial::IsConnected()
{
    // просто возвращаем статус соединения :)
    return this->connected;
}


SerialClass.h
Код: Выделить всё
#ifndef SERIALCLASS_H_INCLUDED
#define SERIALCLASS_H_INCLUDED

#define ARDUINO_WAIT_TIME 20000

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

class Serial
{
    private:
        // дескриптор COM-порта
        HANDLE hSerial;
        // статус соединения
        bool connected;
        // различная информация о соединении
        COMSTAT status;
        // последняя ошибка
        DWORD errors;

    public:
        // инициализация с указанным COM-портом
        Serial(char *portName);
        // закрытие соединения
        //NOTA: по каким-то причинам не удаётся переподключиться
        // нужно перезапускать программу
        ~Serial();
        // считываем данные в буфер – если nbChar больше, чем
        // число доступных байт – возвращает только
        // доступные данные
        // возвращает -1 при ошибке
        int ReadData(char *buffer, unsigned int nbChar);
        // записывает данные из буфера в порт
        // возвращает true при удаче
        bool WriteData(char *buffer, unsigned int nbChar);
        // возвращает статус соединения
        bool IsConnected();


};

class SerialClass
{
public:
   SerialClass(void);
   ~SerialClass(void);
};

#endif // SERIALCLASS_H_INCLUDED


Подскажите, решить проблему с подключением к COM-порту.
p/s Форумом возможно и ошибся. Но ошибся сознательно.
С уважением, Waik/
Waik
 
Сообщения: 1
Зарегистрирован: 27 июн 2014, 17:30
programming: c++

Re: Работа с COM-портом в С++.

Сообщение noonv » 02 июл 2014, 22:53

а вот такой класс Serial попробуйте:
https://github.com/RoboCraft/robot_2wd/ ... 2/serial.h
https://github.com/RoboCraft/robot_2wd/ ... serial.cpp
- зависимость от Stream можно убрать или просто добавить
https://github.com/RoboCraft/robot_2wd/ ... 2/stream.h
Аватара пользователя
noonv
Администратор
 
Сообщения: 540
Зарегистрирован: 05 май 2011, 15:44
Откуда: Калининград
programming: С++

Re: Работа с COM-портом в С++.

Сообщение Userpc1010 » 20 окт 2017, 21:04

В примере на странице указанно:

And: CreateFile may need to be replaced with CreateFileA in Serial.cpp
( https://playground.arduino.cc/Interfaci ... Studio2008 )
Userpc1010
 
Сообщения: 5
Зарегистрирован: 01 авг 2017, 19:53


Вернуться в Программирование

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

© 2009-2017 |  О проекте  |  Политика Конфиденциальности  |