USB to UART Bridge


RJE

Recommended Posts

The serial device I have installs a Silicon Labs CP210x USB to UART Bridge, Com 6 in my case and is in my hardware list as functional.

I can use my serial port monitor to watch the port being open & closed by the included software. I can see the commands sent to it to start streaming a 43 byte packet every second which are received.

Jumping right in with DF and wham, brick wall. When I create a serial device for com 6 I get "Unable to initialize Com6: Can't access port, probably in use by another app".

I'm not sure what to do next. Any ideas?

Randy

Link to comment
Share on other sites

Do you still have your serial port monitor open? You can't have their software and DF running at the same time. Only one software tool can access the port at once and whoever is started first claims it. If it appears that nothing else is running, reboot and try again, then try with Hyperterminal.

Link to comment
Share on other sites

No, I closed it. I can open the serial port monitor that I have first, set it to com 6 and then open their software and start communications. In the serial port monitor window I can see the send receive data flowing.

Did a reboot and tried to set up com 6 in DF and it still says port in use.

Been awhile since I used HT but set up a session for com 6 and HT says it is connected but I couldn't figure out how to send hex values to initiate packet streaming.

PC sends FC(hex)

ECM-1220 responds with FC(hex)

PC send three ASCII bytes

Link to comment
Share on other sites

You are correct sir.

Checking my ports with Sandra from SiSoftWare, com 1 it gives a warning that it is in use, which it is. Checking com 6, no in use warning and it dumps all the port details out.

The driver version is 5.30 which seems to be the latest from Silicon Labs.

Link to comment
Share on other sites

Well, DF is accesses the port through simple windows calls. Perhaps you have the baud or other setting wrong? Something the usb thing isn't compatible with?

I might need to connect into your system to chase this one down with you. Is the system connected to the internet? If so, give us a ring sometime and I can connect into it.

Link to comment
Share on other sites

I tried several things, changed the com port # etc, when selecting a new port in hardware it shows that com 6 is not in use. Still no luck with DF.

I connected a USB to serial converter which was installed to com 7, opened a new DF doc and created a new serial device and was able to connect to another device that I have.

I run several programs to turn things on/off and collect data from my home and was really hoping I could get this all done with DF but I don't think all is lost yet.

The USB to UART driver is located here, http://www.brultech.com/ecmsupportupdate.html. Brultech's Lite-1220 software works fine with this driver but the display of data is just not what I want.

Thanks

Link to comment
Share on other sites

Sounds like there is something funky with their driver. Its really hard to tell what they are doing internally in their software. They may not be using their converter, but instead using straight USB. Also, some usb Anyhow, is there another way to connect into the device? For example, does it have a normal Serial port or ethernet port? If a serial port, you could just use that com 7 converter and connect it to that.

Link to comment
Share on other sites

Bingo and not sure what I did.

Tried again setting up a RS232 device with this thought in mind, my Sandra software tells me that com 6 has DTR & DSR as active so I tried setting the handshaking to manual and enabling DTR & DSR. At first DF said port is busy, I went back and put handshaking to none and the comm monitor window started to show Rx data as 00 coming in on a regular basis.

I sent \xFC and Rx'd back the response of \xFC, which seems correct. So it seems we are talking now. I can't enter the next commands as the ECM-1220 times out to fast. So I will need to create a script to do the handshaking to get the packets flowing every second.

That may take me abit because I'm not sure how to send \xFC, wait for \xFC back, then send T O G, wait for \xFC back and then send P L R.

Randy

Link to comment
Share on other sites

Another ? before the weekend, what's the best way to parse out the package, start from the front or back?

Here's the packet info,

Packet length is 43 bytes:

Byte number

1 to 3 Three distinct header bytes FE, FF, 01

4 to 5 Volt, two bytes Byte 4 = MSB Byte 5 = LSB

6 to 10 CH1 Watt-Second Absolute Counter. Byte 6 = LSB, Byte 10 = MSB

11 to 15 CH2 Watt-Second Absolute Counter. Byte 11 = LSB, Byte 15 = MSB

16 to 20 CH1 Watt-Second Polarized Counter. Byte 16 = LSB, Byte 20 = MSB

21 to 25 CH2 Watt-Second Polarized Counter. Byte 21 = LSB, Byte 25 = MSB

26 to 29 Reserved

30 to 31 Reserved

32 Reset and Polarity Information

33 Device Information

34 to 35 CH1 Current in 100th of a Amp LSB = 34 MSB = 35

36 to 37 CH2 Current in 100th of a Amp LSB = 36 MSB = 37

38 to 40 Seconds Counter LSB = 38 MSB = 40 One second resolution

41 to 42 End of Packet Marker 41 = FF (hex) 42 = FE (hex)

43 Checksum

Thanks again and judging the amout of I/O tags I'll need, it looks like I will need the standard DF package.

Cheers

Link to comment
Share on other sites

Well, the response will be in a string. I'd then use the asca() function to convert that string into an array of bytes. Then you can access any of the bytes just with [x] notation and you'll get a number between 0 and 255. Then its just math, or you can use the To. functions to do the math for you.

BTW: we monitor the forum on weekends as well, so if you have questions over the weekend you'll likely get a timely response. In this industry the notion of a 9-5 work week really is ridiculous. I rarely see a plant that shuts down at 5pm on friday.

Link to comment
Share on other sites

I'm just having a hard time of grasping with what is what. I know what a string is, I know ascii characters, I know hex values but rolling it all up in DF is confusing the hec out of me. So to get this device streaming data packets every second I have to do this:

PC sends FC(hex)

ECM-1220 responds with FC(hex)

PC send three ASCII bytes

Link to comment
Share on other sites

OK, this is a common conceptual problem that is not unique to DAQFactory (which really follows most other languages anyway). A byte is number between 0 and 255. An ASCII character is the representation of that byte using the ASCII standard where, for example, 65 stands for A, 66 for B, etc. There are other character representations, such as Unicode, but it gets more complicated and I'll just avoid that topic for now. A string is a group of bytes represented in their ASCII form and in a single variable. So internally, if you have the string 'ABC', it is storing it as 65, 66 and 67. Externally, though those numbers are represented in their character form, A, B and C, and as a single value 'ABC'.

OK, DAQFactory serial stuff does everything in strings. This is because many devices take basic ascii strings like 'Give me data' and its easy to deal with that way. If you have a binary protocol, like yours, you still have to use strings, you just have to thing of them as a string of bytes, not in terms of their ascii representations.

The problem is that if you are doing a basic ascii protocol you can just do device.ecm.write("give me data"), but if you want to output FC (hex) you have to convert it into its ascii representation, which, I might add, you can't really do since their is no key on most keyboards that will generate the ASCII representation for FC. So, DAQFactory provides two functions, chr() and asc() to convert a number into its ascii representation string and back. So, as you did: chr(252) converts the number 252 into its ascii representation as a string which you can then output. Simply doing write(252) doesn't work because write() expects a string, not a number. Now, I should mention that you could also do chr(0xFC) to do the same thing since putting 0x in front of a value indicates that its in hex format when in script.

Now then, we also have two functions chra() and asca() which do the same thing as chr() and asc(), but on a bunch of characters. So, chr({65,66,67}) will just return 'A' because chr() only takes a single value, doing chra({65,66,67}) will return 'ABC'. Likewise, asc('ABC') will return just 65 because it only looks at the first charcter, asca('ABC') will return the array {65,66,67}. So when doing binary protocols, I use chra() and asca() a lot. This is what I recommended with the streaming data. Do asca() on the string returned by the read, and then you can just treat it as an array of numbers.

Your script basically should look like this:

private string datain
private data
device.ecm.purge()
device.ecm.write(chr(0xFC))
datain = device.ecm.read(1)
if (datain != chr(0xFC))
   return  // error, didn't reply. 
endif
device.ecm.write('TOG')
datain = device.ecm.read(1)
if (datain != chr(0xFC))
   return  // error, didn't reply. 
endif
device.ecm.write('PLR')
while (1)
   try
	  // data should be streaming, read a packet:
	  datain = device.ecm.read(43)
	  // convert the packet from a string to an array of bytes:
	  data = asca(datain)
	  // check for header:
	  if (data[0,2] != {0xfe,0xff,0x01})
		 device.ecm.purge()
		 continue // just loop around for next packet 
	  endif
	  // now process:
	  private ch1 = to.ulong(data[5,9])
	  private ch2 = to.ulong(data[10,13])
	  // etc.  for the two byte ones like 33,34 you'll use to.uword
	  // for 3 byte ones, you'll have to calc it manually
	  // not that everything is 0 indexed, while your byte list above
	  // is 1 indexed, so subtract 1 from all the indexes you listed
   catch()
	  ? strLastError
	  delay(0.5)
  endcatch
endwhile

That should get you started. Post if you have any questions.

Link to comment
Share on other sites

I understand now, your explanation was excellant and your code snippet cleared up alot of confusion.

Oh to have the luxury of your experience but I will get there in time.

I massaged your code abit to fit my situation and I swear it was functioning perfectly last night. I was able to pull L1 and L2 amp values out of the packet, convert them and push them to channels and graph them.

When I started on the project today all I added was the voltage conversion.

private string datain
private data

device.ECM_1220.purge()

device.ECM_1220.write(chr(0xFC))
datain = device.ECM_1220.read(1)

if (datain != chr(0xFC))
   return  // error, didn't reply
endif

device.ECM_1220.write('TOG')
datain = device.ECM_1220.read(1)

if (datain != chr(0xFC))
   return  // error, didn't reply
endif

device.ECM_1220.write('PLR')

while (1)
   try
      // data should be streaming, read a packet
      datain = device.ECM_1220.read(43)
      // convert the packet from a string to an array of bytes
      data = asca(datain)
      // check for header
      if (data[0,3] != {0xfe,0xff,0x01})
         device.ECM_1220.purge()
         continue // just loop around for next packet 
      endif

      // now process amps, bytes are LSB - MSB
      private amp1_raw = to.uWord(data[33,2])
      private amp1 = amp1_raw / 100
      private amp2_raw = to.uWord(data[35,2])
      private amp2 = amp2_raw / 100
      //now process volts, bytes are MSB - LSB
      private volt_raw = to.urWord(data[3,2])
      private volt = volt_raw / 10

      L1_Amps.AddValue(amp1)
      L2_Amps.AddValue(amp2)
      Volts.AddValue(volt)

   catch()
      ? strLastError
      delay(0.5)
  endcatch
endwhile

Amp1 & Amp2 values are always 10.25 and the volt value is always 26 in the channels and when I do a '? amp1' etc to the command window they are the same.

When I do a '? datain' to the command window I can see the values changing. Lost again but still working on it.

A side question, when I buy the standard or base package is it necessary to purchase a run time license?

Thanks for your help.

Link to comment
Share on other sites

The problem is in your subsetting. Its [start index, end index]. Its inclusive, so [5,9] returns elements 5, 6, 7, 8 and 9. I think you are doing: [start index, number of items], actually I'm pretty sure of it. And since DAQFactory will reverse the ordering if you put the bigger number first, you are basically getting item index 2 through 33 and 2 through 35 for the amps, and 2 through 3 for volts. You want [33,34], [35,36] and [3,4].

No you do not need to buy a runtime. The development version will run your system. Runtimes are for when you want to run on one machine and develop on another and don't want to spend the money on multiple development licenses.

Link to comment
Share on other sites

There's that experience thing going again. :)

Don't know where I got that from in the manual and all is working fine now. Now I'm over in general logging.

Really do appreciate your help in helping me climb up the experience ladder. Once I get fairly comfortable with DF I am going to try and migrate it into our control systems at work as an option.

Randy

Link to comment
Share on other sites

Archived

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