Hi Robin,
Do you know the longest possible message?
I don't know the theoretical maximum length, but the longest I've ever seen is 37 hex bytes long:
D0 23 3F A0 00 40 FE FE 00 00 00 00 08 AA 00 00 00 00 00 54 00 00 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 23
Why not just receive all messages (regardless of length) and just ignore some of them?
I guess that's ultimately what I'm trying to do - just not very well.

I've figured out SPI, Rotary encoders, and all sorts of other good stuff, but simply reading in a string of serial data appears to be beyond me. Unfortunately, the whole project is dead in the water until I can figure it out.
How often are messages transmitted?
It varies, but there's quite a lot of traffic. Here's a small section from an IBUS log file with time stamps.
2014-04-14 17:07:55.015: D0 07 BF 5C FF FF FF 00 CB
2014-04-14 17:07:55.015: ! LCM --> GLO : Light dimmer, Data="FF FF FF 00"
2014-04-14 17:07:58.500: 68 03 18 01 72
2014-04-14 17:07:58.500: ! RAD --> CDC : Device status request
2014-04-14 17:07:58.515: 18 04 FF 02 00 E1
2014-04-14 17:07:58.515: ! CDC --> LOC : Device status ready,
2014-04-14 17:07:58.531: 18 0A 68 39 00 02 00 3F 00 07 01 78
2014-04-14 17:07:58.531: ! CDC --> RAD : CD_status, Stop Request=Pause CD=7 Track=1 CDs_Loaded=P1,P2,P3,P4,P5,P6
2014-04-14 17:08:04.468: E8 05 D0 59 50 00 34
2014-04-14 17:08:04.468: ! RLS --> LCM : Light control status, Control: Turn_lights_off Sensor_OK Level_Signal_invalid Reason:Data="50 00"
2014-04-14 17:08:08.031: 68 03 18 01 72
2014-04-14 17:08:08.031: ! RAD --> CDC : Device status request
2014-04-14 17:08:08.046: 18 04 FF 02 00 E1
2014-04-14 17:08:08.046: ! CDC --> LOC : Device status ready,
2014-04-14 17:08:08.046: 18 0A 68 39 00 02 00 3F 00 07 01 78
2014-04-14 17:08:08.046: ! CDC --> RAD : CD_status, Stop Request=Pause CD=7 Track=1 CDs_Loaded=P1,P2,P3,P4,P5,P6
2014-04-14 17:08:10.000: D0 07 BF 5C FF FF FF 00 CB
2014-04-14 17:08:10.000: ! LCM --> GLO : Light dimmer, Data="FF FF FF 00"
2014-04-14 17:08:14.484: E8 05 D0 59 50 00 34
2014-04-14 17:08:14.484: ! RLS --> LCM : Light control status, Control: Turn_lights_off Sensor_OK Level_Signal_invalid Reason:Data="50 00"
2014-04-14 17:08:17.546: 68 03 18 01 72
2014-04-14 17:08:17.546: ! RAD --> CDC : Device status request
2014-04-14 17:08:17.562: 18 04 FF 02 00 E1
2014-04-14 17:08:17.562: ! CDC --> LOC : Device status ready,
2014-04-14 17:08:17.593: 18 0A 68 39 00 02 00 3F 00 07 01 78
2014-04-14 17:08:17.593: ! CDC --> RAD : CD_status, Stop Request=Pause CD=7 Track=1 CDs_Loaded=P1,P2,P3,P4,P5,P6
2014-04-14 17:08:18.531: 68 05 18 38 03 00 4E
2014-04-14 17:08:18.531: ! RAD --> CDC : CD_control, Play
It's a good idea to write a short sketch that just focuses on the problem at hand. Then you can post the whole sketch here and get useful advice without lazy me having to wade through lots of stuff that you know how to do.
Even if you won't/can't write a short sketch post a complete sketch here (not just snippets) so we can see all of it.
Try this for size. It's the smallest I could make it while still remaining functional.
Here's some sample IBUS messages that it's happy with.
50 04 68 32 11 1F
50 04 68 32 10 1E
These are ignored, but the software handles it fine.
50 04 68 3B 02 05
50 04 68 3B 22 25
These will upset things.
44 05 BF 74 04 00 8E
44 05 BF 74 00 FF 75
C8 0F 80 23 42 32 42 6C 75 65 20 52 6F 6F 6D 20 15
D0 23 3F A0 00 40 FE FE 00 00 00 00 08 AA 00 00 00 00 00 54 00 00 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 23
#include <Wire.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(7, 8); // 7 is Rx, 8 is Tx
byte KEY_IN [7] = { 0x44 , 0x05 , 0xBF , 0x74 , 0x04 , 0x00 , 0x8E }; // Ignition key in
byte KEY_OUT [7] = { 0x44 , 0x05 , 0xBF , 0x74 , 0x00 , 0xFF , 0x75 }; // Ignition key out
byte VOL_UP [6] = { 0x50 , 0x04 , 0x68 , 0x32, 0x11 , 0x1F }; // Steering wheel Volume Up
byte VOL_DOWN [6] = { 0x50 , 0x04 , 0x68 , 0x32, 0x10 , 0x1E }; // Steering wheel Volume Down
byte LENGTH;
byte checksumBYTE;
byte IBUSbyte[20];
boolean byteSTATE = false;
int IBUSevent = 0; //boolean value set 1 if IBUS message detected
int EventID = 0; // Event number (for case select)
int CS_LWAKE = 4;
void setup()
{
Serial.begin(9600, SERIAL_8E1);
mySerial.begin(115200);
mySerial.println("--Digital Dock Volume Controller--");
pinMode (CS_LWAKE, OUTPUT); // initialize pin.
digitalWrite (CS_LWAKE, HIGH); // write pin high.
}
void loop(){
if (IBUSevent == 1){
mySerial.println();
switch (EventID){
case 100:
mySerial.println("UNKNOWN KEY");
break;
case 1:
mySerial.println("Key IN");
break;
case 2:
mySerial.println("Key OUT");
break;
case 3:
mySerial.println("VOLup");
break;
case 4:
mySerial.println("VOLdown");
break;
}
IBUSevent = 0;
}
} // END OF MAIN LOOP
void serialEvent() {
if (Serial.available()>=6) { // there are 6 or more bytes in the serial buffer to read
IBUSbyte[0] = Serial.read(); // read in source byte and store in IBUSbyte location 0
IBUSbyte[1] = Serial.read(); // read in length byte and store in IBUSbyte location 1
LENGTH = IBUSbyte[1];
if (IBUSbyte[0] == 0x50 || IBUSbyte[0] == 0x44 && LENGTH <=7){ // ignore messages from some modules
for (int i = 2; i <= LENGTH+2; i++) {// read in rest of message.
IBUSbyte[i] = Serial.read();
}
chkSUM(); // go off and see if checksum matches
}
else
{
debug();
mySerial.println("No Match ");
}
}
} // End of IBUS read routine.
void compare(){
EventID = 100;
if (byteSTATE == 1) {
if(memcmp(IBUSbyte, KEY_IN, 7) == 0 ) {EventID = 1;}
if(memcmp(IBUSbyte, KEY_OUT, 7) == 0 ){EventID = 2;}
if(memcmp(IBUSbyte, VOL_UP, 6) == 0 ){EventID = 3;}
if(memcmp(IBUSbyte, VOL_DOWN, 6) == 0 ){EventID = 4;}
IBUSevent=1;
}
else
{
IBUSevent=0;
}
}
void chkSUM() {
checksumBYTE = 0;
byteSTATE = 0;
for (int i = 0; i < LENGTH+1; i++){ // read in stored bytes and calculate XOR
checksumBYTE ^= IBUSbyte[i];}
if (IBUSbyte[LENGTH + 1] == checksumBYTE){ // see if calculated XOR matches received XOR
byteSTATE = 1;}
else if (IBUSbyte[LENGTH + 1] != checksumBYTE){
byteSTATE = 0;}
if (byteSTATE == 1) // if it matches, go and compare the received byte with the ones stored above
{
compare();
}
else if (byteSTATE == 0) // if it doesn't match, run debug() and display some diagnostic info
{
debug();
checksumBYTE = 0;
}
}
void debug(){
mySerial.print("IBUSbyte = ");
for (int i = 0; i <= LENGTH+1; i++) {
mySerial.print(IBUSbyte[i], HEX);
mySerial.print(" ");
}
mySerial.println();
mySerial.print("Source= ");
mySerial.println(IBUSbyte[0], HEX);
mySerial.print("Length= ");
mySerial.println(IBUSbyte[1], HEX);
mySerial.print("IBUS checksum = ");
mySerial.println(checksumBYTE, HEX);
if (IBUSbyte[LENGTH + 1] == checksumBYTE) {
mySerial.println("IBUS checksum matches "); }
else if (IBUSbyte[LENGTH + 1] != checksumBYTE){
mySerial.println("IBUS checksum bad "); }
mySerial.println();
checksumBYTE = 0;
}