MCP2515
Модуль управляет внешним CAN-контроллером MCP2515 через интерфейс SPI.
MCP2515 поддерживает CAN 2.0B и позволяет подключить шину CAN к ESP32 через внешний модуль.
mcp2515.init(spi_unit, cs_pin, [speed_khz])
Инициализация MCP2515 контроллера.
Аргументы:
- spi_unit: номер SPI шины (2 для HSPI, 3 для VSPI)
- cs_pin: номер GPIO пина для Chip Select
- speed_khz (опционально): скорость SPI в кГц, по умолчанию 1000 (1 МГц)
Возвращает: true в случае успеха, иначе ошибку.
-- Инициализация на SPI2, CS на GPIO25
mcp2515.init(2, 25)
-- Инициализация на SPI3, CS на GPIO5, скорость SPI 2 МГц
mcp2515.init(3, 5, 2000)
mcp2515.send(id, data, [extended])
Отправка CAN сообщения.
Аргументы:
- id: идентификатор CAN сообщения (11 бит для стандартного, 29 бит для расширенного)
- data: строка с данными (до 8 байт)
- extended (опционально): true для расширенного идентификатора (29 бит), по умолчанию false
Возвращает: true в случае успеха, или nil и сообщение об ошибке.
-- Отправка стандартного сообщения (11-bit ID)
mcp2515.send(0x123, "\x01\x02\x03\x04")
-- Отправка расширенного сообщения (29-bit ID)
mcp2515.send(0x18FEF100, "\xAA\xBB\xCC", true)
-- Отправка с использованием string.char
mcp2515.send(0x7DF, string.char(0x02, 0x01, 0x00))
mcp2515.recv([timeout_ms])
Приём CAN сообщения.
Аргументы:
- timeout_ms (опционально): таймаут ожидания в миллисекундах, по умолчанию 1000
Возвращает:
- При успехе: id, data, extended (идентификатор, данные как строка, флаг расширенного ID)
- При таймауте: nil
-- Приём с таймаутом 1 секунда
local id, data, extended = mcp2515.recv(1000)
if id then
print("ID: " .. string.format("0x%X", id))
print("Data: " .. #data .. " bytes")
print("Extended: " .. tostring(extended))
-- Вывод байтов данных
for i = 1, #data do
print(string.format(" byte %d: 0x%02X", i, data:byte(i)))
end
else
print("Таймаут приёма")
end
-- Бесконечное ожидание
local id, data = mcp2515.recv(0xFFFFFFFF)
mcp2515.setBitrate(bitrate)
Установка скорости CAN шины.
Аргументы:
- bitrate: скорость в бит/с или кбит/с
Поддерживаемые скорости: 10000, 25000, 50000, 100000, 125000, 250000, 500000, 1000000 бит/с
Возвращает: true в случае успеха, или nil и сообщение об ошибке.
-- Установка 250 кбит/с
mcp2515.setBitrate(250000)
-- Или используя константы
mcp2515.setBitrate(mcp2515.SPEED_250K)
-- Можно указывать в кбит/с
mcp2515.setBitrate(500) -- будет интерпретировано как 500000
mcp2515.status()
Получение статуса контроллера.
Аргументы: нет
Возвращает: таблицу со следующими полями:
- mode: текущий режим работы (“normal”, “sleep”, “loopback”, “listen”, “config”)
- rx0_pending: true если есть сообщение в буфере RX0
- rx1_pending: true если есть сообщение в буфере RX1
- rx0_overflow: true если было переполнение буфера RX0
- rx1_overflow: true если было переполнение буфера RX1
- bus_off: true если контроллер в состоянии Bus Off
- tx_passive: true если контроллер в состоянии TX Passive
- rx_passive: true если контроллер в состоянии RX Passive
- tx_errors: счётчик ошибок передачи
- rx_errors: счётчик ошибок приёма
- bitrate: текущая скорость CAN шины
local st = mcp2515.status()
print("Режим: " .. st.mode)
print("Скорость: " .. st.bitrate .. " бит/с")
print("Ошибки TX: " .. st.tx_errors)
print("Ошибки RX: " .. st.rx_errors)
if st.bus_off then
print("ВНИМАНИЕ: Bus Off!")
end
mcp2515.reset()
Сброс контроллера MCP2515.
Аргументы: нет
Возвращает: true в случае успеха, или nil и сообщение об ошибке.
-- Сброс контроллера
mcp2515.reset()
mcp2515.setFilter(index, filter_id, mask, [extended])
Установка фильтра приёма сообщений.
MCP2515 имеет 6 фильтров (0-5):
- Фильтры 0-2 работают с буфером RX0
- Фильтры 3-5 работают с буфером RX1
Аргументы:
- index: номер фильтра (0-5)
- filter_id: идентификатор для фильтрации
- mask: маска фильтра (биты установленные в 1 должны совпадать)
- extended (опционально): true для расширенного идентификатора, по умолчанию false
Возвращает: true в случае успеха.
-- Принимать только сообщения с ID 0x123
mcp2515.setFilter(0, 0x123, 0x7FF)
-- Принимать сообщения с ID 0x100-0x1FF (маска игнорирует младшие 8 бит)
mcp2515.setFilter(0, 0x100, 0x700)
-- Фильтр для расширенного ID
mcp2515.setFilter(0, 0x18FEF100, 0x1FFFFFFF, true)
mcp2515.clearFilters()
Сброс всех фильтров. После вызова контроллер будет принимать все сообщения.
Аргументы: нет
Возвращает: true в случае успеха.
-- Принимать все сообщения
mcp2515.clearFilters()
Константы
Модуль предоставляет константы для удобной установки скорости:
| Константа | Значение |
|---|---|
| mcp2515.SPEED_10K | 10000 |
| mcp2515.SPEED_25K | 25000 |
| mcp2515.SPEED_50K | 50000 |
| mcp2515.SPEED_100K | 100000 |
| mcp2515.SPEED_125K | 125000 |
| mcp2515.SPEED_250K | 250000 |
| mcp2515.SPEED_500K | 500000 |
| mcp2515.SPEED_1M | 1000000 |
Примеры
Простой обмен данными
-- Инициализация
mcp2515.init(2, 25)
mcp2515.setBitrate(mcp2515.SPEED_250K)
-- Отправка
mcp2515.send(0x123, string.char(0x01, 0x02, 0x03))
-- Приём
while true do
local id, data = mcp2515.recv(100)
if id then
print(string.format("Получено: ID=0x%X, %d байт", id, #data))
end
end
Мониторинг CAN шины
mcp2515.init(2, 25)
mcp2515.setBitrate(mcp2515.SPEED_500K)
mcp2515.clearFilters() -- принимать все сообщения
print("Мониторинг CAN шины...")
while true do
local id, data, ext = mcp2515.recv(1000)
if id then
local hex = ""
for i = 1, #data do
hex = hex .. string.format("%02X ", data:byte(i))
end
print(string.format("%s 0x%08X [%d] %s",
ext and "EXT" or "STD", id, #data, hex))
end
-- Проверка ошибок
local st = mcp2515.status()
if st.tx_errors > 0 or st.rx_errors > 0 then
print(string.format("Ошибки: TX=%d RX=%d", st.tx_errors, st.rx_errors))
end
end
Фильтрация сообщений OBD-II
mcp2515.init(2, 25)
mcp2515.setBitrate(mcp2515.SPEED_500K)
-- Принимать только ответы OBD-II (0x7E8-0x7EF)
mcp2515.setFilter(0, 0x7E8, 0x7F8)
-- Запрос RPM двигателя
mcp2515.send(0x7DF, string.char(0x02, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00))
local id, data = mcp2515.recv(1000)
if id and #data >= 4 then
local rpm = (data:byte(3) * 256 + data:byte(4)) / 4
print("RPM: " .. rpm)
end
Подключение модуля MCP2515
Типовая схема подключения модуля MCP2515 к ESP32:
| MCP2515 | ESP32 (SPI2) | ESP32 (SPI3) |
|---|---|---|
| VCC | 3.3V | 3.3V |
| GND | GND | GND |
| CS | GPIO25 (любой) | GPIO5 (любой) |
| SCK | GPIO14 | GPIO18 |
| MOSI | GPIO13 | GPIO23 |
| MISO | GPIO12 | GPIO19 |
| INT | опционально | опционально |
Начальные назначения SCK, MOSI и MISO зависят от модели устройства. Проверьте их функцией spi.pins() и при необходимости задайте другие выводы через spi.setpins() до вызова mcp2515.init().