IoT4Car: телеметрия авто через OBD-II на Arduino MKR1000 + облако (dweet.io + freeboard.io)
Компоненты и материалы
- Arduino MKR WiFi 1000 — 1 шт. (3.3В логика!)
- SparkFun OBD-II UART Board (чип STN1110, ELM327-совместимый) — 1 шт.
- Кабель OBD-II → DB9 — 1 шт.
- Logic Level Converter (двунаправленный, 5В↔3.3В) — 1 шт. (обязателен для MKR!)
- LCD 1602 (опционально, для локального вывода) — 1 шт.
Программное обеспечение и сервисы
- Arduino IDE
- dweet.io (простой IoT-брокер, HTTP POST)
- freeboard.io (дашборды, виджеты, читает dweet.io)
Как это работает
- OBD-II UART плата подключается к диагностическому разъёму авто (стандарт с 1996 г., CAN-обязателен с 2008 г.).
- STN1110 переводит OBD-протоколы в UART (AT-команды ELM327).
- MKR1000 общается с платой через Serial1 (пины 13=RX, 14=TX) через логический преобразователь.
- MKR отправляет PID-запросы: 010D (скорость), 010C (об/мин), 012F (уровень топлива), 0105 (температура ОЖ).
- Ответы парсятся, значения конвертируются в физические единицы.
- Данные выводятся на LCD и каждые 10 сек отправляются на dweet.io (HTTP POST).
- freeboard.io визуализирует: спидометр, тахометр, уровень топлива, термометр.
Важные нюансы
- Serial1, а не Serial! На MKR пины 13/14 — это Serial1. Serial — это USB-CDC для ПК.
- Уровни 5В от OBD-платы → 3.3В MKR через конвертер. Прямое подключение убьёт MKR.
- WiFi в машине: автор использует телефон как точку доступа. Для продакшена лучше MKR GSM 1400.
- Парсинг ответа: формат `>1 PID DATA...`, данные начинаются с 6-го символа.
Пример конвертации данных
- RPM: ответ `0C 098C` → 0x098C / 4 = 2444 об/мин
- Speed: `0D 3C` → 0x3C = 60 км/ч → ×0.621 = 37 миль/ч
- Fuel: `2F 1D` → 0x1D / 255 × 100 = 11%
- Coolant: `05 79` → 0x79 − 40 = 81 °C
Код (основные фрагменты)
// WiFi + dweet.io
#include <WiFi101.h>
#include <SPI.h>
#include <LiquidCrystal.h>
char ssid[] = "YOUR_SSID";
char pass[] = "YOUR_PASS";
char server[] = "www.dweet.io";
WiFiClient client;
unsigned long lastPost = 0;
const long postInterval = 10000; // 10 сек
// LCD
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// OBD
char rxData[20]; uint8_t rxIndex = 0;
int vSpeed=0, vRPM=0, vFuel=0, vTemp=0;
void setup() {
lcd.begin(16,2);
Serial1.begin(9600); // OBD UART
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) delay(500);
}
void loop() {
getSpeed(); // 010D
getRPM(); // 010C
getFuel(); // 012F
getCoolTemp(); // 0105
if (millis() - lastPost > postInterval) { httpRequest(); lastPost = millis(); }
}
void getSpeed() {
Serial1.println("010D"); delay(200); getResponse();
vSpeed = strtol(&rxData[6], 0, 16) * 0.621371; // mph
lcd.setCursor(0,0); lcd.print(vSpeed); lcd.print(" mph");
}
void getRPM() {
Serial1.println("010C"); delay(200); getResponse();
vRPM = (strtol(&rxData[6],0,16)*256 + strtol(&rxData[9],0,16)) / 4;
lcd.setCursor(8,0); lcd.print(vRPM); lcd.print(" rpm");
}
void getFuel() {
Serial1.println("012F"); delay(200); getResponse();
vFuel = strtol(&rxData[6],0,16) * 100.0 / 255;
lcd.setCursor(0,1); lcd.print(vFuel); lcd.print(" %");
}
void getCoolTemp() {
Serial1.println("0105"); delay(200); getResponse();
vTemp = strtol(&rxData[6],0,16) - 40;
lcd.setCursor(8,1); lcd.print(vTemp); lcd.write(0xDF); lcd.print("C");
}
void getResponse() {
while (Serial1.available()) {
char c = Serial1.read();
if (c == '\r') { rxData[rxIndex] = '\0'; rxIndex = 0; break; }
if (rxIndex < 19) rxData[rxIndex++] = c;
}
}
void httpRequest() {
if (client.connect(server, 80)) {
String data = "POST /dweet/for/mkr1000?RPM=" + String(vRPM) +
"&Speed=" + String(vSpeed) +
"&Fuel=" + String(vFuel) +
"&Temp=" + String(vTemp);
client.println(data);
client.println("Host: www.dweet.io");
client.println("Connection: close");
client.println();
}
}
Настройка дашборда freeboard.io
- Создать Datasource → Type: JSON, URL: `https://dweet.io/get/latest/dweet/for/mkr1000`, Refresh: 10 сек.
- Добавить Pane → Gauge widgets для RPM, Speed, Fuel, Temp, привязать к datasource.
Перспективы
- Проектирование единой PCB с интеграцией всех модулей.
- Переход на MKR GSM 1400 для независимости от Wi-Fi.
- Добавление GPS, акселерометра, анализ стиля вождения, предиктивное обслуживание.
Производственный процесс
- Полное руководство по транспортным номерам: история, дизайн и будущее
- Антиблокировочная тормозная система (ABS): безопасность на скользких дорогах
- Понимание трансмиссии: как она приводит в движение ваш автомобиль
- Понимание генератора: как он питает ваш автомобиль и признаки отказа
- Система избегания препятствий с ИИ (Q-learning) на Arduino и ультразвуковых датчиках
- DIY USB-геймпад на Arduino: собственный высокопроизводительный контроллер
- DIY-костюм «Облако»: LED-лента, Arduino Nano и детали SparkFun
- Заземление шасси (Chassis Ground): назначение, принцип и значение
- Компоновка шасси автомобиля: положение двигателя и приводные схемы
- Автомобильная проводка: ключевые концепции для надежной работы