Introduction: Getting Started With I2C Sensor Interface?? - Interface Your MMA8451 Using ESP32s

In this tutorial, you will learn all about How to start , connect and get I2C device(Accelerometer) working with controller (Arduino, ESP32 , ESP8266, ESP12 NodeMCU)

Step 1: How to Get Started With I2C - Magnificent World of Inter IC Communication

The Arduino, ESP Series, PIC, Rasberry PI, etc. are all incredible. But what do you do with it once you have one?

The best thing is to add sensors and such. Today a lot of the hot new technology uses the I2C protocol to allow the computer, phones, tablets, or microcontrollers to talk the sensors. Smart phones would be less smart if they couldn’t talk to that accelerometer sensor to know which way your phone is facing.

Step 2: Overview on I2C

I2C is a serial, synchronous, half-duplex communication protocol that allows co-existence of multiple masters and slaves on the same bus. The I2C bus consists of two lines: serial data line (SDA) and serial clock (SCL). Both lines require pull-up resistors.

SDA (Serial Data) – The line for the master and slave to send and receive data. SCL (Serial Clock) – The line that carries the clock signal. With such advantages as simplicity and low manufacturing cost, I2C is mostly used for communication of low-speed peripheral devices over short distances (within one foot).

Want to learn More about I2C ?…...

Step 3: How to Configure I²C Sensors

Before going in to the project, you need to understand a few basics of your Sensor. So pour yourself a cup of coffee before diving in :)😉 …

The great strength of I2C is that you can put so many sensors on the same four wires. But for units with several pre-made modules connected ,you might have to remove a few smd resistors from the breakouts, otherwise the pull-up on the bus might become too aggressive.

What information we want from Datasheet??

  1. Sensor functionality
  2. Pinouts and pins functionality
  3. Interface description (Don't miss to look on “I2c Address Selection table“ )
  4. Registers!!

Everything is fine you will find it easily but Registers??
REGISTERS are simply memory locations inside an I²C device. The summary of how many registers there are in a given sensor, and what they control or contain is called a register map. Most of the information on the sensor’s datasheet is about explaining how each register functions, and they can be quite a slog to read through because the information is rarely presented in direct way.

To give you a sense of what I mean by that:There are many kinds of registers but for this introduction I am going to group them into two general types: Control and Data registers.

1) Control Registers

Most sensors change how they operate based on the values stored in control registers. Think of control registers as banks of On/Off switches, which you turn on by setting a bit to 1 and turn off by setting that bit to 0. I²C chip-based sensors often have a dozen or more operational settings for things like bit-Modes , interrupts,read-write control , depth, sampling speed, noise reduction, etc., so you usually need to set bits in several different control registers before you can actually take a reading.

2) Data registers
Unlike a control registers bank-of-switches, I think of data output registers as containers holding numbers which just happen to be stored in binary form. So you want to know Data ,always read data registers like who am i register for device identification,Status register etc..

So, initializing an I²C sensor is a multi-step process and the correct order of operations is often explained in written in reverse direction,Instead of a straightforward in Datasheet. list never saying “To get a reading from this sensor, do (1),(2),(3),(4), etc”,but you find descriptions of the control register bits saying “before you set bit x in this register you must set bit y in this other control register”.

Still I always find a data sheet is more interactive than most text. if You will reference it for a specific piece or pieces of information and its give you all details , connections and references. Just sit down and read to get out all your references.:)

Step 4: Start With Motion - Accelerometer

Modern accelerometers are Micro Electro-Mechanical Systems (MEMS) devices, which means that they are able to fit on a small chip inside the smallest of gadgets. One method to measure acceleration employed by MEMS accelerometers is to utilize a tiny conductive mass suspended on springs. The acceleration of the device causes the springs to stretch or contract, and the deflection of the conductive mass can be measured through a change in capacitance to nearby, fixed plates.

Accelerometers are specified by the following features:

  1. The number of axes, from one to three axes, labeled X, Y, and Z in the specification diagrams. Note that some accelerometers are called 6-axis or 9-axis, but that just means that they are bundled with other MEMS devices such as gyroscopes and/or magnetometers. Each of those devices also have three axes, which is why there are 3, 6, or 9-axis Inertial Measurement Units (IMUs).
  2. The type of output, either analog or digital. A digital accelerometer takes care of formatting the acceleration data into a digital representation that can be read out over I2C or SPI.
  3. The range of acceleration measured in g’s, where 1g is the acceleration due to Earth’s gravity.
  4. Coprocessors that can offload some of the calculations needed to analyze the raw data from the MCU. Most accelerometers have some simple interrupt capability to detect an acceleration threshold (shock) and a 0-g (freefall) condition. Others can do advanced processing on the raw data to offer more meaningful data to the MCU.

Step 5: Interface With Controller

Since we know ESP Microcontrollers in trend, we will use ESP32 for our example. So first you need a Nodemcu-32s.

No worries if you have any other ESP boards or even Arduino!!! You just have to setup your Arduino IDE and configuration as per your Development boards,for Arduino, ESP NodeMCU, ESP32s etc... You will also need some kind of I2C parts, usually on a breakout board.In this tutorial I am going to use MMA8451 digital Accelerometer breakout board.

And few jumper wires....

Step 6: ​Connections

And here is a layout.

I used the following connection from the module above to my Nodemcu-32s module.

ESP32s -- Module

3v3 -- Vin

Gnd -- Gnd

SDA 21 -- SDA

SCL 22 -- SCL

"Remember ,most of the time not all development boards(mostly in ESPs) have a good clear pinout to help to determine which pins are used !! So before connection ,identify your board's correct pins to use which pins are for SDA and SCL."

Step 7: Code

This requires the Adafruit library


Download,unzip and you will find examples folder, in folder just open MMA8451demo in your Arduino IDE and here you go....

you will see following code for your MMA8451 sensor interface with your controller

#include <Wire.h>
#include <Adafruit_MMA8451.h>
#include <Adafruit_Sensor.h>

Adafruit_MMA8451 mma = Adafruit_MMA8451();

void setup(void) {
  Wire.begin(4,5);  /* join i2c bus with SDA=D1 and SCL=D2 of NodeMCU */
  Serial.println("Adafruit MMA8451 test!");

  if (! mma.begin()) {
    Serial.println("Couldnt start");
    while (1);
  Serial.println("MMA8451 found!");
  Serial.print("Range = "); Serial.print(2 << mma.getRange());  

void loop() {
  // Read the 'raw' data in 14-bit counts;
  Serial.print("X:\t"); Serial.print(mma.x); 
  Serial.print("\tY:\t"); Serial.print(mma.y); 
  Serial.print("\tZ:\t"); Serial.print(mma.z); 

  /* Get a new sensor event */ 
  sensors_event_t event; 

  /* Display the results (acceleration is measured in m/s^2) */
  Serial.print("X: \t"); Serial.print(event.acceleration.x); Serial.print("\t");
  Serial.print("Y: \t"); Serial.print(event.acceleration.y); Serial.print("\t");
  Serial.print("Z: \t"); Serial.print(event.acceleration.z); Serial.print("\t");
  Serial.println("m/s^2 ");
  /* Get the orientation of the sensor */
  uint8_t o = mma.getOrientation();
  switch (o) {
    case MMA8451_PL_PUF: 
      Serial.println("Portrait Up Front");
    case MMA8451_PL_PUB: 
      Serial.println("Portrait Up Back");
    case MMA8451_PL_PDF: 
      Serial.println("Portrait Down Front");
    case MMA8451_PL_PDB: 
      Serial.println("Portrait Down Back");
    case MMA8451_PL_LRF: 
      Serial.println("Landscape Right Front");
    case MMA8451_PL_LRB: 
      Serial.println("Landscape Right Back");
    case MMA8451_PL_LLF: 
      Serial.println("Landscape Left Front");
    case MMA8451_PL_LLB: 
      Serial.println("Landscape Left Back");

Save,Verify and Upload......

Open the serial monitor and you will see something like this, I was moving the sensor about hence the various readings

X: -2166 Y: 1872 Z: 2186

X: -2166 Y: 1872 Z: 2186X: -4.92 Y: 5.99 Z: 4.87 m/s^2

Landscape Left Front

X: -224 Y: -2020 Z: 3188

X: -5.10 Y: -3.19 Z: 7.00 m/s^2

Portrait Up Front

Well if everything went as it should, then you now have the basics of I2C and How to connect your device..

But device not Working??!!

Just go with next step......

Step 8: Get Your I2C Device Working..

Basic steps for get I2C device work!

Let's investigate ....

  • Wiring is correct..(check it again)
  • Program is correct ..(Yes, it's test example..)

Start with stages to solve.....

Stage 1: Run I2C device scanner program to check device address and first your I2C device is okey.

You can Download sketch and check output.

  • Result - Device is working and Sensor address is right
I2C scanner. Scanning ...
Found address: 28 (0x1C)
Found 1 device(s).

Stage 2: Check sensor library .

Open Adafruit_MMA8451.h file and find device address

  • Result - Address is different from my device??..
</strong>#define MMA8451_DEFAULT_ADDRESS                                                \
  (0x1D) //!< Default MMA8451 I2C address, if A is GND, its 0x1C<strong>
  • Do - Edit file from notepad(change address) + Save + Restart IDE

It works .You can get your readings.

Sill not.....??🤷

Stage 3: Check Wire.begin is overwritten?

Open Adafruit_MMA8451.c file and find Wire.begin.

  • Result - This statement is overwritten..
    @brief  Setups the HW (reads coefficients values, etc.)
bool Adafruit_MMA8451::begin(uint8_t i2caddr) {
  _i2caddr = i2caddr;
  • Do - Edit file from notepad(comment statement) + Save + Restart IDE

And finally Device getting Working☺....

I almost overload this tutorial because its main goal was to explain How to start,get data from datasheet , connect and get I2C device working with very basic example.Hope everything will go as it should, and it will useful to start your Sensor.

Good Luck!!