Hello,
I am trying to receive a NMEA2000 fast-packet message, meaning that the entire message is sendt in multiple frames right after each other. In WAGO -IO-CHECK-3 I have verified that all the frames in the message are received by the 750-658 can-bus gateway. However, when I try to process the messages in CODEYS 3.5.19 by using the state-machine in the code below I sometimes seam to get the same message twice. I use the wCounter in the FbCanRx29BitFrame to check if there are any new messages, based on this I trigger the _xRXTrigger to receive a new message which I then process. However, when I process the message, I often get the same data in the message twice, regardless that the wCounter has increased (which I assume is the truth).
First off, is it ok to use the wCounter as and indicator that there is a new message to receive? Is it just that I am handling this wrong, or are there any known issues about processing messages from the CANbus gateway in CODESYS?
Any tips to help me be able to process all the messages received by the CANBUS-gateway in CODESYS, will be appreciated!
//This must be runned every cycle, regardless of the processing afterwards
FbCanL2Open(
xEnable:= TRUE,
I_Port:= _750_658_24,
udiBaudrate:= 250000,
dwFlags:= 2#00000000_00000000_00000000_01010011,
dwPara:= ,
xValid=> ,
xBusy=> ,
xError=> ,
oStatus=> );
currentTime := TIME(); // Get current time
CASE state OF
INIT:
//initialisation state
state := COMMUNICATING;
RESET:
// Reset the communication, in case of hold-ups when communicating or as a fall-back in an error state
COMMUNICATING:
IF FbCanL2Open.xValid AND NOT FbCanL2Open.xError THEN
state:= LISTENING;
ELSE
STATE:= ERROR;
END_IF
LISTENING:
// call the WAGO CANBUS FB to get the updated wCounter;
_FbCanRx29BitFrame(
xEnable := _xEnable,
I_Port := _750_658_24,
xBufferMode := _xBufferMode,
dwCanId := _wCanId,
xBufferMode := _xBufferMode,
xRxTrigger := _xRxTrigger,
xValid => _xValid,
xError => _xError,
xBusy => _xBusy,
oStatus => oStatus,
wCounter => _wCounter,
wFrames => _wFrames,
//xRtrFrame => _xRtrFrame,
bRxNBytes => _bRxNBytes,
aRxBuffer => _aRxBuffer);
IF _wCounter > fetchedMsgCnt THEN
IF _xBufferMode THEN
lastwCount:= lastwCount +1; //count one by one upwards
ELSE
lastwCount := _wCounter; //Skipping whichever msg we missed
END_IF
state:= FETCHING_MSG;
_xRxTrigger:= TRUE; //Set the trigger to true to avoide the need to handle this in fetching
END_IF
FETCHING_MSG:
_FbCanRx29BitFrame(
xEnable := _xEnable,
I_Port := _750_658_24,
xBufferMode := _xBufferMode,
dwCanId := _wCanId,
xBufferMode := _xBufferMode,
xRxTrigger := _xRxTrigger,
xValid => _xValid,
xError => _xError,
xBusy => _xBusy,
oStatus => oStatus,
wCounter => _wCounter,
wFrames => _wFrames,
//xRtrFrame => _xRtrFrame,
bRxNBytes => _bRxNBytes,
aRxBuffer => _aRxBuffer);
IF NOT _xRxTrigger AND NOT _xBusy AND NOT _xError AND _xValid THEN
fetchedMsgCnt:= fetchedMsgCnt+1;
frame := _aRxBuffer;
(* Shift existing frames down *)
FOR i := 100 TO 1 BY -1 DO
arrayOfFrames[i] := arrayOfFrames[i - 1];
END_FOR
(* Insert new frame at the top *)
arrayOfFrames[0] := frame;
state := PROCESSING_MSG;
END_IF
PROCESSING_MSG:
firstByte := frame[0];
sequenceNumber := SHR(firstByte,5) ;
frameCounter := TO_UINT(firstByte AND 16#07);
loc := TO_UINT(frame[5] AND 16#0F);
IF frameCounter = 0 THEN
firstFrameProcessing:= firstFrameProcessing +1;
lastSequenceNumber:= sequenceNumber;
IF loc = 1 THEN
nBowMsgs := nBowMsgs+ 1 ;
END_IF
IF loc = 2 THEN
nSternMsgs:= nSternMsgs +1;
END_IF
END_IF
processedMsgCnt:=processedMsgCnt+1;
IF _wFrames>0 THEN
IF max_nBufferedMsgs <_wFrames THEN
max_nBufferedMsgs := _wFrames;
END_IF
END_IF
state := COMMUNICATING;
DROPPING_MSG:
droppedMsgCnt:= droppedMsgCnt+1;
state:= COMMUNICATING;
ERROR:
IF previousState <> state THEN
errorCount := errorCount + 1;
errorStart := currentTime;
END_IF
errorTimer:= currentTime - errorStart;
state := COMMUNICATING;
END_CASE
previousState := state;