通过串口访问机器人

时间:2012-11-09 05:37:35

标签: c macos serial-port

我尝试使用gcc(我使用mac)通过串口访问机器人。

我让我的程序发送简单的命令:

  

HOME(输入)并且机器人有一些反馈:这就是了   HOMING SEQUENCE COMMAND。机器人会在上面找到它的开关   每个轴并将在该位置执行HOMING功能。 DO
  你想继续(是/否)?

我发送

  

Y(输入)

并且机器人想要移动。

现在访问机器人正在使用调制解调器/终端Zterm。 该调制解调器使用波特率38400,8N1

我使用相同的波特率和8n1

这是我的代码,我不知道为什么我的代码无法让机器人移动有什么问题

谢谢

丹尼尔

    #include<stdio.h>   /* Standard input/output definitions */
    #include<stdlib.h>
    #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 definitions */
    //#include<conio.h> 

    /*
     * 'open_port()' - Open serial port 1.
     *
     * Returns the file descriptor on success or -1 on error.
     */

    int buf_size;
    char *buf;
    char *buff;
    int fd; /* File descriptor for the port */

    int open_port(void)
    {

       fd = open("/dev/tty.USA28X1a2P2.2", O_RDWR | O_NOCTTY | O_NDELAY);  //      USA28X1a2P2.for keyspan 
    //fd = open("/dev/ttys000", O_RDWR | O_NOCTTY | O_NDELAY);   
    if (fd == -1) {
     /*
      * Could not open the port.
      */
      perror("cannot open");
   }
     else 
        fcntl(fd, F_SETFL, 0);
        struct termios options;
          /* 
           * Get the current options for the port...
           */
          tcgetattr(fd, &options);

          /*
           * Set the baud rates to 38400...
           */

         cfsetispeed(&options, B38400);
         cfsetospeed(&options, B38400);


         /*
          * Enable the receiver and set local mode...
          */

         options.c_cflag |= (CLOCAL | CREAD);

         /*
          * Set the new options for the port...
          */

         tcsetattr(fd, TCSANOW, &options);

         options.c_cflag &= ~CSIZE; /* Mask the character size bits */

         options.c_cflag &= ~PARENB;
         options.c_cflag &= ~CSTOPB;
         options.c_cflag &= ~CSIZE;
         options.c_cflag |= CS8;

     return (fd);
    }

    int main(int argc, char**argv) {
        buf =malloc(20);
        buff=malloc(20);

    //   strcpy(buf,"HOME");
    //    strcpy(buff,"Y");
        open_port();
        printf("type the command using Capital Letter : \n");
        scanf("%s",buf);
        write(fd, buf,20); // 
        write(fd," \r ",5);
        printf("Command = %s\n", buf);
        read(fd, buff,50);
        printf(" %s \n",buff);
        free(buf);
        free(buff);
        printf("type Y/N : \n");
        scanf("%s",buf);
        write(fd, buf,2);
        write(fd,"\r",2);

    //    free(buf);
    //  free (buff);
    //    printf("type Y/N : \n");
    //    write(fd, buf,20);
    //    printf("You choose %s \n",buff);
    //    free(buf);

        close(fd);
    }

2 个答案:

答案 0 :(得分:1)

你一次读的太多了。您将缓冲区分配为20个字节,buff=malloc(20);但是在这里您读取50,read(fd, buff,50);这可能会导致奇怪的行为。确保分配尽可能多的空间。你甚至不需要分配它,你可以使用数组。

char buf[1024];
char buff[1024];

然后在再次使用它们之前释放你的记忆。

 free(buf);
 free(buff);
 printf("type Y/N : \n");
 scanf("%s",buf);

在致电close(fd)之前,请勿释放buf或buff。

阅读好的C风格。你正在做一些不是错误的事情,但会让你的生活更加艰难。

答案 1 :(得分:0)

代码中有很多错误(比如缓冲区溢出等),但我能看到的最明显的错误就在这里:

tcsetattr(fd, TCSANOW, &options);

options.c_cflag &= ~CSIZE; /* Mask the character size bits */

options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;

只有在您使用options结构设置文件描述符的属性后,才会设置tcsetattr()结构的字段。您必须将呼叫设置为options.c_cflag &= ~CSIZE; /* Mask the character size bits */ options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; tcsetattr(fd, TCSANOW, &options); 到整个序列的结尾:

{{1}}

如果您不想手动设置所有这些,请尝试我的helper function.