0

コンピューターと arduino の間のシリアル通信チャネルを確立しようとしています。ArduinoIDE を見ると、arduino から送信された完璧なメッセージが表示されます - 3 つの同一の番号。現在、Ubuntu を実行しているコンピューターでそのデータを読み取るための C++ アプリを作成しようとしていますが、文字列に大量のゴミが発生します。私は成功せずに読んだり検索したりしてきました。私の問題の原因を見つけるのを手伝ってくれる人はいますか?

コード:

SerialComm.h:

#ifndef SERIALCOMM_HPP
#define SERIALCOMM_HPP

#include <fstream>
#include <string>

#include <stdio.h> // standard input / output functions
#include <string.h> // string function definitions
#include <unistd.h> // UNIX standard function definitions
#include <fcntl.h> // File control definitions
#include <errno.h> // Error number definitions
#include <termios.h> // POSIX terminal control definitionss

class SerialComm {
public:

    SerialComm() noexcept {
    }

    virtual ~SerialComm() noexcept {
        tcsetattr(fd, TCSANOW, &port_settings);
        close(fd);
    }

    void begin(std::string port, speed_t baudrate);
    std::string read_data();

private:
    int fd;
    speed_t _baudrate;
    std::string _port;
    static constexpr int BUFFER_SIZE = 256;
    char buffer[BUFFER_SIZE];
    termios port_settings;
};

SerialComm.cpp

#include "SerialComm.hpp"

#include <iostream>

using namespace std;

void SerialComm::begin(string porta, speed_t baudrate) {
    _port = porta;
    _baudrate = baudrate;

    // abre a porta
    fd = open(_port.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);

    if (fd == -1) {
        printf((string("Unable to open port ") + _port).c_str());
    } else {
        fcntl(fd, F_SETFL, 0);
        printf("port is open.\n");
    }

    cfsetispeed(&port_settings, _baudrate); // set baud rates
    cfsetospeed(&port_settings, _baudrate);

    port_settings.c_cflag &= ~PARENB; // set no parity, stop bits, data bits
    port_settings.c_cflag &= ~CSTOPB;
    port_settings.c_cflag &= ~CSIZE;
    port_settings.c_cflag |= CS8;

    tcsetattr(fd, TCSANOW, &port_settings); // apply the settings to the port   
}

string SerialComm::read_data() {
    int state = 1;

    while (true) {
        state = read(fd, buffer, BUFFER_SIZE);
        if (state > 0) 
        {
            return string( buffer );
        }
    }
}

main.ccp

int main(int argc, char* argv[])
{

    SerialComm serial;

    serial.begin("/dev/ttyACM0", B115200);

    for(auto i = 0; i < 100; ++i)
    {
        cout << serial.read_data() << endl;
    }
}

シリアル.ino:

double sinal = 0;

void setup()
{
  Serial.begin( 115200 );
}

void loop()
{
  sinal = analogRead( A0 ) * ( 5.0 / 1024.0 );
  Serial.print( "$" );
  Serial.print( sinal, 5 );
  Serial.print( "," );
  Serial.print( sinal, 5 );
  Serial.print( "," );
  Serial.print( sinal, 5 );
  Serial.print( "#\n" );
}

Arduino IDE 出力:

$2.24121,2.24121,2.24121#
$2.24609,2.24609,2.24609#
$2.24121,2.24121,2.24121#
$2.24121,2.24121,2.24121#
$2.24609,2.24609,2.24609#

コンピュータ出力:

$2.24609,2.24?�̯m#
$2.
09375#
$2.2412109375,2.2412109937500#
$2.2460937500,2.2460937500,2.2460937500#
375#
$2.2460937500,2.2460937500,2.2460937500#
$2.
375,2.2412109375#
$2.241210937937500#
$2.2460937500,2.2460937500,2.2460937500#

PS:上記は私が得ることができる最も美しい出力でした。

4

2 に答える 2

4

終端されていない文字列バッファの問題に加えて、 への 1 回の呼び出しで完全なメッセージを受信できるとは言えませんread。代わりに、メッセージの終わり (送信する改行) が得られるまで、ループで読み取る必要があります。

readこれはもちろん、同じ通話で 1 つのメッセージの終わりと次のメッセージの始まりを受信できるという別の問題を引き起こします。これは、次のメッセージの先頭を保存し、次の呼び出しの前にバッファに入れる必要があることを意味しますread

于 2013-11-10T20:03:47.050 に答える