读取Arduino中的串行数据,损坏的数据

时间:2014-06-27 19:06:20

标签: c++ file-io serial-port arduino serial-communication

我正在使用Arduino Due和Visual Studio 2010.我正在用C / C ++编程。下面你看我的程序,然后我解释了什么是错误的。

这是我的Arduino上非常简单的代码。它向PC发送了很多A。

void setup()
{
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

void loop()
{
  Serial.println('A');
  delay(1);        // delay in between reads for stability
}

读取我在此处找到的串行端口的更多代码: http://playground.arduino.cc/Interfacing/CPPWindows

这是我此代码的修改版本:

标题

#ifndef SERIALCLASS_H_INCLUDED
#define SERIALCLASS_H_INCLUDED
#define ARDUINO_WAIT_TIME 2000

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

class Serial
{
    private:
        //Serial comm handler
        HANDLE hSerial;
        //Connection status
        bool connected;
        //Get various information about the connection
        COMSTAT status;
        //Keep track of last error
        DWORD errors;

    public:
        //Initialize Serial communication with the given COM port
        Serial(char *portName);
        //Close the connection
        //NOTA: for some reason you can't connect again before exiting
        //the program and running it again
        ~Serial();
        //Read data in a buffer, if nbChar is greater than the
        //maximum number of bytes available, it will return only the
        //bytes available. The function return -1 when nothing could
        //be read, the number of bytes actually read.
        int ReadData(char *buffer, unsigned int nbChar);
        //Writes data from a buffer through the Serial connection
        //return true on success.
        bool WriteData(char *buffer, unsigned int nbChar);
        //Check if we are actually connected
        bool IsConnected();
};

#endif // SERIALCLASS_H_INCLUDED

CPP:

#include "stdafx.h"
#include <stdio.h>
#include <tchar.h>
#include "SerialClass.h"
#include <string>
#include <windows.h>
#include <assert.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <conio.h>


using namespace System;
using namespace std;

// Serial::Serial looks, if Serial Connection from PC to the Device is proper and everything is working. Then it sets a few Parameters and waits
Serial::Serial(char *portName)
{
    //We're not yet connected
    this->connected = false;

    //Try to connect to the given port throuh CreateFile
    this->hSerial = CreateFileA(portName,
            GENERIC_READ | GENERIC_WRITE,
            0,
            NULL,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            NULL);

    //Check if the connection was successfull
    //if not...show error
    if(this->hSerial==INVALID_HANDLE_VALUE)
    {
        //If not success full display an Error
        if(GetLastError()==ERROR_FILE_NOT_FOUND){
            //Print Error if neccessary
            printf("ERROR: Handle was not attached. Reason: %s not available.\n", portName);
            Sleep(2000);
        }
        else
        {printf("ERROR!!!");}
    }
    // else = connection is working, then -> continue
    else
    {
        //If connected we try to set the comm parameters
        DCB dcbSerialParams = {0};

        //Try to get the current Parameters
        if (!GetCommState(this->hSerial, &dcbSerialParams))
        {
            //If impossible, show an error
            printf("failed to get current serial parameters!");
        }
        else
        {
            //Define serial connection parameters for the arduino board

            dcbSerialParams.BaudRate=CBR_9600;
            dcbSerialParams.ByteSize=8;
            dcbSerialParams.StopBits=ONESTOPBIT;
            dcbSerialParams.Parity=NOPARITY;


             //Set the parameters and check for their proper application
             if(!SetCommState(hSerial, &dcbSerialParams))
             {
                printf("ALERT: Could not set Serial Port parameters");
             }
             else
             {
                 //If everything went fine we're connected
                 this->connected = true;
                 //We wait 2s as the arduino board will be reseting
                 Sleep(ARDUINO_WAIT_TIME);
             }
        }
    }
}


//Has a look if SerialPort is still connected.
//If yes, it disconnects and closes the Serial Handler.
Serial::~Serial()
{
    //Check if we are connected before trying to disconnect
    if(this->connected)
    {
        //We're no longer connected
        this->connected = false;
        //Close the serial handler
        CloseHandle(this->hSerial);
    }
}


// reads data out of Serial Port
int Serial::ReadData(char *buffer, unsigned int nbChar)
{
    //Number of bytes we'll have read
    DWORD bytesRead;
    //Number of bytes we'll really ask to read
    unsigned int toRead;

    //Use the ClearCommError function to get status info on the Serial port
    ClearCommError(
        this->hSerial, // Handle to the communications device, CreateFile Function returns this value
        &this->errors, // a pointer to a variable that receives a mask indicating the type of rror
        &this->status);// a pointer to a COMSTAT structure in which the devices status information is returned. if this parameter is NULL, no status information is returned

//Check if there is something to read
if(this->status.cbInQue>0) // cbInQue: Number of Bytes received by the Serial provider, but not yet read by a ReadFile operation
{
    //If there is we check if there is enough data to read the required number
    //of characters, if not we'll read only the available characters to prevent
    //locking of the application.
    if(this->status.cbInQue>nbChar)
        {toRead = nbChar;}
    else
        {toRead = this->status.cbInQue;}

    //Try to read the require number of chars, and return the number of read bytes on success
    if(ReadFile(
       this->hSerial,   // Handle to a device
       buffer,          // a pointer to the buffer that receives the data read from a file or device
       toRead,          // NumberofBytesToRead: the maximum number of bytes to be read
       &bytesRead,      // NumberofBytesRead: a pointer to the variable that receives the number of bytes read when using a synchronours hFile parameter.
            NULL)           // Overlapped
            && bytesRead    // Value of bytesRead after ReadFile function
            != 0)
        {return bytesRead;
        Sleep(1000);}   // returns Value of BytesRead
    }
    //If nothing has been read, or that an error was detected return -1
    return -1;
}



bool Serial::IsConnected() // simply returns connection status
{
    //Simply return the connection status
    return this->connected;
}

主:

// application reads from the specified serial port and reports the collected data
int _tmain(int argc, _TCHAR* argv[])
 {
     printf("Welcome to the serial test app!\n\n");
     Serial* SP = new Serial("\\\\.\\COM3");    // adjust as needed

     if (SP->IsConnected())
        printf("We're connected");

     // defines how much Data will be catched
     // don't forget to pre-allocate memory

        char incomingData[1025] = "";
        incomingData[1024]='\0';

        int dataLength = 1024; // maximum Length of one DataBit/Word
        int readResult = 0;

        // gives out the Number! of DataBits that could be collected/catched
        readResult = SP->ReadData(incomingData,dataLength);

        printf("Bytes read: (-1 means no data available) %i\n",readResult);


        // transforms the char incomingData into a String and prints it

        std::string test(incomingData);
        printf("%s \n", incomingData);

        printf("Bytes read: (-1 means no data available) %i\n",readResult);

        Sleep(10000);
   }

所以现在这是我的问题:

只要我从Arduino发送的比特数小于DataLength,程序就可以正常工作。 (这里= 1024)我通过设置Arduino程序的延迟相当高(~100ms)得到了那些较少的位。 然后我有一个控制台窗口,其输出类似于:

A
A
A
A
A
... goes on like this

但是如果Arduino发送超过1024位(延迟〜1ms)/ PC接收的数据比DataLength的值多,那么Serial :: ReadData循环中的某些东西似乎出错了。 我的控制台输出有点破坏,有些Bits看起来像这样:

A
ßA

A A
A
... goes on similar to this.

我的计划有什么问题?我认为可能是,ReadFile()函数的一个参数不正确,但我不知道要改变什么,我对此并不是100%肯定。

0 个答案:

没有答案