Skip to content

Commit 989429e

Browse files
JLefebvre55angusjhwuurmilmodi
authored
Sensor Library - TMP006 (#12)
* my sensor testing code for mpu9250 * sensor testing code for tmp006 (last updated dec 30, 2020) * removed excess file * TMP006 Libraries * restructured repo and added readme * Added Gitignore * Added sensor info/details Added sensor output ranges and units, intended use, and code description * my sensor testing code for mpu9250 * sensor testing code for tmp006 (last updated dec 30, 2020) * removed excess file * TMP006 Libraries * restructured repo and added readme * Added sensor info/details Added sensor output ranges and units, intended use, and code description * Library * found potential bug, updated todos * Sensor Implementation Template * Implementation * Adafruit Compatibility Fix * Restructured for Compilation * Fixed Error Checking Co-authored-by: Angus Wu <wuangusjh@gmail.com> Co-authored-by: Angus Wu <78286686+AngusWu25@users.noreply.github.com> Co-authored-by: Urmil Modi <urmilnmodi@gmail.com>
1 parent 16f86d0 commit 989429e

File tree

9 files changed

+755
-0
lines changed

9 files changed

+755
-0
lines changed

TMP006/README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# TMP006
2+
3+
## Sensor Information
4+
5+
### Sensor Output
6+
- Die temperature [Celsius], range: unspecified in official documentation
7+
- Object temperature [Celsius] (calculated from die temp and die voltage), range: -40[C] to 125[C]
8+
9+
### Sensor Use
10+
Sensor is intended to be used in auxiliary, to obtain data for pod improvement.
11+
- Measure the temperature around the center of the pod
12+
13+
### Code Description
14+
1. Sensor checks connection with Arduino
15+
2. Returns the object temperature and die temperature according to the configured sampling rate
16+
3. The sensor can be put to sleep or wake up through serial command
17+
18+
### Supporting Documentation
19+
> Documentation for the **TMP006** can be found [here](https://drive.google.com/drive/folders/14W78F2MIxz7_K_xL1_n9KY-3X8qnph70?usp=sharing).
20+
21+
22+
## Todo
23+
24+
- [ ] Setup, testing, and expected output documentation (screenshot, pictures, logs/stack traces, etc.);
25+
- [ ] A list of dependencies (and links to those);
26+
- [ ] Everything else that is listed under [the master `README`](../README.md).
27+
28+
# Development
29+
30+
## Dependencies
31+
32+
- ...
33+
34+
## Testing
35+
36+
### Setup
37+
38+
...
39+
40+
### Procedure
41+
42+
...
43+
44+
### Expected Output
45+
46+
...

TMP006/TMP006.ino

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Headers for each sensor type
2+
#include "src/TMP006.h"
3+
//...
4+
5+
#include "src/Sensor.h"
6+
#define NUMSENSORS 1 //Or however many
7+
#define BAUDRATE 115200
8+
#define THISARDUINO ARDUINO_ONE
9+
10+
// Objects for each sensor
11+
TMP006 tmp006(TMP006_I2CADDR, THISARDUINO);
12+
//...
13+
14+
Sensor* sensors[NUMSENSORS] = {
15+
// Entry for each sensor object
16+
&tmp006,
17+
18+
//...
19+
};
20+
21+
// !#!#!#!--- EVERYTHING AFTER HERE DOES NOT NEED TO BE CHANGED FOR SENSOR IMPLEMENTATION ---!#!#!#!
22+
23+
void setup(){
24+
Serial.begin(BAUDRATE);
25+
26+
bool success = true;
27+
for(int i = 0; i < NUMSENSORS; i++){
28+
SensorState* state = sensors[i]->begin();
29+
30+
// Print/send sensor post-setup state data here. For example:
31+
bool _success = (state->error == ERR_NONE);
32+
if(_success){
33+
Serial.print("Sensor ");
34+
Serial.print(sensors[i]->sensor);
35+
Serial.println(" initialized.");
36+
} else {
37+
Serial.print("Sensor ");
38+
Serial.print(sensors[i]->sensor);
39+
Serial.println(" failed to initialize!");
40+
}
41+
success &= _success;
42+
}
43+
if(!success){
44+
Serial.println("POST failed on one or more sensors, freezing...");
45+
while(1){delay(1000);}
46+
}
47+
}
48+
49+
void loop(){
50+
for(int i = 0; i < NUMSENSORS; i++){
51+
SensorState* state = sensors[i]->update();
52+
// Print/send sensor post-setup state data here. For example:
53+
bool _success = (state->error == ERR_NONE);
54+
bool _new = (state->debug == DS_NEWREAD);
55+
if(_success){
56+
if(_new){
57+
Serial.print("Sensor ");
58+
Serial.print(sensors[i]->sensor);
59+
Serial.print(" read success: ");
60+
for(int x = 0; x < state->numdata; x++){
61+
Serial.print(state->data[x].data);
62+
Serial.print(' ');
63+
Serial.print(state->data[x].units);
64+
if(x < state->numdata-1){Serial.print(", ");}else{Serial.println();}
65+
}
66+
}
67+
} else {
68+
Serial.print("Sensor ");
69+
Serial.print(sensors[i]->sensor);
70+
Serial.println(" failed to update!");
71+
// TODO: Recover failed sensor?
72+
}
73+
}
74+
}

TMP006/src/Adafruit_TMP006.cpp

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
/***************************************************
2+
This is a library for the TMP006 Temp Sensor
3+
4+
Designed specifically to work with the Adafruit TMP006 Breakout
5+
----> https://www.adafruit.com/products/1296
6+
7+
These displays use I2C to communicate, 2 pins are required to
8+
interface
9+
Adafruit invests time and resources providing this open source code,
10+
please support Adafruit and open-source hardware by purchasing
11+
products from Adafruit!
12+
13+
Written by Limor Fried/Ladyada for Adafruit Industries.
14+
BSD license, all text above must be included in any redistribution
15+
****************************************************/
16+
17+
#include "Adafruit_TMP006.h"
18+
19+
//#define TESTDIE 0x0C78
20+
//#define TESTVOLT 0xFEED
21+
22+
/**************************************************************************/
23+
/*!
24+
@brief Constructor for TMP006 sensor object
25+
@param i2caddr The I2C sensor address to use
26+
*/
27+
/**************************************************************************/
28+
Adafruit_TMP006::Adafruit_TMP006(uint8_t i2caddr) { _addr = i2caddr; }
29+
30+
/**************************************************************************/
31+
/*!
32+
@brief Initialize I2C and connect to the TMP006 sensor
33+
@param samplerate The value written to TMP006_CONFIG
34+
@returns True if sensor found
35+
*/
36+
/**************************************************************************/
37+
boolean Adafruit_TMP006::begin(uint16_t samplerate) {
38+
Wire.begin();
39+
40+
write16(TMP006_CONFIG, TMP006_CFG_MODEON | TMP006_CFG_DRDYEN | samplerate);
41+
42+
uint16_t mid, did;
43+
mid = read16(TMP006_MANID);
44+
did = read16(TMP006_DEVID);
45+
#ifdef TMP006_DEBUG
46+
Serial.print("mid = 0x");
47+
Serial.println(mid, HEX);
48+
Serial.print("did = 0x");
49+
Serial.println(did, HEX);
50+
#endif
51+
if (mid != 0x5449)
52+
return false;
53+
if (did != 0x67)
54+
return false;
55+
return true;
56+
}
57+
58+
/**************************************************************************/
59+
/*!
60+
@brief Enter sleep mode
61+
*/
62+
/**************************************************************************/
63+
void Adafruit_TMP006::sleep() {
64+
// Read the control register and update it so bits 12-14 are zero to enter
65+
// sleep mode.
66+
uint16_t control = read16(TMP006_CONFIG);
67+
control &= ~(TMP006_CFG_MODEON);
68+
write16(TMP006_CONFIG, control);
69+
}
70+
71+
/**************************************************************************/
72+
/*!
73+
@brief Wake from sleep mode
74+
*/
75+
/**************************************************************************/
76+
void Adafruit_TMP006::wake() {
77+
// Read the control register and update it so bits 12-14 are one to enter full
78+
// operation.
79+
uint16_t control = read16(TMP006_CONFIG);
80+
control |= TMP006_CFG_MODEON;
81+
write16(TMP006_CONFIG, control);
82+
}
83+
84+
/**************************************************************************/
85+
/*!
86+
@brief Read the calibrated die temperature
87+
@returns double The calculated temperature of the sensor itself
88+
*/
89+
/**************************************************************************/
90+
double Adafruit_TMP006::readDieTempC(void) {
91+
double Tdie = readRawDieTemperature();
92+
Tdie *= 0.03125; // convert to celsius
93+
#ifdef TMP006_DEBUG
94+
Serial.print("Tdie = ");
95+
Serial.print(Tdie);
96+
Serial.println(" C");
97+
#endif
98+
return Tdie;
99+
}
100+
101+
/**************************************************************************/
102+
/*!
103+
@brief Read the calibrated object temperature
104+
@returns double The calculated temperature of the object in front of sensor
105+
*/
106+
/**************************************************************************/
107+
double Adafruit_TMP006::readObjTempC(void) {
108+
double Tdie = readRawDieTemperature();
109+
double Vobj = readRawVoltage();
110+
Vobj *= 156.25; // 156.25 nV per LSB
111+
Vobj /= 1000; // nV -> uV
112+
Vobj /= 1000; // uV -> mV
113+
Vobj /= 1000; // mV -> V
114+
Tdie *= 0.03125; // convert to celsius
115+
Tdie += 273.15; // convert to kelvin
116+
117+
#ifdef TMP006_DEBUG
118+
Serial.print("Vobj = ");
119+
Serial.print(Vobj * 1000000);
120+
Serial.println("uV");
121+
Serial.print("Tdie = ");
122+
Serial.print(Tdie);
123+
Serial.println(" C");
124+
#endif
125+
126+
double tdie_tref = Tdie - TMP006_TREF;
127+
double S = (1 + TMP006_A1 * tdie_tref + TMP006_A2 * tdie_tref * tdie_tref);
128+
S *= TMP006_S0;
129+
S /= 10000000;
130+
S /= 10000000;
131+
132+
double Vos =
133+
TMP006_B0 + TMP006_B1 * tdie_tref + TMP006_B2 * tdie_tref * tdie_tref;
134+
135+
double fVobj = (Vobj - Vos) + TMP006_C2 * (Vobj - Vos) * (Vobj - Vos);
136+
137+
double Tobj = sqrt(sqrt(Tdie * Tdie * Tdie * Tdie + fVobj / S));
138+
139+
Tobj -= 273.15; // Kelvin -> *C
140+
return Tobj;
141+
}
142+
143+
/**************************************************************************/
144+
/*!
145+
@brief Read the raw, uncalibrated die temperature
146+
@returns int16_t The raw data read from the TMP006_TAMB register
147+
*/
148+
/**************************************************************************/
149+
int16_t Adafruit_TMP006::readRawDieTemperature(void) {
150+
int16_t raw = read16(TMP006_TAMB);
151+
152+
#if TMP006_DEBUG == 1
153+
154+
#ifdef TESTDIE
155+
raw = TESTDIE;
156+
#endif
157+
158+
Serial.print("Raw Tambient: 0x");
159+
Serial.print(raw, HEX);
160+
161+
float v = raw / 4;
162+
v *= 0.03125;
163+
Serial.print(" (");
164+
Serial.print(v);
165+
Serial.println(" *C)");
166+
#endif
167+
raw >>= 2;
168+
return raw;
169+
}
170+
171+
/**************************************************************************/
172+
/*!
173+
@brief Read the raw, uncalibrated thermopile voltage
174+
@returns int16_t The raw data read from the TMP006_VOBJ register
175+
*/
176+
/**************************************************************************/
177+
int16_t Adafruit_TMP006::readRawVoltage(void) {
178+
int16_t raw;
179+
180+
raw = read16(TMP006_VOBJ);
181+
182+
#if TMP006_DEBUG == 1
183+
184+
#ifdef TESTVOLT
185+
raw = TESTVOLT;
186+
#endif
187+
188+
Serial.print("Raw voltage: 0x");
189+
Serial.print(raw, HEX);
190+
float v = raw;
191+
v *= 156.25;
192+
v /= 1000;
193+
Serial.print(" (");
194+
Serial.print(v);
195+
Serial.println(" uV)");
196+
#endif
197+
return raw;
198+
}
199+
200+
/**************************************************************************/
201+
/*!
202+
@brief Read uint16_t bits of data from a register
203+
@param a The register address to write to
204+
@returns uint16_t The data read from the register
205+
*/
206+
/**************************************************************************/
207+
uint16_t Adafruit_TMP006::read16(uint8_t a) {
208+
uint16_t ret;
209+
210+
Wire.beginTransmission(_addr); // start transmission to device
211+
#if (ARDUINO >= 100)
212+
Wire.write(a); // sends register address to read from
213+
#else
214+
Wire.send(a); // sends register address to read from
215+
#endif
216+
Wire.endTransmission(); // end transmission
217+
218+
Wire.requestFrom(_addr, (uint8_t)2); // send data n-bytes read
219+
#if (ARDUINO >= 100)
220+
ret = Wire.read(); // receive DATA
221+
ret <<= 8;
222+
ret |= Wire.read(); // receive DATA
223+
#else
224+
ret = Wire.receive(); // receive DATA
225+
ret <<= 8;
226+
ret |= Wire.receive(); // receive DATA
227+
#endif
228+
229+
return ret;
230+
}
231+
232+
/**************************************************************************/
233+
/*!
234+
@brief Write uint16_t bits of data to a register
235+
@param a The register address to write to
236+
@param d The data to write to the register
237+
*/
238+
/**************************************************************************/
239+
void Adafruit_TMP006::write16(uint8_t a, uint16_t d) {
240+
Wire.beginTransmission(_addr); // start transmission to device
241+
#if (ARDUINO >= 100)
242+
Wire.write(a); // sends register address to read from
243+
Wire.write(d >> 8); // write data
244+
Wire.write(d); // write data
245+
#else
246+
Wire.send(a); // sends register address to read from
247+
Wire.send(d >> 8); // write data
248+
Wire.send(d); // write data
249+
#endif
250+
Wire.endTransmission(); // end transmission
251+
}

0 commit comments

Comments
 (0)