Vantage Serial Support - B.P. 2-5-00 ------------------------------------ I. Specification II. Improvements Over Weatherlink for Monitor II III. LOOP Command IV. Alarms Supported V. COMMANDS SUPPORTED VI. READING HIGH LOW DATA VII. DOWNLOAD Specification ------------- 8 bits no stop bit and no parity. Supports baud rates up to 19,200. 128K of non-volatile flash memory. Designed to operated continuously while on batteries. Power is taken from serial port when present. Improvements Over Weatherlink for Monitor II --------------------------------------------- Besides the faster baud rate and more memory the new firmware supports an enhanced LOOP command which contains more information, and a DMPAFT command which sends only the data in the archive after the specificed date and time. Note, although the LCD display is on all the time the station sleeps and wakes up to receive a data packet. Before a serial command is processed you must make sure the station is awake. Sending any character will wake the station. You can send a '\n' and you should receive a '\n' and '\r' back. Also note, the station does not process commands in the Setup screens other than the first screen and not when numbers are being entered on the display. LOOP Command ------------ LOOP N where N is the number of loops to receive. Previously, N was a 2 byte binary number, but now it is just an ascii number which is part of the string. For example, the string "LOOP 24\n" will send 24 loop packets spaced 4 seconds apart. Unlike all other commands, the station goes to sleep immediately after processing this command. /* +-----------------------------------------------------+ */ void SendLoop (int nextRecord) { byte i; #ifdef EVERYTHING ClearCrc (); PutPcCharCrc ('L'); PutPcCharCrc ('O'); PutPcCharCrc ('O'); PutPcCharCrc ('P'); PutPcCharCrc (0); // Packet Type PutPcUnsigned (nextRecord); PutPcUnsigned (bar); PutPcUnsigned (tempIn); PutPcCharCrc (humIn); PutPcUnsigned (tempOut); PutPcCharCrc (windSpeed); PutPcCharCrc (windSpeed10Min); PutPcUnsigned (windDir); for (i = 0; i < 15; i++) PutPcCharCrc (temp [i]); for (i = 0; i < 8; i++) PutPcCharCrc (hum [i]); PutPcUnsigned (rainRate); PutPcCharCrc (uv); PutPcUnsigned (solarRad); PutPcUnsigned (rainStorm); PutPcUnsigned (stormStartDate); PutPcUnsigned (rainDay); PutPcUnsigned (rainMonth); PutPcUnsigned (rainYear); PutPcUnsigned (etDay); PutPcUnsigned (etMonth); PutPcUnsigned (etYear); for (i = 0; i < 4; i++) PutPcCharCrc (soilMoist [i]); for (i = 0; i < 4; i++) PutPcCharCrc (leaf [i]); /* extern byte insideAlarms; extern unsigned outsideAlarms; extern byte rainAlarms; extern byte tempHumAlarms [8]; // Extra temp hum alarms. extern byte leafSoilAlarms [4]; */ PutPcCharCrc (insideAlarms); PutPcCharCrc (rainAlarms); PutPcUnsigned (outsideAlarms); for (i = 0; i < 8; i++) PutPcCharCrc (tempHumAlarms [i]); for (i = 0; i < 4; i++) PutPcCharCrc (leafSoilAlarms [i]); PutPcCharCrc (GetTxBatteryStatus ()); PutPcUnsigned (GetBatteryCounts ()); PutPcCharCrc (GetForecastIcons ()); PutPcCharCrc (GetForecastRuleNo ()); PutPcUnsigned (GetSunrise ()); // hours * 100 + min PutPcUnsigned (GetSunset ()); // hours * 100 + min PutPcCharCrc ('\n'); PutPcCharCrc ('\r'); PutPcCrc (); #endif } ALARMS SUPPORTED ------------------- extern byte insideAlarms; extern unsigned outsideAlarms; extern byte rainAlarms; extern byte tempHumAlarms [8]; // Extra temp hum alarms. extern byte leafSoilAlarms [4]; /* Outside alarm bits defined. */ #define NUM_OUTSIDE_ALARMS 13 #define LOW_TEMP_OUT_A 0 #define HIGH_TEMP_OUT_A 1 #define SPEED_A 2 #define SPEED_10MIN_A 3 #define LOW_DEW_A 4 #define HIGH_DEW_A 5 #define HEAT_A 6 #define CHILL_A 7 #define THSW_A 8 #define SOLAR_A 9 #define UV_A 10 #define UV_EXPOSURE_A 11 #define UV_EXP_ALARM_ON 12 /* Inside alarm bits defined. */ #define NUM_INSIDE_ALARMS 8 #define BAR_FALL_A 0 #define BAR_RISE_A 1 #define LOW_TEMP_IN_A 2 #define HIGH_TEMP_IN_A 3 #define LOW_HUM_IN_A 4 #define HIGH_HUM_IN_A 5 #define TIME_A 6 //#define LOW_CONSOLE_BATTERY_A 7 /* Rain alarm bits defined. */ #define NUM_RAIN_ALARMS 5 #define RAIN_RATE_A 0 #define RAIN_15MIN_A 1 #define RAIN_24HR_A 2 #define RAIN_STORM_A 3 #define ET_DAY_A 4 /* Extra temp hum bits defined. */ #define NUM_TEMP_HUM_ALARMS 4 #define LOW_TEMP_A 0 #define HIGH_TEMP_A 1 #define LOW_HUM_A 2 #define HIGH_HUM_A 3 /* Leaf and soil bits defined. */ #define NUM_LEAF_SOIL_ALARMS 8 #define LOW_LEAF_A 0 #define HIGH_LEAF_A 1 #define LOW_SOIL_A 2 #define HIGH_SOIL_A 3 #define LOW_LEAF_TEMP_A 4 #define HIGH_LEAF_TEMP_A 5 #define LOW_SOIL_TEMP_A 6 #define HIGH_SOIL_TEMP_A 7 COMMANDS SUPPORTED ------------------- static flash char commandStr [] [10] = { "TEST", // Echo's TEST back... "WRD", // Used to find station type. "DMPAFT", // Downloads all records after a date. "CALFIX", // Write newly corrected temperatures. "CALED", // Send caled data. "PUTRAIN", // Write yearly rain. "PUTET", // Write yearly et. "TXTEST", // Send U's out serial port. "DMP", // Downloads the flash. "PAGEWR", // Write a page of flash memory. "PAGERD", // Read a page of flash memory. "BUFFWR", "BUFFRD", "BAUD", // Change the baud rate. "KICK", "BARON", "BAROFF", "BAR=", // Command used to set barometer from PC. "BARREAD", "BARDATA", /* "TXON", "TXOFF", "OFF", "ON", */ "CLRLOG", "SETTIME", "GETTIME", "NEXTLOG", // Calculate next log time based on clock. "SETPER", // Set log period. "STOP", // Stop logging data. "START", // Start logging data. "RECRD", // Read a record. "RECWR", // Write a record. "NEWDAY", // Force new day. "CLREE", // Clear the EEPROM. "GETEE", // Get the EEPROM data. "SETA", // Set the alarms. "GETA", // Get the alarms. "EEWR", // Write to the EEPROM. "EERD", // Read the EEPROM. "CALON", // Go into calibration mode. "CALOFF", // Leave calibration mode. "ADREAD", // Read an A/D channel. "STRMON", // Send packets out the serial port. "STRMOFF", // Stop sendting packets. "CLKON", // Do output compare on clock for calibration. "CLKOFF", // Do output compare on clock for calibration. //"STACFG", // Output the know configuration for the station. "CLRALM", // Clear the alarms. "CLRCAL", // Clear cal numbers. "CLRGRA", // Clear graph data. "VER", // Clear graph data. "EEBWR", // Write to the EEPROM. Binary input. "EEBRD", // Read the EEPROM. Binary output. "CLRVAR", // Clear a rain or et register. "CLRHIGHS", // Clear highs for day. "CLRLOWS", // Clear lows for day. "CLRBITS", // Clear alarm bits. "CLRDATA", // Clear all current data. "LOOP", // LOOP N "HILOWS", // Get all the high low data. 388 bytes now. "LOG", // Force a write to the archive. "NEWSETUP", // Force call to DoNewSetupStuff (); "SLEEP", // Check sleep current and serial wakeup. "MEASHUM", // Check outside hum in range. "HUM33", // Make hum measurement and use as 33% . "HUM80", // Make hum measurement and use as 80% . "HUMLOW", // Make hum low meas. "HUMHI", // Make hum high meas. "HUMCALC", // Return calculated humidity value. "POW", // Used to turn on and off circuits. "PORT", // USED ON INITIAL TEST TO CHECK I/O PINS. "LAMPS", // LAMPS 0|1 "CHECKEE", // Test EEPROM. "RECEIVERS" // See who console is receiving from. }; /* flash char rxCheckStr [] [25] = { "totalReceived %d\n\r", "totalResynchs %d\n\r", "totalMisses %d\n\r", "timeOutMisses %d\n\r", "totalGood %d\n\r", "nCrcErrors %d\n\r", "maxSaveAfter %d\n\r", "maxInARow %d\n\r" }; */ /* +-------------------------------------------------------------------+ */ void ProcessCommand (void) { int c, i = 0, n, addr, x; float tmp; DateTime aTime; byte k; k = 0; #ifdef EVERYTHING while ((c = GetPcChar ()) >= 0 ) { if ( c == '\n' || c == '\r' || i == 16 ) break; else tmpStr [i++] = c; } tmpStr [i] = '\0'; ClearPcRxBuffer (); // Clear out receive buffer. if ( MyStrcmp (tmpStr, commandStr [k++], 4) == 0 ) // TEST { PutPcChar ('\n'); PutPcChar ('\r'); PutPcStr (commandStr [0]); PutPcChar ('\n'); PutPcChar ('\r'); } else if ( MyStrcmp (tmpStr, commandStr [k++], 3) == 0 ) // WRD { if ( tmpStr [3] == 0x12 && tmpStr [4] == 0x4d ) { PutPcChar (6); PutPcChar (16); // Signal Vantage station. } } else if ( MyStrcmp (tmpStr, commandStr [k++], 6) == 0 ) // DMPAFT { PutPcChar (0x6); BufferToPage (GetNextRecNo ()/5); if ( FlashReady () ) { if ( FillBuffer (tmpStr, 6) == 0 ) { if ( GetCrc () == 0 ) { if ( *((int *)tmpStr) == 0 ) // Give them everything. n = -1; else { n = FindRecord (*((int *)tmpStr), *((int*)(tmpStr+2)) ); currentState.screenUpdate = 1; // Find record uses lcd memory. } PutPcChar (0x6); DumpAfter (n); } else PutPcChar (0x18); } else { PutPcChar (0x21); } } else PutPcChar (0x44); // Flash not ready. } else if ( MyStrcmp (tmpStr, commandStr [k++], 6) == 0 ) // CALFIX { PutPcChar (0x6); if ( FillBuffer (tmpStr, 45) == 0 ) { if ( GetCrc () == 0 ) { SetRealityCheck (0); PutTempIn (*((int *) (tmpStr)), CURRENT); PutTempOut (*((int *) (tmpStr+2)), CURRENT); for (i = 0; i < 15; i++) PutTemp (*((int *) (tmpStr+2+i*2)), i, CURRENT); PutHumIn (tmpStr [34], CURRENT); for (i = 0; i < 8; i++) PutHum (tmpStr [35+i], i, CURRENT); SetRealityCheck (1); PutPcChar (0x6); ShowScreen (); } else PutPcChar (0x18); } else { PutPcChar (0x21); } } else if ( MyStrcmp (tmpStr, commandStr [k++], 5) == 0 ) // CALED { PutPcChar (0x6); SendCaledData (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 7) == 0 ) // PUTRAIN { PutPcChar (0x6); x = StrToInt (tmpStr+8); PutRain (x, YEAR); ShowScreen (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 5) == 0 ) // PUTET { PutPcChar (0x6); x = StrToInt (tmpStr+6); PutEt (x, YEAR); ShowScreen (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 6) == 0 ) // TXTEST { Ok (); SoftRxOff (); currentState.testtx = 1; SetupSoftTx (); SendPacket (); while (1) { if ( GetKey () == KEY_DONE ) break; if ( GetPcChar () == 'Q' ) break; } currentState.testtx = 0; currentState.softTxOn = 0; SoftRxOff (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 3) == 0 ) // DMP { PutPcChar (0x6); i = 0; do { ReadPage (i, (char)(i & 0xFF)); if ( (c = GetPcCharWithWait (10)) == 0x6 ) // ACK { i++; } else if ( c == 21 ) // NAK continue; else if ( c == 27 ) // ESC break; else break; } while (i < 512); } else if ( MyStrcmp (tmpStr, commandStr [k++], 6) == 0 ) // PAGEWR { PutPcChar (0x6); c = StrToInt (tmpStr+7); // Get the page number. if ( WritePage (c) == 0 ) PutPcChar (0x6); else PutPcChar (0x21); } else if ( MyStrcmp (tmpStr, commandStr [k++], 6) == 0 ) // PAGERD { PutPcChar (0x6); c = StrToInt (tmpStr+7); // Get the page number. ReadPage (c, 0); } else if ( MyStrcmp (tmpStr, commandStr [k++], 6) == 0 ) // BUFFWR { PutPcChar (0x6); BufferToPage (GetNextRecNo ()/5); } else if ( MyStrcmp (tmpStr, commandStr [k++], 6) == 0 ) // BUFFRD { PutPcChar (0x6); ReadBuffer (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 4) == 0 ) // BAUD { i = StrToInt (tmpStr+5); k = 6; switch (i) { case 1200: // 1200 UBRR = 95; k = 0; break; case 2400: // 2400 UBRR = 47; k = 1; break; case 4800: // 4800 UBRR = 23; k = 2; break; case 9600: // 9600 UBRR = 11; k = 3; break; case 14400: // 14400 UBRR = 7; k = 4; break; case 19200: // 19200 UBRR = 5; k = 5; break; } if ( k < 6 ) { _EEPUT (BAUD_RATE, k); Ok (); } else No (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 4) == 0 ) // KICK { while (1) { if ( GetPcChar () > 0 ) break; PutPcChar (0x55); } } else if ( MyStrcmp (tmpStr, commandStr [k++], 5) == 0 ) // BARON { PutPcChar (0x6); BarPowerOn (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 5) == 0 ) // BAROFF { PutPcChar (0x6); BarPowerOff (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 4) == 0 ) // BAR= { i = StrToInt (tmpStr+4); n = StrToInt (tmpStr+5+MyStrlen (tmpStr+4)); if ( PutElevation (n) < 0 ) { PutPcChar (0x21); } else { if ( PCSetBar (i) == 0 ) { Ok (); ShowScreen (); } else PutPcChar (0x21); } } else if ( MyStrcmp (tmpStr, commandStr [k++], 7) == 0 ) // BARREAD { Ok (); StartBarConv (); while (1) { if ( adStuff.barPowerOk ) { ReadBar (); if ( adStuff.samples == 10000 ) // Done converting bar. { PutBar (i = CalcBar (), CURRENT); MakeStr (i, (char *)tmpStr); ReverseStr ((char *) tmpStr); PutPcRAMStr (tmpStr); PutPcChar (10); PutPcChar (13); // BarPowerOff (); adStuff.readingBar = 0; adStuff.readingSensors = 0; break; } } } } else if ( MyStrcmp (tmpStr, commandStr [k++], 7) == 0 ) // BARDATA { /* static flash char barStr [] [20] = { "BAR %d\n\r", "ELEVATION %d\n\r", "DEW POINT %d\n\r", "VIRTUAL TEMP %d\n\r", "C %d\n\r", "R %d\n\r", "BARCAL %d\n\r", "GAIN %d\n\r", "OFFSET %d\n\r" }; */ Ok (); sprintf_P ((char *) tmpStr, barStr [0], GetBar (CURRENT)); PutPcRAMStr (tmpStr); sprintf_P ((char *) tmpStr, barStr [1], i = GetElevation ()); PutPcRAMStr (tmpStr); sprintf_P ((char *) tmpStr, barStr [2], GetDewPoint (CURRENT)); PutPcRAMStr (tmpStr); sprintf_P ((char *) tmpStr, barStr [3], GetVirtualTemp ()); PutPcRAMStr (tmpStr); sprintf_P ((char *) tmpStr, barStr [4], CalcBarC (i)); PutPcRAMStr (tmpStr); sprintf_P ((char *) tmpStr, barStr [5], (int)(GetLastBarR () * 1000+.5)); PutPcRAMStr (tmpStr); sprintf_P ((char *) tmpStr, barStr [6], GetBar (CAL)); PutPcRAMStr (tmpStr); EEIntRead (BAR_GAIN, i); EEIntRead (BAR_OFFSET, n); sprintf_P ((char *) tmpStr, barStr [7], i); PutPcRAMStr (tmpStr); sprintf_P ((char *) tmpStr, barStr [8], n); PutPcRAMStr (tmpStr); } /* else if ( MyStrcmp (tmpStr, commandStr [k++], 4) == 0 ) // TXON { PutPcChar (0x6); SoftRxOff (); SetupSoftTx (); currentState.txOn = 1; } else if ( MyStrcmp (tmpStr, commandStr [k++], 4) == 0 ) // TXOFF { PutPcChar (0x6); SoftRxOn (1); currentState.txOn = 0; } else if ( MyStrcmp (tmpStr, commandStr [k++], 3) == 0 ) // OFF { PutPcChar (0x6); currentState.packetStrOff = 1; } else if ( MyStrcmp (tmpStr, commandStr [k++], 2) == 0 ) // ON { PutPcChar (0x6); currentState.packetStrOff = 0; } */ else if ( MyStrcmp (tmpStr, commandStr [k++], 6) == 0 ) // CLRLOG { if ( EraseFlash () == 0 ) PutPcChar (0x6); else PutPcChar (0x21); PageToBuffer (0); // Make sure buffer is clear. ClearLogAccums (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 7) == 0 ) // SETTIME { PutPcChar (0x6); if ( FillBuffer (tmpStr, 8) == 0 ) { if ( GetCrc () == 0 ) { PutPcChar (0x6); clock.sec = tmpStr [0]; clock.min = tmpStr [1]; clock.hour = tmpStr [2]; clock.day = tmpStr [3]; clock.month = tmpStr [4]; clock.year = 1900 + tmpStr [5]; SaveClock (); DoNewSetupStuff (); ShowScreen (); } else PutPcChar (0x18); // CRC check failed. } else PutPcChar (0x21); } else if ( MyStrcmp (tmpStr, commandStr [k++], 7) == 0 ) // GETTIME { PutPcChar (0x6); ClearCrc (); // Protect... PutPcChar (CrcAccum (clock.sec)); PutPcChar (CrcAccum (clock.min)); PutPcChar (CrcAccum (clock.hour)); PutPcChar (CrcAccum (clock.day)); PutPcChar (CrcAccum (clock.month)); PutPcChar (CrcAccum (clock.year-1900)); PutPcCrc (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 7) == 0 ) // NEXTLOG { } else if ( MyStrcmp (tmpStr, commandStr [k++], 6) == 0 ) // SETPER { n = StrToInt (tmpStr+7); _EEPUT (ARCHIVE_PERIOD, n); currentState.logPeriod = GetArchivePeriod (); if ( currentState.logPeriod == n ) Ok (); else PutPcChar (0x21); // SynchLogTimer (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 4) == 0 ) // STOP { Ok (); currentState.logOff = 1; } else if ( MyStrcmp (tmpStr, commandStr [k++], 5) == 0 ) // START { Ok (); currentState.logOff = 0; } else if ( MyStrcmp (tmpStr, commandStr [k++], 5) == 0 ) // RECRD { PutPcChar (0x6); GetRecord (tmpStr [5] + (tmpStr [6] << 8), 0, 52); PutPcCrc (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 5) == 0 ) // RECWR { currentState.screenUpdate = 1; PutPcChar (0x6); n = StrToInt (tmpStr+6); // Get the variable to clear. timeOutSec = 0; i = 0; while ( timeOutSec < 3 ) { if ( (c = GetPcChar ()) >= 0 ) { sharedMem.displayMemory [i++] = c; timeOutSec = 0; // Reset... if ( i == 52 ) break; } } if ( WriteRecord (n) == 0 ) if ( i == 52 ) { PutPcChar (0x6); SetNextRecNo (n+1); // Wrap checked in SetNextRecNo. } } else if ( MyStrcmp (tmpStr, commandStr [k++], 6) == 0 ) // NEWDAY { PutPcChar (0x6); timerStuff.newDay = 1; } else if ( MyStrcmp (tmpStr, commandStr [k++], 5) == 0 ) // CLREE { Ok (); ClearAll (0); Done (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 5) == 0 ) // GETEE { PutPcChar (0x6); GetEEPROMData (0, 4096); } /* else if ( MyStrcmp (tmpStr, commandStr [k++], 7) == 0 ) // RXCHECK { sprintf_P ((char *)tmpStr, rxCheckStr [0], totalReceived [currentState.currentStation-1] ); PutPcRAMStr (tmpStr); sprintf_P ((char *)tmpStr, rxCheckStr [1], totalResynchs [currentState.currentStation-1] ); PutPcRAMStr (tmpStr); sprintf_P ((char *)tmpStr, rxCheckStr [2], totalMisses [currentState.currentStation-1] ); PutPcRAMStr (tmpStr); sprintf_P ((char *)tmpStr, rxCheckStr [3], timeOutMisses [currentState.currentStation-1] ); PutPcRAMStr (tmpStr); sprintf_P ((char *)tmpStr, rxCheckStr [4], goodStreak [currentState.currentStation-1] ); PutPcRAMStr (tmpStr); sprintf_P ((char *)tmpStr, rxCheckStr [5], nCrcErrors); PutPcRAMStr (tmpStr); sprintf_P ((char *)tmpStr, rxCheckStr [6], maxSaveAfter [currentState.currentStation-1] ); PutPcRAMStr (tmpStr); sprintf_P ((char *)tmpStr, rxCheckStr [7], maxInARow [currentState.currentStation-1] ); PutPcRAMStr (tmpStr); } else if ( MyStrcmp (tmpStr, commandStr [k++], 5) == 0 ) // RXBUG { "OCR1A %d\n\r", // 6 "softBitsReceived %d\n\r", // 7 "nextByte %d\n\r", // 8 "TICIE1 is on.\n\r", // 9 "softRxOn is on. \n\r" // 10 sprintf_P ((char *)tmpStr, errorStr [6], OCR1A); PutPcRAMStr (tmpStr); sprintf_P ((char *)tmpStr, errorStr [7], softBitsReceived); PutPcRAMStr (tmpStr); sprintf_P ((char *)tmpStr, errorStr [8], nextByte); PutPcRAMStr (tmpStr); if ( CheckBit(TIMSK, TICIE1) ) PutPcStr (errorStr [9]); if ( currentState.softRxOn ) PutPcStr (errorStr [10]); sprintf_P ((char *)tmpStr, errorStr [11], TCCR1A); PutPcRAMStr (tmpStr); sprintf_P ((char *)tmpStr, errorStr [12], TCCR1B); PutPcRAMStr (tmpStr); sprintf_P ((char *)tmpStr, errorStr [15], softStatusBits); PutPcRAMStr (tmpStr); sprintf_P ((char *)tmpStr, errorStr [16], TIMSK); PutPcRAMStr (tmpStr); sprintf_P ((char *)tmpStr, errorStr [17], bufferStatusBits); PutPcRAMStr (tmpStr); sprintf_P ((char *)tmpStr, errorStr [18], DDRD); PutPcRAMStr (tmpStr); } */ else if ( MyStrcmp (tmpStr, commandStr [k++], 5) == 0 ) // SETA { PutPcChar (6); if ( FillBuffer (tmpStr, 50) == 0 ) { if ( GetCrc () == 0 ) { PutPcChar (6); } else { PutPcChar (0x21); } } } else if ( MyStrcmp (tmpStr, commandStr [k++], 5) == 0 ) // GETA { PutPcChar (6); ClearCrc (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 4) == 0 ) // EEWR { Ok (); MakeUpper ((char *) tmpStr); addr = StrToHex (tmpStr+5); n = StrToHex (tmpStr+6+MyStrlen (tmpStr+5)); _EEPUT (addr, n); } else if ( MyStrcmp (tmpStr, commandStr [k++], 4) == 0 ) // EERD startAddr n { Ok (); MakeUpper ((char *) tmpStr); addr = StrToHex (tmpStr+5); n = StrToHex (tmpStr+6+MyStrlen (tmpStr+5)); ClearCrc (); for (i = 0; i < n; i++) { _EEGET (x, i+addr); PutPcHex (CrcAccum (x)); PutPcChar (10); PutPcChar (13); } } else if ( MyStrcmp (tmpStr, commandStr [k++], 5) == 0 ) // CALON { currentState.calMode = 1; PutPcChar (6); } else if ( MyStrcmp (tmpStr, commandStr [k++], 6) == 0 ) // CALOFF { currentState.calMode = 0; Ok (); StartBarConv (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 6) == 0 ) // ADREAD { Ok (); n = tmpStr [7] - '0'; // Get the channel number. i = StrToInt (tmpStr+9); MakeStr (ReadChannel (n, i), (char *)tmpStr); ReverseStr ((char *) tmpStr); PutPcRAMStr (tmpStr); PutPcChar (10); PutPcChar (13); } else if ( MyStrcmp (tmpStr, commandStr [k++], 6) == 0 ) // STRMON { Ok (); currentState.streamPackets = 1; } else if ( MyStrcmp (tmpStr, commandStr [k++], 7) == 0 ) // STRMOFF { Ok (); currentState.streamPackets = 0; } else if ( MyStrcmp (tmpStr, commandStr [k++], 7) == 0 ) // CLKON { Ok (); TCCR0 |= 0x13; // 4 ticks per second. Outputcompare on. } else if ( MyStrcmp (tmpStr, commandStr [k++], 7) == 0 ) // CLKOFF { Ok (); TCCR0 = 0x3; // 4 ticks per second. Outputcompare off. } /* else if ( MyStrcmp (tmpStr, commandStr [k++], 6) == 0 ) // STACFG { Ok (); for (i = 0; i < 8; i++) { _EEGET (c, STATION_LIST+(i<<1)); if ( c > MAX_STATION_TYPE ) PutPcStr (typeStr [MAX_STATION_TYPE+1]); else PutPcStr (typeStr [c]); PutPcChar (10); PutPcChar (13); if ( c == TEMP_STA || c == TEMP_HUM_STA || c == HUM_STA ) { _EEGET (c, STATION_LIST+(i<<1)+1); PutPcHex (c); PutPcChar (10); PutPcChar (13); } } } */ else if ( MyStrcmp (tmpStr, commandStr [k++], 6) == 0 ) // CLRALM { Ok (); ClearAlarms (0); Done (); ShowScreen (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 6) == 0 ) // CLRCAL { Ok (); ClearCalNums (); Done (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 6) == 0 ) // CLRGRA { Ok (); ClearGraphData (0); Done (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 3) == 0 ) // VER { Ok (); PutPcStr (dateStr); PutPcChar (' '); PutPcStr (timeStr); PutPcChar ('\n'); PutPcChar ('\r'); } else if ( MyStrcmp (tmpStr, commandStr [k++], 5) == 0 ) // EEBWR startAddr n { PutPcChar (6); addr = StrToHex (tmpStr+6); n = StrToHex (tmpStr+7+MyStrlen (tmpStr+6)); if ( FillBuffer (tmpStr, n+2) == 0 ) { if ( GetCrc () == 0 ) { PutPcChar (6); for (i = 0; i < n; i++) _EEPUT (addr+i, tmpStr [i]); } else PutPcChar (0x21); } } else if ( MyStrcmp (tmpStr, commandStr [k++], 5) == 0 ) // EEBRD startAddr n { PutPcChar (6); addr = StrToHex (tmpStr+6); n = StrToHex (tmpStr+7+MyStrlen (tmpStr+6)); ClearCrc (); for (i = 0; i < n; i++) { _EEGET (x, i+addr); PutPcChar (CrcAccum (x)); } PutPcCrc (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 6) == 0 ) // CLRVAR { PutPcChar (6); i = StrToInt (tmpStr+7); // Get the variable to clear. ClearVar (i); ShowScreen (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 8) == 0 ) // CLRHIGHS { PutPcChar (6); i = StrToInt (tmpStr+9); // Get the span to clear. switch (i) { case 0 : // Day stuff ClearHighs (); break; case 1 : // Month stuff ClearMonthHighs (); break; case 2 : // Year stuff ClearYearHighs (); break; } ShowScreen (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 8) == 0 ) // CLRLOWS { PutPcChar (6); i = StrToInt (tmpStr+8); // Get the span to clear. switch (i) { case 0 : // Day stuff ClearLows (); break; case 1 : // Month stuff ClearMonthLows (); break; case 2 : // Year stuff ClearYearLows (); break; } ShowScreen (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 7) == 0 ) // CLRBITS { PutPcChar (6); ClearAlarmBits (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 7) == 0 ) // CLRDATA { PutPcChar (6); ClearData (); ClearRain (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 4) == 0 ) // LOOP { PutPcChar (6); currentState.loopsLeft = StrToInt (tmpStr+5); // Get the variable to clear. if ( currentState.loopsLeft > 0 ) { SendLoop (GetNextRecNo ()); currentState.loopsLeft--; serialPortTimeOut = 0; /* Wait for data to be sent out the shift register. */ while (CheckBit(USR,TXC) == 0 ); return; } } else if ( MyStrcmp (tmpStr, commandStr [k++], 6) == 0 ) // HILOWS { PutPcChar (6); SendHighLows (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 3) == 0 ) // LOG { PutPcChar (6); LogData (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 8) == 0 ) // NEWSETUP { PutPcChar (6); _EEGET (setupBits.Byte, SETUP_BITS); DoNewSetupStuff (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 5) == 0 ) // SLEEP { /* Used in initial test to make sure serial port wakeup works. */ Ok (); WaitFor (3); // Let RC charge up. TCCR0 = 0; // Stop 32khz from waking us up. TIMSK &= 0xfe; // Disable the interrupt. currentState.serialPortWakeup = 0; Sleep (); TCCR0 |= 0x3; // Divide CS by 32. 4 ticks per second... TIMSK |= 1; // Enable the interrupt. SoftRxOn (1); // Just in case turned on in middle of SoftRXOff () above. if ( currentState.serialPortWakeup ) PutPcChar ('Y'); else PutPcChar ('N'); currentState.serialPortWakeup = 0; } else if ( MyStrcmp (tmpStr, commandStr [k++], 7) == 0 ) // MEASHUM { /* Used in initial test to check humidity is within range. */ Ok (); MeasureHum (); MakeStr (humCounts, (char *) tmpStr); ReverseStr ((char *) tmpStr); PutPcRAMStr (tmpStr); PutPcChar (10); PutPcChar (13); } else if ( MyStrcmp (tmpStr, commandStr [k++], 5) == 0 ) // HUM33 { MeasureLowHum (33); Ok (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 5) == 0 ) // HUM80 { MeasureHighHum (80); Ok (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 6) == 0 ) // HUMLOW { i = StrToInt (tmpStr+7); // Get the span to clear. MeasureLowHum (i); Ok (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 5) == 0 ) // HUMHI { i = StrToInt (tmpStr+6); // Get the span to clear. MeasureHighHum (i); Ok (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 7) == 0 ) // HUMCALC { Ok (); MeasureHum (); MakeStr (CalcHum (humCounts), (char *) tmpStr); ReverseStr ((char *) tmpStr); PutPcRAMStr (tmpStr); PutPcChar (10); PutPcChar (13); } else if ( MyStrcmp (tmpStr, commandStr [k++], 3) == 0 ) // POW X { /* Used in initial test to check current. */ Ok (); k = StrToHex (tmpStr+4); if ( CheckBit (k, 0) ) // RFM CHIP { SetBit (PORTC, 0); SetBit (PORTC, 1); } else { ClrBit (PORTC, 0); ClrBit (PORTC, 1); } if ( CheckBit (k, 1) ) // RFM GAIN SetBit (PORTC, 2); else ClrBit (PORTC, 2); if ( CheckBit (k, 2) ) // HUM CIRCUIT SetBit (PORTD, 5); else ClrBit (PORTD, 5); if ( CheckBit (k, 4) ) // Bar power. BarPowerOn (); else BarPowerOff (); if ( CheckBit (k, 3) ) // ~VREF SetBit (PORTD, 6); else ClrBit (PORTD, 6); } else if ( MyStrcmp (tmpStr, commandStr [k++], 3) == 0 ) // PORT P X { /* Used in initial test to I/O pins. */ Ok (); k = StrToHex (tmpStr+7); switch (tmpStr [5]) { case 'A': PORTA = k; break; case 'B': PORTB = k; break; case 'C': PORTC = k; break; case 'D': PORTD = k; break; case 'E': PORTE = k; break; } } else if ( MyStrcmp (tmpStr, commandStr [k++], 5) == 0 ) // LAMPS 0|1 { Ok (); if ( StrToInt (tmpStr+6) ) SetBit (PORTB, 4); else ClrBit (PORTB, 4); } else if ( MyStrcmp (tmpStr, commandStr [k++], 7) == 0 ) // CHECKEE { Ok (); /* Make sure address lines are not shorted. */ /* Make sure address lines are not shorted. */ addr = 1; for (i = 0; i < 12; i++) { _EEPUT (addr, i); addr = addr << 1; } addr = 1; for (i = 0; i < 12; i++) { _EEGET (k, addr); if ( k == i) { addr = addr << 1; } else return; } Ok (); /* Make sure each bit can be set low. */ for (i = 0; i < 4096; i++) { _EEPUT (i, 0); } for (i = 0; i < 4096; i++) { _EEGET (k, i); if ( k == 0) { // Good. } else return; } /* Make sure each bit can be set high. */ Ok (); for (i = 0; i < 4096; i++) { _EEPUT (i, 0xff); } for (i = 0; i < 4096; i++) { _EEGET (k, i); if ( k == 0xff) { // Good. } else return; } Ok (); } else if ( MyStrcmp (tmpStr, commandStr [k++], 9) == 0 ) // RECEIVERS { Ok (); PutPcChar (currentState.fromTx); } else // COMMAND NOT FOUND { PutPcChar (10); PutPcChar (13); currentState.loopsLeft = 0; // Get the variable to clear. } serialPortTimeOut = 120; // Stay on for 2 minutes. #endif } STATION EEPROM DATA ------------------- #define SETUP_START 1 #define BAR_GAIN SETUP_START #define BAR_OFFSET SETUP_START+2 #define BAR_CAL SETUP_START+4 #define HUM33 SETUP_START+6 #define HUM80 SETUP_START+8 #define LATITUDE SETUP_START+10 #define LONGITUDE SETUP_START+12 #define ELEVATION SETUP_START+14 #define TIME_ZONE SETUP_START+16 #define MANUAL_OR_AUTO SETUP_START+17 #define DAYLIGHT_SAVINGS SETUP_START+18 #define GMT_OFFSET SETUP_START+19 #define GMT_OR_ZONE SETUP_START+21 #define USETX SETUP_START+22 #define RE_TRANSMIT_TX SETUP_START+23 /* Use 16 bytes. First byte is station type. Second byte is sensor no. for temp and hum. Upper nibble is hum sensor no. Lower nibble is temp sensor no. */ #define STATION_LIST SETUP_START+24 #define UNIT_BITS SETUP_START+40 #define UNIT_BITS_COMP SETUP_START+41 #define SETUP_BITS SETUP_START+42 #define RAIN_SEASON_START SETUP_START+43 #define ARCHIVE_PERIOD SETUP_START+44 #define TIMECAL SETUP_START+45 #define TIMECAL_COMP SETUP_START+46 // 1's complement of TIMECAL #define HUM_AT_LOW_CAL SETUP_START+47 #define HUM_AT_HI_CAL SETUP_START+48 /* CAL are 8 bit signed numbers. */ #define CAL_START HUM_AT_HI_CAL+1 #define TEMP_IN_CAL CAL_START #define TEMP_IN_COMP CAL_START+1 #define TEMP_OUT_CAL CAL_START+2 #define TEMP_CAL CAL_START+3 #define HUM_IN_CAL CAL_START+18 #define HUM_CAL CAL_START+19 #define DIR_CAL CAL_START+27 #define DEFAULT_BAR_GRAPH CAL_START+29 #define DEFAULT_RAIN_GRAPH CAL_START+30 #define DEFAULT_SPEED_GRAPH CAL_START+31 #define ALARM_START CAL_START+32 #define BAR_RISE_A_X ALARM_START #define BAR_FALL_A_X ALARM_START+1 #define TIME_A_X ALARM_START+2 #define TIME_COMP_A_X ALARM_START+4 #define LOW_TEMP_IN_A_X ALARM_START+6 #define HIGH_TEMP_IN_A_X ALARM_START+7 #define LOW_TEMP_OUT_A_X ALARM_START+8 #define HIGH_TEMP_OUT_A_X ALARM_START+9 #define LOW_TEMP_A_X ALARM_START+10 #define HIGH_TEMP_A_X ALARM_START+25 #define LOW_HUM_IN_A_X ALARM_START+40 #define HIGH_HUM_IN_A_X ALARM_START+41 #define LOW_HUM_A_X ALARM_START+42 #define HIGH_HUM_A_X ALARM_START+50 #define LOW_DEW_A_X ALARM_START+58 #define HIGH_DEW_A_X ALARM_START+59 #define CHILL_A_X ALARM_START+60 #define HEAT_A_X ALARM_START+61 #define THSW_A_X ALARM_START+62 #define SPEED_A_X ALARM_START+63 #define SPEED_10MIN_A_X ALARM_START+64 #define UV_A_X ALARM_START+65 #define UV_DOSE_A_X ALARM_START+66 #define LOW_SOIL_A_X ALARM_START+67 #define HIGH_SOIL_A_X ALARM_START+71 #define LOW_LEAF_A_X ALARM_START+75 #define HIGH_LEAF_A_X ALARM_START+79 #define SOLAR_A_X ALARM_START+83 #define RAIN_RATE_A_X ALARM_START+85 #define RAIN_15MIN_A_X ALARM_START+87 #define RAIN_24HR_A_X ALARM_START+89 #define RAIN_STORM_A_X ALARM_START+91 #define ET_DAY_A_X ALARM_START+93 #define GRAPH_START ET_DAY_A_X+1 #define NEXT_10MIN_PTR GRAPH_START+1 #define NEXT_15MIN_PTR GRAPH_START+2 #define NEXT_HOUR_PTR GRAPH_START+3 #define NEXT_DAY_PTR GRAPH_START+4 #define NEXT_MONTH_PTR GRAPH_START+5 #define NEXT_YEAR_PTR GRAPH_START+6 #define NEXT_RAIN_STORM_PTR GRAPH_START+7 #define NEXT_RAIN_YEAR_PTR GRAPH_START+8 #define START GRAPH_START+9 // NUMBER NUMBER // OF OF // ENTRYS BYTES // -------------- #define TEMP_IN_HOUR START + 0 // 24 || 1 #define TEMP_IN_DAY_HIGHS START + 24 // 24 || 1 #define TEMP_IN_DAY_HIGH_TIMES START + 48 // 24 || 2 #define TEMP_IN_DAY_LOWS START + 96 // 24 || 1 #define TEMP_IN_DAY_LOW_TIMES START + 120 // 24 || 2 #define TEMP_IN_MONTH_HIGHS START + 168 // 25 || 1 #define TEMP_IN_MONTH_LOWS START + 193 // 25 || 1 #define TEMP_IN_YEAR_HIGHS START + 218 // 1 || 1 #define TEMP_IN_YEAR_LOWS START + 219 // 1 || 1 #define TEMP_OUT_HOUR START + 220 // 24 || 1 #define TEMP_OUT_DAY_HIGHS START + 244 // 24 || 1 #define TEMP_OUT_DAY_HIGH_TIMES START + 268 // 24 || 2 #define TEMP_OUT_DAY_LOWS START + 316 // 24 || 1 #define TEMP_OUT_DAY_LOW_TIMES START + 340 // 24 || 2 #define TEMP_OUT_MONTH_HIGHS START + 388 // 25 || 1 #define TEMP_OUT_MONTH_LOWS START + 413 // 25 || 1 #define TEMP_OUT_YEAR_HIGHS START + 438 // 25 || 1 #define TEMP_OUT_YEAR_LOWS START + 463 // 25 || 1 #define DEW_HOUR START + 488 // 24 || 1 #define DEW_DAY_HIGHS START + 512 // 24 || 1 #define DEW_DAY_HIGH_TIMES START + 536 // 24 || 2 #define DEW_DAY_LOWS START + 584 // 24 || 1 #define DEW_DAY_LOW_TIMES START + 608 // 24 || 2 #define DEW_MONTH_HIGHS START + 656 // 25 || 1 #define DEW_MONTH_LOWS START + 681 // 25 || 1 #define DEW_YEAR_HIGHS START + 706 // 1 || 1 #define DEW_YEAR_LOWS START + 707 // 1 || 1 #define CHILL_HOUR START + 708 // 24 || 1 #define CHILL_DAY_LOWS START + 732 // 24 || 1 #define CHILL_DAY_LOW_TIMES START + 756 // 24 || 2 #define CHILL_MONTH_LOWS START + 804 // 25 || 1 #define CHILL_YEAR_LOWS START + 829 // 1 || 1 #define THSW_HOUR START + 830 // 24 || 1 #define THSW_DAY_HIGHS START + 854 // 24 || 1 #define THSW_DAY_HIGH_TIMES START + 878 // 24 || 2 #define THSW_MONTH_HIGHS START + 926 // 25 || 1 #define THSW_YEAR_HIGHS START + 951 // 1 || 1 #define HEAT_HOUR START + 952 // 24 || 1 #define HEAT_DAY_HIGHS START + 976 // 24 || 1 #define HEAT_DAY_HIGH_TIMES START + 1000 // 24 || 2 #define HEAT_MONTH_HIGHS START + 1048 // 25 || 1 #define HEAT_YEAR_HIGHS START + 1073 // 1 || 1 #define HUM_IN_HOUR START + 1074 // 24 || 1 #define HUM_IN_DAY_HIGHS START + 1098 // 24 || 1 #define HUM_IN_DAY_HIGH_TIMES START + 1122 // 24 || 2 #define HUM_IN_DAY_LOWS START + 1170 // 24 || 1 #define HUM_IN_DAY_LOW_TIMES START + 1194 // 24 || 2 #define HUM_IN_MONTH_HIGHS START + 1242 // 25 || 1 #define HUM_IN_MONTH_LOWS START + 1267 // 25 || 1 #define HUM_IN_YEAR_HIGHS START + 1292 // 1 || 1 #define HUM_IN_YEAR_LOWS START + 1293 // 1 || 1 #define HUM_OUT_HOUR START + 1294 // 24 || 1 #define HUM_OUT_DAY_HIGHS START + 1318 // 24 || 1 #define HUM_OUT_DAY_HIGH_TIMES START + 1342 // 24 || 2 #define HUM_OUT_DAY_LOWS START + 1390 // 24 || 1 #define HUM_OUT_DAY_LOW_TIMES START + 1414 // 24 || 2 #define HUM_OUT_MONTH_HIGHS START + 1462 // 25 || 1 #define HUM_OUT_MONTH_LOWS START + 1487 // 25 || 1 #define HUM_OUT_YEAR_HIGHS START + 1512 // 1 || 1 #define HUM_OUT_YEAR_LOWS START + 1513 // 1 || 1 #define BAR_15_MIN START + 1514 // 24 || 2 #define BAR_HOUR START + 1562 // 24 || 2 #define BAR_DAY_HIGHS START + 1610 // 24 || 2 #define BAR_DAY_HIGH_TIMES START + 1658 // 24 || 2 #define BAR_DAY_LOWS START + 1706 // 24 || 2 #define BAR_DAY_LOW_TIMES START + 1754 // 24 || 2 #define BAR_MONTH_HIGHS START + 1802 // 25 || 2 #define BAR_MONTH_LOWS START + 1852 // 25 || 2 #define BAR_YEAR_HIGHS START + 1902 // 1 || 2 #define BAR_YEAR_LOWS START + 1904 // 1 || 2 #define WIND_SPEED_10_MIN_AVG START + 1906 // 24 || 1 #define WIND_SPEED_HOUR_AVG START + 1930 // 24 || 1 #define WIND_SPEED_DAY_HIGHS START + 1954 // 24 || 1 #define WIND_SPEED_DAY_HIGH_TIMES START + 1978 // 24 || 2 #define WIND_SPEED_DAY_HIGH_DIR START + 2026 // 24 || 1 #define WIND_SPEED_MONTH_HIGHS START + 2050 // 25 || 1 #define WIND_SPEED_MONTH_HIGH_DIR START + 2075 // 25 || 1 #define WIND_SPEED_YEAR_HIGHS START + 2100 // 25 || 1 #define WIND_SPEED_YEAR_HIGH_DIR START + 2125 // 25 || 1 #define WIND_DIR_HOUR START + 2150 // 24 || 1 #define WIND_DIR_DAY START + 2174 // 24 || 1 #define WIND_DIR_MONTH START + 2198 // 24 || 1 #define WIND_DIR_DAY_BINS START + 2222 // 8 || 2 #define WIND_DIR_MONTH_BINS START + 2238 // 8 || 2 #define RAIN_RATE_1_MIN START + 2254 // 24 || 2 #define RAIN_RATE_HOUR START + 2302 // 24 || 2 #define RAIN_RATE_DAY_HIGHS START + 2350 // 24 || 2 #define RAIN_RATE_DAY_HIGH_TIMES START + 2398 // 24 || 2 #define RAIN_RATE_MONTH_HIGHS START + 2446 // 25 || 2 #define RAIN_RATE_YEAR_HIGHS START + 2496 // 25 || 2 #define RAIN_15_MIN START + 2546 // 24 || 1 #define RAIN_HOUR START + 2570 // 24 || 2 #define RAIN_STORM START + 2618 // 25 || 2 #define RAIN_STORM_START START + 2668 // 25 || 2 #define RAIN_STORM_END START + 2718 // 25 || 2 #define RAIN_DAY_TOTAL START + 2768 // 25 || 2 #define RAIN_MONTH_TOTAL START + 2818 // 25 || 2 #define RAIN_YEAR_TOTAL START + 2868 // 25 || 2 #define ET_HOUR START + 2918 // 24 || 1 #define ET_DAY_TOTAL START + 2942 // 25 || 1 #define ET_MONTH_TOTAL START + 2967 // 25 || 2 #define ET_YEAR_TOTAL START + 3017 // 25 || 2 #define SOLAR_HOUR_AVG START + 3067 // 24 || 2 #define SOLAR_DAY_HIGHS START + 3115 // 24 || 2 #define SOLAR_DAY_HIGH_TIMES START + 3163 // 24 || 2 #define SOLAR_MONTH_HIGHS START + 3211 // 25 || 2 #define SOLAR_YEAR_HIGHS START + 3261 // 1 || 2 #define UV_HOUR_AVG START + 3263 // 24 || 1 #define UV_MEDS_HOUR START + 3287 // 24 || 1 #define UV_MEDS_DAY START + 3311 // 24 || 1 #define UV_DAY_HIGHS START + 3335 // 24 || 1 #define UV_DAY_HIGH_TIMES START + 3359 // 24 || 2 #define UV_MONTH_HIGHS START + 3407 // 25 || 1 #define UV_YEAR_HIGHS START + 3432 // 1 || 1 #define LEAF_HOUR START + 3433 // 24 || 1 #define LEAF_DAY_LOWS START + 3457 // 24 || 1 #define LEAF_DAY_LOW_TIMES START + 3481 // 24 || 2 #define LEAF_DAY_HIGHS START + 3529 // 24 || 1 #define LEAF_DAY_HIGH_TIMES START + 3553 // 24 || 2 #define WIND_SPEED_HOUR_HIGHS START + 3601 // 24 || 1 #define LEAF_MONTH_LOWS START + 3625 // 1 || 1 #define LEAF_MONTH_HIGHS START + 3626 // 25 || 1 #define LEAF_YEAR_LOWS START + 3651 // 1 || 1 #define LEAF_YEAR_HIGHS START + 3652 // 1 || 1 #define SOIL_HOUR START + 3653 // 24 || 1 #define SOIL_DAY_LOWS START + 3677 // 24 || 1 #define SOIL_DAY_LOW_TIMES START + 3701 // 24 || 2 #define SOIL_DAY_HIGHS START + 3749 // 24 || 1 #define SOIL_DAY_HIGH_TIMES START + 3773 // 24 || 2 #define SOIL_MONTH_LOWS START + 3821 // 25 || 1 #define SOIL_MONTH_HIGHS START + 3846 // 25 || 1 #define SOIL_YEAR_LOWS START + 3871 // 1 || 1 #define SOIL_YEAR_HIGHS START + 3872 // 1 || 1 #define SOIL_YEAR_HIGHS_COMP START + 3873 // 1 || 1 #define RX_PERCENTAGE START + 3874 // 24 || 1 #define SAVE_MIN RX_PERCENTAGE+25 #define SAVE_HOUR SAVE_MIN+1 #define SAVE_DAY SAVE_HOUR+1 #define SAVE_MONTH SAVE_HOUR+2 #define SAVE_YEAR SAVE_HOUR+3 #define SAVE_YEAR_COMP SAVE_HOUR+4 #define BAUD_RATE SAVE_HOUR+5 #define DEFAULT_RATE_GRAPH SAVE_HOUR+6 STATION RAM DATA ----------------- static int bar; //------------------ static int lowBar; static int hiBar; static int lowMonthBar; static int hiMonthBar; static int lowYearBar; static int hiYearBar; static int lowBarTime; static int hiBarTime; //------------------ /* Temperature Ranges Parameter: Memory provision: VP catalog statement: Temp In and Out -90 to +164 F -40 to +140 F Dewpoint -120 to +134 F -105 to +130 F Wind Chill -120 to +134 F -120 to +130 F Heat Index -90 to +164 F -40 to +135 F THSW Index -90 to +164 F -90 to +148 F */ // Temp In static int tempIn; static long tempInAccum; // For average inside temp. //------------------ static int hiTempIn; static int lowTempIn; static int hiTempInTime; static int lowTempInTime; static int lowMonthTempIn; static int hiMonthTempIn; static int lowYearTempIn; static int hiYearTempIn; //------------------ // Hum In static char humIn; //------------------ static char hiHumIn; static byte lowHumIn; static int hiHumInTime; static int lowHumInTime; static char hiMonthHumIn; // Stored only for master tx. static byte lowMonthHumIn; static char hiYearHumIn; static byte lowYearHumIn; //------------------ // Temp static long tempOutAccum; // For average outside temp. static int lowTempOutInPer; static int hiTempOutInPer; static int tempOut ; static int lastTempOut; // Used for reality filtering. //------------------ static int lowTempOut ; static int hiTempOut ; static int lowTempOutTime ; static int hiTempOutTime ; static int hiMonthTempOut ; static int lowMonthTempOut ; static int hiYearTempOut ; static int lowYearTempOut ; //------------------ // 0 through 6 extra temps. 7 through 10 leaf temps. 11 through 14 soil temps. static byte temp [15]; static byte lastTemp [15]; //------------------ static byte lowTemp [15]; static byte hiTemp [15]; static int lowTempTime [15]; static int hiTempTime [15]; static byte hiMonthTemp [15]; static byte lowMonthTemp [15]; static byte hiYearTemp [15]; static byte lowYearTemp [15]; //------------------ // Dew Point static int dewPoint ; //------------------ static int lowDewPoint ; static int hiDewPoint ; static int lowDewPointTime ; static int hiDewPointTime ; static int hiMonthDewPoint; static int lowMonthDewPoint; static int hiYearDewPoint; static int lowYearDewPoint; //------------------ // Chill static int lowChillInPer; static long chillHourAccum; static int lowHourChill; static int chill ; //------------------ static int lowChill ; static int lowChillTime ; static int lowMonthChill; static int lowYearChill; //------------------ // Heat Index static int heatIndex ; //------------------ static int hiHeatIndex ; static int hiHeatIndexTime ; static int hiMonthHeatIndex; static int hiYearHeatIndex; //------------------ // THSW Index static int THSWIndex ; //------------------ static int hiTHSWIndex ; static int hiTHSWIndexTime ; static int hiMonthTHSWIndex; static int hiYearTHSWIndex; //------------------ // Wind Speed static long windSpeedAccum; static byte hiSpeedInPer; static byte hiSpeedHour; static unsigned windSpeed10MinAccum; static unsigned windSpeed1MinAccum; static long windSpeedHourAccum; static byte windSpeed; static byte windSpeed10Min; static byte windSpeed1Min [10]; // Keep track of last 10 minutes of speed. static byte lastWindSpeed; //------------------ static byte hiSpeed; static int hiSpeedTime; static byte hiSpeedMonth; static byte hiSpeedYear; //================================================== static byte maxSpeedCheck; static byte maxSpeedCheckDir; static byte lastMaxSpeedCheck; //------------------ static int windDir; static byte dirOfHiSpeedInPer; // Direction of high speed in per. static byte dirOfHiSpeedDay; static byte dirOfHiSpeedMonth; static byte dirOfHiSpeedYear; static int windDirBin [16]; // For the link. static int windDirGraphBin [8]; // For the hour graph on the console. static byte windHistoryBin [16]; static int nextWindDir; static byte lastDirSector; // UV static long uvAccum; static long uvHourAccum; static byte uv ; static byte lastUV ; //------------------ static byte hiUV ; static int hiUVTime ; static byte hiMonthUV; static byte hiYearUV; //------------------ static byte nDoseSamples; static int uvDoseAccum; // Calculate average uv over 1 minute. static long uvExposure; // .0001 MEDS static long uvDoseDay; // .0001 MEDS static unsigned uvDoseHour; // .0001 MEDS // Soil Moist static byte soilMoist [4]; static byte lastSoilMoist [4]; //------------------ static byte hiSoilMoist [4]; static int hiSoilMoistTime [4]; static byte lowSoilMoist [4]; static int lowSoilMoistTime [4]; static byte lowMonthSoilMoist [4]; static byte hiMonthSoilMoist [4]; static byte lowYearSoilMoist [4]; static byte hiYearSoilMoist [4]; //------------------ // Leaf static byte leaf [4]; static byte lastLeaf [4]; //------------------ static char hiLeaf [4]; static int hiLeafTime [4]; static byte lowLeaf [4]; static int lowLeafTime [4]; static byte lowMonthLeaf [4]; static char hiMonthLeaf [4]; static byte lowYearLeaf [4]; static char hiYearLeaf [4]; //------------------ // Solar Rad static long solarAccum; static long solarHourAccum; static long solar10MinAccum; static int solarRad ; static int lastSolarRad ; //------------------ static int hiSolarRad ; static int hiSolarRadTime ; static int hiMonthSolarRad; static int hiYearSolarRad; //------------------ // Rain static byte rainPacketSeen; static byte rawRain ; // Last value received from ISS. static int rainRate ; static int hiRainRateInPer; static int rainInPer; static int rainInHour; static byte rainIn15Min; static byte rainOneMin [15]; // Keep track of last 15 minutes of rain. //static int rainEachHour [24]; // Keep track of last 24 hours of rain. static byte rain3Hours [3] ; // Used for forecast. static int lastRainRate ; //------------------ static int hiRainRate ; static int hiRainRateTime ; static int hiRainRateHour; // For hour graph. static int hiMonthRainRate; static int hiYearRainRate; //------------------ static int rainStorm ; // month | day | year // Bits 15 12 11..7 6..0 static unsigned stormStartDate; static unsigned stormEndDate; static int rainDay ; static int rainMonth ; static int rainYear ; // Et static int etDay; static int etInHour; static int etInPer; static int etMonth; static int etYear; // Hum 0 index used for outsideHum static int humMeas; // Used to debug humidity. static char hum [8]; static int humGain [8]; // Gain of sensor sent by ISS called hum calibration. static byte humGainOk; // Seen same gain twice. static char lastHum [8]; //------------------ static char lowHum [8]; static char hiHum [8]; static int lowHumTime [8]; static int hiHumTime [8]; static char hiMonthHum [8]; static byte lowMonthHum [8]; static char hiYearHum [8]; static byte lowYearHum [8]; //------------------ READING HIGH LOW DATA ---------------------- Use the HILOWS command. /* +-----------------------------------------------------+ */ void SendBlock (byte *ptr, int n) { int i; for (i = 0; i < n; i++) { PutPcCharCrc ( ptr [i] ); } } /* +-----------------------------------------------------+ */ void SendHighLows () { ClearCrc (); SendBlock ((byte *) &lowBar, 16); SendBlock (&hiSpeed, 5); SendBlock ((byte *) &hiTempIn, 16); SendBlock ((byte *) &hiHumIn, 10); SendBlock ((byte *) &lowTempOut, 16); SendBlock ((byte *) &lowDewPoint, 16); SendBlock ((byte *) &lowChill, 8); SendBlock ((byte *) &hiHeatIndex, 8); SendBlock ((byte *) &hiTHSWIndex, 8); SendBlock ((byte *) &hiSolarRad, 8); SendBlock (&hiUV, 5); SendBlock ((byte *) &hiRainRate, 10); SendBlock (lowTemp, 150); SendBlock ((byte *) lowHum, 80 ); SendBlock (hiSoilMoist, 40); SendBlock ((byte *) hiLeaf, 40); PutPcCrc (); } VII DOWNLOAD ------------ The flash memory is orgainzed into 512 pages with each page is 264 bytes in size. Use the DMPAFT command to download data after a certain time and date. You receive whole pages, but DMPAFT will return the number of pages it will send along with the start record number (0 to 4) in the first page. You stop writing records to the database when you find a -1 in the time field of the record. All blank records have their date and time records initialized to -1. The routines used by the firmware to support the download follow along with the definition of an individual record - 5 per page. struct StandardRec { unsigned dateStamp; // Year | Month | Day 7 bits | 4 bits | 5 bits int timeStamp; // Hour * 100 + Min int tempOut; int hiTempOut; int lowTempOut; int rain; int rainRate; int bar; int solar; int nWindSamples; int tempIn; // .1 degrees F byte humIn; byte humOut; byte windSpeed; byte hiSpeed; byte dirOfHiSpeed; byte domDir; byte uv; byte et; // .001 in byte soilTemp; byte soilMoist [4]; byte leafTemp [4]; byte leafWet [4]; byte extraTemp [2]; byte extraHum [2]; int reedClosed; // reedClosed int reedOpen; // reedOpen }; /* +------------------------------------------------------------------------------------------+ */ int FindRecord (int dateStamp, int timeStamp) { int recNo; #ifdef EVERYTHING recNo = nextRecord; do { GetRecord (recNo, sharedMem.displayMemory, 4); if ( sharedMem.log.timeStamp == -1 ) // Start logging on a blank record. { if ( recNo == nextRecord ) { // OK } else return -1; } else if ( sharedMem.log.dateStamp == dateStamp ) { if ( sharedMem.log.timeStamp == timeStamp ) return recNo; } if (recNo == 0) recNo = 2560; else recNo--; if ( recNo == nextRecord ) break; } while (1); #endif return -1; } /* +------------------------------------------------------------------------------------------+ Reads page n without disturbing buffer RAM on chip. If data == 0 send it out the serial port. */ int ReadPage (int n, char b) { int i; #ifdef EVERYTHING ClrBit(PORTB, 0); // Select the chip. SPI_Out (0x52); // Do a page read. SPI_Out (n >> 7); // First 6 bits are reserved. SPI_Out (n << 1); // Next 9 are page. Next 9 are start byte. SPI_Out (0); SPI_Out (0); // Next 32 are don't care bits. SPI_Out (0); SPI_Out (0); SPI_Out (0); ClearCrc (); PutPcChar (CrcAccum (b)); // first send the block number for (i = 0; i < 264; i++) { PutPcChar (CrcAccum(SPI_In ())); } PutPcCrc (); SetBit(PORTB, 0); // Select the chip. #endif return 0; } static int CalcPage (int recNo) { if ( recNo == -1 ) return 511; else if ( recNo == 2560 ) return 0; else return recNo / 5; } /* +-------------------------------------------------------------------+ */ int DumpAfter (int n) { int i, c, startPage, endPage, startRec; startRec = 0; // First record in the page. if ( (c = NumberOfRecords ()) == 0 ) { ClearCrc (); PutPcUnsigned (0); PutPcUnsigned (0); PutPcCrc (); return 0; } startRec = 0; // Change if necessary later. if ( n == -1 ) { // Record not found. } else // Move on to record after the record found. { n++; if ( n == 2560 ) n = 0; } if ( c == 2560 ) // Buffer has wrapped. { if ( n == -1 ) // Record not found. { startRec = GetNextRecNo () % 5; startPage = CalcPage (GetNextRecNo ()); n = 512; } else if ( GetNextRecNo () == n ) { n = 0; // Asked for after last record. } else if ( GetNextRecNo () < n ) { startRec = n % 5; startPage = CalcPage (n); endPage = CalcPage (GetNextRecNo () -1); /* Calculate how many pages to send. */ if ( startPage == endPage ) n = 512; else n = 512 - (startPage - endPage + 1); } else // GetNextRecNo () > n { startRec = n % 5; startPage = CalcPage (n); endPage = CalcPage (GetNextRecNo () - 1); n = endPage - startPage + 1; } } else // Buffer has not wrapped. { if ( n == -1 ) // Record was not found. { n = (GetNextRecNo () - 1)/5 + 1; startRec = 0; startPage = 0; } else if ( GetNextRecNo () == n ) { n = 0; // Asked after last record. } else if ( GetNextRecNo () > n ) { startRec = n % 5; startPage = CalcPage (n); endPage = CalcPage (GetNextRecNo () - 1); n = endPage - startPage + 1; } else // nextRecord < n should not happen. n = 0; } if ( n == 512 ) // Send first block twice. n++; ClearCrc (); PutPcUnsigned (n); // Send number of pages. PutPcUnsigned (startRec); PutPcCrc (); if ( (c = GetPcCharWithWait (10)) == 0x6 ) // ACK { } else return -1; for (i = 0; i < n; i++ ) { ReadPage (startPage, (char)(i & 0xFF)); if ( (c = GetPcCharWithWait (10)) == 0x6 ) // ACK { startPage++; if ( startPage == 512 ) startPage = 0; } else if ( c == 21 ) // NAK { i--; continue; } // else if ( c == 27 ) // ESC else // Timout and ESC break; } return 0; } else if ( MyStrcmp (tmpStr, commandStr [k++], 6) == 0 ) // DMPAFT { PutPcChar (0x6); BufferToPage (GetNextRecNo ()/5); if ( FlashReady () ) { if ( FillBuffer (tmpStr, 6) == 0 ) { if ( GetCrc () == 0 ) { if ( *((int *)tmpStr) == 0 ) // Give them everything. n = -1; else { n = FindRecord (*((int *)tmpStr), *((int*)(tmpStr+2)) ); currentState.screenUpdate = 1; // Find record uses lcd memory. } PutPcChar (0x6); DumpAfter (n); } else PutPcChar (0x18); } else { PutPcChar (0x21); } } else PutPcChar (0x44); // Flash not ready. }