Skip to content

ESP8266 I2C Master issue #4396

Closed
Closed
@Eddiiie

Description

@Eddiiie

Basic Infos

I am working with a multimaster setup. Have PoC code that works just fine on Uno and Mega, but when I try to run it on ESP8266 Arduino Lib it hangs on waiting for a variable to change from 0 to 1. - a Callback I guess you'd say.

It is awesome that I can specify pin numbers to use, wish that would work on Mega and Uno...

Code:

#include <Wire.h>

#define I2C_BUFFER_SIZE          64

/* Packet definitions */
#define PACKET_SENDER_OFFSET         0
#define PACKET_DATA_LENGTH_OFFSET    1
#define PACKET_COMMAND_OFFSET        2
#define PACKET_DATA_LENGTH_MASK      0x7F

/* Commands */
#define COMMAND_ACK                  6

/* All I2C addresses are 7 bit */
#define CONTROLLER_I2C_ADDRESS       0x28
#define DISPLAY_I2C_ADDRESS          0x27

static unsigned char i2c_rx_buffer[I2C_BUFFER_SIZE];
static unsigned char i2c_tx_buffer[I2C_BUFFER_SIZE];
  
volatile static boolean send_ack_signal = false;
volatile static boolean recv_ack_signal = false;

void i2c_receive_isr(int byte_count)
{
  unsigned char current_position = 0;
  unsigned char buffer_length = 0;
  unsigned char expected_stream_length = 0;
  unsigned char checksum = CONTROLLER_I2C_ADDRESS << 1;

  Serial.write("i2c_receive_isr entered...\n");
  Serial.flush();

  while (Wire.available() > 0)
  {
    /* Check for buffer overflow */
    if (buffer_length >= I2C_BUFFER_SIZE)
    {
      Serial.write("ERROR: I2C buffer overflow occured!\n");
      return;
    }


    /* Store data */
    i2c_rx_buffer[buffer_length++] = Wire.read();
  }

  
  /* Make sure entire packet was received */
  expected_stream_length = (i2c_rx_buffer[PACKET_DATA_LENGTH_OFFSET] &
                            PACKET_DATA_LENGTH_MASK) +
                            3;
                            
  if (expected_stream_length != buffer_length)
  {
    Serial.write("ERROR: Expected ");
    Serial.write(expected_stream_length);
    Serial.write(" bytes, received ");
    Serial.write(buffer_length);
    Serial.write("\n");
    return;   
  }


  /* Calculate checksum and validate packet integrity */
  for (current_position = 0;
       current_position < buffer_length - 1;
       current_position++)
  {
    checksum ^= i2c_rx_buffer[current_position]; 
  }

  if (checksum != i2c_rx_buffer[buffer_length - 1])
  {
    Serial.write("ERROR: Checksum failure!\n");
    Serial.flush();
    return;
  }

  
  /* Call dispatch routine based on command received */
  switch (i2c_rx_buffer[PACKET_COMMAND_OFFSET])
  {
    case COMMAND_ACK:
      recv_ack_signal = true;
      break;

    default:
      /* Any command needs an ACK sent back */
      send_ack_signal = true;
      break;
  }
}


void setup() {
  int display_online = -1;

  Serial.begin(9600);

  Serial.write("Initializing I2C\n");
  Wire.begin(CONTROLLER_I2C_ADDRESS);
  Wire.begin(12, 14);  // NodeMCU
  Wire.onReceive(i2c_receive_isr);
}


void loop() {
  Serial.write("Waiting to send ack...");
  Serial.flush();
  while (!send_ack_signal)
  {
   delay(500);
  }
  send_ack_signal = false;
  Serial.write("Ack sent...");
}

The 'while' loop never exits on ESP8266.

"send_ack_signal" is the function I defined that gets registered when you call Wire.onReceive().

Hardware

Hardware: ?ESP-12?
Core Version: ?2.1.0-rc2?
I've confirmed this on Heltec Wifi 8 kit, NodeMCU, and WeMOS D1.

Settings in IDE

Module: Heltec Wiki 8 kit, NodeMCU, WeMOS D1
Flash Size: 4MB I believe
CPU Frequency: Tested 80 and 160
Flash Mode: huh?
Flash Frequency: once a day? :)
Upload Using: Arduino ISP ?
Reset Method: Power cycle

Metadata

Metadata

Assignees

No one assigned

    Labels

    waiting for feedbackWaiting on additional info. If it's not received, the issue may be closed.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions