PLUS+1 Hardware > Controllers

Read multiple Can messages same ID

<< < (2/3) > >>

Matt_Eng:
Hi,
It can be a little tricky initially to deal with a multi-message data array in GUIDE, I know I struggled with it when I first started working in GUIDE.
There are a few different ways you can go about implementing the reception, but I'll describe the most straight forward method, based on your latest message.

I'll first describe how Protected works, as it is key to getting this working. Imagine you have an list of messages that was received each loop.
When Protected is False, it will only grab the newest message that is available, so if 3 messages were received that match the CAN receiver the oldest 2 are discarded and only the latest is used.
This is useful for receiving something like a joystick message, where the latest data is preferred.
When Protected is True, it will pop off the first message it finds and return that. Then if you have an additional CAN receiver with the same setup and protected True, that 2nd receiver will get the second message that was received.

So by having multiple receivers with Protected True, you can see all the messages that were received over a loop.
The next part is to choose to have a Receive CAN with Filter for every sequence byte, as shown in my example picture. This allows us to apply a data mask and further limit which message is received. This is a good option if the amount of data being transmitted is less than 10 messages.
More Advanced: If it is more than 10, then I just use 3-5 Receive CAN with ID Filter and use additional logic to place the messages in the correct spot of the combined array.

I hope this helps, Matt_Eng

F.M.Elettromeccanica:
Matt_Ing, you are the Goat. that's is working perfectly as i want.
I'm making an NMEA2000 GNSS parsing,i will share the project once tested.

FluidPowerTom:
Matt, that's a good tip which sounds like a possible way to do this in GUIDE graphical.

F.M., should the output arrays be 80 elements instead of 8?  In that case I'd do some index incrementing perhaps like the below when a new message is received with the same Data[0].  I'd recommend using the Rx output from the CANRx block which will turn on for one scan whenever a new message is received:



FUNCTION_BLOCK GGA_Decoder
VAR_INPUT
  Data : ARRAY[0..7] OF USINT;
  Length : USINT;
  CAN_Rx: BOOL;
END_VAR
VAR_OUTPUT
  Arr0 : ARRAY[0..79] OF USINT := [0, 0, 0, 0, 0, 0, 0, 0];
  Arr1 : ARRAY[0..79] OF USINT := [0, 0, 0, 0, 0, 0, 0, 0];
  Arr2 : ARRAY[0..79] OF USINT := [0, 0, 0, 0, 0, 0, 0, 0];
  Arr3 : ARRAY[0..79] OF USINT := [0, 0, 0, 0, 0, 0, 0, 0];
  Arr4 : ARRAY[0..79] OF USINT := [0, 0, 0, 0, 0, 0, 0, 0];
  Arr5 : ARRAY[0..79] OF USINT := [0, 0, 0, 0, 0, 0, 0, 0];
  Arr6 : ARRAY[0..79] OF USINT := [0, 0, 0, 0, 0, 0, 0, 0];
END_VAR
VAR
  Index : USINT;
  Index_Adder: USINT;
END_VAR


//Increment indexer
IF CAN_Rx AND Index=Data[0] THEN
    Index_Adder:=Index_Adder+8;
ELSIF CAN_Rx AND Index<>Data[0] THEN
    Index_Adder:=0;
END_IF

// Extract Identifier
Index := Data[0];

FOR i = 0 TO 7 DO
    Arr0[i+Index_Adder]:=Data;
END_FOR

I think the above will save 80 elements with each message data in sequence in an 80 element array.  I haven't tested this of course.  You'll need to implement some other logic to fill in the other arrays with different byte 0 values, so some logic needs to be added for that


CASE Index OF
  160, 192, 32, 0, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240:
    Arr0 := Data;
  161, 193, 33, 1, 65, 81, 97, 113, 129, 145, 161, 177, 193, 209, 225, 241:
    Arr1 := Data;
  162, 194, 34, 2, 66, 82, 98, 114, 130, 146, 162, 178, 194, 210, 226, 242:
    Arr2 := Data;
  163, 195, 35, 3, 67, 83, 99, 115, 131, 147, 163, 179, 195, 211, 227, 243:
    Arr3 := Data;
  164, 196, 36, 4, 68, 84, 100, 116, 132, 148, 164, 180, 196, 212, 228, 244:
    Arr4 := Data;
  165, 197, 37, 5, 69, 85, 101, 117, 133, 149, 165, 181, 197, 213, 229, 245:
    Arr5 := Data;
  166, 198, 38, 6, 70, 86, 102, 118, 134, 150, 166, 182, 198, 214, 230, 246:
    Arr6 := Data;
 
END_CASE

FluidPowerTom:
The programming syntax is interfering with part of the code I wrote

FOR i = 0 TO 7 DO
    Arr0[i+Index_Adder]:=Data[''i'']; (remove apostrophes on i)
END_FOR

F.M.Elettromeccanica:
FluidPowerTom, I still can't get your code to work. Maybe I'm making a mistake somewhere. I will reply as soon as possible and let you know. Thank you, many thanks for everything.

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version