PIX4flow使用记录

想通过I2C直接读取pix4flow的数据,结果不好使,找原因。
找到官网https://pixhawk.org/modules/px4flow#i2chttp://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 %d\n",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;
 }
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值