AAG Weather Station - RS485 version

I have the original Dallas Semiconductor 1-wire weather sensors and have enjoyed playing with them over the years. I decided to try one of the new AAG stations when I learned they had one with an RS485 interface.

As I've read from pwillard and others, and confirmed on my own, AAG are not the most responsive company that one might deal with. They take their own sweet time with delivery and don't give you any progress reports unless you bug the hell out of them. You have to submit a nda to be considered for them sharing the Windows program that apparently talks to their product. Good luck with that. I wasn't that interested anyway since I mainly use OS X but it would have been nice to have something to test the station with before I started writing my own code. I think it's a good deal for $79, otherwise.

After spending some time deciphering the RS485 protocol in the poorly translated .pdf, I was able to communicate through the very nice RS485 to USB adapter that comes with the kit and a terminal program that can send hex as well as ASCII. The manual was originally written in Chinese and then translated into Spanish which was then translated into English. Very entertaining.

Once I was sure I understood the protocol, the first command I gave it was to turn off the terribly annoying flashing array of 35 blue and red LEDs.

Pros:

The enclosure is waterproof unlike the Dallas original and should last pretty well. It contains a light intensity sensor as well as a DS18S20 type temperature sensor and a wind speed and direction capability using Hall effect devices rather than the original reed switches and magnets. The kit come with almost everything you need to set it up including an RS485-USB bridge and all the cables and power supply.

Cons:

No software. You can submit a form for them to consider sending you a Windows program. I haven't heard squat back.
The case is made out of clear plastic instead of the white opaque of the original and the DS1820 is inside of that. The reading I got during the day when our ambient was 105 F was over 140 F. Useful for knowing when to bring it in to keep from burning it up I guess.
It takes 12 VDC and 5 VDC to operate. The RJ45 connector system that is used is not based on any of the current "standards" for RS485.
Since the interface is no longer 1-wire, there is no documented way to add any additional DS18S20s. The protocol "manual" didn't hint at any way to do this. This means that there is no way to add any additional 1-wire sensors. So far they don't offer any RS485 accessories. That's unfortunate because there has evolved a pretty healthy accessory community because of the popularity of the original Dallas kit.

So, not as cool as it could be. The good news is that most of my other weather related sensors are Arduino based so it will be easy to add them to an RS485 network.

I mounted the station on a pole without completely disassembling it first which I will remedy later. From the pinouts on the presumably accurate schematic, they are using an Atmega8 in the TQFP 32 package. There is a programming connector shown on the schematic. If they haven't prevented reprogramming the chip, it should be very easy to reprogram it with a custom Arduino sketch. The only problem I see is the limited code space in an Atmega8. I think there should be room to turn it into a more useful product, though. Failing that, I'm not afraid to solder a different chip onto it as it has the same pinout as a 328.

I would like to solar power the station and give it wifi capability. I'm still waiting for the Xbee wifi development kit to arrive. Since I intend to have it display on a web page rather than an LCD remote, I haven't written very much code for it. Just enough to set the calibration constants and read and display the station data. It provides temperature, wind speed and direction, light intensity, and power supply voltage. There is also an elaborate protocol available for flashing the LEDs in every imaginable way but I haven't done anything with that except turn it off.

I'll post the sketch for anyone who is interested in how I did the RS485 interface. On the hardware side, I just wired the proper voltages to an RJ45 breakout from Sparkfun and used a MAX3486E RS485 driver for the half-duplex connection. I wired the driver and receiver enables together and drive them with a digital pin on the Arduino. I am using the latest SoftwareSerial library at 9600 baud for communication.

As always, any comments or criticisms are welcome.

I have exceeded the character limit for one post so I'll post the code separately.

/*
The returned datapacket from the weather station:
 Index    Data
 0        data length      # of data bytes not including checksum
 1        node #
 4        wind direction
 5        wind speed
 6, 7     temperature
 12       power supply
 13       light intensity
 14       speed cal
 16       check sum
 */

>
#include <PString.h>
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);


uint8_t dataPacket[20];
uint8_t testDataPacket[20] = {
  0x0f, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x53, 0x00, 0x00, 0x00, 0x00, 0x57, 0x76, 0x64, 0x00, 0x92};
uint8_t head[3] = {
  0x2B, 0x77, 0x73}; // "+ws"
uint8_t dataCommand[10] = {
  0x07, 0x00, 0xEB, 0xA1, 0x00, 0x00, 0x00, 0x00};
uint8_t nn; // node number
uint8_t cs; // checksum
uint8_t nodeSetCommand[] = { 
  0x04, 0x00, 0xEB, 0xB3, nn, cs };   // calculate checksum for new node number
uint8_t br; // baud rate 1(2400bps),2(4800bps),3(9600bps),4(19200bps)
uint8_t baudSetCommand[] = {
  0x06, 0x00, 0xEB, 0xB4, br, 0x00, 0x00, cs };
uint8_t dc; //  direction cal 1 - 16, hold vane steady and set dc to number (1-16) corresponding to direction it is pointing
uint8_t dirSetCommand[] = {
  0x04, 0x00, 0xEB, 0xA4, dc, cs };

char* windDirection[16] = {
  "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"}; // index +1 is used for direction cal

bool flag;
//uint8_t *pPointer;
char buffer[20]; // buffer for LCD display line for PString


//**********************************************************
// declarations for software serial for RS485 link. Node address is default 0x00 but can be changed by command. Reply strings from
// weather station have node address 0x01. No explanation.


const uint8_t DD = 10; // data direction pin 10, xmit = HIGH, recv = LOW
const uint8_t RXpin = 2;
const uint8_t TXpin = 3;
SoftwareSerial RS485(RXpin, TXpin);
uint8_t xmit = HIGH;
uint8_t recv = LOW;



//*****************************************************************
// send "+ws" + variable length command string to weather station. Command strings hard coded constants above.

void sendCommand(uint8_t* command){
  digitalWrite(DD, xmit); //set RS485 to transmit
  uint8_t checksum = 0;
  RS485.write(0x2b);
  RS485.write(0x77);
  RS485.write(0x73);// send header

  RS485.write(*command); // send length
  for (uint8_t i=*command++; i>0; i--){ // for length
    checksum += *command;
    RS485.write(*command++); // send command bytes
  }
  RS485.write(checksum);  // send checksum
  digitalWrite(DD, recv); //set RS485 to receive
}


//***********************************************************
// read variable length packet with "+ws" header followed by length byte + "length" bytes + checksum byte. Stored in *packet.
// returns boolean according to success. False if header not found or receive buffer empty too soon.

boolean readPacket(uint8_t* packet){ // fill array *packet from RS485
  digitalWrite(DD, recv); //set RS485 to receive
  int flag = 1;
  while (RS485.available()) { // search for first "+"
    if (RS485.read() == 0x2b) {
      flag = 0;
      break;        
    }
  }
  if (flag) return false; // exhausted receive buffer without finding "+"

  if (RS485.available())  // then look for "w"
    if (RS485.read() == 0x77)
      ;  
    else return false;
  else return false;

  if (RS485.available())  // then look for "s"
    if (RS485.read() == 0x73)
      ;
    else return false;
  else return false;

  if (RS485.available()) 
    *packet =  RS485.read(); // store length byte in packet[0]
  else return false;

  for (byte i = *packet++; i > 0; i--){
    if (RS485.available())
      *packet++ = RS485.read();
    else return false;
  }
  if (RS485.available()){ // read check sum
    *packet = RS485.read();
    return true;
  }
  else return false;
}

//**************************************************************
// Station has DS18S20 1-wire temp chip. 9-bit resolution, 0.5 C per lsb

float stationTemperature(uint8_t* packet){
  int Cdegrees = (*(packet + 6) << 8) + *(packet + 7) ; // signed integer Temperature in packet[6] and packet[7]
  return Cdegrees / 2.0 * 9.0 / 5.0 + 32.0;  
}


void setup() {
  
  delay(250); // for EtherTen reset issue
  pinMode(RXpin, INPUT);
  pinMode(TXpin, OUTPUT);
  pinMode(DD,OUTPUT); // Create a pin to control the RS485 data direction
  digitalWrite(DD, recv); // Set RS485 transceiver to recieve
  Serial.begin(9600);
  RS485.begin(9600); // Create an instance of SoftwareSerial named "RS485"
  PString str(buffer, sizeof(buffer)); // string to hold LCD line
  lcd.begin(16,2); // 16x2 LCD display

  str.begin();
  lcd.setCursor(0,0); // LCD cursor to col 1 row 1
  str.print("WS Temp "); // internal weather station temperature
  str.print(stationTemperature(testDataPacket), 1);
  str.print(223,BYTE); // 223 is the degree symbol           
  str.print("F");
  lcd.print(str);

  str.begin();
  lcd.setCursor(0,1); // LCD cursor to col 1 row 2
  str.print("Wind ");
  str.print(windDirection[testDataPacket[4]-1]);
  str.print(" ");
  float windSpeed = testDataPacket[5] * 2.453; // mph
  if (windSpeed < 10) str.print(windSpeed,1);
  else str.print(windSpeed,0);
  str.print(" mph");
  lcd.print(str);

}



void loop() {
  /*  sendCommand(dataCommand);
   delay(100); // necessary at 9600 baud!
   
   
   if (readPacket(dataPacket)){ // read data into dataPacket
   Serial.print(stationTemperature(dataPacket), 2);
   Serial.println(" Degrees F");
   
   Serial.print("Wind direction is ");
   Serial.print(windDirection[dataPacket[4]-1]);
   Serial.print(" at ");
   float windSpeed = dataPacket[5] * 2.453; // mph
   Serial.print(windSpeed,2);
   Serial.println(" mph");
   
   Serial.print("Power Supply is ");
   Serial.print(dataPacket[12] / 255.0 * 5.0 * 4.33, 2);
   Serial.println(" Volts DC");
   
   Serial.print("Light Intensity is ");
   Serial.print(dataPacket[13] / 255.0 * 100, 2);
   Serial.println("%");
   }
   else Serial.println(" Major Failure!");
   delay(2000);
   */
}

It's a nice looking device, but why the heck did they make it clear? It was 121F here yesterday and that thing would have roasted if I had put it up on my roof where the temp exceeded 135F (I have a couple of solar heaters up there so I watch it). Also, what the heck are the LEDs for? Do they show wind direction or something? Or, is it just to annoy the neighbors?

At any rate, it might be nice to use something like this because they have at least done the mounting and waterproofing for me. I worry about the heat in my neck of the woods though. Do you think this thing will melt? Or, maybe it would die in some other fashion. The wiring on my roof has to be protected with foil tape to keep the insulation from falling off. Yes, even the teflon insulation goes bad over a couple of years.

Interesting though how they split the line off to various devices. I couldn't tell for sure, did you get all the pieces, or do you have to buy the temperature/humidity, barometer and rain gauge separately?

I totally agree with you though, I would have turned the lights off first thing.

draythomp:
Also, what the heck are the LEDs for? Do they show wind direction or something? Or, is it just to annoy the neighbors?

Yes. To annoy the neighbors. :stuck_out_tongue: They are independently controllable; out of the box they just alternate blinking (red, blue, both). Perhaps intended as a warning to passing Zeppelins.

It's a very ...quirky device. Those LEDs are really, seriously bright, and AFAIK serve no practical purpose whatsoever. I've got the 1-Wire variant of this station and the first thing I did was to harvest those LEDs for other projects.

draythomp:
Interesting though how they split the line off to various devices. I couldn't tell for sure, did you get all the pieces, or do you have to buy the temperature/humidity, barometer and rain gauge separately?

The device has temperature, light level, anemometer and wind direction built in. Other functions need to be added on. I have a UV level detector and rain gauge on the roof, humidity and pressure under the eaves. This is utterly painless to add with 1-Wire, would be interested in hearing if it's as straightforward with the RS485 variant.

Oh, and AAG's insistence upon NDA for software for this device is utterly ridiculous. This is not exactly a novel application of the components being used, and it really doesn't take a whole lot to reverse engineer the whole device. They should really just release a GPL'ed version of a library that provides basic usage examples and let the community flesh it out.

BTW, their Windows-only software for the device is crap. Don't bother.

And for the sake of completeness: The RJ45 wiring for the AAG 1-Wire adapter does not match that used by other vendors. You will probabl fry your other 1-Wire components if you plug them directly into an AAG adapter; I documented a fix for this on my blog: Coming Soon

draythomp:
At any rate, it might be nice to use something like this because they have at least done the mounting and waterproofing for me. I worry about the heat in my neck of the woods though. Do you think this thing will melt? Or, maybe it would die in some other fashion. The wiring on my roof has to be protected with foil tape to keep the insulation from falling off. Yes, even the teflon insulation goes bad over a couple of years.

It seems to be well made. I'm concerned about the lubrication of the bearings at that temperature. Clear was a dumb color.

buzzdavidson:
The device has temperature, light level, anemometer and wind direction built in. Other functions need to be added on. I have a UV level detector and rain gauge on the roof, humidity and pressure under the eaves. This is utterly painless to add with 1-Wire, would be interested in hearing if it's as straightforward with the RS485 variant.

Adding RS485 accessories will be easy for the hobbiest who can do their own designs. I don't know of any company that makes them for the AAG though. They don't do addressing like standard RS485 so I'll have to design my slaves to use their protocol.

buzzdavidson:
Oh, and AAG's insistence upon NDA for software for this device is utterly ridiculous. This is not exactly a novel application of the components being used, and it really doesn't take a whole lot to reverse engineer the whole device. They should really just release a GPL'ed version of a library that provides basic usage examples and let the community flesh it out.

BTW, their Windows-only software for the device is crap. Don't bother.

And for the sake of completeness: The RJ45 wiring for the AAG 1-Wire adapter does not match that used by other vendors. You will probabl fry your other 1-Wire components if you plug them directly into an AAG adapter; I documented a fix for this on my blog: Coming Soon

I think the best thing to do is just re-flash the thing. Hopefully they haven't set the fuses so that can't be accomplished. That would be pretty dumb for them since it would prevent any future firmware updates.

I agree, they should publish the source code with a GPL. Since it's Atmega based, they would have a large community who could program for it and an add-on sensor market would be possible. I don't think they have a business model. Since everything is their own proprietary wiring and protocol, they must think they are going to have accessories for it.

Buzz, it sounds like you've had yours apart. I think mine is held together by two tiny screws but I won't know until I bring it down. I've got it mounted on a section of 2" PVC pipe, my favorite construction material, light and cheap. :slight_smile: Any hints you have for disassembly would be appreciated.

I have a question about repurposing the hardware. It has a programming connector shown on the schematic. Should I try to program a boot loader into it from the Arduino IDE? Is their a way to find out what the fuses are set to without doing that? I'm not knowledgeable about programming this chip down at the fuse level.

I assume their is no way to get the object code out of it to a file. Once I erase the factory code, it will be a brick until I can reprogram it. That doesn't scare me because if the published schematic is correct, it will be very straightforward to get it working again. Once those tacky LEDs are removed, that'll free up half a dozen pins as well :).

The schematic shows MISO, MOSI, SCK, RESET, and GROUND brought out to a header. If I'm not mistaken, I can use an Arduino to program a new boot loader in directly from the IDE? Is the only bad thing that will happen is it won't work?

Should I move this question to the forum on device hacking?

Did a little sleuthing on the "patent" number from the schematic diagram. There is a Chinese patent on the the device. Now from what I know about Chinese patents, they only have force of law in China because they are sometimes duplicates of existing inventions from other countries and they really only intend to prevent the Chinese from ripping off each other. At any rate, the Google translation of the patent abstract:

The invention discloses a number of wind direction with LED lighting anemometer, including base, shaft, the wind cups, weather vane, the Hall sensor circuit board, its features are: light base for the whole cylindrical base, horizontal base wall with link ports, two correspond to the vertical shaft mounted on the base with its corresponding, respectively, within the solid end of the first magnet with the Hall sensor, Hall sensor circuit within the two axes in the base set between the circuit board, circuit board on the bottom with double color LED lamp array, the two sets of shaft and base on the upper and lower ends of the first equipped with the semi-opaque frosted processed by the superstructure and under cover, equipped with waterproof seals at the wind cups, weather vane were mounted on two solid outer end of the shaft head. The utility model structure is simple and there are single-chip processing system, digital, intelligent, network functions, double color LED lamp array with a warning and decorative effect.

I mention this because I think it is ironic to see what has become of the original Dallas Semi weather station.

Interesting point about the Chinese patents on the device. I've purchased several commercial Chinese products over the last year that actually ship with keygen/crack applications for Windows programs. Interesting, as these are not one-off products - they are mass produced devices with a reasonable amount of production cost behind them.

Good thing they have the weather station patented though, because, you know, they really need to protect their intellectual property :stuck_out_tongue:

EmilyJane:
Buzz, it sounds like you've had yours apart. I think mine is held together by two tiny screws but I won't know until I bring it down. I've got it mounted on a section of 2" PVC pipe, my favorite construction material, light and cheap. :slight_smile: Any hints you have for disassembly would be appreciated.

The device is held together by two tiny set screws and friction. Pretty easy to get in to,

Out of curiosity, what benefit does RS485 provide in this application?

Thanks, I thought that was what I saw before i put it up.

Out of curiosity, what benefit does RS485 provide in this application?

The only advantage I can think of the way AAG have implemented it is cable length. You can run RS485 several thousand feet without problems. Otherwise it's no advantage at all. AAG have made it impossible to use RS485's slave addressing capability through the implementation of their own proprietary communication protocol. They also have not provided any mechanism to add 1-wire devices to their internal 1-wire buss. Or, at least they have not documented it in their protocol .pdf. It would have been easy for them to have added a means to control a 1-wire buss from the RS485 interface.

If I can reprogram it, I can fix all of that. :slight_smile:

EmilyJane:
Should I try to program a boot loader into it from the Arduino IDE?

Yes. But, what is connected to RX and TX? A bootloader is only going to work if those two are not used and you have a way to connect to them.

Is their a way to find out what the fuses are set to without doing that?

Yes. AVRDUDE with just a dash-v (-v) command reads and outputs the fuse settings.

I assume their is no way to get the object code out of it to a file.

There is (unless they set the fuses so you can't). The protocol allows writing and reading the processor's memory.

The schematic shows MISO, MOSI, SCK, RESET, and GROUND brought out to a header. If I'm not mistaken, I can use an Arduino to program a new boot loader in directly from the IDE?

Yes. I suggest using "MegaISP" instead of "ArduinoISP"...
http://code.google.com/p/mega-isp/

They have a common heritage. The biggest difference is the ability to read / write the EEPROM (which you may also want to backup).

Is the only bad thing that will happen is it won't work?

It will work. For the past few months, that's the only method I've been using to reprogram processors. The only price to pay is a bit of text-file editing.

Should I move this question to the forum on device hacking?

Good idea. But, I promise, you won't get in trouble if you don't. The moderators are fairly laid-back.

Yes. But, what is connected to RX and TX? A bootloader is only going to work if those two are not used and you have a way to connect to them.

There is an RS485 tranceiver chip (ISL81487L) connected to RX and TX. The transceiver's enable pins are connected to INT0/PD2. I haven't disassembled the thing yet but I'm sure I'll be able to graft a couple of wires to RX and TX. If I pull the transceiver enables HIGH, the receiver output goes hi-z. The Atmega should power up with INT0/PD2 as an input so I should be able to isolate RX and TX with just a pull-up resistor. Correct so far?

The rest looks encouraging. Thanks for the tips. I'll check out MegaISP.

Quote:
Should I move this question to the forum on device hacking?

Good idea. But, I promise, you won't get in trouble if you don't. The moderators are fairly laid-back.

That's what I've heard. :slight_smile:

Do you have an RS-485 converter for the host computer?

Yes, it came with one. What will that do for me re: programming? Wouldn't the bootloader need to know how to control the data direction?

At least to start, I suggest using the Arduino to perform all programming (no bootloader / only ISP) and the serial / RS-485 for debugging. You will be able to leave a terminal application running while you upload a new program (which is very nice).

So, that means that whatever I program into the chip will have to support controlling the RS485 transceiver if I understand you correctly.

I doubt you can use the RS485 as (I assume) it's half duplex and the standard bootloaders won't like that.

Hacking into the RO and DI lines should work though if you disable the 485 receiver as you said.

If I pull the transceiver enables HIGH,

A PU resistor should do the trick here.


Rob

Okay, sounds like a project! Tomorrow, I'll take a closer look at the circuit board and get started. Thanks for the advice so far!

Yes. The benefit is that you will very quickly have reliable code for communicating with your weather station. The drawback is that you have to start with the communications code and that you have to have your Arduino handy so it can act as a programmer.

I think Serial could be fairly easily sub-classed to include the necessary support for transmitting.