This tutorial describes how to use the Omron D6T Thermal Sensor to detect seat occupancy by measuring temperature with the Arduino board. You may watch the following video or read the written tutorial below for more details.
Introduction of Omron D6T Thermal SensorOmron D6T Thermal Sensors are super-sensitive infrared temperature sensors. Unlike typical pyroelectric human presence sensors that rely on motion detection, the D6T Thermal Sensor is able to detect the presence of stationary humans by detecting body heat, and can therefore be used to automatically switch off unnecessary lighting, air conditioning, etc. when people are not present. In this case, we will learn how to obtain data output from D6T sensor to detect whether a person is on a seat or not.
Step 1: Hardware Components/Cabling RequiredThe materials that we need for accomplishing our goal includes the following hardware components:
Omron Sensor Evaluation boards support evaluation platform such as Raspberry Pi, Adafruit Feather and Arduino. These boards can connect easily to 14 models of Omron sensors over 4 different sensor categories including thermal sensors, flow sensors, light convergent reflective sensors, and air quality sensor, all with optional cable harness. These sensor evaluation boards are equipped with six sensing function types - Barometric pressure, Temperature, Humidity, Light, Noise and Acceleration.
- Arduino (Omron’s evaluation board can be used in the following Arduino: MKR Vidor 4000, MKR WiFi 1010, MKR ZERO)
- Harness: 2JCIE-HARNESS-01
- USB Cable (to connect Arduino and PC)
- Windows PC
The hardware setup section basically explains the wiring connections required among sensors, Arduino and Evaluation Board. Ensuring correct connections is the basic necessity while working on any system for the desired output.
The requisite connections are as follows:
- Solder Evaluation Board
- Connect Arduino to Evaluation Board.
- Connect USB cable and Harness to Evaluation Board
- Using the harness connect the D6T Thermal sensor with the evaluation board
- Place the D6T thermal sensor facing human seating detection area horizontally (optionally, you can also place the sensor on the desk or stick it on your PC for the testing). The D6T sensor should be installed in such a way that the human face is in the field of view.
- Download “Arduino IDE” https://www.arduino.cc/en/Main/Software
Steps to download:
1)
2)
3)
4)
5)
6)
7)
- Run the Arduino IDE on your PC.
- The IDE will look like this.
- Connect Arduino board to PC via USB cable.
- Install the package if there is notification in IDE.
- Install the driver.
- Search ‘Device Manager’ in Windows Start Menu.
- Check the ‘COM Port’.
Sample source code for evaluation of sensors are available on Github and can be modified and implemented independently according to the users’ unique application. Access to the code.
After opening the page. Click ‘Clone or download’ in the upper right and download the ZIP file.
- Please select Arduino board type. (We use MKR WiFi 1010)
- Please select COM port according to your Arduino (Can be checked from Device Manager).
- Open the Sample Code in Arduino IDE.
- Select the code from the examples.
- Compile the sample code.
Confirm this display
- Upload the sample code to Arduino.
Confirm this display
Step 7: Get Data- Output window will look like this:
Here in the output window, PTAT is the temperature inside the thermal sensor. Temperature is the 8 pixel temperature values (as we are using 1x8 thermal sensor). For ex: In the output image, room temperature is approximately 250C. As soon as someone moves his hand closer to the sensor, there will be increase in temperature value. This is because surface temperature of human is higher than the room temperature. On the extreme right of the output window, we have occupancy detection result. If there is human presence in the sensor-installed area, the occupancy turns 1. Otherwise, it remains 0.
Step 8: Observation- Place the D6T thermal sensor facing human seating detection area horizontally (optionally, you can also place the sensor on the desk or stick it on your PC for the testing). The D6T sensor should be installed in such a way that the human face is in the field of view.
- The output from Omron’s thermal sensor are only temperature values. This sample codes uses D6T (1x8) to judge whether a person is present on the seat or not.
- If seat is occupied, occupancy output=1
- If seat is not occupied, occupancy output=0
- The setting parameters can be modified for human detection algorithm (seat occupancy) from the ‘setting parameter’ definition in the code.
OMRON's MEMS Thermal sensor is an infrared temperature sensor that can measure target surface temperature without touching, by receiving radiant heat from the object with thermopile element(s). With its non-contact measurement of target surface temperature, MEMS Thermal sensors can contribute to energy saving, better amenity, productivity improvement by detecting a human or an object or abnormal heat generation of equipment in a various places including a home, building, and/or factory.
ReferencesNote: This code may be revised without prior notice.
/* includes */
#include <Wire.h>
/* defines */
#define D6T_ADDR 0x0A // for I2C 7bit address
#define D6T_CMD 0x4C // for D6T-44L-06/06H, D6T-8L-09/09H, for D6T-1A-01/02
#define N_ROW 8
#define N_PIXEL 8
#define N_READ ((N_PIXEL + 1) * 2 + 1)
/***** Setting Parameter *****/
#define comparingNumInc 6 // x250 ms (example) 6 -> 1.5 sec
#define comparingNumDec 6 // x250 ms (example) 6 -> 1.5 sec
#define threshHoldInc 10 // /10 degC (example) 10 -> 1.0 degC
#define threshHoldDec 10 // /10 degC (example) 10 -> 1.0 degC
bool enablePix[8] = {true, true, true, true, true, true, true, true};
/****************************/
uint8_t rbuf[N_READ];
int16_t pix_data[8] = {0};
int16_t seqData[8][40] = {0};
bool occuPix[8] = {0};
bool occuPixFlag = false;
uint8_t resultOccupancy = 0;
uint16_t totalCount = 0;
/** JUDGE_occupancy: judge occupancy*/
bool judge_seatOccupancy(void) {
int i = 0;
int j = 0;
for (i = 0; i < 8; i++){
for (j = 0; j < 39; j++){
seqData[i][39 - j] = seqData[i][38 - j];
}
seqData[i][0] = pix_data[i];
}
if (totalCount <= comparingNumInc){
totalCount++;
}
if (totalCount > comparingNumInc){
for (i = 0; i < 8; i++){
if (enablePix[i] == true){
if (occuPix[i] == false){
if (seqData[i][0] - seqData[i][comparingNumInc] > threshHoldInc){
occuPix[i] = true;
}
}
else{ //resultOccupancy == true
if (seqData[i][comparingNumDec] - seqData[i][0] > threshHoldDec){
occuPix[i] = false;
}
}
}
}
if (resultOccupancy == 0) {
for (i = 0; i < 8; i++){
if(occuPix[i] == true){
resultOccupancy = 1;
break;
}
}
}
else{
occuPixFlag = false;
for (i = 0; i < 8; i++){
if (occuPix[i] == true){
occuPixFlag = true;
break;
}
else{
}
}
if (occuPixFlag == false){
resultOccupancy = 0;
}
}
}
return true;
}
uint8_t calc_crc(uint8_t data) {
int index;
uint8_t temp;
for (index = 0; index < 8; index++) {
temp = data;
data <<= 1;
if (temp & 0x80) {data ^= 0x07;}
}
return data;
}
/** <!-- D6T_checkPEC {{{ 1--> D6T PEC(Packet Error Check) calculation.
* calculate the data sequence,
* from an I2C Read client address (8bit) to thermal data end.
*/
bool D6T_checkPEC(uint8_t buf[], int n) {
int i;
uint8_t crc = calc_crc((D6T_ADDR << 1) | 1); // I2C Read address (8bit)
for (i = 0; i < n; i++) {
crc = calc_crc(buf[i] ^ crc);
}
bool ret = crc != buf[n];
if (ret) {
Serial.print("PEC check failed:");
Serial.print(crc, HEX);
Serial.print("(cal) vs ");
Serial.print(buf[n], HEX);
Serial.println("(get)");
}
return ret;
}
/** <!-- conv8us_s16_le {{{1 --> convert a 16bit data from the byte stream.
*/
int16_t conv8us_s16_le(uint8_t* buf, int n) {
int ret;
ret = buf[n];
ret += buf[n + 1] << 8;
return (int16_t)ret; // and convert negative.
}
/** <!-- setup {{{1 -->
* 1. initialize a Serial port for output.
* 2. initialize an I2C peripheral.
*/
void setup() {
Serial.begin(115200); // Serial baudrate = 115200bps
Wire.begin(); // i2c master
Wire.beginTransmission(D6T_ADDR); // I2C client address
Wire.write(0x02); // D6T register
Wire.write(0x00); // D6T register
Wire.write(0x01); // D6T register
Wire.write(0xEE); // D6T register
Wire.endTransmission(); // I2C repeated start for read
Wire.beginTransmission(D6T_ADDR); // I2C client address
Wire.write(0x05); // D6T register
Wire.write(0x90); // D6T register
Wire.write(0x3A); // D6T register
Wire.write(0xB8); // D6T register
Wire.endTransmission(); // I2C repeated start for read
Wire.beginTransmission(D6T_ADDR); // I2C client address
Wire.write(0x03); // D6T register
Wire.write(0x00); // D6T register
Wire.write(0x03); // D6T register
Wire.write(0x8B); // D6T register
Wire.endTransmission(); // I2C repeated start for read
Wire.beginTransmission(D6T_ADDR); // I2C client address
Wire.write(0x03); // D6T register
Wire.write(0x00); // D6T register
Wire.write(0x07); // D6T register
Wire.write(0x97); // D6T register
Wire.endTransmission(); // I2C repeated start for read
Wire.beginTransmission(D6T_ADDR); // I2C client address
Wire.write(0x02); // D6T register
Wire.write(0x00); // D6T register
Wire.write(0x00); // D6T register
Wire.write(0xE9); // D6T register
Wire.endTransmission(); // I2C repeated start for read
}
/** <!-- loop - Thermal sensor {{{1 -->
* 1. read sensor.
* 2. output results, format is: [degC]
*/
void loop() {
int i, j;
memset(rbuf, 0, N_READ);
// Wire buffers are enough to read D6T-16L data (33bytes) with
// MKR-WiFi1010 and Feather ESP32,
// these have 256 and 128 buffers in their libraries.
Wire.beginTransmission(D6T_ADDR); // I2C client address
Wire.write(D6T_CMD); // D6T register
Wire.endTransmission(); // I2C repeated start for read
Wire.requestFrom(D6T_ADDR, N_READ);
i = 0;
while (Wire.available()) {
rbuf[i++] = Wire.read();
}
if (D6T_checkPEC(rbuf, N_READ - 1)) {
return;
}
// 1st data is PTAT measurement (: Proportional To Absolute Temperature)
int16_t itemp = conv8us_s16_le(rbuf, 0);
Serial.print("PTAT:");
Serial.print(itemp / 10.0, 1);
Serial.print(", Temperature:");
// loop temperature pixels of each thrmopiles measurements
for (i = 0, j = 2; i < N_PIXEL; i++, j += 2) {
itemp = conv8us_s16_le(rbuf, j);
pix_data[j - 2] = itemp;
Serial.print(itemp / 10.0, 1); // print PTAT & Temperature
if ((i % N_ROW) == N_ROW - 1) {
Serial.print(" [degC]"); // wrap text at ROW end.
} else {
Serial.print(","); // print delimiter
}
}
judge_seatOccupancy(); //add
Serial.print(", Occupancy:");
Serial.println(resultOccupancy, 1);
delay(250);
}
// vi: ft=arduino:fdm=marker:et:sw=4:tw=80
Comments
Please log in or sign up to comment.