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:
#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.
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.
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:
/**
* 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;