Closed hogthrob closed 5 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.
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
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.
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.
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.
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:
pio upgrade; pio update
https://travis-ci.com/LibreSolar/MPPT-Charger_Software seems to build.
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:
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]
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.
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.
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.
Hello @martinjaeger , "bat->numbatteries" not used, what's the best way to use this mppt on 24v battery . bat->numcells =12 ; instead ?
Yes, should work like this.
When will you implement auto battery detection feature .🤗 @martinjaeger . Am waiting for the update .
Well, it's open source. You can do it yourself and afterwards send a pull-request :)
Ok, currently on going modifications to suite my hardware, will try and do that too , thanks .
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 .
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.
I only want display control, no Lora nor GSM . Just LCD and keypads with CAN .
The memory is way Small, I think it won't work .
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).
Alright, thanks , after first successful test , my plans is PCBa in Chinese Fab.
Which device are you building up?
32f072 version.
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 .
Very interesting. Can you upload it to github?
Yes, as soon as am done with the developments .. I shall do that .
You can already do during development, maybe others find it interesting and support you.
Sure ! .. but am using Proteus for PCB, not kicad as you do .
If you will support other LCD modules too, that will be fine , cos adafriut LCDs are hard to find in my country .. thanks ..
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.
Ok
Will first implement the auto work
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 .
Recommend any above 47*23mm below $3
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 .
Yes, but I will try further.
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 .
Battery configuration works fine via ThingSet serial interface.
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
PCB configuration: These define maximum operational limits, and are considered to be constant for a given hardware. These limits must be obeyed no matter what the battery pack, solar panel or load wants us to do. Can be derived from the hardware selection during compile time (PCB).
Cell configuration: these are fixed for a battery pack consisting of cells of a given type, but each cell type has different values, each system may use different cell types, and configuration may change over time (reconfig). A chemistry typically has fixed values for voltages, but currents and capacity is varying for each cell
General chemistry: Lead-Acid, LiIo, LiFePO4 ...
max voltage
min voltage
max charge current
max discharge current
Optionally (not required for safe operation): capacity indication
Battery pack configuration: these are fixed for a battery pack consisting of cells, each system may use different configurations, and configuration may change over time (reconfig).
Charge strategy information: CCCV/Trickle/Equalization { various voltages and times; strategy for charge end detection and start detection }
and we have operational (dynamic) data describing the state of things
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).