|
||
EXAMPLE DATA LOGGING PROGRAMCOMMENTARYThe complete program #DATALOG.TDS is in the software library. The example program is kept simple and logs 8 analog and 24 of the digital inputs every 5 seconds, with the storage in CSV format for direct use with an Excel spreadsheet. You can use it as the starting point for your own application program. As it stands a 16-megabyte Flash-ATA card would hold nearly two month's information if set to log every 30 seconds. A second complete program, #232LOG.TDS, collects data from the serial input under interrupt into a circular buffer and stores it sequentially on a memory card for later analysis on a PC. This can be amended to meet your own requirements. For a trial, put a TDS2020CM2 PCMCIA card adapter on top of a TDS2020F, see ADAPTER INSTALLATION, page 256. Add a Flash-ATA, Compact Flash or hard disk card. Once the hardware is ready and you are communicating with Forth, open #DATALOG.TDS into a yellow editing screen. You can edit the constant MANY to alter the logging interval from 5 seconds to whatever you want in the range 1 to 99 seconds. In the word INITIALISE you can change SECOND to MINUTE or HOUR etc. for other units of delay. In United States add the word USA in INITIALISE so that the date appears in your own format. Finally, compile the file with the F8 key. When complete, if you have compiled to RAM type WORK return to start the data collection process. You will see logging every five seconds on the PC along with spurious characters that come from the PC trying to interpret the 0V serial port level while the TDS2020F is in standby. If you have compiled to Flash-EEPROM, type SET WORK to protect the chip from corruption then power down and leave a few minutes to discharge the big storage capacitor on the TDS2020CM2. The word WORK will start to execute when power is reapplied. Now hold down any key and the software will abort to interactive Forth. To extract the data move the memory card to a PC and copy file DATA.FIL. Open it with a text editor to see the collected data looking like the following. Date and time are followed by the 8 analog voltage measurements, and finally the digital levels on 24 inputs:
05.01.00, 22.41.20,3.91,4.18,4.25,4.37,4.50,4.60,4.48,4.52, 05.01.00, 22.41.25,4.93,4.99,4.95,4.88,4.99,4.99,4.97,4.85, 05.01.00, 22.41.30,4.97,4.99,4.91,4.89,4.99,4.99,4.96,4.91, 05.01.00, 22.41.35,4.93,4.99,4.95,4.82,4.99,4.99,4.92,4.88, 05.01.00, 22.41.40,4.99,4.99,4.95,4.91,4.99,4.99,4.99,4.87,
Next, import the file into Excel. Load the spreadsheet program, open the file and answer the wizard's questions, giving comma as the separator and remembering to format the first two values as date and time respectively. The data can be organised how you want, depending on the application. Here we used ASCII CSV values but you could choose binary for better data packing. For example if scanning eight 10-bit A to D channels each could be allocated two bytes and a single byte will suffice for every eight digital channels being logged. DATA LOGGING SOURCEThe source code for the sample data logger follows. This program is intended
q as a demonstration of a minimal data logger which can be developed further into the software for a real application, q as the actual program with no more software to write for jobs which need logging of up to 8 analog and 24 digital channels, q as an example of a simple Forth program, including layout and comments.
As with all Forth programs look at the high-level words at the end first for best understanding, then work back to the beginning. \ Triangle Digital Support Ltd TDS2020 ANS Utilities \ #DATALOG.TDS Ver 3.10 by Peter Rush 28 May 02 \ [C] 2002 Triangle Digital Support Ltd \ Log digital, analog and GPS data into Compact Flash or PCMCIA cards \ -------------------------------------------------------------------------- \ PURPOSE \ This program is intended \ - as a demonstration of a minimal data logger which can be developed \ further into the software for a real application. \ - as the actual program with no more software to write for jobs which \ need logging of up to 8 analog and 31 digital channels. \ - as master for the Datalogger Wizard, which can customise it to meet \ particular requirements. \ - as an example of a simple Forth program, including layout and comments \ As with all Forth programs look at the high level words at the end first \ for best understanding, then work back to the beginning. \ -------------------------------------------------------------------------- \ DESCRIPTION \ Provides data collection using the minimum possible power consumption to \ a Flash-ATA, Compact Flash or hard-disk PCMCIA card. This is achieved by \ putting the module into standby between records. In addition the PCMCIA or \ Compact Flash card is only powered up once a complete cache of data in RAM \ is ready for writing, or at completion of the run \ This program as it stands logs data as follows to a Compact Flash or \ PCMCIA card in a TDS2020CM2 adapter every 5 seconds: \ - 8 analog inputs in CSV format \ - 31 digital inputs in CSV format \ - Date every record in Excel format \ - Time every record in Excel format \ Storage is in CSV format for direct use with an Excel spreadsheet. You can \ use it as the starting point for your own application program. As it \ stands a 16-megabyte Flash-ATA card would hold nearly two month's \ information if set to log every 30 seconds. \ -------------------------------------------------------------------------- \ CUSTOMISATION \ This can be done with the datalogger Wizard or manually as follows. \ Once the hardware is ready and you are communicating with Forth, open \ #DATALOG.TDS. You can edit the time set in the definition of INITIALISE to \ alter the logging interval from 5 seconds to whatever you want in the \ range 1 to 99 seconds. Change SECOND to MINUTE or HOUR etc. for other \ units of delay. \ Finally, compile the file with the F8 key. \ -------------------------------------------------------------------------- \ USING THE PROGRAM \ If you have compiled to RAM type WORK return to start the data collection \ process. You will see logging every five seconds on the PC along with \ spurious characters that come from the PC trying to interpret the 0V \ serial port level while the TDS2020F is in standby. \ If you have compiled to Flash-EEPROM, type SET WORK to protect the chip \ from corruption then power down and leave a few minutes to discharge the \ big storage capacitor on the TDS2020CM2. The word WORK will start to \ execute when power is re-applied. \ Now hold down any key and the software will abort to interactive Forth. To \ extract the data move the memory card to a PC and copy file DATA.FIL. Open \ it with a text editor to see the collected data looking like this, with \ the 8 analog voltage measurements followed by the digital levels on 31 \ inputs. One record is shown, actually it is all on one line. \ 2.03,2.12,2.24,2.34,2.41,2.44,2.45,2.39,1,0,0,1,0,0,0,1,0,0,0,1,0,1,1,0, \ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,.401692,30682, \ Next, import the file into Excel. Load the spreadsheet program, open the \ file and answer the wizard's questions, giving comma as the separator and \ remembering to format the last two values as date and time respectively. \ The data can be organised however you want depending on the application. \ Here we used ASCII CSV values but you could choose binary for better data \ packing. For example if scanning eight 10-bit A to D channels each could \ be allocated two bytes and a single byte will suffice for every eight \ digital channels being logged. \ To start over again, put the card back into the TDS2020F module and type \ HARD-FORMAT (return). \ -------------------------------------------------------------------------- \ COMPILING TO FLASH-EEPROM \ For convenience, uncommenting the last two lines will make the \ Flash-ATA, Compact Flash or hard disk available immediately after \ compilation. Uncomment only if NOT compiling to Flash-EEPROM. \ While compiling to Flash-EEPROM interrupts are disabled. Even the clock \ does not increment. You need to lock the Flash-EEPROM before running \ any program that uses interrupts. For example type SET START followed by \ EIS HARD . Be sure you can always exit to Forth so that you can use COLD \ to erase everything if necessary. DECIMAL \ -------------------------------------------------------------------------- \ LIBRARY FILES INCLUDE #DOSHD.TDS \ Flash-ATA, Compact Flash and hard disk support, \ will also include #DOSHD.TDS, #CARDHD.TDS, #FDISK.TDS, #TIMED.TDS INCLUDE #A-D.TDS \ Faster version of A to D routine \ -------------------------------------------------------------------------- \ CONSTANTS \ Ports A & B addresses $81E0 CONSTANT APORT \ Data register of port A $81D0 CONSTANT BPORT \ Data register of port B $81F0 CONSTANT ABDDR \ Data direction register of ports A & B \ Port 1 addresses $FF82 CONSTANT 1PORT \ Data register of port 1 $FF80 CONSTANT 1DDR \ Data direction register of port 1 \ Port 7 addresses $FF8E CONSTANT 7PORT \ Data register of port 7 $FF8C CONSTANT 7DDR \ Data direction register of port 7 \ Port 8 addresses \ $FF8F CONSTANT 8PORT \ no DDR, Port 8 input only when no A-D used \ Port 9 $FFFF CONSTANT 9PORT \ Data register of port 9 $FFFE CONSTANT 9DDR \ Data direction register of port 9 \ -------------------------------------------------------------------------- \ VARIABLES VARIABLE TLOG \ Records time only every this number of logs VARIABLE TCTR \ Counts records to see if due to log time VARIABLE DLOG \ Records date only every this number of logs \ and set to -1 to record date only with \ the first record of the day VARIABLE DCTR \ Counts records to see if due to log date \ or saves day number when daily date needed \ -------------------------------------------------------------------------- \ PRIMITIVES : @MS ( -- d ) \ Return milliseconds since midnight from board clock -TIMER \ delay timer increments while reading $FFB2 @ 0 5 6144 M*/ \ ms represented by tick fractions TICKS @ 0 160 3 M*/ D+ \ ms represented by ticks, fraction of a minute MINS @ 30000 M* D2* D+ \ ms represented by minutes since midnight +TIMER ; \ timer back on again : TIME>EXCEL ( d-time -- ) \ Send time in format for Excel \ d-time: double number seconds since midnight with \ implied three decimal places \ output is fractional, represents time of day e.g. 0.25 = 6.00am 10 864 M*/ <# 6 0 DO # LOOP ". HOLD #> TYPE ; \ output time : DATE>EXCEL ( date -- ) \ Send date in format for Excel \ date: unsigned single day number since 1 Jan 1984 (day 0) \ output is integer, days since 1 Jan 1900 (day 1) S>D 30682. D+ <# #S #> TYPE ; \ output date : 0/1 ( ca n -- c ) \ Test bit n of address ca and output in CSV format ?BIT IF "1 ELSE "0 THEN EMIT ", EMIT ; : LOG ( -- ) \ Collect one record and output in CSV format. \ For each analog channel convert, scale, send as decimal number & comma. \ For each digital input output each bit as 0 or 1 followed by comma. \ Takes 18.6ms as written (22.6ms with date & time), before any \ customisation, when output has been redirected to a Flash card \ (excludes flush to the card). \ Log analog channels 0 A-D 0 500 1023 M*/ <# ", HOLD # # ". HOLD # #> TYPE \ channel 0 1 A-D 0 500 1023 M*/ <# ", HOLD # # ". HOLD # #> TYPE \ channel 1 2 A-D 0 500 1023 M*/ <# ", HOLD # # ". HOLD # #> TYPE \ channel 2 3 A-D 0 500 1023 M*/ <# ", HOLD # # ". HOLD # #> TYPE \ channel 3 4 A-D 0 500 1023 M*/ <# ", HOLD # # ". HOLD # #> TYPE \ channel 4 5 A-D 0 500 1023 M*/ <# ", HOLD # # ". HOLD # #> TYPE \ channel 5 6 A-D 0 500 1023 M*/ <# ", HOLD # # ". HOLD # #> TYPE \ channel 6 7 A-D 0 500 1023 M*/ <# ", HOLD # # ". HOLD # #> TYPE \ channel 7 \ Log digital channels 2 BASE ! \ go to binary to store inputs as 0 or 1 APORT PC@ 0 <# 8 0 DO ", HOLD # LOOP #> TYPE \ port A 7PORT C@ 0 <# 8 0 DO ", HOLD # LOOP #> TYPE \ port 7 9PORT 7 0/1 \ read and store data from port 9 bit 7 9PORT 4 0/1 \ read and store data from port 9 bit 4 9PORT 3 0/1 \ read and store data from port 9 bit 3 9PORT 2 0/1 \ read and store data from port 9 bit 2 1PORT 6 0/1 \ read and store data from port 1 bit 6 1PORT 5 0/1 \ read and store data from port 1 bit 5 1PORT 0 0/1 \ read and store data from port 1 bit 0 BPORT PC@ 0 <# 8 0 DO ", HOLD # LOOP #> TYPE \ port B \ 8PORT C@ 0 <# 8 0 DO ", HOLD # LOOP #> TYPE \ port 8 if no A to D DECIMAL \ finished with logging of digital inputs \ Log time of day TCTR @ \ check whether to record time or not IF -1 TCTR +! \ don't log time to this record ELSE \ on this record log the time TLOG @ 1- TCTR ! \ ready for next count @MS TIME>EXCEL \ output time in Excel format \ .TIME \ alternative in normal format THEN ", EMIT \ add comma after all times \ Log date DLOG @ 65535 <> \ true if not one date log per day IF \ log date every so many records DCTR @ \ check whether to record date or not IF -1 DCTR +! \ don't log date to this record ELSE \ on this record log the date DLOG @ 1- DCTR ! \ ready for next count @DATE DATE>EXCEL \ output date in Excel format \ .DATE \ alternative in normal format THEN ELSE \ log of date only with first record of the day @DATE DCTR @ OVER <> \ same date as on last record? IF DCTR ! \ ready for next time @DATE DATE>EXCEL \ output date in Excel format \ .DATE \ alternative to above in normal format ELSE DROP \ date same as when last record was taken THEN THEN ", EMIT \ add comma after all dates \ Return and line feed at end of record CR ; \ -------------------------------------------------------------------------- \ TOP LEVEL ROUTINES : INITIALISE ( - ) \ Set up before main loop W@ \ set board clock from clock chip \ USA \ request USA date format 0 DUP CFIGM ! ABDDR PC! \ ports A & B input on all data inputs 0 7DDR C! \ port 7 to input on all 8 data inputs $21 9DDR C! \ port 9 to input on bits 7, 4, 3, 2 $0E 1DDR C! \ port 1 to input on bits 6, 5, 0 10 TLOG ! \ record time only every this number of logs 10 DLOG ! \ record date only every this number of logs TCTR OFF \ records counters for time DCTR OFF \ records counters for date 5 SECOND O'CLOCK ; \ time interval between records : MAIN ( - ) \ Indefinite application loop. Main loop will work down to \ 100ms while keeping SUSPEND and fullest version \ of LOG. This excludes time for FLUSH every so often. INITIALISE \ set up before main loop <HARD \ redirect output to PC card BEGIN \ datalogging starts here <1 CR .TIME 2 SPACES 1> \ redirect to serial port and send \ informative message - with TDS-PC for \ Windows on the PC you will also see other \ characters caused by the illegal RS232 level \ while the TDS2020F is in standby LOG \ collect one data record SUSPEND \ go to low power mode W@ \ set board clock after standby 20 MS \ delay after standby to help get out on a key KEY? \ true on any key press, exit logging UNTIL \ keystroke found HARD> \ cancel redirection, flush buffer START ; \ enter interactive Forth : WORK ( - ) \ Word executed at power-up. See Error \ Handling in technical manual for details BEGIN ['] MAIN CATCH ERROR AGAIN ; \ SET WORK \ type this interactively after compilation \ to start logging at power-up or \ SET START \ type this interactively after compilation \ to start interactive Forth at power-up. \ -------------------------------------------------------------------------- \ COMPILE TIME ACTIONS \ See notes at the start of the file \ EIS \ ensure interrupts on, HARD will depend on them \ if #TIMING.TDS was compiled \ HARD \ reset card also at compile time |