Campbell CR10X download procedures. Dave Wright 5:56 PM 12/9/97 updated 11:09 AM 12/10/97 DKW Details on the interface between OASIS and the Campbell logger Refer to Campell documentation as well, 'Section 5. Telecommunications' When the Campbell logger makes measurements, it stores a number of data values in an 'output array'. An output array consists of a data 'record' for each value stored. The number of records in an array, and the meaning of each record, is defined by the program that is running in the logger. For each unique array definition there will be an 'array type' number assigned to identify the units and meaning of the records in the array, and this number will be the first record in each array. Data may be downloaded from the logger as ASCII or Binary. This brief describes the ASCII method. When communicating with the logger, stored data may be requested on the basis of arrays, without needing to know the number of records in a particular array. The logger spends most of it's time sleeping, but can be awakened by serial communication. It will continue to collect data while communicating. To wake up the logger, issue two characters in succession, and expect a * in reply. Repeat at 250mS intervals for 5 attempts before giving up. When you receive a *, transmit an A, and expect a string as below. *A R+36192. F+62280. V3 A1 L+36184. E00 00 03 M0256 B+3.0825 C3153 * The R value is the current location of the write pointer, and it is maintained by the logger. The L value is the current location of the read pointer, and can be manipulated by you. When the the logger is first awakened, it will set the L pointer to the value of the R pointer. To retrieve data, you have two options. If you are only interested in the latest data, you may issue the B command to 'back up' the read pointer a specified number of arrays, followed by the D command to dump them. The session would look like this: *1B A1 L+36208 C0793 *D 01+0300. 02+1340. 03+21.57 04+36.70 05+0.000 06+295.8 07+311.8 08+0.000 A1 L+36216 C4402 * ...The 1B backed up the read pointer (L) by one array, to location 36208, the A1 means we are dealing with storage area 1, and the C0793 is the checksum. The D caused one array to be dumped. The format for an array dump is RRSDD.DDRRSD.DDDetc..., where RR is the record number, S is the sign of the data, and DDDD is four digits of data. The decimal point is floating, and may appear anywhere in the 5 character data field. Note that the R and L pointers refer to records, whereas the B and D commands deal with arrays. The logger handles the alignment of the array start when executing a B or D command, even if the L pointer is set to the middle of an array. Also note that each record in an array generates 10 ASCII characters when dumped (low precision storage, see Campbell manual) If you want more arrays you simply back up further and dump more. The dump command will only output arrays up to the location of the L pointer when the logger was awakened, so it is permissible to ask for more arrays than have been written. For example, *A R+36325. F+62280. V3 A1 L+36325. E00 00 03 M0256 B+3.0825 C3148 *10B A1 L+36245 C0842 *20D 01+0300. 02+1420. 03+21.97 04+36.17 05+0.000 06+295.8 07+311.8 08+0.000 01+0300. 02+1430. 03+21.77 04+35.63 05+0.000 06+295.8 07+311.8 08+0.000 01+0300. 02+1440. 03+22.10 04+35.50 05+0.000 06+295.8 07+311.8 08+0.000 01+0300. 02+1450. 03+22.17 04+35.09 05+0.000 06+295.8 07+311.8 08+0.000 01+0300. 02+1500. 03+22.30 04+34.89 05+0.000 06+295.8 07+311.8 08+0.000 01+0300. 02+1510. 03+22.37 04+34.82 05+0.000 06+295.8 07+311.8 08+0.000 01+0300. 02+1520. 03+22.43 04+34.89 05+0.000 06+295.8 07+311.8 08+0.000 01+0300. 02+1530. 03+22.30 04+34.82 05+0.000 06+297.4 07+313.4 08+0.000 01+0300. 02+1540. 03+22.57 04+35.02 05+0.000 06+295.8 07+311.8 08+0.000 01+0300. 02+1550. 03+22.70 04+34.62 05+0.000 06+295.7 07+311.7 08+0.000 A1 L+36325 C4418 * ...here we see the write pointer (R) at 36325, we back up 10 arrays to 36245 (L), we ask for 20 arrays to be dumped but only get 10, which brings us to the latest array written. The other option is to collect all the arrays that have been written since the last dump was collected. We must store the value of the L pointer at the end of each dump and then set the L pointer to that value in the next session. That is done with the G command. In the above example, the L pointer was left at 36325 at the end of the dump, having caught up with the R pointer. In the next communication we will set the L pointer to that value and ask for 'everything' written since then. *A R+36346. F+62280. V3 A1 L+36346. E00 00 03 M0256 B+3.0825 C3154 *36325G A1 L+36325 C1008 *20D 01+0200. 02+0343. 03+1600. 04+23.18 05+12.97 01+0300. 02+1600. 03+22.77 04+34.35 05+0.000 06+295.7 07+311.7 08+0.000 01+0300. 02+1610. 03+22.83 04+34.15 05+0.000 06+295.7 07+311.7 08+0.000 A1 L+36346 C2235 * ...here we see that the write pointer (R) has advanced to 36346 since we last communicated. We set the read pointer (L) to the value it had at the end of the last dump, and ask for 20 arrays. We get the three new arrays that have been written since last time, and our read pointer has caught up with our write pointer. At this point we would store the value of the read pointer (L) so we know where to start in the next communication. Note that we have two types of array here, identified by the first record values, 200 and 300, and that they have different numbers of records. Some points to note: In order to keep from falling behind in the data collection it is important that you dump enough arrays to allow the read pointer to 'catch up' to the write pointer. This is done by requesting more arrays be dumped than it is reasonable to assume have been written since the last communication. One way to implement this might be to ask for as many arrays as you can buffer in OASIS. It is possible that the logger will write a new array during the dump. In that case the dump will end with the read pointer located one array behind the write pointer, however the read pointer would be saved by OASIS at that point, and that array will be picked up on the next dump. All of the above assumes that you know where you left the read pointer (L) after the last dump. In the case of the first communication with the logger, or if more arrays have been written than you can possibly accept, some sort of (re)synchronization is needed. That can be accomplished by issuing the B command to back up the read pointer relative to the write pointer some manageable number of arrays, dump those arrays, and then save the read pointer value. One possible way to determine whether you need to sychronize is to compare the loggers write pointer to the value of the read pointer you have saved (or initalized to 0), and see if the difference is too large... If (((current_write_pointer - saved_read_pointer) % MAXRECORDS) > (BUFFERSIZE / CHARS_PER_RECORD)) { sync_get_arrays(); } else { get_arrays(); } ...or something like that. That should handle all cases without knowing the state of OASIS or the logger when coms are established, and allow things to get sorted out. The buffersize should be chosen to handle the ammount of data that could accumulate during an OASIS glitch, or logger disconnection. I'd say maybe a day or two's worth. If we wanted to go back and get more data after an extended interval then that would have to be a manual thing. The logger will probably hold more than a month's worth of data in it's own memory without any need to talk to anybody until a 'rollover' is imminent. At the end of your download or other communication with the logger, issue an E command to exit the communications and allow the logger to go back to sleep. This will happen automatically after 40 seconds of no traffic anyway, but best to be explicit. Any further details on the behaviour of the logger are best determined by tinkering with it connected to a terminal. END