Giter Club home page Giter Club logo

lin's Introduction

LIN Library

Library and examples for LIN (Local Interconnect Network) on Arduino. Developed for the Macchina M2. Can be modified for any Arduino board with UART available and any LIN slave.

Install

  1. Download the files
  2. Move the folder LIN to your Arduino Libraries

EXAMPLES

Several example sketches are included in the LIN Library to demonstrate typical usage:

  • Lin2Lin M2 acts as the Sniffer – when traffic on one LIN channel is detected, incoming data is saved and then sent to another LIN channel with no modification. Arduino Due with simple 1-bit ADC is used as Master Node on first LIN bus and Ambient Light Module is used as a slave on another LIN bus.

  • Master works with Microchip’s Ambient Light Module. User builds an array of bytes, which is the length of the message and contains packages to be send to the module. Package is built out of Control Byte (control intensity, dim and ramp functions for the RGB LED), Red, Green and Blue Color Bytes and Zone Byte. Checksum calculation is supported in v2.0 library. There is no need to calculate checksum and include in it package.

  • Slave M2 acts like sniffer: when traffic is detected on LIN bus, incoming data is saved and processed. Arduino Due with simple 1-bit ADC is used as master. Master Node needs to be programmed with Master example Slave_Master

Data processing: If Identification Byte is correct, Checksum Byte is compared with Checksum calculated from received data. If Checksum Byte is correct, data is printed on Serial Monitor via SerialUSB. Otherwise error is printed on Serial Monitor and data cleared.

  • Sniffer M2 monitors traffic on LIN bus periodically. When traffic is detected, Sniffer reads incoming data and prints it on Serial Monitor via SerialUSB.

NOTES

LIN Stack was developed using the following:

More information about LIN can be found in those documents.

Changes duronflo

  • correct checksum calculation, removed +1
  • inserted parity calculation in writeRequest method
  • implemented parity calculation
  • implemented bus wake up for proper lin bus waking up
  • Changed default baudrate to 19200 which is more common in automotive applications

lin's People

Contributors

adamvoss avatar duronflo avatar rocketjosh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lin's Issues

Need help to port this library for ATmega32M1

I am not an expert programmer, and I need a lin bus library for the atmega32M1, could anyone help me to modify it? I made some changes in lin_stack.cpp to change the Tx and Rx ports for the atmega32M1 but it does't work.
Link to atmega32m1 datasheet: http://www.atmel.com/Images/Atmel-7647-Automotive-Microcontrollers-ATmega16M1-32M1-64M1-32C1-64C1_datasheet.pdf
This is the code that I modify:

#include <lin_stack.h>
const unsigned long bound_rate = 10417;

// CONSTRUCTORS
lin_stack::lin_stack(byte Ch){
	sleep_config(Ch); // Configurating Sleep pin for transceiver
}

lin_stack::lin_stack(byte Ch, byte ident){
	sleep_config(Ch); // Configuration of Sleep pin for transceiver
	identByte = ident; // saving idet to private variable
	sleep(1); // Transceiver is always in Normal Mode
}

// PUBLIC METHODS
// WRITE methods
// Creates a LIN packet and then send it via USART(Serial) interface.
int lin_stack::write(byte ident, byte data[], byte data_size){
	// Calculate checksum
	byte suma = 0;
	for(int i=0;i<data_size;i++) suma = suma + data[i];
	suma = suma + 1;
	byte checksum = 255 - suma;
	// Start interface
	sleep(1); // Go to Normal mode
	// Synch Break
	serial_pause(13);
	// Send data via Serial interface
	if(ch==1){ // For LIN1 or Serial
		Serial.begin(bound_rate); // config Serial
		Serial.write(0x55); // write Synch Byte to serial
		Serial.write(ident); // write Identification Byte to serial
		for(int i=0;i<data_size;i++) Serial.write(data[i]); // write data to serial
		Serial.write(checksum); // write Checksum Byte to serial
		Serial.end(); // clear Serial config
	}
	sleep(0); // Go to Sleep mode
	return 1;
}

int lin_stack::writeRequest(byte ident){
	// Create Header
	byte header[2]= {0x55, ident};
	// Start interface
	sleep(1); // Go to Normal mode
	// Synch Break
	serial_pause(13);
	// Send data via Serial interface
	if(ch==1){ // For LIN1 or Serial
		Serial.begin(bound_rate); // config Serial
		Serial.write(header,2); // write data to serial
		Serial.end(); // clear Serial config
	}
	sleep(0); // Go to Sleep mode
	return 1;
}

int lin_stack::writeResponse(byte data[], byte data_size){
	// Calculate checksum
	byte suma = 0;
	for(int i=0;i<data_size;i++) suma = suma + data[i];
	suma = suma + 1;
	byte checksum = 255 - suma;
	// Start interface
	sleep(1); // Go to Normal mode
	// Send data via Serial interface
	if(ch==1){ // For LIN1 or Serial
		Serial.begin(bound_rate); // config Serial
		Serial.write(data, data_size); // write data to serial
		Serial.write(checksum); // write data to serial
		Serial.end(); // clear Serial config
	}
	sleep(0); // Go to Sleep mode
	return 1;
}

int lin_stack::writeStream(byte data[], byte data_size){
	// Start interface
	sleep(1); // Go to Normal mode
	// Synch Break
	serial_pause(13);
	// Send data via Serial interface
	if(ch==1){ // For LIN1 or Serial
		Serial.begin(bound_rate); // config Serial
		for(int i=0;i<data_size;i++) Serial.write(data[i]);
		Serial.end(); // clear Serial config
	}
	sleep(0); // Go to Sleep mode
	return 1;
}

// READ methods
// Read LIN traffic and then proces it.
int lin_stack::setSerial(){ // Only needed when receiving signals
	if(ch==1){ // For LIN1 (Channel 1)
		Serial.begin(10417); // Configure Serial
		PORTD|= _BV(PD4); // We need software Pull-Up because there is no hardware Pull-Up resistor
	} 
}

int lin_stack::read(byte data[], byte data_size){
	byte rec[data_size+3];
	if(ch==1){ // For LIN1 or Serial
		if(Serial.read() != -1){ // Check if there is an event on LIN bus
			Serial.readBytes(rec,data_size+3);
			if((validateParity(rec[1]))&(validateChecksum(rec,data_size+3))){
				for(int j=0;j<data_size;j++){
				data[j] = rec[j+2];
				}
				return 1;
			}else{
				return -1;
			}	
		}
	}
	return 0;
}

int lin_stack::readStream(byte data[],byte data_size){
	byte rec[data_size];
	if(ch==1){ // For LIN1 or Serial
		if(Serial.read() != -1){ // Check if there is an event on LIN bus
			Serial.readBytes(rec,data_size);
			for(int j=0;j<data_size;j++){
				data[j] = rec[j];
			}
			return 1;
		}
	}
	return 0;
}


// PRIVATE METHODS
int lin_stack::serial_pause(int no_bits){
	// Calculate delay needed for 13 bits, depends on bound rate
	unsigned int del = period*no_bits; // delay for number of bits (no-bits) in microseconds, depends on period
	if(ch=1){
		DDRD = (1<<PD3);
		PORTD&= ~_BV(PD3); // clear PD3
		delayMicroseconds(del); // delay
		PORTD|= _BV(PD3); // set pin high
		//PIOD->PIO_PDR = PIO_PD3; // clear configuration for PIO, needs to be done because Serial wont work with it
	}
	return 1;
}

int lin_stack::sleep(byte sleep_state){
	if(sleep_state==1){ // Go to Normal mode
		if(ch==1) PORTB|= _BV(PB1); // Set PB1, high state, normal mode
		
	}else if(sleep_state==0){ // Go to Sleep mode
		if(ch==1) PORTB&= ~_BV(PB1); // Clear PB1, low state, sleep mode
		
	}
	delayMicroseconds(20); // According to TJA1021 datasheet this is needed for propper working
	return 1;
}

int lin_stack::sleep_config(byte serial_No){
	if(serial_No==1){ // When using LIN1 channel - usign Serial and pin PB4 for Sleep
		DDRB = (1<<PB1); // enable PIO register on pin PB1
		//PIOB->PIO_OER = PIO_PB1; // set PB1 as output
		PORTB&= ~_BV(PB1); // disable pull-up
		ch=1; // saved as private variable, used for determening Serial port
	}
	return 1;
}

boolean lin_stack::validateParity(byte ident) {
	if(ident == identByte)
		return true;
	else
		return false;
}

boolean lin_stack::validateChecksum(unsigned char data[], byte data_size){
	byte checksum = data[data_size-1];
	byte suma = 0;
	for(int i=2;i<data_size-1;i++) suma = suma + data[i];
	byte v_checksum = 255 - suma - 1;
	if(checksum==v_checksum)
		return true;
	else
		return false;
}

lin stack library

hey
i hope u doing well, actually i am working on a lin communication protocol for 28-pin lin broad and mcp2021 (microchip).i have to establish the lin protocol using this component and i found the lin stack library and i do not know how to use there is no documentation and no source code .
i will be so thankful if u help me .

CRC brocken

This CRC right

unsigned char lin_calculate_checksum (lin_frame_t response, lin_checksum_style_t style) {
  unsigned int checksum = 0;
  if (response.length > LIN_MAXIMUM_RESPONSE_LENGTH) { response.length = LIN_MAXIMUM_RESPONSE_LENGTH; }
  for (int byte_index = 0; byte_index < response.length; byte_index++) {
    checksum += response.data[byte_index];
    if (checksum >= 256) { checksum -= 255; }
  }
  if (style == LIN_CHECKSUM_ENHANCED) {
    checksum += response.id;
    if (checksum >= 256) { checksum -= 255; }
  }
  return (~(unsigned char)checksum);
}

LIN TX on Channel 1 not working?

From @rocketjosh on August 10, 2017 15:13

It appears as though LIN1.write( may not be working? LIN2.write( does appear to work. Tested using this example.

RX on both channels does work as verified using this example.

Copied from original issue: macchina/m2-libraries#3

= instead ==

There are errors ?
= instead ==

if(ch=2){
	PIOA->PIO_PER = PIO_PA13; // enable PIO register
	PIOA->PIO_OER = PIO_PA13; // enable PA13 as output
	PIOA->PIO_CODR = PIO_PA13; // clear PA13
	delayMicroseconds(del); // delay
	PIOA->PIO_SODR = PIO_PA13; // set pin high
	PIOA->PIO_PDR = PIO_PA13; // clear configuration for PIO, needs to be done because Serial wont work with it
}else if(ch=1){
	PIOA->PIO_PER = PIO_PA11; // enable PIO register
	PIOA->PIO_OER = PIO_PA11; // enable PA11 as output
	PIOA->PIO_CODR = PIO_PA11; // clear PA11
	delayMicroseconds(del); // delay
	PIOA->PIO_SODR = PIO_PA11; // set pin high
	PIOA->PIO_PDR = PIO_PA11; // clear configuration for PIO, needs to be done because Serial wont work with it
}

Transfer to Macchina organization?

Hi Collin,

I'm working on reorganizing Macchina's libraries on GitHub. This will include splitting the LIN library to its own repository. I notice you have already done this. Since users have filled issues against your repository I am wondering if you would allow this repository to be transferred to the macchina organization? Once that is done, you would be able to fork it to have your own copy again.

Thanks!
Adam

/cc @rocketjosh

Error compiling for AtMega32u4

Sorry to post here but I'm not sure where else to ask for help.
I've installed Arduino IDE 1.6.9 and have an AtMega32u4 connected to a TJA1021 but I'm getting too many compile errors to run the Sniffer sketch.

SerialUSB.begin(9600); // Configure Serial for Serial Monitor ***Should SerialUSB be just Serial?
Sniffer:34: error: 'SerialUSB' was not declared in this scope

I read that for the 32u4 Serial is used on the USB monitor & Serial1 is for the second serial port that needs to talk to the TJA1021.

Sorry again,
[email protected]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.