IMPORTANT! The server may go down soon - possibly permanently. Please read the latest post in Announcements and News

FTP is broken. I strongly advise all users using my server for their web site to make alternative arrangements.

Outgoing mail is disabled because of the malware on the server. No new forum registrations are currently possible, and mail to the forum administrator will not work.

Please read the posts in the Announcements section about the current status of Cumulus development now that I have retired

Please read this post before posting

Latest Cumulus release v1.9.4 (build 1099) - Nov 28 2014
Latest Cumulus MX release - v3.0.0 build 3043 Jan 20 2017. See this post for download

Accessing USB data in .NET

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

Accessing USB data in .NET

Postby Siberwulf » Fri Jun 21, 2013 4:10 am

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: 26692
Joined: Mon Jun 02, 2008 6:49 pm
Weather Station: None
Operating System: None
Location: Vienne, France
Contact:

Re: Accessing USB data in .NET

Postby steve » Fri Jun 21, 2013 6:57 am

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 Jun 21, 2013 4:03 am
Weather Station: AW WS2080
Operating System: Windows 8
Location: Dallas

Re: Accessing USB data in .NET

Postby Siberwulf » Sat Jun 22, 2013 4:31 pm

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: 26692
Joined: Mon Jun 02, 2008 6:49 pm
Weather Station: None
Operating System: None
Location: Vienne, France
Contact:

Re: Accessing USB data in .NET

Postby steve » Sat Jun 22, 2013 5:41 pm

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
-----
Hosting available for Cumulus web sites. See http://sandaysoft.com/forum/viewtopic.php?f=2&t=11876

Please read the posts in the Announcements section about the current status of Cumulus development since I have retired from my day job

Siberwulf
Posts: 6
Joined: Fri Jun 21, 2013 4:03 am
Weather Station: AW WS2080
Operating System: Windows 8
Location: Dallas

Re: Accessing USB data in .NET

Postby Siberwulf » Sun Jun 23, 2013 4:33 pm

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: 26692
Joined: Mon Jun 02, 2008 6:49 pm
Weather Station: None
Operating System: None
Location: Vienne, France
Contact:

Re: Accessing USB data in .NET

Postby steve » Sun Jun 23, 2013 4:55 pm

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
-----
Hosting available for Cumulus web sites. See http://sandaysoft.com/forum/viewtopic.php?f=2&t=11876

Please read the posts in the Announcements section about the current status of Cumulus development since I have retired from my day job

Siberwulf
Posts: 6
Joined: Fri Jun 21, 2013 4:03 am
Weather Station: AW WS2080
Operating System: Windows 8
Location: Dallas

Re: Accessing USB data in .NET

Postby Siberwulf » Sun Jun 23, 2013 5:26 pm

You're right. I totally missed that. Geesh. Lemme get digging. :)

Siberwulf
Posts: 6
Joined: Fri Jun 21, 2013 4:03 am
Weather Station: AW WS2080
Operating System: Windows 8
Location: Dallas

Re: Accessing USB data in .NET

Postby Siberwulf » Tue Jul 02, 2013 4:25 am

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: 26692
Joined: Mon Jun 02, 2008 6:49 pm
Weather Station: None
Operating System: None
Location: Vienne, France
Contact:

Re: Accessing USB data in .NET

Postby steve » Tue Jul 02, 2013 7:13 am

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
-----
Hosting available for Cumulus web sites. See http://sandaysoft.com/forum/viewtopic.php?f=2&t=11876

Please read the posts in the Announcements section about the current status of Cumulus development since I have retired from my day job

Siberwulf
Posts: 6
Joined: Fri Jun 21, 2013 4:03 am
Weather Station: AW WS2080
Operating System: Windows 8
Location: Dallas

Re: Accessing USB data in .NET

Postby Siberwulf » Tue Jul 02, 2013 12:35 pm

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();

        }


Return to “Homebuilt”

Who is online

Users browsing this forum: No registered users and 3 guests