LibreSolar / charge-controller-firmware

Firmware for Libre Solar MPPT/PWM charge controllers
https://libre.solar/charge-controller-firmware/
Apache License 2.0
144 stars 71 forks source link

Development Branch: Battery Pack Configuration #13

Closed hogthrob closed 5 years ago

hogthrob commented 6 years ago

Hi, I have been thinking about a good way to break down the configuration of the system and came up with this breakdown:

We have

So what we need is a way for the user of the firmware easily to describe at least their cell configuration and pack configuration since without this no safe operation is possible. The minimum to specify is the chemistry, the maximum charge current, the maximum discharge current and the numbers of cells in parallel/series. Voltages may be derived from the chemistry (or have these configurable as well).

The charge strategy can be selected based on cell chemistry and calculates certain parameters from the cell and pack configuration parameters. We may permit modification of the strategy's parameters by the user at some stage of future development but this is not mandatory for safe operation.

Technically I would suggest to separate the battery cell / pack information into data structures separate from strategy information and have a way to let the user specify this easily when compiling the firmware and possibly later also for a running system, if there is persistent storage for parameters available (EEPROM).

During system start this "minimal set of user configurable data" is used for deriving the actual charging algorithm operational data from. This separation makes it easier to change the charging internal data structures without having the need to change the user provided information for a given system instance when upgrading to newer versions of the software. User just pulls the newest release, recompiles and loads it.

I think something like this makes using the firmware much easier. Next step is of course to implement a way to provide this information without having to compile the values into the firmware itself. But even then it is still the same issue in general: users don't want to be forced to (re)configure with every firmware update, so we need a stable set of parameters to describe the battery pack defined which are used across version. Having these defined makes at least basic operation within safe limits possible.

If this is an acceptable proposal, I would add this to the development branch of things. Since I would go for separate data structures, this is fairly uninvasive (not entirely, of course as the data needs to be read/used when initializing the charging).

martinjaeger commented 6 years ago

Sounds like a good idea.

I agree to separate battery pack and cells.

The charging strategy is partly defined by the cell type, e.g. Li-ion chemistries shouldn't have trickle charging. So information like voltage setpoints for different charging states might have to be kept in the cell struct. Or do you have a different idea how to prevent a user from selecting trickle charge in the charge strategy even though he has a Li-ion battery?

For initial setup of the charge controller we might have a config/setup/init.cpp which creates and initializes the necessary structs. Other software components afterwards access the structs via external keyword. As suggested before by you, we could have a config.cpp.template which has to be copied to config.cpp by the user and is afterwards kept untouched (added to .gitignore).

For changing the settings without recompilation my idea is to use the thingset protocol in the future. It can be used via serial already (even USB CDC worked for F0 with the old USBDevice library). We just need to add the parameters we want to make changeable to the data_objects. In order to store the values in EEPROM, we need to add them to eeprom_data_objects afterwards.

Currently Thingset only supports reading and writing specific values. We could add an RPC "setBatteryLFP" for example, which would automatically select this type of chemistry. But the !exec function is not yet fully specified nor implemented in Thingset.

You are welcome to implement your proposed changes in the data structure. In the meantime I will put the thingset part into a separate library: https://github.com/ThingSet/thingset-c.

hogthrob commented 6 years ago

Hi Martin,

good. I will start with a little refactoring in the original code charger.cpp cde for battery_init.

But could you please push the changes regarding the use of the thingset-c library to this project, or do you intend to keep the thingset-c repo in sync manually with the copy in the lib folder?

In any case I do have one small thing for this library:

In cbor.c: around line 98 and 320 use the pragmas around the respective lines to mute the gcc warnings regarding the cast. With this we can leave the otherwise very helpful warning active.

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
    *((uint32_t*)&data[1]) = htonl(*((uint32_t*)&value));
#pragma GCC diagnostic pop
martinjaeger commented 6 years ago

Not completely sure about good workflow for thingset library.

The separate repository is now uploaded. It could be integrated via platformio with: lib_deps = https://github.com/ThingSet/thingset-c

Alternatively, we could integrate it as a git submodule into the library folder. This would allow changing the library within the MPPT code and push the changes. But in the past I found that git submodules were quite difficult to handle.

Thanks for the hint regarding the warning.

hogthrob commented 6 years ago

I am good with any of these approaches, just wanted to know how you want to handle this. Since I haven't used submodules before, I would have had a slight prerefence for trying it (just to learn how it works and when not) but your choice entirely.

hogthrob commented 6 years ago

One more question: I can't compile any of the builds with USB enabled, why can you do this? I get the following error: https://travis-ci.org/hogthrob/MPPT-Charger_Software/builds/438383733#L1904 Happens not only on Travis but also locally on my machine.

martinjaeger commented 6 years ago

Looks like it still picks the broken mbed USB libraries instead of the local ones in the lib folder: /home/travis/.platformio/packages/framework-mbed/features/unsupported/USBDevice/targets/TARGET_STM/USBHAL_STM32.cpp

I cloned the complete repository again to a temp folder and compiled all 4 environments (libresolar 5/10 and cloudsolar 02/03). Only some warning, but no errors.

Ideas:

martinjaeger commented 6 years ago

https://travis-ci.com/LibreSolar/MPPT-Charger_Software seems to build.

hogthrob commented 6 years ago

Well, with the libraries from the repo I now can compile with USB support. The USB stuff in the folder appears to be older since when I enable USBserial, it compiles but throws massive warnings regarding deprecated stuff:

^
In file included from src\main.cpp:41:0:
lib\USBSerial/USBSerial.h: In constructor 'USBSerial::USBSerial(uint16_t, uint16_t, uint16_t, bool)':
lib\USBSerial/USBSerial.h:59:203: warning: 'mbed::FunctionPointerArg1<R, void>::FunctionPointerArg1(R (*)()) [with R = void]' is deprecated: FunctionPointer has been replaced by Callback<void()> [since mbed-os-5.1] [-Wdeprecated-declarations]
USBSerial(uint16_t vendor_id = 0x1f00, uint16_t product_id = 0x2012, uint16_t product_release = 0x0001, bool connect_blocking = true): USBCDC(vendor_id, product_id, product_release, connect_blocking){

Anyway, it compiles but there is for sure some kind of version mismatch. My pio versions are:

Platform Manager

Platform ST STM32

Updating ststm32 @ 4.4.0 [Up-to-date] Updating framework-mbed @ 5.50904.1 [Up-to-date] Updating toolchain-gccarmnoneeabi @ 1.70201.0 [Up-to-date]

martinjaeger commented 6 years ago

Yes, the USB library is somewhat old, but it is actually working (in contrast to the one from official repository, which doesn't even compile).

Will have to look into USB support again, but it's currently not my top priority. There is some rework going on in a dedicated mbed branch.

Decided for platformio library for ThingSet. Will push my changes in a minute.

hogthrob commented 6 years ago

Okay, we have to hope time is working for us. For now I would suggest to have USB disabled at least for the Travis Builds because it creates a lot of warnings in application level files. This makes it harder to identify new warnings in commits. One of our priorities should be to get rid of warnings so that by default the application files build without warnings. By following this principle it is easier to see when new issues (the issues which create warnings, of course most don't) are introduced. The software as such is not overly complex or has too many files but still following this principle is a valuable best practice.

martinjaeger commented 6 years ago

I made some updates in the battery user configuration I'd like to explain:

Requirements:

Main battery setup with just 3 parameters (battery cell type, number of cells and capacity) is done in config.h. This results in a typical, working and safe setup for this type of battery.

More detailed user-defined compile-time changes can be done in config.cpp, as suggested by @hogthrob. The user settings are now specified on battery level. Decided for battery level because all other charge controllers on the market typically set values on 12V battery level and this might be more intuitive for most users.

An empty function of battery_init_user is already defined as WEAK. So if the user doesn't want to do additional changes, he does not have to copy the config.cpp_template and the program still compiles.

User parameters are stored in the global variable bat_user (of type battery_user_settings_t). The data can also be accessed (i.e. changed and read) via ThingSet commands on the serial interface. After a change, a function applySettings has to be called (still to be implemented). In this function, all user settings are checked and applied to the actual battery configuration if valid.

The checks for both hard-coded changes and changes via serial interface are done in the function battery_user_settings.

atochukwu0 commented 5 years ago

Hello @martinjaeger , "bat->numbatteries" not used, what's the best way to use this mppt on 24v battery . bat->numcells =12 ; instead ?

martinjaeger commented 5 years ago

Yes, should work like this.

atochukwu0 commented 5 years ago

When will you implement auto battery detection feature .🤗 @martinjaeger . Am waiting for the update .

martinjaeger commented 5 years ago

Well, it's open source. You can do it yourself and afterwards send a pull-request :)

atochukwu0 commented 5 years ago

Ok, currently on going modifications to suite my hardware, will try and do that too , thanks .

atochukwu0 commented 5 years ago

We are having troubles soldiering the STM , @martinjaeger can the same bare metal timer configuration work for STM32F030K6T6 , I want to adopt to more spaced pin chip .

martinjaeger commented 5 years ago

Probably yes, but I can't promise. You have to read and compare the datasheet / reference manual carefully.

But the STM32F030K6T6 will definitely have too little flash memory. 128kB is already tight if you want to implement stuff like LoRa communication and display control.

atochukwu0 commented 5 years ago

I only want display control, no Lora nor GSM . Just LCD and keypads with CAN .

atochukwu0 commented 5 years ago

The memory is way Small, I think it won't work .

martinjaeger commented 5 years ago

Anyway, you won't be able to flash the software at all with only 32 kB of Flash. You will have to completely rewrite it.

You can use soldering wick to remove solder bridges. It's definitely possible to hand-solder the STM. There should be lots of videos on youtube to explain how to hand-solder small pin-pitch SMD parts. But you need a good and clean soldering iron and thin solder (leaded solder is more easy to use).

atochukwu0 commented 5 years ago

Alright, thanks , after first successful test , my plans is PCBa in Chinese Fab.

martinjaeger commented 5 years ago

Which device are you building up?

atochukwu0 commented 5 years ago

32f072 version.

atochukwu0 commented 5 years ago

But 20a is small for me, so I redesigned the whole circuit to be 45a capable, but using isolation grounding method to limit Ground noise from STM .

martinjaeger commented 5 years ago

Very interesting. Can you upload it to github?

atochukwu0 commented 5 years ago

Yes, as soon as am done with the developments .. I shall do that .

martinjaeger commented 5 years ago

You can already do during development, maybe others find it interesting and support you.

atochukwu0 commented 5 years ago

Sure ! .. but am using Proteus for PCB, not kicad as you do .

atochukwu0 commented 5 years ago

If you will support other LCD modules too, that will be fine , cos adafriut LCDs are hard to find in my country .. thanks ..

martinjaeger commented 5 years ago

I'm not planning to support any other LCD modules right now. But it's open source, you can implement it yourself :) Happy to receive your pull request to include the feature afterwards.

atochukwu0 commented 5 years ago

Ok

atochukwu0 commented 5 years ago

Will first implement the auto work

frankrichter commented 5 years ago

Cheap Chinese OLED displays with SSD1306 controller are easy available.

atochukwu0 notifications@github.com schrieb am Mo., 18. März 2019, 10:54:

If you will support other LCD modules too, that will be fine , cos adafriut LCDs are hard to find in my country .. thanks ..

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/LibreSolar/ChargeController_Software/issues/13#issuecomment-473841904, or mute the thread https://github.com/notifications/unsubscribe-auth/AMnX-FfClCKMJ30hNnIi45UXAGssGxcmks5vX2JIgaJpZM4XUoli .

atochukwu0 commented 5 years ago

Recommend any above 47*23mm below $3

frankrichter commented 5 years ago

Did you use flux? With enough flux it's pretty easy to solder once the package is placed correctly.

atochukwu0 notifications@github.com schrieb am Mo., 18. März 2019, 10:30:

We are having troubles soldiering the STM , @martinjaeger https://github.com/martinjaeger can the same bare metal timer configuration work for STM32F030K6T6 , I want to adopt to more spaced pin chip .

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/LibreSolar/ChargeController_Software/issues/13#issuecomment-473833791, or mute the thread https://github.com/notifications/unsubscribe-auth/AMnX-FMg01j2YMp_QFzMTJZwvEeBW_h2ks5vX1y8gaJpZM4XUoli .

atochukwu0 commented 5 years ago

Yes, but I will try further.

atochukwu0 commented 5 years ago

To auto detect battery num cells, I need to init adc first before init battery, will that cause an issue if I init adc before anything in setup() ? @martinjaeger .

martinjaeger commented 5 years ago

Battery configuration works fine via ThingSet serial interface.