Datalogger and Log Analyzer Extension

Introduction

The Logger and LogAnalyzer objects are now based on defined rules. They now only are a framework that contains most of the functionality that any datalogger or log analyzer would need. For example, the Logger class provides a way to send and recieve data, and output that data to the user. It does NOT provide the functionality specific to one ecu. Thats where the rules come in.

A Rule is essentialy an interface with which the Logger can notify your code that some task needs to be done. In the case of the Logger, rules allow the programmer to have complete control over what is sent to the ecu, manipulations on the data recieved back from the ecu, and the data output to the screen and to the log file. In the case of the LogAnalyzer, the programmer has control over the data being displayed and analyzed through rules.

Extending the Datalogger

In order to extend the BRE data logger You need to do a few things:

There is an example below in the Examples section.

Special Functions

There are a few special functions that must be set by some Rule that is running in the Logger. The values kept by these functions are automatically added to the csv file so the analyzer can properly analyze. These values are NOT added to the output grid. If you want them in the grid you must create a LoggerKey for them. The special functions in the Logger class are:

        //These functions must be used at each iteration of the datalogger.

        //self explanatory
        void setAfr(float afr)
        void setMapIndex(int index)
        void setCurrentColumn(int x)
        void setCurrentFuelRow(int fy)
        void setCurrentIgnitionRow(int iy)

        //This sets a cells weight based on the interpolation.
        //index [0,0] is the current cell, index [1,0]
        //is the east cell, [0,1] is the south cell, etc.
        //The weights should always add up to 1.
        void setCellWeight(int col, int row, float value)

The same functions are provided in the AutoEdit class where the values are stored. They are only in the Logger class for convenience. The get counterparts to these functions are in the AutoEdit class as well.

Adding a New O2 sensor Definition

With the Rule framework it is easy to add a new O2 sensor definition to the Logger. You need to first create a script which catches the OnDataloggerCreated event:

        public object ScriptMain(params object[] args)
        {
                romWind = (child)args[1];
                romWind.subscribeToEvent("OnDataloggerCreated", "BensScripts.NewO2Def.log_Opened");
                return null;
        }

Then define a function that adds an object of type AfrRule to the Logger:

        public object log_Opened(params object[] args)
        {
                if(args[2] == null)
                        return null;
                ((Logger)args[2]).addO2Type(new NewO2Rule("My New O2"));
                return null;
        }

You obviously need to create the object that extends AfrRule. But the key to it is the executeRule function:

        public bool executeRule(Form frm)
        {
                Logger lo = ((Logger)frm);
                //is it our o2 type? if not return false
                if(index != lo.getO2Type()) return false;
                
                //get value from the hash table
                Integer val = lo.getLoggerData().getHashtable()["o2afr"];

                //if its null, return false
                if(val == null) return false;

                //do calc stuff here:
                float afr = (float)(val.Value)/2.0f+9.0f;

                //set the value for the output
                afrKey->Value = afr.ToString("0.00");

                //set the afr for the rest of the Logger
                lo.setAfr(afr);

                return true;
        }

The full example is down in the Examples section.

Logger Order of Events...

...On Instantiation

...When The User Clicks Start

...When The Datalogger Is Running

LogAnalyzer Order of Events...

...On Instantiation

Examples

New O2 Sensor Definition

//This adds a new o2 sensor definition to BRE

using System;
using System.Windows.Forms;

using bre20;
//css_reference ..\bre20.exe;

namespace BensScripts
{
        public class NewO2Def
        {
                public static object AppliesTo(){return "all";}
                public static object ScriptTitle(){return "New O2 Def by Ben Ogle";}
                //args[1] = child window of type bre20.child
                public object ScriptMain(params object[] args)
                {
                        romWind = (child)args[1];
                        romWind.subscribeToEvent("OnDataloggerCreated", "BensScripts.NewO2Def.log_Opened");
                        return null;
                }
                public object log_Opened(params object[] args)
                {
                        if(args[2] == null)
                                return null;

                        ((Logger)args[2]).addO2Type(new NewO2Rule("My New O2"));

                        return null;
                }
        }//end class

        public class NewO2Rule: AfrRule
        {
                //stuff we can use:
                //afrKey
                //index
                public NewO2Rule(string name){base(name);}

                public bool executeRule(Form frm)
                {
                        Logger lo = ((Logger)frm);
                        //is it our o2 type? if not return false
                        if(index != lo.getO2Type()) return false;
                        
                        //get value from the hash table
                        Integer val = lo.getLoggerData().getHashtable()["o2afr"];

                        //if its null, return false
                        if(val == null) return false;

                        //do calc stuff here:
                        float afr = (float)(val.Value)/2.0f+9.0f;

                        //set the value for the output
                        afrKey->Value = afr.ToString("0.00");

                        //set the afr for the rest of the Logger
                        lo.setAfr(afr);

                        return true;
                }
        }
}//end namespace

General Rule Example

//This adds a Datlogger definition definition to BRE

using System;
using System.Windows.Forms;
using System.Collections;

using bre20;
//css_reference ..\bre20.exe;

namespace BensScripts
{
        public class Vt0Logger
        {
                child romWind;
                public static object AppliesTo(){return "pr3:pw0";}
                public static object ScriptTitle(){return "Obd0 Vtec Logger Defn by Ben Ogle";}
                //args[1] = child window of type bre20.child
                public object ScriptMain(params object[] args)
                {
                        romWind = (child)args[1];
                        //subscribe to the event
                        romWind.subscribeToEvent("OnDataloggerOpened", "BensScripts.Vt0Logger.log_Opened");
                        return null;
                }
                public object log_Opened(params object[] args)
                {
                        //when the logger is opened, then we add our rule
                        romWind.addLoggerRule(new Vt0LoggerDef());
                        return null;
                }
        }//end class

        public class Vt0LoggerDef: Rule
        {
                Logger log;
                //save a reference to our key
                LoggerKey rpm;
                public Vt0LoggerDef(){}
                public override void setupRule(Form frm)
                {
                        log = ((Logger)frm);

                        //here we set up the rpm LoggerKey
                        rpm = new LoggerKey("Rpm",true,true);
                        //add it to the logger
                        log.getLoggerData().addLoggerKey(rpm);
                }
                public override bool executeRule(Form frm)
                {       
                        //get the results values from the hash table
                        //the names/labels/keys are from loggerCmd.ini
                        Hashtable hash = log.getLoggerData().getHashtable();
                        Integer val = (Integer)hash["rpm low"];
                        int tmp = val.Value + 256*(((Integer)hash["rpm high"]).Value);

                        //set the value for the output
                        rpm.Value = tmp.ToString();
                        return true;
                }
                //when a log file is being replayed this gets called. If you create
                //LoggerKeys which are not put in the csv file or gauges, you will
                //need to update those objects in this method. BRE automatically 
                //matches the values in the csv file with their LoggerKey object;
                //those values will be put in the output grid for you. But BRE does
                //not update gauges. 
                public override bool executeReplay(string[] keys, Hashtable values)
                {
                        return true;
                }
                //this is what we are modifying
                public override string modifiedFields(){return "rpm";}
        }
}//end namespace



BRE Documentation Home