【问题标题】:Serial port in c++ , Unixc++ , Unix 中的串口
【发布时间】:2014-12-28 21:02:41
【问题描述】:

我写了一个代码来连接,通过一个串口,mi计算机到arduino。

这是arduino的代码:

#include <Servo.h>

Servo servo;
const int pinServo = 2;
unsigned int angle;

void setup()
{
    Serial.begin(9600);
    servo.attach(pinServo);

    servo.write(0);

}

void loop()
{
    if(Serial.available()>0)
    {  
       angle = Serial.read();

       if(angle <= 179)
       {
         servo.write(angle);
       }
    }
}

这是 c++ 的:

#include <iostream>
#include <unistd.h>
#include <fstream>
#include <termios.h>

using namespace std;

int main()
{
    unsigned int angle;
    ofstream arduino;
    struct termios ttable;

    cout<<"\n\ntest1\n\n";

    arduino.open("/dev/tty.usbmodem3a21");

    cout<<"\n\ntest2\n\n";

    if(!arduino)
    {
        cout<<"\n\nERR: could not open port\n\n";
    }
    else
    {
        if(tcgetattr(arduino,&ttable)<0)
        {
            cout<<"\n\nERR: could not get terminal options\n\n";
        }
        else
        {
            ttable.c_cflag &= ~PARENB;
            ttable.c_cflag &= ~CSTOPB;
            ttable.c_cflag &= ~CSIZE;
            ttable.c_cflag |= CS8;
            ttable.c_cflag &= ~CRTSCTS;
            ttable.c_cflag |= CREAD | CLOCAL;
            ttable.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
            ttable.c_oflag &= ~OPOST;
            ttable.c_cc[VMIN]  = 0;
            ttable.c_cc[VTIME] = 0;

            cfsetospeed(&ttable,9600);

            if(tcsetattr(arduino,TCSANOW,&ttable)<0)
            {
                cout<<"\n\nERR: could not set new terminal options\n\n";
            }
            else
            {
                do
                {
                    cout<<"\n\ninsert a number between 0 and 179";
                    cin>>angle;
                    arduino<<angle;
                }while(angle<=179);

                arduino.close();
            }
        }
    }

}

它应该连接到 arduino ,然后问我一个介于 0 到 179 之间的数字,然后将该数字发送到 arduino,该数字将该数字作为伺服电机的角度; 但它停在arduino.open("/dev/tty.usbmodem3a21")。我该怎么办?

【问题讨论】:

  • 什么意思“它停止了”?您是否遇到异常,或者程序是否挂起?请您详细说明实际行为。
  • Sorry.it 编译,没有错误没有警告,然后它由终端执行,我看到输出“test1”然后程序停止,在“test1”之后没有输出,没有文本,什么都没有。我也确信这不是时间问题。
  • 当你说 "it stop" 时你会得到 shell 提示吗?另请注意,您应该使用std::endl 而不是"\n" 作为行尾。您可能会错过输出,除非它们被刷新(这就是 std::endl 与输出 "\n" 相比所做的额外操作)。
  • 不,我认为“它冻结”是一个更好的主意,终端保持打开状态,程序继续运行,但没有任何输出
  • 我越来越相信tcgetattr(arduino,&amp;ttable) 会导致问题。请记住,ofstream 会自动转换为 bool,因此会自动转换为 int。假设open 很好,您将1 作为fd 参数有效地传递,并更改stdin fd 的属性。使用原始 c 样式 open() 为您的 arduino 设备获取 fd。

标签: c++ unix serial-port arduino termios


【解决方案1】:

我认为你的问题出现在这几行代码中

if(tcgetattr(arduino,&ttable)<0) {
    // ...
}
else {
    // ...

    if(tcsetattr(arduino,TCSANOW,&ttable)<0) {
        // ...
    }
}

arduino 变量的类型为ofstream,其中tcgetattr()tcsetattr() 期望此时使用open() 获得文件描述符。

ofstream 提供到bool 的自动转换,因此隐式地提供int。假设是

arduino.open("/dev/tty.usbmodem3a21");

一切顺利,您有效地将1 传递给tcgetattr()tcsetattr(),这是标准输入文件描述符。


解决方法是不要为arduino 使用ofstream,而是使用普通的文件描述符

int arduino = open("/dev/tty.usbmodem3a21",O_WRONLY);

【讨论】:

  • 好的,谢谢,但另一件事,标志设置是否可以仅输出到arduinos?
  • @DaddaBarba 我对 arduino 了解不多。您需要了解波特率、奇偶校验等。我也不太确定,angle = Serial.read(); 对串行端口的期望是什么。看起来我喜欢传输文本数据(如您尝试使用 arduino&lt;&lt;angle;)不正确。
  • 好的,再次感谢您。对于 serial.read() arduino 应该只在 te 串行端口文件中取 te 值并将其放入角度,但我也认为会有问题,因为角度是 int ,但我也可以使用字符串到 int 转换器所以它不是如此重要的 arduino 代码,它可以通过简单的方式进行串行连接
猜你喜欢
  • 1970-01-01
  • 2011-02-23
  • 1970-01-01
  • 1970-01-01
  • 2015-01-02
  • 2012-01-22
  • 2012-07-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多