Programming OMRON D6T 1A 01 and uploading data into database

Hi all,

I am a beginner in Arduino and I bought an Omron D6T 1A 01 temperature sensor. I'm just having trouble with information and knowledge as well. I have Wemos D1 mini microcontroller based on the esp8266 module.

My plan would be to run a database on a raspberry and a D1 mini send a temperatue data via wifi.
Here is a picture that properly explains what i want.

I found an excellenet tutorial about it but not my sensor and not my microcontroller. Here is the link.

So I think I need to merge my code and the code in the tutorial. (5. step) I attach my omron code.

/* 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 1
#define N_PIXEL 1

#define N_READ ((N_PIXEL + 1) * 2 + 1)
uint8_t rbuf[N_READ];


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
}


/** <!-- 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.println(itemp / 10.0, 1);

    // loop temperature pixels of each thrmopiles measurements
    for (i = 0, j = 2; i < N_PIXEL; i++, j += 2) {
        itemp = conv8us_s16_le(rbuf, j);
        Serial.print(itemp / 10.0, 1);  // print PTAT & Temperature
        if ((i % N_ROW) == N_ROW - 1) {
            Serial.println(" [degC]");  // wrap text at ROW end.
        } else {
            Serial.print(",");   // print delimiter
        }
    }
    delay(1000);
}
// vi: ft=arduino:fdm=marker:et:sw=4:tw=80

Can anyone help me with this? Thank you very much!

Please show the sketch on this forum. Put the sketch between code tags, that is the '< / >' button.
After you have posted, you can see the link to your attachment. Then you can "Modify" your post and insert a picture with a link to your own attachment. That way the picture is shown and we don't have to open attachments.
Give also links, picture, photos, schematics and drawings :o Even if it is only to give us an idea what you are doing :wink:

Omron D6T-1A-01: http://components.omron.eu/Product-details/D6T-1A-01

It seems that it is a 5V I2C sensor. Is that correct ? The ESP8266 runs at 3.3V. Is the I2C bus from the ESP8266 compatible with that 5V sensor ? Is that specified somewhere in a datasheet ? I can not find that. If that is not mentioned somewhere, perhaps you can ask the manufacturer. Maybe a I2C level shifter is needed.

Is your sketch working ? Have you confirmed that the data is indeed what you want ?

The database is on the Raspberry Pi, so all the complex things are on the Raspberry Pi.
You should make a database with data that is for your sensor.
The database is now for: "sensor, location, value1, value2, value3, reading_time".
I know almost nothing about a MySQL database. If you have questions about that, then you can try the forum at raspberrypi.org or stackexchange. I think the nerds at stackexchange are the most eager to answer your questions :wink:

The ESP8266 reads the sensor and uploads the data, that's all.

In the sketch, the line "Serial.println(httpRequestData);" uploads the data.
So you should check how that is created:

String httpRequestData = "api_key=" + apiKeyValue + "&sensor=" + sensorName + "&location=" + sensorLocation + "&value1=" + String(bme.readTemperature()) + "&value2=" + String(bme.readHumidity()) + "&value3=" + String(bme.readPressure()/100.0F) + "";

That is the part that works together with the database.

First of all thank you for your answer.

I think it works with 5V because my sensor works fine. I got perfect temp data.

I merged my code with his code. What do you think about that? It can works? I can't call a bme.gettemperature...

#ifdef ESP32
  #include <WiFi.h>
  #include <HTTPClient.h>
#else
  #include <ESP8266WiFi.h>
  #include <ESP8266HTTPClient.h>
  #include <WiFiClient.h>
#endif


#include <Wire.h>

String apiKeyValue = "tPmAT5Ab3j7F9";

String sensorName = "D6T-1A-01";
String sensorLocation = "Office";

// Replace with your network credentials
const char* ssid     = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// REPLACE with your Domain name and URL path or IP address with path
const char* serverName = "http://example.com/post-esp-data.php";

/* 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 1
#define N_PIXEL 1

#define N_READ ((N_PIXEL + 1) * 2 + 1)
uint8_t rbuf[N_READ];

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() {
  
  WiFi.begin(ssid, password);
  Serial.println("Connecting");

 while(WiFi.status() != WL_CONNECTED) { 
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());

  // (you can also pass in a Wire library object like &Wire2)
  bool status = bme.begin(0x76); // ---> [b]WHAT AM I WRITING HERE??? I HAVE OMRON D6T-1A-01[/b]
  if (!status) {
    Serial.println("Could not find a valid BME280 sensor, check wiring or change I2C address!");
    while (1);
  }

  
  Serial.begin(115200);  // Serial baudrate = 115200bps
  Serial.println("Datum es ido, Testhomerseklet degC");
  Wire.begin();  // i2c master
}


/** <!-- loop - Thermal sensor {{{1 -->
   1. read sensor.
   2. output results, format is: [degC]
*/
void loop() {

  //Check WiFi connection status
  if(WiFi.status()== WL_CONNECTED){
    HTTPClient http;
    
    // Your Domain name with URL path or IP address with path
    http.begin(serverName);
    
    // Specify content-type header
    http.addHeader("Content-Type", "application/x-www-form-urlencoded");
    
    // Prepare your HTTP POST request data
    String httpRequestData = "api_key=" + apiKeyValue + "&sensor=" + sensorName
                          + "&location=" + sensorLocation + "&value1=" + String(bme.readTemperature() + ""; 

[b]//[u] ---> WHAT AM I WRITING HERE?????[/u][/b]

    Serial.print("httpRequestData: ");
    Serial.println(httpRequestData);
    
    // You can comment the httpRequestData variable above
    // then, use the httpRequestData variable below (for testing purposes without the BME280 sensor)
    //String httpRequestData = "api_key=tPmAT5Ab3j7F9&sensor=BME280&location=Office&value1=24.75&value2=49.54&value3=1005.14";

    // Send HTTP POST request
    int httpResponseCode = http.POST(httpRequestData);
     
    // If you need an HTTP request with a content type: text/plain
    //http.addHeader("Content-Type", "text/plain");
    //int httpResponseCode = http.POST("Hello, World!");
    
    // If you need an HTTP request with a content type: application/json, use the following:
    //http.addHeader("Content-Type", "application/json");
    //int httpResponseCode = http.POST("{\"value1\":\"19\",\"value2\":\"67\",\"value3\":\"78\"}");
        
    if (httpResponseCode>0) {
      Serial.print("HTTP Response code: ");
      Serial.println(httpResponseCode);
    }
    else {
      Serial.print("Error code: ");
      Serial.println(httpResponseCode);
    }
    // Free resources
    http.end();
  }
  else {
    Serial.println("WiFi Disconnected");
  }
  //Send an HTTP POST request every 30 seconds
  delay(30000);  
  
  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);

  // loop temperature pixels of each thrmopiles measurements
  /*for (i = 0, j = 2; i < N_PIXEL; i++, j += 2) { 
      itemp = conv8us_s16_le(rbuf, j);
      Serial.print(itemp / 10.0, 1);  // print PTAT & Temperature
      if ((i % N_ROW) == N_ROW - 1) {
          Serial.println(" [degC]");  // wrap text at ROW end.
      } else {
          Serial.print(",");   // print delimiter
      }
    }
  */
  int16_t itemp = conv8us_s16_le(rbuf, 2);

 


  //Serial.println(" [degC]");  // wrap text at ROW end.

  Serial.print(";");
  Serial.println(itemp / 10.0, 1);// print PTAT & Temperature




  delay(1000);
}

'value1' is set to String(bme.readTemperature().
I think you can put your complete array in 'value1'.
So you have to know how you can turn your binary array into readable ASCII. For debugging it is easier when it is a readable string. A URL should also be according to the standard: HTML URL Encoding Reference.

You could, for example, turn the byte 0x23 into the ASCII string "23". Is your array 32 or 33 bytes ? then convert them all to readable ASCII representing a hexadecimal value. That will double the size.

I don't know what is best to store in the database. Perhaps the binairy data would be more appropriate then the readable ASCII. That means you have to convert it to binairy data.