virtualdave
Well-known member
I need some advice / pointers in dealing with interrupts when a particular value comes in one of the serial ports.
Quick overview: I have lots of sensor data coming in via Serial1. ~100 bytes @ 921600 baud @100Hz. Takes about 1.3ms to read that data. Then LOTS of data processing to produce some magic numbers. On serial2 I am listening for a message from another board. It's 9-bit data (yeah Paul & Nick for the 9-bit serial option) via rs485. When I get a message addressed for me, I am to report some those magic numbers immediately. Problem is this could be delayed by up to 1.3ms if I am tied up reading the data on Serial1.
Question: What I need to have my sketch do is when I receive 0x0109 on serial2, stop everything, listen for the remaining 3 ints to check what I am being asked to do, pass along 6 bytes, then return to what I was doing. I'm assuming I need to edit serial2.c (or maybe serial1.c to stop it?) to make this happen (I've already added some extra code to serial2.c to handle the enable pin for rs485, so I'm not afraid to make these edits...now . I just know very little about interrupts (or if this is even the right path?) and would love some gentle nudges on how I might go about tackling this.
Here's a whittled down sketch that shows how things are set-up in my main sketch.
Thanks,
David
Quick overview: I have lots of sensor data coming in via Serial1. ~100 bytes @ 921600 baud @100Hz. Takes about 1.3ms to read that data. Then LOTS of data processing to produce some magic numbers. On serial2 I am listening for a message from another board. It's 9-bit data (yeah Paul & Nick for the 9-bit serial option) via rs485. When I get a message addressed for me, I am to report some those magic numbers immediately. Problem is this could be delayed by up to 1.3ms if I am tied up reading the data on Serial1.
Question: What I need to have my sketch do is when I receive 0x0109 on serial2, stop everything, listen for the remaining 3 ints to check what I am being asked to do, pass along 6 bytes, then return to what I was doing. I'm assuming I need to edit serial2.c (or maybe serial1.c to stop it?) to make this happen (I've already added some extra code to serial2.c to handle the enable pin for rs485, so I'm not afraid to make these edits...now . I just know very little about interrupts (or if this is even the right path?) and would love some gentle nudges on how I might go about tackling this.
Here's a whittled down sketch that shows how things are set-up in my main sketch.
Thanks,
David
Code:
byte gesture = 0;
byte vnavIn;
const int vbuff_size = 120;
byte vbuff[vbuff_size];
byte vbuff_idx = 0;
// RS-485 Transmit variables
byte gTxBuffer[8];
// RS-485 Receive variables
int gRxByteCount = 0;
int gRxBuffer[16];
//*****************************************************************************
void setup() {
Serial2.begin(38400, SERIAL_9N1);
Serial.begin(38400);
}
//*****************************************************************************
void loop() {
byte b;
int c;
// =========== Task 1 ==========
// Service the serial1 sensor data
while (Serial1.available() > 0) { // mail call
vnavIn = Serial1.read();
vbuff[vbuff_idx] = vnavIn;
if (vnavIn == 10) { // = line feed = end of packet from vn100
vnavIn = 0;
doSomeMagic();
vbuff_idx = 0; // reset vn100 buffer index and get ready to receive next packet
}
else { // keep filling the buffer, more data coming in
vbuff_idx++;
}
} // end vn100 check
// =========== Task 2 ==========
// Service incoming RS-485 serial data
while (Serial2.available()) {
// Read a 9-bit byte
c = Serial2.read();
// If we're waiting for the start of a new messaqe
// then the first 9-bit byte must be 0x0109
if (gRxByteCount == 0) {
if (c == 0x109) {
gRxBuffer[0] = c;
gRxByteCount++;
}
}
else { // keep filling the buffer, more data coming in
gRxBuffer[gRxByteCount++] = c;
// If the received bytecount is 4, then we have an
// entire message. We should check the values to
// validate, but let's just assume it's correct.
if (gRxByteCount >= 3) {
// reset the byte count
gRxByteCount = 0;
// Pause to let RS-485 settle, then send the response
// with the current gesture number
delayMicroseconds(10);
gTxBuffer[0] = gesture;
gTxBuffer[1] = 0;
gTxBuffer[2] = 0;
gTxBuffer[3] = 0x0055;
Serial2.write(gTxBuffer, 4);
} // if (gRxByteCount >= 4)
} // if (gRxByteCount != 0)
} // while (Serial2.available())
}
void doSomeMagic() {
// just a bucket for the actual data processing
gesture++;
if (gesture > 99) {
gesture = 0;
}
}
Last edited: