Refactoring of commandQueue to support stxChar defined for each command
This commit is contained in:
80
CarBmwI3.cpp
80
CarBmwI3.cpp
@@ -8,44 +8,45 @@
|
||||
void CarBmwI3::activateCommandQueue() {
|
||||
const uint16_t commandQueueLoopFrom = 18;
|
||||
|
||||
const std::vector<String> commandQueue = {
|
||||
"AT Z", // Reset all
|
||||
"AT D", // All to defaults
|
||||
"AT I", // Print the version ID
|
||||
"AT E0", // Echo off
|
||||
"AT PP2COFF", // Disable prog parameter 2C
|
||||
//"AT SH6F1", // Set header to 6F1
|
||||
"AT CF600", // Set the ID filter to 600
|
||||
"AT CM700", // Set the ID mask to 700
|
||||
"AT PBC001", // Protocol B options and baudrate (div 1 = 500k)
|
||||
"AT SPB", // Set protocol to B and save it (USER1 11bit, 125kbaud)
|
||||
"AT AT0", // Adaptive timing off
|
||||
"AT STFF", // Set timeout to ff x 4ms
|
||||
"AT AL", // Allow long messages ( > 7 Bytes)
|
||||
"AT H1", // Additional headers on
|
||||
"AT S0", // Printing of spaces off
|
||||
"AT L0", // Linefeeds off
|
||||
"AT CSM0", // Silent monitoring off
|
||||
"AT CTM5", // Set timer multiplier to 5
|
||||
"AT JE", // Use J1939 SAE data format
|
||||
// const std::vector<String> commandQueue = {
|
||||
const std::vector<LiveData::Command_t> commandQueue = {
|
||||
{0, "ATZ"}, // Reset all
|
||||
{0, "ATD"}, // All to defaults
|
||||
{0, "ATI"}, // Print the version ID
|
||||
{0, "ATE0"}, // Echo off
|
||||
{0, "ATPP2COFF"}, // Disable prog parameter 2C
|
||||
//{0, "ATSH6F1"}, // Set header to 6F1
|
||||
{0, "ATCF600"}, // Set the ID filter to 600
|
||||
{0, "ATCM700"}, // Set the ID mask to 700
|
||||
{0, "ATPBC001"}, // Protocol B options and baudrate (div 1 = 500k)
|
||||
{0, "ATSPB"}, // Set protocol to B and save it (USER1 11bit, 125kbaud)
|
||||
{0, "ATAT0"}, // Adaptive timing off
|
||||
{0, "ATSTFF"}, // Set timeout to ff x 4ms
|
||||
{0, "ATAL"}, // Allow long messages ( > 7 Bytes)
|
||||
{0, "ATH1"}, // Additional headers on
|
||||
{0, "ATS0"}, // Printing of spaces off
|
||||
{0, "ATL0"}, // Linefeeds off
|
||||
{0, "ATCSM0"}, // Silent monitoring off
|
||||
{0, "ATCTM5"}, // Set timer multiplier to 5
|
||||
{0, "ATJE"}, // Use J1939 SAE data format
|
||||
|
||||
// Loop from (BMW i3)
|
||||
// BMS
|
||||
"ATSH6F1",
|
||||
{0, "ATSH6F1"},
|
||||
|
||||
"22402B", // STATUS_MESSWERTE_IBS - 12V Bat
|
||||
//////"22F101", // STATUS_A_T_ELUE ???
|
||||
"22D85C", // Calculated indoor temperature
|
||||
"22D96B", // Outdoor temperature
|
||||
//"22DC61", // BREMSLICHT_SCHALTER
|
||||
"22DD7B", // ALTERUNG_KAPAZITAET Aging of kapacity
|
||||
"22DD7C", // GW_INFO - should contain kWh but in some strange form
|
||||
"22DDBF", // Min and Max cell voltage
|
||||
"22DDC0", // TEMPERATUREN
|
||||
"22DD69", // HV_STORM
|
||||
//"22DD6C", // KUEHLKREISLAUF_TEMP
|
||||
"22DDB4", // HV_SPANNUNG
|
||||
"22DDBC" // SOC
|
||||
{0x12, "22402B"}, // STATUS_MESSWERTE_IBS - 12V Bat
|
||||
//////{0x12, "22F101"}, // STATUS_A_T_ELUE ???
|
||||
{0x78, "22D85C"}, // Calculated indoor temperature
|
||||
{0x78, "22D96B"}, // Outdoor temperature
|
||||
//{0, "22DC61"}, // BREMSLICHT_SCHALTER
|
||||
{0x07, "22DD7B"}, // ALTERUNG_KAPAZITAET Aging of kapacity
|
||||
{0x07, "22DD7C"}, // GW_INFO - should contain kWh but in some strange form
|
||||
{0x07, "22DDBF"}, // Min and Max cell voltage
|
||||
{0x07, "22DDC0"}, // TEMPERATUREN
|
||||
{0x07, "22DD69"}, // HV_STORM
|
||||
//{0x07, "22DD6C"}, // KUEHLKREISLAUF_TEMP
|
||||
{0x07, "22DDB4"}, // HV_SPANNUNG
|
||||
{0x07, "22DDBC"} // SOC
|
||||
|
||||
|
||||
};
|
||||
@@ -65,17 +66,12 @@ void CarBmwI3::activateCommandQueue() {
|
||||
liveData->params.tireRearRightTempC = 0;
|
||||
|
||||
// Empty and fill command queue
|
||||
for(auto item : liveData->commandQueue) {
|
||||
item = "";
|
||||
}
|
||||
|
||||
for (int i = 0; i < commandQueue.size(); i++) {
|
||||
liveData->commandQueue[i] = commandQueue[i];
|
||||
}
|
||||
liveData->commandQueue.clear(); // probably not needed before assign
|
||||
liveData->commandQueue.assign(commandQueue.begin(), commandQueue.end());
|
||||
|
||||
liveData->commandQueueLoopFrom = commandQueueLoopFrom;
|
||||
liveData->commandQueueCount = commandQueue.size();
|
||||
liveData->rxBuffOffset = 1; // there is one additional byte in received packets compared to other cars
|
||||
liveData->bAdditionalStartingChar = true; // there is one additional byte in received packets compared to other cars
|
||||
liveData->expectedMinimalPacketLength = 6; // to filter occasional 5-bytes long packets
|
||||
liveData->rxTimeoutMs = 500; // timeout for receiving of CAN response
|
||||
liveData->delayBetweenCommandsMs = 100; // delay between commands, set to 0 if no delay is needed
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "CarHyundaiIoniq.h"
|
||||
#include <vector>
|
||||
|
||||
#define commandQueueCountHyundaiIoniq 27
|
||||
#define commandQueueLoopFromHyundaiIoniq 8
|
||||
|
||||
/**
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
void CarHyundaiIoniq::activateCommandQueue() {
|
||||
|
||||
String commandQueueHyundaiIoniq[commandQueueCountHyundaiIoniq] = {
|
||||
std::vector<String> commandQueueHyundaiIoniq = {
|
||||
"AT Z", // Reset all
|
||||
"AT I", // Print the version ID
|
||||
"AT E0", // Echo off
|
||||
@@ -68,15 +68,13 @@ void CarHyundaiIoniq::activateCommandQueue() {
|
||||
liveData->params.batModuleTempCount = 12;
|
||||
|
||||
// Empty and fill command queue
|
||||
for (int i = 0; i < 300; i++) {
|
||||
liveData->commandQueue[i] = "";
|
||||
}
|
||||
for (int i = 0; i < commandQueueCountHyundaiIoniq; i++) {
|
||||
liveData->commandQueue[i] = commandQueueHyundaiIoniq[i];
|
||||
liveData->commandQueue.clear();
|
||||
for (auto cmd : commandQueueHyundaiIoniq) {
|
||||
liveData->commandQueue.push_back({ 0, cmd });
|
||||
}
|
||||
|
||||
liveData->commandQueueLoopFrom = commandQueueLoopFromHyundaiIoniq;
|
||||
liveData->commandQueueCount = commandQueueCountHyundaiIoniq;
|
||||
liveData->commandQueueCount = commandQueueHyundaiIoniq.size();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "CarKiaDebugObd2.h"
|
||||
#include <vector>
|
||||
|
||||
#define commandQueueCountDebugObd2Kia 256
|
||||
//#define commandQueueCountDebugObd2Kia 256
|
||||
#define commandQueueLoopFromDebugObd2Kia 8
|
||||
|
||||
/**
|
||||
@@ -8,7 +9,7 @@
|
||||
*/
|
||||
void CarKiaDebugObd2::activateCommandQueue() {
|
||||
|
||||
String commandQueueDebugObd2Kia[commandQueueCountDebugObd2Kia] = {
|
||||
std::vector<String> commandQueueDebugObd2Kia = {
|
||||
"AT Z", // Reset all
|
||||
"AT I", // Print the version ID
|
||||
"AT E0", // Echo off
|
||||
@@ -219,15 +220,13 @@ void CarKiaDebugObd2::activateCommandQueue() {
|
||||
liveData->params.batteryTotalAvailableKWh = 64;
|
||||
|
||||
// Empty and fill command queue
|
||||
for (uint16_t i = 0; i < 300; i++) {
|
||||
liveData->commandQueue[i] = "";
|
||||
}
|
||||
for (uint16_t i = 0; i < commandQueueCountDebugObd2Kia; i++) {
|
||||
liveData->commandQueue[i] = commandQueueDebugObd2Kia[i];
|
||||
liveData->commandQueue.clear();
|
||||
for (auto cmd : commandQueueDebugObd2Kia) {
|
||||
liveData->commandQueue.push_back({ 0, cmd });
|
||||
}
|
||||
|
||||
liveData->commandQueueLoopFrom = commandQueueLoopFromDebugObd2Kia;
|
||||
liveData->commandQueueCount = commandQueueCountDebugObd2Kia;
|
||||
liveData->commandQueueCount = commandQueueDebugObd2Kia.size();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
#include <sys/time.h>
|
||||
#include "LiveData.h"
|
||||
#include "CarKiaEniro.h"
|
||||
#include <vector>
|
||||
|
||||
#define commandQueueCountKiaENiro 29
|
||||
#define commandQueueLoopFromKiaENiro 8
|
||||
|
||||
/**
|
||||
@@ -24,7 +24,7 @@
|
||||
*/
|
||||
void CarKiaEniro::activateCommandQueue() {
|
||||
|
||||
String commandQueueKiaENiro[commandQueueCountKiaENiro] = {
|
||||
std::vector<String> commandQueueKiaENiro = {
|
||||
"AT Z", // Reset all
|
||||
"AT I", // Print the version ID
|
||||
"AT S0", // Printing of spaces on
|
||||
@@ -90,15 +90,14 @@ void CarKiaEniro::activateCommandQueue() {
|
||||
}
|
||||
|
||||
// Empty and fill command queue
|
||||
for (int i = 0; i < 300; i++) {
|
||||
liveData->commandQueue[i] = "";
|
||||
}
|
||||
for (int i = 0; i < commandQueueCountKiaENiro; i++) {
|
||||
liveData->commandQueue[i] = commandQueueKiaENiro[i];
|
||||
liveData->commandQueue.clear();
|
||||
//for (int i = 0; i < commandQueueCountKiaENiro; i++) {
|
||||
for (auto cmd : commandQueueKiaENiro) {
|
||||
liveData->commandQueue.push_back({ 0, cmd }); // stxChar not used, keep it 0
|
||||
}
|
||||
|
||||
liveData->commandQueueLoopFrom = commandQueueLoopFromKiaENiro;
|
||||
liveData->commandQueueCount = commandQueueCountKiaENiro;
|
||||
liveData->commandQueueCount = commandQueueKiaENiro.size();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "CarKiaNiroPhev.h"
|
||||
#include <vector>
|
||||
|
||||
#define commandQueueCountKiaNiroPhev 25
|
||||
#define commandQueueLoopFromKiaNiroPhev 8
|
||||
|
||||
/**
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
void CarKiaNiroPhev::activateCommandQueue() {
|
||||
|
||||
String commandQueueKiaNiroPhev[commandQueueCountKiaNiroPhev] = {
|
||||
std::vector<String> commandQueueKiaNiroPhev = {
|
||||
"AT Z", // Reset all
|
||||
"AT I", // Print the version ID
|
||||
"AT E0", // Echo off
|
||||
@@ -64,15 +64,13 @@ void CarKiaNiroPhev::activateCommandQueue() {
|
||||
liveData->params.batModuleTempCount = 5;
|
||||
|
||||
// Empty and fill command queue
|
||||
for (int i = 0; i < 300; i++) {
|
||||
liveData->commandQueue[i] = "";
|
||||
}
|
||||
for (int i = 0; i < commandQueueCountKiaNiroPhev; i++) {
|
||||
liveData->commandQueue[i] = commandQueueKiaNiroPhev[i];
|
||||
liveData->commandQueue.clear();
|
||||
for (auto cmd : commandQueueKiaNiroPhev) {
|
||||
liveData->commandQueue.push_back({ 0, cmd });
|
||||
}
|
||||
|
||||
liveData->commandQueueLoopFrom = commandQueueLoopFromKiaNiroPhev;
|
||||
liveData->commandQueueCount = commandQueueCountKiaNiroPhev;
|
||||
liveData->commandQueueCount = commandQueueKiaNiroPhev.size();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
#include <sys/time.h>
|
||||
#include "LiveData.h"
|
||||
#include "CarRenaultZoe.h"
|
||||
#include <vector>
|
||||
|
||||
#define commandQueueCountRenaultZoe 34
|
||||
#define commandQueueLoopFromRenaultZoe 8
|
||||
|
||||
/**
|
||||
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
void CarRenaultZoe::activateCommandQueue() {
|
||||
|
||||
String commandQueueRenaultZoe[commandQueueCountRenaultZoe] = {
|
||||
std::vector<String> commandQueueRenaultZoe = {
|
||||
"AT Z", // Reset all
|
||||
"AT I", // Print the version ID
|
||||
"AT S0", // Printing of spaces on
|
||||
@@ -113,15 +113,13 @@ void CarRenaultZoe::activateCommandQueue() {
|
||||
|
||||
|
||||
// Empty and fill command queue
|
||||
for (int i = 0; i < 300; i++) {
|
||||
liveData->commandQueue[i] = "";
|
||||
}
|
||||
for (int i = 0; i < commandQueueCountRenaultZoe; i++) {
|
||||
liveData->commandQueue[i] = commandQueueRenaultZoe[i];
|
||||
liveData->commandQueue.clear();
|
||||
for (auto cmd : commandQueueRenaultZoe) {
|
||||
liveData->commandQueue.push_back({ 0, cmd });
|
||||
}
|
||||
|
||||
liveData->commandQueueLoopFrom = commandQueueLoopFromRenaultZoe;
|
||||
liveData->commandQueueCount = commandQueueCountRenaultZoe;
|
||||
liveData->commandQueueCount = commandQueueRenaultZoe.size();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -54,7 +54,9 @@ bool CommInterface::doNextQueueCommand() {
|
||||
}
|
||||
|
||||
// Send AT command to obd
|
||||
liveData->commandRequest = liveData->commandQueue[liveData->commandQueueIndex];
|
||||
liveData->commandRequest = liveData->commandQueue[liveData->commandQueueIndex].request;
|
||||
liveData->commandStartChar = liveData->commandQueue[liveData->commandQueueIndex].startChar; // TODO: add to struct?
|
||||
|
||||
if (liveData->commandRequest.startsWith("ATSH")) {
|
||||
liveData->currentAtshRequest = liveData->commandRequest;
|
||||
}
|
||||
|
||||
@@ -148,45 +148,43 @@ void CommObd2Can::sendPID(const uint16_t pid, const String& cmd) {
|
||||
uint8_t txBuf[8] = { 0 }; // init with zeroes
|
||||
String tmpStr;
|
||||
|
||||
if (liveData->settings.carType == CAR_BMW_I3_2014)
|
||||
if (liveData->bAdditionalStartingChar)
|
||||
{
|
||||
struct Packet_t
|
||||
{
|
||||
uint8_t startChar;
|
||||
uint8_t length;
|
||||
uint8_t data[6];
|
||||
uint8_t payload[6];
|
||||
};
|
||||
|
||||
Packet_t* pPacket = (Packet_t*)txBuf;
|
||||
|
||||
if (cmd == "22402B" || cmd == "22F101") {
|
||||
pPacket->startChar = txStartChar = 0x12;
|
||||
} else if (cmd == "22D85C" || cmd == "22D96B") {
|
||||
pPacket->startChar = txStartChar = 0x78;
|
||||
} else {
|
||||
pPacket->startChar = txStartChar = 0x07;
|
||||
}
|
||||
|
||||
|
||||
pPacket->startChar = liveData->commandStartChar; // todo: handle similar way as cmd input param?
|
||||
pPacket->length = cmd.length() / 2;
|
||||
|
||||
for (uint8_t i = 0; i < sizeof(pPacket->data); i++) {
|
||||
for (uint8_t i = 0; i < sizeof(pPacket->payload); i++) {
|
||||
tmpStr = cmd;
|
||||
tmpStr = tmpStr.substring(i * 2, ((i + 1) * 2));
|
||||
if (tmpStr != "") {
|
||||
pPacket->data[i] = liveData->hexToDec(tmpStr, 1, false);
|
||||
pPacket->payload[i] = liveData->hexToDec(tmpStr, 1, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
txBuf[0] = cmd.length() / 2;
|
||||
struct Packet_t
|
||||
{
|
||||
uint8_t length;
|
||||
uint8_t payload[7];
|
||||
};
|
||||
|
||||
Packet_t* pPacket = (Packet_t*)txBuf;
|
||||
pPacket->length = cmd.length() / 2;
|
||||
|
||||
for (uint8_t i = 0; i < 7; i++) {
|
||||
for (uint8_t i = 0; i < sizeof(pPacket->payload); i++) {
|
||||
tmpStr = cmd;
|
||||
tmpStr = tmpStr.substring(i * 2, ((i + 1) * 2));
|
||||
if (tmpStr != "") {
|
||||
txBuf[i + 1] = liveData->hexToDec(tmpStr, 1, false);
|
||||
pPacket->payload[i] = liveData->hexToDec(tmpStr, 1, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -200,6 +198,7 @@ void CommObd2Can::sendPID(const uint16_t pid, const String& cmd) {
|
||||
lastDataSent = millis();
|
||||
} else {
|
||||
syslog->infoNolf(DEBUG_COMM, "Error sending PID ");
|
||||
lastDataSent = millis();
|
||||
}
|
||||
syslog->infoNolf(DEBUG_COMM, pid);
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
@@ -216,10 +215,10 @@ void CommObd2Can::sendFlowControlFrame() {
|
||||
|
||||
uint8_t txBuf[8] = { 0x30, requestFramesCount /*request count*/, 20 /*ms between frames*/ , 0, 0, 0, 0, 0 };
|
||||
|
||||
// insert 0x07 into beginning for BMW i3
|
||||
if (liveData->settings.carType == CAR_BMW_I3_2014) {
|
||||
// insert start char if needed
|
||||
if (liveData->bAdditionalStartingChar) {
|
||||
memmove(txBuf + 1, txBuf, 7);
|
||||
txBuf[0] = txStartChar;
|
||||
txBuf[0] = liveData->commandStartChar;
|
||||
}
|
||||
|
||||
const uint8_t sndStat = CAN->sendMsgBuf(lastPid, 0, 8, txBuf); // 11 bit
|
||||
@@ -290,7 +289,8 @@ uint8_t CommObd2Can::receivePID() {
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
return rxBuf[0 + liveData->rxBuffOffset];
|
||||
const uint8_t rxBuffOffset = liveData->bAdditionalStartingChar? 1 : 0;
|
||||
return rxBuf[0 + rxBuffOffset]; // return byte containing frame type, which requires removing offset byte
|
||||
}
|
||||
|
||||
static void printHexBuffer(uint8_t* pData, const uint16_t length, const bool bAddNewLine)
|
||||
@@ -340,10 +340,10 @@ CommObd2Can::enFrame_t CommObd2Can::getFrameType(const uint8_t firstByte) {
|
||||
https://en.wikipedia.org/wiki/ISO_15765-2
|
||||
*/
|
||||
bool CommObd2Can::processFrameBytes() {
|
||||
|
||||
uint8_t* pDataStart = rxBuf + liveData->rxBuffOffset; // set pointer to data start based on specific offset of car
|
||||
const uint8_t rxBuffOffset = liveData->bAdditionalStartingChar ? 1 : 0;
|
||||
uint8_t* pDataStart = rxBuf + rxBuffOffset; // set pointer to data start based on specific offset of car
|
||||
const auto frameType = getFrameType(*pDataStart);
|
||||
const uint8_t frameLenght = rxLen - liveData->rxBuffOffset;
|
||||
const uint8_t frameLenght = rxLen - rxBuffOffset;
|
||||
|
||||
switch (frameType) {
|
||||
case enFrame_t::single: // Single frame
|
||||
|
||||
@@ -22,7 +22,6 @@ class CommObd2Can : public CommInterface {
|
||||
char msgString[128]; // Array to store serial string
|
||||
uint16_t lastPid;
|
||||
unsigned long lastDataSent = 0;
|
||||
uint8_t txStartChar = 0; // set when sending PID, used when sending FlowControl
|
||||
|
||||
std::vector<uint8_t> mergedData;
|
||||
std::unordered_map<uint16_t, std::vector<uint8_t>> dataRows;
|
||||
|
||||
12
LiveData.h
12
LiveData.h
@@ -218,15 +218,21 @@ class LiveData {
|
||||
protected:
|
||||
public:
|
||||
// Command loop
|
||||
struct Command_t {
|
||||
uint8_t startChar; // special starting character used by some cars
|
||||
String request;
|
||||
};
|
||||
|
||||
uint16_t commandQueueCount;
|
||||
uint16_t commandQueueLoopFrom;
|
||||
String commandQueue[300];
|
||||
std::vector<Command_t> commandQueue;
|
||||
String responseRow;
|
||||
String responseRowMerged;
|
||||
std::vector<uint8_t> vResponseRowMerged;
|
||||
uint16_t commandQueueIndex;
|
||||
bool canSendNextAtCommand = false;
|
||||
String commandRequest = "";
|
||||
uint8_t commandStartChar;
|
||||
String commandRequest = ""; // TODO: us Command_t struct
|
||||
String currentAtshRequest = "";
|
||||
// Menu
|
||||
bool menuVisible = false;
|
||||
@@ -249,7 +255,7 @@ class LiveData {
|
||||
BLEScan* pBLEScan;
|
||||
|
||||
// Canbus
|
||||
uint8_t rxBuffOffset = 0; // offset of processing received data, in some cars needs to be set to 1, like in BMW i3
|
||||
bool bAdditionalStartingChar = false; // some cars uses additional starting character in beginning of tx and rx messages
|
||||
uint8_t expectedMinimalPacketLength = 0; // what length of packet should be accepted. Set to 0 to accept any length
|
||||
uint16_t rxTimeoutMs = 100; // timeout for receiving of CAN response
|
||||
uint16_t delayBetweenCommandsMs = 0; // delay between commands, set to 0 if no delay is needed
|
||||
|
||||
Reference in New Issue
Block a user