想通过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;
}
想通过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;
}
举报