Welcome to the Cumulus Support forum.

Latest Cumulus MX V3 release 3.28.6 (build 3283) - 21 March 2024

Cumulus MX V4 beta test release 4.0.0 (build 4017) - 17 March 2024

Legacy Cumulus 1 release v1.9.4 (build 1099) - 28 November 2014 (a patch is available for 1.9.4 build 1099 that extends the date range of drop-down menus to 2030)

Download the Software (Cumulus MX / Cumulus 1 and other related items) from the Wiki

Accessing USB data in .NET

For discussion of DIY weather equipment - sensors, accessories, improvements to existing kit etc
Post Reply
Siberwulf
Posts: 6
Joined: Fri 21 Jun 2013 4:03 am
Weather Station: AW WS2080
Operating System: Windows 8
Location: Dallas

Accessing USB data in .NET

Post by Siberwulf »

I hope this is the right place, but I'm not 100% sure. Please move it to the right place if I'm posting incorrectly.

I'm working on a DIY project where I can program my sprinkler system to actually use my AW WS2080 to help modify my watering schedule. Being in the Dallas area, we're already under stage 3 watering restrictions and I'd like to do my part to keep unnecessary watering down.

I'm trying to pull the real-time data from the weather station via USB and just can't seem to get it to work. I'm using LibUsbDotNet as an interface, rather than cumulus because this is going to be part of a service that feeds into Raspberry Pi and I won't always have a logged-in user to pull data to a simple text file.

Has anyone done this before? I know Cumulus 2 was supposed to be all in .NET, but I can't seem to find it anywhere (looks like it was taken down, as the wiki page is gone).

Any help is greatly appreciated. I'm not looking for someone to write this for me, but just help point me in the right direction. Half the fun of this is going to be writing this. I've been a .NET dev for over 10 years, but have zero experience in peripheral manipulation. :(
User avatar
steve
Cumulus Author
Posts: 26702
Joined: Mon 02 Jun 2008 6:49 pm
Weather Station: None
Operating System: None
Location: Vienne, France
Contact:

Re: Accessing USB data in .NET

Post by steve »

I used HID.net in Cumulus 2 - http://libhidnet.sourceforge.net/

The code to open the device is then something like this:

Code: Select all

IDevice[] stations;
IDevice device;

stations = DeviceFactory.Enumerate(0x1941, 0x8021);

device = stations[0];
and the code to read 32 byte chunks of the memory is something like this:

Code: Select all

byte lowbyte = (byte) (address & 0xFF);
byte highbyte = (byte) (address >> 8);

byte[] request = new byte[] { 0xa1, highbyte, lowbyte, 0x20, 0xa1, highbyte, lowbyte, 0x20 };
byte[] response = new byte[8];

// get the first 8 bytes
response = device.WriteRead(0x00, request);
[do something with the data]

// read the next 3 lots of 8 bytes
for (int i = 0; i < 3; i++)
  {
    device.Read(0, response);
    [do something with the data]
  }
Note that Cumulus will run as a service using (e.g.) SrvAny, but of course that shouldn't deter you from writing your own software.
Siberwulf
Posts: 6
Joined: Fri 21 Jun 2013 4:03 am
Weather Station: AW WS2080
Operating System: Windows 8
Location: Dallas

Re: Accessing USB data in .NET

Post by Siberwulf »

Thanks for the info, Steve. That was super helpful. I have it connecting now and I can read all the basic data from the WS. I'm still trying to figure out how to read stuff above 0xFF, as you the real data starts at 100H, which naturally is 256. That wont' fit in a byte though without an overflow, so I'm still plugging on that one.

Again, thanks for the info! I hope to open source this when I'm done so others can take a peek. :)
User avatar
steve
Cumulus Author
Posts: 26702
Joined: Mon 02 Jun 2008 6:49 pm
Weather Station: None
Operating System: None
Location: Vienne, France
Contact:

Re: Accessing USB data in .NET

Post by steve »

Siberwulf wrote:I'm still trying to figure out how to read stuff above 0xFF, as you the real data starts at 100H, which naturally is 256. That wont' fit in a byte though without an overflow, so I'm still plugging on that one.
You split the address into the low byte and the high byte, as in the code I quoted. Or am I missing something?
Steve
Siberwulf
Posts: 6
Joined: Fri 21 Jun 2013 4:03 am
Weather Station: AW WS2080
Operating System: Windows 8
Location: Dallas

Re: Accessing USB data in .NET

Post by Siberwulf »

Not missing anything. Total brain fart on my part. :)

It's working, with one small caveat. Their documentation on where the *latest* data is stored is a bit lacking, or I'm doing this completely wrong.

I correctly requested data from 0x00 and it looks fine*. The first couple of bytes are what I expect them to be (0x55 and 0xAA).

When I change my query to read from 0x100, I see data, but it doesn't match what I see on the display. I've poked around a little and am really starting to feel like there's something I just don't *get* something a little obvious. :-/

Again, thanks for the help in advance, I'm hoping once I get this functioning, I can shut up and post working code. :)

Code: Select all

 
IDevice[] stations;
IDevice device;

stations = DeviceFactory.Enumerate(0x1941, 0x8021);

device = stations[0];

ushort address = 0x100;

byte lowbyte = (byte)(address & 0xFF);
byte highbyte = (byte)(address >> 8);

byte[] request = new byte[] { 0xa1, highbyte, lowbyte, 0x20, 0xa1, highbyte, lowbyte, 0x20 };
byte[] responselower = new byte[8];
byte[] responseupper = new byte[8];

// get the first 8 bytes
responselower = device.WriteRead(0x00, request);

//get the last 8 bytes
//device.Read(0, responseupper);
* basing my ROM Mapping on http://code.google.com/p/fowsr/download ... 80-cal.doc

PS. This is obviously related to my code, as Cumulus has no issue showing the correct values for everything on the station.
User avatar
steve
Cumulus Author
Posts: 26702
Joined: Mon 02 Jun 2008 6:49 pm
Weather Station: None
Operating System: None
Location: Vienne, France
Contact:

Re: Accessing USB data in .NET

Post by steve »

If you're looking at the 16 bytes of data at 0x100 and expecting that to match the current data, then you've missed the fact that 0x100 is just the start of the data, and the address of the current entry is in the fixed block at 0x1E/0x1F.
Steve
Siberwulf
Posts: 6
Joined: Fri 21 Jun 2013 4:03 am
Weather Station: AW WS2080
Operating System: Windows 8
Location: Dallas

Re: Accessing USB data in .NET

Post by Siberwulf »

You're right. I totally missed that. Geesh. Lemme get digging. :)
Siberwulf
Posts: 6
Joined: Fri 21 Jun 2013 4:03 am
Weather Station: AW WS2080
Operating System: Windows 8
Location: Dallas

Re: Accessing USB data in .NET

Post by Siberwulf »

So this is the part where I start feeling rather... dumb. And it's ok to admit that, right?

I've modified the code and for some reason my array of bytes returned is not correct. It is like this [0,0,0,0,0,19,7,1]

Here's what I've got; a simple "look here, dummy" will do, if you can spare the time! :)

Am I flipping a set of bytes around by accident?

Thanks again in advance.

Code: Select all

  IDevice[] stations;
IDevice device;

stations = DeviceFactory.Enumerate(0x1941, 0x8021);

device = stations[0];

ushort address = BitConverter.ToUInt16(GetLatestAddress(device),0);

byte lowbyte = (byte)(address & 0xFF);
byte highbyte = (byte)(address >> 8);

byte[] request = new byte[] { 0xA1, highbyte, lowbyte, 0x20, 0xA1, highbyte, lowbyte, 0x20 };
byte[] response = new byte[8];

// get the first 8 bytes
response = device.WriteRead(0x00, request);

Code: Select all

private static byte[] GetLatestAddress(IDevice device)
{
     ushort address = 0x1E;

     byte lowbyte = (byte)(address & 0xFF);
     byte highbyte = (byte)(address >> 8);

     byte[] request = new byte[] { 0xa1, highbyte, lowbyte, 0x20, 0xa1, highbyte, lowbyte, 0x20 };
     byte[] response = new byte[8];

     // get the first 8 bytes
     response = device.WriteRead(0x00, request);

     return response.Take(2).ToArray();
}
User avatar
steve
Cumulus Author
Posts: 26702
Joined: Mon 02 Jun 2008 6:49 pm
Weather Station: None
Operating System: None
Location: Vienne, France
Contact:

Re: Accessing USB data in .NET

Post by steve »

I only ever read the data on a 16-byte boundary, so that may be your problem. Also, the station always sends 32 bytes, so I always read off 32 bytes even if I only want the first part. I assume it gets buffered, so if you don't read it all off every time, you may be getting the end of your previous read.
Steve
Siberwulf
Posts: 6
Joined: Fri 21 Jun 2013 4:03 am
Weather Station: AW WS2080
Operating System: Windows 8
Location: Dallas

Re: Accessing USB data in .NET

Post by Siberwulf »

That was exactly what it was. I added in three junk reads and it looks like it's returning the right data. :)

Here's the updated method so others can see. Thanks again!

Code: Select all

 private static byte[] GetLatestAddress(IDevice device)
        {
            ushort address = 0x1E;

            byte lowbyte = (byte)(address & 0xFF);
            byte highbyte = (byte)(address >> 8);

            byte[] request = new byte[] { 0xa1, highbyte, lowbyte, 0x20, 0xa1, highbyte, lowbyte, 0x20 };
            byte[] response = new byte[8];
            byte[] junk = new byte[8];
            // get the first 8 bytes
            response = device.WriteRead(0x00, request);

            device.Read(0, junk);
            device.Read(0, junk);
            device.Read(0, junk);

            return response.Take(2).ToArray();

        }
Post Reply