Skip to main content
FabAcademy week9 assignment

Week 9 - Input Devices

Group Assignment

The link to our group work: https://fabacademy.org/2026/labs/chaihuo/docs/week9/chaihuo/week9_group_assignment

For this week's group assignment, we gathered around the lab's OWON EDS102 CV oscilloscope to actually visualize the electrical signals traveling across the custom ESP32 PCBs we fabricated in earlier weeks.

While I have used a multimeter before to check basic voltages, looking at signals on an oscilloscope was a completely different experience. Here are my biggest personal takeaways from our group probing sessions:

Demystifying PWM (Pulse Width Modulation) We hooked up the scope probe to a servo motor's control line. I always knew conceptually that PWM uses "duty cycles" to dictate position, but watching the physical square waves instantly expand and contract on the screen as we commanded the servo to move from -90° to 90° was a huge "Aha!" moment. We could physically measure the 20ms period (50Hz) and see the pulse width shift between roughly 1.0ms and 2.0ms. It made the abstract code incredibly tangible.

Oscilloscope PWM waveform

The Golden Rule of Grounding I learned very quickly that an oscilloscope is useless without a shared reference. In one of our early attempts, we forgot to connect the probe's alligator clip to the PCB's ground plane. The screen just showed a messy, floating "garbage" waveform. Tying the grounds together instantly snapped the signal into a clean, readable shape.

Taming the Trigger At first, the waveforms we probed were constantly drifting horizontally across the screen, making them impossible to read. I learned how to adjust the scope's trigger level so it sits directly inside the voltage swing (e.g., around 1.5V for our 3.3V logic). Once the trigger caught the edge, the waveform froze perfectly in place.

The Right Tool for the Job This exercise taught me the fundamental difference in troubleshooting: a multimeter tells you what the voltage level is, but a scope tells you how it gets there. It can reveal hidden hardware issues like contact bounce on a digital button or noisy edges on a sensor line.

How this informed my Individual Project

This hands-on scope training was directly applicable to my final project—the digital Morin Khuur. When I moved on to integrating my digital I2S microphone, I knew that if the ESP32 wasn't receiving audio data, I shouldn't just blindly stare at my C++ code. My first troubleshooting step would be to hook the oscilloscope up to the BCLK (Bit Clock) and WS (Word Select) pins to physically verify if the microphone was generating clean, square clock pulses on the physical PCB traces. Knowing how to verify the hardware layer first gave me massive confidence moving into the software integration.

Individual Assignment

Objective

The objective of this assignment is to design and implement an input device system that can read environmental data using a digital sensor and communicate the data to a microcontroller via the I2C protocol.

The system is required to:

  • Detect and communicate with an I2C sensor
  • Read real-time temperature and humidity values
  • Output data through serial communication
  • Demonstrate understanding of embedded communication protocols

System Overview

This project uses the following components:

  • ESP32-C3 microcontroller
  • SHT40 temperature and humidity sensor
  • USB connection for serial output

The communication structure is based on the I2C protocol, where:

  • The ESP32-C3 acts as the master device
  • The SHT40 sensor acts as an I2C slave device
  • Each device is identified using a unique I2C address

In this system, the SHT40 sensor is detected at address 0x44.

About Grove SHT40 temperature and humidity sensor:

Grove - Temperature & Humidity Sensor (SHT40) is a digital Humidity and Temperature Sensor which has an accuracy rate of up to ±1.8% ~ ±3.5% RH and ±0.2 °C, and an operating range of 0% to 100% RH, -40°C to +125°C. It comes with a SEEED's standard grove I2C interface enabling developers or even beginners to easily communicate with the SHT40 sensor on different hardware platforms, for a wide variety of applications, such as Climate Monitoring, Smart Home, etc.

Specifications:

  • Temperature accuracy rate | ±0.2 ℃
  • Typical Humidity accuracy rate | ±1.8% RH
  • Maximum Relative Humidity Accuracy Rate | ±3.5%
  • Operating temperature range | -40°C to 125°C
  • Operating Humidity range | 0% to 100% RH
  • Grove power supply | 5/3.3 volts
  • Serial Protocol | I2C
  • Grove's average current supply | 1.2 µA
  • Grove idle current | 32µA
  • Product Dimension | 20mm x 40mm

Grove SHT40 sensor

Why I2C is used

I2C was selected for this project because:

  • It only requires two communication lines (SDA and SCL)
  • Multiple devices can share the same bus
  • Each device is identified by a unique address
  • It is widely supported by sensors and microcontrollers

In this project, the I2C bus simplifies wiring and allows reliable communication between the ESP32-C3 and the SHT40 sensor.

Hardware Setup

Components used

  • XIAO ESP32-C3 development board
  • Grove SHT40 temperature and humidity sensor
  • Jumper wires
  • USB cable

Wiring configuration

Before Wiring, I reviewed the pin definition of my designed board with XIAO ESP32C3 as well as the Grove SHT40 temperature and humidity sensor.

XIAO ESP32-C3 pin definition

Grove SHT40 pin definition

Schematic review

The Grove - SHT40 sensor is connected as follows:

  • VCC → 3.3V power supply
  • GND → Ground
  • SDA → I2C data line (SDA pin on XIAO ESP32-C3)
  • SCL → I2C clock line (SCL pin on XIAO ESP32-C3)

I found one problem—from the schematic I designed, there is no extra socket pin for 3.3V on XIAO ESP32C3. So, I used a particular jumper wire to connect the original 3.3V on XIAO then connect to the SHT40 temperature & humidity sensor's VCC pin.

Wiring workaround for 3.3V

Why these connections are used

  • The Grove SHT40 sensor operates at 3.3V logic level, so it must not be connected to 5V
  • SDA is used for transmitting data between devices
  • SCL provides synchronization for data transmission
  • ESP32-C3 supports flexible I2C pin assignment depending on board configuration

Arduino IDE Setup & Programming

Step 1 – Install ESP32 board package

The ESP32 board package is added to Arduino IDE by inserting the following URL into the additional board manager field: https://espressif.github.io/arduino-esp32/package_esp32_index.json

This allows Arduino IDE to recognize ESP32 boards.

Arduino IDE board manager URL

Board manager settings

Step 2 – Install board support

After adding the URL, the ESP32 package is installed from the Board Manager by searching for "ESP32 by Espressif Systems". I double checked and found it's already installed before.

ESP32 board package search

ESP32 board package installed

Step 3 – Select board

The correct board selection is: XIAO_ESP32C3

This ensures correct pin mapping and USB behavior for Seeed XIAO hardware.

Board selection XIAO_ESP32C3

Step 4: Hardware Connection Test

Before any I2C or sensor testing, basic hardware connectivity is verified.

I used the multimeter again to test if all the connections on board is working well.

Multimeter connection test

I go to Tools → Port, and confirm device appears as: /dev/cu.usbmodemXXXX

USB port selection

Step 5: Basic Serial Test (Firmware Validation)

This step ensures the board itself is functioning before using I2C, by confirming firmware upload works and Serial Monitor works. I intended to print simple "Hello" or boot message, and verified stable serial communication at 115200 baud.

void setup() {
Serial.begin(115200);
}

void loop() {
Serial.println("Hello Mac + XIAO!");
delay(2000);
}

Then I can see the "Hello Mac + XIAO" from the Serial Monitor.

Serial monitor hello test

STEP 6 – I2C Device Scan

Now I verify that the sensor is visible on the I2C bus. The code is generated by ChatGPT:

#include <Wire.h>

void setup() {
Wire.begin();
Serial.begin(115200);
delay(1000);

Serial.println("I2C Scanner Start");
}

void loop() {
byte error, address;
int nDevices = 0;

for(address = 1; address < 127; address++) {
Wire.beginTransmission(address);
error = Wire.endTransmission();

if (error == 0) {
Serial.print("Found I2C device at 0x");
Serial.println(address, HEX);
nDevices++;
}
}

if (nDevices == 0) {
Serial.println("No I2C devices found");
}

Serial.println("----------------------");

delay(3000);
}

I2C scanner initial result

I double checked if the USB connection or the pin connection is correct; or if the wiring of jumper wire is too loose. After checking, it's because the jumper wire too loose, I reconnected them and I can see the positive result on Serial Monitor.

The sensor is detected at: 0x44

I2C scanner success at 0x44

STEP 7 – Sensor Data Acquisition

After all validation steps, I used the code below to initialize the SHT40 sensor to show me temperature and humidity. The code below is generated by ChatGPT.

#include <Wire.h>
#include "Adafruit_SHT4x.h"

Adafruit_SHT4x sht4 = Adafruit_SHT4x();

void setup() {
Serial.begin(115200);
Wire.begin(); // ESP32-C3 default I2C pins

if (!sht4.begin()) {
Serial.println("SHT4x not found!");
while (1) delay(1);
}

Serial.println("SHT4x ready");
sht4.setPrecision(SHT4X_HIGH_PRECISION);
sht4.setHeater(SHT4X_NO_HEATER);
}

void loop() {
sensors_event_t humidity, temp;

sht4.getEvent(&humidity, &temp);

Serial.print("Temperature: ");
Serial.print(temp.temperature);
Serial.println(" °C");

Serial.print("Humidity: ");
Serial.print(humidity.relative_humidity);
Serial.println(" %");

Serial.println("-----");

delay(1000);
}

The system reads: Temperature (°C) & Humidity (%). The data is updated every 1 second via Serial Monitor.

Temperature and humidity serial output

Summary

In this assignment, I developed and tested an input device system using the Seeed Studio XIAO ESP32C3 and a Grove SHT40 temperature and humidity sensor. The system was built using the I2C communication protocol, where the microcontroller acts as the master device and the sensor operates as a slave device with the address 0x44.

The workflow started with basic hardware and software setup in Arduino IDE, including installing the ESP32 board package and required sensor libraries. Before reading sensor data, I verified system stability through hardware connection checks and serial communication tests. I then used an I2C scanner to confirm that the sensor was correctly detected on the bus.

After successful detection, the Adafruit SHT4x library was used to initialize the sensor and retrieve real-time environmental data. The system continuously outputs temperature and humidity values through the Serial Monitor at a 1-second interval.

This exercise demonstrates a complete embedded input device workflow, including hardware setup, communication verification, sensor integration, and real-time data acquisition using I2C.

Completed SHT40 input device setup