Custom i2c component and Esphome?

I’m trying to add support for a tmp75 to my esphome install. I’m tripping over myself somewhat. Does anyone have any examples?

I’ve looked at
I²C Bus — ESPHome (How i2c works on esphome)

http://www.esp32learning.com/code/esp32-and-tmp175-digital-temperature-sensor-example.php (How the tmp75 works on the i2c bus)

Custom I²C Device — ESPHome (How custom i2c works)

Custom Sensor Component — ESPHome (how custom sensors work)
This is what I have so far. If compiles and loads, but the board becomes immediately non responsive. Any advice would be appreciated.


#include "esphome.h"
byte TempHi;              // Variable hold data high byte
byte TempLo;              // Variable hold data low byte
boolean P_N;              // Bit flag for Positive and Negative
unsigned int Decimal;     // Variable hold decimal value
void Cal_Temp();

class TMP75 : public PollingComponent, public Sensor {
 public:
  // constructor
  TMP75() : PollingComponent(15000) {}
  void setup() override {
    // This will be called by App.setup()
    Wire.begin();
    delay(1000);
  }
  void update() override {
    // This will be called every "update_interval" milliseconds.
      const int I2C_address = 0x4f;  // I2C write address
  delay(100);
  Wire.beginTransmission(I2C_address);
  Wire.write(1);             // Setup configuration register
  Wire.write(0x60);          // 12-bit
  Wire.endTransmission();
  Wire.beginTransmission(I2C_address);
  Wire.write(0);             // Setup Pointer Register to 0
  Wire.endTransmission();
  while (1)
  {
    delay(1000);
    // Read temperature value
    Wire.requestFrom(I2C_address, 2);
    while(Wire.available())          // Checkf for data from slave
    {
      TempHi = Wire.read();       // Read temperature high byte
      TempLo = Wire.read();       // Read temperature low byte
    }
    Cal_Temp ();
    // Display temperature
    publish_state(Decimal);
  }
}
};

void Cal_Temp()
{
  if (TempHi&0x80)          // If bit7 of the TempHi is HIGH then the temperature is negative
    P_N = 0;
  else                      // Else the temperature is positive
    P_N = 1;

  TempHi = TempHi & 0x7F;   // Remove sign
  TempLo = TempLo & 0xF0;   // Filter out last nibble
  TempLo = TempLo >> 4;      // Shift right 4 times
  Decimal = TempLo;
  Decimal = Decimal * 625;  // Each bit = 0.0625 degree C
}

sensor:
 - platform: custom
   lambda: |-
     auto diningtemp = new TMP75();
     App.register_component(diningtemp);
     return {diningtemp};
   sensors:
     name: "Dining Room Temperature"

I think I figured it out… I think its the while loop in there…

Damn. Didn’t work…

Got it working…


#include "esphome.h"

byte TempHi;              // Variable hold data high byte
byte TempLo;              // Variable hold data low byte
signed int P_N;              // Bit flag for Positive and Negative
unsigned short rawtemp;
void Cal_Temp();
const int I2C_address = 0x4f;  // I2C write address

class TMP75: public PollingComponent, public Sensor {
 public:
  // constructor
  TMP75() : PollingComponent(15000) {}
  void setup() override {
    // This will be called by App.setup()
    Wire.begin();
    delay(1000);
    Wire.beginTransmission(I2C_address);
  Wire.write(1);             // Setup configuration register
  Wire.write(0x60);          // 12-bit
  Wire.endTransmission();
  Wire.beginTransmission(I2C_address);
  Wire.write(0);             // Setup Pointer Register to 0
  Wire.endTransmission();
  }
  void update() override {
    // This will be called every "update_interval" milliseconds.
  Wire.requestFrom(I2C_address, 2);
     TempHi = Wire.read();       // Read temperature high byte
     TempLo = Wire.read();       // Read temperature low byte
  Cal_Temp ();
  // Display temperature 
  
  publish_state(float(rawtemp)*float(0.0625)*float(P_N));
  
  }
};

void Cal_Temp()
{
  if (TempHi&0x80)          // If bit7 of the TempHi is HIGH then the temperature is negative
    P_N = -1;
  else                      // Else the temperature is positive
    P_N = 1;

  TempHi = TempHi & 0x7F;   // Remove sign
  TempLo = TempLo & 0xF0;   // Filter out last nibble
  rawtemp = TempHi << 4;
   TempLo = TempLo >> 4;      // Shift right 4 times
   rawtemp = rawtemp | TempLo;
}
3 Likes