├── .gitattributes ├── .gitignore ├── DEV_Identify.h ├── DEV_Sensors.h ├── LICENSE ├── TempSensorI2C.ino └── docs └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .development 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /DEV_Identify.h: -------------------------------------------------------------------------------- 1 | 2 | ////////////////////////////////// 3 | // DEVICE-SPECIFIC SERVICES // 4 | ////////////////////////////////// 5 | 6 | struct DEV_Identify : Service::AccessoryInformation { 7 | 8 | int nBlinks; // number of times to blink built-in LED in identify routine 9 | SpanCharacteristic *identify; // reference to the Identify Characteristic 10 | 11 | DEV_Identify(const char *name, const char *manu, const char *sn, const char *model, const char *version, int nBlinks) : Service::AccessoryInformation(){ 12 | 13 | new Characteristic::Name(name); // create all the required Characteristics with values set based on above arguments 14 | new Characteristic::Manufacturer(manu); 15 | new Characteristic::SerialNumber(sn); 16 | new Characteristic::Model(model); 17 | new Characteristic::FirmwareRevision(version); 18 | identify=new Characteristic::Identify(); // store a reference to the Identify Characteristic for use below 19 | 20 | this->nBlinks=nBlinks; // store the number of times to blink the LED 21 | 22 | pinMode(homeSpan.getStatusPin(),OUTPUT); // make sure LED is set for output 23 | } 24 | 25 | boolean update(){ 26 | 27 | for(int i=0;i 7 | 8 | struct DEV_TempSensor : Service::TemperatureSensor { // A standalone Temperature sensor 9 | 10 | SpanCharacteristic *temp; // reference to the Current Temperature Characteristic 11 | int addr; // I2C address of temperature sensor 12 | uint32_t timer=0; // keep track of time since last update 13 | 14 | DEV_TempSensor(int addr) : Service::TemperatureSensor(){ // constructor() method 15 | 16 | this->addr=addr; // I2C address of temperature sensor 17 | 18 | #ifdef CUSTOM_SDA_PIN 19 | Wire.setPins(CUSTOM_SDA_PIN,CUSTOM_SCL_PIN); 20 | #endif 21 | 22 | Wire.begin(); // start I2C in Controller Mode 23 | 24 | Wire.beginTransmission(addr); // setup transmission 25 | Wire.write(0x0B); // ADT7410 Identification Register 26 | Wire.endTransmission(0); // transmit and leave in restart mode to allow reading 27 | Wire.requestFrom(addr,1); // request read of single byte 28 | uint8_t id = Wire.read(); // receive a byte 29 | 30 | Wire.beginTransmission(addr); // setup transmission 31 | Wire.write(0x03); // ADT740 Configuration Register 32 | Wire.write(0xC0); // set 16-bit temperature resolution, 1 sampler per second 33 | Wire.endTransmission(); // transmit 34 | 35 | double tempC=getTemp(); 36 | 37 | temp=new Characteristic::CurrentTemperature(tempC); // instantiate the Current Temperature Characteristic 38 | temp->setRange(-50,100); // expand the range from the HAP default of 0-100 to -50 to 100 to allow for negative temperatures 39 | 40 | Serial.printf("Configuring Temperature Sensor ADT7410 version 0x%02X with address 0x%02X: %0.2f C.\n",id,addr,tempC); // initialization message 41 | 42 | } // end constructor 43 | 44 | void loop(){ 45 | 46 | char c[64]; 47 | 48 | if(millis()-timer>5000){ // only sample every 5 seconds 49 | timer=millis(); 50 | 51 | Wire.beginTransmission(addr); // setup transmission 52 | Wire.write(0x00); // ADT7410 2-byte Temperature 53 | Wire.endTransmission(0); // transmit and leave in restart mode to allow reading 54 | Wire.requestFrom(addr,2); // request read of two bytes 55 | 56 | double tempC=getTemp(); 57 | 58 | if(abs(temp->getVal()-tempC)>0.5){ // only update temperature if change is more than 0.5C 59 | temp->setVal(tempC); // set the new temperature; this generates an Event Notification and also resets the elapsed time 60 | sprintf(c,"ADT7410-%02X Temperature Update: %g\n",addr,tempC); 61 | LOG1(c); 62 | } 63 | } 64 | 65 | } // loop 66 | 67 | double getTemp(){ 68 | Wire.beginTransmission(addr); // setup transmission 69 | Wire.write(0x00); // ADT7410 2-byte Temperature 70 | Wire.endTransmission(0); // transmit and leave in restart mode to allow reading 71 | Wire.requestFrom(addr,2); // request read of two bytes 72 | 73 | double t; 74 | int16_t iTemp; 75 | 76 | iTemp=((int16_t)Wire.read()<<8)+Wire.read(); 77 | t=iTemp/128.0; 78 | return(t); 79 | } 80 | 81 | }; 82 | 83 | ////////////////////////////////// 84 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020, 2021 Gregg E. Berman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /TempSensorI2C.ino: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 Gregg E. Berman 5 | * 6 | * https://github.com/HomeSpan/HomeSpan 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in all 16 | * copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | * SOFTWARE. 25 | * 26 | ********************************************************************************/ 27 | 28 | // Comment out two lines below to use default I2C pins 29 | 30 | #define CUSTOM_SDA_PIN 3 // override default I2C pins 31 | #define CUSTOM_SCL_PIN 2 32 | 33 | #include "HomeSpan.h" 34 | #include "DEV_Identify.h" 35 | #include "DEV_Sensors.h" 36 | 37 | 38 | void setup() { 39 | 40 | Serial.begin(115200); 41 | 42 | homeSpan.begin(Category::Sensors,"Temperature Sensor"); 43 | 44 | new SpanAccessory(); 45 | new DEV_Identify("Temp Sensor","HomeSpan","ADT7410","Adafruit I2C Temp Sensor","1.0",0); 46 | new Service::HAPProtocolInformation(); 47 | new Characteristic::Version("1.1.0"); 48 | new DEV_TempSensor(0x48); 49 | 50 | } // end of setup() 51 | 52 | ////////////////////////////////////// 53 | 54 | void loop(){ 55 | 56 | homeSpan.poll(); 57 | 58 | } // end of loop() 59 | 60 | ////////////////////////////////////// 61 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # TempSensorI2C - A HomeSpan Project 2 | 3 | TempSensorI2C is a working example of how to use the I2C protocol to capture temperature readings from an Analog Device ADT7410 high-resolution temperature sensor and stream them to HomeKit. Built using the [HomeSpan](https://github.com/HomeSpan/HomeSpan) HomeKit Library, TempSensorI2C is designed to run on an ESP32 device as an Arduino sketch. 4 | 5 | Hardware used for this project: 6 | 7 | * An ESP32 board, such as the [Adafruit HUZZAH32 – ESP32 Feather Board](https://www.adafruit.com/product/3405) 8 | * An Analog Device ADT7410 Temperature Sensor, such as the [Adafruit ADT7410 Breakout Board](https://www.adafruit.com/product/4089) 9 | 10 | ## Overview 11 | 12 | This simple HomeSpan sketch illustrates how the standard Arduino I2C library `Wire.h` can be used to capture temperature readings from an ADT7410 temperature sensor and stream them to HomeKit. The sketch: 13 | * implements a single HomeKit *Accessory* containing a HomeKit *TemperatureSensor Service*; 14 | * captures samples from the ADT7410 every 5 seconds; 15 | * sends updates to HomeKit only if the temperature has changed by more than 0.5 Celsius; and 16 | * is easily modified to accomodate up to 4 ADT7410 sensors, each with their own unique I2C address. 17 | 18 | ## Connections 19 | 20 | The connections below provide for I2C communicaiton between the ESP32 and the ADT7410 using the 7410's default address of 0x48: 21 | 22 | |ADT7410|ESP32| 23 | |-------|-----| 24 | |VIN|3V| 25 | |GND|GND| 26 | |SDA|SDA| 27 | |SCL|SCL| 28 | |A0|unused| 29 | |A1|unused| 30 | |INT|unused| 31 | |CT|unused| 32 | 33 | --- 34 | 35 | ### Feedback or Questions? 36 | 37 | Please consider adding to the [Discussion Board](https://github.com/HomeSpan/HomeSpan/discussions), or email me directly at [homespan@icloud.com](mailto:homespan@icloud.com). 38 | 39 | 40 | 41 | 42 | --------------------------------------------------------------------------------