【问题标题】:How to receive a JPEG image over serial port如何通过串行端口接收 JPEG 图像
【发布时间】:2016-05-29 20:51:09
【问题描述】:

所以我正在尝试使用 Xbee 系列 1 将树莓派中的 jpeg 图像 (4Kb) 无线发送到我的 Mac。我在树莓派上有一个图像,可以将其读取为二进制格式。我已经使用这种二进制格式将其保存到另一个图像文件中,它会正确创建图像的副本。这告诉我我读对了。因此,我试图通过串行端口(由 xbee 传输)将该数据发送到我的 Mac。旁注,我认为 Xbee 的每个数据包只能传输 80 字节的数据或其他东西。我不知道这如何影响我正在做的事情。

我的问题是,我不知道如何读取数据并将其正确存储到 jpeg 文件中。我发现的大多数 Read() 函数都要求您输入要读取的长度,我不知道如何判断它有多长,因为它只是一个串行流进来。

这是我发送 jpeg 的代码。

#include "xSerial.hpp"
#include <iostream>
#include <cstdlib>
using namespace std;

int copy_file( const char* srcfilename, const char* dstfilename );


int main(){

copy_file("tylerUseThisImage.jpeg", "copyImage.jpeg");

return 0;
}

int copy_file( const char* srcfilename, const char* dstfilename )
  {
  long  len;
  char* buf = NULL;
  FILE* fp  = NULL;

  // Open the source file
  fp = fopen( srcfilename, "rb" );
  if (!fp) return 0;

  // Get its length (in bytes)
  if (fseek( fp, 0, SEEK_END ) != 0)  // This should typically succeed
    {                                 // (beware the 2Gb limitation, though)
    fclose( fp );
    return 0;
    }

  len = ftell( fp );
  std::cout << len;
  rewind( fp );
  // Get a buffer big enough to hold it entirely
  buf = (char*)malloc( len );
  if (!buf)
    {
    fclose( fp );
    return 0;
    }

  // Read the entire file into the buffer
  if (!fread( buf, len, 1, fp ))
    {
    free( buf );
    fclose( fp );
    return 0;
    }

  fclose( fp );

  // Open the destination file
  fp = fopen( dstfilename, "wb" );
  if (!fp)
    {
    free( buf );
    return 0;
    }
  // this is where I send data in but over serial port. 
  //serialWrite() is just the standard write() being used
  int fd;
  fd = xserialOpen("/dev/ttyUSB0", 9600);
  serialWrite(fd, buf, len);

   //This is where the file gets copied to another file as a test
  // Write the entire buffer to file
  if (!fwrite( buf, len, 1, fp ))
    {
    free( buf );
    fclose( fp );
    return 0;
    }

  // All done -- return success
  fclose( fp );
  free( buf );
  return 1;
  }

在接收端,我知道我需要打开串行端口来读取和使用某种 read(),但我不知道这是如何完成的。使用串行库,它具有一些功能来检查串行数据是否可用并返回可供读取的字符数。

一个关于可读取字符数的问题,这个数字会随着串行流的到来而增长,还是会立即告诉要读取的数据的整个长度?

但最后,我知道打开串口后,我需要将数据读入缓冲区,然后将该缓冲区写入文件,但我没有任何运气。这是我迄今为止尝试过的。

// Loop, getting and printing characters
char temp;
bool readComplete = false;
int bytesRead = 0;

fp = fopen("copyImage11.jpeg", "rwb");

  for (;;)
  {
        if(xserialDataAvail(fd) > 0)
        {
        bytesRead = serialRead(fd, buf, len);
        readComplete = true;
        }
        if (readComplete)
        {
         if (!fwrite(buf, bytesRead, 1, fp))
         {
         free(buf);
         fclose(fp);
         return 0;
         }

         fclose(fp);
         free(buf);
         return 1;
        }
}

我的代码没有出错,只是没有正确创建 jpeg 文件。也许我没有正确传输它,或者我没有正确读取/写入文件。任何帮助,将不胜感激。谢谢你摇滚的每一个人!

【问题讨论】:

  • 我知道您想使用自己的代码来解决它,但是使用现有的实用程序来解决它不是更简单吗?例如。使用sz 发送文件,使用rz 接收文件,使用ZMODEM 协议。
  • 这是 C 风格与 C++ 特性的糟糕混合。但是,它不是 C 代码。不要为不相关的语言添加标签。
  • free(buf); 吓坏了我。 serialRead 是在分配buf 吗?如果是,我建议不要。你正在打开一罐不必要的蠕虫。如果不是,那么这些bufs 到底是从哪里来的?
  • 在发送方,而不是mallocing 缓冲区,有一个固定大小的缓冲区。读取源文件的缓冲区大小的块并将它们写入串行端口(您确定您没有过度填充串行端口吗?),然后循环返回并读取另一个。这样,如果您错过了free(buf),内存就不会丢失,并且内存碎片问题也会更少。
  • 现在我已经读完了所有这些,如果没有serialReadserialWrite 的信息,这个问题就无法回答。

标签: c++ serial-port raspberry-pi2 transmission


【解决方案1】:

如果你要定义自己的协议,那么你首先需要有一个发送长度的方法。

我建议通过发送一小段 ascii 文本来确认您的 i/o 来测试您的代码。一旦工作正常,您就可以使用 ascii 来设置传输;即发送长度,并让您的接收器为预期的块做好准备。

【讨论】:

    猜你喜欢
    • 2020-09-11
    • 1970-01-01
    • 2021-08-23
    • 1970-01-01
    • 1970-01-01
    • 2010-11-07
    • 1970-01-01
    • 2013-01-09
    • 1970-01-01
    相关资源
    最近更新 更多