solution for LG GM750 accelerometer

Feb 3, 2010 at 3:09 PM

This solution is based on the Samsung sensor class, modified to meet the peculiarities of the LG GM750.

 First of all, the import of the DeviceIoControl in NativeMethods.cs must be modified such way dwIoControlCode is type uint, and the buffers are byte:

 [DllImport("coredll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool DeviceIoControl(IntPtr hDevice, uint dwIoControlCode, [In] byte[] inBuffer, int nInBufferSize, [Out] byte[] outBuffer, int nOutBufferSize, ref int pBytesReturned, IntPtr lpOverlapped);
After a long time dissassembling the accelsensor.dll and and a lot of trial and error testing I came to this conclusion that works:
The constant that starts/stops data output becomes:
        const uint ACCOnRot = 0x1014EE8;
        const uint ACCOffRot = 0x1014EE8;
and for reading values:
const uint ACCReadValues = 0x1014F10;
The difference between start and stop comes from the input given in DeviceIoControl method as follows:
        public static LGAccSensor Create()
        {
            DeviceIoControl(ACCOnRot, new byte[1] {1}, new byte[4] );
            return new LGAccSensor();
        }
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            DeviceIoControl(ACCOffRot, new byte[1] {0}, new byte[1] );
        }
The DeviceIoControl inside the accelerometer class becomes
 public static void DeviceIoControl(uint controlCode, byte[] inBuffer, byte[] outBuffer)
        {


                IntPtr file = NativeMethods.CreateFile("ACC1:", 0, 0, IntPtr.Zero, ECreationDisposition.OpenExisting, 0, IntPtr.Zero);
                if (file == (IntPtr)(-1))
                    throw new InvalidOperationException("Unable to Create File");

                try
                {

                    int bytesReturned = 0;
                    int inSize = sizeof(byte) * inBuffer.Length;
                    int outSize = sizeof(byte) * outBuffer.Length;
                    if (!NativeMethods.DeviceIoControl(file, controlCode, inBuffer, inSize, outBuffer, outSize, ref bytesReturned, IntPtr.Zero))
                            throw new InvalidOperationException("Unable to perform operation.");

                  
                }

                finally
                {
                    NativeMethods.CloseHandle(file);
                }      
        }
Note that the accelerometer device is called ACC1:.
Further the method that returns the three component vector becomes
        public override GVector GetGVector()
        {
            byte[] outBuffer = new byte[4];
            DeviceIoControl(ACCReadValues, new byte[1] {1}, outBuffer);
            GVector ret = new GVector();
          
            
            int accx = outBuffer[2];
            if (accx <=31)
                ret.X = accx/2.17;
            else
                ret.X = (accx-64)*0.47;
            ret.X = -ret.X;
            int accy = outBuffer[1] ;
            if (accy <=31)
                ret.Y =  accy/2.17;
            else
                ret.Y = (accy - 64) * 0.47;

            int accz = outBuffer[0] ;
            if (accz <=31)
                ret.Z = accz/2.17;
            else
                ret.Z = (accz - 64) * 0.47;
            double somefactor = 1;
            return ret.Scale(somefactor);
        }
Note that the when called with AccReadValues parameter, the DeviceIoControl returns three bytes each of them containing a signed 6 bit 2's complement value.
Basicly there are values on 6 bit ranging from -32 to +31. In the docs below there are tables that put in correspondence these values with acceleration in range -1.5g +1.5g which are the limits of the device. The code I wrote returns acceleration in meters/second2 where 1g=9.8 m/s2
That information I extracted from the technical specifications of the MMA7660FC accelerometer, as found at
http://www.comtech.com.cn/pdf/FSL-MMA7660FC.pdf. Also, the type of the accelerometer circuit is found in the service manual (I only found the service manual for LG GM730 which is pretty close).
Please, update the library with this code.
Enjoy!