Honda Insight Forum banner
1 - 20 of 186 Posts

Engine-Off-Coast
Joined
2,782 Posts
I think one of the selling points on this one was the touch-screen aspect, so you can update config parameters.
 

Engine-Off-Coast
Joined
2,782 Posts
I know this is herecy, but I like the 4x20 display, I just wish I could get it in red.
 

Engine-Off-Coast
Joined
2,782 Posts
Hey @mudder what pins do I wire the Nextion to?

So far I've got the most rudimentary display ever... just a SoC % number display, a bar graph of it, and a spot for the LiBCM software version number. I want to test it out all hooked up before I go further.
 

Engine-Off-Coast
Joined
2,782 Posts
I was able to program a rudimentary display for the Nextion, and it shows, but so far I can't get anything on the screen to update from LiBCM. In LiBCM.cpp I'm using the Serial1 functions. Are they correctly set up to send data on the wires going to the Nextion?
 

Engine-Off-Coast
Joined
2,782 Posts
I can't get the Nextion to receive any information from LiBCM. Is Serial1 configured properly?

Code:
//Copyright 2021-2022(c) John Sullivan
//github.com/doppelhub/Honda_Insight_LiBCM

//LiDisplay (HMI) Serial Functions

#include "libcm.h"

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void LiDisplay_begin(void)
{
  Serial.print(F("\nLiDisplay BEGIN"));
  Serial1.begin(9600,SERIAL_8E1);
  Serial1.print("page0.t1.txt=" + String('"') + String(FW_VERSION) + String('"'));
  Serial1.write(0xFF);
  Serial1.write(0xFF);
  Serial1.write(0xFF);
  Serial1.print("page0.n0.val=" + String('"') + SoC_getBatteryStateNow_percent() + String('"'));
  Serial1.write(0xFF);
  Serial1.write(0xFF);
  Serial1.write(0xFF);
  Serial1.print("page0.j0.val=" + String('"') + SoC_getBatteryStateNow_percent() + String('"'));
  Serial1.write(0xFF);
  Serial1.write(0xFF);
  Serial1.write(0xFF);
  Serial.print(F("\nLiDisplay SENT"));

  //LiDisplay_writeByte(SoC_getBatteryStateNow_percent());


  //LiDisplay_writeByte(SoC_getBatteryStateNow_percent());

}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

uint8_t LiDisplay_bytesAvailableForWrite(void)
{
  return Serial1.availableForWrite();
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

uint8_t LiDisplay_writeByte(uint8_t data)
{
  Serial1.write(data);
  return data;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

uint8_t LiDisplay_readByte(void)
{
  return Serial1.read();
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

uint8_t LiDisplay_bytesAvailableToRead()
{
  return Serial1.available();
}

I'm just trying to get it to display firmware version and SoC when it's turned on. There's only 1 page. t1 is a text box. n0 is a number box. j0 is a bar graph.
 

Engine-Off-Coast
Joined
2,782 Posts
Okay forget above post. First progress I've had so far... I got this to display the version number:

Code:
//Copyright 2021-2022(c) John Sullivan
//github.com/doppelhub/Honda_Insight_LiBCM
//LiDisplay (HMI) Serial Functions
#include "libcm.h"
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void LiDisplay_begin(void)
{
  Serial.print(F("\nLiDisplay BEGIN"));
  Serial1.begin(9600,SERIAL_8E1);
  Serial1.print("page0.t1.txt=" + String('"') + String(FW_VERSION) + String('"'));
  Serial1.write(0xFF);
  Serial1.write(0xFF);
  Serial1.write(0xFF);
  Serial1.print("page0.n0.val=" + String('"') + String(SoC_getBatteryStateNow_percent()) + String('"'));
  Serial1.write(0xFF);
  Serial1.write(0xFF);
  Serial1.write(0xFF);
/*  Serial1.print("page0.j0.val=" + String('"') + String(SoC_getBatteryStateNow_percent()) + String('"'));
  Serial1.write(0xFF);
  Serial1.write(0xFF);
  Serial1.write(0xFF); */
  Serial.print(F("\nLiDisplay SENT"));
  //LiDisplay_writeByte(SoC_getBatteryStateNow_percent());
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
uint8_t LiDisplay_bytesAvailableForWrite(void)
{
  return Serial1.availableForWrite();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
uint8_t LiDisplay_writeByte(uint8_t data)
{
  Serial1.write(data);
  return data;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
uint8_t LiDisplay_readByte(void)
{
  return Serial1.read();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
uint8_t LiDisplay_bytesAvailableToRead()
{
  return Serial1.available();
}
Still wouldn't update the number with the SoC. But maybe the buffer is overflowed that fast.

To make this work I (temporarily) put LiDisplay_begin() into metsci.cpp because it has a loop. This made the nextion reset over and over again but it did display the version number.

I think what this means is the initial placement of LiDisplay_begin() in MVP.ino in void setup() has it running too early and the Nextion isn't turned on or something so it never gets the data.

So LiDisplay_begin() doesn't need to attempt to display anything.

I'll keep experimenting.
 

Engine-Off-Coast
Joined
2,782 Posts
Where I've gotten now is I can control text elements like the version info, but I still can't change the value of other elements.

There's another way the data can be formatted using bytes instead of the strings seen here. I'll look into that next and see if that lets me update bar graphs and numbers.



Code:
//Copyright 2021-2022(c) John Sullivan
//github.com/doppelhub/Honda_Insight_LiBCM

//LiDisplay (HMI) Serial Functions

#include "libcm.h"

bool versionAlreadyDisplayed = false;
uint8_t LiDisplayElementToUpdate = 0;
const String typeMap[3] = {
    "j", "n", "t"
};
const String attrMap[2] = {
    "txt", "val"
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void LiDisplay_begin(void)
{
    #ifdef LIDISPLAY_CONNECTED
         Serial.print(F("\nLiDisplay BEGIN"));
        Serial1.begin(9600,SERIAL_8E1);

        LiDisplayElementToUpdate = 0;

/*  Serial1.print("page0.j0.val=" + String('"') + String(SoC_getBatteryStateNow_percent()) + String('"'));
  Serial1.write(0xFF);
  Serial1.write(0xFF);
  Serial1.write(0xFF); */

  //LiDisplay_writeByte(SoC_getBatteryStateNow_percent());
    #endif
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void LiDisplay_updateElement(uint8_t page, uint8_t elementTypeIndex, uint8_t elementId, uint8_t elementAttrIndex, String value) {
    #ifdef LIDISPLAY_CONNECTED
        static String LiDisplay_Data_Str;
        LiDisplay_Data_Str = "page" + String(page) + "." + typeMap[elementTypeIndex] + elementId + "." + attrMap[elementAttrIndex] + "=" + String('"') + value + String('"');
        Serial1.print(LiDisplay_Data_Str);
        Serial1.write(0xFF);
        Serial1.write(0xFF);
        Serial1.write(0xFF);
    /*
        Serial1.print("page0.t1.txt=" + String('"') + String(FW_VERSION) + String('"'));
        Serial1.write(0xFF);
        Serial1.write(0xFF);
        Serial1.write(0xFF);
        Serial1.print("page0.n0.val=" + String('"') + String(SoC_getBatteryStateNow_percent()) + String('"'));
        Serial1.write(0xFF);
        Serial1.write(0xFF);
        Serial1.write(0xFF);
    */
    #endif
}

void LiDisplay_refresh(void)
{
    #ifdef LIDISPLAY_CONNECTED

        //static uint8_t LiDisplayElementToUpdate = LCDUPDATE_NUMERRORS; //init round-robin with least likely state to have changed
        static uint32_t millis_previous = 0;

        #define LIDISPLAY_UPDATE_RATE_MILLIS 256 //one element is updated each time

        if(millis() - millis_previous > LIDISPLAY_UPDATE_RATE_MILLIS)
        {
            millis_previous = millis();

            switch(LiDisplayElementToUpdate)
            {
                case 0:
                    //LiDisplay_updateElement(0, 1, 0, 1, String(SoC_getBatteryStateNow_percent()));
                    LiDisplay_updateElement(0, 2, 1, 0, String(FW_VERSION));
                    break;
                case 1:
                    //LiDisplay_updateElement(0, 2, 1, 0, String(555));
                    LiDisplay_updateElement(0, 1, 0, 1, String(SoC_getBatteryStateNow_percent()));
                    break;
                case 2:
                    //LiDisplay_updateElement(0, 2, 1, 0, String(666));
                    LiDisplay_updateElement(0, 0, 0, 1, String(SoC_getBatteryStateNow_percent()));
                    break;
            }

            LiDisplayElementToUpdate += 1;

            if (LiDisplayElementToUpdate > 2) {
                LiDisplayElementToUpdate = 0;
            }

            /*
            uint8_t updateAttempts = 0;
            do
            {
                if( (++LiDisplayElementToUpdate) > LIDISPLAYUPDATE_MAX_VALUE ) { LiDisplayElementToUpdate = 1; } //reset to first element
                updateAttempts++;
            } while( (lcd_updateValue(LiDisplayElementToUpdate) == SCREEN_DIDNT_UPDATE) && (updateAttempts < MAX_LIDISPLAYUPDATE_ATTEMPTS) );
            */
        }

    #endif
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

uint8_t LiDisplay_bytesAvailableForWrite(void)
{
  return Serial1.availableForWrite();
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

uint8_t LiDisplay_writeByte(uint8_t data)
{
  Serial1.write(data);
  return data;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

uint8_t LiDisplay_readByte(void)
{
  return Serial1.read();
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

uint8_t LiDisplay_bytesAvailableToRead()
{
  return Serial1.available();
}
 

Engine-Off-Coast
Joined
2,782 Posts
Television set Bumper Gadget Automotive exterior Gas


Very beginnings... I finally got it to edit the values of more than just text boxes. Now that it works I can start making us an actual UI.

I'm thinking 5 screens:
  • Splash On
  • Grid Charging
  • Driving
  • Configuration
  • Splash Off

Different stuff could be displayed on each. Splash Off for example might display version number, hours left, and KW used during most recent drive cycle. Splash On might display version, hours left, and KW charged or energy consumption (from fan) during the period since last key-off.
 

Engine-Off-Coast
Joined
2,782 Posts
So far most of my efforts have been spent on getting the functionality down... have it turn on when car on, show splash then, and same with when car turned off, update data while driving without getting hung up, etc.

I haven't given a lot of thought to what parameters I want to display, but I've had a few ideas.

I'm assuming the stock instrument cluster was NHTSA approved, so I want to borrow ideas from it. Font, text size, colours used, black background, etc. Because the Nextion can do so much more than an old 4x20 character display I want to get away from the raw parameter readout. The stock instrument cluster makes sense to anyone who can read english even if they've never sat in the car before. The 4x20 displays are confusing and complicated.

I don't think most of the data that was displayed on the beta LCD needs to go on here, except maybe on a secondary page the driver can access by pressing a button to toggle between screens. For debugging purposes it will be good to see high and low cell for example but for most driving it's not helpful. When I still had the LCD the only thing I ever looked at was the SoC.

Anyway, on the Nextion I'll probably have a battery gauge similar to the one shown. I was also thinking of adding charge and assist bar graphs, maybe with numbers next to them, because we know from OBDIIC&C that the stock CHRG and ASST gauges lie to the driver all the time -- failing to show bg charge or incorrectly indicating maximum assist, etc.

Version info is for sure only going to end up on the splash page.

I might make a display of cumulative pack delta (kw in subtracted from kw out) or maybe a display of total KW regenerated over the drive cycle and total KW used over the drive cycle. The G2 Insight had the little plant gauge of driving fuel economy that it showed you when you turned the car off -- maybe some kind of helpful info presented at the end of the drive like could inform the driver on their driving habits.
 

Engine-Off-Coast
Joined
2,782 Posts
I ended up with NXT4832T035_011 which is one of the least sophisticated screens. LiBCM has a beeper and it already uses that to beep warnings at the driver.

Here's what I'm working with right now:

Gauge Font Measuring instrument Trip computer Odometer




This would be for the main driving screen. I'm not 100% sure about this layout yet.
 

Engine-Off-Coast
Joined
2,782 Posts
Mario made an .svg of the Insight graphs, so it wasn't that hard, I just copied from what he had done.

In the video I posted earlier I do have a normal Nextion bar graph of SoC, but when driving it isn't very helpful because it goes from 0 to 100 instead of 20 to 80, and it's a continuous bar instead of incremented segments so you can't actually get a feel for the value it's trying to represent. When looking at it, it's always just somewhere in the middle and isn't very informative, so looking at the written SoC was the only way to have an actual idea.
 

Engine-Off-Coast
Joined
2,782 Posts
Writing data to the nextion is slow, and I can only send 1 command at a time. Right now I've got it sending commands every 250ms. I think that time can be reduced, but changing bar graph colour would make an SoC change take 3 commands instead of 1.
 
  • Like
Reactions: Arbus

Engine-Off-Coast
Joined
2,782 Posts
If you are going to use touchscreen inputs... it is sensitive to the polling interval so you can end up hanging the screen if you don't poll it often enough etc... the stock Nextion library is very prone to this.

I ended up using EasyNextion which handles alittle of the work of getting the thing to work reliably .... you put a bit of code in each button and it triggers predefined functions eg trigger0() etc... when you press a button that is printing the correct bytes to UART. The other nextion libraries are all nice and use objects and such but they this is the only library I got working reliably.

You can put
Code:
bauds=38400
In the Program.s to set the baud rate to a permanently higher or lower rate... I have tested higher rates and they can only really be done over short cables, 38400 is a good compromise speed. I also changed all the names of my screen objects to single letters... so I could maximize sceen update speed and minimze serial errors.

I implemented a progress guage for the project I did (it was QT tester for an industrial board).... it also had an encoder my board was using and displaying the output to a graph with, something like add 0,23,0,data here to add plot points... I can dig up the code if curious.
# Touch Screen Inputs:
Yes we will need to use those

# Baud Rate:
LiBCM, for its own purposes, needs all the memory and storage it can get so the code has to be compact, so I'm not importing a nextion library. Do you know a way to set Nextion baud rate without the library? Note: The cable is probably about 5 feet long. IDK if that's too long.

# Plot data:
I would be happy to see the code if you have it!
 
1 - 20 of 186 Posts
Top