Canbus Data Communicaion


ethushara

Recommended Posts

hi,

 

In my project i need to get data through the CAN bus protocol (CAN1 - 11bits) from the modules to the PC (Daqfactory). It is better if i can do this without using protocol converters. So please let me know if you can help me on this. Actually both the read and write are required. 

 

 

 

BR

 

Thushara.

Link to comment
Share on other sites

As far as I know, in order to do CAN, you have to have a device.  Unfortunately there is no standard API for these devices, so we don't have native support.  However, many have pretty simple API's that can be linked into DAQFactory using the extern() function.  You may be able to hack a serial port to work with CAN, I don't know.  I would imagine not as CAN tends to be much higher speed than regular serial.  You'd also have to probably create a low level Windows driver as Windows doesn't give access to individual bits of the serial port, only bytes.  Given the effort required, I would just buy a CAN converter.

Link to comment
Share on other sites

  • 2 weeks later...

YEs, Thanks. I have made an order for a CAN-USB adapter. After it received i can connect it to my pc and assign a port number. And also then i can add it under adding new serial port in to the daqfactory. But from that onwards i have no idea to progress. So I hope you will help me on this to make this success. For the moment i am using other data formats such as Modbus, Labjack modules, Ethernet etc.. with daqfactory in my hydro power control projects. There i used an HMI in between my CAN modules and the PC. Those HMIs read CAN from the modules and send to the PC through Ethernet. Now i need to remove that HMIs. So i need to read those CAN modules directly from the PC. So i need your support to make it success.

 

Thanks in advance.

Link to comment
Share on other sites

  • 2 weeks later...

HI,

The device type is USB-Serial CH340.  The device details and the software related to this can be downloaded from the below link.

http://yun.baidu.com/share/link?shareid=2231924035&uk=1178160824

The page is in Chinese,but you can right click and translate it. 

I checked this converter with their own monitoring software by connecting to my CAN modules. it is working correctly for both receiving and sending. Then i used i with Daqfactory also. Then i could monitor the incoming frames with correct data in MONITOR in the ETHERNET/SERIAL DEVICE window. Below are some one frames taken from DAQfactory MONITOR. The CAN ID was 24 (18H) and he data were 232,232,230,229,229,229.etc.

Rx: \170U\001\001\001\024\000\000\000\008\232\232\230\229\229\229\000\000\000\136

Rx: \xAAU\x01\x01\x01\x18\x00\x00\x00\x08\xE8\xE8\xE6\xE5\xE5\xE5\x00\x00\x00\x88

 

The settings in the DAQfactory was as below.

Baud rate: 1228800bps

Byte Size: 8 

1 stop bit,No parity

I hope these details will help you help me on the requirement. 

Any further clarifications needed, please revert to me.

 

Thanks in Advance.

 

Thushara

Link to comment
Share on other sites

Hi,

I tried and finally succeeded the reading part of the CAN data. I could customize the scripts i used previously and then came to the success. Now the 8 data can be monitored from the channels IN0 - IN7. Below is the script used for this. If any changes needed for a proper operation please let me know.

Now i need to make the writing part (Data sending from PC). In fact this is he most critical requirement for my project. But i have no idea to implement this. So i hope your valuable support on this from the beginning. i hope the platform is clear for you and waiting for your support on scripting. 

while (1)
   device.Miacc.Purge()
   private string strIn = device.Miacc.read(1)
   private string in = asca(strIn)
   strIn = device.Miacc.read(in[1])
   in = asca(strIn)
   ID.Addvalue(in [4])
   If ((ID (0) > 22) && (ID (0) < 26))
      IN0.Addvalue(in [9])
      IN1.Addvalue(in [10])
      IN2.Addvalue(in [11])
      IN3.Addvalue(in [12])
      IN4.Addvalue(in [13])
      IN5.Addvalue(in [14])
      IN6.Addvalue(in [15])
      IN7.Addvalue(in [16])
   else
   delay (1)
   endif
   delay (1)
endwhile

Thanks,

 

Thushara

Link to comment
Share on other sites

what you have looks good, though I'm not sure about frame alignment.

 

As for output, I don't know what is required, so can't really give you any input.  The techniques are very similar to inputs, but reversed.  Build an array of bytes, use chra() to convert it to a string, then use write() to write it to the port.

Link to comment
Share on other sites

Hi,

Yes. I did it as below and finally it could be read by the micro-controller. 

while (1)
   Device.Miacc.write (ChrA({170,085,001,001,001,056,000,000,000,008,0,1,2,3,4,5,6,7,000,95}))
   delay (1)
endwhile

Here all are in ASCII. the 056 is the ID of the CAN frame. 008 is the number of data bytes trailing. from 0-7 are the data bytes. 

Please let me know if any mistakes done in the script. And now i need to add data from channels and variables to this array. it means for the ID and the data bytes. in other words i need to add the values of the channels or the variables to this array in order to send them to the micro-controller. So please help me on this scripting. 

 

And this script is getting automatically stopped after running some time.  please give me the possible reasons for this too.

 

Thanks,

 

Thushara.

Link to comment
Share on other sites

  • 2 years later...

Hi,

As per the above discussions i read and wrote canbus data from and to can devices in several projects. But when the number of channels are increasing the CAN-USB converter i used was giving faults. It stops the communication after sometimes of running well. o i decided to go with a more reliable converter with high quality. But this converters are not working with the previous scripts. 

here is the data word comes from the device through the new converter when analyzed through Tera term software. 

S18N1C1B1C1C1B1C1B00

for the address is 18 Hex

and the 8 data are

28,27,28,28,27,28,27,0

Please guide me to read this same as the previous converter. 

Best regards,

Thushara.

Link to comment
Share on other sites

I can't give you complete instruction without knowing more, but it looks like the data values are coming over as ASCII characters.  I'm not familiar with Teraterm so can't tell if its doing any translations (which is why its better to use the DAQFactory Comm Monitor).  Anyhow, 1C is 28, 1B is 27, so assuming it is ascii characters you want to use mid() to pull out each pair, and then either use evaluate() with "0x" or simply use the from.hexstring() function.  So, either:

evaluate("0x" + mid(datain,4,2))

which will give you the first #.  Then repeat incrementing the first number of the mid() by two, so mid(datain,6,2), etc.  Use a for() loop.

Or you can use from.hexstring() to do it in one shot:

from.hexString(mid(datain,4,16), 1)

It will return an array of values

Link to comment
Share on other sites

  • 4 weeks later...

Hi,

i'm not that familiar with these scripting and hence i couldn't made it success with your instructions. So here i'm including the script which i'm using right now for the previous CAN module. 

while (1)
   device.Miacc.Purge()
   private string strIn = device.Miacc.read(1)
   private string in = asca(strIn)
   strIn = device.Miacc.read(in[1])
   in = asca(strIn)
   ID.Addvalue(in [4])
   If ((ID () > 22) && (ID () < 26))
      IN0.Addvalue(in [9])
      IN1.Addvalue(in [10])
      IN2.Addvalue(in [11])
      IN3.Addvalue(in [12])
      IN4.Addvalue(in [13])
      IN5.Addvalue(in [14])
      IN6.Addvalue(in [15])
      IN7.Addvalue(in [16])
   else
   delay (1)
   endif
   delay (1)
endwhile

So can you please make the mentioned changes to this program to read the data from the new module? 

Also i have attached a screen shot of the DAQfactory comm monitor as well. The address of the data array is 18 (hex) and the data in decimal  10,11,12,13,14,15,16,17

Your support on this is highly appreciated. 

Thanks,

Thushara.

comm monitor DAQfactory.jpg

Link to comment
Share on other sites

  • 2 weeks later...

It be something more like:

while (1)
   device.Miacc.Purge()
   private string strIn = device.Miacc.readUntil(chr(';'))
   ID.Addvalue(strToDouble(mid(strIn,1,2)))
   If (ID[0] == 18)
      IN0.Addvalue(evaluate("0x" + mid(strIn, 4,2)))
      IN1.Addvalue(evaluate("0x" + mid(strIn, 6,2)))
      IN2.Addvalue(evaluate("0x" + mid(strIn, 8,2)))
      IN3.Addvalue(evaluate("0x" + mid(strIn, 10,2)))
      IN4.Addvalue(evaluate("0x" + mid(strIn, 12,2)))
      IN5.Addvalue(evaluate("0x" + mid(strIn, 14,2)))
      IN6.Addvalue(evaluate("0x" + mid(strIn, 16,2)))
      IN7.Addvalue(evaluate("0x" + mid(strIn, 18,2)))
   else
      delay(1)
   endif
   delay(1)
endwhile
Link to comment
Share on other sites

  • 3 months later...

hi,

Thanks a lot for your reply and now i can read and write to the CAN modules. But for this i have to write in ascii figures of Hex values of the required decimal value to be written in the CAN device. 

EX, if I need to write the value 40 in decimal in my CAN device, I have to convert it to Hex (24) and it is required to get ascii values of these two figures 2 and 4, which are 050\052 and send. In other words I have to send 050\052 in array to get the decimal figure 40 written in my CAN device. 

Ex:

the value to be written in decimal is 255 a script  is required to result the two Ascii codes (070\070) of the hexa figures. (FF)

So please let me know how can i get these conversions in scripts. I need to convert a value in a variable to this format to send for writing finally.  

Thanks in advance,

BR

Thushara

Link to comment
Share on other sites

Just use the format() function with the %X specifier.  For example:

device.myDevice.write(format("%X", 255))

will output FF (or \070\070, same thing) to myDevice.

Note that you can use %X or %x depending on whether you want the letters in any hex result to be upper case or lower case.

Link to comment
Share on other sites

Hi,

To send the data 10,11,12,13,14,15,16,17 through address 18 Hex ( 24 in decimal) I have to send the below array, I tested this and its working properly. 

private out = {058,083,049,056,078,048,065,048,066,048,067,048,068,048,069,048,070,049,048,049,049,059}
Device.U1GOV.write(ChrA(out))

Now i need to add the values in my variables to this. please help me to do this. If you can write the complete script for me you will be appreciated. 

 

The transmission format is as below for your reference. 

:S18N0A0B0C0D0E0F1011;

 

Transmission.jpg

Link to comment
Share on other sites

Since timing isn't critical, I would store the data in an array as numbers, 10, 11, 12, etc. then only convert to hex at the last minute.  So, 

private data = seqAdd(10,1,15)  // create initial array
data = data + someOtherVariable // add some data to it
for (private i = 0, i < numrows(data), i++)
   device.U1GOV.write(chra(format("%X",data)))
endfor

You don't have to output everything in a single Write().  While normally I avoid loops in script because they are slow, when doing serial comms, its still much faster then the serial port itself.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.