diff --git a/CHANGELOG.md b/CHANGELOG.md index 72dbe56..41d5a53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ Change Log ====================== +v2.9: +* Adds support for the TMP102 temperature sensor v2.8: --------- diff --git a/COMPILE_BINARY.md b/COMPILE_BINARY.md index ea89785..1559585 100644 --- a/COMPILE_BINARY.md +++ b/COMPILE_BINARY.md @@ -52,6 +52,7 @@ Copy and paste the following into an empty sketch. Click on each link in turn to // http://librarymanager/All#SparkFun_SGP30 // http://librarymanager/All#SparkFun_VCNL4040 // http://librarymanager/All#SparkFun_MS5637 +// http://librarymanager/All#SparkFun_TMP102 // http://librarymanager/All#SparkFun_TMP117 // http://librarymanager/All#SparkFun_u-blox_GNSS // http://librarymanager/All#SparkFun_NAU7802 diff --git a/Firmware/OpenLog_Artemis/OpenLog_Artemis.ino b/Firmware/OpenLog_Artemis/OpenLog_Artemis.ino index a7e5b26..a5ba62b 100644 --- a/Firmware/OpenLog_Artemis/OpenLog_Artemis.ino +++ b/Firmware/OpenLog_Artemis/OpenLog_Artemis.ino @@ -108,6 +108,7 @@ (done) Add a fix for issue #109 - check if a BME280 is connected before calling multiplexerBegin: https://github.com/sparkfun/OpenLog_Artemis/issues/109 (done) Correct issue #104. enableSD was redundant. The microSD power always needs to be on if there is a card inserted, otherwise the card pulls the SPI lines low, preventing communication with the IMU: https://github.com/sparkfun/OpenLog_Artemis/issues/104 + (done) Add support for TMP102 temperature sensor (while differentating between it and the ADS1015 (which share the same 4 addresses starting at 0x48) v2.2: Use Apollo3 v2.2.1 with changes by paulvha to fix Issue 117 (Thank you Paul!) @@ -160,10 +161,12 @@ The charsReceived debug print ("Total chars received: ") now excludes the length of the timestamps Consistent use of File32/ExFile/FsFile/File. Don't use SdFile for temporary files + v2.9 + Adds support for TMP102 low(er) cost temperature sensor */ const int FIRMWARE_VERSION_MAJOR = 2; -const int FIRMWARE_VERSION_MINOR = 8; +const int FIRMWARE_VERSION_MINOR = 9; //Define the OLA board identifier: // This is an int which is unique to this variant of the OLA and which allows us @@ -315,6 +318,7 @@ icm_20948_DMP_data_t dmpData; // Global storage for the DMP data - extracted fro #include "SparkFun_SGP30_Arduino_Library.h" //Click here to get the library: http://librarymanager/All#SparkFun_SGP30 #include "SparkFun_VCNL4040_Arduino_Library.h" //Click here to get the library: http://librarymanager/All#SparkFun_VCNL4040 #include "SparkFun_MS5637_Arduino_Library.h" //Click here to get the library: http://librarymanager/All#SparkFun_MS5637 +#include "SparkFunTMP102.h" //Click here to get the library: http://librarymanager/All#SparkFun_TMP102 #include "SparkFun_TMP117.h" //Click here to get the library: http://librarymanager/All#SparkFun_TMP117 #include "SparkFun_u-blox_GNSS_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS #include "SparkFun_Qwiic_Scale_NAU7802_Arduino_Library.h" //Click here to get the library: http://librarymanager/All#SparkFun_NAU7802 diff --git a/Firmware/OpenLog_Artemis/Sensors.ino b/Firmware/OpenLog_Artemis/Sensors.ino index 052a744..d6ca5b0 100644 --- a/Firmware/OpenLog_Artemis/Sensors.ino +++ b/Firmware/OpenLog_Artemis/Sensors.ino @@ -434,6 +434,20 @@ void gatherDeviceValues(char * sdOutputData, size_t lenData) } } break; + case DEVICE_TEMPERATURE_TMP102: + { + TMP102 *nodeDevice = (TMP102 *)temp->classPtr; + struct_TMP102 *nodeSetting = (struct_TMP102 *)temp->configPtr; + + if (nodeSetting->log == true) + { + olaftoa(nodeDevice->readTempC(), tempData1, 4, sizeof(tempData1) / sizeof(char)); //Resolution to 0.0625°C, ACCURACY: 0.5°C (–25°C to +85°C) + sprintf(tempData, "%s,", tempData1); + strlcat(sdOutputData, tempData, lenData); + + } + } + break; case DEVICE_TEMPERATURE_TMP117: { TMP117 *nodeDevice = (TMP117 *)temp->classPtr; @@ -1465,6 +1479,19 @@ static void getHelperText(char* helperText, size_t lenText) } } break; + case DEVICE_TEMPERATURE_TMP102: + { + + struct_TMP102 *nodeSetting = (struct_TMP102 *)temp->configPtr; + if (nodeSetting->log) + { + // Include unique ID's for bus/port/address for each TMP102 temp sensor + char tempTxt[25]; + sprintf(tempTxt,"TMP102 %02X-%d-%02X DegC,", temp->muxAddress, temp->portNumber, temp->address); + strlcat(helperText, tempTxt, lenText); + } + } + break; case DEVICE_TEMPERATURE_TMP117: { struct_TMP117 *nodeSetting = (struct_TMP117 *)temp->configPtr; diff --git a/Firmware/OpenLog_Artemis/autoDetect.ino b/Firmware/OpenLog_Artemis/autoDetect.ino index 232b4ff..1531008 100644 --- a/Firmware/OpenLog_Artemis/autoDetect.ino +++ b/Firmware/OpenLog_Artemis/autoDetect.ino @@ -147,6 +147,12 @@ bool addDevice(deviceType_e deviceType, uint8_t address, uint8_t muxAddress, uin temp->configPtr = new struct_VCNL4040; } break; + case DEVICE_TEMPERATURE_TMP102: + { + temp->classPtr = new TMP102; + temp->configPtr = new struct_TMP102; + } + break; case DEVICE_TEMPERATURE_TMP117: { temp->classPtr = new TMP117; @@ -402,6 +408,14 @@ bool beginQwiicDevices() temp->online = tempDevice->begin(qwiic); //Wire port } break; + case DEVICE_TEMPERATURE_TMP102: + { + TMP102 *tempDevice = (TMP102 *)temp->classPtr; + struct_TMP102 *nodeSetting = (struct_TMP102 *)temp->configPtr; //Create a local pointer that points to same spot as node does + if (nodeSetting->powerOnDelayMillis > qwiicPowerOnDelayMillis) qwiicPowerOnDelayMillis = nodeSetting->powerOnDelayMillis; // Increase qwiicPowerOnDelayMillis if required + temp->online = tempDevice->begin(temp->address, qwiic); //Address, Wire port + } + break; case DEVICE_TEMPERATURE_TMP117: { TMP117 *tempDevice = (TMP117 *)temp->classPtr; @@ -819,6 +833,18 @@ void configureDevice(node * temp) sensor->setAmbientIntegrationTime(sensorSetting->ambientIntegrationTime); } break; + + case DEVICE_TEMPERATURE_TMP102: + { + TMP102 *sensor = (TMP102 *)temp->classPtr; + struct_TMP102 *sensorSetting = (struct_TMP102 *)temp->configPtr; + + // JWS - I did not initalize the TMP102 sensor, as they appear to + // work just fine with no special initalization code. + + + } + break; case DEVICE_TEMPERATURE_TMP117: { TMP117 *sensor = (TMP117 *)temp->classPtr; @@ -1106,6 +1132,9 @@ FunctionPointer getConfigFunctionPtr(uint8_t nodeNumber) case DEVICE_PROXIMITY_VCNL4040: ptr = (FunctionPointer)menuConfigure_VCNL4040; break; + case DEVICE_TEMPERATURE_TMP102: + ptr = (FunctionPointer)menuConfigure_TMP102; + break; case DEVICE_TEMPERATURE_TMP117: ptr = (FunctionPointer)menuConfigure_TMP117; break; @@ -1324,6 +1353,7 @@ void swap(struct node * a, struct node * b) #define ADR_MS8607 0x40 //Humidity portion of the MS8607 sensor #define ADR_UBLOX 0x42 //But can be set to any address #define ADR_ADS122C04 0x45 //Alternates: 0x44, 0x41 and 0x40 +#define ADR_TMP102 0x48 //Alternates: 0x49, 0x4A, and 0x4B #define ADR_TMP117 0x48 //Alternates: 0x49, 0x4A, and 0x4B #define ADR_ADS1015 0x48 //Alternates: 0x49, 0x4A, and 0x4B #define ADR_BIO_SENSOR_HUB 0x55 @@ -1488,10 +1518,54 @@ deviceType_e testDevice(uint8_t i2cAddress, uint8_t muxAddress, uint8_t portNumb if (sensor.begin(i2cAddress, qwiic) == true) //Address, Wire port return (DEVICE_TEMPERATURE_TMP117); - //Confidence: Low - only does a simple isConnected + + + + + // Confidence: Medium - does a simple isConnected check, and then tests that two bits are read/write to disambiguate + // from the TMP102 sensor, where those two bits are read only 11. ADS1015 sensor1; - if (sensor1.begin(i2cAddress, qwiic) == true) //Address, Wire port - return (DEVICE_ADS1015); + if (sensor1.begin(i2cAddress, qwiic) == true) //Address, Wire port + { + //Peek at the current config register (same 01 pointer addr as the TMP102) + uint16_t config = sensor1.readRegister(ADS1015_POINTER_CONFIG); + + //Write zeros to the MUX[2:1] bits of the ADS1015 (read/write bits) which + // happen to be in the same place as the R1/R0 bits of the TMP102 (and + // are read only 11 on the TMP102 + uint16_t newConfig = config & 0x9FFF; // 0x9FFF is 1001 1111 1111 1111 so it zeros out those two bits + + //SerialPrintf2("ADS1015 detect, newconfig is:: %x \r\n", newConfig); + + + sensor1.writeRegister(ADS1015_POINTER_CONFIG, newConfig); + + //Read back to see if our changes were recorded (ADS1015) or not (TMP102) + newConfig = sensor1.readRegister(ADS1015_POINTER_CONFIG); + + + //SerialPrintf2("ADS105 detect, after write/read cycle, config is: %x \r\n", newConfig); + + + // Write the original config back to restore the correct state. + sensor1.writeRegister(ADS1015_POINTER_CONFIG, config); + + //Check to see if the bits we wrote zero stayed at 00 (ADS1015) or returned as + // 1's because it's actually a TMP102 or some other chip with read only bits + // in that spot... + if( (newConfig & 0x6000) == 0 ) // 0x6000 is 0110 0000 0000 0000 so it zeros out all bits except the two we are interested in. + { + // Our cannary bits correctly stayed set at zero! Write successful, assume it is a ADS1015 + return (DEVICE_ADS1015); + + } + // Otherwise, fall through to the TMP102 test below, which just assumes anything on the correct address is in fact a TMP102 sensor... + } // end if there is a device on this address. + + //Confidence: Low - only does a simple isConnected. + TMP102 sensor2; + if (sensor2.begin(i2cAddress, qwiic) == true) //Address, Wire port + return (DEVICE_TEMPERATURE_TMP102); } break; case 0x55: @@ -1889,6 +1963,9 @@ const char* getDeviceName(deviceType_e deviceNumber) case DEVICE_PROXIMITY_VCNL4040: return "Proximity-VCNL4040"; break; + case DEVICE_TEMPERATURE_TMP102: + return "Temperature-TMP102"; + break; case DEVICE_TEMPERATURE_TMP117: return "Temperature-TMP117"; break; diff --git a/Firmware/OpenLog_Artemis/menuAttachedDevices.ino b/Firmware/OpenLog_Artemis/menuAttachedDevices.ino index 28f37ca..6214bbd 100644 --- a/Firmware/OpenLog_Artemis/menuAttachedDevices.ino +++ b/Firmware/OpenLog_Artemis/menuAttachedDevices.ino @@ -297,6 +297,9 @@ void menuAttachedDevices() case DEVICE_PROXIMITY_VCNL4040: SerialPrintf3("%s VCNL4040 Proximity Sensor %s\r\n", strDeviceMenu, strAddress); break; + case DEVICE_TEMPERATURE_TMP102: + SerialPrintf3("%s TMP102 Temperature Sensor %s\r\n", strDeviceMenu, strAddress); + break; case DEVICE_TEMPERATURE_TMP117: SerialPrintf3("%s TMP117 High Precision Temperature Sensor %s\r\n", strDeviceMenu, strAddress); break; @@ -1643,6 +1646,35 @@ void menuConfigure_VCNL4040(void *configPtr) } + +void menuConfigure_TMP102(void *configPtr) +{ + struct_TMP102 *sensorSetting = (struct_TMP102*)configPtr; + while (1) + { + SerialPrintln(F("")); + SerialPrintln(F("Menu: Configure TMP102 Temperature Sensor")); + + SerialPrint(F("1) Sensor Logging: ")); + if (sensorSetting->log == true) SerialPrintln(F("Enabled")); + else SerialPrintln(F("Disabled")); + + SerialPrintln(F("x) Exit")); + + byte incoming = getByteChoice(menuTimeout); //Timeout after x seconds + + if (incoming == '1') + sensorSetting->log ^= 1; + else if (incoming == 'x') + break; + else if (incoming == STATUS_GETBYTE_TIMEOUT) + break; + else + printUnknown(incoming); + } + +} + void menuConfigure_TMP117(void *configPtr) { struct_TMP117 *sensorSetting = (struct_TMP117*)configPtr; diff --git a/Firmware/OpenLog_Artemis/nvm.ino b/Firmware/OpenLog_Artemis/nvm.ino index 692f70f..9b353a2 100644 --- a/Firmware/OpenLog_Artemis/nvm.ino +++ b/Firmware/OpenLog_Artemis/nvm.ino @@ -587,11 +587,17 @@ void recordDeviceSettingsToFile() settingsFile.println((String)base + "resolution=" + nodeSetting->resolution); } break; + case DEVICE_TEMPERATURE_TMP102: + { + struct_TMP102 *nodeSetting = (struct_TMP102 *)temp->configPtr; + settingsFile.println((String)base + "log=" + nodeSetting->log); + } + break; case DEVICE_TEMPERATURE_TMP117: { struct_TMP117 *nodeSetting = (struct_TMP117 *)temp->configPtr; settingsFile.println((String)base + "log=" + nodeSetting->log); - settingsFile.println((String)base + "logTemperature=" + nodeSetting->logTemperature); + settingsFile.println((String)base + "logTemperature=" + nodeSetting->logTemperature); // JWS: I don't think this value is ever changed? } break; case DEVICE_PRESSURE_MS5637: @@ -1145,13 +1151,22 @@ bool parseDeviceLine(char* str) { SerialPrintf2("Unknown device setting: %s\r\n", deviceSettingName); } break; + case DEVICE_TEMPERATURE_TMP102: + { + struct_TMP102 *nodeSetting = (struct_TMP102 *)deviceConfigPtr; //Create a local pointer that points to same spot as node does + if (strcmp(deviceSettingName, "log") == 0) + nodeSetting->log = d; + else + SerialPrintf2("Unknown device setting: %s\r\n", deviceSettingName); + } + break; case DEVICE_TEMPERATURE_TMP117: { struct_TMP117 *nodeSetting = (struct_TMP117 *)deviceConfigPtr; //Create a local pointer that points to same spot as node does if (strcmp(deviceSettingName, "log") == 0) nodeSetting->log = d; else if (strcmp(deviceSettingName, "logTemperature") == 0) - nodeSetting->logTemperature = d; + nodeSetting->logTemperature = d; // JWS: I don't think this value is ever used?? else SerialPrintf2("Unknown device setting: %s\r\n", deviceSettingName); } diff --git a/Firmware/OpenLog_Artemis/settings.h b/Firmware/OpenLog_Artemis/settings.h index 2323c82..3bc67a0 100644 --- a/Firmware/OpenLog_Artemis/settings.h +++ b/Firmware/OpenLog_Artemis/settings.h @@ -34,6 +34,8 @@ typedef enum DEVICE_ADS1015, DEVICE_PRESSURE_LPS28DFW, DEVICE_LIGHT_VEML7700, + DEVICE_TEMPERATURE_TMP102, + DEVICE_TOTAL_DEVICES, //Marks the end, used to iterate loops DEVICE_UNKNOWN_DEVICE, @@ -170,12 +172,18 @@ struct struct_VL53L1X { unsigned long powerOnDelayMillis = minimumQwiicPowerOnDelay; // Wait for at least this many millis before communicating with this device. Increase if required! }; +struct struct_TMP102 { + bool log = true; + unsigned long powerOnDelayMillis = minimumQwiicPowerOnDelay; // Wait for at least this many millis before communicating with this device. Increase if required! +}; + + #define TMP117_MODE_CONTINUOUS 0 #define TMP117_MODE_SHUTDOWN 1 #define TMP117_MODE_ONESHOT 2 struct struct_TMP117 { bool log = true; - bool logTemperature= true; + bool logTemperature= true; // JWS : This value is set to true here, and then never changed ever again??? int conversionMode = TMP117_MODE_CONTINUOUS; int conversionAverageMode = 0; //Setup for 15.5ms reads int conversionCycle = 0; diff --git a/README.md b/README.md index ac75f68..5677ddf 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ The OpenLog Artemis automatically scans, detects, configures, and logs various Q * [SDP3X Differential Pressure Sensor](https://www.sparkfun.com/products/17874) * [MS8607 Pressure Humidity Temperature Sensor](https://www.sparkfun.com/products/16298) * [MPR0025PA MicroPressure Sensor](https://www.sparkfun.com/products/16476) +* [TMP102 Temperature Sensor] (https://www.sparkfun.com/products/13314) * [TMP117 High Precision Temperature Sensor](https://www.sparkfun.com/products/15805) * [AHT20 Humidity and Temperature Sensor](https://www.sparkfun.com/products/16618) * [SHTC3 Humidity and Temperature Sensor](https://www.sparkfun.com/products/16467) diff --git a/SENSOR_UNITS.md b/SENSOR_UNITS.md index 81e86ca..8377628 100644 --- a/SENSOR_UNITS.md +++ b/SENSOR_UNITS.md @@ -49,6 +49,7 @@ This document summarizes the units used for each sensor measurement. - [MCP9600 thermocouple amplifier](#MCP9600-thermocouple-amplifier) - [Qwiic PT100 ADS122C04 platinum resistance sensor](#Qwiic-PT100-ADS122C04-platinum-resistance-sensor) - [TMP117 precision temperature sensor](#TMP117-precision-temperature-sensor) +- [TMP102 temperature sensor](#TMP102-temperature-sensor) ### Weight: @@ -350,6 +351,13 @@ Fan operational status: | Temperature Internal | degC | Degrees Centigrade | | Raw Voltage | V*2.048/2^23 | Volts * 2.048 / 223 | +--- +## TMP102 temperature sensor + +| []() | | | +|---|---|---| +| Temperature | degC | Degrees Centigrade | + --- ## TMP117 precision temperature sensor