# XN04 - Temp-Hum / Lum

<figure><img src="https://docs.microside.com/~gitbook/image?url=https%3A%2F%2F177299348-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FbyV2zAlQAiqg46a3Lr8z%252Fuploads%252FxC8gXjNba3Sn4kr3jy75%252FMODULO%2520SENSOR%2520X-NODE%2520Temperatura%2520Humedad%2520Luminosidad%2520XN04%2520XIDE%2520MICROSIDE%252001.webp%3Falt%3Dmedia%26token%3D791c44ea-e72e-4eb7-8f4c-265e4bdc451c&#x26;width=768&#x26;dpr=1&#x26;quality=100&#x26;sign=af4776d&#x26;sv=2" alt=""><figcaption><p>XN04 - Temperature - Humidity - Ambient Light </p></figcaption></figure>

**X-NODE Temp-Hum / Lum** is a module that allows measurement of 3 environmental variables: **Temperature, Humidity and Ambient Light**. Ideal for IoT projects requiring control and monitoring of closed systems, such as air conditioning, refrigeration chambers, or automatic lighting adjustments. This module simplifies designs by reducing the need for multiple devices, offering a compact and efficient solution for monitoring applications.

### TABLE OF CONTENTS

1. [**How does it work?**](#i.-how-does-it-work)
2. [**Hardware description**](#ii.-hardware-description)
3. [**Specifications**](#iii.-specifications)
4. [**Pinout**](#iv.-pinout)
5. [**Usage**](#v.-usage)
   * [**UARTProtocol**](#uart-protocol)
   * [**UART Example Arduino Framework**](#uart-example-arduino-framework)
   * [**I2C Protocol**](#i2c-protocol)
   * [**I2C Example Arduino Framework**](#i2c-example-arduino-framework)
6. [**Downloads**](#vi.-downloads)
   * [**Schematic**](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbyV2zAlQAiqg46a3Lr8z%2Fuploads%2FcFaznEDQxatEy6prNwMl%2Fschematic.pdf?alt=media\&token=bff01aea-d514-49e9-8d7b-c41ae9a939ef)
   * [**Dimensions**](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbyV2zAlQAiqg46a3Lr8z%2Fuploads%2FEAvXcjTy4yVAr0qRZMzF%2Fdimensions.pdf?alt=media\&token=0d1a1c2b-f723-4763-bdcd-eb254c8511f1)

## I. How does it work?

The **X-NODE Temp-Hum / Lum** is a module that combines 2 sensors: a [SHT40](https://sensirion.com/resource/datasheet/sht4x) from [Sensirion®](https://sensirion.com/) for measuring ambient temperature/humidity and an [LTR-329ALS](https://optoelectronics.liteon.com/upload/download/DS86-2014-0006/LTR-329ALS-01_DS_V1.pdf) from [LITEON®](https://www.liteon.com/en) for measuring indoor brightness. It also comes with an integrated controller, that allows you to obtain these variables using a series of *ASCII* commands.

**X-NODE Temp-Hum / Lum** is compatible with the [mikroBUS™](https://www.mikroe.com/mikrobus) standard from [Mikroe®](https://www.mikroe.com/) for easy use with a large ecosystem of hardware development kits, and also features JST connectors compatible with the [Qwiic®](https://www.sparkfun.com/qwiic) standard from [SparkFun®](https://www.sparkfun.com/) for quick and easy I2C communication between various modules and development boards.

## II. Hardware description

<figure><img src="https://docs.microside.com/~gitbook/image?url=https%3A%2F%2F177299348-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FbyV2zAlQAiqg46a3Lr8z%252Fuploads%252Fp5l4BaQ1xYzos4ogJPiQ%252Fuser-manual-hardware-description.webp%3Falt%3Dmedia%26token%3D087e85bf-ee99-4d51-9c1c-c39ce08ac6de&#x26;width=768&#x26;dpr=1&#x26;quality=100&#x26;sign=f8ccd656&#x26;sv=2" alt=""><figcaption></figcaption></figure>

1. [SHT40](https://sensirion.com/resource/datasheet/sht4x) sensor from [Sensirion®](https://sensirion.com/)
2. JST connectors compatible with [Qwiic®](https://www.sparkfun.com/qwiic)
3. [LTR-329ALS](https://optoelectronics.liteon.com/upload/download/DS86-2014-0006/LTR-329ALS-01_DS_V1.pdf) sensor from [LITEON®](https://www.liteon.com/en)
4. Hardware controller
5. UART <> I2C communication ports
6. X-NODE model
7. X-NODE type
8. [mikroBUS™](https://www.mikroe.com/mikrobus) standard connectors
9. Jumper pad to enable native I2C communication\* with the sensors.
10. Hardware version: R2
11. Main components on the X-NODE

{% hint style="info" %}
**Note:** The **X-NODE Temp-Hum / Lum** includes a hardware controller to simplify implementation, however, if you wish to use the sensors' native I2C protocol, you must send the command to turn off the hardware controller (see usage) and solder the I2C-EN pads (9).
{% endhint %}

## III. Specifications

<table data-header-hidden><thead><tr><th width="148"></th><th></th></tr></thead><tbody><tr><td><strong>Type</strong></td><td>Temperature, humidity, and ambient light sensor</td></tr><tr><td><strong>Applications</strong></td><td>Development of IoT systems requiring monitoring within closed systems, such as air conditioning, refrigeration chambers, or automatic lighting adjustments.</td></tr><tr><td><strong>Module 1</strong></td><td><a href="https://sensirion.com/resource/datasheet/sht4x">SHT40</a></td></tr><tr><td><strong>Manufacturer</strong></td><td><a href="https://sensirion.com/">Sensirion®</a></td></tr><tr><td><strong>Module 2</strong></td><td><a href="https://optoelectronics.liteon.com/upload/download/DS86-2014-0006/LTR-329ALS-01_DS_V1.pdf">LTR-329ALS</a></td></tr><tr><td><strong>Manufacturer</strong></td><td><a href="https://www.liteon.com/en">LITEON®</a></td></tr><tr><td><strong>Features</strong></td><td>* Temperature and humidity sensor with detection from 0 °C to 85 °C with typical accuracy of +/- 0.2 °C and +/- 1.8% RH, automatic calibration, 0.5 mA consumption, and high signal-to-noise ratio.<br>* Ambient light sensor with detection from 0.01 to 64 klx, 50 Hz/60 Hz noise suppression, and typical consumption of 90µA.</td></tr><tr><td><strong>Interface</strong></td><td>UART, I2C</td></tr><tr><td><strong>Compatibility</strong></td><td>mikroBUS™ standard and Qwiic® standard</td></tr><tr><td><strong>Size</strong></td><td>41 x 25.4 x 20.5 mm</td></tr><tr><td><strong>Voltage</strong></td><td>3.3 V</td></tr></tbody></table>

{% hint style="info" %}
For complete technical information, you can download each manufacturer's specifications at the following links: [SHT40](https://sensirion.com/resource/datasheet/sht4x) - [LTR-329ALS](https://optoelectronics.liteon.com/upload/download/DS86-2014-0006/LTR-329ALS-01_DS_V1.pdf)
{% endhint %}

## IV. Pinout

The following table shows the pinout of the **X-NODE Temp-Hum / Lum** with respect to the [mikroBUS™](https://www.mikroe.com/mikrobus) standard (the latter is in the two center columns).

<figure><img src="https://docs.microside.com/~gitbook/image?url=https%3A%2F%2F177299348-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FbyV2zAlQAiqg46a3Lr8z%252Fuploads%252FJo1oZSK1hQRwkYoRQILz%252Fuser-manual-mikrobus-pinout-table.jpg%3Falt%3Dmedia%26token%3D658ae120-a66c-401f-8bd0-e8a7e97a22e6&#x26;width=768&#x26;dpr=4&#x26;quality=100&#x26;sign=ed36da55&#x26;sv=2" alt=""><figcaption></figcaption></figure>

## V. Usage

For easy and quick use of the X-NODE, you can use the ASCII command set provided by the integrated hardware controller via UART serial communication, or more advanced use via the I2C protocol.

### UART Protocol

**Configuration**

UART communication uses the following configuration:

* Baud rate: 115,200 bps
* Parity: None
* Data bits: 8
* Stop bits: 1

**Syntax**

The UART protocol allows sending instructions in plain *ASCII* text. Each instruction consists of the X-NODE identifier, a command, and an end-of-line.

**Identifier**

The **ID** identifier is made up of the X-NODE model, which can be found at point 6 in the Hardware description section, and is complemented by an index, which can be a letter from A to Z, by default is **A**. To connect more than one module of the same model in a system, you must configure a unique identifier for each module, allowing up to 26 modules of the same model to be connected via UART protocol\*.

<figure><img src="https://3632356340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwzhjxMFtAHZqHlRBU68T%2Fuploads%2FED7Sf3SaCFWSNeMfKRVR%2FProtocol%20UART%20X-NODE%20Temperatura%20-%20Humedad%20Proximidad%20-%20%20Luminosidad.jpg?alt=media&#x26;token=6ad79ef9-edcb-4c5b-8dde-aab162c7070d" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
**Note:** From this point on, the default index of the **X-NODE Temp-Hum / Lum** will be used for the rest of the manual: **XN04A**.
{% endhint %}

**Command list**

<table data-header-hidden><thead><tr><th width="177"></th><th></th></tr></thead><tbody><tr><td><strong>XN04A?</strong></td><td>Checks if communication was established successfully.<br><strong>Response if successful:</strong> OK<br><strong>Response if error:</strong> XN04A=Error<br><strong>Example:</strong> XN04A=3<br><strong>Error codes:</strong><br><strong>1:</strong> Temperature/humidity sensor error<br><strong>2:</strong> Light sensor error<br><strong>3:</strong> Both sensors errored</td></tr><tr><td><strong>XN04A+V</strong></td><td>Gets the current firmware version integrated in the X-NODE.<br><strong>Response:</strong> XN04A=Version<br><strong>Example:</strong> XN04A=2.0.0</td></tr><tr><td><strong>XN04A+ID=(A-Z)</strong></td><td>Changes the ID index to a different uppercase letter from A to Z. Once changed, you must use the new ID to change it again.<br><strong>Response:</strong> OK<br><strong>Example:</strong> XN04C+ID=H</td></tr><tr><td><strong>XN04A+TW=(1-126)</strong></td><td>Changes the factory I2C address to a different one, this only takes effect if the hardware driver is not disabled. The new address is written in decimal, selecting a value from 1 to 126.<br><strong>Response:</strong> OK<br><strong>Example:</strong> XN04A+TW=28</td></tr><tr><td><strong>XN04A+GT</strong></td><td>Gets the temperature value from the sensor. Returns the final value in °C with two decimals.<br><strong>Response:</strong> XN04A=VAL<br><strong>Example:</strong> XN04A=27.81</td></tr><tr><td><strong>XN04A+GH</strong></td><td>Gets the humidity value from the sensor. Returns a relative humidity (%) value.<br><strong>Response:</strong> XN04A=VAL<br><strong>Example:</strong> XN04A=80</td></tr><tr><td><strong>XN04A+GL</strong></td><td>Gets the light value from the sensor. Returns an ambient light value in Lux.<br><strong>Response:</strong> XN04A=VAL<br><strong>Example:</strong> XN04A=198</td></tr></tbody></table>

**Advanced commands**

<table data-header-hidden><thead><tr><th width="191"></th><th></th></tr></thead><tbody><tr><td><strong>XN04A+ETW=(0-1)</strong></td><td>Enables (1) or disables (0) the device's I2C interface.<br><strong>Note</strong>: This setting is volatile, disconnecting power or sending the reset command will restore the I2C interface.<br><strong>Response:</strong> OK<br><strong>Example:</strong> XN04A+ETW=0</td></tr><tr><td><strong>XN04A+SLP</strong></td><td>Enables deep sleep mode to reduce power consumption, during deep sleep, the device will not respond to UART commands. To wake the device, send a logic low (0) to the WAKEUP/UPDI pin.<br><strong>Response:</strong> OK<br><strong>Example:</strong> XN04A+SLP</td></tr><tr><td><strong>XN04A+RST</strong></td><td>Resets the device, non-volatile values (e.g., ID, I2C address) are preserved, and volatile values return to default.<br><strong>Response:</strong> OK</td></tr><tr><td><strong>XN04A+SP</strong></td><td>Sets the temperature/humidity sensor precision to high (H)* (default), medium (M), or low (L), lower precision allows faster updates.<br><strong>Response:</strong> OK<br><strong>Example:</strong> XN04A+SP=L</td></tr><tr><td><strong>XN04A+SH</strong></td><td>Turns the humidity sensor heater on (1) or off (0). Use this if humidity readings are incorrect, enable the heater for at least 2 hours to repair the sensor.<br><strong>Response:</strong> OK<br><strong>Example:</strong> XN04A+SH=0</td></tr><tr><td><strong>XN04A+SG</strong></td><td>Sets the light sensor gain to 1 (1-64k lux, default), 2 (1-32k lux), 4 (1-16k lux), 8 (1-8k lux), 48 (1-1.3k lux), or 96 (1-600 lux), higher gain means lower range but higher precision.<br><strong>Response:</strong> OK<br><strong>Example:</strong> XN04A+SG=96</td></tr><tr><td><strong>XN04A+SD</strong></td><td>Turns the hardware controller for the sensors on (1) or off (0).<br><strong>Response:</strong> OK<br><strong>Example:</strong> XN04A+SD=1</td></tr><tr><td><strong>XN04A+SN</strong></td><td>Reads the serial number of the temperature and humidity sensor.<br><strong>Response:</strong> XN04A=<br><strong>Example:</strong> XN04A=4294900000</td></tr></tbody></table>

When reading temperature, humidity, or light, the following error responses may occur:

* **ERROR:** Sensor communication error.
* **OL:** Light value overflowed the register, set a lower gain if possible.
* **MEASURING:** Sensor reading not finished, wait at least 20 ms for initialization.
* **HW\_DRIVER\_OFF:** Hardware controller is not enabled.

**End of line**

The X-NODE will only respond to a command when a set of end-of-line characters are sent, each command must end with: **\<CR+LF>**

* CR means carriage return.
* LF means line feed.

The combination **\<CR+LF>** is a common way for computers to represent a new line, e.g., in a word processor to separate paragraphs.

For the X-NODE, **\<CR+LF>** characters are used to identify the end of a command. If the identifier matches the node, the command exists, and it ends with **\<CR+LF>**, the node will send a response.

Depending on your system, you must configure sending these characters differently.

### **UART Example Arduino Framework**

{% hint style="info" %}
Example code for [XC01 - R5](https://docs.microside.com/en/user-manuals/xide/x-nodes/xc01-mcu-wifi-ble/r5/xc01-mcu-wifi-ble-esp32-s3), see the manual to use our [XC01 - R5](https://docs.microside.com/en/user-manuals/xide/xc01-mcu-wifi-ble/r5/xc01-mcu-wifi-ble-esp32-s3#v.-setup-and-usage) in **Arduino IDE/PlatformIO**
{% endhint %}

```cpp
#include "Arduino.h"

float getVariable( const char * command ){
  // Clear the buffer
  if (Serial2.available()) {
    Serial2.read();
  }

  // Send the command
  Serial2.print(command);
  Serial2.println();

  // Wait for a response
  String variable_value = Serial2.readStringUntil('\n');

  // If the response starts with the ID, communication was successful
  if (!variable_value.startsWith("XN04A=")) {
    Serial.println("Error");
    return NAN;
  }

  // Convert ASCII value to decimal
  return variable_value.substring(variable_value.indexOf('=') + 1).toFloat();
}

void setup() {
  // Initialize serial monitor
  Serial.begin(115200);

  // Initialize UART communication on MikroBUS port
  Serial2.begin(115200, SERIAL_8N1, 9, 10);
}

void loop() {
  // Get environmental variable values

  // Send command to get temperature
  // \r\n represents <CR+LF> in C/C++
  float temp = getVariable("XN04A+GT\r\n");

  // Send command to get humidity
  float hum = getVariable("XN04A+GH\r\n");

  // Send command to get light
  float lum = getVariable("XN04A+GL\r\n");

  Serial.print("Temp: ");
  Serial.print(temp);
  Serial.println(" °C");
  Serial.print("Hum: ");
  Serial.print(hum);
  Serial.println(" %");
  Serial.print("Lum: ");
  Serial.print(lum);
  Serial.println(" lx");

  delay(1000);
}
```

### I2C Protocol

To establish communication, you must know the I2C address of the X-NODE, the factory value is 0x04. I2C addresses are usually represented in **hexadecimal**, make sure to use the correct number system.

**Configuration**

* Communication speed: 100 kHz - 400 kHz
* Address: 7 bits

{% hint style="info" %}
**Note:** Make sure you do not have another device with the same address on the I2C BUS, if so, remember that the X-NODE can change its I2C address with the **XN04A+TW=(1-126)** command.
{% endhint %}

**Write**

To write to a register of the **X-NODE Temp-Hum / Lum**, the I2C controller must perform the following operations:

1. Send a **start condition**: The controller generates a logic low (0) on SDA while SCL remains high (1).
2. Send the **X-NODE address**: The controller sends the 7-bit address.
3. Send the **operation type**: The controller indicates if the operation is read (0) or write (1).
4. Wait for an **acknowledge (ACK)**: The controller waits for a logic low (0) as confirmation (Acknowledgment) that a target with the sent address exists on the I2C BUS. If no response (1), there was a communication error or the address is incorrect.
5. Write **n bytes** of data: The controller writes n bytes in 8 bit (1 byte) sequences, MSB first. The target will send an **ACK** for each byte written.
6. Send a **stop condition**: The controller releases the I2C BUS by generating a logic high (1) on SDA while SCL is high (1).

**Read**

To read from a register of the **X-NODE Temp-Hum / Lum**, the I2C controller must perform the following operations:

1. Send a **start condition**: The controller generates a logic low (0) on SDA while SCL remains high (1).
2. Send the **X-NODE address**: The controller sends the 7 bit address.
3. Send the **operation type**: The controller indicates if the operation is read (0) or write (1).
4. Wait for an **acknowledge (ACK)**: The controller waits for a logic low (0) as confirmation (Acknowledgment) that a target with the sent address exists on the I2C BUS. If no response (1), there was a communication error or the address is incorrect.
5. Read **n bytes** of data: The target will send n bytes in 8 bit (1 byte) sequences, MSB first, after receiving a byte, the controller must send an **ACK** to request another byte, or a **NACK** to indicate the end of transmission and request the target to release the BUS.
6. Send a **stop condition**: The controller releases the I2C BUS by generating a logic high (1) on SDA while SCL is high (1).

**Register list**

In an I2C target, registers are memory addresses that allow configuring or obtaining data from the target. There are two types of operations: read (R) and write (W).

<table><thead><tr><th width="143">Register</th><th width="92" align="center">Address (hex)</th><th width="80" align="center">Type</th><th width="92" align="center">No. Bytes</th><th>Description</th></tr></thead><tbody><tr><td>TEMP</td><td align="center">0x01</td><td align="center">R</td><td align="center">2</td><td>Gets the temperature value in °C*100, divide by 100 to get °C</td></tr><tr><td>HUM</td><td align="center">0x02</td><td align="center">R</td><td align="center">2</td><td>Gets the relative humidity value * 100, divide by 100 to get percentage (0-100%)</td></tr><tr><td>LUM</td><td align="center">0x03</td><td align="center">R</td><td align="center">2</td><td>Gets the ambient light (ALS) value in Lux</td></tr><tr><td>HEATER</td><td align="center">0x04</td><td align="center">R/W</td><td align="center">1</td><td>Turns the humidity sensor heater on (1) or off (0). Use this if humidity readings are incorrect, enable the heater for at least 2 hours to repair the sensor.</td></tr><tr><td>PRECISION</td><td align="center">0x05</td><td align="center">R/W - NV</td><td align="center">1</td><td>Sets the temperature/humidity sensor precision to high (3)* (default), medium (2), or low (1), lower precision allows faster data updates.</td></tr><tr><td>GAIN</td><td align="center">0x06</td><td align="center">R/W - NV</td><td align="center">1</td><td>Sets the light sensor gain to 1 (1-64k lux, default), 2 (1-32k lux), 4 (1-16k lux), 8 (1-8k lux), 48 (1-1.3k lux), or 96 (1-600 lux). Higher gain means lower range but higher precision.</td></tr><tr><td>SERIAL_NUM</td><td align="center">0x07</td><td align="center">R</td><td align="center">4</td><td>Reads the serial number of the temperature and humidity sensor</td></tr><tr><td>DRIVER</td><td align="center">0x36</td><td align="center">R/W - NV</td><td align="center">1</td><td>Turns the hardware controller for the sensors on (1) or off (0)</td></tr><tr><td>STAT</td><td align="center">0x37</td><td align="center">R</td><td align="center">1</td><td>XNODE status, 0x00 if no errors, any other value means communication error.<br><strong>Error codes:</strong><br><strong>1:</strong> Temperature/humidity sensor error<br><strong>2:</strong> Light sensor error<br><strong>3:</strong> Both sensors errored</td></tr><tr><td>FW</td><td align="center">0x38</td><td align="center">R</td><td align="center">3</td><td>Firmware version, in major, minor, and patch: 0x02.0x00.0x00</td></tr><tr><td>UART_ID</td><td align="center">0x39</td><td align="center">R/W - NV</td><td align="center">1</td><td>Reads and writes the ID index as a letter from A (0x41) to Z (0x5A)</td></tr><tr><td>TW_ADD</td><td align="center">0x3A</td><td align="center">R/W - NV</td><td align="center">1</td><td>Reads and writes the device's I2C address from 1 (0x01) to 126 (0x7D). Requires a reset or a power-on sequence to be applied</td></tr><tr><td>UART_EN</td><td align="center">0x3B</td><td align="center">W</td><td align="center">1</td><td>Enables (0x01) or disables (0x00) the device's UART interface</td></tr><tr><td>SLEEP</td><td align="center">0x3C</td><td align="center">W</td><td align="center">1</td><td>Enables (0x01) or disables (0x00) deep sleep, the device will wake up if the master writes the device's I2C address on the BUS</td></tr><tr><td>RESET</td><td align="center">0x3D</td><td align="center">W</td><td align="center">1</td><td>Writing 0x01 resets the device</td></tr><tr><td>WHO_AM_I</td><td align="center">0x3E</td><td align="center">R</td><td align="center">2</td><td>First byte is the XNODE model, second byte is the hardware revision</td></tr></tbody></table>

**Non-volatile registers (NV)**

Non-volatile registers are stored in the device's EEPROM, meaning they retain their values even if the device is powered off.

**TEMP, HUM, LUM register structure:**

When reading temperature, humidity, or light, the following reserved values indicate errors:

* **0xFFFF:** Sensor communication error.
* **0xFFFE:** Light value overflowed the register, set a lower gain if possible.
* **0xFFFD:** Sensor reading not finished, wait at least 20 ms for initialization.
* **0xFFFC:** Hardware controller is not enabled.

<figure><img src="https://docs.microside.com/~gitbook/image?url=https%3A%2F%2F177299348-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FbyV2zAlQAiqg46a3Lr8z%252Fuploads%252FhG1B892ucnZeJ10FJ2UX%252Fuser-manual-i2c-protocol-register-outputs.png%3Falt%3Dmedia%26token%3Dd2291cd6-27c8-4a22-b9d1-7a3a15b5e530&#x26;width=768&#x26;dpr=1&#x26;quality=100&#x26;sign=9d1b104e&#x26;sv=2" alt=""><figcaption></figcaption></figure>

### **I2C Example Arduino Framework**

{% hint style="info" %}
Example code for [XC01 - R5](https://docs.microside.com/en/user-manuals/xide/x-nodes/xc01-mcu-wifi-ble/r5/xc01-mcu-wifi-ble-esp32-s3), see the manual to use our [XC01 - R5](https://docs.microside.com/en/user-manuals/xide/xc01-mcu-wifi-ble/r5/xc01-mcu-wifi-ble-esp32-s3#v.-setup-and-usage) in **Arduino IDE/PlatformIO**
{% endhint %}

```cpp
#include <Arduino.h>
#include <Wire.h>

void setup() {
  // Initialize serial monitor
  Serial.begin(115200);

  // Set I2C communication pins
  Wire.setPins( 12, 13 );
  // Initialize I2C communication
  Wire.begin();
}

void loop() {
  // Get environmental variable values
  float temperature;
  float humidity;
  int lum;

  Wire.beginTransmission(0x04);
  Wire.write(0x01);
  if ( Wire.endTransmission() != 0) {
    delay(1000);
    return;
  }

  if (Wire.requestFrom(0x04, 2) != 2) {
    delay(1000);
    return;
  }

  // Divide by 100 to get value in Celsius
  temperature = ( (Wire.read() << 8) | Wire.read() )/100.0f;
  
  Wire.beginTransmission(0x04);
  Wire.write(0x02);
  if ( Wire.endTransmission() != 0) {
    delay(1000);
    return;
  }

  if (Wire.requestFrom(0x04, 2) != 2) {
    delay(1000);
    return;
  }

  // Divide by 100 to get value in percent relative humidity
  humidity = ( (Wire.read() << 8) | Wire.read() )/100.0f;

  Wire.beginTransmission(0x04);
  Wire.write(0x03);
  if ( Wire.endTransmission() != 0) {
    delay(1000);
    return;
  }

  if (Wire.requestFrom(0x04, 2) != 2) {
    delay(1000);
    return;
  }

  lum = ((Wire.read() << 8) | Wire.read());

  Serial.print("Temperature:");
  Serial.print(temperature);
  Serial.println(" C");
  Serial.print("Humidity:");
  Serial.print(humidity);
  Serial.println(" %");

  Serial.print("Light: ");
  Serial.print(lum);
  Serial.println(" lx");

  delay(1000);
}
```

## VI. Downloads

<table data-card-size="large" data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center"><mark style="color:green;"><strong>Schematic</strong></mark></td><td><a href="https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbyV2zAlQAiqg46a3Lr8z%2Fuploads%2FcFaznEDQxatEy6prNwMl%2Fschematic.pdf?alt=media&#x26;token=bff01aea-d514-49e9-8d7b-c41ae9a939ef">https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbyV2zAlQAiqg46a3Lr8z%2Fuploads%2FcFaznEDQxatEy6prNwMl%2Fschematic.pdf?alt=media&#x26;token=bff01aea-d514-49e9-8d7b-c41ae9a939ef</a></td></tr><tr><td align="center"><mark style="color:green;"><strong>Dimensions</strong></mark></td><td><a href="https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbyV2zAlQAiqg46a3Lr8z%2Fuploads%2FEAvXcjTy4yVAr0qRZMzF%2Fdimensions.pdf?alt=media&#x26;token=0d1a1c2b-f723-4763-bdcd-eb254c8511f1">https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbyV2zAlQAiqg46a3Lr8z%2Fuploads%2FEAvXcjTy4yVAr0qRZMzF%2Fdimensions.pdf?alt=media&#x26;token=0d1a1c2b-f723-4763-bdcd-eb254c8511f1</a></td></tr></tbody></table>
