Введение/
К 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/