Hardware Matrix

Is SN65HVD230 TWAI CAN Transceiver Compatible with Home Assistant (ESPHome)?

Verdict Badge
VERDICT: [ COMPATIBLE (MANUAL CONFIG REQUIRED) ]
Protocol: TWAI GPIO / 3.3V
Bridge Needed: NO

Electrical Specifications

Always confirm pin assignments against the manufacturer datasheet before wiring.

Not yet documented. Electrical specifications for this device have not been confirmed against a manufacturer datasheet, so none are shown here rather than showing estimates. Submit verified specifications if you have the datasheet to hand.

Compatibility Overview

Integrated 3.3V CAN bus transceiver leveraging ESP32-S3 TWAI peripheral for industrial CAN networks.

Wiring SN65HVD230 TWAI CAN Transceiver to ESP32-S3

Module pin ESP32-S3 Note
3V3 3V3 The SN65HVD230 runs from 3.0–3.6V, so its receive output is already at the S3's logic level and needs no divider.
GND GND
CTX GPIO5 The transceiver's driver input (D), fed from tx_pin. Labelled from the controller's side: CTX goes to TX.
CRX GPIO4 The receiver output (R), into rx_pin.
CANH / CANL the bus Twisted pair. On an OBD-II port, pins 6 (CANH) and 14 (CANL).

Host pins are the ones the configuration on this page uses. Move a pin here and change it in the YAML — they are documented together so they cannot disagree.

Technical Specification Matrix

Feature / Attribute Specification / Status
Hardware Protocol TWAI GPIO / 3.3V
Bridge Required NO
Border Router Needed None
Hardware Capabilities & Peripherals
Vehicle Telemetry CAN Frame Receiver Bus Errors

Note: these entities come from the ESPHome configuration you flash — each one needs its matching component in that YAML before it appears.

Pairing Complexity Advanced
Factory Reset Instruction Hold BOOT button while cycling reset.

Wire, Flash, Adopt, Check

1

Wire it up

Follow the wiring table above. The ESP32-S3 pins there are the ones the configuration uses, so if you move one, change it in both places.

2

Flash the configuration

Create a new device in the ESPHome dashboard (the Home Assistant add-on) and paste the configuration below into it, or save it as emb_esp32s3_canbus_ha.yaml and run esphome run emb_esp32s3_canbus_ha.yaml. The first flash goes over USB. If it is not detected, hold BOOT button while cycling reset to put it in download mode. Every update after that is over the air.

3

Adopt it in Home Assistant

Settings → Devices & Services. A node on the same network shows up as a discovered ESPHome device within a minute of joining Wi-Fi; choose Configure and enter the API encryption key from your secrets.yaml. If discovery does not find it, add the ESPHome integration by hand with the node's IP address.

4

Check it works

The boot log sets up the canbus component with no "setup error!" line. With a second node on the bus at 500kbps, each frame it sends appears in the log as a "Frame id 0x…, n bytes" line, and pressing Send Test Frame makes ID 0x123 appear on the other node. No frames at all points to the bit rate or to CANH and CANL swapped. Frames received but every send failing means either nothing else on the bus is acknowledging, or the transceiver's Rs pin is held high.

ESPHome Configuration

Starting configuration for SN65HVD230 TWAI CAN Transceiver on ESP32-S3. Untested on hardware — verify wiring and pins against your own board.

# ESPHome configuration for SN65HVD230 TWAI CAN Transceiver
# Host: ESP32-S3. Pin numbers below are host-side defaults — any free
# GPIO will do, and you should change them to match your own wiring.

esphome:
  name: emb_esp32s3_canbus_ha
  friendly_name: "SN65HVD230 TWAI CAN Transceiver"

esp32:
  board: esp32-s3-devkitc-1
  framework:
    type: esp-idf

logger:

api:
  encryption:
    key: !secret api_encryption_key

ota:
  - platform: esphome
    password: !secret ota_password

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

# The ESP32's own CAN (TWAI) controller, with the SN65HVD230 as a bare
# transceiver: no SPI, no crystal to match, 3.3V throughout.
canbus:
  - platform: esp32_can
    id: can_bus
    tx_pin: GPIO5
    rx_pin: GPIO4
    can_id: 4
    bit_rate: 500KBPS
    on_frame:
      - can_id: 0
        can_id_mask: 0
        then:
          - lambda: |-
              ESP_LOGI("can", "Frame id 0x%03X, %d bytes", can_id, x.size());

button:
  - platform: template
    name: "Send Test Frame"
    on_press:
      then:
        - canbus.send:
            canbus_id: can_bus
            can_id: 0x123
            data: [0x01, 0x02, 0x03]

Before you flash: the !secret values come from your secrets.yaml, and the GPIO numbers are host-side defaults rather than properties of this part — change them to match how you actually wired it.

What Appears in Home Assistant

Send Test Frame
button

Sends three bytes, 01 02 03, with the standard ID 0x123. It is a wiring test for a bench bus, not something to press while connected to a car.

Received frames
not an entity

The on_frame handler matches every ID (can_id: 0 with can_id_mask: 0) and only writes each frame's ID and length to the log. A value reaches Home Assistant only when a handler for one ID decodes the bytes in a lambda and publishes them to a template sensor, one per value, as on the MCP2515 page.

Known Problems and Fixes

A bus of one cannot send

Every CAN frame must be acknowledged by another node. With the S3 alone on the wire, or the other node at a different bit rate, Send Test Frame is never acknowledged. The controller keeps retrying and its error counters climb, and once the transmit queue is full further sends fail with a "send to standard id=0x123 failed" line in the log. Test with two nodes, or with a USB CAN adapter on the other end.

Listen first on a car

mode: LISTENONLY stops the S3 from transmitting anything, including acknowledgements and error frames. That is the safe way to find a vehicle's bit rate and IDs. In normal mode at the wrong bit rate, a node treats every frame as an error and signals it, disrupting the bus it is plugged into. The config uses normal mode only because the test button needs it.

Termination

A CAN bus needs 120Ω at each physical end and nowhere else, which measures about 60Ω across CANH and CANL with the power off. Check whether your breakout carries its own resistor (an SMD part marked 121). Keep it for a two-node bench bus, and remove it for an OBD-II port, where the car already has both.

The bit rate belongs to the bus

The config sets 500KBPS, the usual rate on a car's OBD-II diagnostic bus. Other buses in the same car, and equipment such as battery management systems, often run at a different rate; ESPHome's own default is 125KBPS. At the wrong rate the log stays silent in listen-only mode, and in normal mode the node causes bus errors.

Classic CAN only

The S3's TWAI controller handles CAN 2.0 frames and treats CAN FD frames as errors. On a bus that carries FD traffic it cannot take part, and in normal mode it will flag those frames as errors on the bus.

Logging every frame

can_id_mask: 0 passes every frame to the lambda. On a busy vehicle bus that can mean thousands of log lines a second, more than the logger can push over Wi-Fi. Before connecting to anything busy, narrow the handler to the IDs you want with can_id and can_id_mask.

Rs has to be low to transmit

Pin 8 of the SN65HVD230 selects its mode. Tied low, it runs at full speed; with a 10kΩ to 100kΩ resistor to GND, its edges slow down to reduce emissions; held high, it goes into a standby that only listens. If your board brings Rs out to a header, receives but never transmits, check that Rs is not pulled high.

🛠️ Hardware Correction & Field Contributions

Report a Pinout Error or Submit Tested Code Snippets

Found a pin mapping quirk or built a custom ESPHome YAML driver for SN65HVD230 TWAI CAN Transceiver? Submit a pull request or report corrections to our index.

Frequently Asked Questions

Does SN65HVD230 TWAI CAN Transceiver work without an internet connection?
100% local TWAI CAN bus processing.
How is SN65HVD230 TWAI CAN Transceiver powered and wired to the host board?
3.3V VCC CTX=GPIO5 CRX=GPIO4.
How does the host board reach Home Assistant (ESPHome)?
Wi-Fi 2.4GHz.

Alternatives

Guides for this part

Related Compatibility Matrix Guides