This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

TWI(I2C) communication between esp32(slave) and nRF52840(master).

I am using nRF52840 as a master to communicate with esp32. For esp32 i am using arduino ide and esp 32 slave library( available in library manager of arduino ide).

For nRF52840 , i am using segger embedded ide.

First, i implemented the i2c scanner example from sdk(nRF5SDK160098a08e2) and used esp32 as a slave code and successfully able to read the address of the esp32.

Now, when i started to send TX packets from nRF52840 to esp32 , the esp 32 didn't recognise it and the receive event function was not called. This is my main problem.

/**
 * Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form, except as embedded into a Nordic
 *    Semiconductor ASA integrated circuit in a product or a software update for
 *    such product, must reproduce the above copyright notice, this list of
 *    conditions and the following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 *
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * 4. This software, with or without modification, must only be used with a
 *    Nordic Semiconductor ASA integrated circuit.
 *
 * 5. Any software provided in binary form under this license must not be reverse
 *    engineered, decompiled, modified and/or disassembled.
 *
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
/** @file
 * @defgroup tw_scanner main.c
 * @{
 * @ingroup nrf_twi_example
 * @brief TWI Sensor Example main file.
 *
 * This file contains the source code for a sample application using TWI.
 *
 */

#include <stdio.h>
#include "boards.h"
#include "app_util_platform.h"
#include "app_error.h"
#include "nrf_drv_twi.h"
#include "nrf_delay.h"



#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

/* TWI instance ID. */
#if TWI0_ENABLED
#define TWI_INSTANCE_ID     0
#elif TWI1_ENABLED
#define TWI_INSTANCE_ID     1
#endif

 /* Number of possible TWI addresses. */
 #define TWI_ADDRESSES      127

 // ret_code_t err_code_1;

/* TWI instance. */
static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);


/**
 * @brief TWI initialization.
 */
void twi_init (void)
{
    ret_code_t err_code;

    const nrf_drv_twi_config_t twi_config = {
    .scl                = ARDUINO_SCL_PIN,
     .sda                = ARDUINO_SDA_PIN,
      .frequency          = NRF_DRV_TWI_FREQ_100K,
       .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
       .clear_bus_init     = false
    };

    err_code = nrf_drv_twi_init(&m_twi, &twi_config, NULL, NULL);
    APP_ERROR_CHECK(err_code);

    nrf_drv_twi_enable(&m_twi);
}


/**
 * @brief Function for main application entry.
 */
int main(void)
{
    ret_code_t err_code;
   ret_code_t err_code_1;
    uint8_t address;
    uint8_t sample_data;
    bool detected_device = false;
  
    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    NRF_LOG_INFO("TWI scanner started.");
    NRF_LOG_FLUSH();
    twi_init();

   for (address = 1; address <= TWI_ADDRESSES; address++)
   {
       err_code = nrf_drv_twi_rx(&m_twi, address, &sample_data, sizeof(sample_data));
      if (err_code == NRF_SUCCESS)
        {
           detected_device = true;
           NRF_LOG_INFO("TWI device detected at address 0x%x.", address);
        // packet format necessary to send to esp32( wire packer format as described in esp32 slave library in arduino ide)
        // Here 1 byte: start bit(0x02)
        //      2 byte : Length(0x05)
        //      3 byte : Data(  i have taken any data , in my case as 0x11)
        //      4 byte : CRC8( checksum of length (0x05)and payload(0x11) is 0x36)
        //      5 byte : end bit(0x04)
         uint8_t packet[5]={0x02,0x05,0x11,0x36,0x04};
            err_code_1 = nrf_drv_twi_tx(&m_twi, address, packet, sizeof(packet) , false);
              APP_ERROR_CHECK(err_code_1);

          
       }
       NRF_LOG_FLUSH();
   }

   if (!detected_device)
   {
       NRF_LOG_INFO("No device was found.");
       NRF_LOG_FLUSH();
   }

    while (true)
    {
        
    }
}

/** @} */

On the esp 32 , the code is predefined example slave_receiver of the esp 32 slave library( https://www.arduino.cc/reference/en/libraries/esp32-i2c-slave/ ) of the arduino ide.

.

// WireSlave Receiver
// by Gutierrez PS <https://github.com/gutierrezps>
// ESP32 I2C slave library: <https://github.com/gutierrezps/ESP32_I2C_Slave>
// based on the example by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the WireSlave library for ESP32.
// Receives data as an I2C/TWI slave device; data must
// be packed using WirePacker.
// Refer to the "master_writer" example for use with this

#include <Arduino.h>
#include <Wire.h>
#include <WireSlave.h>

#define SDA_PIN 4
#define SCL_PIN 0
#define I2C_SLAVE_ADDR 0x09

void receiveEvent(int howMany);

void setup()
{
    Serial.begin(115200);

    bool success =WireSlave.begin(SDA_PIN, SCL_PIN, I2C_SLAVE_ADDR);    
    if (!success) {
        Serial.println("I2C slave init failed");
        while(1) delay(100);
    }
    WireSlave.onReceive(receiveEvent);
}

void loop()
{
    // the slave response time is directly related to how often
    // this update() method is called, so avoid using long delays
    // inside loop()
    WireSlave.update();
//let I2C and other ESP32 peripherals interrupts work
    delay(1);
}

// function that executes whenever a complete and valid packet
// is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
    while (1 < WireSlave.available()) // loop through all but the last byte
    {
        char c = WireSlave.read();  // receive byte as a character
        Serial.print(c);            // print the character
    }

    int x = WireSlave.read();   // receive byte as an integer
    Serial.println(x);          // print the integer
}

Now, my question is when i am able to read the slave address of the esp32 from the master nRF52840 ,  why i am unable to trigger the receive event in the esp32 slave code by transmitting the given packet as defined in the nRF52840 code?

Parents Reply Children
No Data
Related