10-21-2013 02:00 PM
Hi All,
Need a bit of direction on this one as I suspect (and hope) it is pretty simple, but I cannot for the life of me figure it out. Not used much in the way of TCP/IP or HTTP protocol before so am a bit out of my comfort zone.
I'm trying to talk to a SoMat eDAQ Lite. There is a command that I can call in a web browser that works perfectly (from the perspective of getting data and displaying it on-screen): http://192.168.100.100:2345/realtime?Rate=10&Headers=0
This returns the data, continuously, to my Chrome window. If I scroll to the bottom I find that new values are being continuously written to the bottom of the page. It is all in a text format.
Now, all I want to do is to replicate this in LabVIEW. This is where I get stuck. I've tried various HTTP and TCP/IP protocol and got more or less errors. I've attached a VI that doesn't work. Any reasons why? I don't get errors until I recieve a timeout error on the TCP/IP read (error 56). If I run it again I get error 60 from the very first VI.
Any help gratefully recieved.
Solved! Go to Solution.
10-22-2013 07:29 AM - edited 10-22-2013 07:31 AM
Looking at the details of the HTTP protocol for the device, you have the following 2 options:
1) Use the HTTP Client VIs to request a fixed amount of data
2) Use the TCP/IP VIs to implement a HTTP protocol that can 'keepalive' the TCP connection to read the data continuously
With Option 1, the HTTP VIs will send a HTTP request and expect a response to be sent followed by the device closing the connection. I think the URL you are providing keeps the TCP connection alive to keep sending data (which is appended continuously to the page) which probably means that the HTTP client VI will keep reading the data until the VI times out. You would need to request a fixed amount of data each time you ran the HTTP VI (e.g. 1 data point) that would be returned within the timeout of the HTTP VI.
I think with Option 2, you would need to implement a basic HTTP request in TCP - similar to what you have done but instead of sending a string that is a URL, you would need to send a properly formatted HTTP GET request header and then in the TCP read you would receive the HTTP response headers followed by your data.
According to Wikipedia...the string should be formatted as follows:
- A request line (e.g. GET /realtime?Rate=10&Headers=0 HTTP/1.1)
- Request headers (maybe not required...but a 'Host: <ip address of device>' line apparently is required as part of the HTTP/1.1 specification)
- An Empty line
- Message body (probably not required...)
If you use the CRLF mode of the TCP read, you should get one read per line of the HTTP headers (which might not be sent by the device - I assume that's what Headers=0 is for) followed by one read per line of data (as you were seeing when accessing it through the browser).
If you use some of the tools in your browser (e.g. in chrome - tools->developer tools->network tab) - you can usually see the raw HTTP data sent/received when you access the URL you provided.
10-22-2013 10:43 AM
I think Sam's second suggestion might be slighly easier to implement, assuming the back and forth protocol to get the streaming going is relatively simple. HTTP is a protocol on top of TCP/IP, so if you can do it in H, you can do it in T.
Have a look at WireShark. It is an open source network packet sniffer. Using it, you can listen in on the communication between the client and server, and see exactly what each side is sending to get the communications going. You can copy and paste in many cases, with little or no modification.
10-22-2013 01:48 PM
Spot on Sam!
I've now got it working. Solution two worked. Just put in 'GET /realtime?Rate=10&Headers=0 HTTP/1.1' followed by two carriage returns and out pops the data.
HOWEVER, I've not got another problem. When I run the code the first time it runs fine. If I stop the VI and then start it again I get an error 60 being thrown: 'The specified port or network address is currently in use. Select an available port or network address.'
Looks like it is not being closed properly even though I have a TCP Close Connection in there. I haven't wired the Abort input on the TCP Close Connection.vi, although the help file says this is for future use.
Any suggestions as to what to do?
10-22-2013 01:54 PM
each time a new connection comes in, you have to increment the port number. Windows (maybe labview) let's it linger for a while, before recycling.
10-22-2013 02:04 PM
There is an example of maintaining a TCP server with one or more connections. It's called Multiple Connection - Server.vi. You can find it in the LabVIEW help examples. As long as you don't stop the VI without closing all references, you should be able to re-use the same port for multiple connections. Is the server the eDAQ?
10-22-2013 02:25 PM - edited 10-22-2013 02:26 PM
I think you can just leave the 'local port' unwired and LabVIEW will assign an unused port itself - the only important one (unless you have some odd firewall rules) is the remote port so you connect to the right endpoint.
Glad to hear it worked out anyway!
10-23-2013 02:48 AM
Works a treat. Thanks everyone for all your help.
08-15-2015 08:10 AM
Hello, do you have a snippet or sample of the vi ? Because I can't seem to get it working 😞
08-15-2015 08:33 AM
Sorry I'm very new to labview, I'm doing something wrong. I got Sam's answer but I don't see where I can limit the stream number.......or how I would do that on labview.