Well to start im working with a freematics ONE+ OBD data logger. The documentation and how to actually use this thing is scarce for new users. They seem to think everyone is as advanced as they are and their forum is sub par with answering anything so thats why im here. The other thing is that im new to this so please bear with me. i have an idea that i will explain below but i am unsure to to make it actually work.
What i am trying to do is make the freematics one+ into a data logger for an old audi motronic that has a custom data logging protocol written into it. its fairly simple how it works. there are 2 siemens SAB80C535 processors and they have to take turns sending data. the first processor sends its data than 0xAA 0xBB HEX, this lets the other processor thats watching know when its its turn to send its data and the process starts over. the baud rate of this output is 187500 as thats as fast as these processors can go. how we connect to these now is with a cheap ebay VAG data cable is pretty much a simple USB to serial converter. as soon as the ECU boots its sending data, there is no telling it to start the logging.
What i want to do is use the ONE+ as a bluetooth logger and be able to log internally to the SD card.
This is the data that is sent from the ECU. This came from a DLL plugin that he created for tuner pro RT semi open source tuning software.
// Calculates and sets data
void setData(unsigned char* buf, int len) {
// Boost chip
fielddata[0] = buf[0]/194.0*100; //N75
fielddata[1] = buf[1]/194.0*100; //N75 base
fielddata[2] = (buf[2] / 255.0 * 5 / 1.03515625*config.mapMult + config.mapOffset)*0.14503773800722 - 14.6959494; //PSI
fielddata[3] = buf[2] / 255.0 * 5 / 1.03515625*config.mapMult + config.mapOffset; //MAP
fielddata[4] = (buf[3] / 255.0 * 5 / 1.03515625*config.mapMult + config.mapOffset)*0.14503773800722 - 14.6959494; //PSI REQ
fielddata[5] = buf[3] / 255.0 * 5 / 1.03515625*config.mapMult + config.mapOffset; //MAP REQ
fielddata[6] = buf[4]*0.5; // KNOCK1
fielddata[7] = buf[5]*0.5; // KNOCK2
fielddata[8] = buf[6]*0.5; // KNOCK3
fielddata[9] = buf[7]*0.5; // KNOCK4
fielddata[10] = buf[8]*0.5; // KNOCK5
fielddata[11] = buf[9]*0.5; // KNOCKGLOB
fielddata[12] = buf[10]*0.5; // KNOCKDYN
// Fuel chip
fielddata[13] = (buf[31])*40; //RPM
fielddata[14] = (buf[30]*256+buf[29])/25.0; //LOAD
fielddata[15] = (buf[28])*0.068; //Battery voltage
fielddata[16] = (((buf[27])-70.0)*0.70)*9/5+32; //IAT (F)
fielddata[17] = (((buf[27])-70.0)*0.70); //IAT (C)
fielddata[18] = (((buf[26])-70.0)*0.70)*9/5+32; //ECT (F)
fielddata[19] = (((buf[26])-70.0)*0.70); //ECT (C)
fielddata[20] = (buf[25])*0.416; //TPS
fielddata[21] = 0.75*((buf[24])-(buf[23])); //Timing request
double ipw = 0.52*((buf[22]) + (buf[21])/256.0);
fielddata[22] = ipw; //IPW (effective)
fielddata[23] = (buf[20])*0.010667; // Injector dead time
fielddata[24] = ipw + fielddata[23]; // IPW (actual)
fielddata[25] = fielddata[24]*fielddata[13]/1200.0; // IDC
fielddata[26] = (((buf[19]*2)/1.609344)-0.621371)-2; //VSS MPH
fielddata[27] = buf[19]*2; //VSS KMH
fielddata[28] = ((buf[18]*0.0196078)-0.4)*2 +10; //Zetronix Wideband input
fielddata[29] = buf[17]; //MAF table cell
// Target AFR
double calcvalue = (buf[15]*256+buf[14])*pow(2.0, buf[13]);
unsigned char injconstant = buf[16] == 0 ? 1 : buf[16];
calcvalue = (128.0/injconstant)*calcvalue;
calcvalue = calcvalue == 0 ? 1 : calcvalue;
calcvalue = 1/(calcvalue/65536.0)*14.7;
fielddata[30] = calcvalue > 99.0 ? 99.00 : calcvalue;
// Knock including DYN and GLOB
fielddata[31] = fielddata[6] + fielddata[11] + fielddata[12]; // KNOCKOUT1
fielddata[32] = fielddata[7] + fielddata[11] + fielddata[12]; // KNOCKOUT2
fielddata[33] = fielddata[8] + fielddata[11] + fielddata[12]; // KNOCKOUT3
fielddata[34] = fielddata[9] + fielddata[11] + fielddata[12]; // KNOCKOUT4
fielddata[35] = fielddata[10] + fielddata[11] + fielddata[12]; // KNOCKOUT5
fielddata[36] = (fielddata[31] + fielddata[32] + fielddata[33] + fielddata[34] + fielddata[35])/5; // KNOCKOUTAVG
// Ignition angle output
fielddata[37] = fielddata[21] - fielddata[31]; //IGNOUT1
fielddata[38] = fielddata[21] - fielddata[32]; //IGNOUT2
fielddata[39] = fielddata[21] - fielddata[33]; //IGNOUT3
fielddata[40] = fielddata[21] - fielddata[34]; //IGNOUT4
fielddata[41] = fielddata[21] - fielddata[35]; //IGNOUT5
My first goal is to get this to push the data from the ECU over bluetooth. once that is achieved than focusing on logging to the SD card is my next step.
this is something that was recently added to the freematics github, they call it uart_forward which is what i think i need to make this all start coming together. the code for it is below. it will not compile at all.
#include <Arduino.h>
#include "esp_task_wdt.h"
#define PIN_LED 4
#define PIN_UART_RXD 32
#define PIN_UART_TXD 33
#define PIN_POWER 15
#define USE_SOFT_SERIAL 0
#define UART_BAUDRATE 115200
TaskHandle_t xThread;
#if USE_SOFT_SERIAL
uint32_t inline IRAM_ATTR getCycleCount()
{
uint32_t ccount;
__asm__ __volatile__("esync; rsr %0,ccount":"=a" (ccount));
return ccount;
}
uint8_t inline IRAM_ATTR readRxPin()
{
#if PIN_UART_RXD < 32
return (uint8_t)(GPIO.in >> PIN_UART_RXD) << 7;
#else
return (uint8_t)(GPIO.in1.val >> (PIN_UART_RXD - 32)) << 7;
#endif
}
void inline setTxPinHigh()
{
#if PIN_UART_TXD < 32
GPIO.out_w1ts = ((uint32_t)1 << PIN_UART_TXD);
#else
GPIO.out1_w1ts.val = ((uint32_t)1 << (PIN_UART_TXD - 32));
#endif
}
void inline setTxPinLow()
{
#if PIN_UART_TXD < 32
GPIO.out_w1tc = ((uint32_t)1 << PIN_UART_TXD);
#else
GPIO.out1_w1tc.val = ((uint32_t)1 << (PIN_UART_TXD - 32));
#endif
}
void serialTx(uint8_t c)
{
uint32_t start = getCycleCount();
// start bit
setTxPinLow();
for (uint32_t i = 1; i <= 8; i++, c >>= 1) {
while (getCycleCount() - start < i * F_CPU / UART_BAUDRATE);
if (c & 0x1)
setTxPinHigh();
else
setTxPinLow();
}
while (getCycleCount() - start < (uint32_t)9 * F_CPU / UART_BAUDRATE) taskYIELD();
setTxPinHigh();
while (getCycleCount() - start < (uint32_t)10 * F_CPU / UART_BAUDRATE) taskYIELD();
}
#endif
void IRAM_ATTR taskRx(void* arg)
{
#if USE_SOFT_SERIAL
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
for (;;) {
while (readRxPin());
uint32_t start = getCycleCount();
uint8_t c = 0;
taskYIELD();
taskENTER_CRITICAL(&mux);
for (uint32_t i = 1; i <= 8; i++) {
while (getCycleCount() - start < i * F_CPU / UART_BAUDRATE + F_CPU / UART_BAUDRATE / 3);
c = (c | readRxPin()) >> 1;
}
taskEXIT_CRITICAL(&mux);
Serial.write(c);
while (getCycleCount() - start < (uint32_t)9 * F_CPU / UART_BAUDRATE + F_CPU / UART_BAUDRATE / 2) taskYIELD();
}
#else
for (;;) {
if (Serial1.available()) {
char c = Serial1.read();
Serial.write(c);
} else {
taskYIELD();
}
}
#endif
}
void setup()
{
pinMode(PIN_LED, OUTPUT);
pinMode(PIN_POWER, OUTPUT);
digitalWrite(PIN_POWER, HIGH);
delay(100);
// USB serial
Serial.begin(115200);
// GPS serial
#if USE_SOFT_SERIAL
pinMode(PIN_UART_RXD, INPUT);
pinMode(PIN_UART_TXD, OUTPUT);
digitalWrite(PIN_UART_TXD, HIGH);
#else
Serial1.begin(UART_BAUDRATE, SERIAL_8N1, PIN_UART_RXD, PIN_UART_TXD);
#endif
// start serial UART Rx task
xTaskCreate(taskRx, "taskRx", 1024, 0, 1, &xThread);
// set watchdog
esp_task_wdt_init(3600, 0);
}
void loop()
{
if (Serial.available()) {
digitalWrite(PIN_LED, HIGH);
char c = Serial.read();
#if USE_SOFT_SERIAL
serialTx(c);
#else
Serial1.write(c);
#endif
digitalWrite(PIN_LED, LOW);
}
}
so anyone thats willing to help me figure out a starting point and give some pointers would be great. thanks.