Results 1 to 25 of 125

Threaded View

  1. #16
    Active Member
    Join Date
    Aug 2020
    Location
    Poland
    Posts
    81
    Spyder Garage
    0

    Default

    With information above I've succesfully finished my first trip yesterday without any errors and in fact without ABS, DPS and with my own LCD in cluster -> no limp mode off course .

    Without nanny this is a drift beast. TBH it's better for drifting than normal riding. For uneven roads it's constantly a bit wobbly with passanger present. For drifting it's pure fun.

    So, let's start technical.

    After removing motor from DPS to remove any resistance in steering system I've had to pretend there is working DPS by constantly putting message 0x330 with data 0x00, 0x99, 0x99, 0x00, 0xFF, 0xFF, 0x00, 0x00 to can bus and it works. No DPS and no errors

    Because ABS was also partly fauly (all can bus data correct but going into error above 10km/h), I've had to remove any traces of errors going from ABS. To do that ABS in on separate CAN bus and messages are forwarded to main bus but with removed errors. This also is succesfull.

    Unfortunately after key is turned there is a delay between ABS working and my program which causes errors in ECM. To clear errors I'm sending diagnostic messages after 5s from when key is turned:

    msg_error_clear[0].id = 0x713;
    msg_error_clear[1].id = 0x71C;
    msg_error_clear[2].id = 0x710;
    msg_error_clear[3].id = 0x715;
    msg_error_clear[4].id = 0x717;
    msg_error_clear[5].id = 0x715;
    msg_error_clear[6].id = 0x715;

    uint8_t tmp_buf_0[8] = { 0x04, 0x03, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00 };
    uint8_t tmp_buf_1[8] = { 0x0D, 0x03, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00 };
    uint8_t tmp_buf_2[8] = { 0x01, 0x03, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00 };
    uint8_t tmp_buf_3[8] = { 0x06, 0x03, 0x14, 0xFF, 0x00, 0x00, 0x00, 0x00 };
    uint8_t tmp_buf_4[8] = { 0x06, 0x03, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00 };
    uint8_t tmp_buf_5[8] = { 0x06, 0x02, 0x10, 0x89, 0x00, 0x00, 0x00, 0x00 };
    uint8_t tmp_buf_6[8] = { 0x06, 0x02, 0x10, 0x81, 0x00, 0x00, 0x00, 0x00 };

    There is also a matter of menu button which must be pressed before every ride. I'm sending 0x519 together with 0x402:

    0x591: 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    0x402: { /* three types of data */
    { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
    { 0x03, 0x21, 0x13, 0x61, 0x20, 0x11, 0x09, 0x00 },
    { 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00 }
    }

    Below is the code for can bus commmunication which sends, changes and retrieves data to/from can bus:

    Code:
    #pragma once
    
    #include <FlexCAN_T4.h>
    #include <globalVar.h>
    
    extern void can_changer_modify(CAN_message_t &msg);
    
    FlexCAN_T4<CAN1, RX_SIZE_1024, TX_SIZE_32> can1; // internal
    FlexCAN_T4<CAN2, RX_SIZE_1024, TX_SIZE_32> can2; // external
    
    CAN_message_t msg1;
    bool hasMsg1;
    
    CAN_message_t msg2;
    bool hasMsg2;
    
    #define msg_changer_id 0xAA
    CAN_message_t msg_changer0; // b0 - 0/1/2 no action/change/new,  b1 b2 - message id, b3 len, b4 type - 0/1/2/3 set exactly/set/reset/toggle
    CAN_message_t msg_changer1; // b0-b7 - toggle
    CAN_message_t msg_changer_new;
    
    uint16_t ready_delay_ms = 5000; // delay for isok message and error cleaning
    
    CAN_message_t msg_dps;
    CAN_message_t msg_lcd[3];
    uint8_t msg_lcd_cnt;
    CAN_message_t msg_isok;
    CAN_message_t msg_error_clear[7];
    uint8_t msg_error_clear_repeat_cntdn = 2;
    uint8_t msg_error_clear_cnt;
    
    uint8_t btn_buf_prev;
    
    void can_setup()
    {
        can1.begin();
        can1.setBaudRate(500000);
    
        can2.begin();
        can2.setBaudRate(500000);
    }
    
    void can_calcCrc8(CAN_message_t &msg)
    {
        switch (msg.len)
        {
            case 8: msg.buf[7] = msg.buf[0] ^ msg.buf[1] ^ msg.buf[2] ^ msg.buf[3] ^ msg.buf[4] ^ msg.buf[5] ^ msg.buf[6]; break;
            case 7: msg.buf[6] = msg.buf[0] ^ msg.buf[1] ^ msg.buf[2] ^ msg.buf[3] ^ msg.buf[4] ^ msg.buf[5]; break;
            case 6: msg.buf[5] = msg.buf[0] ^ msg.buf[1] ^ msg.buf[2] ^ msg.buf[3] ^ msg.buf[4]; break;
            case 5: msg.buf[4] = msg.buf[0] ^ msg.buf[1] ^ msg.buf[2] ^ msg.buf[3]; break;
            case 4: msg.buf[3] = msg.buf[0] ^ msg.buf[1] ^ msg.buf[2]; break;
        }
    }
    
    void can_incCounter0F(CAN_message_t &msg)
    {
        // assumption that if counter exists, it is before last byte
        msg.buf[msg.len - 2]++;
        if (msg.buf[msg.len - 2] == 0x10)
            msg.buf[msg.len - 2] = 0x00;
    }
    
    void can_changer_modify(CAN_message_t &msg)
    {
        if (msg_changer0.buf[3] > 8)
            msg.len = msg_changer0.buf[3] & 0xFF;
        else
            msg.len = 8; // default to 8
    
        if (msg_changer0.buf[4] == 0)
        {
            msg.buf[0] = msg_changer1.buf[0];
            msg.buf[1] = msg_changer1.buf[1];
            msg.buf[2] = msg_changer1.buf[2];
            msg.buf[3] = msg_changer1.buf[3];
            msg.buf[4] = msg_changer1.buf[4];
            msg.buf[5] = msg_changer1.buf[5];
            msg.buf[6] = msg_changer1.buf[6];
            msg.buf[7] = msg_changer1.buf[7];
        }
        else if (msg_changer0.buf[4] == 1)
        {
            msg.buf[0] |= msg_changer1.buf[0];
            msg.buf[1] |= msg_changer1.buf[1];
            msg.buf[2] |= msg_changer1.buf[2];
            msg.buf[3] |= msg_changer1.buf[3];
            msg.buf[4] |= msg_changer1.buf[4];
            msg.buf[5] |= msg_changer1.buf[5];
            msg.buf[6] |= msg_changer1.buf[6];
            msg.buf[7] |= msg_changer1.buf[7];
        }
        else if (msg_changer0.buf[4] == 2)
        {
            msg.buf[0] &= ~msg_changer1.buf[0];
            msg.buf[1] &= ~msg_changer1.buf[1];
            msg.buf[2] &= ~msg_changer1.buf[2];
            msg.buf[3] &= ~msg_changer1.buf[3];
            msg.buf[4] &= ~msg_changer1.buf[4];
            msg.buf[5] &= ~msg_changer1.buf[5];
            msg.buf[6] &= ~msg_changer1.buf[6];
            msg.buf[7] &= ~msg_changer1.buf[7];
        }
        else if (msg_changer0.buf[4] == 3)
        {
            msg.buf[0] ^= msg_changer1.buf[0];
            msg.buf[1] ^= msg_changer1.buf[1];
            msg.buf[2] ^= msg_changer1.buf[2];
            msg.buf[3] ^= msg_changer1.buf[3];
            msg.buf[4] ^= msg_changer1.buf[4];
            msg.buf[5] ^= msg_changer1.buf[5];
            msg.buf[6] ^= msg_changer1.buf[6];
            msg.buf[7] ^= msg_changer1.buf[7];
        }
    }
    
    /*void can_testchange_401(CAN_message_t &msg)
    {
        switch (msg.buf[0])
        {
            case 1:
                msg.buf[1] = 0;
                msg.buf[2] = 3;
                msg.buf[3] = 0xe7;
                msg.buf[4] = 0;
                msg.buf[5] = 0;
                msg.buf[6] = 0;
                msg.buf[7] = 0;
                break;
            case 3:
                msg.buf[1] = 0;
                msg.buf[2] = 0;
                msg.buf[3] = 6;
                msg.buf[4] = 149;
                msg.buf[5] = 13;
                msg.buf[6] = 107;
                msg.buf[7] = 0;
                break;
            case 4:
                msg.buf[1] = 0;
                msg.buf[2] = 0;
                msg.buf[3] = 6;
                msg.buf[4] = 204;
                msg.buf[5] = 19;
                msg.buf[6] = 170;
                msg.buf[7] = 0;
                break;
        }
    
    }*/
    
    void can_send_changer_new()
    {
        msg_changer_new.id = msg_changer0.buf[2];
        msg_changer_new.id = msg_changer_new.id << 8;
        msg_changer_new.id += msg_changer0.buf[1];
        can_changer_modify(msg_changer_new);
    
        can1.write(msg_changer_new);
    }
    
    void can_save_msg_keys(CAN_message_t &msg)
    {
        if (btn_buf_prev == msg.buf[1])
            return;
    
        // store bits changed to 1
        uint8_t tmp = (btn_buf_prev ^ msg.buf[1]) & msg.buf[1];
    
        if (tmp & 0x1)
            key_up = true;
        if (tmp & 0x2)
            key_down = true;
        if (tmp & 0x4)
            key_left = true;
        if (tmp & 0x8)
            key_right = true;
        if (tmp & 0x10)
            key_menu = true;
        if (tmp & 0x20)
            key_set = true;
        if (tmp & 0x40)
            key_back = true;
    
        btn_buf_prev = msg.buf[1];
    }
    
    void can_save_data_cluster_401(CAN_message_t &msg)
    {
        /*                Serial.println(
                    String(msg.buf[1]).append( " ")
                    .append(msg.buf[2]).append(" ")
                    .append(msg.buf[3]).append(" ")
                    .append(msg.buf[4]).append(" ")
                    .append(msg.buf[5]).append(" ")
                    .append(msg.buf[6]).append(" ")
                    .append(msg.buf[7]).append(" "));
        */
        switch (msg.buf[0])
        {
            case 0: 
                break;
            case 1: 
                break;
            case 2: 
                can_triptotal = ((uint32_t)msg.buf[1] << 24) + ((uint32_t)msg.buf[2] << 16) + ((uint32_t)msg.buf[3] << 8) + msg.buf[4];
                break;
            case 3: 
                can_tripa = ((uint32_t)msg.buf[1] << 24) + ((uint32_t)msg.buf[2] << 16) + ((uint32_t)msg.buf[3] << 8) + msg.buf[4];
                break;
            case 4: 
                can_tripb = ((uint32_t)msg.buf[1] << 24) + ((uint32_t)msg.buf[2] << 16) + ((uint32_t)msg.buf[3] << 8) + msg.buf[4];
                break;
            case 5: 
                break;
            case 6: 
                can_acslevel = B1000 - ((msg.buf[2] & B1110) >> 1);
                can_acsheight = ((uint16_t)msg.buf[3] << 8) + msg.buf[4];
                break;
        }
    }
    
    void can_save_data(CAN_message_t &msg)
    {
        switch (msg.id)
        {
            case 0x102:
                can_tempengine = msg.buf[3];
                can_tempair = msg.buf[4];
                break;
    
            case 0x308:
                // B0: bity: low bat, -, -, -, engine hi temp, -, oil switch
                can_islowbat = msg.buf[0] & 1;
                can_i****emp = msg.buf[0] >> 4 & 1;
                can_isoilswitch = msg.buf[0] >> 6 & 1;
                break;
    
            case 0x310:
                can_gearbyte = msg.buf[0] & 0xF; // b0: bieg 1-6, 7 neutral, 8 reverse
                break;
    
            case 0x430:
                can_abspressure = msg.buf[4]; // stosunek 1:33 kpa, 0x3E == 0, 0xFF == 6369 kPa
                break;
        }
    }
    
    void can_send_dps()
    {
        // initialize dps message
        if (msg_dps.id == 0)
        {
            msg_dps.id = 0x330;
            uint8_t tmp_buf[8] = { 0x00, 0x99, 0x99, 0x00, 0xFF, 0xFF, 0x00, 0x00 };
            memcpy(msg_dps.buf, tmp_buf, 8);
        }
    
        // send dps data to both buses
        can1.write(msg_dps);
        can2.write(msg_dps);
    
        // set new values for counter and crc8 bytes
        can_incCounter0F(msg_dps);
        msg_dps.buf[7] = msg_dps.buf[6]; // copy counter to crc because crc in this case is the same as counter
    }
    
    void can_send_lcd()
    {
        // initialize lcd message
        if (msg_lcd[0].id == 0)
        {
            msg_lcd[0].id = 0x402;
            msg_lcd[1].id = 0x402;
            msg_lcd[2].id = 0x402;
    
            uint8_t tmp_buf[3][8] = { 
                { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
                { 0x03, 0x21, 0x13, 0x61, 0x20, 0x11, 0x09, 0x00 },
                { 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00 } };
            
            memcpy(msg_lcd[0].buf, tmp_buf[0], 8);
            memcpy(msg_lcd[1].buf, tmp_buf[1], 8);
            memcpy(msg_lcd[2].buf, tmp_buf[2], 8);
        }
    
        if (msg_lcd_cnt == 11)
            can1.write(msg_lcd[2]);
        else if (msg_lcd_cnt == 10)
            can1.write(msg_lcd[1]);
        else
            can1.write(msg_lcd[0]);
    
        msg_lcd_cnt++;
        if (msg_lcd_cnt == 12)
            msg_lcd_cnt = 0;
    }
    
    void can_send_isok()
    {
        // initialize lcd message
        if (msg_isok.id == 0)
        {
            msg_isok.id = 0x591;
            msg_isok.len = 1;
            uint8_t tmp_buf[8] = { 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
            memcpy(msg_isok.buf, tmp_buf, 8);
        }
    
        can1.write(msg_isok);
    }
    
    void can_send_error_clear()
    {
        // initialize lcd message
        if (msg_error_clear[0].id == 0)
        {
            msg_error_clear[0].id = 0x713;
            msg_error_clear[1].id = 0x71C;
            msg_error_clear[2].id = 0x710;
            msg_error_clear[3].id = 0x715;
            msg_error_clear[4].id = 0x717;
            msg_error_clear[5].id = 0x715;
            msg_error_clear[6].id = 0x715;
    
            uint8_t tmp_buf_0[8] = { 0x04, 0x03, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00 };
            uint8_t tmp_buf_1[8] = { 0x0D, 0x03, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00 };
            uint8_t tmp_buf_2[8] = { 0x01, 0x03, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00 };
            uint8_t tmp_buf_3[8] = { 0x06, 0x03, 0x14, 0xFF, 0x00, 0x00, 0x00, 0x00 };
            uint8_t tmp_buf_4[8] = { 0x06, 0x03, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00 };
            uint8_t tmp_buf_5[8] = { 0x06, 0x02, 0x10, 0x89, 0x00, 0x00, 0x00, 0x00 };
            uint8_t tmp_buf_6[8] = { 0x06, 0x02, 0x10, 0x81, 0x00, 0x00, 0x00, 0x00 };
    
            memcpy(msg_error_clear[0].buf, tmp_buf_0, 8);
            memcpy(msg_error_clear[1].buf, tmp_buf_1, 8);
            memcpy(msg_error_clear[2].buf, tmp_buf_2, 8);
            memcpy(msg_error_clear[3].buf, tmp_buf_3, 8);
            memcpy(msg_error_clear[4].buf, tmp_buf_4, 8);
            memcpy(msg_error_clear[5].buf, tmp_buf_5, 8);
            memcpy(msg_error_clear[6].buf, tmp_buf_6, 8);
        }
    
        can1.write(msg_error_clear[msg_error_clear_cnt]);
    
        can2.write(msg_error_clear[msg_error_clear_cnt]);
    
        msg_error_clear_cnt++;
        if (msg_error_clear_cnt == 7)
        {
            msg_error_clear_repeat_cntdn--;
            msg_error_clear_cnt = 0;
        }
    }
    
    void can_handle_msg_post(CAN_message_t &msg)
    {
        switch (msg.id)
        {
            // store message changer data
            case (msg_changer_id+0): msg_changer0 = msg; break;
            case (msg_changer_id+1): msg_changer1 = msg; break;
    
            //case 0x401: can_testchange_401(msg); break;
    
            case 0x102: can_save_data(msg); break;
            case 0x308: can_save_data(msg); break;
            case 0x310: can_save_data(msg); break;
            case 0x401: can_save_data_cluster_401(msg); break;
            case 0x340: can_save_msg_keys(msg); break;
    
            case 0x430: // remove error from vcm message
                can_save_data(msg); break;
                break;
        }
    }
    
    void can_handle_msg_pre(CAN_message_t &msg)
    {
        switch (msg.id)
        {
            case 0x020: // remove error from vcm message
                msg.buf[0] = msg.buf[0] & 0xF0;
                msg.buf[1] = 0x00;
                can_calcCrc8(msg);
                break;
            case 0x430: // remove error from vcm message
                msg.buf[0] = msg.buf[1] = 0x99;
                can_calcCrc8(msg);
                break;
        }
    
        // change message
        if (msg_changer0.buf[0] == 1)
        {
            // match id
            if ((msg.id & 0xFF) == msg_changer0.buf[1] && ((msg.id >> 8) & 0xFF) == msg_changer0.buf[2])
                can_changer_modify(msg);
        }
    }
    
    void can_handle()
    {
        // send custom messages with minimum 1ms offset
        if (event1ms && timer1msCounterStored > 10) // skip first few ms because of -n in checks
        {
            if (ready_delay_ms > 0)
                ready_delay_ms--;
    
            // send dps every 34ms
            if (!((timer1msCounterStored -0) & (0x20-1)))
                can_send_dps();
    
            // send lcd every 128ms
            if (!((timer1msCounterStored -1) & (0x80-1)))
                can_send_lcd();
    
            // send isok every 128ms
            // start sending after moto is ready
            if (ready_delay_ms == 0 && !((timer1msCounterStored -2) & (0x80-1)))
                can_send_isok();
    
            // send error clear every 128ms
            // start sending after moto is ready
            // send only once
            if (ready_delay_ms == 0 && msg_error_clear_repeat_cntdn > 0 && !((timer1msCounterStored -2) & (0x80-1)))
                can_send_error_clear();
    
            // send test message every 128ms
            if (!((timer1msCounterStored -4) & (0x80-1)))
            {
                // new test message
                if (msg_changer0.buf[0] == 2)
                    can_send_changer_new();
            }
        }
    
        // read messages
        hasMsg1 = can1.read(msg1);
        hasMsg2 = can2.read(msg2);
    
        // don't change message going from ecu to external bus
        if (hasMsg1)
        {
            if (msg1.id < 0x700) // skip diagnostic messages
                can_handle_msg_pre(msg1);
    
            can2.write(msg1);
    
            if (msg1.id < 0x700) // skip diagnostic messages
                can_handle_msg_post(msg1);
        }
    
        if (hasMsg2)
        {
            if (msg2.id < 0x700) // skip diagnostic messages
                can_handle_msg_pre(msg2);
    
            can1.write(msg2);
    
            if (msg2.id < 0x700) // skip diagnostic messages
                can_handle_msg_post(msg2);
        }
    }
    Below is code responsible for lcd screen with LVGL library:

    Code:
    #pragma once
    
    #include <lvgl.h>
    #include <types.h>
    #include <globalVar.h>
    #include <gui.h>
    
    
    
    class scr_main : public screen_base
    {
        // styles
        lv_style_t box_style_box;
        lv_style_t box_style_box_checked;
        lv_style_t bar_style_temp;
    
        // controls
        lv_obj_t*  rol_gearpos;
        lv_obj_t*  lbl_tempair;
        lv_obj_t*  lbl_tripa;
        lv_obj_t*  lbl_triptotal;
    
        lv_obj_t*  lbl_tempengine;
        lv_obj_t*  bar_tempengine;
        lv_obj_t*  bar_abspressure;
        lv_obj_t*  lbl_acslevel;
        lv_obj_t*  bar_acsheight;
    
        lv_obj_t*  box_islowbat;
        lv_obj_t*  box_i****emp;
        lv_obj_t*  box_isoilswitch;
    
        uint32_t gui_tripa;
        uint32_t gui_triptotal;
        uint16_t gui_tempair;
        uint16_t gui_tempengine;
        uint16_t gui_acslevel;
        uint16_t gui_abspressure;
        uint16_t gui_acsheight;
    
        lv_obj_t* build()
        {
            lv_obj_t* ret = lv_obj_create(NULL);
    
            //lv_obj_set_style_bg_color(ret, lv_palette_lighten(LV_PALETTE_BLUE, 4), LV_PART_MAIN);
    
            lv_obj_set_style_bg_color(ret, lv_color_black(), LV_PART_MAIN);
            lv_obj_set_style_text_color(ret, lv_color_white(), LV_PART_MAIN);
    
            // create styles
            lv_style_init(&box_style_box);
            lv_style_set_border_color(&box_style_box, lv_palette_main(LV_PALETTE_RED));
            lv_style_set_border_width(&box_style_box, 3);
    
            lv_style_init(&box_style_box_checked);
            lv_style_set_border_color(&box_style_box_checked, lv_palette_main(LV_PALETTE_RED));
            lv_style_set_border_width(&box_style_box_checked, 3);
            lv_style_set_bg_color(&box_style_box_checked, lv_palette_main(LV_PALETTE_RED));
    
            lv_style_init(&bar_style_temp);
            lv_style_set_bg_opa(&bar_style_temp, LV_OPA_COVER);
            lv_style_set_bg_color(&bar_style_temp, lv_palette_main(LV_PALETTE_RED));
            lv_style_set_bg_grad_color(&bar_style_temp, lv_palette_main(LV_PALETTE_BLUE));
            lv_style_set_bg_grad_dir(&bar_style_temp, LV_GRAD_DIR_VER);
    
            // lv_style_set_bg_grad_color(&style_btn, lv_palette_main(LV_PALETTE_GREY));
            // lv_style_set_bg_grad_dir(&style_btn, LV_GRAD_DIR_VER);
    
            lv_obj_t * panel;
            lv_obj_t * obj;
    
            // gear pos
            rol_gearpos = lv_roller_create(ret);
            lv_roller_set_options(rol_gearpos, " \n1\n2\n3\n4\n5\n6\nN\nR", LV_ROLLER_MODE_INFINITE);
            lv_roller_set_visible_row_count(rol_gearpos, 5);
            lv_obj_set_width(rol_gearpos, 40);
            lv_obj_set_pos(rol_gearpos, 0, 0);
    
            // air temp
            lbl_tempair = lv_label_create(ret);
            lv_label_set_text(lbl_tempair, "AIR T");
            lv_obj_set_pos(lbl_tempair, 50, 0);
    
            // Trip A
            obj = lv_label_create(ret);
            lv_label_set_text(obj, "Trip");
            lv_obj_set_style_text_font(obj, &lv_font_montserrat_20, LV_PART_MAIN);
            lv_obj_set_pos(obj, 50, 41);
    
            lbl_tripa = lv_label_create(ret);
            // lv_obj_set_style_text_align(lbl_triptotal, LV_TEXT_ALIGN_RIGHT, 0); // crashing
            lv_obj_set_width(lbl_tripa, 120);
            lv_obj_set_pos(lbl_tripa, 110, 40);
    
            // Total
            obj = lv_label_create(ret);
            lv_label_set_text(obj, "Total");
            lv_obj_set_style_text_font(obj, &lv_font_montserrat_20, LV_PART_MAIN);
            lv_obj_set_pos(obj, 50, 81);
    
            lbl_triptotal = lv_label_create(ret);
            //lv_obj_set_style_text_align(lbl_triptotal, LV_TEXT_ALIGN_RIGHT, 0); // crashing
            lv_obj_set_width(lbl_triptotal, 120);
            lv_obj_set_pos(lbl_triptotal, 110, 80);
    
            // right side bars
            // engine temp
            lbl_tempengine = lv_label_create(ret);
            lv_label_set_text(lbl_tempengine, "ENG T");
            lv_obj_set_pos(lbl_tempengine, 215, 0);
    
            bar_tempengine = lv_bar_create(ret);
            lv_obj_add_style(bar_tempengine, &bar_style_temp, LV_PART_INDICATOR);
            lv_obj_set_size(bar_tempengine, 30, 180);
            lv_bar_set_range(bar_tempengine, 40, 130);
            lv_obj_set_pos(bar_tempengine, 235, 30);
    
            // abs pressure
            bar_abspressure = lv_bar_create(ret);
            lv_obj_set_style_bg_color(bar_abspressure, lv_palette_main(LV_PALETTE_RED), LV_PART_INDICATOR);
            lv_obj_set_size(bar_abspressure, 20, 180);
            lv_bar_set_range(bar_abspressure, 0x3e, 0xCA); // 140 * 33 = 4620kPa
            lv_obj_set_pos(bar_abspressure, 270, 30);
    
            // acs level
            lbl_acslevel = lv_label_create(ret);
            lv_label_set_text(lbl_acslevel, "-");
            lv_obj_set_pos(lbl_acslevel, 295, 0);
            
            // acs height
            bar_acsheight = lv_bar_create(ret);
            lv_obj_set_size(bar_acsheight, 20, 180);
            lv_bar_set_range(bar_acsheight, 250, 650);
            lv_obj_set_pos(bar_acsheight, 295, 30);
    
            // checkboxes
            panel = lv_obj_create(ret);
            lv_obj_set_size(panel, 320, 30);
            lv_obj_set_pos(panel, 0, 210);
    
            lv_obj_set_flex_flow(panel, LV_FLEX_FLOW_ROW);
            lv_obj_set_flex_align(panel, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER);
    
            box_islowbat = lv_checkbox_create(panel);
            lv_checkbox_set_text(box_islowbat, "Bat");
            lv_obj_add_style(box_islowbat, &box_style_box, LV_PART_INDICATOR);
            lv_obj_add_style(box_islowbat, &box_style_box_checked, LV_PART_INDICATOR | LV_STATE_CHECKED);
    
            box_i****emp = lv_checkbox_create(panel);
            lv_checkbox_set_text(box_i****emp, "Temp");
            lv_obj_add_style(box_i****emp, &box_style_box, LV_PART_INDICATOR);
            lv_obj_add_style(box_i****emp, &box_style_box_checked, LV_PART_INDICATOR | LV_STATE_CHECKED);
    
            box_isoilswitch = lv_checkbox_create(panel);
            lv_checkbox_set_text(box_isoilswitch, "Oil");
            lv_obj_add_style(box_isoilswitch, &box_style_box, LV_PART_INDICATOR);
            lv_obj_add_style(box_isoilswitch, &box_style_box_checked, LV_PART_INDICATOR | LV_STATE_CHECKED);
    
            lv_obj_update_layout(box_isoilswitch);
    
            return ret;
        }
    
        void open()
        {
    
        }
    
        void close()
        {
            
        }
    
        // 100us main 
        void event()
        {
            // only one at a time for optimization purposes starting from highest priority
            if (gui_abspressure != can_abspressure)
            {
                gui_abspressure = can_abspressure;
                lv_bar_set_value(bar_abspressure, gui_abspressure, LV_ANIM_OFF);
            }
            else if (gui_acsheight != can_acsheight)
            {
                gui_acsheight = can_acsheight;
                lv_bar_set_value(bar_acsheight, gui_acsheight, LV_ANIM_OFF); 
            }
            else if (gui_tempair != can_tempair)
            {
                gui_tempair = can_tempair;
                int temp = gui_tempair-60;
                lv_label_set_text(lbl_tempair, String((temp)).append("*C").c_str());
            }
            else if (gui_tripa != can_tripa)
            {
                gui_tripa = can_tripa;
                String tripastr = String(gui_tripa >= 10 ? gui_tripa : 10); // co najmniej 100m zeby bylo co wyswietlac
                String tripadec = tripastr.substring(tripastr.length()-2, tripastr.length());
                tripastr.remove(tripastr.length()-2, 2);
                tripastr.append(",").append(tripadec);
                lv_label_set_text(lbl_tripa, tripastr.c_str());
            }
            else if (gui_triptotal != can_triptotal)
            {
                gui_triptotal = can_triptotal;
    
                String triptotalstr = String(gui_triptotal);
                String triptotaldecstr = triptotalstr.substring(triptotalstr.length()-2, triptotalstr.length());
                triptotalstr.remove(triptotalstr.length()-2, 2);
                triptotalstr.append(",").append(triptotaldecstr);
                lv_label_set_text(lbl_triptotal, triptotalstr.c_str());
            }
            else if (gui_tempengine != can_tempengine)
            {
                gui_tempengine = can_tempengine;
                int temp = gui_tempengine-60;
                lv_label_set_text(lbl_tempengine, String((temp)).append("*C").c_str());
                lv_bar_set_value(bar_tempengine, temp, LV_ANIM_OFF);
            }
            else if (gui_acslevel != can_acslevel)
            {
                gui_acslevel = can_acslevel;
                lv_label_set_text(lbl_acslevel, String(gui_acslevel).c_str());
            }
            else
            {
                lv_roller_set_selected(rol_gearpos, (uint16_t)can_gearbyte, LV_ANIM_OFF);
    
                if (can_islowbat) lv_obj_add_state(box_islowbat, LV_STATE_CHECKED);
                else lv_obj_clear_state(box_islowbat, LV_STATE_CHECKED); 
                
                if (can_i****emp) lv_obj_add_state(box_i****emp, LV_STATE_CHECKED);
                else lv_obj_clear_state(box_i****emp, LV_STATE_CHECKED); 
    
                if (can_isoilswitch) lv_obj_add_state(box_isoilswitch, LV_STATE_CHECKED);
                else lv_obj_clear_state(box_isoilswitch, LV_STATE_CHECKED);
            }
        }
    };
    global variables:

    Code:
    // can bus data
    bool can_islowbat, can_i****emp, can_isoilswitch;
    uint16_t can_tempengine, can_tempair;
    uint16_t can_gearbyte;
    uint16_t can_abspressure;
    uint16_t can_acsheight;
    uint16_t can_acslevel;
    uint32_t can_triptotal;
    uint32_t can_tripa;
    uint32_t can_tripb;
    main loop:

    Code:
    void loop()
    {
    
      // critical code 
      can_handle();
    
      // catch volatile timer
      event1ms = timer1msCounterStored != timer1msCounter;
      if (!event1ms)
        return;
    
      // 1ms code
      timer1msCounterStored = timer1msCounter;
      event4ms = !(timer1msCounterStored & 0x3);
      
      // GUI code every 4ms
      if (event4ms)
      {
        gui_update();
      }
    
    }
    gui_update() basically calls event() on current screen.

    I have two screens:
    - main for brake pressure, trip, ACS height, gear position, temp and some other stuff
    - snake game for playing while my wife goes for shopping


    Last edited by megagame; 05-04-2023 at 05:44 AM.
    2011 Spyder RT with some work to do

    https://www.spyderlovers.com/forums/...from-graveyard

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •