CODESYS - the IEC 61131-3 automation software

Welcome to the official CODESYS Forum
Deutsche Version English version russian version 
It is currently Sat Dec 16, 2017 5:46 pm

All times are UTC+01:00




Post new topic  Reply to topic  [ 5 posts ] 
Author Message
PostPosted: Wed Feb 15, 2017 5:14 pm 
Offline

Joined: Thu Jan 26, 2017 5:00 pm
Posts: 16
I am brand new to codesys programming and am working on a project where I am trying to read raw CAN values off of a CAN network.

I believe my code is correct since I used a referenced codesys program from v2.3 that reads CAN values as well. The problem is that the code I was referencing used functions from an IFM library and I am programming a DI4 Display from Bosch/Rexroth. I don't believe this is the library I want. Although I did try to import the library into my v3.5 program but I get an error.

Which library should I use to get my program working? Or is there a way to make the IFM libraries work with my new device?

I have a CANbus J1939 Manager configured and I'll paste the code below in my CAN_READ program if that helps.

EDIT: I just remembered that this controller uses CAN2.0B? I am not entirely sure what that is or where I can download it. Google hasn't been very helpful so far.

EDITT: Apparently CAN2.0B is an industry standard but I don't understand how that helps with implementation since I haven't been able to find useful literature so far.

Code:
PROGRAM CAN_Read
VAR
   rx_Message1: CAN_RX;
   abMessage1: ARRAY [0..7] OF BYTE;
   rx_Message2: CAN_RX;
   abMessage2: ARRAY [0..7] OF BYTE;
   nFPMNeedleAngle : INT;
   rx_Message3: CAN_RX;
   abMessage3: ARRAY [0..7] OF BYTE;
   rx_Message4: CAN_RX;
   abMessage4: ARRAY [0..7] OF BYTE;
   rx_Message5: CAN_RX;
   abMessage5: ARRAY [0..7] OF BYTE;
   rx_Message6: CAN_RX;
   abMessage6: ARRAY [0..7] OF BYTE;
   rx_Message7: CAN_RX;
   abMessage7: ARRAY [0..7] OF BYTE;
   rx_Message8: CAN_RX;
   abMessage8: ARRAY [0..7] OF BYTE;
   rx_Message9: CAN_RX;
   abMessage9: ARRAY [0..7] OF BYTE;
   rx_Message10: CAN_RX;
   abMessage10: ARRAY [0..7] OF BYTE;
   rx_Message11: CAN_RX;
   abMessage11: ARRAY [0..7] OF BYTE;
   
   //Addresses of PDO-IDs
   PDO1: INT:=16#2FA;
   PDO2: INT:=16#2FB;
   PDO3: INT:=16#2FC;
   PDO4: INT:=16#2FD;
   PDO5: INT:=16#2FE;
   PDO6: INT:=16#2FF;
   PDO7: INT:=16#3FA;
   PDO8: INT:=16#3FB;
   PDO9: INT:=16#3FC;
   PDO10: INT:=16#3FD;
   PDO11: INT:=16#3FE;
   
   //Create one instane and only have to change it once if wrong.
   Chan: INT:=1;
   
   //Variable names moved to Global Variable List
   
   Unpack1: UNPACK;
   Unpack2: UNPACK;
END_VAR


Code:
//Recieve CAN Data
rx_Message1(ENABLE:= TRUE,CHANNEL:= Chan,ID:= PDO1);
rx_Message2(ENABLE:= TRUE,CHANNEL:= Chan,ID:= PDO2);
rx_Message3(ENABLE:= TRUE,CHANNEL:= Chan,ID:= PDO3);
rx_Message4(ENABLE:= TRUE,CHANNEL:= Chan,ID:= PDO4);
rx_Message5(ENABLE:= TRUE,CHANNEL:= Chan,ID:= PDO5);
rx_Message6(ENABLE:= TRUE,CHANNEL:= Chan,ID:= PDO6);
rx_Message7(ENABLE:= TRUE,CHANNEL:= Chan,ID:= PDO7);
rx_Message8(ENABLE:= TRUE,CHANNEL:= Chan,ID:= PDO8);
rx_Message9(ENABLE:= TRUE,CHANNEL:= Chan,ID:= PDO9);
rx_Message10(ENABLE:= TRUE,CHANNEL:= Chan,ID:= PDO10);
rx_Message11(ENABLE:= TRUE,CHANNEL:= Chan,ID:= PDO11);

   IF rx_message1.RESULT = 1 THEN
      abMessage1 := rx_Message1.DATA;
   ELSE
      abMessage1 := abMessage1;
   END_IF

   IF rx_message2.RESULT = 1 THEN
      abMessage2 := rx_Message2.DATA;
   ELSE
      abMessage2 := abMessage2;
   END_IF

   IF rx_message3.RESULT = 1 THEN
      abMessage3 := rx_Message3.DATA;
   ELSE
      abMessage3 := abMessage3;
   END_IF

   IF rx_message4.RESULT = 1 THEN
      abMessage4 := rx_Message4.DATA;
   ELSE
      abMessage4 := abMessage4;
   END_IF

   IF rx_message5.RESULT = 1 THEN
      abMessage5 := rx_Message5.DATA;
   ELSE
      abMessage5 := abMessage5;
   END_IF

   IF rx_message6.RESULT = 1 THEN
      abMessage6 := rx_Message6.DATA;
   ELSE
      abMessage6 := abMessage6;
   END_IF

   IF rx_message7.RESULT = 1 THEN
      abMessage7 := rx_Message7.DATA;
   ELSE
      abMessage7 := abMessage7;
   END_IF

   IF rx_message8.RESULT = 1 THEN
      abMessage8 := rx_Message8.DATA;
   ELSE
      abMessage8 := abMessage8;
   END_IF
   
   IF rx_message9.RESULT = 1 THEN
      abMessage9 := rx_Message9.DATA;
   ELSE
      abMessage9 := abMessage9;
   END_IF

   IF rx_message10.RESULT = 1 THEN
      abMessage10 := rx_Message10.DATA;
   ELSE
      abMessage10 := abMessage10;
   END_IF

   IF rx_message11.RESULT = 1 THEN
      abMessage11 := rx_Message11.DATA;
   ELSE
      abMessage11 := abMessage11;
   END_IF

Engine_Speed:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage1[0], MS_BYTE:=abMessage1[1]);
Hyd_Oil_Psi:= TWOBYTES_TO_WORD(LS_BYTE:=abMessage1[2], MS_BYTE:=abMessage1[3]);
Fuel_Level:=BYTE_TO_INT(abMessage1[4]);
Machine_Speed:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage1[5], MS_BYTE:=abMessage1[6]);

Left_Gate_Pot:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage2[0], MS_BYTE:=abMessage2[1]);
Right_Gate_Pot:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage2[2], MS_BYTE:=abMessage2[3]);
Left_Gate_Volt:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage2[4], MS_BYTE:=abMessage2[5]);
Right_Gate_Volt:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage2[6], MS_BYTE:=abMessage2[7]);

Joystick_Volt:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage3[0], MS_BYTE:=abMessage3[1]);
Motor_Freq:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage3[2], MS_BYTE:=abMessage3[3]);
Pump_Fwd:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage3[4], MS_BYTE:=abMessage3[5]);
Pump_Rev:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage3[6], MS_BYTE:=abMessage3[7]);

Motor_Front:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage4[0], MS_BYTE:=abMessage4[1]);
Motor_Rear:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage4[2], MS_BYTE:=abMessage4[3]);
Left_Gate_Open:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage4[4], MS_BYTE:=abMessage4[5]);
Left_Gate_Close:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage4[6], MS_BYTE:=abMessage4[7]);

Right_Gate_Open:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage5[0], MS_BYTE:=abMessage5[1]);
Right_Gate_Close:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage5[2], MS_BYTE:=abMessage5[3]);
Hyd_Oil_Temp:=BYTE_TO_INT(abMessage5[4]);
Engine_Coolant_Temp:=BYTE_TO_INT(abMessage5[5]);
Machine_Speed2:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage5[6], MS_BYTE:=abMessage5[7]);

Agg_Dist_Rate:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage6[0], MS_BYTE:=abMessage6[1]);
Agg_Density_Right:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage6[2], MS_BYTE:=abMessage6[3]);
Agg_Density_Left:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage6[4], MS_BYTE:=abMessage6[5]);
Battery_Volt:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage6[6], MS_BYTE:=abMessage6[7]);

Agg_Size:=BYTE_TO_INT(abMessage7[0]);
Left_Auger_Percent:=BYTE_TO_INT(abMessage7[1]);
Right_Auger_Percent:=BYTE_TO_INT(abMessage7[2]);
Left_Conv_Percent:=BYTE_TO_INT(abMessage7[3]);
Right_Conv_Percent:=BYTE_TO_INT(abMessage7[4]);
Joystick_Percent:=BYTE_TO_INT(abMessage7[5]);

Right_Gate_Close_Current:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage8[0], MS_BYTE:=abMessage8[1]);
Right_Gate_Open_Current:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage8[2], MS_BYTE:=abMessage8[3]);
Left_Gate_Close_Current:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage8[4], MS_BYTE:=abMessage8[5]);
Left_Gate_Open_Current:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage8[6], MS_BYTE:=abMessage8[7]);

Pump_Fwd_Min:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage9[0], MS_BYTE:=abMessage9[1]);
Pump_Rev_Min:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage9[2], MS_BYTE:=abMessage9[3]);
Front_Motor_Min:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage9[4], MS_BYTE:=abMessage9[5]);
Rear_Motor_Min:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage9[6], MS_BYTE:=abMessage9[7]);

Right_Screen_Rate:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage10[0], MS_BYTE:=abMessage10[1]);
Left_Screen_Rate:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage10[2], MS_BYTE:=abMessage10[3]);
Gate_Open_Hold:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage10[4], MS_BYTE:=abMessage10[5]);
Gate_Shut_Hold:=TWOBYTES_TO_WORD(LS_BYTE:=abMessage10[6], MS_BYTE:=abMessage10[7]);

Engine_Hours:=FOURBYTES_TO_DWORD(BYTE1:=abMessage11[0], BYTE2:=abMessage11[1], BYTE3:=abMessage11[2], BYTE4:=abMessage11[3]);
Distance_Chipped:=FOURBYTES_TO_DWORD(BYTE1:=abMessage11[4], BYTE2:=abMessage11[5], BYTE3:=abMessage11[6], BYTE4:=abMessage11[7]);



Top
   
PostPosted: Fri Feb 17, 2017 8:15 am 
Offline
Site Admin

Joined: Mon Sep 05, 2005 9:42 am
Posts: 2333
Hi,
for me the questions are:
1. which plc are you using now
2. in which Version
and
3. you want to use J1939 is that right?

BR
Edwin


Top
   
PostPosted: Fri Feb 17, 2017 10:02 pm 
Offline

Joined: Thu Jan 26, 2017 5:00 pm
Posts: 16
Hello Edwin,

1) We are not using a PLC per say but using a BODAS controller RC28 14-30.

2) The version I am using is CODESYS V3.5 SP4 Patch1

3) Yes that is correct.

From the time I originally posted this question, I have since realized that the code I posted above is incorrect for trying to read CAN data with this DI4 Bodas Display. I have re-written it as of now using the CAN API package.

I have another question though, what does the "red triangle" mean next to the device?

Attachment:
redTriangle.JPG


You do not have the required permissions to view the files attached to this post.


Top
   
PostPosted: Sun Feb 19, 2017 7:50 am 
Offline
Site Admin

Joined: Mon Sep 05, 2005 9:42 am
Posts: 2333
Hi,
do not use the Simulation mode with Control Win,
Control Win is installed on the same machine where your CODESYS instance is running so why not login to the real plc.
It does not really make sense to use the Simulation with all the restirctions it have.
By the way if you want to use Control Win for CAN communication, please use a Peak-USB CAN Interface,
this will work with Control Win.
(So your pc could be the CANopen Master / CANopen Device or J1939 or even CAN raw sending/receive machine)

Br
Edwin


You do not have the required permissions to view the files attached to this post.


Top
   
PostPosted: Tue Feb 21, 2017 8:45 pm 
Offline

Joined: Thu Jan 26, 2017 5:00 pm
Posts: 16
Well the controller is currently sititing in one of our products right now waiting for field testing (it's brand new software for this controller). I do have a Peak-USB CAN interface but the plug-in is only usefull for uploading software from a labtop to the controller. The adapter doesn't fit the DI4 Display and thus am waiting for one to ship here from Rexroth/Bosch.

What I would like to do is verify that my code works before trying it on our new computer that's sitting in our product right now. What I'm getting away from this conversation right now is that I can having my computer set-up as a CANMaster to send messages to the "slave" (i.e. my codesys program) correct? How should I set-up my CAN devices then?

My current set-up right now is shown in the attached picture. I'm confused on the structure of the parent/child devices.

I have my CANbus device added, then I have my J1939_Manager device below that one as a child, and finally the J1939_ECU as the child to the manager. Does this device tree mean that the J1939-Manager is a 'slave' device to the CANbus and the J1939_ECU is a 'slave' to it's master the J1939-Manager? I really don't understand the heirarchy here and I can't find a good explanation on the internet. Could you explain the significance of each device or at least point me to a source that I can read?

Attachment:
childDevices.JPG


You do not have the required permissions to view the files attached to this post.


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 5 posts ] 

All times are UTC+01:00


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Limited