我正在尝试使用C#和mono与覆盆子pi上的IMU传感器(BNO055)进行通信。无论我做什么,我都无法成功读写传感器。有经验的人可以让我知道这样做的正确方法是什么?感谢。
初始化:
private void ConnectToBNO055()
{
GPIO.Write(ResetPin, true);
Task.Delay(650).Wait();
Port = new SerialPort();
Port.PortName = PortName;
Port.BaudRate = 115200;
Port.Parity = Parity.None;
Port.DataBits = 8;
Port.StopBits = StopBits.One;
Port.Handshake = Handshake.None;
Port.ReadTimeout = 5000;
Port.WriteTimeout = 5000;
try
{
Port.Open();
while (!Port.IsOpen) { Task.Delay(1).Wait(); }
SetMode(OperationMode.OPERATION_MODE_CONFIG);
WriteRegister((byte)PageIDRegisterDefinition.BNO055_PAGE_ID_ADDR, 0, false);
byte chipID = ReadRegister((byte)PageRegisterDefinitionStart.BNO055_CHIP_ID_ADDR);
if ((byte)I2CAddress.BNO055_ID == chipID)
{
Reset();
WriteRegister((byte)ModeRegisters.BNO055_PWR_MODE_ADDR, (byte)PowerMode.POWER_MODE_NORMAL);
WriteRegister((byte)ModeRegisters.BNO055_SYS_TRIGGER_ADDR, 0x0);
SetMode(OperationMode.OPERATION_MODE_NDOF);
Connected = true;
Console.WriteLine("Connected to IMU.");
Console.WriteLine("Calibrating IMU. . .");
BNO055.CalibrationStatus lastCal;
BNO055.CalibrationStatus cal = GetCalibrationStatus();
Console.WriteLine("System: " + cal.System.ToString() + ", Magnometer: " + cal.Mag.ToString() + ", Gyroscope: " + cal.Gyro.ToString() + ", Accelerometer: " + cal.Accel.ToString());
while (cal.System != 3 || cal.Mag != 3 || cal.Gyro != 3 || cal.Accel != 3)
{
Task.Delay(250).Wait();
lastCal = cal;
cal = GetCalibrationStatus();
if (cal.Accel != lastCal.Accel || cal.Gyro != lastCal.Gyro || cal.Mag != lastCal.Mag || cal.System != lastCal.System)
{
Console.WriteLine("System: " + cal.System.ToString() + ", Magnometer: " + cal.Mag.ToString() + ", Gyroscope: " + cal.Gyro.ToString() + ", Accelerometer: " + cal.Accel.ToString());
}
}
Calibrated = true;
Console.WriteLine("IMU Calibrated.");
}
else
{
Console.WriteLine("Unable to connect to IMU.");
}
}
catch (Exception)
{
Console.WriteLine("Unable to connect to IMU.");
}
}
IO方法:
private void WriteRegister(byte address, byte data, bool ack = true)
{
byte[] writeBuffer = new byte[] { 0xAA, 0x00, address, 1, data };
byte[] response;
try
{
response = WriteData(writeBuffer, ack);
if (ack)
{
if (0xEE01 != (response[0] << 8 | response[1]))
throw new Exception(string.Format("WriteRegister returned 0x{0:x2},0x{1:x2}", response[0], response[1]));
}
}
catch (Exception ex)
{
Console.WriteLine(string.Format("WriteRegister error: {0}", ex.Message));
}
}
private byte ReadRegister(byte register)
{
byte[] commandBuffer = new byte[] { 0xAA, 0x01, register, 1 };
byte[] readBuffer = new byte[1];
try
{
readBuffer = ReadData(commandBuffer, 1);
}
catch (Exception ex)
{
Console.WriteLine(string.Format("ReadRegister error: {0}", ex.Message));
}
return readBuffer[0];
}
private byte[] WriteData(byte[] command, bool ack = true, int retries = 5)
{
byte[] ackBuffer = new byte[2];
bool done = false;
while ((!done) && (retries-- > 0))
{
Port.Write(command, 0, command.Length);
if (ack)
{
while (Port.BytesToRead != 2) { Task.Delay(1).Wait(); }
Port.Read(ackBuffer, 0, 2);
done = 0xEE07 != (ackBuffer[0] << 8 | ackBuffer[1]);
}
else
done = true;
}
if (!done)
throw new Exception("WriteData retries exceeded");
return ackBuffer;
}
private byte[] ReadData(byte[] command, int readLength)
{
byte[] headerBuffer = new byte[2];
byte[] returnBuffer = new byte[readLength];
Port.Write(command, 0, command.Length);
while (Port.BytesToRead != 2) { Task.Delay(1).Wait(); }
Port.Read(headerBuffer, 0, 2);
if (headerBuffer[0] != 0xBB)
throw new Exception(string.Format("ReadData error 0x{0:x2}{1:x2}", headerBuffer[0], headerBuffer[1]));
if (headerBuffer[1] != readLength)
throw new Exception(string.Format("ReadData error: failed to read {0} bytes. Read {1}", readLength, headerBuffer[1]));
while (Port.BytesToRead != readLength) { Task.Delay(1).Wait(); }
Port.Read(returnBuffer, 0, readLength);
return returnBuffer;
}
答案 0 :(得分:0)
这里的问题是我在写入数据后立即尝试从传感器读取响应。要解决此问题,请添加一个等待BytesToRead属性的循环,使其等于所需的响应长度,然后再读取。