Main Site Documentation

Accelerometer - SMB380


#1

I’ve got an SMB380 - On the +/-2g my Z-axis seems to rest at -0.5g; the X and Y rest fairly closely to 0. Is there a recalibration procedure I can do on the board?


#2

Your code should calibrate the accelerometer.

If you are indeed getting 0.5g on the Z axis, you may have the accelerometer set to 4g, or your m/s/s per Volts is not correct for the 2g setting.

Can you show us your code.


#3

    public sealed class SMB380
    {
        public enum GRange : byte
        {
            G2 = 0x00,
            G4 = 0x01,
            G8 = 0x10
        }

        public enum FilterBandwidth : short
        {
            Hz25 = 0x000,
            Hz50 = 0x001,
            Hz100 = 0x010,
            Hz190 = 0x011,
            Hz375 = 0x100,
            Hz750 = 0x101,
            Hz1500 = 0x110
        }

        #region Fields
        private SPI spi;
        private byte[] read = new byte[2];
        private byte[] write = new byte[2];

        private GRange _range = GRange.G4;
        #endregion Fields

        #region Constructor
        static SMB380()
        {
            Instance = new SMB380();
        }

        private SMB380()
        {
            spi = new SPI(new SPI.Configuration((Cpu.Pin)FEZ_Pin.Digital.UEXT10, false, 0, 0, true, true, 200, SPI.SPI_module.SPI2));
        }
        #endregion Constructor

        #region Properties
        /// <summary>
        /// Gets the current instance of the SMB380
        /// </summary>
        public static SMB380 Instance { get; private set; }

        /// <summary>
        /// Gets the Acceleration in the X-direction
        /// </summary>
        public float AccelerationX
        {
            get
            {
                short lsb = (sbyte)ReadRegister(0x02);
                short msb = (sbyte)ReadRegister(0x03);
                return ExtractAcceleration(lsb, msb);
            }
        }

        /// <summary>
        /// Gets the Acceleration in the Y-direction
        /// </summary>
        public float AccelerationY
        {
            get
            {
                short lsb = (sbyte)ReadRegister(0x04);
                short msb = (sbyte)ReadRegister(0x05);
                return ExtractAcceleration(lsb, msb);
            }
        }

        /// <summary>
        /// Gets the Acceleration in the Z-direction
        /// </summary>
        public float AccelerationZ
        {
            get
            {
                short lsb = (sbyte)ReadRegister(0x06);
                short msb = (sbyte)ReadRegister(0x07);
                return ExtractAcceleration(lsb, msb);
            }
        }

        public GRange Range
        {
            get
            {
                return _range;
            }
            set
            {
                _range = value;
                byte val = ReadRegister(0x14);//xxx Range(2) Bandwidth(3)
                val &= (byte)(0xE7 | ((byte)value << 3));
                WriteRegister(0x14, val);
            }
        }

        public FilterBandwidth Bandwidth
        {
            get
            {
                return (FilterBandwidth)(ReadRegister(0x14) & 0x07);
            }
            set
            {
                byte val = ReadRegister(0x14);//xxx Range(2) Bandwidth(3)
                val &= (byte)(0xF8 | (byte)value);
                WriteRegister(0x14, val);
            }
        }
        #endregion Properties

        #region Private Helpers
        private byte ReadRegister(byte address)
        {
            write[0] = (byte)(0x80 | address);
            write[1] = 0xFF;
            spi.WriteRead(write, read);
            return read[1];
        }

        private void WriteRegister(byte address, byte value)
        {
            write[0] = address;
            write[1] = value;
            spi.WriteRead(write, read);
        }

        private float ExtractAcceleration(short lsb, short msb)
        {
            float multiplier = Range == GRange.G8 ? 8.0f : Range == GRange.G4 ? 4.0f : 2.0f;
            return (float)(((((short)((msb << 2) | (lsb >> 6))) << 4) >> 4) / 512.0f) * multiplier;
        }
        #endregion
    }

Misread the data sheet - it does default to +/-4 - my mistake; however it’s now ~= -1g, which is kind of to be expected I suppose given the earth and whatnot. I take it then that I’d have to report 0 when given that reading?


#4

Also, no matter what I seem to do, I’m always getting 0 out of Register 9, even during an interrupt handler…


        private SMB380()
        {
            spi = new SPI(new SPI.Configuration((Cpu.Pin)FEZ_Pin.Digital.UEXT10, false, 0, 0, true, true, 200, SPI.SPI_module.SPI2));

            //Enabled latched interrupts
            WriteRegister(0x15, (byte)(ReadRegister(0x15) | 0x10));

            interruptPort = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.UEXT4, false, Port.ResistorMode.PullDown, Port.InterruptMode.InterruptEdgeHigh);
            interruptPort.OnInterrupt += new NativeEventHandler(OnInterrupt);
            interruptPort.EnableInterrupt();
        }

        private void OnInterrupt(uint data1, uint data2, DateTime time)
        {
            //LG
            byte register = ReadRegister(0x09);
            if ((register & (byte)0x08) > 0)
            {
                WriteRegister(0x09, (byte)(register & 0xF7));
                Debug.Print("Low-G Threshold");
            }

            //HG
            if ((register & (byte)0x04) > 0)
            {
                WriteRegister(0x09, (byte)(register & 0xFB));
                Debug.Print("High-G Threshold");
            }

            //Clear the interrupt on the smb380
            WriteRegister(0x0A, (byte)(ReadRegister(0x0A) | 0x40));
        }


#5

OK solved the second one- had a phone connected via USB and was getting absolutely nothing out of the SMB380… ::slight_smile: