Hi guys,
I'm working on a LIN bus network and I am using the MCP2003 LIN bus chip form Microchip.
I have read a couple of forums and then started working on the prototypes using a breadbord. I have tried a lot of things but can't get any communication.
I'm using the MCP2003 chip but have learned that you can write to it using the Software Serial communication (LIN-BUS, MCP2004, Serial write does not work - Microcontrollers - Arduino Forum).
But the SoftwareSerial does not use some kind of protocol so after some searching i found the RS485 library from Nick Gamon (Gammon Forum : Electronics : Microprocessors : RS485 communications).
I tried to use this library to make the MCP2003 send data over the LIN bus. Every time i run the sketch i get the "Error!" and the LED on the master is lit.
I'm not sure what the problem is because i'm kind of a newbie to this. Help is much appreciated!
The schematics are attached.
Code for the Master:
#include "RS485_protocol.h"
#include <SoftwareSerial.h>
const byte ENABLE_PIN = 4;
const byte LED_PIN = 13;
int myAdr = 0x00; // Adres of this slave (0x00 = master)
byte old_level = 0;
char serString;
SoftwareSerial LIN (2, 3); // receive pin, transmit pin
// callback routines
void fWrite (const byte what)
{
LIN.write(what);
}
int fAvailable ()
{
return LIN.available ();
}
int fRead ()
{
return LIN.read ();
}
void setup()
{
Serial.begin(9600);
LIN.begin (19200);
pinMode (ENABLE_PIN, OUTPUT); // driver output enable
pinMode (LED_PIN, OUTPUT); // built-in LED
Serial.println("LIN Master test");
} // end of setup
void loop()
{
int i = 0;
// read potentiometer
byte level = analogRead (0) / 4;
// no change? forget it
if (level == old_level)
return;
// assemble message
byte msg [] = {
myAdr, // My adres
1, // Adres receiver
2, // turn light on
level // to what level
};
Serial.print("Sending: ");
for (i==0 ; i< sizeof(msg) ; i++){
Serial.print(msg[i]);
Serial.print(", ");
}
Serial.print(".");
// send to slave
digitalWrite (ENABLE_PIN, HIGH); // enable sending
sendMsg (fWrite, msg, sizeof msg);
Serial.println("Sent");
digitalWrite (ENABLE_PIN, LOW); // disable sending
// receive response
byte buf [10];
byte received = recvMsg (fAvailable, fRead, buf, sizeof buf);
if (received == 0){
digitalWrite (LED_PIN, HIGH); // turn on LED if error
Serial.println("Error!");
}
// only send once per successful change
if (received){
digitalWrite(LED_PIN, LOW);
Serial.print("Received: ");
for (i==0; i<sizeof(buf); i++){
Serial.print(buf[i]);
Serial.print(", ");
}
old_level = level;
}
else {
Serial.println("Receive failed");
}
} // end of loop
Code for the slave:
#include <SoftwareSerial.h>
#include "RS485_protocol.h"
const byte ENABLE_PIN = 4;
const int myAdr = 0x01; // Adres of this slave (master = 0x00)
SoftwareSerial LIN (2, 3); // receive pin, transmit pin
void fWrite (const byte what)
{
LIN.write (what);
}
int fAvailable ()
{
return LIN.available ();
}
int fRead ()
{
return LIN.read ();
}
void setup()
{
Serial.begin(9600);
LIN.begin (19200);
pinMode (ENABLE_PIN, OUTPUT); // driver output enable
Serial.println("LIN Slave test");
}
void loop()
{
byte buf [10];
int i = 0;
byte received = recvMsg (fAvailable, fRead, buf, sizeof (buf));
if (received){
Serial.print("Received: ");
for (i==0; i<sizeof(buf); i++){
Serial.print(buf[i]);
Serial.print(", ");
}
Serial.println(".");
if (buf [0] != 0)
return; // not sent from master
if (buf [1] != 1)
return; // not my device
if (buf [2] != 2)
return; // unknown command
byte msg [] = {
myAdr, // my
buf[0], // adres sender (master)
0xFF, // Message received correctly (ACK)
};
Serial.print("Sending: ");
for (i==0 ; i< sizeof(msg) ; i++){
Serial.print(msg[i]);
Serial.print(", ");
}
Serial.println(".");
delay (1); // give the master a moment to prepare to receive
digitalWrite (ENABLE_PIN, HIGH); // enable sending
sendMsg (fWrite, msg, sizeof msg);
digitalWrite (ENABLE_PIN, LOW); // disable sending
analogWrite (11, buf [2]); // set light level
} // end if something received
} // end of loop