1. Create a new .cpp file in the respective folders. For example, anything dealing with the battery management system (BMS) should go in the src/devices/bms (things could change but general idea).
  2. All new .cpp files that you create require a [name].cpp and a [name].h file. For the [name].h you should organize your files like this.
#ifndef BATTMANAGE_H_
#define BATTMANAGE_H_

#include <Arduino.h>
#include "../../config.h"
#include "../Device.h"
class BatteryManagerConfiguration : public DeviceConfiguration {
public:
    float packCapacity;
    float packAHRemaining;
    float highVoltLimit;
    float lowVoltLimit;
    float highCellLimit;
    float lowCellLimit;
    float highTempLimit;
    float lowTempLimit;
};

class BatteryManager : public Device {
public:
    BatteryManager();
    ~BatteryManager();
    float getPackVoltage();
    float getPackCurrent();
    float getSOC();
    float getHighestTemperature();
    float getLowestTemperature();
    DeviceType getType();
    void setup();
    void handleTick();
    
    void loadConfiguration();
    void saveConfiguration();
    
    //a bunch of boolean functions. Derived classes must implment
    //these functions to tell everyone else what they support
    virtual bool hasPackVoltage() = 0;
    virtual bool hasPackCurrent() = 0;
    virtual bool hasTemperatures() = 0;
    virtual bool isChargeOK() = 0;
    virtual bool isDischargeOK() = 0;
protected:
    float packVoltage;
    float packCurrent;
    float SOC; //state of charge in percent
    float lowestCellV, highestCellV;
    float lowestCellTemp, highestCellTemp;
    //should be some form of discharge and charge limit. I don't know if it should be % or amps
    //some BMS systems will report one way and some the other.
    int dischargeLimit, chargeLimit;
    bool allowCharge, allowDischarge;

private:
};

#endif

Key notes when setting up the .h file.

For the .cpp file you should write all of the necessary Constructor, Destructor, and initializing of functions. An example is below

#include "BatteryManager.h"

BatteryManager::BatteryManager() : Device()
{
    packVoltage = 0;
    packCurrent = 0;
    SOC = 0;
}

BatteryManager::~BatteryManager()
{
}

DeviceType BatteryManager::getType() {
    return (DEVICE_BMS);
}

void BatteryManager::handleTick() {
    
}

void BatteryManager::setup() {

    BatteryManagerConfiguration *config = (BatteryManagerConfiguration *) getConfiguration();

    ConfigEntry entry;
    entry = {"CAPACITY", "Capacity of battery pack in ampere-hours", &config->packCapacity, CFG_ENTRY_VAR_TYPE::FLOAT, {.floating = 0.0}, {.floating = 100000.0}, 2, nullptr};
    cfgEntries.push_back(entry);
    entry = {"VOLTLIMHI", "High limit for pack voltage in volts", &config->highVoltLimit, CFG_ENTRY_VAR_TYPE::FLOAT, {.floating = 0.0}, {.floating = 800.0}, 1, nullptr};
    cfgEntries.push_back(entry);
    entry = {"VOLTLIMLO", "Low limit for pack voltage in volts", &config->lowVoltLimit, CFG_ENTRY_VAR_TYPE::FLOAT, {.floating = 0.0}, {.floating = 800.0}, 1, nullptr};
    cfgEntries.push_back(entry);
    entry = {"CELLLIMHI", "High limit for cell voltage in volts", &config->highCellLimit, CFG_ENTRY_VAR_TYPE::FLOAT, {.floating = 0.0}, {.floating = 5.0}, 3, nullptr};
    cfgEntries.push_back(entry);
    entry = {"CELLLIMLO", "Low limit for cell voltage in hundredths of a volt", &config->lowCellLimit, CFG_ENTRY_VAR_TYPE::FLOAT, {.floating = 0.0}, {.floating = 5.0}, 3, nullptr};
    cfgEntries.push_back(entry);
    entry = {"TEMPLIMHI", "High limit for pack and cell temperature in degrees C", &config->highTempLimit, CFG_ENTRY_VAR_TYPE::FLOAT, {.floating = 0.0}, {.floating = 255.0}, 1, nullptr};
    cfgEntries.push_back(entry);
    entry = {"TEMPLIMLO", "Low limit for pack and cell temperature in degrees C", &config->lowTempLimit, CFG_ENTRY_VAR_TYPE::FLOAT, {.floating = -255.0}, {.floating = 255.0}, 1, nullptr};
    cfgEntries.push_back(entry);

#ifndef USE_HARD_CODED
    if (prefsHandler->checksumValid()) { //checksum is good, read in the values stored in EEPROM
    }
    else { //checksum invalid. Reinitialize values and store to EEPROM
        //prefsHandler->saveChecksum();
    }
#else
#endif

//TickHandler::getInstance()->detach(this);
//TickHandler::getInstance()->attach(this, CFG_TICK_INTERVAL_MOTOR_CONTROLLER_DMOC);

}

float BatteryManager::getPackVoltage()
{
    return packVoltage;
}

float BatteryManager::getPackCurrent()
{
    return packCurrent;
}

float BatteryManager::getSOC()
{
    return SOC;
}

float BatteryManager::getHighestTemperature()
{
    return highestCellTemp;
}

float BatteryManager::getLowestTemperature()
{
    return lowestCellTemp;
}

void BatteryManager::loadConfiguration() {
    BatteryManagerConfiguration *config = (BatteryManagerConfiguration *)getConfiguration();

    Device::loadConfiguration(); // call parent

    //if (prefsHandler->checksumValid()) { //checksum is good, read in the values stored in EEPROM
        prefsHandler->read("Capacity", &config->packCapacity, 100.0f);
        prefsHandler->read("AHRemaining", &config->packAHRemaining, 50.0f);
        prefsHandler->read("HVHighLim", &config->highVoltLimit, 385.0f);
        prefsHandler->read("HVLowLim", &config->lowVoltLimit, 240.0f);
        prefsHandler->read("CellHiLim", &config->highCellLimit, 3.900f);
        prefsHandler->read("CellLowLim", &config->lowCellLimit, 2.400f);
        prefsHandler->read("TempHighLim", &config->highTempLimit, 60.0f);
        prefsHandler->read("TempLowLim", &config->lowTempLimit, -20.0f);        
}

void BatteryManager::saveConfiguration() {
    BatteryManagerConfiguration *config = (BatteryManagerConfiguration *)getConfiguration();
    
    Device::saveConfiguration(); // call parent

    prefsHandler->write("AHRemaining", config->packAHRemaining);
    prefsHandler->write("Capacity", config->packCapacity);
    prefsHandler->write("HVHighLim", config->highVoltLimit);
    prefsHandler->write("HVLowLim", config->lowVoltLimit);
    prefsHandler->write("CellHiLim", config->highCellLimit);
    prefsHandler->write("CellLowLim", config->lowCellLimit);
    prefsHandler->write("TempHighLim", config->highTempLimit);
    prefsHandler->write("TempLowLim", config->lowTempLimit);    

    prefsHandler->saveChecksum();
}

Some Important Functions That Will Be Useful

rawSignal.input1 = systemIO.getAnalogIn(5);