SolidGeek / VescUart

An Arduino library for interfacing with the VESC over UART
GNU General Public License v3.0
177 stars 92 forks source link

[Feature] get battery_level in % #55

Open n3roGit opened 10 months ago

n3roGit commented 10 months ago

Could you please implement to get battery_level in % from serial?

sussyboiiii commented 10 months ago

You can get a battery percentage estimate using this code:

voltage = (VESC.data.inpVoltage);
batterypercentage = ((voltage-38.4)/12)*100;    // ((Battery voltage - minimum voltage) / number of cells) x 100
n3roGit commented 10 months ago

Is this the same calculation as the vesc software? At the moment I use a battery drain curve and interpolate the percentage

sussyboiiii commented 10 months ago

I don't know but this isn't the most accurate because it assumes the discharge is linear but for me it works fine.

sussyboiiii commented 10 months ago

Is this the same calculation as the vesc software? At the moment I use a battery drain curve and interpolate the percentage

May I ask how you use a battery drain curve on an arduino?

n3roGit commented 10 months ago

https://github.com/n3roGit/DPVControl/tree/mytest/DPVController

Look into the battery function in the mytest branch :)

sussyboiiii commented 10 months ago

Thanks, I tested it and it seems to be pretty similar to the one I am using but probably a bit more accurate. Heres a graph of both: graph1

n3roGit commented 10 months ago

Oh great thanks for the feedback!

I hope someone implement to get it directly from the vest because the vesc has some filter and extra logic to get besser results

sussyboiiii commented 10 months ago

Yes, but the battery percentage the vesc shows me is also weird, my battery is at 3.7v per cell and 7 out of 16Ah drained and the vesc says its at 35% or below 30 with sag.

n3roGit commented 10 months ago

That doesn't sound optimal either. Unfortunately, I don't have any comparison values here yet. My project is still relatively at the beginning. May I ask what you have implemented with VESCUart?

sussyboiiii commented 10 months ago

Its a bit weird but heres the vesc function:

/**
 * Get the battery level, based on battery settings in configuration. Notice that
 * this function is based on remaining watt hours, and not amp hours.
 *
 * @param wh_left
 * Pointer to where to store the remaining watt hours, can be null.
 *
 * @return
 * Battery level, range 0 to 1
 */
float mc_interface_get_battery_level(float *wh_left) {
    const volatile mc_configuration *conf = mc_interface_get_configuration();
    const float v_in = motor_now()->m_input_voltage_filtered_slower;
    float battery_avg_voltage = 0.0;
    float battery_avg_voltage_left = 0.0;
    float ah_left = 0;
    float ah_tot = conf->si_battery_ah;

    switch (conf->si_battery_type) {
    case BATTERY_TYPE_LIION_3_0__4_2:
        battery_avg_voltage = ((3.2 + 4.2) / 2.0) * (float)(conf->si_battery_cells);
        battery_avg_voltage_left = ((3.2 * (float)(conf->si_battery_cells) + v_in) / 2.0);
        float batt_left = utils_map(v_in / (float)(conf->si_battery_cells),
                                    3.2, 4.2, 0.0, 1.0);
        batt_left = utils_batt_liion_norm_v_to_capacity(batt_left);
        ah_tot *= 0.85; // 0.85 because the battery is not fully depleted at 3.2V / cell
        ah_left = batt_left * ah_tot;
        break;

    case BATTERY_TYPE_LIIRON_2_6__3_6:
        battery_avg_voltage = ((2.8 + 3.6) / 2.0) * (float)(conf->si_battery_cells);
        battery_avg_voltage_left = ((2.8 * (float)(conf->si_battery_cells) + v_in) / 2.0);
        ah_left = utils_map(v_in / (float)(conf->si_battery_cells),
                2.6, 3.6, 0.0, conf->si_battery_ah);
        break;

    case BATTERY_TYPE_LEAD_ACID:
        // TODO: This does not really work for lead-acid batteries
        battery_avg_voltage = ((2.1 + 2.36) / 2.0) * (float)(conf->si_battery_cells);
        battery_avg_voltage_left = ((2.1 * (float)(conf->si_battery_cells) + v_in) / 2.0);
        ah_left = utils_map(v_in / (float)(conf->si_battery_cells),
                2.1, 2.36, 0.0, conf->si_battery_ah);
        break;

    default:
        break;
    }

    const float wh_batt_tot = ah_tot * battery_avg_voltage;
    const float wh_batt_left = ah_left * battery_avg_voltage_left;

    if (wh_left) {
        *wh_left = wh_batt_left;
    }

    return wh_batt_left / wh_batt_tot;
}
sussyboiiii commented 10 months ago

May I ask what you have implemented with VESCUart?

I'm building an e-bike and want to view speed, power consumption, temperatures etc. without the need for a phone.

n3roGit commented 10 months ago

oh very nice. for me it's a scooter for diving. feel free to look at content in the code if it helps you. but the webinterface and logging into a database will follow. https://github.com/n3roGit/DPVControl/tree/mytest

sussyboiiii commented 10 months ago

Cool project! How fast and far are you planning to go?

n3roGit commented 10 months ago

Yesterday I have already tested the part in the lake. Currently I'm at about 60m/minute, which is already quite fast in the water. Here I will still have to do some software sided tuning. Such devices are also rather long runners. I think I should be able to drive 4-6 hours.

sussyboiiii commented 10 months ago

Cool, keep it up!