View Single Post
Old 06-04-2011, 05:57 PM   #19 (permalink)
Greg Fordyce
EcoModding Lurker
Join Date: Nov 2009
Location: Scottish Borders, Scotland
Posts: 92
Thanks: 7
Thanked 33 Times in 16 Posts
As promised, the latest version of my code.

#platform "uLCD-32PT_GFX2"

/*----------  CougArd Explorer by Greg Fordyce.  04 June 2011 --------------
------    4DGL Workshop 3 Version - Platform uLCD32PT_GFX2     -------
------------------------compiled size 817 bytes of 15360----------------------

**************************** General Information ******************************

This software carries no warranty or guarantee of any kind! Use at
your own risk, and I make no claims as to its suitability for a particular
function. Prospective users must evaluate the system before using it, and no
liability will be entertained by myself in any shape or form whatsoever.
The software has been produced at low cost for the benefit of
the EV & electronic community. The software is available free via the internet.
Users may modify or adapt the system as they see fit. If you are not fully
competent to work on potentially lethal battery systems and high voltages,
then do not experiment with or use this system. Be aware that vehicle
modifications can lead to invalidated insurance and warranty issues. You the
end user remain fully liable for any modifications made to your vehicle.

****************************** Description ************************************

This software is to capture the real time data stream from the cougar controller
and display it in a graphical interface to the driver. This first version is a
proof of concept and just displays the info as test after capturing and storing the
data to variables. It compiles o.k. but has not yet been tested on the actual
display. It probably has lots of bugs in it at the moment. More info, see links.

************************** Connection warning ***********************************

The cougar controller uses a serial RS232 port if built to the standard design.
The uLCD-32PT_GFX2 uses 3.3v ttl level serial comms (5 volt tolerent). You must use
a serial to ttl level shifter/converter. Direct connection of the display to the
serial port will likely damage the display. See cougard-explorer link above for
connection info and schematics.

var i, j, p, n;
var HStemp;         // In Celsius

var cougRXbuf[33];  // Data string format from controller
                    //"TR=xxx CR=xxx CF=xxx PW=xxx HS=xxxx RT=xxxx FB=xx BA=xxx AH=xxx.x\r\n"

var coug_rtd[9];    // Data from controller
                    // [0] TR 'throttle'
                    // [1] CR 'current reference'
                    // [2] CF 'current feedback'
                    // [3] PW 'PWM'
                    // [4] HS 'heatsink'
                    // [5] RT 'raw throttle'
                    // [6] FB 'fault bits'
                    // [7] BA 'battery amps'
                    // [8] AH 'amp hours' note: the 1/10 value is ignored

/* Heatsink look-up table (LUT). Raw heatsink values(RawHS)correspond to actual temp values (Cval). You may
   substitute your own values making sure you use appropiate corresponding values. You must have a
   RawHS value of 0 at the start and 1024 at the end. You may add any number of values that you like
   to the table. Formula to calculate look-up table for a 'stock' 2C controller can be found here;

    word RawHS  0, 250, 500, 630, 670, 1024
    word Cval -40,  20,  45,  65,  75,  270

func main()
    print("Motor Amps    \n");
    print("Battery Amps  \n");
    print("Heatsink Temp \n");
    print("Amp Hours     \n");
    com_SetBaud(COM0,1920);              // Cougar comms is 19200 8-n-1
    com_Init(cougRXbuf,64,0);            // set up a interrupt driven ring buffer for comms
    p:= str_Ptr(cougRXbuf);              // pointer
    while(!com_Full()) continue;         // wait till com buffer fills

//      str_Printf (&p,"%s\n\n");    //uncomment to print buffer as diagnostic output

/***************Capture cougar data stream variables to array coug_rtd[]************************/
        p := p + 3;
        str_GetW(&p, &coug_rtd[i]);      // coug_rtd[0] TR 'throttle'
        p := p + 4;
        i++ ;
        str_GetW(&p, &coug_rtd[i]);      // coug_rtd[1] CR 'current reference'
        p := p + 4;
        str_GetW(&p, &coug_rtd[i]) ;     // coug_rtd[2] CF 'current feedback'
        p := p + 4;
        str_GetW(&p, &coug_rtd[i]);      // coug_rtd[3] PW 'PWM'
        p := p + 4;
        str_GetW(&p, &coug_rtd[i]) ;     // coug_rtd[4] HS 'heatsink'
        p := p + 4;
        str_GetW(&p, &coug_rtd[i]) ;     // coug_rtd[5] RT 'raw throttle'
        p := p + 4;
        str_GetW(&p, &coug_rtd[i]) ;     // coug_rtd[6] FB 'fault bits'
        p := p + 4;
        str_GetW(&p, &coug_rtd[i]) ;     // coug_rtd[7] BA 'battery amps'
        p := p + 4;
        str_GetW(&p, &coug_rtd[i]) ;     // coug_rtd[8] AH 'amp hours' note: the 1/10 value is ignored
        p := p + 5;
        com_Init(cougRXbuf,64,0);        // reset RX buffer

/************** Calculate heatsink tempurature from LUT **********************************************
Thanks to user DJBecker for the look up table example using 16 bit maths to calculate tempurature in Celsius. */

       for (j:=1; coug_rtd[4] >= RawHS[j]; j++); // j is now pointing to the required value in the LUT
       HStemp := coug_rtd[4] - RawHS[j-1];
       HStemp *= Cval[j];
       HStemp += (RawHS[j-1] - coug_rtd[4])*Cval[j-1];
       HStemp /= RawHS[j] - RawHS[j-1];
       HStemp += Cval[j-1];

/************************************* Display controller data***************************************/

        print("    ");
        print(coug_rtd[2]);             // Motor Amps

        print("    ");
        print(coug_rtd[7]);             // Battery Amps

        print("    ");
        print(HStemp);                  // Heatsink tempurature in Celcius

        print("    ");
        print(coug_rtd[8]);             // Amp hours, interger value only.

Although it only displays 4 values, Motor amps, Battery amps, Heatsink temp and Ah, all values from the cougar real time data stream are captured and stored as variables, with one exception. The Amp hour data is only captured as an integer value. A bit more work is required to get the tenth of an amp figure. But what we do have is a useful drivers display of what I consider to be the most important info while driving.

The controller will need to be set to output the data stream using RTD explorer or moserial. I have set 'rtd_period 1000' and remember to send the 'save' command. I have not tested to see how fast a rtd stream it can handle, updating once a second is fine for driving, not to distracting.

Things that need to be done;

Fancy graphics instead of text display. After all that is why I bought the thing.

Fault bits display.

Data logging to built in uSD card slot. Ideally make the output a csv that is identical to the RTD explorer output.

Get the amp hour data to 0.1 of an ah.

Reduce battery amp limit when a low battery warning is received. Ideally use one of the available digital i/o pins that you can connect to whatever battery warning system you have.

This is some of my immediate goals for this project. Longer term goal is to use the second available serial port to get my bms data into the unit and have one display for both.

As you may have guessed, my projects don't move at any great pace, but I am always open for code submissions if anyone else is wanting to play with one of these 4d displays.
  Reply With Quote