STM32
直播中

李华瑞

7年用户 923经验值
私信 关注
[问答]

怎样通过I2C去直接读取PIX4FLOW的数据呢

PIX4FLOW返回有哪几种数据帧呢?
怎样通过I2C去直接读取PIX4FLOW的数据呢?

回帖(1)

张艳梅

2021-11-12 11:29:15
  想通过I2C直接读取pix4flow的数据,结果不好使,找原因。
  找到官网https://pixhawk.org/modules/px4flow#i2c和http://www.pixhawk.com/zh/dev/px4flow,安装了QGC地面站和PX4flow的驱动,详细的如何装驱动https://pixhawk.org/users/px4flow_windows_driver 然后在地面站里看到了图像还有其他的一些数据都挺正常的,至少证明手头这块flow没坏,不过通电的时候有点热是怎么回事。
  以下是一些网页上内容的翻译:
  PX4FLOW模块输出USB和串行端口上的MAVLink包。使用QGroundControl从模块读取数据。还提供了一个用于传感器数据读取的I2C接口。第三方库可以在您的项目中连接和集成PX4FLOW数据。PIX4flow的7位I2C地址是用户可选择的。在模块背面有焊点,8个可选择的地址范围是:0x42 - 0x49。
  PIX4FLOW返回两种不同的数据帧。一种是I2C frame,向PX4FLOW模块发送0x00,能接收返回22字节的数据,内部地址自动增量。
  I2C frame有22个字节,数据结构如下:
  typedef struct i2c_frame
  {
  uint16_t frame_count;// counts created I2C frames [#frames]
  int16_t pixel_flow_x_sum;// latest x flow measurement in pixels*10 [pixels]
  int16_t pixel_flow_y_sum;// latest y flow measurement in pixels*10 [pixels]
  int16_t flow_comp_m_x;// x velocity*1000 [meters/sec]
  int16_t flow_comp_m_y;// y velocity*1000 [meters/sec]
  int16_t qual;// Optical flow quality / confidence [0: bad, 255: maximum quality]
  int16_t gyro_x_rate; // latest gyro x rate [rad/sec]
  int16_t gyro_y_rate; // latest gyro y rate [rad/sec]
  int16_t gyro_z_rate; // latest gyro z rate [rad/sec]
  uint8_t gyro_range; // gyro range [0 。. 7] equals [50 deg/sec 。. 2000 deg/sec]
  uint8_t sonar_timestamp;// time since last sonar update [milliseconds]
  int16_t ground_distance;// Ground distance in meters*1000 [meters]。 Positive value: distance known. Negative value: Unknown distance
  } i2c_frame;
  另一种是 I2C integral frame有25个字节,向PX4FLOW模块发送0x16(22),接收回25字节的数据,内部地址自动增量。数据的结构如下:
  typedef struct i2c_integral_frame
  {
  uint16_t frame_count_since_last_readout;//number of flow measurements since last I2C readout [#frames]
  int16_t pixel_flow_x_integral;//accumulated flow in radians*10000 around x axis since last I2C readout [rad*10000]
  int16_t pixel_flow_y_integral;//accumulated flow in radians*10000 around y axis since last I2C readout [rad*10000]
  int16_t gyro_x_rate_integral;//accumulated gyro x rates in radians*10000 since last I2C readout [rad*10000]
  int16_t gyro_y_rate_integral;//accumulated gyro y rates in radians*10000 since last I2C readout [rad*10000]
  int16_t gyro_z_rate_integral;//accumulated gyro z rates in radians*10000 since last I2C readout [rad*10000]
  uint32_t integration_timespan;//accumulation timespan in microseconds since last I2C readout [microseconds]
  uint32_t sonar_timestamp;// time since last sonar update [microseconds]
  int16_t ground_distance;// Ground distance in meters*1000 [meters*1000]
  int16_t gyro_temperature;// Temperature * 100 in centi-degrees Celsius [degcelsius*100]
  uint8_t quality;// averaged quality of accumulated flow values [0:bad quality;255: max quality]
  } __attribute__((packed)) i2c_integral_frame;
  我暂时觉的我程序并没有写错,虽然之前没有看过官网的介绍,但也看过一些别的帖子的介绍。也有可能时序还是不对,等下去用示波器看看模块的SDA引脚上有没有数据输出吧。
  程序没有写错之前得不到数据是因为在晚上调试,摄像头没有采到特征鲜明的图像,PIX4flow没有能够做出识别。当采到的图像特征比较鲜明,PIX4flow就可以输出数据了,还要注意I2C的时序,PIX4flow用的是STM32的硬件I2C对时序要求比较严格,我用匿名的I2C进行移植就不太好使,用正点原子的I2C做的移植。
  读取函数
  void read_pixflow(void)
  {
  flow_read_data(PX4FLOW_ADDR,0x00,22,pix_flow_buffer);
  flow_data.frame_count= pix_flow_buffer[1]《《8|pix_flow_buffer[0];
  flow_data.pixel_flow_x_sum =pix_flow_buffer[3]《《8|pix_flow_buffer[2];
  flow_data.pixel_flow_y_sum =pix_flow_buffer[5]《《8|pix_flow_buffer[4];
  flow_data.flow_comp_m_x= pix_flow_buffer[7]《《8|pix_flow_buffer[6];
  flow_data.flow_comp_m_y= pix_flow_buffer[9]《《8|pix_flow_buffer[8];
  flow_data.qual= pix_flow_buffer[11]《《8|pix_flow_buffer[10];
  flow_data.gyro_x_rate= pix_flow_buffer[13]《《8|pix_flow_buffer[12];
  flow_data.gyro_y_rate= pix_flow_buffer[15]《《8|pix_flow_buffer[14];
  flow_data.gyro_z_rate= pix_flow_buffer[17]《《8|pix_flow_buffer[16];
  flow_data.gyro_range= pix_flow_buffer[18];
  flow_data.sonar_timestamp= pix_flow_buffer[19];
  flow_data.ground_distance= pix_flow_buffer[21]《《8|pix_flow_buffer[20];
  //printf(“%d %dn”,flow_data.frame_count,flow_data.flow_comp_m_x);
  }
  以及i2c
  void IIC_Init(void)
  {
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//??GPIOB??
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  IIC_SCL=1;
  IIC_SDA=1;
  }
  void IIC_Start(void)
  {
  SDA_OUT();
  IIC_SDA=1;
  Delay_us(1);
  IIC_SCL=1;
  Delay_us(2);
  IIC_SDA=0;
  Delay_us(2);
  IIC_SCL=0;
  }
  void IIC_Stop(void)
  {
  SDA_OUT();
  IIC_SCL=0;
  Delay_us(1);
  IIC_SDA=0;
  Delay_us(2);
  IIC_SCL=1;
  Delay_us(1);
  IIC_SDA=1;
  Delay_us(2);
  }
  u8 IIC_Wait_Ack(void)
  {
  u8 ucErrTime=0;
  SDA_IN();
  IIC_SDA=1;
  Delay_us(1);
  IIC_SCL=1;
  Delay_us(1);
  while(READ_SDA)
  {
  ucErrTime++;
  if(ucErrTime》250)
  {
  IIC_Stop();
  return 1;
  }
  }
  IIC_SCL=0;
  return 0;
  }
  void IIC_Ack(void)
  {
  IIC_SCL=0;
  Delay_us(1);
  SDA_OUT();
  IIC_SDA=0;
  Delay_us(2);
  IIC_SCL=1;
  Delay_us(2);
  IIC_SCL=0;
  }
  void IIC_NAck(void)
  {
  IIC_SCL=0;
  Delay_us(1);
  SDA_OUT();
  IIC_SDA=1;
  Delay_us(2);
  IIC_SCL=1;
  Delay_us(2);
  IIC_SCL=0;
  }
  void IIC_Send_Byte(u8 txd)
  {
  u8 t;
  SDA_OUT();
  IIC_SCL=0;
  for(t=0;t《8;t++)
  {
  IIC_SDA=(txd&0x80)》》7;
  txd《《=1;
  Delay_us(2);
  IIC_SCL=1;
  Delay_us(2);
  IIC_SCL=0;
  Delay_us(2);
  }
  }
  u8 IIC_Read_Byte(unsigned char ack)
  {
  unsigned char i,receive=0;
  SDA_IN();
  for(i=0;i《8;i++ )
  {
  IIC_SCL=0;
  Delay_us(2);
  IIC_SCL=1;
  receive《《=1;
  if(READ_SDA)
  receive++;
  Delay_us(2);
  }
  if (!ack)
  IIC_NAck();
  else
  IIC_Ack();
  return receive;
  }
举报

更多回帖

发帖
×
20
完善资料,
赚取积分