Тема: Привязка высоковольтной батареи
Всем привет! Решил поделиться методом привязки (регистрации) высоковольтной батареи. Отдельной темы не нашел, поэтому создал новую. Здесь я приведу пример дешевой реализации на плате Ардуино + Can модуль Mcp2515, возможен также абсолютно бесплатный вариант посредством написания АТ-команд и отправки в кан с помощью ELM адаптера, используя алгоритм из моего скетча. Бонусом в скетче еще прописан перевод приборной панели, добавлен переключатель режимов. В одном положении переключателя устройство работает как привязка ВВБ, в другом перевод панели на английский.
Скетч:
#include<Arduino.h>
#include <mcp_can.h>
#include<SPI.h>
#define MODE_PIN 9
const byte data[8] = {0x02, 0x21, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00};
const byte data2[8] = {0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const byte COUNT_ROWS = 11;
byte command[COUNT_ROWS][8] = {
{0x10, 0x0A, 0x3B, 0x1F, 0x00, 0x00, 0x00, 0x00},
{0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x14, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00},
{0x02, 0x10, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x02, 0x10, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x02, 0x21, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x22, 0x12, 0x03, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x22, 0x12, 0x05, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x22, 0x12, 0x5C, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
};
byte command1[5][8] = {
{0x02, 0x10, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x06, 0x3D, 0x04, 0x00, 0x02, 0x3E, 0x02, 0x00},
{0x02, 0x11, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x14, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00}
};
long unsigned int rxId; // CAN message ID
unsigned char len = 0; // Data length
unsigned char rxBuf[8]; // Buffer IN
unsigned char txBuf[8]; // Buffer OUT
long CANInterval = 500; // 0x79b message repeat interval in case of unsuccessful previous attempts
int CANSt = 0;
long CANMillis = 0; // for 0x79b message repeat
byte RcvFrIdx = 0;
byte count = 0;
byte count1 = 0;
bool state = false;
#define CAN0_INT 2 // Set INT to pin 2
MCP_CAN CAN0(10); // Set CS to pin 10
void setup(void) {
if (CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ) == CAN_OK) {
}
else {
}
CAN0.setMode(MCP_NORMAL); // Set operation mode to normal so the MCP2515 sends acks to received data.
pinMode(CAN0_INT, INPUT); // Configuring pin for /INT input
pinMode(MODE_PIN, INPUT_PULLUP);
state = digitalRead(MODE_PIN);
}
void loop(void) {
if (state != digitalRead(MODE_PIN)) {
state = digitalRead(MODE_PIN);
count = 0;
count1 = 0;
delay(500);
}
// talking to the CANbus and caclulating stuff
if (!digitalRead(CAN0_INT)) // If CAN0_INT pin is low, read receive buffer
{
if (count == 0) {
if (digitalRead(MODE_PIN)) {
CAN0.readMsgBuf(&rxId, &len, rxBuf); // Read data: len = data length, buf = data byte(s)
if (CANSt == 0) {
byte sndStat = CAN0.sendMsgBuf(0x79b, 0, 8, data);
CANMillis = millis();
CANSt = 1;
}
if (rxId == 0x7bb && rxBuf[0] == 0x10) {
for (uint8_t k = 4; k < 8; k++ ) command[0][k] = rxBuf[k];
byte sndStat = CAN0.sendMsgBuf(0x79b, 0, 8, data2);
}
else if (rxId == 0x7bb && rxBuf[0] == 0x21) {
for (uint8_t k = 1; k < 5; k++ ) command[1][k] = rxBuf[k];
RcvFrIdx = 1;
}
if (RcvFrIdx == 1) {
// Отправление посылки
for (uint8_t k = 0; k < COUNT_ROWS; k++) {
for (uint8_t i = 0; i < 8; i++) txBuf[i] = command[k][i];
byte sndStat = CAN0.sendMsgBuf(0x797, 0, 8, txBuf);
delay(100);
}
delay(500);
count = 1;
}
//unsigned long currentCANMillis = millis();
if (millis() - CANMillis > (3 * CANInterval)) {
CANSt = 0;
}
}
}
if (count1 == 0) {
if (! digitalRead(MODE_PIN)) {
for (uint8_t k = 0; k < 5; k++) {
for (uint8_t i = 0; i < 8; i++) txBuf[i] = command1[k][i];
byte sndStat = CAN0.sendMsgBuf(0x743, 0, 8, txBuf);
delay(200);
}
count1 = 1;
}
}
}
}
Схема подключения: