Home→Forums→MonoBrick EV3 Firmware→How to use AbsoluteIMU-ACG sensor?
- This topic has 10 replies, 4 voices, and was last updated 10 years, 1 month ago by Anders Søborg.
-
AuthorPosts
-
October 29, 2014 at 13:14 #4937
Andreas BoerzelParticipantI have a AbsoluteIMU-ACG sensor, which combines gyrometer, accelerometer and compass in one sensor. For my project I want to use this sensor with the MonoBrick library, but it seems not to be supported yet. Does anyone know how to use the AbsoluteIMU-ACG sensor with MonoBrick?
I’m grateful for any hint or tip!
Andreas- This topic was modified 10 years, 2 months ago by Andreas Boerzel.
- This topic was modified 10 years, 2 months ago by Andreas Boerzel.
- This topic was modified 10 years, 2 months ago by Andreas Boerzel.
October 29, 2014 at 19:32 #4941
Tcm0ParticipantYour sensor is an I2C sensor. You can find information about the usage of an I2C sensor at https://github.com/Larsjep/monoev3/blob/release/MonoBrickFirmware/Sensors/HTColorSensor.cs. Other information about the adresses to be read etc. can be found in the official sourcecode for the NXC library: http://www.mindsensors.com/index.php?module=documents&JAS_DocumentManager_op=viewDocument&JAS_Document_id=198 (IMU-lib.nxc). The adress of the I2C sensor appears to be 0x22 as you can find in the demo (IMU-demo.nxc).
October 30, 2014 at 15:52 #4942
Andreas BoerzelParticipantThank you very much for your answer, I think it’s the right way. I tried to implement my own sensor-class, see code below. But my test program reads only invalid and constant values.
Does anyone know what’s wrong with my sensor implementation?
Thanks,
Andreaspublic class AbsoluteIMU_ACGSensor : I2CSensor { private const byte ADDRESS = 0x22; private enum I2CRegisters : byte { Command = 0x41, XGyroDataLSB = 0x53, XGyroDataMSB = 0x54, YGyroDataLSB = 0x55, YGyroDataMSB = 0x56, ZGyroDataLSB = 0x57, ZGyroDataMSB = 0x58 }; private static int MLBToInteger(byte lsb, byte msb) { return (int)lsb + ((int)msb << 8); } public AbsoluteIMU_ACGSensor(SensorPort port) : base(port, ADDRESS, I2CMode.LowSpeed) { base.Initialise(); } public GyroData ReadGyro() { LcdConsole.WriteLine("ReadGyro..."); byte[] result = ReadRegister((byte)I2CRegisters.XGyroDataLSB, 6); LcdConsole.WriteLine("{0}, {1}, {2}, {3}, {4}, {5}", result[0], result[1], result[2], result[3], result[4], result[5]); return new GyroData(result); } public class GyroData { public GyroData(byte[] rawData) { X = MLBToInteger(rawData[0], rawData[1]); Y = MLBToInteger(rawData[2], rawData[3]); Z = MLBToInteger(rawData[4], rawData[5]); } public int X { get; private set; } public int Y { get; private set; } public int Z { get; private set; } };
Testprogram:
class Program { static void Main(string[] args) { var buts = new ButtonEvents(); LcdConsole.WriteLine("Starting..."); var gyroSensor = new AbsoluteIMU_ACGSensor(SensorPort.In2); gyroSensor.SendCommand((byte)AbsoluteIMUCommands.ChangeAccelerometerSensitivityTo2G); bool end = false; buts.EscapePressed += () => { end = true; LcdConsole.WriteLine("Stopping..."); }; while (!end) { // LcdConsole.Clear(); var result = gyroSensor.ReadGyro(); LcdConsole.WriteLine("GX: {0}", result.X); LcdConsole.WriteLine("GY: {0}", result.Y); LcdConsole.WriteLine("GZ: {0}", result.Z); Thread.Sleep(250); } }
The AbsoluteIMU-User-Guide describes the I2C-registers.
October 30, 2014 at 17:46 #4943
Tcm0ParticipantIt may use the 9V I2C Sensor mode.
October 31, 2014 at 07:53 #4944
Andreas BoerzelParticipantI also tried sensor mode LowSpeed9V, but with the same result.
October 31, 2014 at 17:43 #4945
Tcm0ParticipantCould you please try the following code?
using System; using MonoBrickFirmware.Sensors; namespace MonoBrickHelloWorld { public class MindsensorsAbsoluteIMU : I2CSensor { public MindsensorsAbsoluteIMU (SensorPort Port) : base (Port, (byte)0x22, I2CMode.LowSpeed) { base.Initialise (); } public void ChangeAccelerometerSensitivity (string Sensitivity) { byte[] BytesToWrite = {(byte)0}; if (Sensitivity == "2G" || Sensitivity == "2g") BytesToWrite[0] = (byte) 0x31; else if (Sensitivity == "4G" || Sensitivity == "4g") BytesToWrite[0] = (byte) 0x32; else if (Sensitivity == "8G" || Sensitivity == "8g") BytesToWrite[0] = (byte) 0x33; else if (Sensitivity == "16G" || Sensitivity == "16g") BytesToWrite[0] = (byte) 0x34; else throw new ArgumentException(); base.WriteRegister((byte)0x22, BytesToWrite); return; } public byte[] ReadX () { return(base.ReadRegister ((byte)0x42, 8)); } public byte[] ReadY () { return(base.ReadRegister ((byte)0x43, 8)); } public byte[] ReadZ () { return(base.ReadRegister ((byte)0x44, 8)); } public override string ReadAsString() { return("X: " + Convert.ToString(base.ReadRegister(0x42)) + " Y: " + Convert.ToString(base.ReadRegister(0x43)) + " Z: " + Convert.ToString(base.ReadRegister(0x44))); } public override void SelectNextMode() { return; } public override void SelectPreviousMode() { return; } public override string GetSensorName() { return (Convert.ToString (base.ReadRegister ((byte)0x10, (byte)0x07))); } public override int NumberOfModes() { return 1; } public override string SelectedMode() { return ("Mode 1"); } } }
using System; using MonoBrickFirmware; using MonoBrickFirmware.Display; using MonoBrickFirmware.UserInput; using System.Threading; using MonoBrickFirmware.Sensors; namespace MonoBrickHelloWorld { class MainClass { public static void Main (string[] args) { EventWaitHandle stopped = new ManualResetEvent (false); MindsensorsAbsoluteIMU NewSensor = new MindsensorsAbsoluteIMU (SensorPort.In1); ButtonEvents buts = new ButtonEvents (); buts.EscapePressed += () => { stopped.Set (); }; buts.EnterPressed += () => { LcdConsole.WriteLine(NewSensor.ReadAsString()); }; LcdConsole.WriteLine ("Hello World"); stopped.WaitOne (); } } }
(Why can’t we attach .cs files?)
- This reply was modified 10 years, 1 month ago by Tcm0.
November 2, 2014 at 08:35 #4947
Filip KirschnerParticipantHi everyone!
I seem to have bumped into this problem as well, however with different sensor, the Mindsensors GlideWheel. It seems to me that the base.ReadRegister(register, length) method doesn’t do what it is supposed to do and returns constant value. The value seems to be the beginning register number in the first byte. I’m investigating the issue futher, but as I am quite inexperienced in working with registers, it may take a while.
Help anyone?
Cheers!November 2, 2014 at 17:10 #4951
Andreas BoerzelParticipantHi,
I tried the sample code from Max, but it’s the same resultbyte[] ReadRegister(byte register, byte rxLength)
returns only the first byte and all other bytes are zero, exactly as described by Filip. I really want to use this sensor with MonoBrick and I am willing to provide a sensor implementation, but my knowledge regarding I2C devices are not sufficient for this purpose. Can someone help me?Thanks!
November 3, 2014 at 10:41 #4954
Tcm0Participant“Try to read 8 bytes instead of four. I found that some sensors only supports read 8 bytes at a time. If this does not work try to read a single byte.” (Anders Søborg)
November 3, 2014 at 20:06 #4956
Andreas BoerzelParticipantHi Max,
I’ve tried both, but without success…November 3, 2014 at 21:29 #4957
Anders SøborgParticipantWe are trying to deal with the same issue in two different threads. Look at the last answer that i posted here and post in this thread instead.
/Anders
-
AuthorPosts
You must be logged in to reply to this topic.
Follow