Experiment Controller Data File Format

 

The ECL emulator firmware and the ECBasic firmware (in transparent mode) output data in a binary format. On IBM-PC platforms the ExpRun program writes this data into files in the same format as it is sent from the controller, except that an information header is written at the beginning of the data file.

The file header is 14 bytes long and has the following format:

Byte Number

Byte Usage

Description

1

LSB Subject No

Subject number as entered in ExpRun

2

MSB Subject No

3

LSB Time

Start Time and date

See discussion below

4

2nd Byte Time

5

3rd Byte Time

6

MSB Time

7

LSB Weight

Subject weight as entered in ExpRun

8

MSB Weight

9

LSB Box

Box number used in Exprun

10

MSB Box

11

LSB Prog ID

Program ID number not currently used (always 0)

12

2nd Byte Prog ID

13

3rd Byte Prog ID

14

MSB Prog ID

The date and time is stored as the number of seconds since 00:00 January 1, 1970. This is the return value of the time() function found in most "C" compilers. The localtime() function is commonly used to convert this value to a more usable structure.

Data items follow the header and are 6 bytes long. They have the following format:

Byte Number

Byte Usage

Description

1

Type

Event Type 1-8 are Currently used

2

Value

Event Value 0-255

3

LSB Data

Time in 1 millisecond ticks since program started

or data value if type 7

4

2nd Byte Data

5

3rd Byte Data

6

MSB Data

ECL and ECBasic encodes these data records as follows:

Type

Value

Data

Description

1

1-48

Time

Turn on Output

2

1-48

Time

Turn off Output

3

1-8

Time

Input seen

4

1-255

Time

Marker

5

0

Time

Program Ends

6

1-5

Time

Timer Expired

7

0

Value

Send 32-bit Data value

8

0-255

Line Number

Error Number

Record type 5 marks the end of the data. There should not be any data records after the marker type 5, so you can use this as the "end of file" indicator.

Error Number

Probable Cause

0

Syntax Error

1

Illegal Variable Name

2

Constant Redefined

3

Variable redefined

4

Symbol table full - too many variables

5

Illegal Variable usage

6

Expression Missing

7

Variable not defined

8

Illegal use of string

9

Parentheses Balance Error

10

Improper Parameter Count

11

Internal Error - usually a bad instruction was encountered

12

Illegal Array Usage

13

Array not dimensioned

14

Illegal Array Subscript

15

Illegal Expression Type

16

NEXT without FOR

17

Improper Nesting of FOR/NEXT

18

Missing Argument

19

Subroutine Stack Overflow

20

Line number not found

21

Return without GoSub

22

Array Redimensioned

23

Illegal Expression Value

24

Break seen (control program terminated)

25

Stop command seen

26

Division by zero

27

Nesting too deep in FOR/NEXT

28

Out of Data in read command

29

Out of Memory

30

Dimension Too Large - Exceeded available memory


An example program to read the data files is readw.c. Note that the I/O routines called are in iosubs.c.


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
 
char infile[40];	/* input file name */
FILE *ipnt;		/* input file descriptor */
 
struct tm *localtime();
struct tm *time_ptr;
 
void put8( unsigned char, FILE * );
void put16( unsigned short, FILE * );
void put32( unsigned long, FILE * );
unsigned char get8( FILE * );
unsigned short get16( FILE * );
unsigned long get32( FILE * );
 
int main( int argc, char *argv[] )
{
	int i;
	int ibird,itype,idata;
	long oldtim;
	long bird_time;
	int weight;
	int box;
	unsigned long prog_id;
 
	if (argc<2)
	{
		while(1)
		{
			printf( "File name? " );
			fgets( infile, 20, stdin );
			if ( strlen( infile ) == 0 ) continue;
			break;
		}
	}
	else
	{
		strcpy(infile,argv[1]);
	}
	i = strlen( infile );
	if ( infile[i-1] == '\n' ) infile[i-1] = '\0';
 
	ipnt = fopen(infile,"rb");
	if(ipnt == NULL)
	{
		printf( "Cannot open %s\n", infile );
		exit( 1 );
	}
	oldtim = 0;
 
	ibird = get16( ipnt );
	bird_time = get32( ipnt );
	weight = get16( ipnt );
	box = get16( ipnt );
	prog_id = get32( ipnt );
 
	putenv( "TZ=EST0" );
	tzset();
	time_ptr = localtime(&bird_time);
 
	printf( "Bird #%d, Date: %d/%d/%d %d:%d:%d\n",
		ibird,
		time_ptr->tm_mon+1,
		time_ptr->tm_mday,
		time_ptr->tm_year,
		time_ptr->tm_hour,
		time_ptr->tm_min,
		time_ptr->tm_sec );
	printf( "Weight = %d, Box = %d, ID = %ld\n", weight, box, prog_id );
 
	while( feof( ipnt ) == 0)
	{
		itype = get8( ipnt );
		idata = get8( ipnt );
		bird_time = get32( ipnt );
 
		if( itype == 7 )
		{
			if (idata == 0)
			{
			    printf( "%3d      %ld\n", itype, bird_time );
			}
			else
			{
			    printf( "%3d %3d  %ld\n", itype, idata, bird_time );
			}
		}
		else
		{
		    printf( "%3d %3d  %ld,%ld\n",itype,idata,
					bird_time,bird_time-oldtim);
		    oldtim = bird_time;
		    if ( itype == 5 ) break;
		}
	}
 
	fclose( ipnt );
	return( 1 );
}


If you use readw to read this sample data file you should get an output something like this:

Bird #11, Date: 5/22/97 9:30:5
Weight = 11, Box = 9, ID = 1
  1   4  20,20
  4 100  22,2
  4   1  22,0
  1  28  22,0
  4   2  6022,6000
  1  21  6023,1
  4   3  12022,5999
  1  27  12023,1
  4   4  18023,6000
  1  26  18023,0
  4   5  24023,6000
  1  19  24023,0
  4   6  30023,6000
  1  23  30023,0
  3   2  31211,1188
  3   2  31418,207
  3   2  31586,168
  3   2  31725,139
  3   2  31860,135
  4   7  36022,4162
  1  22  36023,1
  4   8  42022,5999
  1  25  42023,1
  4   9  48023,6000
  1  24  48023,0
  4  10  54023,6000
  1  20  54023,0
  2   4  60023,6000
  1   2  60023,0
  2   2  63022,2999
  1   4  63023,1
  4 100  63024,1
  4   1  63024,0
  1  28  63025,1
  5   0  65867,2842


Note that the first column is the record type, the 2nd is the value, and the 3rd is the data (usually the time) followed by the difference of this records time and the previous records time.


Some actual data is available for a pigeon running a FI-60 schedule for a period of 3 months. A zip archive is available here.
Jacksonville State University Jacksonville Psychology SEBAC Psychology Server

Last Updated : August 19, 2002