Author Topic: Troubleshooting I2C on ESP-12F(ESP8266)  (Read 386 times)

0 Members and 1 Guest are viewing this topic.

Offline bsodmike

  • Regular Contributor
  • *
  • Posts: 206
  • Country: lk
Troubleshooting I2C on ESP-12F(ESP8266)
« on: June 15, 2021, 07:16:35 am »
Hi all,

I would like to start off by saying that I've tried a lot of various ideas to troubleshoot this, and ultimately whittled it down to using the following code:

Code: [Select]
#include <Arduino.h>
#include <Wire.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <DNSServer.h>
#include <HIH6130.h>

#define PULSE_LED     17     // ESP-12F pin 2
// #define PULSE_LED     5     // Thing
#define PULSE_DELAY   200

// HIH6130 sensor
#define I2C_SDA     2 // GPIO2
#define I2C_SCL     5 // GPI04
#define SENSOR_PWR  20 // GPIO5
const byte I2C_ADDRESS = 0x27;

HIH6130 sensor(I2C_ADDRESS, SENSOR_PWR);

void setupPulseLED(void) {
  pinMode(PULSE_LED, OUTPUT);
}

void pulse()
{
  digitalWrite(PULSE_LED, HIGH);
  delay(PULSE_DELAY);
  digitalWrite(PULSE_LED, LOW);
  delay(PULSE_DELAY);
}

void printHex8(uint8_t *data, uint8_t length) // prints 8-bit data in hex with leading zeroes
{
        Serial.print("0x");
        for (int i=0; i<length; i++) {
          if (data[i]<0x10) {Serial.print("0");}
          Serial.print(data[i],HEX);
          Serial.print(" ");
        }
}

void i2cCheck(byte address)
{
  byte error;
  int nDevices;
 
  Serial.print("Scanning for I2C device at address ");
  printHex8(&address, 1);
  Serial.println("");

  nDevices = 0;

  // The i2c_scanner uses the return value of
  // the Write.endTransmisstion to see if
  // a device did acknowledge to the address.
  Wire.beginTransmission(address);
  error = Wire.endTransmission();

  if (error == 0)
  {
    nDevices++;

    Serial.println(String(nDevices) + " I2C devices found ");
   
      Serial.print("0x");
   
    if (address<16)
      Serial.print("0");

    Serial.println(address,HEX);
  }
  else if (error==4)
  {
    Serial.print("Unknown error at address 0x");
    if (address<16)
      Serial.print("0");
    Serial.println(address,HEX);
  } 

  if (nDevices == 0)
  {
    Serial.println("No I2C devices found\n");
  }
  else
    Serial.println("done\n");
}

void setup(){
  Serial.begin(115200);
  Serial.println("\n\nSetup: initialising...\n");
  setupPulseLED();

  // Setup I2C
  Wire.begin(I2C_SDA, I2C_SCL);

  sensor.powerSensor();
  Serial.println("\nSetup: completed.\n");
}

void loop(void) {
  pulse();            // 200ms delay
  Serial.println("pulsed.");

  i2cCheck(I2C_ADDRESS);
}

So what's the issue? The main issue is that the ESP-12F isn't generating any clock-signal on the assigned SCL pin.  Looking a bit deeper, calling `Wire.begin()` sets up the following; so I also played with the Clock stretch limit, but no luck.

Code: [Select]
void Twi::init(unsigned char sda, unsigned char scl)
{
    // set timer function
    ets_timer_setfn(&timer, onTimer, NULL);

    // create event task
    ets_task(eventTask, EVENTTASK_QUEUE_PRIO, eventTaskQueue, EVENTTASK_QUEUE_SIZE);

    twi_sda = sda;
    twi_scl = scl;
    pinMode(twi_sda, INPUT_PULLUP);
    pinMode(twi_scl, INPUT_PULLUP);
    twi_setClock(preferred_si2c_clock);
    twi_setClockStretchLimit(150000L); // default value is 150 mS
}

and the `Wire.endTransmission()` function calls `twi_writeTo` which bit-bangs the following, where it changes state on the SCL line.

Code: [Select]
bool Twi::write_bit(bool bit)
{
    SCL_LOW(twi_scl);
    if (bit)
    {
        SDA_HIGH(twi_sda);
    }
    else
    {
        SDA_LOW(twi_sda);
    }
    busywait(twi_dcount + 1);
    SCL_HIGH(twi_scl);
    WAIT_CLOCK_STRETCH();
    busywait(twi_dcount);
    return true;
}

Therefore my main point of debugging this has been with an Oscilloscope sitting on both the SDA/SCL lines, and using a previous project with an Arduino board (and hardware I2C) reading off the same Honeywell temp-sensor.

Steps I took to troubleshoot this:
  • Is the tempsensor working: confirmed with my Arduino setup.  However, this powers the temp sensor at 5VDC. It is 3.3Vdc compatible as per the Sparkfun site though.
  • To isolate issues with the sensor at 3.3VDC, I'm powering the sensor at 5VDC and using a level-shifter on both the SDA/SCL lines. with 1kOhm pull-up resistors on both sides. The LV side pulls up to 3.3vdc and the HV side to 5VDC.

Any suggestions to figure out why the ESP-12F is struggling to clock the SCL line?  I've tried various port configurations too. Here's another config:

Code: [Select]
/**
 *  Pinout details
 */
#define LED_PIN      4 // ESP_12F pin 4 (GPIO16)

#define PULSE_LED    2     // ESP-12F
#define PULSE_DELAY  200

// HIH6130 sensor
#define I2C_SDA     17 // GPIO2
#define I2C_SCL     5  // GPI14
#define SENSOR_PWR  20 // GPIO5
const byte I2C_ADDRESS = 0x27;
 

Offline bsodmike

  • Regular Contributor
  • *
  • Posts: 206
  • Country: lk
Re: Troubleshooting I2C on ESP-12F(ESP8266)
« Reply #1 on: June 15, 2021, 01:07:03 pm »
Decided to go with ESP32 as my ESP-12s were very old. My code needed some working over, mainly changing the dependencies but it's working great.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf