PIX4flow使用记录

来源:互联网 发布:js 取数组前几个 编辑:程序博客网 时间:2024/05/29 03:48

想通过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 %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; }
原创粉丝点击