【问题标题】:How to send and receive UDP Pakets on Lego Mindstorms EV3 using Simulink External Mode?如何使用 Simulink External Mode 在 Lego Mindstorms EV3 上发送和接收 UDP 数据包?
【发布时间】:2015-11-18 16:39:57
【问题描述】:

我正在尝试使用我的 EV3 的 c 代码创建一个 simulink 块,以通过 UDP 包从其传感器发送测量值和/或从其他硬件(树莓派)接收数据。但是我在互联网上找不到任何具体的例子。我尝试按照https://www.abc.se/~m6695/udp.html 的示例编写自己的代码。我希望它能够工作,因为 EV3 是一个 linux 系统。但是,它不起作用。

udp_receiver的c代码库(更新):

#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>

// BUFLEN = max size
#define BUFLEN 512
#define NPACK 1


double * linux_udp_empfaenger(int32_t PORT)
{
  struct sockaddr_in si_me, si_other;

  int s, i, j, slen = sizeof(si_other) , recv_len;
  char buf[BUFLEN];
  //char buf_h[BUFLEN];
  unsigned short recv_port = (unsigned short) PORT;
  double * data;

  //create a UDP socket
  if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
  {
    return 0;
    exit(1);
  } else{

    // zero out the structure
    memset((char *) &si_me, 0, sizeof(si_me));

   si_me.sin_family = AF_INET;
   si_me.sin_port = htons(recv_port);
   si_me.sin_addr.s_addr = htonl(INADDR_ANY);

   //bind socket to port
   if( bind(s , (struct sockaddr*)&si_me, sizeof(si_me) ) == -1)
   {
     close(s);
     return 0;
     exit(1);
   } else{

    //clear the buffer by filling null, it might have previously received data
    //memset(buf,'\0', BUFLEN);

    for (i=0; i<NPACK; i++) {
     if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen)==-1)
      {
        close(s);
        return 0;
       } else {
        //Convert buf into usable host format
        //buf_h = ntohs(buf);

        // Convert data from string to double
        //data = atof(buf);

        int N_DATA = sizeof(buf)/sizeof(buf[0]);

        for (j = 0; j < N_DATA; j++){
        data[j] = (double)be64toh(((uint64_t *)buf)[j]);
        }

        close(s);
        return data;
      } 

    }

  }

 }

}

当我在外部运行模块时,模型显示正在运行,但 T=0.000 一直。我现在什至无法停止模型。

希望能得到你的帮助。 谢谢大家!

【问题讨论】:

  • 您是在 EV3 上使用 LEGO Group 的标准固件还是使用第 3 方操作系统?另外,您的两个代码示例看起来都在接收数据,在传输什么?你是在EV3上编译安装c代码吗?
  • 你好大卫,我使用的是乐高集团的标准固件。是的,我正在编写代码来接收数据。基本上我想使用该代码接收所有类型的数据,尤其是来自其他硬件的测量数据。现在,我正在从我的树莓派发送一个无限正弦信号,并希望 EV3 能够接收到该信号。 c 代码与 simulink 模型一起编译到 EV3 上,并由 matlab 功能块在那里执行。
  • 我刚刚上传了我在上述问题的编译过程中收到的警告。希望你能帮助我,谢谢:)

标签: c matlab udp simulink mindstorms


【解决方案1】:

./udp_send_receive.c:14: 警告:内置函数'exit'的隐式声明不兼容

你不见了

#include <stdlib.h>

./udp_send_receive.c:31:警告:内置函数“memset”的隐式声明不兼容

./udp_send_receive.c:66:警告:内置函数“memset”的隐式声明不兼容

./udp_send_receive.c:76: 警告:内置函数'strlen'的隐式声明不兼容

你不见了

#include <string.h>

./udp_send_receive.c:44: 警告:从不兼容的指针类型传递“recvfrom”的参数 5

不完全确定如何解决这个问题。定义__USE_GNU 可能会有所帮助。见sys/socket.h

./udp_send_receive.c:70: 警告:传递 'inet_aton' 的参数 1 使指针从整数而不进行强制转换

./udp_send_receive.c:76: 警告:传递 'strlen' 的参数 1 使指针从整数而不进行强制转换

需要在参数声明中添加*char 是单个字符。 char * 是一个字符串。

void udp_send(char *data, char *SERVER, int PORT)

【讨论】:

  • 谢谢大卫!我更正了 c 代码中的所有错误和警告。更正后的代码在问题中更新。但是,该模型仍然始终以 T=0.0000 运行并卡在那里。我想知道我包含的那些标头是否存在于 EV3 中。有什么方法可以检查吗?
  • 您永远不会为buf 分配任何内存。我想象当您尝试使用 buf 时,程序会出现 segfualt。在您原来的帖子中,您使用的是 buf[BUFLEN];,它在堆栈上分配内存,这很可能是您想要在这里执行的操作。
  • 谢谢大卫。我已经更正了它并尝试一点一点地运行 c 代码。当我评论recvfrom()函数时,就像我刚刚在我的问题中更新的那样,模型运行顺利,但当然没有收到数据,并且数据一直返回-1。所以首先,我认为如果没有收到数据,它应该返回 0 作为值,因为我声明了double data = 0;?我也不知道为什么recvfrom 函数不起作用。
  • 我无权访问 simulink,所以我不知道数据实际上是如何在那里返回的,以及为什么它会是 -1。 recvfrom() 功能阻塞,直到它接收到数据。你真的在发送数据吗?此外,您目前在close(s) 之前有return data,因此套接字没有正确关闭。
  • 我明白了。我还没有向它发送任何数据。但我想要做的是,如果在超时时间内没有收到数据,数据将返回 0。有什么办法可以实现吗?另外,当创建或绑定套接字出错时,数据也会返回0。(但我不太确定我写的方式是否正确。基本上我想退出函数并将输出数据返回为0) .该函数在无限循环中被调用,直到我停止模型。如果我得到数据为0而不是等待接收数据,那就太好了,这样模型中的其他组件也可以运行。
猜你喜欢
  • 1970-01-01
  • 2014-01-14
  • 2023-03-04
  • 2012-10-03
  • 2012-05-20
  • 1970-01-01
  • 2019-01-04
  • 2011-09-24
  • 2017-12-09
相关资源
最近更新 更多