Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
与Arduino和Python的慢速串行通信_Python_Arduino_Hex_Jpeg_Spresense - Fatal编程技术网

与Arduino和Python的慢速串行通信

与Arduino和Python的慢速串行通信,python,arduino,hex,jpeg,spresense,Python,Arduino,Hex,Jpeg,Spresense,在我的一个项目中,我必须从一个连接到Sony Spresense Arduino板的相机上拍照,该板通过USB端口连接到我的电脑。我在Arduino和串行通信方面不是很有经验,事实上一点也没有,所以我请求一些帮助 我想从相机中读取数据,该数据以十六进制形式从Arduino通过串口发送到我的计算机。以给定的波特率开始,由Python程序处理,以收集十六进制代码,纠正它(出现了一些打印错误,现已解决),并将其转换为JPEG图像。 我能够做到这一点,但我的程序中Python从Arduino收集数据的串

在我的一个项目中,我必须从一个连接到Sony Spresense Arduino板的相机上拍照,该板通过USB端口连接到我的电脑。我在Arduino和串行通信方面不是很有经验,事实上一点也没有,所以我请求一些帮助

我想从相机中读取数据,该数据以十六进制形式从Arduino通过串口发送到我的计算机。以给定的波特率开始,由Python程序处理,以收集十六进制代码,纠正它(出现了一些打印错误,现已解决),并将其转换为JPEG图像。 我能够做到这一点,但我的程序中Python从Arduino收集数据的串行通信部分速度非常慢,需要34秒才能以115200的波特率获得一个“仅”100KO的图像(我不知道对于Arduino来说这是否太难处理)。如果我试图增加这个数字,收集到的十六进制代码会显示一些错误,并且图像无法转换。我也可以更改图像的像素分辨率,但我希望能够处理高清图片

具体来说,这是Arduino的代码,我没有找到其他方法从相机获取数据(Spresense库中没有设计用于串行通信的函数)。相关部分在末尾:


#include <SDHCI.h>
#include <stdio.h>  /* for sprintf */

#include <Camera.h>

#define BAUDRATE                (115200)

/**
 * Print error message
 */

void printError(enum CamErr err)
{
  Serial.print("Error: ");
  switch (err)
    {
      case CAM_ERR_NO_DEVICE:
        Serial.println("No Device");
        break;
      case CAM_ERR_ILLEGAL_DEVERR:
        Serial.println("Illegal device error");
        break;
      case CAM_ERR_ALREADY_INITIALIZED:
        Serial.println("Already initialized");
        break;
      case CAM_ERR_NOT_INITIALIZED:
        Serial.println("Not initialized");
        break;
      case CAM_ERR_NOT_STILL_INITIALIZED:
        Serial.println("Still picture not initialized");
        break;
      case CAM_ERR_CANT_CREATE_THREAD:
        Serial.println("Failed to create thread");
        break;
      case CAM_ERR_INVALID_PARAM:
        Serial.println("Invalid parameter");
        break;
      case CAM_ERR_NO_MEMORY:
        Serial.println("No memory");
        break;
      case CAM_ERR_USR_INUSED:
        Serial.println("Buffer already in use");
        break;
      case CAM_ERR_NOT_PERMITTED:
        Serial.println("Operation not permitted");
        break;
      default:
        break;
    }
}

void CamCB(CamImage img)
{

  /* Check the img instance is available or not. */

  if (img.isAvailable())
    {

      /* If you want RGB565 data, convert image data format to RGB565 */

      img.convertPixFormat(CAM_IMAGE_PIX_FMT_RGB565);

    }
  else
    {
      Serial.print("Failed to get video stream image\n");
    }
}

/**
 * @brief Initialize camera
 */
void setup()
{
  CamErr err;

  /* Open serial communications and wait for port to open */

  Serial.begin(BAUDRATE);
  while (!Serial)
    {
      ; /* wait for serial port to connect. Needed for native USB port only */
    }


  /* begin() without parameters means that
   * number of buffers = 1, 30FPS, QVGA, YUV 4:2:2 format */

  Serial.println("Prepare camera");
  err = theCamera.begin();
  if (err != CAM_ERR_SUCCESS)
    {
      printError(err);
    }

  /* Start video stream.
   * If received video stream data from camera device,
   *  camera library call CamCB.
   */

  Serial.println("Start streaming");
  err = theCamera.startStreaming(true, CamCB);
  if (err != CAM_ERR_SUCCESS)
    {
      printError(err);
    }

  /* Auto white balance configuration */

 // Serial.println("Set Auto white balance parameter");
  err = theCamera.setAutoWhiteBalanceMode(CAM_WHITE_BALANCE_DAYLIGHT);
  if (err != CAM_ERR_SUCCESS)
    {
      printError(err);
    }

  /* Set parameters about still picture.
   * In the following case, QUADVGA and JPEG.
   */

  Serial.println("Set still picture format");
//  err = theCamera.setStillPictureImageFormat(
//     CAM_IMGSIZE_QUADVGA_H,
//     CAM_IMGSIZE_QUADVGA_V,
//     CAM_IMAGE_PIX_FMT_JPG);
    //err = theCamera.setStillPictureImageFormat(320, 240, CAM_IMAGE_PIX_FMT_JPG);
    err = theCamera.setStillPictureImageFormat(CAM_IMGSIZE_QUADVGA_H, CAM_IMGSIZE_QUADVGA_V, CAM_IMAGE_PIX_FMT_JPG);
  if (err != CAM_ERR_SUCCESS)
    {
      printError(err);
    }


/**
 * @brief Take picture with format JPEG per second
 */
/******** Affichage serie ********/
/* une ligne de vide et l'image */
  Serial.println(" ");
  CamImage img = theCamera.takePicture();

  /* Check availability of the img instance. */
  /* If any error was occured, the img is not available. */

  if (img.isAvailable())
    {
        /*Indicateur de debut img : FFD8FF (Magic number of the jpeg format) */      

       for(int i=0;i<img.getImgSize();i++)
       {
        Serial.print(*(img.getImgBuff()+i),HEX); //img.getImgBuff() gets the data address of the picture, so the * before.
        Serial.print(";");
       }


        /*End indicator : FFD9FF (Magic number of jpeg format) */

    }

}

void loop() 
{

  // put your main code here, to run repeatedly:
  sleep(1);
}

如果你有任何想法或任何建议,以加快这一进程,我接受它。我听说到处都有一些流控制和缓冲区的故事,但当我试图找到与我的情况相关的东西时,我完全不知所措。提前感谢。

这里不太可能有什么问题,但是您应该真正使用上下文管理器来处理Python代码中的所有文件对象。这只是一个猜测-与Pi相比,Arduino的内部内存非常少。我认为,对于图像所需的处理速度,Arduino根本不够好。对于类似的东西,我会直接将相机连接到Pi,然后从那里进行图像处理。这不太可能是一个问题,但您应该真正使用上下文管理器来处理Python代码中的所有文件对象。这只是一个猜测-与Pi相比,Arduino的内部内存非常少。我认为,对于图像所需的处理速度,Arduino根本不够好。对于类似的东西,我会直接将相机连接到Pi,然后从那里进行图像处理。
## Serial collecting the data of the picture taken by the camera

import serial
from serial import Serial

import binascii
import string

from PIL import Image

import time
start_time = time.time()



ser = serial.Serial('COM3', baudrate=115200, timeout=1)

# writing the data in a text file
data = open("data.txt", "w")
data.write(str(ser.readlines()))

## Correcting the data

data = open("data.txt", "r")

string = str(data.readlines())


# spliting the string into a list
# I chose to use the ";" to split the different hex couples in the Arduino program
tab=string.split(";")

tab[0] = 'FF'
tab.pop(-1)

N = len(tab)

# correcting the arguments that are not couples :
# Indeed, when Arduino encounter a couple starting with a 0,
# it omits it, so I have to add it back manually
for i in range(N):
    if len(tab[i]) == 1:
        tab[i] = '0' + tab[i]


newdata = open("newdata.txt", "w")

# writing the new data in a text file
for s in tab:
    newdata.write(s)

newdata.close()
data.close()

## Converting the hex data into a JPEG file

file = open("newdata.txt", "r")
data= file.read()

# conversion
data = binascii.a2b_hex(data)

# creation of the JPEG file
with open('imagenew.jpg', 'wb') as image_file:
    image_file.write(data)


file.close()


img = Image.open('imagenew.jpg')
img.show()

print("--- %s seconds ---" % (time.time() - start_time))