Gadgeteer Accelerometer bug

Hello GHI experts,

I’m using Raptor with accelerometer module and there’s a problem with the Z axis data (only positive and wrong values).

I already opened a topic for that,
You said I need to use the software i2c library.
I tried to do it but no success. There is no documentation for that.
This is not ok.
We bought a bounch of accelerometers (more than 10 pcs) but non of them works.

One of two:

  1. Guide me step by step how to fix the bug with the software solution
  2. Return the damaged modules

Thanks,
Yaakov.

P.s. - Does the G248 accelerometer has the same issue?

@ yakov.morgen -

Hi,

Both are no issue. But I have worked on G248 more than Seed accelerometers so I am ready to help you on G248 if I can.

on G400, G248 can work both hardwareI2C or softwareI2C. But if you want to see how softwareI2C work, I am also willing to help.

Frist, should take a look on how to change gadgeteer driver module

https://www.ghielectronics.com/docs/122/gadgeteer-driver-modification

then modify the G248 driver as below:

using System;
using Microsoft.SPOT;

using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using GTI = Gadgeteer.Interfaces;

using GHI.Premium.Hardware;
using Microsoft.SPOT.Hardware;
namespace Gadgeteer.Modules.GHIElectronics
{
    // -- CHANGE FOR MICRO FRAMEWORK 4.2 --
    // If you want to use Serial, SPI, or DaisyLink (which includes GTI.SoftwareI2C), you must do a few more steps
    // since these have been moved to separate assemblies for NETMF 4.2 (to reduce the minimum memory footprint of Gadgeteer)
    // 1) add a reference to the assembly (named Gadgeteer.[interfacename])
    // 2) in GadgeteerHardware.xml, uncomment the lines under <Assemblies> so that end user apps using this module also add a reference.

    /// <summary>
    /// A Accel G248 module for Microsoft .NET Gadgeteer
    /// </summary>
    public class Accel_G248 : GTM.Module
    {
        //private GTI.I2CBus i2c;

        /// <summary>Constructor</summary>
        /// <param name="socketNumber">The socket that this module is plugged in to.</param>
        static SoftwareI2CBus softwarei2cBus;
        static SoftwareI2CBus.I2CDevice softwarei2cDevice;
        const int SDA_PIN = 0; // need to change with your socket, at pin 8
        const int SCL_PIN = 0; // need to change with your socket, at pin 9
        public Accel_G248(int socketNumber)
        {
            Socket socket = Socket.GetSocket(socketNumber, true, this, null);

            socket.EnsureTypeIsSupported('I', this);

            //i2c = new GTI.I2CBus(socket, 0x1C, 400, this);
            softwarei2cBus = new SoftwareI2CBus((Cpu.Pin)SCL_PIN, (Cpu.Pin)SDA_PIN); //add your sda, scl 
            softwarei2cDevice = softwarei2cBus.CreateI2CDevice(0x1C, 100);

            WriteRegister(0x2A, 1);
        }

        private void WriteRegister(byte reg, byte value)
        {
           
            byte[] RegisterNum = new byte[2] { reg, value };
            //i2c.Write(RegisterNum, 1000);
            softwarei2cDevice.Write(RegisterNum, 0, RegisterNum.Length);
           
        }

        private byte[] ReadRegister(byte reg, int readcount)
        {
            int numWrite;
            int numRead;
            byte[] RegisterNum = new byte[1] { reg };

            // create read buffer to read the register
            byte[] RegisterValue = new byte[readcount];
 
            //i2c.WriteRead(RegisterNum, RegisterValue, 1000);
            softwarei2cDevice.WriteRead(RegisterNum, 0, RegisterNum.Length, RegisterValue, 0, RegisterValue.Length, out numWrite, out numRead);

            return RegisterValue;
        }

        /// <summary>
        /// Returns X acceleration. 
        /// </summary>
        /// <returns>X acceleration</returns>
        public int GetX()
        {
            byte[] test = ReadRegister(0x1, 2);

            int X = test[0] << 2 | test[1] >> 6 & 0x3F;

            if (X > 511)
                X = X - 1024;

            return X;
        }

        /// <summary>
        /// Returns Y acceleration.
        /// </summary>
        /// <returns>Y acceleration</returns>
        public int GetY()
        {
            byte[] test = ReadRegister(0x3, 2);

            int Y = test[0] << 2 | test[1] >> 6 & 0x3F;

            if (Y > 511)
                Y = Y - 1024;

            return Y;
        }

        /// <summary>
        /// Returns Z acceleration.
        /// </summary>
        /// <returns>Z acceleration</returns>
        public int GetZ()
        {
            byte[] test = ReadRegister(0x5, 2);

            int Z = test[0] << 2 | test[1] >> 6 & 0x3F;

            if (Z > 511)
                Z = Z - 1024;

            return Z;
        }

        /// <summary>
        /// Obtains the X, Y, and Z accelerations.
        /// </summary>
        /// <param name="X"></param>
        /// <param name="Y"></param>
        /// <param name="Z"></param>
        public void GetXYZ(out int X, out int Y, out int Z)
        {
            byte[] test = ReadRegister(0x1, 6);

            X = test[0] << 2 | test[1] >> 6 & 0x3F;
            Y = test[2] << 2 | test[3] >> 6 & 0x3F;
            Z = test[4] << 2 | test[5] >> 6 & 0x3F;

            if (X > 511)
                X -= 1024;

            if (Y > 511)
                Y -= 1024;

            if (Z > 511)
                Z -= 1024;
        }
    }
}

You can compare with original file to see what I changed, then you will know how to change from hardwareI2C to softwareI2C, than do same way for Seed accelerometer.

Just a note here is, Accel G248 when read, need repeat start condition, so when read, should use WriteRead function.

I also have test code in NETMF without gadgeeter for G248, in case you want to test only G248.