-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Driver error in syslog #1
Comments
Nevermind a reboot of the system fixed that. |
Hi! I am glad that the driver is working for you. I never thought someone
else besides me would find it useful since this Weather Station is so old
but I am glad you are using it. My system has been running with that driver
without issues for a few months now, let me know if you find any bugs.
FYI, I have code in the driver that allows you to enter the calibration
values into the station but I haven't had the time to implement that in weewx,
I might do that in the near future. That might be useful, for example, if
you have a different rain bucket size that the default one in the US
(0.01").
This is what the manual says:
-----------------------------------------
Default CAL = 100 (for 0.01" rain collector).
If you have a 0.2 mm rain collector, you must change the calibration
number. First adjust the console to display rainfall in millimeters and
then change CAL to 0005. (For instructions on how to change CAL, see
“Changing Calibration Numbers” below). Be aware that the console will
revert to its default calibration (i.e., inches) if it loses power.
------------------------------------------
Right now the rain calibration number is hard coded into the driver (100),
so if your rain bucket is the metric one (0.2 mm rain collector) you would
have to change that in the driver itself, on line 123: self.rncal = 100
Jardi.
…On Sun, Mar 17, 2019 at 8:02 AM Peter Stevenson ***@***.***> wrote:
Closed #1 <#1>.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#1 (comment)>, or mute the
thread
<https://github.com/notifications/unsubscribe-auth/ABCc3MwJ1_6V93RzW5LcOOhffYR8Nf3Oks5vXlkjgaJpZM4b4a0g>
.
|
Thanks for the tips on calibration. I need to investigate this warning message: I have two of these weather stations and there is hardly any software that supports them besides the expensive and old Davis software. So it's awesome to make better use of a still very accurate peice of hardware. Thanks for your driver. |
Which Station do you have? My Weather Monitor II returns the humidity as a
percentage already so I there is no calculation done in the driver, I am
attaching the file with the Technical Reference that I used to write the
driver. No all the stations report the same values nor in the same order,
so look in the file for the structure of the LOOP packets that you station
returns when you send a LOOP command.
Let me know if I can be of any further assistance, and if you make
modifications to support your station I would like to see if I can
incorporate that in the current driver so someone else might benefit from
it.
Jardi.
On Sun, Mar 17, 2019 at 1:30 PM Peter Stevenson ***@***.***> wrote:
Thanks for the tips on calibration. I need to investigate this warning
message: Mar 17 20:28:35 weewx weewx[363]: engine: 2019-03-17 20:28:34
GMT (1552854514) LOOP value 'outHumidity' 141 outside limits (0.0, 100.0).
I suspect it's some simple math that needs changing in the code that
converts the value into a %.
I have two of these weather stations and there is hardly any software that
supports them besides the expensive and old Davis software. So it's awesome
to make better use of a still very accurate peice of hardware.
Thanks for your driver.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#1 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ABCc3GVEAYzTlY-DwCW79WJeouuwIsdxks5vXqYBgaJpZM4b4a0g>
.
2/11/98 4:52 PM 48
Monitor, Wizard, Perception
GroWeather, Energy, & Health
WeatherLink Protocol 02-11-98
Rev 3.3
Table of Contents:
I. Introduction
II. Definitions
III. Pseudo code description of WeatherLink command processing loop.
IV. Code illustration of the Communication functions used in the examples.
V. Link Types and Revision Levels
VI. Command Description
VII. Command Summary
VIII. Illustrated Examples
A. Reading Calibrated Data
1. Temperature CAL
2. Humidity CAL
3. Barometer
4. Rain
5. Wind Speed
6. Rain Rate
7. UV MED's
B. Using the LOOP command
C. Using MDMP command
D. Invalid Data values
E. Calculated Data values
1. Wind Chill
2. Dew Point
3. Temperature-Humidity Index
4. THSWI
5. Wind Run
6. Degree-Days
7. Solar Energy
8. UV Dose
9. Rain Rate
F. CRC Checking
G. Reading Hi/Low Times and Dates
IX. Memory addresses.
A. Monitor, Wizard, and Perception Station
B. Monitor, Wizard, and Perception Link
C. GroWeather Station
D. GroWeather Link
E. Energy Station
F. Energy Link
G. Health Station
H. Health Link
Appendices (Contained in "appendix.txt")
A Bar/Power Bit definitions
B Control Module communication status codes (AOM Status)
C Model Numbers
D Power Voltage Codes
E THSWI Latitude Codes
F Wind Direction Sector Codes
G1 GroWeather Alarm Bits
G2 ET Status bits
G3 Leaf Wetness Data/Status byte in the LOOP packet.
E1 Energy Alarm Bits
H1 Health Alarm Bits
I. Introduction
This document is a technical description of the software
interface to both the Standard WeatherLink, which can connect to
the Monitor, Wizard, and Perception models, and the GroWeather
WeatherLink, the Energy WeatherLink, and the Health WeatherLink.
The WeatherLink interprets commands sent by a PC over an RS232C
serial link (8 bits, 1 stop bit, no parity). The commands are a
combination of ASCII and binary data. The command structure and
format are almost identical for the 4 kinds of WeatherLink, but
the available data and their locations are different.
The diagram below illustrates the relationship between the
PC, WeatherLink, and Weather Station. The sensor image, archive
image, and the archive memory belong to the WeatherLink. As
shown in the diagram the PC sends commands and receives data from
the WeatherLink. The WeatherLink sends commands and receives
data from the Weather Station. Data is contained in both the
WeatherLink and the Weather Station. You will notice you can
read data from the WeatherLink faster than the Weather Station.
Therefore, if the data exists in the WeatherLink and is being
updated fast enough for your purposes, read it from the
WeatherLink. Study the "Command Processing Loop" carefully to
understand what is in the WeatherLink and when it is updated.
"RRD" commands read from the WeatherLink. "WRD" commands read
from the Weather Station. The addresses of the data available in
the WeatherLink and the Weather Station are given in section IX.
cmds cmds (Monitor Station)
PC -> Weather -> Weather Station (Wizard Station)
Link (Perception Station)
data data (GroWeather)
<- . <- (Energy Station)
. (Health Station)
.
sensor image
archive image
archive memory
The Appendices, in the separate file "appendix.txt", contain
descriptions of coded numerical values and Bit definitions.
Please note Davis Instruments is not responsible for any
damages your use of this information may cause. Furthermore, we
reserve the right to modify our designs without notice.
II. Definitions
station processor memory - 256 bytes of memory directly
accessible by the station processor, organized into 2
banks of 256 nibbles.
link processor memory - 256 bytes of memory directly
accessible by the link processor, organized into 2
banks of 256 nibbles.
archive memory - 32K of memory where weather data is stored
before downloading to PC.
sensor image - Memory containing the latest data from the
weather station. Part of the link processor memory
archive image - Memory where archive entries are assembled
before being written to the archive memory. Part of the
link processor memory
III. Pseudo code description of WeatherLink command processing loop.
All references to Inside temperature apply to Soil temperature
on the GroWeather station.
Items marked (G) are only applicable to the GroWeather station
(E) are only applicable to the Energy Station
(H) are only applicable to the Health Station
(O) are only applicable to the Monitor, Wizard, & Perception
(N) are only applicable to the GroWeather, Energy, & Health
// Initialize the Link chip memory
Set archive interval to be 30 minutes.
Set sample interval to be 20 seconds.
Test archive memory.
If (memory test passes)
Do a beep on the weather station.
/*
Wind speed and wind direction are read and stored in the
sensor image each time around the loop. Temperature is
read once for every ten wind speed readings. Humidity,
Barometer, and Rain are updated every time the sensor image
is updated.
*/
while (1) // beginning of command processing loop
GetWindSpeed ();
Test for new Gust Value;
GetWindDirection ();
For every 10 wind speed reads {
read Inside and Outside temperature;
Read Rain Rate (N)
read Solar Rad (N)
read UV Intensity (H)
read Alarm and Control-Module communication status (N)
Check current Outside Temp for new Hi/Low in this period
And record in archive image.
Check for new Hi Rain Rate (N)
Check for new Hi Solar Rad (H)
Check for new Hi UV Intensity (H)
}
if (in loop mode)
Transmit copy of sensor image.
if (time to sample sensor image) Sample sensor image:
Add current data values for variables that are averaged:
Inside & Outside Temperature
Wind Speed
Solar Radiation (N)
UV Intensity (H)
If wind speed is > wind threshold (0), then add one to the
direction bin corresponding to the current wind direction
Read other values not read in above: (GetRBH)
read Rain
read Barometer
read outside Humidity
read inside Humidity (H) (O)
read Wind Run (G) (E)
read Total ET (G)
read Total Growing Degree-Days (G)
read Total Heating, Chill, Cooling, & THI Degree-Days (E)
read Total Solar Energy (G) (E)
read Bar and Power status bits (N)
read Leaf Wetness value (G)
read Rain Cal (N)
Every 18 seconds
collect data from the ET Sensors to calculate hourly ET (G)
if ( Time to check archive clock ) // Every 16 seconds.
{
Call GetRBH as above (N)
if (it is time to calculate ET) (G)
calculate ET and store in archive Image (G)
if (lastArchiveTime - currentTime >= archiveInterval)
{
// Make sure the sensor image is up to date.
Call GetRBH as above (O)
// Fill in the archive image before archiving
// Hi and Low Outside temps are already set (see above)
// The following reads are stored in the sensor image.
Read current barometric pressure.
Read current outside humidity.
Read the current Leaf Wetness Value (G)
Read current inside humidity. (H) (O)
// The following are incremental values derived from the
difference between the current value and the previous
value
Calculate rain in period.
Calculate Wind Run in Period (G) (E)
Calculate Growing Degree Days in period (G)
Calculate Heating Degree Days in period (E)
Calculate Wind Chill Degree Days in period (E)
Calculate Cooling Degree Days in period (E)
Calculate Temp-Hum-Index Degree Days in period (E)
Calculate Solar energy in Period (G) (E)
Calculate UV Dose in period (H)
// The following are average values are derived by
dividing an accumulator by the number of samples taken
Calculate average Inside temperature for period.
Calculate average Outside temperature for period.
Calculate average wind speed for period.
Calculate Average Solar Rad for period. (N)
Calculate Average UV Intensity (H)
Calculate dominant wind direction for period
Finally, read the primary power voltage code from the station (G) (E)
Write data to archive memory.
Update last archive time:
(O) Set the "last time" to the current station time
(N) set the "last time" so that the next archive happens on the hour
Clear Hi/Low entries in Archive image
Clear Accumulators and sample count
Set the "Previous" registers to the current values
Reset ET data to FFFF (G)
} // create archive record
} // 16 second polling
if (A command is available)
Process the command.
} // End while (1)...
IV. Code illustration of the Communication functions used in the examples.
The functions "put_serial_char()", "put_serial_string()",
"send_unsigned()", "get_serial_char()" "get_acknowledge()",
"fill_buffer()", and "fill_crc_buffer()" are used in the examples
in the next sections to send commands and data to the
WeatherLink. You must provide these functions. The illustrations
given here are for reference.
All of the example code included with this programmer's
reference disk assumes that the "int" data type is a 16 bit (2
byte) signed number. On some machines you may be required to use
the "short int" data type. In most cases, the "char" data type is
explicitly stated as being unsigned. In a few places (i.e. Hum
Cal on GroWeather, etc.) a one byte number needs to be treated as
a signed value.
"receive_buffer" is an external (global) array of unsigned
char that is at least 32K in length (the size of the SRAM).
/* +----------------------------------------------------------+
Output a character to current serial port.
*/
int put_serial_char (unsigned char c)
{
// write character c to the current serial port
}
/* +-------------------------------------------------------------+
Output a string to current serial port.
*/
int put_serial_string (char *s)
{
int i;
for (i = 0; s [i] != '\0'; i++)
put_serial_char (s [i]);
}
/* +-------------------------------------------------------------+
Outputs the unsigned integer (16 bits) to the current
serial port. assumes "Intel" least significant byte first.
*/
int send_unsigned (unsigned d)
{
unsigned char *cp;
cp = (unsigned char *) &d;
put_serial_char (*cp); // Low order byte
put_serial_char (*(cp+1)); // Hi order byte
}
/* +-------------------------------------------------------------+
Read a character from the current serial port.
*/
int get_serial_char ()
{
int c
// read a character from the current serial port and assign it to c
// If there has been a timeout or some other error, set c to a negative
// value that indicates the type of error
return c;
}
/* +-------------------------------------------------------------+
anticipates an ACK to verify that the link has understood
the command it has just received. If the character received
is not ACK, or there has been some serial error (i.e. timeout),
return an error value, otherwise return OK
*/
int get_ acknowledge ()
{
int c
c = get_serial_char();
if (c == ACK)
return OK;
else if (c < 0) // serial error
return serial_error_code;
else // did not receive ACK
return c
}
/* +------------------------------------------------------------------+
Read a series of bytes from the current serial port and store them in
the receive buffer.
*/
int fill_buffer (int n)
{
int i;
for (i=0; i<n; i++)
{
c = get_serial_char();
if (c >= 0)
recieve_buffer[i] = c;
else
// there has been an error getting the next character
return serial_error_code;
}
return OK; // we have read in n bytes
}
/* +------------------------------------------------------------------+
Read a series of bytes from the current serial port, perform a CRC
check on the data, and store them in the receive buffer.
*/
int fill_crc_buffer (int n) // n includes the CRC bytes
{
int i;
int crc = 0; // initialize the CRC checksum to 0
for (i=0; i<n; i++)
{
c = get_serial_char();
if (c >= 0)
{
recieve_buffer[i] = c; // Store the data
crc = crc_table [(crc >> 8) ^ c] ^ (crc << 8);
}
else
// there has been an error getting the next character
return serial_error_code;
}
if (crc == 0)
return OK; // we have read in n bytes and the CRC is OK
else
return CRC_ERROR; // The CRC check failed.
}
V. Link Types and Revision Levels
WeatherLink hardware modules can be classified by the
station model they are intended for, and by revision level.
There is one link type for the Monitor, Wizard, and
Perception stations. The WeatherLink logs all the sensors for
each of these stations, Any sensor or calculated value that the
station does not support will be filled with the appropriate
Invalid Data value (see below).
The GroWeather, Energy, and Health stations are substatialy
different from each other, both in the sensors supported, and in
the types of calculated values. The corresponding Links are
therefore also different. The primary difference, from the
programmer's viewpoint, is the memory locations of the desired
data which can be found in the corresponding memory address table
below.
There are 3 different revision levels of WeatherLink
modules. These represent changes and upgrades made over the life
of the product.
The Rev C (and earlier) level is only used for
Monitor/Wizard/ Perception Links. This version does not support
the use of SR modems for communicating with the PC at distances
greater than 50 feet
The only difference between Monitor Links made at Rev D and
Rev C is that the Rev D WeatherLinks support the use of SR
modems. The GroWeather, Energy, and Health Links are also
manufactured at the Rev D level.
The Rev E Link implements a slightly different
communication protocol between it and the PC to provide greater
communication reliability. This consists, primarily, of extra CRC
information that must be provided by the PC so that the
WeatherLink can verify every command. Also, ALL data returned by
the WeatherLink has a CRC code included, not just LOOP, MDMP, and
SRD data. This means that the Rev E link is software incompatible
with previous versions. The actual commands used to program a
Rev E link, however, are the same as the corresponding Rev D
link. Two additional commands are added to allow Rev E links to
operate with the Rev D communication protocol ("Rev D Emulation
Mode").
In addition, the GroWeather and Energy versions of the Rev
E link implements a simple powersavings procedure with the AOM
for use with solar powered radio installations.
At this time only the GroWeather link is available in Rev E
versions. Contact Davis' technical support at
support@davisnet.com for information on getting Energy or Health
versions of the Rev E link if required.
Most of the included software examples assume you are NOT
using a Rev E WeatherLink. Please read the "CRC Checking"
(section VIII-F) for information on how to generate the necessary
CRC codes. Or, read the description of the "CRC0" command for how
to disable CRC command checking.
VI. Command Description
Commands must be in upper case and terminated with a
carriage return (0dh). Do not insert spaces between binary data
arguments. If an argument description uses the character '|' then
one byte of data is to be formed from the 4 bit values on either
side. For example: "bank | n-1" becomes the single byte "0x13"
where bank = 1 and n = 4
Rev E links must also include a two byte CRC code with each
command so that the WeatherLink can verify correct transmission.
The CRC code is transmitted BEFORE the command. It is possible to
program Rev E links to use the Rev D communication protocol, if
desired.
If a command is understood, an ASCII 6 (0x06) (ACK) is
returned (before any returned data). If the command was not
understood, an ASCII 33 (0x21) (!) is returned. Note that this
implies that the command passed its CRC check sum if the link is
a Rev E. For Rev E links, if the command does not pass its CRC
check sum, then an ASCII 24 (0x18) (CAN) is returned.
Some commands return a data stream and a CRC check sum. The
generator polynomial for the check sum is x^16 + x^12 + x^5 + 1
(CRC-CCITT backward).
All binary data is transferred in "Intel" format: least
significant byte first. In addition, multi-nibble data values on
the station are stored least significant nibble first. This does
not make a difference when you look at byte sized pieces of
memory, since the Link will correctly align the nibbles when
sending byte data.
Use the appropriate table in section IX to determine the
memory locations and sizes for the data you would like to operate
on. If you read data with an odd length, the upper nibble of the
last (most significant) byte will be set to 0, not sign extended.
If you write data with an odd length, the upper nibble of the
last byte will be ignored. Sign extension is taken care of for
data in the sensor image and archive image on the link.
The commands "RRD" and "RWR" operate on the link processor
memory. These commands execute faster than the "WRD" and "WWR"
commands which operate on the station processor memory.
The MDMP command is only available on the GroWeather,
Energy, and Health Links.
The CRC0 and CRC1 commands are only available on Rev E links.
DMP
Transfer the contents of the archive memory beginning at
address 0 using the XMODEM CRC protocol. This command can be
used with any standard communication package (i.e. Procomm). The
archive memory is organized as a set of equal sized archive
records. The appropriate link memory addresses section contains a
description of the size and structure of an archive image, which
is the same as the format of the archive records.
i.e.
put_serial_string ("DMP");
put_serial_char (0x0d);
MDMP
Dumps an image of the current contents of the Station
processor memory to the serial port. This typically takes around
6 seconds and is much faster than requesting lots of pieces
separately. 256 bytes are sent along with a 2 byte CRC check sum
in a similar fashion to the SRD command below. The memory tables
below show how this data is organized. See "Using the MDMP
command" (section VIII-C) below for how to do the appropriate bit
masking and shifting to extract data from the received data.
NOTE: MDMP uses archive memory 7F00-7FFF to record the
memory image from the station before sending it on the computer.
This archive memory is not available for normal archive purposes,
but the last MDMP can be read by using the SRD command, or the
DMP command.
The MDMP command is only available on the GroWeather,
Energy, and Health Links.
put_serial_string ("MDMP");
put_serial_char (0x0d);
LOOP 65536-n
Send 'n' packets of weather data (sensor image) from the
WeatherLink. The first byte (01) signals the start of a new
block. This is followed by binary data (15 bytes for the
Monitor/Wizard/Perception, 33 bytes for the GroWeather, 27 bytes
for the Energy, or 25 bytes for the Health) and a 2 byte CRC
check sum. The CRC check sum is calculated on the data only. The
"start of block" byte is not included in the CRC calculation. See
"CRC Checking" (section VIII-F) below for how to use the CRC
information.
Monitor, Wizard, and Perception Sensor Image:
start of block 1 byte
inside temperature 2 bytes
outside temperature 2 bytes
wind speed 1 byte
wind direction 2 bytes
barometer 2 bytes
inside humidity 1 byte
outside humidity 1 byte
total rain 2 bytes
not used 2 bytes
CRC checksum 2 bytes
--------
18 bytes
GroWeather Sensor Image:
start of block 1 byte
Archive memory address of
the next Archive record 2 bytes
Bar/Power status bits 1 byte See Appendix A
Soil temperature 2 bytes
Air temperature 2 bytes
wind speed 1 byte
wind direction 2 bytes
barometer 2 bytes
Rain Rate 1 byte
outside humidity 1 byte
total rain 2 bytes
Solar Radiation 2 bytes
Total Wind Run 3 bytes
Total ET 2 bytes
Total Degree-Days 3 bytes
Total Solar Energy 3 bytes
Alarm Bits and AOM status 3 bytes See Appendices G1 & B
Leaf Wetness Data and status 1 byte See Appendix G3
CRC checksum 2 bytes
--------
36 bytes
Energy Sensor Image:
start of block 1 byte
Archive memory address of
the next Archive record 2 bytes
Bar/Power status bits 1 byte See Appendix A
Inside temperature 2 bytes
Outside temperature 2 bytes
wind speed 1 byte
wind direction 2 bytes
barometer 2 bytes
Rain Rate 1 byte
outside humidity 1 byte
total rain 2 bytes
Solar Radiation 2 bytes
Total Wind Run 3 bytes
Total Solar Energy 3 bytes
Alarm Bits and AOM status 3 bytes See Appendices E1 & B
CRC checksum 2 bytes
--------
30 bytes
Health Sensor Image:
start of block 1 byte
Archive memory address of
the next Archive record 2 bytes
Bar/Power status bits 1 byte See Appendix A
Inside temperature 2 bytes
Outside temperature 2 bytes
wind speed 1 byte
wind direction 2 bytes
barometer 2 bytes
Rain Rate 1 byte
total rain 2 bytes
Solar Radiation 2 bytes
Inside humidity 1 byte
outside humidity 1 byte
UV Intensity 1 bytes
UV Dose 2 bytes
Alarm Bits and AOM status 3 bytes See Appendices H1 & B
CRC checksum 2 bytes
--------
28 bytes
Example:
put_serial_string ("LOOP");
send_unsigned ((unsigned) (65536 - n));
put_serial_char (0x0d);
See "Using the LOOP command" (section VIII-B) for examples
of how to extract data from a Loop image
RRD bank address n-1
Read 'n' nibbles from the link processor memory from
'address' in bank 'bank'. n = 1...8
On Rev E links, the data returned will also include a 2 byte
CRC code. See "CRC Checking" (section VIII-F) for how to use the
CRC information.
put_serial_string ("RRD"); // Send the command.
put_serial_char (bank); // bank = 0 or 1.
put_serial_char (address); // address = 0..FF
put_serial_char (n - 1); // Get n nibbles..
put_serial_char (0x0d); // Send CR...
RWR bank | n-1 address data
Write 'n' nibbles of 'data' into the link processor memory
beginning at 'address' in bank 'bank.' n = 1..8
put_serial_string("RWR"); // Send the command.
put_serial_char(0x13); // bank = 1 n = 4
put_serial_char(0x54); // address = 54h (Last Archive Time)
send_unsigned (0); // write 0.
put_serial_char(0x0D); // Send CR...
SRD address n-1
Read 'n' bytes of archive memory beginning at 'address.'
Both 'address' and 'n-1' are 16 bit numbers between 0 and 0x7FFF.
A two byte CRC checksum is sent at the end of the data stream.
See "CRC Checking" (section VIII-F) for how to use the CRC
information.
put_serial_string ("SRD"); // Send the command.
send_unsigned (address); // Start sending from address.
send_unsigned (n-1); // Send n bytes.
put_serial_char (0x0d); // Send CR...
SWR address data
Write 'data' (one byte) to 'address' in archive memory.
'address' is a 16 bit number between 0 and 0x7FFF.
put_serial_string ("SWR"); // Send the command.
send_unsigned (address); // Send two byte address.
put_serial_char (data); // Send byte of data.
put_serial_char (0x0d); // Send CR...
WRD n | bank address
Read 'n' nibbles of data from the station processor memory
starting at 'address' in bank 'bank'. For bank 0 use 'bank' = 2
for bank 1 use 'bank' = 4. A maximum of 8 nibbles can be read.
On Rev E links, the data returned will also include a 2 byte
CRC code. See "CRC Checking" (section VIII-F) for how to use the
CRC information.
put_serial_string ("WRD"); // Send read command.
put_serial_char (0x44); // read 4 nibbles from bank 1.
put_serial_char (0xB0); // Read beginning at B0h.
// (Period Length on GroWeather)
put_serial_char (0x0D); // Send CR...
WWR n | bank address data
Write 'n' nibbles of data to the station processor memory
starting at 'address' in bank 'bank'. For bank 0 use 'bank' = 1
for bank 1 use 'bank' = 3. A maximum of 8 nibbles can be written.
put_serial_string ("WWR"); // Send write command.
put_serial_char (0x31); // n = 3, writing to bank 0.
put_serial_char (0x34); // Write to AAh.=
// Daily ET Alarm Threshold on GroWeather
send_unsigned (0x0FFF); // Send 4095 or 0FFFh.
put_serial_char (0x0D); // Send CR...
SAP n
Set the archive interval to 'n' minutes. 'n' is one byte.
put_serial_string ("SAP"); // Send the command.
put_serial_char (n); // Set interval to 'n' minutes.
put_serial_char (0x0D); // Send CR...
SSP 256-n
Set the time interval between samples of the sensor image in
the WeatherLink to 'n' seconds. 'n' is one byte. At each
sampling instant the sensor image is sampled and variables that
are "averaged" are accumulated. The maximum number of samples in
an interval is 255.
put_serial_string ("SSP"); // Send the command...
put_serial_char ((unsigned char) (256 - newSamplePeriod));
put_serial_char (0x0D); // Send CR...
STOP
Tell the WeatherLink to stop it's constant updating of
weather information from the weather station. The command also
disables the archive timer on the WeatherLink. Stopping weather
station reads allows the WeatherLink to process commands more
quickly.
put_serial_string ("STOP");
put_serial_char (0x0d);
START
Tell the WeatherLink to begin "reading" the weather station
and archiving weather information. This command is only needed if
you have previously sent a STOP command.
put_serial_string ("START");
put_serial_char (0x0d);
ARC
Force a write to archive memory.
put_serial_string ("ARC");
put_serial_char (0x0d);
IMG
Force a sampling of the sensor image.
put_serial_string ("IMG");
put_serial_char (0x0d);
DBT
Disable the archive timer.
put_serial_string ("DBT");
put_serial_char (0x0d);
EBT
Enable the archive timer.
put_serial_string ("EBT");
put_serial_char (0x0d);
CRC0
Disable CRC command checking for Rev E links. This command
will set a Rev E WeatherLink into Rev D emulation mode. This means
that CRC check sums are not required (not allowed either!) for
commands sent to the WeatherLink. Also, only LOOP, MDMP, and SRD
data from the WeatherLink include CRC check sums.
If CRC command checking is enabled when you issue this
command, you MUST include the CRC code. CRC command checking is
only disabled AFTER the command is received and validated. The CRC
code is given below.
CRC0 command is only available on Rev E Links.
Note, the last character of the command is an ASCII zero
character.
put_serial_char (44); // CRC code first byte (decimal)
put_serial_char (247); // CRC code second byte (decimal)
put_serial_string ("CRC0"); // The fourth character is a zero
put_serial_char (0x0d);
CRC1
Enable CRC command checking for Rev E links. This command will
return a Rev E WeatherLink to normal operation. This means that CRC
check sums ARE required for commands sent to the WeatherLink. Also,
ALL data from the WeatherLink includes CRC check sums.
If CRC command checking is disabled when you issue this
command, you MUST NOT include the CRC code. CRC command checking is
only enabled AFTER the command is received.
CRC1 command is only available on Rev E Links.
put_serial_string ("CRC1");
put_serial_char (0x0d);
VII. Command Summary
DMP
Transfer the contents of the archive memory using the XMODEM
CRC protocol.
MDMP
Dumps an image of Station processor memory to the serial
port. This command is only available on the GroWeather, Energy,
and Health Links.
LOOP 65536-n
Send 'n' packets of weather data (sensor image) from the
WeatherLink.
RRD bank address n-1
Read 'n' (1-8) nibbles from the link memory from 'address' in
'bank'.
RWR bank | n-1 address data
Write 'n' (1-8) nibbles of 'data' into the link memory at
'address' in 'bank.'
SRD address n-1
Read 'n' bytes of archive memory beginning at 'address.' Both
'address' and 'n-1' are 16 bit numbers.
SWR address data
Write 'data' (one byte) to 'address' (2 bytes) in archive
memory.
WRD n | bank address
Read 'n' (1-8) nibbles of data from the station memory
starting at 'address' For a bank 0 use 'bank' = 2, for a bank 1
use 'bank' = 4.
WWR n | bank address data
Write 'n' (1-8) nibbles of data to the station memory
starting at 'address' For bank 0 use 'bank' = 1, for bank 1 use
'bank' = 3.
SAP n
Set the archive interval to 'n' minutes. 'n' is one byte.
SSP 256-n
Set the time interval between samples of the sensor image to
'n' seconds. 'n' is one byte. The maximum number of samples in
an interval is 255.
STOP
Tell the WeatherLink to stop updating the sensor image and
archiving.
START
Tell the WeatherLink to begin updating the sensor image and
archiving data. This command is only needed if you have
previously sent a stop command.
ARC
Force a write to archive memory.
IMG
Force a sampling of the sensor image.
DBT
Disable the archive timer.
EBT
Enable the archive timer.
CRC0
Disable CRC command checking for Rev E links.
CRC1
Enable CRC command checking for Rev E links.
VIII. Illustrated Examples
A. Reading Calibrated Data
Most of the data values displayed on the Station's LCD have
been calibrated. The term "calibrated" here means a user supplied
offset has been added to the "raw" number read by the weather
station. The data stored in "XxxxDta" memory locations (i.e.
Tp1Dta, SpdDta, etc. See Section IX) are uncalibrated. This goes
for LOOP data, and archived data as well. Thus, you may have to
calibrate the data you read off the station (or link). You should
take the time to read the station's user manual to familiarize
yourself with some of the Cal number basics.
There are several approaches to how to implement Cal
numbers. 1: Your program takes input from the user and records
the Cal numbers in a configuration file on the PC. Optionally the
program could set the station's Cal numbers at the same time so
they agree. 2. Or, the user could set the Cal number on the
station (either manually or with another program) and your
program reads the required Cal numbers off the station.
Always check sensor values for invalid data BEFORE applying
calibration numbers. Do not apply a calibration number to an
invalid data value. See "Invalid Data values" below for more
information.
The rest of this section will explain how to use the second
approach. The following Cal Numbers are explained: 1 Temperature,
2 Humidity, 3 Barometer, 4 Rain, 5 Wind Speed, 6 Rain Rate, and 7
UV MED's.
1. Temperature CAL
Each of the two temperature sensors has a separate Cal
number. Only the current station data and all Link
data--including the sensor image (LOOP) and archived data--needs
to be calibrated. Hi/Low data on the station and "derived" data
(i.e. Dewpoint, Wind chill, and THI) already have the Cal number
taken into account. The value at the Cal number location is an
offset (in Degrees F*10) to be added to the data. Note: this
value is a signed data value.
Reading Inside Temp on the Monitor (or Wizard or
Perception):
put_serial_string ("WRD"); // Send read command.
put_serial_char (0x44); // read 4 nibbles from bank 1.
put_serial_char (0x52); // Read beginning at 52h.
// (Inside Temp Cal on Monitor)
put_serial_char (0x0D); // Send CR...
get_acknowledge(); // verify that the command was
received and got ACK
fill_buffer(2); // get the returned data (in bytes)
InTempCAL = *((int *) receive_buffer)
// read the Cal number out of the
buffer
put_serial_string ("WRD"); // Send read command.
put_serial_char (0x44); // read 4 nibbles from bank 1.
put_serial_char (0x30); // Read beginning at 30h.
// (Inside Temp Data on Monitor)
put_serial_char (0xd); // Send CR...
get_acknowledge(); // verify that the command was
received and got ACK
fill_buffer(2); // get the returned data (in bytes)
InTemp = *((int *) receive_buffer)
// read the Raw Temperature out of the
buffer
// Verify that the Raw Temperature is not an invalid data value
before
// applying the cal number. See "Invalid Data values" below for
// more information.
InTemp = InTemp + InTempCal // InTemp is now Calibrated
Reading Outside Temp on the Energy Station:
put_serial_string ("WRD"); // Send read command.
put_serial_char (0x34); // read 3 nibbles from bank 1.
put_serial_char (0x45); // Read beginning at 45h.
// (Outside Temp Cal on Energy)
put_serial_char (0xd); // Send CR...
get_acknowledge(); // verify that the command was
received and got ACK
fill_buffer(2); // get the returned data (in bytes)
// Note that the upper nibble of the last byte will be set
// to 0 Also, even though the address was odd, the nibbles
// are aligned so that the addressed nibble is the least
// significant nibble of the first byte
OutTempCAL = *((int *) receive_buffer)
// read the Cal number out of the
buffer
if(OutTempCAL > 2048) // Check for negative numbers
{
OutTempCAL = OutTempCAL - 4096;
// convert a 3 nibble 2's complement
negative
// number into a "real" negative
number
}
put_serial_string ("WRD"); // Send read command.
put_serial_char (0x34); // read 3 nibbles from bank 1.
put_serial_char (0x36); // Read beginning at 36h.
// (Outside Temp Data on Energy)
put_serial_char (0xd); // Send CR...
get_acknowledge(); // verify that the command was
received and got ACK
fill_buffer(2); // get the returned data (in bytes)
OutTemp = *((int *) receive_buffer)
// read the Raw Temperature out of the
buffer
if(OutTemp > 2048) // Check for negative numbers
{
OutTemp = OutTemp - 4096; // convert a 3 nibble 2's complement
negative
// number into a "real" negative
number
}
// Verify that the Raw Temperature is not an invalid data value
// before applying the cal number. See "Invalid Data values"
// below for more information.
OutTemp = OutTemp + OutTempCAL // OutTemp is now Calibrated
2. Humidity CAL
Only Outside Humidity on the GroWeather, Energy, Health,
and on the Monitor Rev C or later have a CAL number. It consists
of either a signed 2-byte number (on the Monitor) or a signed 1-
byte number (on the other stations) to be added to the current
station data and Link data including the sensor image (LOOP) and
archived data. Hi/Low and "Derived" values (dewpoint, THI, etc.)
already take the Cal number into account.
After adding the Cal number to the data, you will need to
make sure that the result is in the range 1 to 100. If not, then
clip the data at these boundaries.
Reading Outside Hum on the Monitor:
put_serial_string ("WRD"); // Send read command.
put_serial_char (0x44); // read 4 nibbles from bank 1.
put_serial_char (0xDA); // Read beginning at DAh.
// (Outside Hum Cal on Monitor)
put_serial_char (0xd); // Send CR...
get_acknowledge(); // verify that the command was
received and got ACK
fill_buffer(2); // get the returned data (in bytes)
OutHumCAL = *((int *) receive_buffer)
// read the Cal number out of the
buffer
put_serial_string ("WRD"); // Send read command.
put_serial_char (0x24); // read 2 nibbles from bank 1.
put_serial_char (0x98); // Read beginning at 98h.
// (Outside Hum Data on Monitor)
put_serial_char (0xd); // Send CR...
get_acknowledge(); // verify that the command was
received and got ACK
fill_buffer(1); // get the returned data (in bytes)
OutHum = *((unsigned char *) receive_buffer)
// read the Raw Humidity out of the
buffer
if (OutHum == 128) // if the raw sensor value is 128,then either the
return HUM_ERROR_VALUE // hum sensor is not working or not attached.
OutHum = OutHum + OutHumCal
// OutHum is now Calibrated, but possibly
out of range
if (OutHum >100)
OutHum = 100;
else if (OutHum < 1)
OutHum = 1; // OutHum has been clipped to the
range 1 - 100.
3. Barometer
The weather station measures the absolute atmospheric
pressure. In order to convert this to a Standard Barometric
pressure, the station subtracts a calibration offset value. This
is determined by having the user enter the desired Barometric
reading (derived from some other source i.e. airport, newspaper
etc.). The station stores the difference between the desired
reading and the actual reading in the "StnDrd" memory register.
This calibration number must be subtracted from the current
Station data and Link data including the sensor interface (LOOP)
and archived data.
Note: since at higher elevations the absolute pressure
decreases, the barometric pressure is generally larger than the
atmospheric pressure and since the calibration number is
subtracted from the data, it is generally a negative number. It
is 2 bytes long
Reading Barometer on the Monitor (or Perception):
put_serial_string ("WRD"); // Send read command.
put_serial_char (0x44); // read 4 nibbles from bank 1.
put_serial_char (0x2C); // Read beginning at 2Ch.
// (Barometer Standard on Monitor)
put_serial_char (0xd); // Send CR...
get_acknowledge(); // verify that the command was
received and got ACK
fill_buffer(2); // get the returned data (in bytes)
BarCAL = *((int *) receive_buffer) // read the Cal number out
of the buffer
put_serial_string ("WRD"); // Send read command.
put_serial_char (0x44); // read 4 nibbles from bank 1.
put_serial_char (0x00); // Read beginning at 00h.
// (Barometer Data on Monitor)
put_serial_char (0xd); // Send CR...
get_acknowledge(); // verify that the command was
received and got ACK
fill_buffer(2); // get the returned data (in bytes)
Barometer = *((int *) receive_buffer)
// read the Raw Barometer out of the
buffer
Barometer = Barometer - BarCal // Barometer is now Calibrated
4. Rain
Rain data on all stations and links are stored in "unit-
less" clicks. The RainCal number tells how many clicks are in an
inch of rain. The most common numbers are: 10 for the 0.1" rain
collector, 100 for the 0.01" rain collector, and 127 for the
0.2mm rain collector.
Reading Yearly Rain on the Monitor (or Wizard):
put_serial_string ("WRD"); // Send read command.
put_serial_char (0x44); // read 4 nibbles from bank 1.
put_serial_char (0xD6); // Read beginning at D6h.
// (Rain Cal on Monitor)
put_serial_char (0xd); // Send CR...
get_acknowledge(); // verify that the command was
received and got ACK
fill_buffer(2); // get the returned data (in bytes)
RainCAL = *((int *) receive_buffer) // read the Cal number out
of the buffer
put_serial_string ("WRD"); // Send read command.
put_serial_char (0x44); // read 4 nibbles from bank 1.
put_serial_char (0xCE); // Read beginning at CEh.
// (Yearly Rain Data on Monitor)
put_serial_char (0xd); // Send CR...
get_acknowledge(); // verify that the command was
received and got ACK
fill_buffer(2); // get the returned data (in bytes)
RainClicks = *((int *) receive_buffer)
// read the Raw Rain out of the buffer
YearRain = (float) RainClicks / (float) RainCal
// Make sure this is a floating point
calculation
// YearRain is now Calibrated in
Inches
Reading Daily Rain on the GroWeather Station:
put_serial_string ("WRD"); // Send read command.
put_serial_char (0x44); // read 4 nibbles from bank 1.
put_serial_char (0xCF); // Read beginning at CFh.
// (Rain Cal on GroWeather)
put_serial_char (0xd); // Send CR...
get_acknowledge(); // verify that the command was
received and got ACK
fill_buffer(2); // get the returned data (in bytes)
RainCAL = *((int *) receive_buffer)
// read the Cal number out of the
buffer
put_serial_string ("WRD"); // Send read command.
put_serial_char (0x34); // read 3 nibbles from bank 1.
put_serial_char (0xC9); // Read beginning at C9h.
// (Daily Rain Data on GroWeather)
put_serial_char (0xd); // Send CR...
get_acknowledge(); // verify that the command was
received and got ACK
fill_buffer(2); // get the returned data (in bytes)
// Note that the upper nibble of the last byte will be set
// to 0 Also, even though the address was odd, the nibbles
// are aligned so that the addressed nibble is the least
// significant nibble of the first byte
RainClicks = *((int *) receive_buffer) // read the Raw Rain out
// of the buffer. Since Rain is unsigned, we do not need to
// Check for negative numbers
DailyRain = (float) RainClicks / (float) RainCal
// Make sure this is a floating point calculation
// YearRain is now Calibrated in Inches
5. Wind Speed
While all of the stations have a Wind Speed cal number,
there are very few situations where it is useful. Primarily if
you do not attach a Davis anemometer, or if you are not measuring
wind speed. The formula for Wind Speed in MPH is "SpdDta" * 1600
/ "SpdCal". Since, the default Cal number is 1600, you can just
read "SpdDta" in MPH directly without any further calculation.
The Speed Cal only effects the LCD display of the current
and Hi wind speed. It is not used in any "Derived" calculations
(i.e. Wind Chill, THSWI, or ET).
Setting the Cal Number to 3600 will cause the display to be
in Hz. That is it will show the number of anemometer revolutions
per second.
6. Rain Rate
Rain Rate is only available on the GroWeather, Energy, and
Health stations. There are two different ways that the Rain Rate
data is stored. On the Links (both Sensor Image and archived
data), the rate is stored in inches per hour times 10. The
current station rain cal is used to calculate this value. See
Below.
On the Station, the current rain rate (and the Hi rate on
the Health station) is stored as "The number of half-seconds
between the last rain click and the previous rain click. Given
the information above about the station's rain Cal number, the
formula for converting raw rate data is:
Rate(in/hr) = 7200(1/2 sec/hr) / ("RateDta"(1/2sec/clicks)*
"RainCal"(clicks/In))
7. UV MED's
The UV MED's Cal number is designed to allow the UV MED's
displays to be adjusted for different skin types. UV Intensity
data is stored in tenths of an Index, but can be displayed in
both Index and MED's per Hour. UV Doses are stored as "Standard"
MED's and always displayed in MED's. The UV MED's Cal number is a
number between 1 and 14 which represents a multiplication factor
of 0.1 to 1.4. The "Standard" Cal number is 10, representing a
multiplication factor of 1.0.
The formula for converting UV Index to "Standard" MED's is:
UV_MEDs = (3/7) * UV_Index
The formula to convert "Standard" MED's to calibrated MED's
is:
Caled_MEDs = Standard_MEDs * "UVCal" / 10
Note: Make sure that you perform both of the above conversions
using floating point arithmetic!
B. Using the LOOP command
The LOOP command is the preferred way to acquire real time
updates of weather data. The data sent in a LOOP packet is the
data from the Link's Sensor interface. The pseudo-code
description of the link processing loop above describes how often
this data is updated from the station. The answer to the question
"How often is the data updated?" in the FAQ contains some useful
approximate timing figures. LOOP data is also CRC checked (See
below for how to implement CRC Checking).
Assuming that you want a virtually continuous stream of loop
packets, one approach is to ask for a large number (say 1000) of
packets in one LOOP command, another approach is to ask for a few
packets (5-10) in one LOOP command and repeat the request when
they have arrived. In either case there is the possibility that
missed characters or other communication difficulties may cause
the receiver to become unsynchronized with the link as to where
the data packets begin. If this happens you should first stop the
stream of LOOP data by sending another valid command (like a read
of Link memory). Then clear your receive buffer and send the LOOP
command again.
Another feature of the LOOP command, only available on the
GroWeather, Energy, and Health stations, is the ability to
monitor the archiving of data. On these stations, one of the data
fields is the "NewPtr" that indicates the SRAM address where the
next archive record is to be written. If this number changes
during the course of reading LOOP packets, you know that the
station has created a new archive record. This feature is used in
the "Strip Charts" in the GroWeather, Energy, and Health software
to keep the PC database current with the archive memory.
The following examples show how to extract data from a data
buffer filled with LOOP data. See above for a description of
fill_crc_buffer() and see below for how CRC checking is done.
Example of reading a Monitor Sensor Image. (reading a Wizard
or a Perception is the same only omitting the fields of non-
existing sensors).
put_serial_string ("LOOP");
send_unsigned ((unsigned) (65535)); // request 1 LOOP packet
put_serial_char (0x0d);
get_acknowledge(); // verify that the command was
received and got ACK
header = get_serial_char(); // This should be the block header
byte
if (header != 1) { error = 1;}
// If the header byte is not 1 then
there is an error
// assuming there is no error ...
CRC_Error = fill_crc_buffer(17); // 15 data bytes + 2 CRC bytes.
// Header Byte is not included
in CRC check
// assuming there is no CRC error, the data is stored in
recieve_buffer ...
inside_temperature = *((int *)(receive_buffer+0));
outside_temperature = *((int *)(receive_buffer+2));
wind_speed = *((unsigned char *)(receive_buffer+4));
wind_direction = *((int *)(receive_buffer+5));
barometer = *((int *)(receive_buffer+7));
inside_humidity = *((unsigned char *)(receive_buffer+9));
outside_humidity = *((unsigned char*)(receive_buffer+10));
rain = *((unsigned *)(receive_buffer+11));
Example of reading a GroWeather sensor image
put_serial_string ("LOOP");
send_unsigned ((unsigned) (65535)); // request 1 LOOP packet
put_serial_char (0x0d);
get_acknowledge(); // verify that the command was
received and got ACK
header = get_serial_char(); // This should be the block header
byte
if (header != 1) { error = 1;}
// If the header byte is not 1 then there is an error
// assuming there is no error ...
CRC_Error = fill_crc_buffer(34); // 32 data bytes + 2 CRC bytes.
// Header Byte is not included in CRC check
// assuming there is no CRC error, the data is stored in
receive_buffer ...
New_pointer = *((unsigned int *)(receive_buffer));
bar_power_flag = *(( unsigned char *)(receive_buffer+2));
soil_temperature = *((int *)(receive_buffer+3));
air_temperature = *((int *)(receive_buffer+5));
wind_speed = *((unsigned char *)(receive_buffer+7));
wind_dir = *((int *)(receive_buffer+8));
barometer = *((int *)(receive_buffer+10));
rain_rate = *((unsigned char *)(receive_buffer+12));
outside_humidity = *((unsigned char*)(receive_buffer+13));
rain = *((unsigned *)(receive_buffer+14));
solar_rad = *((int *)(receive_buffer+16));
wind_run = *((unsigned char *) (recieve_buffer+18)) +
*((unsigned char *) (recieve_buffer+19))*256 +
*((unsigned char *) (recieve_buffer+20))*65536
ET = *((unsigned char *) (recieve_buffer+21))
ET_Flags = *((unsigned char *) (recieve_buffer+22))
Deg_Days = *((unsigned char *) (recieve_buffer+23)) +
*((unsigned char *) (recieve_buffer+24))*256 +
*((unsigned char *) (recieve_buffer+25))*65536
Energy = *((unsigned char *) (recieve_buffer+26)) +
*((unsigned char *) (recieve_buffer+27))*256 +
*((unsigned char *) (recieve_buffer+28))*65536
Alarm_Flags = *((unsigned char *) (recieve_buffer+29)) +
*((unsigned char *) (recieve_buffer+30))*256 +
(*((unsigned char *) (recieve_buffer+31)) &
0x0F)*65536
AOM_status = (*((unsigned char *)(recieve_buffer+31)) & 0xF0) >> 4
LeafWetnessData = (*((unsigned char *)(recieve_buffer+32)) &
0xF);
LeafWetnessEnabled = (*((unsigned char *)(recieve_buffer+32)) &
0x40) == 0x40;
// Check the value of bit 6
C. Using MDMP command
While the MDMP command is only available on the GroWeather,
Energy, and Health stations, it is very useful any time you want
to examine several station memory locations at once. For
instance, looking at all the Hi/Lows or all the Alarm thresholds.
You could, in principal, use MDMP as an alternative to the LOOP
command to provide real time data, but it imposes a greater
burden on the Station, Link, and PC processing power and
bandwidth. It is therefore not recommend for continuous use.
There are 2 difficulties that must be addressed when
extracting MDMP data. First, locating the desired data in the
data buffer. Second, making sure that the number is sign extended
if the value is supposed to be a negative number.
Assuming that the MDMP data is stored in a continuous byte
sized buffer starting with byte 0, Bank 0 data from the station
will be found in Bytes 0-127. Bank 1 data from the station will
be found in Bytes 128-255. Remembering that the addresses in the
tables below are in nibbles, even addresses are stored in the
Least-Significant-Nibble of their corresponding byte, and odd
addresses are in the Most-Significant-Nibble.
To request and store a memory dump:
put_serial_string ("MDMP"); // Request Memory Dump
put_serial_char (0x0d);
get_acknowledge(); // verify that the command was
// received and got ACK
CRC_Error = fill_crc_buffer(258); // 256 data bytes + 2 CRC bytes.
// receive_buffer has memory dump data.
Some examples of reading data out of this buffer:
Wind speed on the GroWeather is located at address 0x060 =
96. This corresponds to byte 48 in the buffer. Since the data
starts on an even address and is only 2 nibbles long and
unsigned, byte 48 is the Wind Speed without any further
processing.
WindSpeed = receive_buffer(48);
Daily ET on the GroWeather is located at address 0x0A7 =
167. This corresponds to the upper nibble of byte 83 in the
buffer. Since the data value is 3 nibbles long, the whole of byte
84 is also part of this data field. The data is unsigned so we do
not have to worry about sign extension.
// Mask and shift nibble 1
nibble1 = (receive_buffer[83] & 0xF0) >> 4;
// Add in the upper 2 nibbles
DayET = nibble1 + (receive_buffer[84] * 16);
Hi Air Temp on the GroWeather is located at address 0x145 =
325 (69 in Bank 1). This corresponds to the upper nibble of byte
162 (128 + 34.5). The data field also includes all of byte 163.
After extracting the data, we must check for a negative value.
// Mask and shift nibble 1
nibble1 = (receive_buffer[162] & 0xF0) >> 4;
// Add in the upper 2 nibbles
HiAirTemp = nibble1 + (receive_buffer[163] * 16);
// Check the sign bit of a 3-nibble 2's complement number
if (HiAirTemp > 2048)
HiAirTemp = HiAirTemp - 4096; // If negative, make it so
And finally, Soil Temp Low Alarm Threshold on the GroWeather
is located at address 0x13C = 316 (60 in Bank 1). This
corresponds to byte 158. The data also extends into the lower
nibble of byte 159. Again the data needs to be sign extended if
necessary
// Mask out the Hi nibble
nibble3 = (receive_buffer[159] & 0x0F) * 256;
// add lower byte to nibble3
SoilLowAlarm = receive_buffer[158] + nibble3;
// Check the sign bit of a 3-nibble number
if (SoilLowAlarm > 2048)
// If negative, make it so
SoilLowAlarm = SoilLowAlarm - 4096;
D. Invalid Data values
In general there are 2 different ways that numerical data is
stored on the weather station: Signed and Unsigned. These two
methods use different values to indicate that the sensor is not
attached (or not working). Signed data can use either the
largest positive or smallest negative number that fits into it's
data size. Unsigned data uses the largest value.
You must keep in mind the size (in nibbles) of the data
field you are examine since this will affect the numerical values
to be checked for.
These Data values are also used in Alarm Thresholds to
indicate that no threshold has been set and therefore not to test
for that particular alarm condition.
Always check sensor values for invalid data BEFORE applying
calibration numbers. Do not apply a calibration number to an
invalid data value.
Rain Rate is a special case dealt with below.
Data that accumulates over time (i.e. Rain, ET, Degree-Days,
Wind Run, Solar Energy, and UV Dose) is unsigned data. The error
value is used only for inactive alarm thresholds.
Signed Data Values:
Temperature: All temperatures, Hi/Lows, Alarm thresholds,
and Cal numbers are Signed data. On the Monitor, the Wizard, and
the Perception, these values are stored in 4 nibble fields.
Therefore the error values are 0x7FFF = 32767 and 0x8000 = -
32768.
On the GroWeather, Energy, and Health stations, these values are
stored in 3 nibble fields. And the error values are 0x7FF = 2047
and 0x800 = -2048.
Barometer: The current and stored barometer data is stored
in 4 nibble fields on all stations. The barometer alarm is stored
in 2 nibbles, and uses the value 0x7F = 127 or 0x80 = -128 for
invalid data.
Wind Direction: On the Monitor, and Wizard stations, the
wind direction is stored in a 4 nibble field and uses the values
0x7FFF or 0x8000 to indicate an invalid wind direction.
On the GroWeather, Energy, and Health stations, wind
direction is stored in a 3 nibble field and uses the values 0x7FF
or 0x800 to indicate an invalid wind direction.
This information only applies to the current wind direction
on the station, or in the sensor image on the link (i.e. LOOP
data packet). The data stored in the archive memory is an
unsigned byte with the compass direction of the prevailing wind
from 0-15. The value 255 is used to indicate that there was
either no wind or no wind direction data during the archive
period.
In addition, the GroWeather, Energy, and Health stations
also have 1 nibble fields that record both the current wind
direction and the wind direction at the time of the hi wind
speed. All 16 values of a 1 nibble number are needed to represent
the 16 different compass points. You will need to check the value
of the appropriate status bit in order to determine if the data
is valid.
Humidity: Since valid Humidity values only range from 1% to
100%, it does not make much difference whether humidity is
considered a signed or unsigned value. An illegal Humidity
reading is represented by the value 0x80 which can either be
thought of as 128 or -128 depending upon whether the data is
signed or unsigned. The weather station treats the data as signed
for the purposes of clearing Hi/Low values.
Unsigned Data Values:
Wind Speed: Except for Rev A Monitors, and Wizards, wind
speed data on all stations is 2 nibbles long and unsigned. On the
Rev A Monitors and Wizards, the data is signed.
The wind speed hi alarm threshold on all Monitors and
Wizards is a 4 nibble signed number using 0x7FFF or 0x8000 to
indicate an invalid alarm.
On the GroWeather, Energy, and Health stations, the wind
speed hi alarm is a 2 nibble unsigned number which uses 0xFF =
255 to indicate an invalid alarm. Note that this means that while
the current (and Hi) data can display the value of 255, the alarm
can not be set to this value, since that value is used to
indicate the absence of a wind speed alarm.
Solar Rad: Solar rad is a 3 nibble unsigned number that uses
0xFFF = 4095 to indicate invalid data.
UV Intensity: UV Intensity is stored as a 2 nibble unsigned
number. The current value, hi value, and hi alarm use the value
0xFF = 255 to indicate invalid data.
Rain Rate Data
The rain rate data is stored as a 3 nibble unsigned number.
Because of the way that rain rate is measured and calculated,
larger data values correspond to smaller rain rates. Setting the
hi rain rate to zero, for instance, results in an infinite rain
rate that is displayed with dashes. These dashes will not go away
until the hi rain rate is cleared. When a rain rate value is
cleared, it is set to 0xFFF = 4095, the display will read 0.0
inches per hour. In some cases, the station treats this value as
a signed number and uses the value 0x7FF = 2047 to indicate a
cleared rain rate.
E. Calculated Data values
Here are some formulas and code examples for how to
calculate some of the "Derived" data values found on the station:
1. Wind Chill
Wind chill represents how cold the temperature feels in the
presence of wind. It is based on the current wind speed
(calibration is ignored) and the current outside temperature
(calibration is used). The following C code shows how this is
done. Note that if the temperature is above 91, the wind has no
effect on the wind chill.
/* Chill Factor (cf) at 5 MPH intervals */
unsigned char chillTableOne [] =
{
156, 151, 146, 141, 133, 123, 11
|
Is there a command which I can run to see the response of the station before it gets processed by weewx? I tried looking around but didn't find such a debug command. It appears in syslog the humidty is showing 162. I will try locate the exact model of station however from memory it's a Weather Monitor 2 and I didnt recall seeing any other indications without writing down its serial number. |
I wonder if I need to adjust the stations calibration manually on the panel or something. |
On the front panel it says low humidity is 1% and high is 100% under the recal button. It also says current reading is 65% outside. That is also what weewx is reporting as current. I wonder why its creaping above 100% then. |
Oh and thanks for the specification you sent too. I may just have to see if pressing that recal did reset it to 100% or if it already was set to 100% as high. I can't recall how all the interface works since I haven't used it for a while. |
If you run weewx directly from the command line it will print the packets
directly to the screen as they come in. You'll probably see the humidity
there going above 100% because that's how it is being parsed by the driver,
I will probably need a little more information about your station in order
to figure out why it's parsing it that way.
I am attaching my Python script where I originally developed the methods
for reading the data from the station, it's called wmTest.py, you can use
it as follows (I generally use iPython for these sort of debugging):
From wmTest import Station
my_station = Station('/dev/ttyUSB0') # whatever your stations port is.
my_station.open()
readings = my_station.get_readings()
data = my_station.parse_readings(readings)
print(data)
The variable [readings] will hold the packet returned by the station for
our sent LOOP command and for the Weather Monitor II stations it has the
following structure:
1 byte = header ---> 0x01 (checked and removed by get_readings)
2 bytes = inTemp
2 bytes = outTemp
1 byte = windSpeed
2 bytes = windDir
2 bytes = pressure
1 byte = inHumidity
1 byte = outHumidity
2 bytes = rain_total
2 bytes = not_used
2 bytes = CRC_checksum
Notice that they are all in little-endian byte packs, so the
parse_readings() function unpacks it using python's struct.unpack module.
You could do the same with the [readings] variable like this:
buf = struct.unpack('<hhBhhBBhhh', readings)
The header byte gets removed from the packet by the get_readings function
so the struct.unpack starts with the inTemp data, your variable [buf] will
be a list of the data in the described order. If you can send me what that
looks like with the corresponding data on the screen of you Weather Station
we might be able to figure out what's going on.
Thanks,
Jardi.
…On Sun, Mar 24, 2019, 11:39 AM Peter Stevenson ***@***.***> wrote:
Oh and thanks for the specification you sent too. I may just have to see
if pressing that recal did reset it to 100% or if it already was set to
100% as high. I can't recall how all the interface works since I haven't
used it for a while.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#1 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ABCc3CR-BNOiCPf9zAa2tu_xrKp2yZY2ks5vZ8Z7gaJpZM4b4a0g>
.
|
Also. Can you open a new issue? since all this is unrelated to the original one. |
Hi I have the following entry in my syslog:
Mar 17 14:20:36 raspberrypi wee_device[2077]: The driver user.wmII does not include a configuration tool: 'module' object has no attribute 'configurator_loader'
Any ideas?
The text was updated successfully, but these errors were encountered: