简体   繁体   English

无法与连接的串口通信?

[英]No communication to a connected serial port?

I'm trying to connect to an Arduino Mega 2560 unit connected via USB serial port in my Linux based PC. 我正在尝试连接到基于Linux的PC中通过USB串行端口连接的Arduino Mega 2560单元。

Using C code, I'm trying to send and receive simple text strings, just I'm able to send and receive on both sides. 使用C代码,我试图发送和接收简单的文本字符串,只是我能够在两侧进行发送和接收。

On Arduino: 在Arduino上:

int incomingByte = 0;    // for incoming serial data

void setup() {
    Serial.begin(19200);    // opens serial port, sets data rate to 9600 bps
}

void loop() {
  // send data only when you receive data:
  if (Serial.available() > 0) {

    // read the incoming byte:
    incomingByte = Serial.read();

    // say what you got:
    Serial.print((char)incomingByte);
  }

}

Basically just a loop that checks if there is serial data, and if so reads it and prints it back. 基本上只是一个循环,它检查是否有串行数据,如果有则读取并打印回来。 there's a (char) conversion so I'll see right away the sent data is what I got back (Linux side) 有一个(字符)转换,所以我马上就会看到发送的数据是我返回的(Linux方面)

For the Linux code I use the pretty standard code for opening a port which I found here 对于Linux代码,我使用相当标准的代码来打开端口,我在这里找到

I call the Arduino "Table" as it will eventually operate a moving table through USB commands. 我称Arduino为“桌子”,因为它最终将通过USB命令操作移动桌子。

C file: C文件:

#include "TableFunctions.h"

bool connected=false;
int fd;
char *portname;


int set_interface_attribs (int fd, int speed, int parity)
{
        connected=false;
        struct termios tty;
        struct termios tty_old;
        memset(&tty, 0, sizeof tty);
        if (tcgetattr (fd, &tty) != 0)
        {
                printf("PC: Error %d from tcgetattr  \n", errno);
                return -1;
        }
        tty_old = tty;

        cfsetospeed (&tty, (speed_t)B19200);
        cfsetispeed (&tty, (speed_t)B19200);

        //tty.c_cflag |= B19200;
        tty.c_cflag     &=  ~PARENB;            // Make 8n1
        tty.c_cflag     &=  ~CSTOPB;
        tty.c_cflag     &=  ~CSIZE;
        tty.c_cflag     |=  CS8;

        tty.c_cflag     &=  ~CRTSCTS;           // no flow control
        tty.c_cc[VMIN]   =  1;                  // read doesn't block
        tty.c_cc[VTIME]  =  5;                  // 
        tty.c_cflag     |=  CREAD | CLOCAL;     // turn on READ & ignore ctrl lines
        cfmakeraw(&tty);
        tcflush( fd, TCIFLUSH );

        if (tcsetattr (fd, TCSANOW, &tty) != 0)
        {
                printf("PC: Error %d from tcsetattr  \n", errno);
                return -1;
        }
        return 0;
}

void set_blocking(int fd, int should_block)
{
        struct termios tty;
        memset(&tty, 0, sizeof tty);
        if (tcgetattr (fd, &tty) != 0)
        {
                printf("PC: Error %d from tggetattr  \n", errno);
                return;
        }

        tty.c_cc[VMIN]  = should_block ? 1 : 0;
        tty.c_cc[VTIME] = 10;            // 0.5 seconds read timeout

        if (tcsetattr (fd, TCSANOW, &tty) != 0)
                printf("PC: Error %d setting term attributes  \n", errno);
}


void OpenSerialPort()
{
    char *portname = "/dev/ttyACM0";

    printf("PC: Opening port to table \n");

    int fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);

    usleep(2000000);
    if (fd < 0)
    {
        printf("PC: Error %d opening %s: %s  \n", errno, portname, strerror(errno));
        return;
    }

    set_interface_attribs(fd, B19200, 0);  // set speed to 19,200 bps, 8n1 (no parity)
    set_blocking(fd, 0);                // set no blocking
    printf("PC: Connected\n");
    connected = true;
}
void PrepareWriteCommand(int numberOfCommands, const char *commands[numberOfCommands])
{
    if(connected) //check if arduino still connected
    {
        for(int i = 0; i<numberOfCommands; i++) //go through commands 
        {
            int bufferSize = strlen(commands[i]); //get the buffer size needed for this command
            char charArray[bufferSize]; //helper char array
            memcpy(charArray,commands[i],bufferSize);//copy command to the char array
            charArray[bufferSize]=0; //make sure there is a stop symbok at the end
            WriteSerialPort(charArray); //command is ready to be sent, send it.
        }
    }
}
int WriteSerialPort(const char *buffer)
{
    printf("PC: Now writing: ");
    int n_written = 0; //how many bytes were written

    n_written = write(fd, buffer, strlen(buffer)); //write the command and return how many bytes were written

    printf("\n");

    //check bytes send and return ouput (error, nothing or x bytes sent)
    if(n_written<0)
    {
        printf("PC: Error %d from %s \n",errno, strerror(errno));
    }
    else if(n_written == 0)
    {
        printf("PC: Nothing was written  \n");
    }
    else
    {
        printf("PC: Written %i bytes  \n", n_written);
    }

}

int ReadSerialPort(char *buffer, unsigned int buff_size)
{
    //check if arduino still connected
    if(connected)
    {
        //read the serial data
        if(read(fd,buffer,buff_size))
            return sizeof(buffer); //return how much bytes were read
        else
        {
            //else print nothing received
            printf("PC: Arduino not Connected (ReadSerialPort) \n");
        }
    }
}

In OpenSerialPort I basically open a new fd , and call the functions that set the communication settings. OpenSerialPort我基本上打开一个新的fd ,并调用用于设置通信设置的函数。

I use PrepareWriteCommand to make sure commands input from users are with a stop symbol and send them to WriteSerialPort where I use write() and print how many bytes were sent. 我使用PrepareWriteCommand来确保用户输入的命令带有停止符号,并将其发送到WriteSerialPort ,在其中我使用write()并打印发送了多少字节。

H file: H档:

#include <errno.h>
#include <fcntl.h> 
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>


#define MAX_DATA_LENGTH 256

int set_interface_attribs (int fd, int speed, int parity);
void set_blocking(int fd, int should_block);
void OpenSerialPort();
void PrepareWriteCommand(int numberOfCommands, const char *commands[numberOfCommands]);
int WriteSerialPort(const char *buffer);
int ReadSerialPort(char *buffer, unsigned int buff_size);

Main: 主要:

    #include "TableFunctions.h"
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
    {
        char output[MAX_DATA_LENGTH]; //char array to hold arduino output
        int received = 0; // check if read() got any bytes
        const char* commands[]={"test"}; //test command

        OpenSerialPort(); // open serial port

        PrepareWriteCommand((sizeof(commands)/sizeof(commands[1])),commands); //prepare command for sending

        usleep(500000); //wait for arduino response

        while(true)
{
    received = ReadSerialPort(output,MAX_DATA_LENGTH);//check serial port for response
    switch(received)
    {
        case -1:
        {
            printf("PC: Error %d from %s \n",errno, strerror(errno));
            break;
        }
        case 0:
        {
            printf("PC: Nothing received\n");
            usleep(500000);
            break;
        }
        default:
        {
             printf("PC: received %i\n",received); //if yes, how many bytes
            printf("PC: %s\n",output); //and what was received
            usleep(500000);
        }
    }
}
return 0; //finish program

I tried tweaking the TTY flags settings with no success. 我尝试调整TTY标志设置没有成功。 Each time I run the C code I see the Arduino resets (and after opening a new fd I give it some time for bootloading) but no communication is sent between the two. 每次我运行C代码时,我都会看到Arduino重置(在打开新的fd我会给它一些时间进行引导加载),但是两者之间没有通信发送。

Output: 输出:

PC: Opening port to table 
PC: Connected
testPC: Now writing: 
PC: Written 4 bytes  

PC: received 0
PC: 

Any help with understanding why the C code can't communicate with the Arduino will be highly appreciated! 非常感谢您理解为什么C代码无法与Arduino通信的任何帮助!

Problem was in OpenSerialPort() . 问题出在OpenSerialPort() I set another variable fd which is local, thus given priority. 我设置了另一个局部变量fd ,因此具有优先级。 then when OpenSerialPort() is done, it is deleted, and the global fd remain unset. 然后在完成OpenSerialPort()其删除,并且全局fd保持未设置状态。 This is why I can't send anything from or to the PC. 这就是为什么我无法从PC发送任何东西到PC的原因。

Thanks. 谢谢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM