Hi I am making a project to conect 1 master arduino UNO to 3 slave arduino UNOs using MCP2003 chips to send data using LIN comunication, I have sucsesfully set the comunication up to send a simple signal and response between the master and slaves with LEDs to signal the when the data is recieved at both the slave and the master, every time i press the relivent button the correct LEDs flash.
However i want to send data that is gathered from sensors on each of the slave arduinos alongside the signal data, when i try to do this the signal and response only work the first time I press the button and does not work on subsiquent presses.
I want to read data from a nine axis motion sensor shield which i have got working seperatly from the main project it is the data from this i want to send to the master along with the identification code.
See below for wiering diagram and code for master and 1st slave and 9 axis motion sensor
master code
volatile const int Rx = 2; // Rx looped from Rx pin (Uno/Nano pin 0)
const int ledPin = 13;
const int CS = 4; // HIGH enables MCP2003 chip
volatile boolean clearToSend = true; // can be used to flag that you shouldn't try to send anything as the LIN bus is busy
const int buttonPin = 7;
const int button2Pin = 8;
const int button3Pin = 9;
int buttonState;
int button2State;
int button3State;
int lastButtonState = LOW;
int lastButton2State = LOW;
int lastButton3State = LOW;
bool responseReceived = false; // Flag to track if the response has been receved
bool response2Received = false; // Flag to track if the response has been receved
bool response3Received = false; // Flag to track if the response has been receved
char inByte[3];
const int led2Pin = 10;
const int led3Pin = 11;
const int led4Pin = 12;
long lastDebounceTime = 0;
long lastDebounceTime2 = 0;
long lastDebounceTime3 = 0;
long debounceDelay = 50;
void busClear() {
#define START_TIMER1 TCCR1B |= (1 << CS10)|(1 << CS12) // //Set CS10 and CS12 bits for 1024 prescaler:
#define STOP_TIMER1 TCCR1B &= 0B11111000
// initialize Timer1
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
// set compare match register to desired timer count:
OCR1A = 157; // Set timer to fire CTC interrupt after approx 10ms
// turn on CTC mode:
TCCR1B |= (1 << WGM12);
// enable timer compare interrupt:
TIMSK1 |= (1 << OCIE1A);
attachInterrupt(0, rxChange, CHANGE); // run rxChange every time serial Rx changes state
}
//========================
void rxChange() {
if (PIND & (1<<PIND1) && (PIND & (1<<PIND0))){ // check Tx high and Rx high
START_TIMER1;
}
else if (PIND & (1<<PIND1) && (!(PIND & (1<<PIND0)))){ // check Tx high and Rx low
clearToSend = false;
digitalWrite(ledPin, HIGH);
STOP_TIMER1;
}
}
//========================
ISR(TIMER1_COMPA_vect) // runs if timer runs for 10ms
{
clearToSend = true;
digitalWrite(ledPin, LOW);
STOP_TIMER1;
}
void setup()
{
Serial.begin(9600);
pinMode (CS, OUTPUT); // initialize pin.
pinMode(Rx, INPUT_PULLUP); // pin looped from Rx pin 0
digitalWrite (CS, HIGH); // write pin high.
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
digitalWrite(led2Pin, HIGH);
digitalWrite(led3Pin, HIGH);
digitalWrite(led4Pin, HIGH);
delay (500);
digitalWrite(ledPin, LOW);
digitalWrite(led2Pin, LOW);
digitalWrite(led3Pin, LOW);
digitalWrite(led4Pin, LOW);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(button2Pin, INPUT_PULLUP);
pinMode(button3Pin, INPUT_PULLUP);
busClear();
}
void loop(){
// add your main loop code in here
int reading = digitalRead(buttonPin);
if (reading != lastButtonState){
lastDebounceTime = millis();
}
if ((millis()-lastDebounceTime) > debounceDelay){
if (reading != buttonState){
buttonState = reading;
if (buttonState == LOW){
byte msg[] = {
0x41, 0x42, 0x43
};
for (int i = 0; i < sizeof msg; i++){
Serial.write(msg[i]);
}
}
}
}
lastButtonState = reading;
//#########################################
int reading2 = digitalRead(button2Pin);
if (reading2 != lastButton2State){
lastDebounceTime2 = millis();
}
if ((millis()-lastDebounceTime2) > debounceDelay){
if (reading2 != button2State){
button2State = reading2;
if (button2State == LOW){
byte msg[] = {
0x47, 0x48, 0x49
};
for (int i = 0; i < sizeof msg; i++){
Serial.write(msg[i]);
}
}
}
}
lastButton2State = reading2;
//#########################################
int reading3 = digitalRead(button3Pin);
if (reading3 != lastButton3State){
lastDebounceTime3 = millis();
}
if ((millis()-lastDebounceTime3) > debounceDelay){
if (reading3 != button3State){
button3State = reading3;
if (button3State == LOW){
byte msg[] = {
0x53, 0x54, 0x55
};
for (int i = 0; i < sizeof msg; i++){
Serial.write(msg[i]);
}
}
}
}
lastButton3State = reading3;
if(Serial.available() == 3){// checks the response
for (int i = 0; i < 3; i++){
inByte[i] = Serial.read(); // reads the response signal
}
if(inByte[0] == 0x44 && inByte[1] == 0x45 && inByte[2] == 0x46){// compares the input signal to see if relivent
if (!responseReceived) { // Check if the response has not been recieved yet
digitalWrite(led2Pin, HIGH);// lights 1st led
//digitalWrite(led3Pin, HIGH); // lights 2nd led
}
responseReceived = true; // Set the flag to indicate that the response has been receved
delay(100);
digitalWrite(led2Pin, LOW);// turn off 1st led
responseReceived = false; // Set the flag to indicate that the next response can be recieved
busClear();
}else {
//###################################################
if(inByte[0] == 0x50 && inByte[1] == 0x51 && inByte[2] == 0x52){// compares the input signal to see if relivent
if (!response2Received) { // Check if the response has not been recieved yet
digitalWrite(led3Pin, HIGH);// lights 1st led
//digitalWrite(led3Pin, HIGH); // lights 2nd led
}
response2Received = true; // Set the flag to indicate that the response has been receved
delay(100);
digitalWrite(led3Pin, LOW);// turn off 1st led
response2Received = false; // Set the flag to indicate that the next response can be recieved
busClear();
}else {
//###################################################
if(inByte[0] == 0x56 && inByte[1] == 0x57 && inByte[2] == 0x58){// compares the input signal to see if relivent
if (!response3Received) { // Check if the response has not been recieved yet
digitalWrite(led4Pin, HIGH);// lights 1st led
//digitalWrite(led3Pin, HIGH); // lights 2nd led
}
response3Received = true; // Set the flag to indicate that the response has been receved
delay(100);
digitalWrite(led4Pin, LOW);// turn off 1st led
response3Received = false; // Set the flag to indicate that the next response can be recieved
busClear();
}else{
// Reset the responseReceived flag if the condition is not met
responseReceived = false;
response2Received = false;
response3Received = false;
digitalWrite(led2Pin, LOW);
digitalWrite(led3Pin, LOW);
digitalWrite(led4Pin, LOW);
}
}}}}
Slave code
#include <SoftwareSerial.h>
volatile const int Rx = 3; // Rx looped from Rx pin (Uno/Nano pin 0)
const int ledPin = 13;
const int CS = 4; // HIGH enables MCP2003 chip
volatile boolean clearToSend = false; // can be used to flag that you shouldn't try to send anything as the LIN bus is busy
char inByte[3];
const int led2Pin = 8;
const int led3Pin = 9;
bool responseSent = false; // Flag to track if the response has been sent
SoftwareSerial debugSerial(10, 11); // RX, TX
//#########################################################################
void busClear()
{
#define START_TIMER1 TCCR1B |= (1 << CS10)|(1 << CS12) // //Set CS10 and CS12 bits for 1024 prescaler:
#define STOP_TIMER1 TCCR1B &= 0B11111000
// initialize Timer1
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
// set compare match register to desired timer count:
OCR1A = 157; // Set timer to fire CTC interrupt after approx 10ms
// turn on CTC mode:
TCCR1B |= (1 << WGM12);
// enable timer compare interrupt:
TIMSK1 |= (1 << OCIE1A);
attachInterrupt(0, rxChange, CHANGE); // run rxChange every time serial Rx changes state
}
//###############################################
void rxChange() {
if (PIND & (1<<PIND1) && (PIND & (1<<PIND0))){ // check Tx high and Rx high
START_TIMER1;
}
else if (PIND & (1<<PIND1) && (!(PIND & (1<<PIND0)))){ // check Tx high and Rx low
clearToSend = false;
digitalWrite(ledPin, HIGH);
STOP_TIMER1;
}
}
ISR(TIMER1_COMPA_vect) // runs if timer runs for 10ms
{
clearToSend = true;
digitalWrite(ledPin, LOW);
STOP_TIMER1;
}
//##############################################################
void setup()
{
Serial.begin(9600);
debugSerial.begin(9600);
pinMode (CS, OUTPUT); // initialize pin.
pinMode(Rx, INPUT_PULLUP); // pin looped from Rx pin 0
digitalWrite (CS, HIGH); // write pin high.
pinMode(ledPin, OUTPUT);
pinMode(led2Pin, OUTPUT);
pinMode(led3Pin, OUTPUT);
digitalWrite(led2Pin, HIGH);
digitalWrite(led3Pin, HIGH);
delay(500);
digitalWrite(ledPin, LOW);
digitalWrite(led2Pin, LOW);
digitalWrite(led3Pin, LOW);
busClear();
}
void loop(){
// add your main loop code in here
if(Serial.available() == 3){// checks the input
for (int i = 0; i < 3; i++){
inByte[i] = Serial.read(); // reads the input signal
}
if(inByte[0] == 0x41 && inByte[1] == 0x42 && inByte[2] == 0x43){// compares the input signal to see if relivent
if (!responseSent) { // Check if the response has not been sent yet
digitalWrite(led2Pin, HIGH);// lights 1st led
digitalWrite(led3Pin, HIGH); // lights 2nd led
debugSerial.print(0x47); // sends an output to serial debudder (seperate pin output)
byte msg[] = {
0x44, 0x45, 0x46
};
for (int i = 0; i < sizeof msg; i++){
Serial.write(msg[i]);
}
responseSent = true; // Set the flag to indicate that the response has been sent
delay(500);
digitalWrite(led2Pin, LOW);// turns off 1st led
digitalWrite(led3Pin, LOW); // turns off 2nd led
responseSent = false; // Set the flag to indicate that the slave is ready to send next response
}
else {
// Reset the responseSent flag if the condition is not met
responseSent = false;
digitalWrite(led2Pin, LOW);
digitalWrite(led3Pin, LOW);
}
}
}
}
9 axis motion sensor code
#include "Arduino_NineAxesMotion.h" //Contains the bridge code between the API and the Arduino Environment
#include <Wire.h>
NineAxesMotion mySensor; //Object that for the sensor
unsigned long lastStreamTime = 0; //To store the last streamed time stamp
const int streamPeriod = 20; //To stream at 50Hz without using additional timers (time period(ms) =1000/frequency(Hz))
void setup() //This code is executed once
{
//Peripheral Initialization
Serial.begin(9600); //Initialize the Serial Port to view information on the Serial Monitor
Wire.begin(); //Initialize I2C communication to the let the library communicate with the sensor.
//Sensor Initialization
mySensor.initSensor(); //The I2C Address can be changed here inside this function in the library
mySensor.setOperationMode(OPERATION_MODE_NDOF); //Can be configured to other operation modes as desired
mySensor.setUpdateMode(MANUAL); //The default is AUTO. Changing to MANUAL requires calling the relevant update functions prior to calling the read functions
//Setting to MANUAL requires fewer reads to the sensor
}
void loop() //This code is looped forever
{
if ((millis() - lastStreamTime) >= streamPeriod)
{
lastStreamTime = millis();
mySensor.updateEuler(); //Update the Euler data into the structure of the object
mySensor.updateCalibStatus(); //Update the Calibration Status
Thankyou for any help you could provide