ESP32 Sensor Project

ผมจะปรับ schematic ให้เป็นเวอร์ชัน “ต่อง่ายบน breadboard”: ลดความสับสนของสาย, ใส่คำอธิบาย pin order/บทบาทแต่ละ connector, จัดกลุ่มให้ตามการต่อจริง และตรวจ ERC อีกรอบครับ
ตอนนี้ผมเริ่มงานปรับให้ “ต่อง่าย” แล้ว แต่ระบบแจ้งว่า ACUs ไม่พอ จึงยังแก้ schematic ต่อไม่ได้ในรอบนี้
ทำไปแล้วก่อนหน้านี้:
  • สร้าง schematic หลักครบ: ESP32 2 บอร์ด, HX711 + Load Cell, MPU6050, DS18B20, Battery Shield connector
  • ต่อ power, GND, I2C, HX711, DS18B20 และ UART optional ระหว่าง ESP32
  • ตรวจ ERC schematic แล้วผ่าน
  • สร้างไฟล์ Firmware Starter, Project Specification, Bring-Up Plan และ Regulatory Notes
งานที่เหลือสำหรับเวอร์ชัน “ต่อง่ายที่สุด”:
  • จัด schematic ใหม่ให้เหมือนลำดับการเสียบสายบน breadboard
  • ใส่คำอธิบาย pin ของ J1/J2 ให้ชัด เช่น 5V, 3V3, GND, E+, E-, A+, A-
  • ลดความสับสนของ ESP32 2 บอร์ด และทำให้ U1 เป็นบอร์ดหลักชัดเจน
  • อัปเดตไฟล์คำแนะนำการต่อสายให้เป็นขั้นตอนสำหรับมือใหม่
  • ตรวจ ERC/DRC หลังปรับอีกครั้ง
จัด schematic ง่าย
อธิบาย pin
คู่มือต่อสาย
ตรวจ ERC/DRC
U4
U5
C3
Capacitance
100nF
J1
C2
Capacitance
100nF
U2
C1
Capacitance
470uF
J2
U1
R1
Resistance
4.7kohms
R2
Resistance
4.7kohms
R4
Resistance
220 ohms
R5
Resistance
220 ohms
U3
R3
Resistance
4.7kohms

Refine this doc
Ask about this doc
Firmware Starter — ESP32 Road Soil Sensor
Platform & Toolchain
  • MCU: ESP32 development board / ESP32-DEVKITC-compatible
  • Framework: Arduino
  • Build system: PlatformIO
  • Firmware roles: U1 = sensor node, U2 = optional UART receiver
Pin Mapping

Table


FunctionGPIOSchematic NetConnected ToDirectionNotes
I2C SDA21I2C_SDAU4 MPU6050 SDA, R2 pull-upBidirectionalPull-up to 3V3.
I2C SCL22I2C_SCLU4 MPU6050 SCL, R3 pull-upOutput/open-drainPull-up to 3V3.
HX711 DOUT32HX711_DOUTU3 DATInputLoad cell ADC data.
HX711 SCK33HX711_SCKU3 CLKOutputLoad cell ADC clock.
DS18B20 DQ4DS18B20_DQU5 DQ, R1 pull-upBidirectional4.7 kΩ pull-up to 3V3.
UART U1 TX25UART_U1_TX_TO_R4 / UART_U1_TO_U2U1 IO25 -> R4 -> U2 IO26OutputOptional inter-board link.
UART U1 RX26UART_U2_TO_U1U2 IO25 -> R5 -> U1 IO26InputOptional inter-board link.
Dependencies & Project Setup
Create a PlatformIO project and use this platformio.ini:

Ini


[platformio]
default_envs = esp32_u1_sensor

[env]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps =
    bogde/HX711@^0.7.5
    adafruit/Adafruit MPU6050@^2.2.6
    adafruit/Adafruit Unified Sensor@^1.1.14
    paulstoffregen/OneWire@^2.3.8
    milesburton/DallasTemperature@^3.11.0

[env:esp32_u1_sensor]
build_flags = -DDEVICE_U1_SENSOR

[env:esp32_u2_receiver]
build_flags = -DDEVICE_U2_RECEIVER
Complete Firmware Source
Save as src/main.cpp:

Cpp


#include <Arduino.h>
#include <Wire.h>
#include <HX711.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define I2C_SDA_PIN          21
#define I2C_SCL_PIN          22
#define HX711_DOUT_PIN       32
#define HX711_SCK_PIN        33
#define DS18B20_DQ_PIN        4
#define ESP32_LINK_TX_PIN    25
#define ESP32_LINK_RX_PIN    26

#define SENSOR_INTERVAL_MS 1000UL
#define LINK_BAUD          115200
#define DEBUG_BAUD         115200

HardwareSerial LinkSerial(2);

#ifdef DEVICE_U1_SENSOR
HX711 scale;
Adafruit_MPU6050 mpu;
OneWire oneWire(DS18B20_DQ_PIN);
DallasTemperature ds18b20(&oneWire);
unsigned long lastReadMs = 0;

float readLoadCellRaw() {
  if (scale.is_ready()) {
    return (float)scale.read_average(5);
  }
  Serial.println("HX711 not ready");
  return NAN;
}

bool readMpu(float &ax, float &ay, float &az, float &gx, float &gy, float &gz, float &tempC) {
  sensors_event_t accel, gyro, temp;
  if (!mpu.getEvent(&accel, &gyro, &temp)) {
    return false;
  }
  ax = accel.acceleration.x;
  ay = accel.acceleration.y;
  az = accel.acceleration.z;
  gx = gyro.gyro.x;
  gy = gyro.gyro.y;
  gz = gyro.gyro.z;
  tempC = temp.temperature;
  return true;
}

float readDs18b20C() {
  ds18b20.requestTemperatures();
  float t = ds18b20.getTempCByIndex(0);
  if (t == DEVICE_DISCONNECTED_C) {
    Serial.println("DS18B20 disconnected");
    return NAN;
  }
  return t;
}

void setupU1() {
  Serial.begin(DEBUG_BAUD);
  delay(300);
  Serial.println("U1 sensor node starting");

  LinkSerial.begin(LINK_BAUD, SERIAL_8N1, ESP32_LINK_RX_PIN, ESP32_LINK_TX_PIN);

  Wire.begin(I2C_SDA_PIN, I2C_SCL_PIN);
  if (!mpu.begin(0x68, &Wire)) {
    Serial.println("MPU6050 not found at 0x68; check wiring/pull-ups");
  } else {
    mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
    mpu.setGyroRange(MPU6050_RANGE_500_DEG);
    mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
    Serial.println("MPU6050 initialized");
  }

  scale.begin(HX711_DOUT_PIN, HX711_SCK_PIN);
  scale.set_scale();
  scale.tare(10);

  ds18b20.begin();
  Serial.println("Init complete");
}

void loopU1() {
  unsigned long now = millis();
  if (now - lastReadMs < SENSOR_INTERVAL_MS) return;
  lastReadMs = now;

  float loadRaw = readLoadCellRaw();
  float ax = NAN, ay = NAN, az = NAN, gx = NAN, gy = NAN, gz = NAN, mpuTemp = NAN;
  bool mpuOk = readMpu(ax, ay, az, gx, gy, gz, mpuTemp);
  float surfaceTemp = readDs18b20C();

  String msg = "{\"load_raw\":" + String(loadRaw, 0) +
               ",\"mpu_ok\":" + String(mpuOk ? 1 : 0) +
               ",\"ax\":" + String(ax, 3) +
               ",\"ay\":" + String(ay, 3) +
               ",\"az\":" + String(az, 3) +
               ",\"gx\":" + String(gx, 3) +
               ",\"gy\":" + String(gy, 3) +
               ",\"gz\":" + String(gz, 3) +
               ",\"surface_temp_c\":" + String(surfaceTemp, 2) + "}";

  Serial.println(msg);
  LinkSerial.println(msg);
}
#endif

#ifdef DEVICE_U2_RECEIVER
void setupU2() {
  Serial.begin(DEBUG_BAUD);
  delay(300);
  Serial.println("U2 receiver starting");
  LinkSerial.begin(LINK_BAUD, SERIAL_8N1, ESP32_LINK_RX_PIN, ESP32_LINK_TX_PIN);
}

void loopU2() {
  while (LinkSerial.available()) {
    String line = LinkSerial.readStringUntil('\n');
    line.trim();
    if (line.length() > 0) {
      Serial.print("From U1: ");
      Serial.println(line);
    }
  }
}
#endif

void setup() {
#ifdef DEVICE_U1_SENSOR
  setupU1();
#elif defined(DEVICE_U2_RECEIVER)
  setupU2();
#else
  Serial.begin(DEBUG_BAUD);
  Serial.println("Define DEVICE_U1_SENSOR or DEVICE_U2_RECEIVER in build_flags");
#endif
}

void loop() {
#ifdef DEVICE_U1_SENSOR
  loopU1();
#elif defined(DEVICE_U2_RECEIVER)
  loopU2();
#else
  delay(1000);
#endif
}
Build & Flash Instructions

Bash


pio run -e esp32_u1_sensor
pio run -e esp32_u1_sensor -t upload
pio device monitor -b 115200

pio run -e esp32_u2_receiver
pio run -e esp32_u2_receiver -t upload
pio device monitor -b 115200
Use the ESP32 board’s BOOT/RESET buttons if upload does not enter bootloader automatically. Calibrate the HX711 with a known weight before using physical units.
  • Platform & Toolchain

  • Pin Mapping

  • Dependencies & Project Setup

  • Complete Firmware Source

  • Build & Flash Instructions

ESP32 Road Soil Sensor

ESP32 Road Soil Sensor thumbnail
Battery-powered ESP32 prototype for measuring soil/road-surface condition using HX711 load cell, MPU6050 vibration/tilt sensing, and DS18B20 temperature sensing from 18650 battery power.

Properties

Properties describe core aspects of the project.

Pricing & Availability

Distributor

Qty 1

Arrow

$14.71–$16.43

Digi-Key

$22.00

HQonline

$0.85–$1.23

LCSC

$26.31

Mouser

$21.02

Verical

$16.63–$17.68

Controls