Home

Awesome

LIN-Interface-Library

LIN-BUS Implementation on Frame, Transportation and Node-Configuration Level

The HardwareSerial UART of an ESP32 is used. (But in the past I used a software serial and therefore I derived this class in a prior version from the class SoftwareSerial.)

Transceiver

I've used a TJA1020 Transceiver on HW side in my project. The chip contains a statemachine, which needs to be controlled before you will be able to write or receive data. To keep things easy, I created a derived class (from this one) which consider the statemachine every time using the bus: https://github.com/mestrode/Lin-Transceiver-Library

example

Remark: Current Example uses v.0.0.2. The interface was modified in in Version 1.0.0.

Need a basic example: Take a look into the example folder.

More complex example: Take a look into this repo to see, how this works: https://github.com/mestrode/IBS-Sensor-Library

This code calls some methods of BatSensor which utilizes the Lin-Interface

// LIN Bus Interface provided viy TJA1020
#include "TJA1020.hpp"
// IBS Batterie Sensor
#include "IBS_Sensor.hpp"

#define LIN_SERIAL_SPEED LIN_BAUDRATE_IBS_SENSOR /* Required by IBS Sensor */
#define lin_NSLP_Pin 32

// utilize the TJA1020 by using UART2 for writing and reading frames
// but keep in mind: the Lin_TJA1020 is only an extension of this library.
Lin_TJA1020 LinBus(2, LIN_SERIAL_SPEED, lin_NSLP_Pin); // UART_nr, Baudrate, /SLP

// Hella IBS 200x "Sensor 2"
IBS_Sensor BatSensor(2);

void setup()
{
    // tell the BatSensor object which LinBus to be used
    BatSensor.LinBus = &LinBus;
}

void showSensorData() {
    // read data from sensor (method request data by using several
    // Lin-Frames)
    BatSensor.readFrames();

    // may you using a Bus-Transceiver like the TJA1020 which should
    // go to sleep after transmission (depends on your HW)
    LinBus.setMode(LinBus.Sleep);

    // use received data
    Serial.printf("Calibration done: %d &\n",
                               BatSensor.CalibrationDone);
    Serial.printf("Voltage: %.3f Volt\n", BatSensor.Ubat);
    Serial.printf("Current: %.3f Ampere\n", BatSensor.Ibat);
    Serial.printf("State of Charge: %.1f %\n", BatSensor.SOC);
    Serial.printf("State of Health: %.1f &\n", BatSensor.SOH);
    Serial.printf("Available Capacity: %.1f &\n", BatSensor.Cap_Available);
}

The LinBus is provided to the BatSensor and is used internally.

The actual data handling looks like this:

bool IBS_Sensor::readFrameCapacity()
{
    bool chkSumValid = LinBus->readFrame(IBS_FrameID[_SensorNo][IBS_FRM_CAP]);
    if (chkSumValid)
    {
        // decode some bytes (incl. rescaling)
        Cap_Max = (float((LinBus->LinMessage[1] << 8) + LinBus->LinMessage[0])) / 10;
        Cap_Available = (float((LinBus->LinMessage[3] << 8) + LinBus->LinMessage[2])) / 10;
        // receive a single byte
        Cap_Configured = LinBus->LinMessage[4];
        // decode flags within a byte
        CalibByte = LinBus->LinMessage[5];
        CalibrationDone = bitRead(LinBus->LinMessage[5], 0);
    }
    return chkSumValid;
}

configuration frames

See description of Frame 0x3C and 0x3D in the doc folder of this project.

Don't know if this is valid in general, but at least in the Project IBS-Sensor-Library it worked.

Compiler Flags

Remember that we use gnu++17 in the compiler flags

See also

LIN Specification 2.2A provides by lin-cia.org https://www.lin-cia.org/fileadmin/microsites/lin-cia.org/resources/documents/LIN_2.2A.pdf

IBS-Sensor-Library https://github.com/mestrode/IBS-Sensor-Library

LIN-Transceiver-Library (TJA1020) https://github.com/mestrode/Lin-Transceiver-Library