Skip to content

Reference Design Waveshare General Driver

hippo5329 edited this page Oct 15, 2026 · 13 revisions

Reference Design: Waveshare General Driver Board (ESP32)

Overview · What you need · Hardware · Wiring · Setup · The LiDAR header in simulation mode · Status

Waveshare General Driver board, with a red jumper wire from the LIDAR pin to IO4 on the middle header

The board with the one wire it needs: the red jumper from LIDAR to IO4 on the middle header. Photo: Waveshare, General Driver for Robots (the jumper drawn in, as on the linorobot2_hardware wiki).

Waveshare General Driver wiring

Config gendrv_config.yaml
Drivetrain 2WD differential (the shared default chassis)
MCU ESP32-WROOM-32
Firmware image esp32-jazzy / esp32-lyrical (the plain ESP32 release) plus the design's env block
micro-ROS link USB serial through the on-board CP2102N at 1.5 Mbaud, or Wi-Fi (udp4)
LiDAR LD19 on the board's LiDAR connector; the robot computer reads it through the board's own LiDAR USB-C port, and a jumper from LIDAR to IO4 gives the ESP32 the same line
Status ✅ bench board: serial and Wi-Fi, both distros, in simulation mode; a real LD19 on a real robot has also run

Overview

The Waveshare General Driver Board carries an ESP32-WROOM-32, a TB6612FNG dual motor driver, four I2C sensors, a LiDAR header and a CP2102N USB bridge fast enough for 1.5 Mbaud micro-ROS. It runs the plain ESP32 release image. What makes it a General Driver is its pin matrix and LiDAR wiring, which the cockpit writes into the env block when it flashes. The reference is 2WD. Its kinematics are the shared default-chassis placeholders, so measure and enter your own chassis (step 7 below).


What you need

Part Notes
Waveshare General Driver for Robots The board itself; it has the IMU, magnetometer, current sensor and barometer on board
Two DC gear motors with quadrature encoders 12 V; each plugs into one of the board's two motor-with-encoder headers
LD19 LiDAR 230400 baud; powered from the board's LiDAR header
One jumper wire (female–female) From LIDAR to IO4 on the middle header: the one wire the board needs
Two USB-C cables The board's USB port (micro-ROS) and its LiDAR port (the scan) to the robot computer
3S battery (12.6 V full) Into the board's power input; the board regulates its own 5 V and 3.3 V
Robot computer A Raspberry Pi 5 or any arm64/x86 computer running the cockpit (Installation & Docker)
Chassis Any 2WD base: the board mounts on M3 standoffs

Key Hardware Specifications

Component Specification Notes
MCU ESP32-WROOM-32 (dual Xtensa LX6, 240 MHz) Wi-Fi on the Wi-Fi transport (micro-ROS, syslog, OTA); off on serial
USB bridge Silicon Labs CP2102N, /dev/ttyUSB0 micro-ROS at 1.5 Mbaud: four sensors at 50 Hz need more than a bare DevKit's 921600
Motor driver Toshiba TB6612FNG Driven the two-PWM way (driver_type: BTS7960); PWMA / PWMB are held high as the enable. driver_type names the firmware's drive scheme, not the chip: BTS7960 is the two-PWM scheme, where IN A and IN B carry the PWM and the config's pwm pin is an enable held high. That is how this board's TB6612 is wired (PWMA/PWMB on GPIO 25/26), so two PWM pins per motor drive it
IMU QMI8658 (6-axis) I2C, found by probing the bus
Magnetometer AK09918 Gives the EKF an absolute heading; see Heading & Magnetometer Calibration
Current / barometer INA219 / BMP280 /battery, /pressure, /temperature
LiDAR LD19 on the LiDAR connector, 230400 baud The board's LiDAR USB-C port has its own bridge on that line: the robot computer reads the stream there (/dev/ttyUSB1) with the LD19 driver. The ESP32 reaches the same line through the IO4 jumper

All four sensors are compiled into the image and found by probing the I2C bus: a chip that answers is used whatever the config names, and a chip the config names that does not answer is an error.


Wiring

Function GPIO Notes
Motor 1 (Left) PWM / IN A / IN B 25 / 17 / 21 TB6612 PWMA held high as the enable; IN A and IN B carry the PWM, and IN A is the forward one
Motor 2 (Right) PWM / IN A / IN B 26 / 23 / 22 TB6612 PWMB held high as the enable; IN A forward
Encoder 1 A / B 34 / 35 Input-only pins
Encoder 2 A / B 16 / 27
I2C SDA / SCL 32 / 33 QMI8658, AK09918, INA219, BMP280 (on board)
LiDAR line (LIDAR_RXD) 4 lidar.rx_pin; not wired on the board: add a jumper from LIDAR to IO4 on the middle header
Status LED 2 Not connected on this board; a strapping pin, harmless here

The pinout is the board's copper, from the linorobot2_hardware wiki's Waveshare General Driver section. Everything except the motors, the encoders, the LiDAR and the IO4 jumper is already wired on the board.

  1. Motors: plug the left motor into the TB6612's A channel header and the right one into the B channel. Each header carries both the motor leads and the encoder lines, so one cable per wheel does it. Check the encoder pin order against your motor's datasheet before plugging in.
  2. The IO4 jumper: on the middle header, connect LIDAR to IO4 with one jumper wire (the red wire in the photo). Without it the ESP32 has no LiDAR line: GPIO 4 is not routed to the LiDAR connector on the board.
  3. LiDAR: plug the LD19 into the LiDAR connector, and the board's LiDAR USB-C port into the robot computer, where it appears as /dev/ttyUSB1.
  4. Power: the battery goes into the board's power input (DC 9–12.6 V); the USB USB-C port to the robot computer carries micro-ROS.

Setup, step by step

The order is Building a Real Robot's; this page fills in the board's own values.

  1. Install the cockpit on the robot computer: Installation & Docker.
  2. Prove the bare board first. Plug in the board alone (no motors, no LiDAR). The header names the silicon (ESP32) and picks lino_esp32, a bare module of it. Press 🚀 Start 1-Click: it flashes the release image, writes the env and runs the board in simulation mode. A bare ESP32 has no LiDAR line to carry its simulated scan, so this run proves the topics and the eight drive manoeuvres and stops there, with no SLAM, Nav2 or map (No /scan: … Topics and drive only -- no SLAM, no Nav2.). With nothing wired, nothing can be damaged.
  3. Name your robot and apply the design. Type a name for your robot in the header's Robot field and press Enter, then pick Linorobot2 Differential Drive Autonomy Platform (the General Driver design) under Reference Designs on MCU & Sim (tab 1). The board's controller side becomes your robot's (MCU, pins, motor driver, sensors, link); a chassis you already set keeps its wheels, motors and Nav2 tuning. Your robot is real from then on: no simulated devices, and every change you make is saved to it as you go.

Steps 4 to 11 run on the Real-robot bring-up card on Hardware Tests (tab 6); what each card step checks is in The bring-up checklist. Use the card, not commands typed into the tool: the card records each pass, and the 1-Click will not move a real robot until card steps 1 to 5 (sensors, battery, motors, wheel speed, LiDAR) have passed ([BRINGUP REQUIRED]). The same tests typed by hand record nothing.

Before any motor test: connect the pack. USB powers only the ESP32; the TB6612, the motors and the LD19 need the battery. Lift the robot so its wheels spin freely. To stop a wheel, press ■ STOP MOTORS (or Esc) on the page, or send an empty line in the terminal.

  1. Sensors (card step 1): ① Hold still, then ② Turn and shake. The table should show the QMI8658 and AK09918 changing as the robot moves, and gravity near 9.8 m/s² at rest.
  2. Motors (card step 3), wheels lifted: wire one wheel, press Spin forward for it and say which way it turned. The card offers the motor or encoder invert it needs (Save). Then wire the other wheel. The full symptom table is step 5.
  3. Battery (card step 2): Read the board, type a multimeter's reading of the pack, Compare. The INA219 sits after the board's input diode and reads about 0.65 V low; a current monitor passes within 1 V (see below for the min_v / max_v to set).
  4. Measure the chassis and enter it on Base (tab 2): wheel diameter, track width, motor RPM and encoder counts per wheel revolution (step 7). Then Wheel speed (card step 4), wheels lifted, with a laser tachometer (or by counting turns by hand).
  5. Mount the LiDAR on the centre line with its zero mark facing forward, enter its position on Base, and check it on LiDAR / Scan (tab 7). Then start Bringup (tab 8) on the pack and run Check the LiDAR (card step 5).
  6. Calibrate the magnetometer on the finished robot: Calibrating the magnetometer.
  7. First drive: (the design made the robot real: the header's badge reads 🔧 Real) leave the tool with Back to robot (base) so the board runs the robot firmware, start Bringup (tab 8) and drive gently with Teleop (tab 9). /odom/unfiltered and /imu/data should run near 50 Hz and /scan near 10 Hz.
  8. On the floor: Speed check (card step 6, 0.6 m clear; it is the speed check against the LiDAR) and put its ratios into the config before the first Nav2 goal; then Run test_acc (card step 7, 1.0 m clear, every wheel at up to full power).
  9. SLAM and Nav2: on Operations (tab 11) press ▶ Start 1-Click Pipeline (the robot runs real), in a small room, next to the robot.

Over Wi-Fi instead: set transport: udp4 on MCU & Sim, fill in the Secrets tool tab (Wi-Fi and the agent address), and flash once over USB. After that the board needs only power. The Wi-Fi transport (udp4) turns use_dual_core off, and the board says so at boot: the control loop's critical section would block the core that runs the Wi-Fi stack.


A real LD19 on the General Driver

The LD19's TX goes to LIDAR_RXD (GPIO 4, a jumper from LIDAR to IO4; see Wiring above). How its scan reaches the robot computer is lidar.comm_mode, and the choice follows the robot:

The robot comm_mode Measured on a real LD19
A robot computer on board, LiDAR on its own USB port serial (lidar.serial_port, e.g. /dev/ttyUSB1; not the MCU's port) the usual robot
No robot computer: micro-ROS over Wi-Fi udp 10 Hz, 456 points a revolution, every packet intact (CRC)
The LiDAR on the board, the board on the 1.5 Mbaud cable topic /raw_scan 37.5 Hz, /scan 9.98 Hz with 456 points, /odom 46 Hz, IMU 40 Hz

topic over Wi-Fi does not carry a real LD19: the scan floods the micro-ROS session (/scan came at 0.8 Hz and the IMU at 3.4 Hz), so it is refused. Use udp. The LiDAR Link selector on Pin Matrix (tab 5) offers only the links the robot's own link can carry; see How the scan reaches the robot computer.

The battery reads low by the board's input diode: the INA219 sits after it, about 0.65 V below the pack at idle and more under motor current. Set pins.battery.min_v / max_v that much below the pack's 3.0 / 4.2 V a cell, so the percentage is right.

The LiDAR header in simulation mode

In simulation mode the board sends its simulated LD19 stream out of LIDAR_RXD. Whatever reads that pin on the robot computer (/dev/ttyUSB1) gets a scan exactly as a real LD19 would deliver it, through the real driver. On a board where nothing reads that pin back, there is no /scan: set lidar.comm_mode: topic and the simulated scan travels over micro-ROS instead. Topic mode shares the USB link with the control loop: at 1.5 Mbaud /odom and /imu/data measured 46–49 Hz instead of 50, and Nav2 still reached every goal. See Simulation Mode & the Bare Module.


Status

Gated on every release, in simulation mode: the bench board runs the full Nav2 test (goals behind a wall, eight drive manoeuvres) over serial and over Wi-Fi, on jazzy and lyrical, in all three drivetrains, plus a real-sensor run (QMI8658, AK09918, INA219 and BMP280 read for real). A real LD19 on a real robot built on this board has also run (the measurements above).


All reference designs · Pin Matrix & Wiring · Building a Real Robot

Clone this wiki locally