How to use AbsoluteIMU-ACG sensor?

HomeForumsMonoBrick EV3 FirmwareHow to use AbsoluteIMU-ACG sensor?

This topic contains 10 replies, has 4 voices, and was last updated by Author Image Anders Søborg 2 years, 7 months ago.

Viewing 11 posts - 1 through 11 (of 11 total)
  • Author
    Posts
  • #4937
    Author Image
    Andreas Boerzel
    Participant

    I 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

    #4941
    Author Image
    Tcm0
    Participant

    Your 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 0×22 as you can find in the demo (IMU-demo.nxc).

    #4942
    Author Image
    Andreas Boerzel
    Participant

    Thank 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,
    Andreas

     public 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.

    #4943
    Author Image
    Tcm0
    Participant

    It may use the 9V I2C Sensor mode.

    #4944
    Author Image
    Andreas Boerzel
    Participant

    I also tried sensor mode LowSpeed9V, but with the same result.

    #4945
    Author Image
    Tcm0
    Participant

    Could 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 2 years, 7 months ago by Author Image Tcm0.
    #4947
    Author Image
    Filip Kirschner
    Participant

    Hi 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!

    #4951
    Author Image
    Andreas Boerzel
    Participant

    Hi,
    I tried the sample code from Max, but it’s the same result byte[] 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!

    #4954
    Author Image
    Tcm0
    Participant

    “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)

    #4956
    Author Image
    Andreas Boerzel
    Participant

    Hi Max,
    I’ve tried both, but without success…

    #4957
    Author Image
    Anders Søborg
    Participant

    We 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

Viewing 11 posts - 1 through 11 (of 11 total)

You must be logged in to reply to this topic.

Posted in

Make a donation