Programming Serial Ports

Joined
May 1, 2004
Messages
3,417
Location
Springfield, IL
Hey gang,

I have an Inspeed Vortex wind gauge that is connected to my computer via an RS232 serial cable. The gauge sends pulses on the 4 and 6 pins of the serial connector and the software I have for it counts these pulses. I'm writing my own software as part of a custom made weather station and wanted to incorporate this gauge. Does anyone know how to get these pulses pro grammatically? I'm using .Net but will take any Windows advice. The .Net SerialPort class is mainly for reading bytes and strings that transmitted digitally, and apparently this wind gauge doesn't send any digital information, just pulses. I get nothing back when I use any of the Read functions. Any ideas on how to read these pulses would be greatly appreciated.
 
Sounds like you may need a A/D converter in front of the serial port. Do you have the spec sheet on signal you are trying to read? Looked at it on a scope yet?
 
Hmm, that spec isn't very helpful is it? I guess my next step would be to put it on a scope and see what the output really is and then take a look at how the .net class would see that output. Sorry, not very helpful, but that would be my next step.
 
Yea, it's unclear what sort of data the unit is sending.
Is it streaming standard serial packets, toggling the port at a variable rate, varying the duty cycle, or???

Got an O-scope?

If not, write a loop that polls the port and displays it's state, then give the anemometer a spin to observe any change in the data. (Assuming .net programming allows direct serial port access.)
 
It sounds like there is a magnetic read switch in the anemometer. It switches once every revolution of the cups. I wrote a program back in the mid 80's for the Commodore64 that read data like that and plotted the windspeed on a pen plotter. I wrote an interrupt that counted the pulses every second and calculated the windspeed.
 
Good ideas...

I don't have a scope. I've tried polling all the boolean properties on that serial port class in a loop and none of them appear to be changing. But maybe there is a state property in there that I can try. I thought about switching to a Commodore64, but smoothing probably wouldn't work in GR. ;)
 
Use the WaitCommEvent Windows API to monitor changes in the DSR line (pin 6):

http://msdn.microsoft.com/en-us/library/aa363479(VS.85).aspx

There's probably a .NET equivalent. Also, since they use pin 4 (DTR), you'll probably need to set that line in order to start communication (set DCB.fDtrControl to DTR_CONTROL_ENABLE in your SetCommState call).

I'd fire off a separate thread to handle the COM stuff. I imagine the WaitCommEvent() call will return frequently, so sit in a small loop that waits for the DSR event, increments a counter, then loops back to WaitCommEvent. Have the main thread check the counter occasionally to see how fast the pulses are arriving.


Edit: actually, looks like the .NET serial stuff is fairly easy. Setup the SerialPort object (and enable DTR) then set the PinChanged event handler:

http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.pinchanged.aspx



Mike
 
Last edited by a moderator:
As others have mentioned above there is probably a hall effect sensor on the thing running off 5V I would guess. It is most likely an analog signal and I doubt .net is going to be very happy with it if you don't know the specs it is using. You could probably figure it out with a cheap multimeter if you don't have a decent bench scope.

Sorry you are so far away, or I would volunteer my gear for you to test it on.
 
Edit: actually, looks like the .NET serial stuff is fairly easy. Setup the SerialPort object (and enable DTR) then set the PinChanged event handler:

Brilliant! I had hooked into that event in earlier attempts and it was never being fired, but I had not set the DtrEnable property to true.

I also tried an example that uses the WaitCommEvent function you suggested but it kept returning back a IO OPERATION PENDING error 997 message. But this event will definitely work, as it fires twice for each rotation of the cups. I'll just increment a counter like you suggested.

Thanks all for the help.
 
Brilliant! I had hooked into that event in earlier attempts and it was never being fired, but I had not set the DtrEnable property to true.

I also tried an example that uses the WaitCommEvent function you suggested but it kept returning back a IO OPERATION PENDING error 997 message. But this event will definitely work, as it fires twice for each rotation of the cups. I'll just increment a counter like you suggested.

Thanks all for the help.
Be prepared for more frustration with the Comm APIs! There are many interactions in the Comm functions and they aren't documented well. Your error 997 would probably go away if you ClearCommError() at the beginning.

I wrote an x86 asm commercial library back in the 1980s that included full comm port support for DOS apps -- the target was Lahey Fortran. Supported the 8250, 16450, and 16550. So, when it came to adding GPS support to GRx I thought the least of my worries would be handling simple serial port IO. I was wrong!

One final thought, while a simple "counter++" in your PinChanged code would work fine on a single core computer, you should should go ahead and place a CriticalSection (or whatever .net calls its lightweight thread synchronization technique) around access to your counter variable. Also, define the counter variable as "volatile" so that the optimizer doesn't move the increment and retrieval code outside the EnterCriticalSection and LeaveCriticalSection calls.

Mike
 
Not to threadjack, but for those reading this thread who are interested in learning the INs and OUTs of programming and reading data from weather instruments, I highly recommend Weather Toys: Building and Hacking Your Own 1-Wire Weather Station. I've got the book, but none of the hardware yet. However, it is a great introduction to grabbing the data and the foundation software is provided. Reviewers of the book say it is worth it for the introduction to Java it provides, alone. Learning is more fun when you have a specific goal in mind, as with Skip's problem here. There is a great associated discussion board and companion web site. One benefit of the Weather Toys approach is that it is modular (you can start simple with a temperature gauge and add on later) and (although I'm not a big fan of the Java programming language) you have to admit is nice to be able to run the software on any platform (Windows, Mac, or Linux).
 
What about reading the data the original software is writing to disk?

While I am not a programmer, I own a software development company and employ several .Net programmers. We constantly need to incorporate data from instruments and robots. When we can not get at the data directly as you are attempting, there is usually another way to get the data indirectly (see below). Just a thought. Good luck.

This from the URL you posted for your weather station.
"DATA FILES The data stored includes the current speed, the max and min during the previous storage interval, and the average over the interval selected. It is stored in ASCII format such that it can be read by virtually any graphing software. An example is shown here where the storage interval was one minute. Stopping and starting the program APPENDS the new data and does NOT overwrite existing data. "
 
I've already written software for the Inspeed anemometer with Python using wxWindows. It runs on Linux and Windows for sure, not sure about OSX though I'm sure it would work. The hardest part for me was that I was actually actively sampling the port, rather than using events. This allowed me to create my own mins and maxes for capability. In going this route I'm only limited by the amount of CPU I want to take up.

I'm not sure if it would be possible to get this code to work with something like IronPython, but it might be a possibility. I'm not a fan of developing for a single platform, like .NET, but I'll gladly offer any help I can.
 
Back
Top