Webbsidan är senast uppdaterad:
Batterimonitor
NordicOffGrid Ultra-precise Battery System Monitor
Batterimonitor för driftsövervakning av off-grid solcellssystem

Batterimonitor typ "tankmätare" för batterier där man summerar ström / effekt till batteribanken över tid till Ah/Wh urladdad status från 100% SOC fulladdat. Utifrån känd C20-batterikapacitet kan man då även försöka ange en relevant SOC-status för laddnivån som 0-100% SOC.
Är en väldigt viktig grundläggande funktion i ett off-grid solcellssystem för batteridriften!
NordicOffGrid Batterimonitor övervakar många fler parameterar för driften än Ah/Wh så utgör en driftsövervakning av off-grid solcellssystemet, med även historisk data och statistik!
Gör även om rå mätdata till information, s.k. aggregerad data, med mer info över driften.
Det jag gör här blir mer som en "Battery System Monitor" (BSM) än en ren batterimonitor, med autonom proaktiv förbrukarstyrning för skonsam hantering av batteridriften!
Batterimonitorn används i projektet: PWM-solladdregulator
Kommer uppdatera här efterhand som jag utvecklar Batterimonitorn.
Beskrivning av grundfunktion:
Genom att mäta den ström / effekt som laddas ur/i batterierna över tiden fås den strömmängd som påverkar hur mycket av batterikapaciteten som för tillfället lånats ur batterierna. Med 1A ström urladdning under 1h har 1Ah laddats ur batterierna, och motsvarande med 12W effekt urladdning under 1h har 12Wh laddats ur. Men då strömmen normalt varierar mycket över tid måste den mätas väldigt ofta och för varje sådant kort tidsintervall summeras ihop till den totala strömmängden.
För att få en bra noggrannhet över lite längre tid så måste både ström / effekt mätas väldigt noga och med stort dynamiskt omfång samt de korta tidsintervallen måste också kunna mätas med hög precision. Stort dynamiskt omfång betyder att man måste både kunna mäta väldigt små strömmar och de stora som systemet är max dimensionerat för, då även väldigt små strömmar blir en signifikant strömmängd över en längre tid.
En ström på bara 10mA (0,010A) blir på en vecka till 1,7Ah.
Sedan tillkommer problem med att batteriverkningsgraden är lägre än 100%, att den varierar med hur fulladdade batterierna är samt med om driften hela tiden växlar mellan kortare ur/i-laddningar eller längre kontinuerliga ur/i-laddningar. Samt verkningsgraden påverkas även av hur hög ström ur/i-laddningen sker med, det som kallas för Peukert´s law, och batterier har en viss självurladdning också. Detta är även olika för olika batterityper, där vanliga blybatterier har rätt stor inverkan av detta, blykol-batterier betydligt mindre och LiFePO4 ännu mindre.
Så för en bra batterimonitor-funktion bör det tas hänsyn till dessa förluster samt man måste även ha en väldigt stabil bra synkronisering mot 100% SOC fulladdad batteribank för att mot fulladdad batteribank kalibrera bort den drift / onoggranhet som ofrånkomligen summeras över tid.
Det enda säkra tillståndet att nollställa / kalibera batterimonitorn mot är 100% SOC fulladdade batterier! Så är en oerhört viktig funktion att få stabil med hög noggrannhet, som även sköter sig helautomatiskt själv utan inställningar av användaren.
Idealet för en batterimonitor är att den själv kan utvärdera dessa olika parametrar dynamiskt under drift, då de varier över dels tid, dels med temperatur samt dels med hur driften är. Så för bra noggrann långtidsstabil drift kan man inte ha fasta inställningsvärden för dessa, värden som dessutom är svåra för användaren att avgöra!
Så min ambition är att försöka utveckla en batterimonitor som hanterar detta själv, sedan får vi se hur långt jag lyckas nå med det. Är svårt så hela vägen når jag nog inte!
Mina analyser visar att batterimonitorn då måste ha tillgång till information om hur solladdregulatorn arbetar för stunden med batteriladdningen, direkt från regulatorn. Är inget som den själv kan utvärdera tillräckligt bra via sina egna mätvärden. Så jag tänker bygga en hybrid PWM-solladdregulator med integrerad batterimonitor. (Och solladdregulatorn i sin tur behöver veta strömmen in-/ut-ur batteribanken för bäst laddstyrning, så en hybrid är välmotiverat.)
2022-10-26
En frågeställning är dock hur får man till allt helt rätt när man har både sol och andra laddare samtidigt?
Peukert´s Law: 2022-10-14
I denna batterimonitor kommer jag inte alls ha med Peukert´s law för Ah- och SOC-beräkningar, samt kommer som första början räkna mot blybatteriernas nominella C20-kapacitet så får resten bara bli en extra marginal för åldrande vid moderata strömuttag.
Jag och en del andra som tittat rätt mycket på detta med batterimonitor är inne på att för batterimonitor i ett off-grid solcellssystem bör man inte alls ta med Peukert´s law så för SOC-beräkningarna, då det blir ett missbruk av den och Peukert´s law inte alls beskriver det driftsfallet eller en verklig förlust av batterikapacitet vid sådan växlande battericykling!

Peukert´s law gäller bara för en urladdning med konstant ström i ett svep från 100% SOC till "0% SOC" som bestäms av att urladdningen avbryts vid 10,5V batterispänning för 12V blybatteri. Så Peukert´s law gäller inte alls när man som i ett off-grid solcellssystem har ständigt växlande laddning / urladdning som det blir där!
Därmed är det väldigt osäkert vad den bidrar till i en batterimonitor? Bör ge helt fel resultat!
Är väldigt svårt att hitta kunskap kring hur blybatterier beter sig ur Peukert´s law synvinkel med en växlande daglig laddning från solceller och urladdning där emellan.
Peukert´s relation describes how the capacity is related to the total time to discharge the battery to 10.5 volts. Simply put, the reason you get less amp hours out when the amps are higher is that the higher amps drag down the volts more than a lower amp load, so the 10.5 volts endpoint is reached sooner. It is not because some of the electrons [capacity] in the battery get lost or wasted when you draw current out faster. [källa]
Så Peukert´s Law beskriver inte en förlust i batterikapacitet, utan bara hur mycket av kapaciteten som kan urladdas i ett svep för olika strömmar innan man når 10,5V batterispänning!
Vilket då är helt ointressant för en batterimonitor, inte minst i ett off-grid solcellssystem!
Handlar om tillfälliga polarisations-effekter som sänker batterispänningen under urladdning, mer vid högre ström, som återställs vid vila eller minskar signifikant vid låg ström, mer ju lägre!

Som exempel, låter man ett blybatteri som laddats ur till 0% SOC enligt Peukert´s law vila 24h så hämtar det sig och är inte längre urladdat till 0% SOC, utan en signifikant del av kapaciteten återkommer igen under vilan.
Och det är ju precis så driften sker i off-grid solcellssystem, där solcellsladdning i detta sammanhang kan ses som "supervila" för blybatterierna! Så vid ständig växlande laddning / urladdning får man inte alls de förluster i kapacitet som Peukert´s law beskriver när ett blybatteri laddas ur helt i ett svep!
It is a common misunderstanding that the energy not delivered by the battery due to Peukert´s law is "lost" (as heat for example). In fact, once the load is removed, the battery voltage will recover and more energy can again be drawn out of the battery. This is because the law applies specifically to batteries discharged at constant current down to the cutoff voltage. The battery will no longer be able to deliver that current without falling below the cutoff voltage, so it is considered discharged at that point, despite significant energy still remaining in the battery.
What happens is that the chemical process (diffusion) responsible for transporting active chemicals around the battery progresses at a finite rate, so draining the battery quickly causes the voltage to reach the cutoff level prematurely before all the active material in the battery is used up. Given time, the active material will diffuse through the cell (for example, sulfuric acid in a lead-acid battery will diffuse through the porous lead plates and separators) and be available for further reaction.
What Peukert really meant: When energy is drawn, battery voltage falls. As an example were a battery able to sustain 5 amps for 20 hours (before falling below 10.6 volts) it can be rated as being 100 amp hours.
When a heavier load (say 50 amps) is connected across that battery, its voltage falls more rapidly. After (say) 60 minutes, it is likely below 10.6 volts. The battery is consequently unable to sustain that discharge rate. But its energy has been depleted by 50 amp hours. No more – nor less.
A lead acid battery reacts very slowly. Once that 50 amp load is removed it slowly recovers. Off-load voltage will be 12.2-12.3 volts. It may still be able to supply 50 amps, but this time for only 30 minutes. Delivered available capacity is now 75%. The 25% remaining is still available, but now at five or so amps.
So, what Peukert really meant is that rate of discharge does not affect overall capacity. That which it affects is only its usable capacity when loaded above its rated current. In other words its rated capacity (energy) is still available, but only at its intended (rated) current. Some see that as "available capacity". [källa]

Ger medelurladdningsström 0,8A/100Ah.
Peukert´s k=1.25 är högt för AGM & BlyKol.
Men riktigt vad man får tillgång till för extra kapacitet vid moderata urladdningsströmmar vet jag inte, då jag hittat absolut noll kunskap kring det för denna växlande driften i ett off-grid solcellssystem. Så i ett senare skede ska jag troligen försöka utvärdera det ur blybatterispänningen vid lägre SOC när strömmen är som lägst nattetid utan solcellsladdning. Men då främst för åldrandet.
Jag har av samma anledning inte med Peukert´s law i min Kalkylator små Solelsystem II då jag under min drift sedan 2007 i mitt off-grid solcellssystem inte kunnat se någon inverkan av det som Peukert´s law beskriver!
Jag hade med den från början men har under åren verkligen letat väldigt noga efter inverkan av Peukert's law i min off-grid drift och inte kunnat hitta några spår av den.
Då har jag i och för sig rätt måttliga strömmar, men ska man klara 5dygns dåligt-väder-reserv kan höga urladdningsströmma bara förekomma väldigt korta tider av den totala driftstiden, så bör vara i stort samma för alla.
Precis under en kortvarig hög urladdningsström borde man kunna notera en effekt av Peukert´s law, men sedan hämtar sig blybatterierna från den (i stort helt vid driften i ett off-grid solcellssystem vad jag kunnat få fram).
Bogart Engineering med sin TriMetric batterimonitor beskriver tydligt varför de inte använder Peukert´s law i sin batterimonitor, och det utifrån över 25 års erfarenhet av att utveckla batterimonitorer.
När jag läser på Victrons webbsida om Peukert exponent för deras BMV 700-serie batterimonitorer får jag uppfattningen att Victron till stor del har missförstått vad Peukert´s Law står för och vad för effekt i blybatterier den beskriver då Victron bl.a. skriver "The capacity of a battery depends on the rate of discharge. The faster the rate of discharge, the less capacity will be available.", vilket känns lite märkligt ihop med batterimonitor i off-grid solcellssystem (även om Peukert´s Law missuppfattas rätt ofta, så förståeligt om även deras ingenjörer gjort så)!
Peukert´s exponent ökar även med blybatteriernas åldrande, så den kommer ju aldrig vara korrekt över tid, och som sagt beskriver inget fenomen användbart för en batterimonitor så som jag och en del andra uppfattat det. Samt den är många gånger svår att få tag på för sina blybatterier, men går att räkna fram om de har minst två kapaciteter angivna typ C5 / C10 / C20 / C100.
De delar av Peukerts effekt som eventuellt påverkar lite även vid cyklisk drift kommer då till stor del med som del av den utvärderade batteriverkningsgraden i batterimonitorn. Så med sådan funktion kan jag verkligen inte se något behov av Peukert´s exponent i batterimonitorn!
Utökad funktion: 2022-06-30 / 2023-04-18
För oss lite mer intresserade kunde det vara intressant med mer information än bara Ah och SOC från en batterimonitor, typ hur mycket ström som använts direkt från solcellerna och hur mycket som plockats ur batteribanken. Hur mycket av strömförbrukning som just nu kommer från solcellerna respektive batteribanken samt ström / effekt ut till utgående förbrukning.
Och vid off-grid för fritidsboende att man kunde nollställa och mäta för en boendeperiod där hur mycket av strömmen som solcellerna resp. batteribanken levererat samt systemet förbrukat, både för boendeperioden och senaste dygnet (24h). Ur det kunde systemet även mer smart beräkna hur länge till batteribankens dåligt-väder-reserv räcker utifrån senaste 24h drift.
Har man 5 dygns dåligt-väder-reserv i batteribanken och solcellerna levererar 75% av förbrukad ström i molnig väder så räcker den reserven då i 20 dygn som exempel.
Kanske även en prognos baserat på senaste timmens förbrukning, men baserat på momentan förbrukning som flera batterimonitorer idag gör känns rätt meningslöst.
Bra att få info om, men lite krävande att själv försöka uppskatta!
Även detta görs lättas genom en samverkan mellan solladdregulator och batterimonitor.
Jag tänker även försöka lagra data kortare tid lokalt i ESP32 (typ 24h till 7? dygn, samt viss nyckeldata kanske ett år och annan 30dygn) samt regelbundet koppla upp den mot egen webbplats inhyrd på webbhotell och lagra långtidsdata där. Så kan jag hålla koll på batteridriften även via Internet varifrån jag vill. Får se under utvecklingen hur mycket sparad data som verkar vettigt!
Sedan hade även någon form av "Battery state of health estimation (SOH)" varit bra, som även kunde larma om något batteri börjar bli dåligt, men får nog ses som överkurs.
Har dock lite funderingar på att övervaka float-ström när solladdregulatorn reglerar den, hålla koll på lägsta batterispänning nattetid samt kanske mäta batteribankens impedans när PWM-regulatorn strömpulsar fulladdad batteribank. Bör kunna ge viss insikt om batteribankens status om någon av de börjar avvika från de normalt uppmätta värdena över lite längre tid!
Även kanske jämföra olika tidsfiltrerade batteriverkningsgrads-mätningar, typ 1/1, 1/10, 1/100 & 1/1000 och se om det blir en tydlig plötslig förändring i batteriverkningsgrad över tid som då kan indikera utvecklingen av problem i blybatterierna! Borde kunna vara ett bra mått!
Hårdvara att bygga på:
Har nu detaljstuderat databladen för INA260 (datasheet) och INA226 (datasheet) och de har verkligen flera riktigt bra funktioner för att kunna bygga en batterimonitor med hög precision! Mer om INA260/INA226.
Dels kan man sätta ADC (Analogue to Digital Converter) conversion time till mellan 140µs och 8.244ms där längre tid ger en mer exakt avläsning, dels kan man låta dem beräkna medelvärdena för mellan 1 till 1024st mätningar, vilket också ger möjlighet till noggrannare mätning av ström och effekt. INA226 använder extern strömshunt med mätområdet ≤36V, ±81,9mV, 16-bit, som då ger möjlighet till externt RC-filter av signalen från strömshunten så ingen data missas mellan samplingarna typ kraftiga korta strömpulser. INA260 har intern 2mΩ strömshunt för ±15A och ≤36V 16-bit mätområde inom -40°C to +85°C. The device operates from a single 2.7V to 5.5V supply, drawing 310 µA (typical), så är strömsnåla också!
Innebär att med maxvärdena 8.244ms och 1024st mätningar fås nya exakta medelvärdesbildade aggregerade data 1ggr/8,64s och som snabbast ca 1ggr/140µs, som INA260/226 då arbetar självständigt med att samla in.
Kretsarna har även en signalutgång som indikerar exakt när nya aggregerade mätvärden är tillgängliga, så man kan synka av läsningen av ström/effekt från INA260/226 hos ESP32-mikro-processorkortet med den, vilket görs via s.k. interrupt.
Den utsignalen skulle under långvarig standby-drift även kunna användas till att väcka upp ESP32 mikroprocessorkortet (källa2) ifrån strömsnål light-sleep och läsa av strömförbrukningen med upp till 1ggr/8,64s intervall och vara i light-sleep däremellan, som strömsnål batterimonitor! Men 2x (U+I) 1.1ms conversion time och 1024 averages, 1ggr/2,25s, är nog vettigt så kan responstiden på knapptryckning under light-sleep bli max 2,25s. Då borde kanske ca 22ms RC-filter bli lagom? Typ 4,12kΩ * 4,7µF, R82 50V (RC=19ms), så bör INA226´s 830kΩ ingångsresistans inverka minimalt på mätresultaten.
2023-02-16
Är bara INA226 spänningsmätning VBUS som har 830kΩ ingångsresistans, strömmätningens ingångar IIN+/IIN- har en Input bias current på typ 10µA, men uppmätt ca 35µA i drift!
Så går inte att göra en RC-filtrering på samma lätta sätt där som för VBUS!
Med 4,7µF/4,2kΩ (20ms RC) fick jag 341mA mätt med 500mA genom strömshunten! Utan 4,2kΩ mättes 501,7mA genom 60A/60mV shunten (LSB=1,8mA).
Multiple INA226´s with INA226_WE library (limit: 4 INA226).
Kanske kan kombinera interrupt med ISR och light sleep wakeup på samma GPIO?
Låter möjligt: ESP32 using interrupt to momentarily wake from Light Sleep - bug?
Går att göra via ONLOW_WE / ONHIGH_WE attachInterrupt(pin, ISR, ONLOW_WE);
där WE=Wakeup Enabled, dvs Interrupt och Wakeup från sleep på samma digitala ingång.
Kan göras som deferred interrupt via Queue API med tidsstämpling på 1µs upplösning för effektiv interrupt-hantering och exakt Ah-/Wh-summering / integrering.
Och ESP32 i sin tur har en 64-bitars tidmätning som mäter tiden med 1µs upplösning (0,000001s) och som bara startar om (overflow) 1ggr/292år så man kan mäta tiden mellan ström- och effekt-mätningarna med riktigt hög precision, vilken används för att summera ihop ström (A) och effekt (W) till Ah och Wh för värdena i batterimonitorn.
Ihop med batterier som trivs/tål att float-laddas 100% SOC längre tid (typ blybatterier) kan jag då även göra så batterimonitorn regelbundet automatisk nollströmskalibrerar sig under drift, vilket också ökar långtidsstabiliteten och precisionen. Har jag inte sett någon batterimonitor nu på marknaden har (möjligen BALMAR SG200). Kanske nollströmskalibrera sig mot den ström som är självurladdningen, då det egentligen är en strömförbrukning som inte strömshunten kan registrera och inte bör komma med i ∑Ah / ∑Wh.
Ska bli spännande det här!
Mobil 4G Router Teltonika RUT241: 2022-07-30

Införskaffat den 4G-router jag ska använda för att överföra driftsdata från off-grid solcellssystemet till min webbplats server. Valet föll på en Teltonika RUT241 4G/LTE(Cat 4), 3G, 2G industriell router med bra rykte om stabil tillförlitlig drift, med bra temperaturdriftsområde på -40°C - +75°C, driftsspänning 9VDC - 30VDC samt chassit är i aluminium för bästa värmeöverföring och kylning. Drar uppkopplad mot 4G utan datatrafik 1,2W matad från 12V enligt wiki, <2,5Ah/dygn. Har rimligt pris för prestandan tycker jag!
"RUT241 is an excellent fit in various IoT and M2M solutions that require easy setup, reliable network, and remote accessibility.
Kommer använda extern rundstrålande puck-antenn placerad uppe i takluckan i husvagnen, då alla väggar av aluminiumplåt skärmar av rätt mycket där det är dålig mottagning.
RUT241 är en ny version av RUT240, beskriven som: "Teltonika RUT241 är en ny uppgraderad version av den klassiska industriella LTE-routern RUT240. De är nära identiska förutom styrkretsen som uppgraderats till Mediatek MT7628 som har väsentligt bättre tillgänglighet och något snabbare prestanda [580MHz vs 400MHz]." Samt dubbelt så mycket RAM-minne som RUT240, så plats för uppgradering till mer krävande OS i framtiden.

- Teltonika RUT241 4G/LTE(Cat 4, ≤150Mbps), 3G, 2G
- Teltonika RUT241 Flyer
- Teltonika RUT241 Datasheet
- Teltonika RUT241 Quick start guide
- Teltonika RUT241 Wiki
- Teltonika RUT241 Wiki Power Consumption
- Teltonika RUT241 Wiki Firewall
- Teltonika RUT241 Firmware Downloads
- COMBO MIMO Mobile ROOF SMA Antenna
- COMBO MIMO Mobile ROOF SMA Antenna, Datasheet
- Power cable with 4-way screw terminal
- Power cable with 4-way screw terminal, Datasheet
- Teltonika RUT240 Setup Wizard
- Teltonika: Mobile Signal Strength Recommendations
- RUT241 Remote Monitoring & Administration, JSON-RPC, Modbus TCP, MQTT, etc.
- Dustin: Teltonika RUT241
- Ställt in tidsserver se.pool.ntp.org & europe.pool.ntp.org hos RUT241: europe.pool.ntp.org Samt uppdaterat till senaste firmware.
ESP32 WIFI uppkopplad till RUT241: 2022-08-03
Har kopplat upp RUT241 här hemma nu och tycker WIFI känns helt OK! Har placerat RUT241 ute i köket med en armerad betongvägg i vägen in till vardagsrummet där jag sitter längst in nu. Får full signalstyrka på mobilen där ifrån RUT241 samt min ESP32 som är lite kinkig kopplade upp och synkade med tidsserver på Internet utan problem via RUT241 här längst in i vardagsrummet vid datorn.
ESP32 kopplar upp snabbare till RUT241 än till min bredbands-router som finns i hallen precis utanför dörröppningen in till vardagsrummet och således med bättre kontaktväg så utan armerad betongvägg i vägen. Och den är ändå bra.
I mobilen får inte min bredbands-router riktigt full signalstyrka hela tiden här inne i vardagsrummet, så RUT241 verkar ge något bättre WIFI.
Här är ändå 14st andra routrar från grannar som sänder ut WIFI jag ser i mobilen, så är väl ingen perfekt miljö här precis tänker jag.
Har låtit ESP32 koppla upp och synka mot tidsserver via RUT241 8-9ggr nu och fungerar bra hela tiden. 2022-12-16 Nu har min ESP32 bootat och hämtat tid från NTP-server >1000ggr!
Så känns riktigt lovande för husvagnen och mitt kommande PWM-regulator + batterimonitor ESP32 projekt.
Lär ju få tillgång till WIFI även utanför husvagnen, vilket blir som en extra bonus då jag är fullt nöjd med bra Internet inne i husvagnen.
Jag får nu WIFI-signalstyrka RSSI -59dBm i ESP32, vilken anses som:
-50 to -67dBm – At Good signal strength for Web browsing, voice/video calls.
Wireless dBm table
Teltonika RUT241 4G-router i glesbygd: 2022-08-28

Tog med Teltonika RUT241 till husvagnen för test av funktion där. Är en ofta svag långsam intermittent mobil-uppkoppling där via mobilen, så en bra referensplats för funktion i bergig skogig Östgötsk glesbygd. Testade även hur ESP32 kan koppla upp och synka sin RTC mot tidsserver på Internet via RUT241´s wifi, och det skedde fint stabilt samt snabbt!

Fick -81dB signalstyrka med puck-antenn på soffbordet där nära mobilen samt pendlade mellan 2-3 (5) streck på RUT241´s indikator. Uppe i taklucka låg den på 3 streck signalstyrka större delen av tiden. Samt fick ned 4-8Mbit/s och upp 0,5-2Mbit/s med snitt runt 6Mbit/s ned och 0,7Mbit/s upp, en 5-10ggr snabbare än med mobilen direkt mot 4G! Är ofta låg kapacitet så hos basstationer ute i glesbygd, som brukar vara rätt hårt belastade så här vid 17:30-tiden på dygnet. Men den mest avgörande skillnaden var att RUT241 behöll sin uppkoppling stabilt med 2-3 streck i signalstyrka, där mobilen tappar den av och till lite längre perioder.
Och wifi räckte bra långt utanför husvagnen med bra signalstyrka 8-10m bort, trots husvagnens utsida av Al-plåt. Så jag känner mig helt nöjd med funktionen, som känns bättre än en del framhållit på Internet för föregångaren RUT240!
Adafruit Proto-Screwshield Arduino R3: 2022-12-01

Lödde ihop ett Proto-Screwshield R3 för utvecklingsfasen när jag testar fram funktionen. Är smidigt och enkelt att arbeta med, att slippa löda in anslutningstrådar från givare, strömförsörjning, etc. till WeMOS ESP32 D1 R32 Uno.
"The next generation Proto-ScrewShield is a dual-purpose prototyping shield. Not only does it have a large 0.1" grid prototyping area but it also extends the Arduino pins to sturdy, secure, and dependable screw terminal blocks. You even get a few bonus terminals for extra GND and four ´free´ terminals for whatever connections you wish! New! As of June 23, 2014 we now have an R3 update to this design - we now have a stacking header for the ICSP 2x3 pins and breakout the SCL and SDA pins. It now works much better with R3 UNO´s, Mega, Leonardo, as well as stacking nicely with any shield.
The stack-able wing design allows you slip this under any shield and still get easy access to the "analog" & "digital" ports of the Arduino. The ScrewShield can be stacked above or below pretty much every other shield."
Solid-state relay AC/DC: 2022-12-04
För att styra strömmatningen till Teltonika RUT241 4G Router behöver jag solid-state-relay / load-switch / power-switch funktion som kan styra strömmen ON/OFF på high-side med 3.3V signal från ESP32. Hittade denna hos Electrokit, men finns nog billigare: LCA717 DIP-6 Solid-state relay AC/DC.
What is a Load Switch?
Load switches (TI)
Load switches Low quiescent current, 0-3A (TI)
Batteriverkningsgrad: 2022-12-11
Lite idéer / tankar dök upp kring hur den ska mätas / utvärderas... Kanske som funktion av hur djup en battericykling varit (max DOD) samt kanske hur lång tid den varat innan 100% SOC fulladdat igen? Kan den även vara beroende av batteritemperatur? Får mäta och se när jag har batterimonitorn i skarp drift med den första inledande funktionen för batteriverkningsgrad och coulombverkningsgrad.
Är nog en sådan funktion som kunde använda ML (machine learning) i framtiden?
ML | What is Machine Learning?, GeeksForGeeks
Se även TinyML ESP32 Arduino, TensorFlow.
Grundkoden med menyer & NTP tid klar: 2022-12-13
Blev idag klar med grundkoden för alla menyer, WiFi samt för synkning av RTC (Real Time Clock) med NTP tidsserver på Internet. Sparade en kopia av den som bas för framtida ESP32-projekt. Detta är en mycket stor del av den totala kodningen men bara så viktig med det smidiga användargränssnitt den ger via 16x2 LCD displayen. Samt välutvecklat i FreeRTOS så det med väldigt lite kodning lätt läggs till nya menyer, både som editerar dataparameterar samt som visar driftsdata eller Datum / Tid från RTC, etc.
Har även varit ett lärosteg för mig att börja använda FreeRTOS för effektiv realtidsfunktion! Så hela funktionen är uppbyggd kring ett antal FreeRTOS-tasks, och Arduino loop() raderad.
ID för varje ESP32, macAdress: 2022-12-14
När driftsdata ska skickas till en webbserver på Internet kan ESP32´s MAC-adress användas som ID för respektive ESP32, då det ska vara unikt för varje individ. Så kan data skickas från flera olika ESP32-batterimonitorer utan risk att blandas ihop!
ESP32 Async web server SSE: 2022-12-18

Flyttar senare Grafisk dashboard överst.
När all ESP32 funktion är på plats.
Nu kodat färdig för en Async Webbserver med webbsida i ESP32 som skickar datauppdateringar direkt till webbsidan via Server-Sent Events (SSE). SSE är effektivt, strömsnålt och elegant!
Har använt infon och en del kod från: ESP32 Web Server using Server-Sent Events.
Samt från ESP32 WiFiMulti: Connect to the Strongest Wi-Fi Network (from a list of networks)
Med biblioteket: ESPAsyncWebServer-esphome installerat inifrån PlatformIO, ett "Asynchronous HTTP and WebSocket Server Library for ESP8266 and ESP32".
ESPAsyncWebServer-esphome Readme user manual!!!
Var förvånadsvärt enkelt och smärtfritt samt gick mycket snabbare än jag hade förväntat mig! Fungerade direkt.
Är lite snabbt kodat så är inte slutligt utförande / design, samt skickar just nu bara fuskade slumtalsvärden för att se funktionen.
Fungerar jättebra mot wifi-routern här hemma samt mot Teltonika RUT241! ESP32 skickar webbsidan via wifi till routern som i sin tur skickar den vidare via sin wifi ut till mobil / dator.
Så på plats i ett off-grid boende / husvagn kan man kolla sin solcells-batteri driftsstatus inom hela området som routerns wifi når, vilket bör bli ett större områden än för en app via Bluetooth.
ESP32 skickar först hela webbsidan till webbläsaren och sedan bara den data som uppdateras där direkt till webbsidan via Server Sent Events (SSE), vilket är jätteeffektivt och strömsnålt även när flera olika enheter är uppkopplade mot webbsidan samtidigt.
Jag har valt att skicka nya data 1ggr/s så upplevs visningen stabil.
I mobilen kan man välja fullskärmsläge som då ser ut precis som en app, så blir lika snyggt med webbsidan på så sätt utan något beroende av någon extern tjänst eller kontakt med mobilnätet.
Jag väljer att använda en webbsida istället för app, dels för att jag redan har bra kunskap i att koda webbsidor, dels att driftsdatan då kan visas på en mängd olika enheter med webbläsare.
Så vill man ha en stor display kan man bara köpa en billig enkel surfplatta och montera hos sig, samt går ju även att visa på en smart-TV om man har en sådan.
Ska senare koda den som en progressive web app! (Web app manifests | Installing web apps)
Och smidigt att visa driftsdata så direkt från ESP32 mikrokontrollern!
Ska visas mer info där efterhand som projektet framskrider, som en dashboard.
Men nästa steg är att skriva koden för ström-energi-sensorn INA226 och koppla in den mot mitt lilla experimentella off-grid solcellssystem här hemma är tanken. Ska bli intressant!
ESP32 Useful WiFi Library Functions, Arduino
Espressif: ESP32 WiFi API Reference, Networking APIs
HTML vs Body: How to Set Width and Height for Full Page Size
HTML vs Body in CSS (2018)

Ska bli en till canvas grafisk dashboard.
När full funktion så flyttas de överst.
Ser liknande ut på liggande mobilskärm.
ESP32 Async web server kraschar: 2022-12-21
Har nu kört med ESP32 Async web server SSE några dagar och det visar sig att ESP32-koden kraschar oregelbundet rätt glest (typ 5-10min) när en eller flera webbläsare är uppkopplad aktivt mot ESP32-webbservern och får Server Side Events skickade till sig. Bara då!
ESP32 bootar då om i en oändlig loop utan att lyckas starta om, förutom typ efter 80st gånger som vid debug-utskriften nedan (ResetBootCountRTC in RTC memory: 80).
Trodde först de orsakades av lite svag strömmatning via USB då LCD-displayens LED-bakgrundsbelysning blinkar lite när WiFi kortvarigt drar lite högre ström.
Men dels får jag Reset reason: 4, ESP_RST_PANIC, vilket inte är orsakat av spänningsmatning, dels blev det ingen skillnad när jag monterade in en kondensator för stabilisering av 5V på ESP32!
Och sedan hittad jag hur det gick att få ut mer debug-info i serial-monitor.
Så får där nu följande när det händer:
-------
Reset reason: 4, ESP_RST_PANIC
ResetBootCountRTC in RTC memory: 80
Total booting / resets: 2855
assert failed: tcpip_api_call IDF/components/lwip/lwip/src/api/tcpip.c:497 (Invalid mbox)
(Ser ut som ett av Espressiv-IDF biblioteken är orsak - kan det då fixas med någon inställning för webbservern, eller annat kodmässigt?)
Backtrace:0x40083b71:0x3ffb4c700x4008dadd:0x3ffb4c90 0x40093119:0x3ffb4cb0 0x400fadf1:0x3ffb4de0 0x401493f1:0x3ffb4e10 0x40149c15:0x3ffb4e50 0x400e095e:0x3ffb4e90 0x400d476b:0x3ffb4eb0 0x400d4854:0x3ffb4f20
ELF file SHA256: 0000000000000000
Rebooting...
ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
-------
Så får dels läsa på mer i ESPAsyncWebServer-esphome Readme user manual, dels se om jag kan få felutskrift för heap corruption diagnostics, om det kan vara en orsak.
Espressif: Heap Memory Debugging
Samt i övrigt gå igenom min kod mer grundligt, ihop med att leta lite mer info på Internet.
Har sett indikation på lösning med att skicka SSE lite mer sällan än nuvarande 1ggr/s?
Vad jag förstått körs allt ESP32-internt kring WiFi / Bluetooth stöd i Core0, så att jag lagt mina funktioner för ESP32-webbserver också i Core0 kanske leder till någon krock av något slag, så får även testa att byta till Core1!
Efter att slagit på mer debug-info kom följande fram:
> assert [RX:' '] [RX:'failed: tcpip_api_call IDF/comp'] failed: tcpip_api_call IDF/comp [RX:'o'] o [RX:'nents/lwip/lwip/src/api/tcpip.c'] nents/lwip/lwip/src/api/tcpip.c [RX:':'] : [RX:'497 (Invalid mbox)\r\n
> \r\n
> \r\n
> Backtra'] 497 (Invalid mbox)
Så problemet ligger tydligen i tcpip...
Edit: Det mesta pekar på att det var ett spänningsfall av strömspik när SSE-data skickas via WiFi / Webbserver, då en 470µF kondensator kopplad till 3,3V på ESP32-kortet för att buffra för dessa fick kodkrasher med det felmeddelandet att försvinna!
Därmed är per se inte min kod det direkta problemet, men får testa ändå med att koda om lite för bättre mer renodlad kod samt lägga i Core1 och se om det kan påverka. Har ändrat så SSE bara exekveras 1ggr/3s (från 1ggr/s) och det verkar lite stabilare!
Samt även läsa på mer i ESPAsyncWebServer-esphome Readme user manual för att se om det är saker i min kod som kan förbättras för ESP32-webbservern. Kanske typ finns någon buffert man kan dimensionera upp?
2022-12-22
Testat en del olika samt läst på nu och blivit något klokare.
Provade att lägga in en vTaskDelay() på 2ms mellan varje av de 11st events.send(), men det gjorde ingen skillnad.
Provade att ändra frekvensen för SSE från 1ggr/s till 1ggr/3s och det blev märkbart stabilare men kraschade ändå någon gång per timme.
Provade att bara låta sända 4st events.send() data mot 11st hittills och då fick jag ingen krasch under flera timmar.
Provade då att öka till 6st events.send() data och då fick jag en krasch under drygt två timmar, när jag hade webbsidan aktiv i två olika webbläsare samtidigt som SSE-data skickades till.
Har något luddigt minnesfragment av att jag läst att vid behov av många datavärden bör man välja att skicka dessa i en JSON fil istället, så ska nog prova det som alternativ.
Även mätt tiden det tog att skicka de 11st events.send() data och blev 12-20ms, så tänkte att med id = millis() fanns risken att två kunde få samma id och det kanske krashade då. Så även provat med id=micros() för att utesluta det, men blev ingen skillnad.
Men jag kan med 6st events.send() data gå vidare nu och koda för energi/ström-sensorn INA226 och installera den mot blybatteriet för lite riktiga mätvärden. Är så nyfiken på att få den sensor i drift och känna pulsen på den!
Och därefter koda om för data via JSON-fil.
Funderar även på ESP32 Webbserver byggt på WebSocket för att kunna få en tvåvägskommunikation så jag kan justera inställningsvärden från webbsidan och aktivera funktioner i ESP32, via Remote Control.
2022-12-22
Kört i flera timmar med bara 6st events.send() data skickade samt ett webbläsarfönster anslutet till ESP32 utan någon krasch!
2022-12-23
Provade att flytta de 11st events.send() data från den Deferred-Interrupt-Task med höga FreeRTOS Priority=7 där jag lagt dem tillfälligt till en nykodad Task_WebServerESP32 med låga FreeRTOS Priority=2 i Core0 som tänkt, och då med den lägre prioriteten fungerade det mycket stabilare.
Så sannolikt krockar en så hög FreeRTOS prioritet för webb-/WiFi-kommunikation med Espressif-IDF bibliotekskods prioritet i core0! Men måste ändå vara en bug/svaghet där, då den kraschar så hårt att ESP32 fastnar i en ändlös reboot och kräver manuell fysisk reset.

Canvas dashboard sneak-peek
Kunde köra två webbläsarfönster anslutna till ESP32-webbservern som uppdaterades med 11st events.send() data under ett par timmar utan krasch. Och med två datorer + en mobil med total 4st webbläsarfönster mot ESP32-webbservern klarade den drygt 15min innan krasch, vilket inte gick alls tidigare. Syns även på RAM-minnes hanteringen som ser mer stabil ut nu!
Så är på rätt spår. Har även checkat att det inte är något minnesläckage!
Sedan flyttade jag allt eget med wifi / webbserver till core1 så blev det ytterligare stabilare samt några andra småmodifieringar.
Så tydligt krockade den hög task-prioriteten med de task Espressif lagt för wifi i core0 så webbservern blockerade det. Har även prova att lägga in en 100ms vTaskDelay() efter hälften av events.send() som delegerar processorkraften i FreeRTOS till andra uppgifter de 100ms.
Har även tittat över alla ESP32 FreeRTOS Task stack size för mina kodade Tasks och optimerat dem.
Nu även kopplat den SSE-skickade datan till den canvas-grafik dashboard jag har på ESP32-webbsidan så mätvärden och mätare uppdateras där, vilket känns riktigt häftigt och coolt! Visar en sneak-peek av dashboard-grafiken och kommer visa hela när jag har den i full drift.
De två olika felmeddelande jag får vid krasch nu är:
assert failed: tcpip_api_call IDF/components/lwip/lwip/src/api/tcpip.c:497 (Invalid mbox)
Guru Meditation Error: Core 0 panic´ed (LoadProhibited). Exception was unhandled.
Där "LoadProhibited" = The error LoadProhibited means that the CPU tried to load a variable form an illegal address.
2022-12-28
Ändrade alla globala variabler till static typedef så de bara blir globala inom min fil, vilket är det normala inom C/C++ för att slippa namnkrock med variabler i inlänkade bibliotek. Verkar som det löste mina misstankar om en klassisk C/C++ bug typ pekarefel eller dylikt som jag hade isolerat till att finnas i en av mina Task. Har i vart fall inte fått något mer sådant felmeddelande.
Men får ändå enstaka glesa kraschar så inte helt stabilt ännu, även om jag oftast kan exekvera fler timmar i sträck.
Ska kolla upp att jag verkligen använder Mutex för exklusiv åtkomst till data / resurser på alla ställen i koden det behövs för att undvika krockar mellan min olika asynkront exekverande FreeRTOS-Tasks! Och om jag inte hittar något där så ta bort alla String-class variabler jag använt (Php-kodvana) och ersätta med klassisk C/C++ char[]-array istället, vilket är mycket effektivare samt antytts någon stans att String kan vålla dessa krascher ihop med webbserver-biblioteket ESPAsyncWebServer-esphome jag använder. Så hoppas få det helt stabilt så!
Lite intressant läsning kring C++ kodning:
Static local variables, Learn C++
Sharing global constants across multiple files (using inline variables)
Why (non-const) global variables are evil
2022-12-29
Fick "Guru Meditation Error: Core 1 panic´ed (LoadProhibited). Exception was unhandled." igen när jag aktiverade en av tryckknapparna, och misstänker det har något att göra med missad Mutex kring min DisplayHandler(), Task_DisplayViewHandler() samt Task_LCDButtonsHandler(), eller Mutex kring Serial.print() då det händer när jag aktiverar menyn för att Serial.printa info om FreeRTOS Task stack size!
Nya versioner av espressif/arduino-esp32 (ESP32 Arduino 2.0.6 based on ESP-IDF 4.4.3) och av platformio/platform-espressif32, 5.3.0 med bl.a. "Fixed issue where esp32 won´t reconnect to WiFi AP if the AP was restarted." som jag tackar för just nu när jag håller på med WiFi och async webbserver!
Har även upptäckt att med PlatformIO längre tid passiv i bakgrunden med öppen Serie-Monitor ansluten till ESP32 så kraschar ESP32-webbservern ibland, men stänger jag Serie-Monitor så undviks det! Verkar som Serie-Monitor blir inaktiv då.

Fullskärmsläge på mobilen liknar en App.
LCD-display på ESP32 med driftsdata.
2022-12-31
Har nu fin långtidsstabilitet med ESP32-webbservern med en uppkopplad webbläsare / webbsida samt med att jag sänkt uppdateringsfrekvensen till 1ggr/2s. Den sänkta uppdateringsfrekvensen beror troligen på att mitt Olimex LCD-shield arbetar så enormt långsamt då det saknar en buffert för inkommande texter så min kod får vänta på den riktigt långsamma skrivning av varje tecken till själva displayen med drygt 640ms för att skriva alla de 2x16 tecknen (20ms/tecken) vid I2C busshastighet 80kHz som är max den klarar.
Vid data till flera webbläsarfönster får jag fortfarande krascher med felmeddelandet: "assert failed: tcpip_api_call IDF/components/lwip/lwip/src/api/tcpip.c:497 (Invalid mbox)". Nämns dock något om ESP32 reset WiFi stack samt How can I increase wifi task stack size?, ESP32: Increase wifi task stack size to support advanced logging, 4WAY_HANDSHAKE_TIMEOUT.
Espressif: Optimization of Internal RAM, Fatal Errors, Guru Meditation Errors
Verkar vara någon buffert / stack size som inte räcker till, men inte lyckats hitta någon bra info om det trots mycket sökande på Internet!
2023-01-18
Har nu hittat både CONFIG_ASYNC_TCP_STACK stack-size och CONFIG_ASYNC_TCP_QUEUE_SIZE event-queue-size för AsyncTCP.cpp i AsyncTCP-esphome-biblioteket:
me-no-dev / AsyncTCP
Sending big blocks of data triggers async_tcp task watchdog, i AsyncTCP.cpp:
event-queue-size:
static inline bool _init_async_event_queue(){
if(!_async_queue){
_async_queue = xQueueCreate(512, sizeof(lwip_event_packet_t *)); // 32 default
if(!_async_queue){
return false;
}
}
return true;
}
Att öka event-queue-size från default 32 till 512 gjorde att jag kunde öka gränsen för antal events.avgPacketsWaiting() jag tillåter samt köra det helt stabilt även när jag hetsar med 5ggr snabbare sändningsfrekvens via SSE till webbsidorna, även när jag uppdaterar mot två samtidiga webbsidor! Kan med interrupt via tryckknapp uppdatera ca 5ggr/s och fungerar ändå stabil!Kanske inte skulle behöva kö-övervakningen alls nu, men när jag nu kodat den funktionen känns den bra att ha där. Nu med ökad gräns behöver den i stort aldrig ingripa.
Beskrivs även här: AsyncWebServer giving wdt reset.
Där tipsas även om EspExceptionDecoder för felsökning.
Är ju synd bara att de inte kodat en funktion i AsyncTCP.cpp så man kan justera både dess stack-size och event-queue-size inifrån sin egen kod!
Och i AsyncTCP.h
#define CONFIG_ASYNC_TCP_STACK_SIZE 8192 * 2
, som jag även ska prova att öka.Ökade till 16384 * 2 men det tar mycket RAM-minne, så går tillbaka igen till default. Märkte ingen skillnad vid en snabb test.
Lite mer att läsa:
Using server.serveStatic causes WDT crashes
ESPAsyncWebServer Fork
The combination I currently using Wenserver
Känns inuitivt som att det skulle fixa sig genom att gå över till WebSocket istället för nuvarande SSE med den datamängd jag skickar!
Eller annars använda antingen JSON-data eller Protocol Buffers (Protobuf) (is a free and open-source cross-platform data format used to serialize structured data) för datan.
Går vidare med att koda för och koppla in INA226 energi-/ström-sensorn nu, så får test med WebSocket komma senare. Blir en intressant start på nya året!
2023-01-01
Har haft problem med ESPAsyncWebServer template processing engine då den ersätter template-namn mellan två %-tecken, typ %VOLTAGE% med datan från en C/C++-variable i ESP32-koden. Blir problem dels när man använder % som längdmått i CCS typ width=100%;, samt dels även som enhet i sin html-text! Har ägnat flera dagar åt att hitta en möjlig fix till detta och löste det idag äntligen :-)
Provade att införa
#define TEMPLATE_PLACEHOLDER '$'
i min kod, men fungerade inte då det inte rår på ESPAsyncWebServer biblioteket.Hittade tips om att
build_flags = -TEMPLATE_PLACEHOLDER='$'
i platformio.ini filen skulle fixa det, men inte!Infogade
#define TEMPLATE_PLACEHOLDER '$'
i min kod så fick jag upp ett felmeddelande om att symbolen i WebResponseImpl.h var redefinierad och kunde då klicka upp den filen där den ursprungliga #define
fanns, så editerade jag den där till #define TEMPLATE_PLACEHOLDER '$'
! Och det fungerade!Där finns även
#define TEMPLATE_PARAM_NAME_LENGTH 32
, så default kan max 32 tecken användas.Och även där är en allvarlig bug i denna kodfunktionen, för den tar inledande %-tecken och de följande 32 tecknen och ersätter fast inte hittat avslutande %-tecken. Egentligen är det nog huvudproblemet, och ett grovt kodningsfel tycker jag!
Genom att behålla
#define TEMPLATE_PLACEHOLDER '$'
i min kod så kommer jag bli uppmärksam på ny uppdatering av ESPAsyncWebServer / WebResponseImpl.h vid kompilering och får då editera där igen. Men oförändrad blir det inga felmeddelande så.Känns rätt klantigt att använda "%"-tecken för denna funktion, liksom att inte infört ett lätt sätt att själv i sin kod kunna välja lämpligt tecken! Jag provad även att i den egna processor() funktion man gör för utbytet att returnera den var-String man får där ihop med %-tecken, så skulle ju det vid width=100%; ersättas med ursprunglig kod och ingen skada skedd, men då reprocessar den hela den koden från början för varje template-name-processing så hamnade då i en oändlig loop! Också rätt märklig kodfunktion som slösar processorkraft! Borde ju fungerat!
Han som kodat detta bad redan 2018 om ursäkt för den funktionen, men ändå är det nu drygt 4 år senare inte åtgärdat! Ger ett lite dåligt intryck av biblioteket som trots det är det mest använda och mest aktuellt uppdaterade Async Web Server SSE bibliotekt vad jag ser.
Ska senare kolla in WebSockets och då även kanske testa PlatformIO biblioteket WebSocket Server and Client for Arduino ESP32.
- WebResponseImpl.h -
#define TEMPLATE_PLACEHOLDER '%'
- PlatformIO: Setting variables in code using build_flags
- Allow to override default template placeholder value with #define during compilation
- Template confused by data containing percent ('%')
- Send large webpage from PROGMEM containing templates with '%' sign in it (CSS part of page)
- Using template processor corrupts response HTML if it includes %
- CSS styles are removed when served by ESP8266 running an ESPAsyncWebServer
- DuckDuckGo: ESPAsyncWebServer "TEMPLATE_PLACEHOLDER"
- ESP32 Arduino HTTP server: Template processing
- ESP32 web server: template processing when serving HTML from file system
- ESPAsyncWebServer README.md
Har nu visat driftsdata (slumptals-fejkade än så länge) från min ESP32 batterimonitor (och blivande PWM-regulator) aktivt uppdaterat via WiFi mot mobilen två timmar i ett streck med stabil funktion från webbservern i ESP32 mikrokontrollern!
Så känns tillräckligt stabilt nu för att gå vidare med att koppla in energi-/ström-sensorn INA226 och fixa programkoden för den samt ansluta till min lilla experiments-solcellsanläggning här hemma.
Server Side Events (SSE) är en elegant smidig teknik, men med detta kodbiblioteket känns den inte riktigt stabil för en "större" datamängd som här, så ska senare testa med WebSockets istället. Men går nu först vidare med att koppla in INA226!
Är så jäkla nyfiken på att testa den smarta INA226: 36V, 16-bit, ultra-precise I2C output current / voltage / power monitor w/alert!

Fullskärmsläge på mobilen liknar en App.
LCD-display på ESP32 med driftsdata.
2023-01-05
Nu verkar jag fått min ESP32-webbserver att arbeta helt stabilt utan kodkrascher, både med 1ggr/s uppdateringfrekvens av SSE-data till webbsidan och av LCD-displayen, genom fem ytterligare åtgärder. Har även provat med 2st webbsidor på datorn och 1st i mobilen nu.
- Införde en Mutex för DisplayHandler-funktionen så bara en instans av den kan vara aktiv åt gången via anrop från olika FreeRTOS Tasks. Fast den i sig utnyttjar Mutex för I2C-seriebussen så belastar det RAM-minnet med flera aktiva instanser av DisplayHandler inlästa där helt i onödan, samt tar även processorkraft. Syntes tydligt på heap-minnet!
- Införde adaptiva funktioner i koden som minskar uppdateringsfrekvensen av SSE-skickade data till webbsidan samt av uppdateringen av LCD-displayen så fort det blir för mycket kö i de Queue-dataflödena. Gjorde stor märkbar skillnad, samt innebär att jag nu normalt kan uppdatera båda 1ggr/s, som väldigt glest tillfälligt görs långsammare individuellt för de olika enheterna. För SSE-skickade data var detta extra kritiskt när en nedstängd webbserver väcks upp igen!
- Ändrade WiFi.useStaticBuffers(true); till true (set the buffers memory allocation to dynamic = false), då dynamisk minnesbuffert verkade fragmentera heap-minnet och efter lång driftstid kraschade exekveringen med felmeddelande att heap-allocation inte gick.
- Bytte ut den 10µF kondensator jag kopplat till 3,3V på ESP32-kortet till en 470µF kondensator för att buffra för de korta lite högre strömspikar WiFi-kommunikationen drar, vilket gjorde stor skillnad. Nu försvann helt det väldigt glesa kodkrascherna när jag hade ett webbläsarfönster öppet mot ESP32-webbservern, och de mer frekventa krascherna vid 2-3 uppkopplad webbläsarfönster försvann också, så var helt klart spänningsdippar som störde mikroprocessorn! Det luriga är att jag fick inga Brownout-resets utan ESP_RST_PANIC (Panic Handler), så Brownout´s detekterar tydligen inte så korta spänningsdrop!
- I min Task där jag skickar alla SSE-data events.send() till webbsidan införde jag ckeck för events.avgPacketsWaiting() så inte de köar upp för mycket väntande Packets i webbservern utan väntar då med att skicka nya, vilket även skonade RAM/Heap-utnyttjandet signifikant. Med events.count() får man även antal webbsidor som servas för stunden!
Var ett litet dektivjobb att hitta, då det inte tas med i de enkla exemplen för webbserver-kod till ESP32 jag hittat på Internet!
Har testat vid svag WiFi-signal och arbetar helt stabilt nu även när det kan ta 10-15s mellan att SSE-data via events.send() når webbläsaren! Tidigare kraschade kod-exekveringen då!
Köandet ökar inte vid 3st anslutna webbläsarfönster mot 1st, så är inte skickad datamängd som ger kö utan tydligen antal anrop till events.send(). Har läst att vid större mängd data blir det bättre att packa in dem i en JSON-fil och skicka med ett anrop till events.send(), så ska prova det senare. Även sett info om att WebSockets skulle vara bättre / effektivare vid denna typ av dataskickande till webbsida, bl.a. för att den kan även skicka binär data (typ float/int tal) mot SSE som bara tar textsträngar, så även det ska jag prova senare.
Men då jag fått det stabilt nu installerar jag först effekt/ström-sensor INA226 så jag får igång riktig mätning mot batteriet i mitt lilla experiment off-grid solcellssystem här hemma!
Har lagt in en WiFi.onEvent() som aktiverar server.begin() så att webbservern helt säkert återstartas direkt när WiFi har återanslutit och fått IP efter varit nedkopplad. Tidigare kunde webbserverns återstartande vara lite segt, som ibland t.o.m. kraschade kodexekveringen.
Gör att även efter automatisk WiFi-Reconnect med WiFi.setAutoReconnect(true) så återstartas webbservern direkt!
WiFi.onEvent() är riktigt snabb så
WiFi.onEvent(ARDUINO_EVENT_WIFI_STA_GOT_IP);
aktiveras innan wifiMulti.run() exekverat färdigt med sin anslutning till WiFi! Märks även när jag nu testat med att min ESP32-kod fått stänga ned WiFi och sedan återstarta en mängd gånger, att webbservern återansluter väldigt snabbt och SSE-data kan uppdateras direkt i webbläsaren efter WiFi-Reconnect! Samt har varit 100% stabilt!Så ytterligare en pusselbit i att få en riktigt långtidsstabil ESP32 webbserver kod-funktion.
Info och kodtips från: Reconnect to Wi-Fi Network After Lost Connection (Wi-Fi Events)
ESP32 C/C++ kod:
WiFi.onEvent(WiFiGotIP, WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_GOT_IP);
void WiFiGotIP(WiFiEvent_t event, WiFiEventInfo_t info){
server.begin();
}
Funktionens parametrar: ESP32 Arduino: Getting WiFi Event information.
2023-01-11
Mätt upp via oscilloskop hur snabbt jag kan växla en GPIO-utgång 1-0-1 på mitt ESP32-kort. Är förberedelse inför att kunna utvärdera en Deferred interrupt processing jag snart ska implementera för INA226. Tog 100ns (10MHz), vilket jag är nöjd med!
Så kan göra sådana utvärderingar då med 100ns upplösning!
När jag sedan mäter med interrupt så måste jag göra det via oscilloskop såhär, då signalen kommer utifrån från INA226.
Gör detta med direkt portmanipulation:
GPIO.out_w1tc = ((uint32_t)1 << 18); // Set PIO 18 to 0
GPIO.out_w1ts = ((uint32_t)1 << 18); // Set PIO 18 to 1
GPIO.out_w1tc = ((uint32_t)1 << 18); // Set PIO 18 to 0
Mätte även upp hur exakt den FreeRTOS-Task jag exekverar 1ggr/1000ms blir i sin frekvens samt den tid själva Task-exekveringen tar varje gång. Styrs då av vTaskDelayUntil( &xLastWakeTime, 1000 / portTICK_PERIOD_MS ) samt exekveringen innefattar bl.a. 2st xQueueSend() som initierar exekvering av två andra Task.
Den önskade 1ggr/1000ms exekveringsfrekvensen mäts till 1ggr/1000,01ms stabilt med Std-Dev 4,78µs över 50 mätningar, så det är ju imponerande bra!
Oscilloskopet mäter upp en exekveringsfrekvens på 999,99mHz!
Samt själva exekveringen tar 0,6 - 0,7ms, så xQueueSend()-data till andra Task är också snabbt, då jag gör lite andra småsaker också under Task-exekveringen. Detta går ju att mäta inne i koden också med microsekund-upplösning. Men man ser tydligare hur tiden varierar på oscilloskopet.
Så en duty-cycle för exekveringen på 0,06% - 0,07% i denna Task!
Inte så hård belastning på processorn precis :-)
Gör detta för att få insikt i hur exekveringen och koden arbetar, för eventuellt senare optimering om det behövs! Ökar även min kunskap om hur det jag gör verkligen fungerar.



2023-01-16
Kodat Interrupt och WakeUp från light sleep på samma GPIO:
För INA226 effekt/ström-sensorn så dess Alert-interrupt signal både kan indikera nya mätvärden att läsa av samt samtidigt väcka upp ESP32 via GPIO från light sleep när i energisparläge. Görs med attachInterrupt(19, ISR, ONLOW_WE);
, där WE=WakeUp Enabled. Var svårt att hitta info om, men nu fungerar det emulerat via en tryckknapp på bread-board. Så nästa steg är att koppla ihop med INA226!
2023-01-18
Har nu hittat både CONFIG_ASYNC_TCP_STACK stack-size och CONFIG_ASYNC_TCP_QUEUE_SIZE event-queue-size för AsyncTCP.cpp i AsyncTCP-esphome-biblioteket:
me-no-dev / AsyncTCP
Sending big blocks of data triggers async_tcp task watchdog, i AsyncTCP.cpp:
event-queue-size:
static inline bool _init_async_event_queue(){
Att öka event-queue-size från default 32 till 512 gjorde att jag kunde öka gränsen för antal events.avgPacketsWaiting() jag tillåter samt köra det helt stabilt även när jag hetsar med 5ggr snabbare sändningsfrekvens via SSE till webbsidorna, även när jag uppdaterar mot två samtidiga webbsidor! Kan med interrupt via tryckknapp uppdatera ca 5ggr/s och fungerar ändå stabil!
if(!_async_queue){
_async_queue = xQueueCreate(512, sizeof(lwip_event_packet_t *)); // 32 default
if(!_async_queue){
return false;
}
}
return true;
}
Kanske inte skulle behöva kö-övervakningen alls nu, men när jag nu kodat den funktionen känns den bra att ha där. Nu med ökad gräns behöver den i stort aldrig ingripa.
Beskrivs även här: AsyncWebServer giving wdt reset.
Där tipsas även om EspExceptionDecoder för felsökning.
Är ju synd bara att de inte kodat en funktion i AsyncTCP.cpp så man kan justera både dess stack-size och event-queue-size inifrån sin egen kod!
Och i AsyncTCP.h #define CONFIG_ASYNC_TCP_STACK_SIZE 8192 * 2
, som jag även ska prova att öka.
Ökade till 16384 * 2 men det tar mycket RAM-minne, så går tillbaka igen till default. Märkte ingen skillnad vid en snabb test.
Lite mer att läsa:
Using server.serveStatic causes WDT crashes
ESPAsyncWebServer Fork
The combination I currently using Wenserver
2023-01-20

Har nu kodat ett menysystem färdigt till 5st webbsidor i ESP32, så nu är där en hel webbplats. Huvudwebbsidan är nu 41,23 kB i överförd storlek som tar ca 150-300ms att ladda ned för webbläsaren. Jag tycker det är imponerande hanterat av ESP32 prestandamässigt!
Är gjort som en modern s.k. "responsive hamburger menu" med en inline <svg></svg> hamburger-icon kod från CSS-Tricks.
Har delat upp webbkoden i separata CSS, JavaScript & Html char-variabler kodblock som är gemensamma för alla webbsidorna, som kopieras in via processor-funktionen i ESPAsyncWebServer-esphome. Sparar på så sätt flash-minne samt slipper redundant kod så blir enklare att uppdatera koden för webbsidorna.
Är fortfarande gott om plats i ESP32 där kompilatorn rapporterar:
RAM: [= ] 14.4% (used 47196 bytes from 327680 bytes)
Flash: [=== ] 28.9% (used 908177 bytes from 3145728 bytes)
Samt i aktiv drift mäter jag i ESP32:
FreeSketchSpace(%): 75
FreeHeap(%): 57 (52% när SSE skickas till webbsida)
SdkVersion: v4.4.3
ChipModel: ESP32-D0WDQ6
ChipRevision: 1
Har även lagt in <svg></svg> för en icon för aktivering av full-screen mode uppe till höger.
Koden hämtad från Arrows fullscreen Icon Svg Code. Finns även Arrows Maximize Icon SVG.
Här är alla FontAwesomeIcons SVG Icons | SVG Code Generator.
Har även lagt till en SVG-FavIcon: Use inline SVG as favicon där <svg></svg>-koden URL-encodes via URL-encoder for SVG.
Nu som första start använder jag Speedometer2 SVG Icon Code men tänker senare skapa en egen SVG-FavIcon.
Html-kodas såhär i <head>-sektionen:
<link rel="icon" href="data:image/svg+xml,[YOUR URL-ENCODED SVG HERE]" type="image/svg+xml" />

2023-01-21
Har kopplat in INA226 till ESP32 med INA226_WE biblioteket och dess Conversion-Ready-Alarm Interrupt signal triggar min ISR och dess deferred interrupt processing Task med en väldigt hög repetitiv precision på 1129695±2µs! Mätt via 64-bit esp_timer_get_time()!
En otrolig tidsnoggrannhet upplever jag, men kommer ändå summera Ah med den mätta tiden!
Har då satt INA226 till 1.1ms conversion time och 512 samples för medelvärdesbildning och det är spänning + ström som läses av så 1,1ms * 512 * 2 = 1126ms mellan att INA226 ska ha färdiga nya mätvärden att läsa av, plus ca 4ms overhead på det tydligen.
INA226 mäter därmed ström och spänning 512ggr/1,129695s dvs 453ggr/s, 1ggr/2,2ms!
Ihop med 19ms RC-filter fångas även de allra snabbaste och korta pulser upp i mätningarna!
Så INA226 styr på så sätt nu "pulsen" för min kods exekvering.
Har ingen ström ansluten till INA226 ännu så den mäter nu 3,286V, 0,000A & 0,000W, då spänningsmätningen är kopplad till 3,3V matningsspänningen. Mätdatan 3,286V ligger exakt stabilt på den spänningen och strömmen är 0,000A hela tiden, riktigt imponerande!
Mätt med min digitala multimeter får jag 3,285V.
Ser ut att bli riktigt bra förutsättningar för en hög noggrannhet i batterimonitorn med detta!
Så stämmer med hur jag noga valt komponenter.
Att medelvärdesbilda så här över 1,1s ger väldigt stabila värden att visa och att reglera på!
Blir spännande att se hur stabila mätvärden jag får inkopplat mot blybatteriet senare.
Är möjligt sedan när jag ska reglera laddningen att jag behöver läsa av strömmen lite oftare, men får prova då. Med 588µs conversion time och 256 samples får jag 0,588ms * 256 * 2 = 301ms intervall, som nog kan vara bra att sikta mot om jag behöver snabbare respons för strömmen.
Men samtidigt är den medelvärdesbildade strömmätningen så extremt stabil brusfri att man kan göra en snabbare och mer exakt reglering på den, så tror ändå det räcker med 1ggr/1,1s avläsning. Vid en linjärt förändrad ström över tid så skulle man kunna ta 2ggr förändringen sedan senaste medelvärdesbildade mätvärde, då det skulle motsvara nuvarande momentant värde, så kan experimentera med att ta 1,5-2ggr strömförändringen så i PWM-regleringen. Sedan är en ren PWM-reglering smidig då en ändring i duty-cycle / pulskvot direkt motsvarar en strömändring, så går att matematiskt räkna fram väldigt nog hur mycket pulskvoten behöver ändras för att justera en viss avvikelse i strömregleringen! Och strömreglering i sig mot blybatterier har mycket snabbare respons än spänningsreglering, så det blir en bra bas för regleringen.
Kan se att min nuvarande rent spänningsreglerande PWM-regulator agerar rätt långsamt pga det för stabil reglering mot blybatterierna, då de är rätt spänningströga!
Ska även ha en ström+ reglering för extra snabb noggrann laddreglering, min specialare.
Fri SRAM ligger fortfarande kvar på 52% under aktiv exekvering med SSE-data till webbsida, så en försumbar inverkan på ESP32 prestandan liksom en minimal försumbar tid att hämta mätvärden över I2C. Totala aktiva exekveringstiden för mina FreeRTOS Task´s är kvar på ca 1%.
Och jag lyckas få ihop detta med använt I2C Olimex Shield-LCD 16x2 som har svårt att samsas med annan enhet på samma I2C. Har gjort lite smart kodande där som adaptivt håller koll på detta och skyddar och optimerar Olimex Shield-LCD´s I2C-kommunikation.
Och det går inte ut över INA226´s I2C-kommunikation, så känner mig väldigt nöjd så!
2023-01-22
Testad att sätta ESP32 i light-sleep strömsparläge mellan varje INA226-avläsning, som väcks upp av interrupt från INA226 för ny avläsning av mätdata och sedan light-sleep igen. Nu med 1,1s cykeltid får jag då 10% aktiv drift (för uppdatering av LCD med nya datan) och 90% light-sleep energisparläge. I light-sleep drar ESP32 ca 15mA från 5V USB, samt ca 52mA i aktiv drift utan WiFi och med WiFi i snitt runt 75mA grovt. Fungerade jättebra!
I sådan drift blir strömförbrukning ca 19mA i snitt, vilket känns rätt OK. Vid drift från 12V via DC-DC-konverter bör det bli lägre, beroende på effektiviteten hos DC-DC-konvertern.
2023-01-23
Gjort nu att i strömsparläge med light-sleep så väntar koden adaptivt in en uppdatering av LCD, vilket då tar 2-5% av cykeltiden. Så medelströmförbrukningen då blir vid 5% 0,05x52mA + 0,95x15mA = 17mA från 5V USB. Samt lagt in att när någon av de fyra tryckknapparna är nedtryckt går den ur strömsparläge. Fungerar bra.
It is common to use the idle hook function to place the microcontroller CPU into a power saving mode. The Idle Task Hook - får titta in på detta för light-sleep strömsparfunktion!
INA226 breakout-boardet har en 100mOhm strömshunt, så ställt in INA226 för 100mOhm och 1A mätområde nu under inledande testande. Då mäter den med 0,00125V / 0,00003A upplösning (1 LSB step size). Med ström via 1k+3,3V matningsspänning mäter den då stabilt 3,28625V, 0,00366A samt 0,012W, utan att siffrorna ändras sig alls, dvs utan något som helst brus! Någon gång glest ibland växlar den till 3,28750V dvs 1 LSB upp. Mätvärdena är då medelvärdena av 512st avläsningar av strömshunten, spänningen samt effekten under 1,1s. Medelvärdesbildningen i INA226 så ger väldigt stabila mätvärden samtidigt som avläsning 512ggr/1,1s internt i INA226 fångar upp snabba förändringar i batteribankens ström / spänning för noggrann Ah/Wh-mätning!
Håller jag med två fuktiga fingrar över 1k-motståndet ökar strömvärdet till 0,00369A med just +0,03mA minsta mätsteget (1 LSB step size).
Så med 100A 0,5mOhm strömshunt blir mätupplösningen 3mA i mitt off-grid solcellssystem!
Senare ska jag ta bort strömshunten på INA226 breakout-boardet och koppla mot extern strömshunt 60A / 60mV som jag har i mitt lilla experiment off-grid solcellssystem här hemma.
Mätt med digitalt minnes-oscilloskop på Interrupt → ISR → ISR Deferred Handling

With: I2C Wire.setClock(80000); (Hz)
The I2C LCD-display sets this limit in speed
Only latency that vary is the Mutex lock I2C
due to interference with I2C LCD-display communication

Interrupt frequency (INA226): 1/1129695±2µs (1/1,1s)
Finns lite att läsa på hos espressif kring snabbheten för Interrupt och kod:
High-Level Interrupts
Interrupt allocation
Maximizing Execution Speed

Rätt långsamt för en 240MHz 32-bit processor
Men väldigt stabil tidsmässigt
Med portYIELD_FROM_ISR() / taskYIELD_FROM_ISR() context switch (ger samma funktion) i ISR fås en bra realtidsfunktion med extremt liten variation i 1,82µs ISR-Latency, ESP32 ISR → deferred interrupt processing latency! En extrem skillnad mot utan Yield()!
void IRAM_ATTR ISR_INA226Batt(void)
Beskrivning av ISR context switch samt FreeRTOS: Why to call taskYIELD_FROM_ISR() method within the isrHandler. "Calling either xQueueSendFromISR() or xQueueReceiveFromISR() within an interrupt service routine can potentially cause a task to leave the Blocked state which then necessitates a context switch if the unblocked task has a higher priority than the interrupted task.
{
auto InterruptTime = esp_timer_get_time();
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xQueueSendToBackFromISR(DeferredInterruptQueue, &InterruptTime, &xHigherPriorityTaskWoken);
if( xHigherPriorityTaskWoken )
{
portYIELD_FROM_ISR(); // same as taskYIELD_FROM_ISR()
}
}
A context switch is performed transparently (within the API functions) when either xQueueSend() or xQueueReceive() cause a task of higher priority than the calling task to exit the Blocked state. This behavior is desirable from a task, but not from an interrupt service routine. Therefore, xQueueSendFromISR() and xQueueReceiveFromISR(), rather than performing the context switch themselves, instead return a value indicative of whether a context switch is required. If a context switch is required, the application writer can use taskYIELD_FROM_ISR() to perform the context switch at the most appropriate time, normally at the end of the interrupt handler."
Utan Yield() varierar ESP32 ISR → deferred interrupt processing latency mellan 52µs till 900µs.
Beror troligen på att FreeRTOS portTICK_PERIOD_MS är 1ms i ESP32, dvs FreeRTOS tick rate = 1000Hz som är så ofta FreeRTOS kan växla mellan Task under sin Preemptive Multitasking. Min ISR Deferred Interrupt Task har här priority 7 (medelhög).
ESP32 FreeRTOS max Task priority är: 24. Low priority numbers denote low priority tasks. The idle task has priority zero (tskIDLE_PRIORITY).
Max latency utan Yield() för ISR → deferred interrupt processing kan därmed sannolikt bli ≤1000µs = portTICK_PERIOD_MS för en deferred Task med högre prioritet än övriga Tasks.



2023-01-28
Har idag kodat in en finite-state machine i form av en C++ class i mitt ESP32 batterimonitor / PWM-regulator hobbyprojekt. Blev riktigt bra och trevlig!
Styr och håller koll på vilka driftslägen den arbetar i samt sköter om växlingen mellan olika driftslägen på ett strukturerat robust sätt, så jag smidigt kan sköta det från en central kod-funktion.
Blir nu mycket tydligare i programkoden vad som görs samt väldigt mycket enklare att implementera en avancerad robust funktion kring detta! Som att stänga ned i light-sleep kräver att det görs i ett antal steg för bra stabil funktion i mitt projekt, och då tar finite-state machinen hand om den processen bl.a. att stänga ned WiFi först.
Och behöver jag framöver optimera en sådan process eller föra in nya driftslägen så blir det väldigt smidig med en gemensam central kod / class som tar hand om det.
Nu har jag för WiFi / Webbserverns drift samt för CPU-diftsläge / strömsparläge med olika CPU-klockning samt light-sleep.
Kommer senare även att ha för PWM-regulatorn och dess olika laddfaser för blybatterierna.
Kan då även från olika delar i koden fråga finite-state machinen om aktuellt driftsläge för de olika funktionerna.
Är väl något man gjort intuitivt förut också, men inte såhär formaliserat och tydligt, vilket blev mycket bättre och kraftfullare :-)
Så känns som detta projektet tog ett tydligt steg framåt idag!
Även lagt in ny LCD-meny för dels att nolla datan för ESP32 Hard- / WDT-resets, dels för Ah/Wh.
Samt lött in en 470µF/16V/105°C och en 2.2µF/50V R82 kondensator mot den pyttelilla som finns invid ESP32-shipets 3,3V matning, för att hantera när ESP32 sänder data via WiFi.
2023-01-29
Nu summerar ESP32 Ah/Wh både vid CPU 240MHz och i Light-Sleep energisparläge. Lagt in en Serial.print() som visar miljarddelar av en Ah/Wh för att lätt kunna följa summeringen över tid där med den lilla 0,00366A ström (1kΩ) 3,28500V jag mäter just nu.
Får utskrivet vid Light-Sleep / 240MHz typ:
Serial.print(): INA226 Interrupt Time: 45232715734µs, TimeDiff (µs): 2261571 / 1129689, 0.046016466Ah, 0.153235674Wh, 99.959991% vid ström 0,00366A och spänning 3,28500V.
Ger 0.046016466Ah / 0,00366A = 12,57h samma som 45232,715734s / 3600 = 12,57h så OK!
Har då infört en C++ BatteriMonitor class som tar hand om denna loggning.
Har även optimerat funktionen vid drift med Light-Sleep så INA226 växlar till AVERAGE_1024 från AVERAGE_512 annars som ihop med 1,1ms conversion-time ger 2,2s resp. 1,1s cykeltid, samt gjort lite annan kod tydligare. Med 2,2s cykeltid blir Light-Sleep driften extra strömsnål.
Processorn väcks upp ur Light-Sleep via INA260-interrupt och efter avlästa mätvärden, uträknade Ah/Wh och uppdaterad LCD sätts i Light-Sleep igen. Så är då i Light-Sleep >95% av tiden när i energisparläge typ nattdrift, där den då drar 15mA från 5V USB.
2023-01-30
Mätte med ESP32+INA226 i frysen (-18°C) och då blev 0,00000A i rumstemperatur -0,00012A nedkyld vid 1A mätområde, så en hyfsat liten inverkan. Mätningen strulade lite så vet inte hur säkert resultatet blev. Motsvarar då -12mA vid 100A mätområde, ca 2Ah/vecka i felvisning så ifall. Men jag har tänkt att automatiskt regelbundet nollström-kalibrera mot aktiv float-laddström vid 100% SOC fulladdat så även batteribankens självurladdning kommer med, så då blir påverkan försumbar.
Är tänkt att göra en förenklad ML (Machine Learning) hur det varierar med batteritemperaturen, en sorts kalibreringstabell-funktion vs batteritemperatur, för extra precision i Ah-räknandet. Senare kanske via TinyML / Tensorflow om det verkar kunna ge någon fördel.
Även tänkt utvärdera batteriverkningsgrad på liknande sätt, vs temperatur, urladdningsdjup, tid sedan senaste fulladdat, etc.
2023-01-31
Köpt DollaTek 10st MP1584EN ultra liten DC-DC 3A ström step-down omvandlare efter tips om att DC-DC-omvandlare baserade på MP1584 har låg tomgångsström (quiescent current). Testat nu och utan utgående ström drar de låga 0,24mA matad med 12,5V, och ut 7,03V belastade med 22Ω / 0,304A drar den 0,182A. Blir 7,03 x 0,304 / (12,5 x 0,182) = 0,94 dvs 94% verkningsgrad vid så låg belastning! Känns lovande för låg strömförbrukning för ESP32 i drift matad via denna! Bör kunna bli ca 10mA i strömsparläge typ nattdrift med bara loggning av strömförbrukning från/till batterierna aktiv med >95% i light-sleep som drar 15mA från 5V USB. Målet har varit <15mA för strömsnål vinterdrift. Får se hur den och ESP32 trivs ihop.
Driftstemperatur: -45°C till 85°C, Storlek: 22mm gånger 17mm.
Finns även hos svenska Invize: Spänningsomvandlare step-down 3A MP1584
2023-02-01
Ändrat så vid night-mode strömsparläge med light-sleep sänks CPU-frekvensen från 240MHz till 80MHz. Med 10, 20 &
40MHz fungerade inte Serial.print() OK, troligen för ESP32 inte hinner skriva databuffertern innan satt i light-sleep. Övriga koden fungerade helt OK även vid 10MHz!
Men är OK med 80MHz som då ger omkring 0,05x40mA + 0,95x15mA = 16mA från 5V USB. Bör kunna bli ca 10mA i snitt via DC-DC-konverter från 12V, klart under målet <15mA.
Har mätt nu och drar ca 11mA från 12,5V vid 7,0V ut vid night-mode strömsparläge med light-sleep, så är nöjd med det! Går kanske att trimma ned till 6,5-6V, men får bli senare testande vart den gränsen går.
Kodat så bara de ändrade mätvärdena skickas över via SSE (Server Side Events) till webbsidan, vilket både belastar SSE mindre samt gav lägre strömförbrukning. Då även kodat in en liten punkt som blinkar på webbsidan i takt med uppdateringarna, så man ser att SSE är aktiv även om inga siffervärden ändras. Den punktens events() uppdaterar även canvas-grafiken.
2023-02-03
Kodat in att menyinställningarna för strömshunt (mV/A, typ 60mV/60A) nu även ändrar inställningarna i INA226 via ina226.setResistorRange(Ω,A), så därmed kodmässigt klart för inkoppling mot blybatteriet i mitt lilla experiment off-grid solcellssystem.
Även installerat breadboard och ESP32 på en gemensam bottenplatta med fasta kopplingsplintar för att säkert kunna dra elledningarna till batteriet. Blir inte så bra direkt från breadboard!
2023-02-04
Kört och loggat min lilla testström lite längre idag, här i strömsparläge / light-sleep:
INA226 Interrupt Time: 26808049418, TimeDiff (us): 2262446, -2.735489130Ah, -8.853511810Wh, SOC 97.621315%. Kodfunktionen för Ah / Wh & SOC är på plats!
2023-02-05
Optimerat Task_LCDbuttonsHandler() för snabbare respons på knapptryckning samt mindre inverkan på övrig kodexekvering. Blev även en renare, tydligare och kortare kod kring I2C.
2023-02-16
Är bara INA226 spänningsmätning VBUS som har 830kΩ ingångsresistans, strömmätningens ingångar IIN+/IIN- har en Input bias current på typ 10µA, men uppmätt ca 35µA i drift!
Så går inte att göra en RC-filtrering på samma lätta sätt där som för VBUS!
Med 4,7µF/4,12kΩ (20ms RC) fick jag 341mA mätt med 500mA genom strömshunten! Utan 4,2kΩ mättes 501,7mA genom 60A/60mV shunten (LSB=1,8mA).
Missat där så blev lite feltänk! Få fundera på hur jag kan göra istället för att inte missa strömmätningen mellan 2,2ms samplings intervallen! Vill få med även korta strömspikar!
Har nu 22Ω och 4,7µF för strömingångarna som skydd, vilket bara ger 0,10ms tidskonstant.
2023-02-20
Kopplat in min ESP32-batterimonitor till mitt lille experiment off-grid solcellssystem här hemma i lägenhet nu i testdrift.
Så jag kan testa i riktigt driftsmiljö och utveckla den vidare mot färdig funktion med verklig driftsdata för mer skarp drift.
Visar sig då ett elektriskt fenomen som gör att de snabba superkorta strömpulserna från min Battery Reconditioner (9kHz, >50A) ger fel strömvärden vid avläsning av spänningsfallet över 60A/60mV strömshunten. Det då även en så grov strömshunt innehar lite induktans så spänningen vid snabba strömpulser visar inte bara den resistiva spänningen över shunten utan en induktiv sådan också som blir som en falsk strömsignal! Så kondensatorn i strömmätningens RC-filter på 22Ω / 4,7µF laddas upp så det vid strömmar på 100-200mA fås 5-10ggr högre mätt ström, samt vid 800mA ca 2ggr högre!
Utan djupare analys trodde jag att de skulle ta ut sig över en cykel med inverkan av den mikroinduktansens strömtröghet, men gör uppenbarligen inte så!
Så ska försöka få lite hjälp med mer djup kunskap kring det från folk som kan elteorier mer på djupet än jag kan och kanske få tips eller tankar som gör att jag kan arbeta vidare med att nå en lösning även på det. Men kändes lite motigt tillfälligt nu.
Funderar lite kring om LC- eller LRC-lågpassfilter skulle kunna lösa det?
Men känns ändå jäkla skoj att kommit såhär lång nu!
Vid kontinuerlig jämn DC-ström mäter den med väldig hög precision!
Lite input kring detta:
- Kalkylator för låg-/högpassfilter
- LC Filter Calculator – How LC filters work
- LC low pass calculator
- Basic Knowledge of LC Filters
- Transient Robustness for Current Shunt Monitor, Tips?
- TI: INA226 - pulse current measurement
- INA226: 1uA measure current resolution for INA226
- INA226: Measurement resolution and ADC error, 1 LSB Shunt Voltage: 2.5µV
- INA226: Current measurement error with PWM motor driver
- INA240 -4 to 80V, bidirectional, ultra-precise current sensor with enhanced PWM rejection
- ESP32 corrupt heap when handling multiple simultaneous requests, Websockets has been updated / fixed, but SSE (which has similarities with websockets) not. As stated I use Server Sent Events so possible an issue still exists in SSE. (2018, ESPAsyncWebServer)
2023-02-23
Mätt upp strömförbrukningen till: 35mA/12,5V WiFi/webbserver + LCD-bakgrundsbelysning + ESP32 240MHz awake, 33mA vid 1/3-del "Soft" LCD-bakgrundsbelysning mode.
Drar 9mA i snitt med Wifi-OFF, släckt LCD-bakgrundsbelysning, ESP32 80MHz samt light-sleep som väcks upp av INA226-interrupt bara för att kort läsa av nya mätvärden och uppdatera LCD-display 1ggr/2,2s, vid 7,0V från DC-DC omvandlaren. Under själva light-sleep drar den 7mA.
Känner mig nöjd med 9mA då det är <<15mA som var målet!
2023-02-26
Mätt upp strömvärden i off-grid solcellsdrift via de tre olika källorn PWM-display / DMM (True RMS spänning över strömshunt) & INA226 (över strömshunt 60A/60mV), när PWM-regulatorn strömpulsar med drygt 8A pulser 30Hz (ca 7% duty-cycle) samt en Battery Reconditioner strömpulsar >50A 9kHz extremt korta strömpulser genom strömshunten in i blybatteriet:
Mätn1: PWM: 0,3A / DMM: 0,55A / INA226: 1,483A
Mätn2: PWM: 0,2A / DMM: 0,48A / INA226: 1,459A
Vid Batteri: 13,87V = PV Throttle, INA226 mätt ca 20W.
Så är något i min mättekniska utformning kring INA226 som måste fixas för att hantera sådan kraftigt strömpulsad mätning OK!
När ingen strömpulsning förekommer mäter alla tre källorna lika strömvärde!
OBS! PWM-regulatorns egen strömmätning från solpanelen visar också stort fel gentemot DMM True RMS mätvärdet, och då inkluderar det även ESP32´s egenförbrukning på 9mA samt Battery Reconditioner´s på ca 20mA!

PV off-grid Operational status dashboard sneak-peek.
2023-03-02
Fått strömmätningen med kraftiga strömpulser att fungera nu genom att spänningen över 60A/60mV strömshunten filtreras i ett LRCL-filter vid ingångarna till INA226. Nu stämmer strömvärdena från INA226 med DMM True RMS spänningsmätningar (mV med 2 decimaler) över strömshunten. Ska utvärdera och analysera mätningarna mer noga framöver. Jag kan inte ännu riktigt förklara el-teoretiskt varför det fungerar så och därmed inte heller optimera komponentvärdena för det. Men troligen är det inte mer känsligt än för ett RC-filter, då det ser ut att visa rätt med båda de helt olika strömpulserna! Har gått på min analyserande intuition vad som borde kunna fixa detta!
Visar en liten sneak-peek från mitt grafiska dashboard för "PV off-grid Operational status" i verkligt drift nu i mitt lilla experimentella off-grid solcellssystem vid mobil-laddning.
2023-03-07
Presentation av projektstatus i ett par Facebook-grupper:
Nu har jag mitt ESP32-mikrokontroller baserade batterimonitor projekt i drift sedan en dryg vecka här hemma i mitt lilla experiment off-grid solcellssystem i lägenheten :-)
Känns riktigt skoj att kommit så långt, men är lite svårare än jag tänkt och tar rätt mycket tid att utveckla!
Laddar mobilen här 9 månader/år för att få lite verklig drift, övrig tid på vintern räcker inte strömmen till. Så är mobil-säsong nu igen.
Skoj då att kunna följa driften så detaljerat nu :-)
Med 60A/60mV strömshunt här kan den mäta med en upplösning på 1,8mA (LSB). Med 100A/50mV strömshunt i mitt riktiga off-grid solcellssystem blir det med 3,0mA LSB, så bra precision.
Med INA226 "ultra-precise I2C output current / voltage / power monitor" med väldigt hög precision samt hög noggrannhet över lång tid och stort temperaturområde (så jag inte trodde det var tekniskt möjligt med den prestandan) så bör jag få en riktigt fin precision hos batterimonitorns mätningar, även över hyfsat lång tid.
INA226 får göra upprepat i kontinuerlig följ 512st mätningar av spänning / ström / effekt under 1,1s som den då medelvärdesbildar och sätter en interruptsignal till ESP32 att det finns nya mätvärde att hämta från dess buffert. Så ESP32 hämta varje 1,1s nya sådana fint aggregerade data till sina beräkningar. Får på så sätt både väldigt stabila data som ändå tar med snabba förändringar i ström / spänning 512ggr/1,1s!
I ESP32 mäter jag tid med 1µs upplösning, så beräkningen / summering av Ah och Wh sker med väldigt hög precision så också.
Jag har en Battery Reconditioner till batteriet som via strömshunten strömpulsar med väldigt korta skarpa pulser på >50A i 9kHz för att motverka sulfatering samt PWM-regulatorn strömpulsar med >8A 30Hz när den begränsar laddströmmen för att anpassa laddningen till batteriet.
Jag har nu lyckats få till att jag ändå kan mäta så små strömmar som några mA utan att mätningen störs ut av de höga strömpulserna, och samtidigt mäta strömmängden de höga strömpulserna ger. Ska senare utvärdera lite bättre hur bra det blivit, men ser så här långt riktigt bra ut. Min NASA BM1 batterimonitor jag har i mitt off-grid solcellssystem idag störs helt klart av det strömpulsandet och mäter inte riktigt rätt då. Samt den är inte riktigt temperaturstabil eller långtidsstabil heller, men har ändå haft väldigt bra nytta av den under många år.
Har även en webbserver kodad i ESP32 med webbsidor som visar driftsdata, statistik och info på fem olika webbsidor, som jag då via WiFi kan se i webbläsaren på mobilen eller på en dator, som man ser i mobilen på fotot.
Men är rätt mycket jobb kvar ändå till helt färdigt.
Att göra en egen batterimonitor såhär innebär att jag kan visa precis den driftsdata och statistik jag vill se, samt som det ser ut nu kan jag få en väldigt hög precision i mätningarna.
Ska senare även försöka att skicka data via WiFi / Internet till en webbsida jag har på webbhotell, där jag kan samla driftsdata över längre tid, samt som jag då kan se hemifrån eller vart jag än befinner mig.
Men några gånger har jag nästan varit på väg att ge upp då det dykt upp svårigheter som kändes omöjliga att lösa för mig, men jag lyckats med till slut ändå :-)
Samt är mycket nytt att lära för mig, då detta är mitt första ESP32-projekt samt första gången jag använder FreeRTOS i kodandet!
Tror dock jag tagit mig igenom de värsta svårigheterna så nu...
Jag gör detta som ett hobbyprojekt till mig själv för bättre funktion i mitt off-grid solcellssystem i husvagnen och är bara självlärd inom elektronik, C++ kodning samt ESP32-mikrokontroller.
Samt gör det även lite för att ha något tekniskt att engagera mig i och få stimulans från som pensionär.
För de som är nyfikna kan man se mer på min webbsida för projektet:
https://www.nordicoffgrid.se/datalogging/batterymonitor.php

2023-03-08
Texas Instruments benämner sin sensor INA226 jag använder för "ultra-precise I2C output current / voltage / power monitor".
Så ihop med den precision jag kan får ut ur ESP32 så får jag kanske då en ultra-precise batterimonitor som kan mäta sig väl mot de som finns på marknaden.
Det jag via min ESP32-batterimonitor nu följt laddningen i mitt 44Ah blykolbatteri här hemma senaste dygnet är riktigt intressant, där -2Ah urladdat (95% SOC) återladdades igår via bulk-, absorptions- och float-laddning i fullt solsken under dagen ger en väldigt detaljerad info om laddförloppet.
PWM-regulatorn skiftade från kontinuerlig float-laddning till bulk- / absorptions-laddning, då batterispänning sjönk till ca 12,3V vid mobilladdning, under <12,4V som är gränsen för det. Är det initiala spänningdroppet "coup de fouet" man får vid riktigt 100% SOC fulladdade blybatterier i bra kondition, så strömpuls-laddningen har verkligen hunnit fräschat upp blybatteriet efter ca 2,5 vintermånader utan att nått 100% SOC full laddnivå!
Riktigt skoj att kunna följa det så noga, vilket även gav mig ett par nya intressanta kunskaper kring blybatteriladdning.
Kunde bl.a. bekräfta ett antagande jag gjort utifrån ett flertal olika källor om nivån på 0,015C / 1,5% tail-current (1,5A/100Ah) som gräns där absorptions-laddningen bör avbrytas för optimal laddning, så man låter blybatterierna själva tala om när de fått lagom med absorptions-laddning.
Så kommer använda det i min egna PWM-solladdregulator.
Strömmen under 3h absorptions-laddning gick ned till <0,44A/44Ah (0,01C / 1%) utan tvekan där, så blir bra marginaler!
Samt vid 13,8V float-laddning stabiliserade sig den pulsade laddströmmen på ca 200mA (för högt). När solen sedan började gå ned så solcellsströmmen sjönk långsamt och stabilt så blev strömmen vid 13,4V ca 35mA, vilket känns mer lagom för standby-laddning.
Är så grovt och primitiv att köra med en fast tidsgräns för absorptions-laddning, och även med en adaptiv tidsfunktion mot batterispänningen precis när laddningen startar på morgonen blir en grov osäker styrning av blybatteriladdningen, om än något bättre.
Senare ska jag koda lite mer analytisk funktion så jag får ut än mer intressant data från den, som även ska kunna styra laddförloppet bättre.
Jag tycker hela den här branschen med 12/24/48V off-grid solcellssystem är lite seg i att utnyttja den moderna tekniken och skapa lite aktivare smartare laddhantering.
När man gick från oreglerad laddning till s.k. smarta batteriladdare för blybatterier var det ett stort steg, men lite synd utvecklingen verkar ha stannat där känner jag!
Man verkar helt ha nöjt sig med vanlig flerstegsladdning med fasta gränser!
På kvällen uppdaterades de grundbibliotek från Espressif man använder för ESP32 kodning inkl. Arduino v2.0.7, och var några buggfixar där som eventuellt åtgärdar några saker jag haft lite problem kring med WiFi / Webbservern.
Har även gjort lite code refactoring så jag nu fått in i stort all driftsstyrning via en Finite-State Machine (FSM) och därmed en bättre tydligare funktion. Innebär att alla de olika driftslägena, "states", nu styrs och växlas mellan av StateMachine-koden, så allt det är samlat på en plats och det blir inte redundant kod. Blir även mycket enklare att underhålla den delen av funktionaliteten samlad centralt på så sätt, samt mindre risk för buggar.
En tydlig förbättring blev att jag införde en Task_StateMachine() för asynkron växling av driftsläge, så t.ex. inte aktivering av WiFi / Webbserver blockerar responsen hos tryckknapparna. Task_StateMachine() kommunicerar med class StateMachine som har en synkron funktion.
Idag 14 Mars när jag aktiverade ESP32-batterymonitorn med en knapptryckning på morgonen kopplade den upp snabbt smidigt mot WiFi, vilket efter en natts drift tidigare ofta varit trögt och ibland misslyckats. Om det håller i sig är det ett signifikant framsteg mot stabil 24/7/365 drift!
Jag hade en svag intuitiv känsla att en asynkron Finite-State Machine (FSM) funktion skulle kunna ha den inverkan, så håller tummarna för det!
Förfinade även ESP32-webbsidornas meny-funktion lite, med att när man tryckt på ett menyval så fälls meny in snyggt mjukt igen tills webbläsaren hinner växla webbsida.
2023-03-15

PV off-grid Operational status dashboard sneak-peek.
Även idag startade ESP32-batterymonitor upp WiFi snabbt och smidigt vid knapptryckning!
Samt flera gånger under gårdagen och kvällen.
Kan även se att när WiFi / Webbserver stängs ned frigör mycket SRAM nu (52% till 76% ledigt), vilket inte skett tidigare, så indikerar också tydliga förändringar i kodens funktion som känns positiva. Samt lägsta ledigt SRAM nu 129204b under dessa dygn och största allokerbart heap block 110580b stabilt. Är ca 161970b vid 52% ledigt SRAM.
Är stabilaste drift hittills under flera dygn såhär! Känns riktigt lovande!
Aktiv WiFi, webbserver och SSE-data till webbsida drar ca 35mA för sin drift, så rätt måttligt.
2023-03-16
Helt stabil snabb smidig uppkoppling mot WiFi nu tredje morgonen (24/3-drift) i drift också, när aktiverad med knapptryckning! Riktigt upplyftande, känns att jag går i mål med detta nu.
Samma många gånger under hela gårdagen, så ett riktigt bra framsteg för 24/7/365-drift!
Är sannolikt en kombination av WiFi-buggfixar i Platform-espressif32 v6.1.0 / ESP-IDF v5.0.1 / Arduino v2.0.7 samt min dynamiska Task_StateMachine() ihop med min code refactoring!
2023-03-17
Har två gånger fått kod-krascher när jag aktiverat WiFi / Webbserver med felmeddelandet:
"Guru Meditation Error: Core 0 panic´ed (IntegerDivideByZero). Exception was unhandled."
Har lite snabbt sökt men inte hittat orsaken i min kod. Ska göra det noggrannare senare!
Men ESP32 fixar Rebooting snabbt och bra direkt efter det, så inget som direkt påverkar stabil 24/7/365-drift annat än att <15min (<2hr) data förloras!
2023-03-18

Har kodat "Senaste 24-timmars löpande statistik" för strömmen, med Akuell-, Medelvärdes-, Maxvärdes- & Minvärdes-ström över senaste 24 timmarna löpande. Ska bli för de andra mätvärdena också. Får här tränga djupare in i C++, klasser och objektorientering m.m.!
Ger en bra överblick över senaste dygnets drift i off-grid solcellssystemet.
ESP-batterimonitorn fortsätter att arbeta stabilt över dygnet.
2023-03-19

Hade haft NordicOffGrid Batterimonitorn i drift i dryga 24h när skärmdumpen från mobilen togs idag. De senaste 24h har medelströmmen då varit -5mA i det väldigt gråmulna vädret, samt Max +73mA och Min -82mA. Max laddström mitt lilla experiment solcellssystem ger är ca 1A i bra soligt väder, så idag ca 7% av det som mest. Är mätt med en 60A/60mV strömshunt.
Det löpande strömmedelvärdet för 24h är beräknat på ca 80.000 strömvärden hanterade i ESP32 från INA226-sensorn, som i sin tur skapar varje sådant strömvärde som medelvärdet under 1,1s för 512st strömmätningar.
Så totalt baseras det löpande 24h strömmedelvärdet på ca 40.000.000 strömmätningar, vilket ger bra precision! Liknande gäller för Max- och Min-värdena. Max- och Min-värdena bygger på de under 1,1s medelvärdesbildade mätvärdena från 512st mätningar i INA226, så korta irrelevanta strömspikar filtreras bort på så sätt. Blir samma för batterispänning och övriga datamätvärden också.
Med så många mätvärden blir det viktigt med en bra effektiv algoritm för hur man hanterar det i programkoden, och jag har fixat en som både är väldigt snål på minne och CPU-belastning.
Med strömmedelvärdet för senaste 24h kommer jag göra en bra tidsprognos för hur länge kvarvarande batterikapacitet bör räcka, något helt annat än den prognos baserad på momentan-strömmen min NASA BM1 ger idag. Baserat på momentanström fås olika tidsprognos när 12V kylskåpskompressorn arbetar eller pausar i sin drift, helt oanvändbart! Med 24h tas även den lägre strömförbrukningen under natten med i prognosen.
Ger en bra överblick över senaste dygnets drift i off-grid solcellssystemet.
Blir mer som driftsövervakning av off-grid solcellssystemet än bara batterimonitor!
Ger på så sätt en tydligare överblick över driften av min Victron blykolbatteribank, samt kommer bättre kunna planera aktiv drift i lite längre dåligt solcellsväder.
Känns roligt med en batterimonitor med bra precision och bra info via aggregerad data :-)
2023-03-24



Stabila värden trots korta solglimtar!

Har idag kodat en "Time To Go" panel för en bra tidprognos över hur länge kvarvarande batterikapacitet bör räcka för driften vid urladdning, eller tid till fulladdat när solcellerna laddar upp batteribanken. Upp↑/ned↓-pilar visar laddning/urladdning.
Visar bara i hela dagar och timmar, då minuter blir för precist i förhållande till den långtidsprecision man får i ett sådant här system anser jag, och kanske än mer till hur noga man rent tekniskt kan synkronisera 100% SOC med verkligt fulladdad batteribank. Blir då inom ±30min som ↑↓1hr visas avrundat.
Tidprognosen visas dels för senaste löpande 24hr strömmedelvärde, dels för senaste 1hr strömmedelvärde. På så sätt får man en stabil bra uppfattning över hur man ligger till med driften av batteribanken och off-grid socellssystemet oavsett lite varierande ström över dygnet eller från kylskåpskompressors drift ON/OFF, från korta solglimtar, etc. "Time To Go" baserat på momentanström är värdelös!
Kanske blir det senare någon form av adaptiv funktion för 1hr visningen, som någon gav förslag på för anpassning till hur aktuell drift är.


Idag är det väder med ständigt korta solglimtar, men får då ändå en stabil fin prognos för hur lång återladdningstid som är kvar, istället för att den hoppar kraftigt fram och tillbaka efter hur den momentana strömmen är i systemet!
Strömmen varierade då 400-500% till 1000% snabbt upp och ned, så blir svårt att bilda sig en uppfattning på det momentana strömvärdet / tidsprognosen, men med 1hr medelvärde får man ändå stabila fina värden både för strömmen och återstående laddtid! Riktigt häftigt!
Ska även bli löpande 7dygns statistik och troligen även 30dygns, för än bättre info, insikt och överblick det ger över off-grid-systemets drift. I ett sunt dimensionerat off-grid solcellssystem med ≥5dygns dåligt-väder-reserv (Days Of Autonomy) utjämnar batteribanken normalt variationer i strömproduktion av verkligt väder över minst 1-2 veckors tid, så 7dygns strömstatistik är värdefullt i sådan drift.
Min vision med detta är även ett system som helt autonomt smart kan styra laster efter hur mycket ström den utvärderar att det finns att utnyttja över tid, typ 4G router, fläkt, belysning, etc.

Skapat en TIME-panel för dels ESP32 Uptime, dels för datum/tid för ESP32 RTC samt Client tid, så kan se hur länge ESP32 varit igång sedan senaste bootning samt kan jämföra hur ESP32 RTC-tiden håller sig och är uppdaterad.
Har efter det fått ett par panic-reboot med felmeddelandet: "Guru Meditation Error: Core 0 panic´ed (LoadProhibited). Exception was unhandled.", som jag får felsöka!
The error LoadProhibited means that the CPU tried to load a variable form an illegal address.
Do you use String Class and do a lot off String constructions with String c = "a" + "b", or are you creating char arrays on the fly e.g. char d[ ] = "efg".
Arduino: ESP32 - Guru Meditation Error: Core 1 panic´ed (LoadProhibited): "My guess is that "lastData" returnedData = int(lastData[7]);
has not been set and is still a null (0) pointer. You get an error when you try to read address 7."
Har lagt in att alla class StateMachine´s public variabler initieras i dess Constructor StateMachine(), kanske en möjlig orsak? En variabel, ESP_Time_us, som jag missat där används tidigt för just Uptime, kanske innan den hade initierats med något värde!
Optimerat för detta när bara IP förloras, så WiFi nu ska startas om och återansluta IP:
15:32:02.824 > INA226 Interrupt Time: 144809137, TimeDiff(us): 4592239, -0.038083Ah, 0.596590Wh, 99.913%, 0.96/0.52W
OBS!
15:32:05.962 > [157673][V][WiFiGeneric.cpp:374] _arduino_event_cb(): STA IP Lost
15:32:05.968 > [157674][D][WiFiGeneric.cpp:931] _eventCallback(): Arduino Event: 9 - STA_LOST_IP
15:32:05.973 > WiFi.onEvent(): No WifiConnect, Event: 9
15:32:05.975 >
15:32:07.851 > INA226 Interrupt Time: 150549432, TimeDiff(us): 5740295, -0.038016Ah, 0.598343Wh, 99.914%, 1.10/0.54W
WiFi.status() != WL_CONNECTED
blir nog inte True då, vilket jag nog förutsatt!?
Får fundera mer på det och söka kunskap om! Inträffar så väldigt sällan, så svårt att ha tur och fånga upp meddelandet såhär.Har modifierat nu så det bör återansluta WiFi / IP!
Hanterar nu dessa
WiFi.onEvent(): RDUINO_EVENT_WIFI_STA_DISCONNECTED || ARDUINO_EVENT_WIFI_STA_LOST_IP || ARDUINO_EVENT_WIFI_STA_STOP
för anrop av WiFiReconnect(), samt har tagit bort villkoret WiFi.status() != WL_CONNECTED
för återanslutning.
Skulle jag kunna använda IDF Monitor ihop med Espressif Arduino-framework så skulle jag få ut det radnummer det inträffar vid samt i vilken kod-fil! Då hade det genast blivit mycket lättare att hitta och åtgärda (om det är i min kod-fil), så får söka efter om det är möjligt på något sätt!
Felmeddelande jag får i Verbose mode (DCORE_DEBUG_LEVEL=5):
Guru Meditation Error: Core 0 panic´ed (StoreProhibited). Exception was unhandled.
Core 0 register dump:
PC : 0x40094090 PS : 0x00060233 A0 : 0x80094506 A1 : 0x3ffe1c10
A2 : 0x3ffb8014 A3 : 0x3ffb8e1c A4 : 0xabba1234 A5 : 0x00000010 A6 : 0x00000003 A7 : 0x00000003 A8 : 0x00000003 A9 : 0x00000002
A10 : 0x3ffb8e18 A11 : 0x0000003c A12 : 0x00000059 A13 : 0x3ffb8e14
A14 : 0x3ffb8e48 A15 : 0x00000000 SAR : 0x0000001d EXCCAUSE: 0x0000001d
EXCVADDR: 0xabba1240 LBEG : 0x4008be5d LEND : 0x4008be6d LCOUNT : 0xfffffffe
Guru Meditation Error: Core 0 panic´ed (LoadProhibited). Exception was unhandled.
Core 0 register dump:
PC : 0x400ded89 PS : 0x00060030 A0 : 0x800deded A1 : 0x3ffe1d80
A2 : 0x3ffb85d4 A3 : 0xbaad5678 A4 : 0x3ffb85e0 A5 : 0x3ffb93c8
A6 : 0x0a0d0a0d A7 : 0x32343031 A8 : 0x800ded85 A9 : 0x3ffe1d60
A10 : 0x00000000 A11 : 0xbaad5678 A12 : 0x00000000 A13 : 0x3ffb857c
A14 : 0x00000000 A15 : 0x74000a0d SAR : 0x0000000a EXCCAUSE: 0x0000001c
EXCVADDR: 0xbaad567c LBEG : 0x4008a530 LEND : 0x4008a546 LCOUNT : 0xffffffff
Här finns felbeskrivning av LoadProhibited, StoreProhibited:
"These CPU exceptions happen when an application attempts to read from or write to an invalid memory location. The address which has been written/read is found in the EXCVADDR register in the register dump. If this address is zero, it usually means that the application has attempted to dereference a NULL pointer. If this address is close to zero, it usually means that the application has attempted to access a member of a structure, but the pointer to the structure is NULL. If this address is something else (garbage value, not in 0x3fxxxxxx - 0x6xxxxxxx range), it likely means that the pointer used to access the data is either not initialized or has been corrupted."
Så antagligen försöker min C++ programkod läsa/skriva till en variabel som inte längre existerar (ett klassiskt C++ kodfel), som kanske skulle behöva göras static för att behållas i programminnet typ Local variable scope.
Eftersom exekveringsfelet inträffar i Core 0 (där Espressif WiFi systemkod ligger, ihop med en del av mina FreeRTOS Task) skulle jag som felsökning kunna flytta alla mina Task till Core 1 temporärt. Följer då felet med till Core 1 så är det någon av mina Task. Då kan jag flytta en Task i taget tillbaks och när felet följer med tillbaka till Core 0 så vet jag vilken Task som orsakar det. Men hade varit lättare om det inträffade oftare!
Verkar dock som jag lyckats skapa något pekar- eller variable scope-fel i min senare kodning nu! Känns bara lite konstigt att det inträffar så sällan med många timmar emellan!
Nu senast LoadProhibited med EXCVADDR: 0x00000005.
Får även senare framöver titta på Get started with Arduino and ESP32-DevKitC: debugging and unit testing!
Även kanske om problemen fortsätter: Please build project in debug configuration to get more details about an exception, ihop med PlatformIO meny: PROJEKT TASKS - wemos_d1_uno32 - General - Monitor (kan det vara "IDF Monitor"?).
Har nu lokaliserat ett problem jag fick efter den senaste större kodförändringen till dålig kontakt och glappkontakt i just en sådan som går mellan min DC-DC-konverter och ESP32! Trodde naturligtvis jag fått till någon dum bugg i min kod, men hittade glappkontakt och sannolikt även dålig kontakt i den kopplingstråden. Sedan är det nog även något typ pekarfel i min C++ kod!
Samt efter de senaste kodförändringarna har ESP32 fått svårt att återansluta till WiFi / Webbserver, så något blev inte bra där!
Backar därför till senaste version jag märkt OK (2023-03-14), och där fungerar det bra igen. Så blir att återinföra förändringar sedan dess en i taget och checka när problemet uppstår. Går lätt via "Compare Selected" i PlatformIO / VSCode där jag får upp de två filer jag jämför sida vid sida med alla skillnader utmärkta, så bara kopiera kod mellan dem steg för steg via den pil-icon-kopieringsfunktionen som finns där. Blev två steg fram ett tillbaka nu, som det blir ibland!

Är inget minnesläckage heller under den tiden med: Fri SRAM 52% (161660b), Lägst ledig heap: 135324b samt Största allokerbara heap 110580b.
Så noga under så lång tid har jag inte följt upp kodexekveringen förut, även om jag haft igång den i flera dygn tidigare. Men ville nu vara säker på att jag utgår från en stabilt fungerande kod för felsökningen av senare tillagd kod!
Känns skönt, för då ska det lättare gå att hitta buggen / buggarna i den kod jag successivt återinför steg för steg nu igen.
Även om det känns lite märkligt att ett typ pekarfel kan inträffa så glest som 3-4h eller längre tid med programkoden exekverandes 1ggr/1,1s! Men är delvis asynkrona kodloopar med FreeRTOS Task ihop med att lite olika kod exekveras beroende på mätt batteriström, så kanske någon kombination kan uppstå så sällan då? Samt har bara hänt när WiFi / Webbservern är aktiva, så är i någon kod som bara exekveras då så har mina aningar var jag ska se upp lite extra när koden återinförs steg för steg! Detta är lärpengar som ny på objektorienterad C++ kodning!
Får läsa på lite mer om det, som typ: Grundläggande objektorienterad programmering i C++: Klasser och objekt, Creating a class object in C++, References to the class object. Access to a class object by reference., DuckDuckGo: C++ "class" "object" new pointer vs reference, DuckDuckGo: C++ new reference "class" "object", Static Objects in C++, Static Members of a C++ Class.
Ser ut som att jag missuppfattat någon nyans där och bör modifiera min C++ OOP-kod?
W3school testing C++ OOP coding.
[746963][D][WiFiGeneric.cpp:931] _eventCGuru Meditation Error: Core 0 panic´ed (IntegerDivideByZero). Exception was unhandled.
Guru Meditation Error: Core 0 panic´ed (LoadStoreAlignment). Exception was unhandled. EXCVADDR: 0x401057be LBEG
Vid aktivering av strömsparläge light-sleep?
[747746][D][WiFiGeneric.cpp:931] _eventGuru Meditation Error: Core 0 panic´ed (IntegerDivideByZero). Exception was unhandled.
Kom efter: Uptime: 00y00m00d 00:12:26, med 12 minuters tid till aktivering av strömsparläge light-sleep!

Återinförde all kod utom den som gör statistiska beräkningar inom class RingBuffer24hr och då fungerar det stabilt inklusive Time-displayen med Uptime och datum! Så kodbuggen finns i den koden för statistiska beräkningarna inom class RingBuffer24hr eller dess SSE-skickande till webbsidan. Så får gå igenom koden för varje sådan statistikdata där och införa en och en tills jag hittat kodfelet. En hyfsat rimlig uppgift!
Skönt jag fått stabil drift igen så långt med koden!
Konstaterar samtidigt så tomt det känns med bara rå mätdata med frånvaro av den omgjord till information s.k aggregerad data! Så min vision kring detta är helt rätt och värt arbetet!
Och efter Uptime: 00y00m00d 01:35:34 kom det igen:
Guru Meditation Error: Core 0 panic´ed (LoadProhibited). Exception was unhandled. EXCVADDR: 0x00000005 LBE
Kommer så jäkla sällan, så svårt att veta vilken kodförändring som orsakar det!
Provar nu att köra alla mina Task på Core 1.
Har tänkt att float- och int-variabler accessas inom en klockcykel så ingen risk för kollision där, men kan ju bli det när en global sådan variabel accessas samtidigt från de två olika CPU-kärnorna! Så ett lite feltänk pga oerfaren inom Multitasking- / Mulitecore-kodande!
Samt får nog även kolla att jag ger exklusiv access till globala double-variabler då de tar två klockcykler att accessa, samt troligen samma till alla class-object instanser (eller bara dess funktioner()?) i min Multitasking-koddrift!


Nu har jag återställt all kod samt, fixat några små buggar, optimerat lite kod samt gjort lite Code refactoring, ihop med att all min kod nu körs på Core 1. Och nu ser det ut att arbeta stabilt och bra utan kodkrasch, i vart fall i ett par 3-4 timmar pass.
Har även omprövat min tidigare åsikt och redovisar nu "Time To Go" antingen som ddhh eller hhmm, dvs gått ifrån att visa timme som minsta mått utan tar även minuter så man får lite mer upplösning på det. Man får se det som tid kvar till att batterimonitorn når 100% SOC, vilket kan skilja något från batteribankens verklighet.
Kommer framöver för 24hr Time-To-Go statistiskt analysera hela dess datamängd och få en lite bättre prognos som aldrig bör komma fram till en fulladdad tid mitt i natten! Blir även senare liknande för löpande 7 dygns statistik!
Denna 24hr statistik baseras på 40.000.000 mätvärden / dygn av spänning, ström och effekt till/från batteribanken, så fångar även upp snabba förändringar för hög precision.
Är det VOLTAGE, POWER, DISCHARGE & SOC som också ska få sina 24hr data, vilket den mesta C++ OOP-koden redan är kodad för.
Ska senare bli en lika dan dashboard för "Latest 7days running statistics"!


Har nu passerat 5 dygns uptime, när detta skrivs 00y00m05d 06:43:11. Så det visar på hög exekveringsstabilitet. Det motsvar ca 412.000 programloopsexekveringar, så alla kombinationer borde ha hunnit uppstå då som kan leda till kodkrasch tänker jag.
Är lite av en milstolpe för 24/7/365-drift känner jag!
Är bara att koda vidare för att VOLTAGE, POWER, DISCHARGE & SOC också ska få sina 24hr data, vilket den mesta C++ OOP-koden redan är kodad för.
Kan även konstatera att objektorinterad programmering (OOP) är bara så bra och smidigt, samt att jag trivs bra med att koda i C/C++ som ger väldigt snabb prestanda och minnessnål kod!
I Computer Sweden´s De 10 mest populära programmeringsspråken i april 2023 ligger C på 2:a och C++ på 4:e plats i populäritet, så är populära hos många.

Men ska först göra ett snabbt test om jag inte lite enkelt kan skicka data till min egna webbsite.
Även fått tips att använda Grafana på egen server hemma för att visa aggregerad mätdata i olika dashboards som är lätta att tyda. Får kolla upp om det även går på min webbplats inhyrd på webbhotell! Grafana ser fint ut och har spanat in det för rätt länge sedan då Grafana kan ge fina grafiska dashboards.
Samt en som via Zabbix gjort egen monitoring från Victron-enheter i sin båt.
Själv skulle jag i framtiden vilja använda MQTT med en tidsdatabas typ InfluxDB + MQTT.
Samt för egen grafisk display ser LVGL - Light and Versatile Graphics Library trevligt ut.
Vid cykling 100%-98%-100% SOC blir Coulomb(Ah)-verkningsgraden 48% för mitt gamla blykol-startbatteri jag använder i experiment solcellssystemet här hemma. Utgör den cykling min mobil-laddning ger.
Är betydligt bättre verkningsgrad än jag trodde för den lilla marginella cyklingen. Vid automatisk mätning av verkningsgraden senare ska det bara göras för de urladdningscykler som batteriet nått <90% SOC för att ge vettiga värden är tanken.
Denna aktuella verkningsgradssiffra kommer jag använda på ett smart sätt i batterimonitorn för att få riktigt bra precision i dess mätningar, vilket då sker med en ständigt uppdaterad aktuell verkningsgradssiffra för batteribanken.
Ska bli spännande att mäta på mina Victron lead-carbon batterier i mitt riktiga off-grid solcellssystem inom några veckor!
Här med laddströmmen 0,157A för 44Ah batteriet under aktiv float-laddning är det 0,0036C dvs ca 1,4ggr marginal mot 0,005C för Tail current! Är också något jag kunde övervaka för stabil robust funktion / drift, och till en början följa upp när i skarp drift. Nu under några dygn mätt till >1,5ggr lägsta ström vid aktiv float-laddning!
Inspiration / referens:
AI-felsökning i 5G-mobilnätet med maskininlärning visar hur analys av stora datamängder ger fördel!
Batteribolaget: "Tur-och-retur-verkningsgrad (urladdning från 100% till 0% och tillbaka till 100% laddning) hos det genomsnittliga blybatteriet är 80%. Motsvarande för ett LFP-batteri (LiFePO4) är 92%. Laddningsprocessen hos bly-syra batterier blir särskilt ineffektivt när 80% laddningstillståndet har uppnåtts, vilket resulterar i 50% effektivitet eller till och med mindre i solcellssystem där flera dagars reservenergi krävs (batteritid i 70% till 100% laddat tillstånd)."
TAO Performance: A complete Energy Management System
UPS VRLA lead acid battery predictive maintenance.

OBS! EFFIENCY siffrorna (99) & (97) är bara fake ännu.
Fick då mätt av min ESP32 batterimonitor batteriverkningsgrad 75% nu mot 48% när jag cyklade till 98% SOC, vilket är riktigt bra för så minimal 4% DOD cykling. Det blykol-startbatteriet är från 2016, så indikerar att det är rimligt fräscht fortfarande märkligt nog men naturligtvis krävs det djupare urladdning för att avgöra det mer säkert.
Energiverkningsgraden 58% är inte helt OK mätt ännu, då jag har någon överledning / störning i hårdvaran vid låga effekter så den mäter fel där. Men vet ungefär vad jag ska ändra på hårdvarumässigt, dock valt att få programkoden rimligt färdig först.
Men programkoden verkar fungera fint som tänkt i att utvärdera batteriverkningsgrad!
(Siffrorna (99) / (97) är bara fake ännu, men ska bli något medelvärde över tid.)
Nästa steg är att lyckas koppla upp mot befintlig PWM-regulator så jag får en automatisk detektering av Tail-current 0,005C vid aktiv float-laddning för synkning mot 100% SOC fulladdad blybatteribank.

OBS! EFFIENCY siffrorna (99) & (97) är bara fake ännu.
Utvärdering av batteribankens coulomb-verkningsgrad (Ah) är intressant data att ta del av, men främst är det viktig data för hög precision i batterimonitorns mätning av SOC/Ah-laddningsnivå status i batteribanken! Coulomb-verkningsgraden blir löpande utvärderad så den fås för aktuellt driftsmönster och batteritemperatur för bästa precision. På så sätt får man hela tiden aktuell batteriverkningsgrad för den typ av drift / cykling man har för sin blybatteribank samt för batteritemperatur och inverkan från åldrande batterier.
För att kunna mäta batteriverkningsgrad rimligt exakt krävs det att batterimonitorn har en bra precision i att kunna synkronisera sitt 100% SOC fulladdat mätvärde med verkligt 100% SOC fulladdat batteri, och där har jag fått till bra funktion nu.
Samt under de första tio cyklingarna kalibrerar sig batterimonitorn mot batteribanken!
Blir en helt annat precision än om man som användare ska försöka mata in ett fast sådant värde själv för batteriverkningsgrad som inställning!
Ska man uppnå en bra långtidsstabiltet i mätningarna av batteribankens SOC/Ah-laddstatus vid längre tids partiell (PSOC) cykling krävs ett bra verkligt värde för batteriverkningsgraden för att det inte ska driva iväg, så en viktig funktion för det. Med båda LiFePO4 och AGM-blykol (lead-carbon) som tål mycket PSOC-cykling blir detta mer viktigt hos en batterimonitor än tidigare!
Så måste vara kombinationen blykolbatteri (mitt gamla Tudor High Tech Carbon Boost 2.0 startbatteri) och strömpulsad laddning från PWM-regulatorns som ger den bra verkningsgraden.
Är skoj att mäta upp och få data på, men den riktiga vinsten är i att med den datan kunna mäta urladdningsnivån (SOC / Ah-urladdning) i blybatteriet med högre precision då jag använder verkningsgraden i beräkningarna där! Här systemdata jag får ut (dock alla datavärden inte helt korrekt där då jag flera gånger laddat upp ny programkod som då stört mitt i mätningar).
Igår kväll/inatt laddade jag ur till 93% SOC så blev absorptions-laddning idag. Då denna PWM-regulator har en fast 3h absorptionstid så kom laddströmmen ned ända till 350mA (0,008C) innan växling till float-laddning, vilket är betydligt lägre än den 0,015C (1,5%, 0,66A/44Ah) Tail-current som är lämplig gräns att avbryta absorptions-laddningen vid för växling till float-laddning.
Om växling skett vid 0,015C Tail-current hade laddnivån då varit någon stans mellan 99,5-100% SOC, så absorptions-laddningen hade kommit väldigt nära 100% SOC fulladdat och bara några få 1/10-dels procent återstått att ladda via float-laddning!
Så blev en bra kvittens på att 0,015C (1,5%) Tail-current är en bra säker gräns att avbryta absorptions-laddningen vid, med god marginal mot hur låg laddströmmen kan bli under absorptions-laddningen. Visar även att 0,015C Tail-current hade avbrutit denna absorptions-laddning signifikant tidigare än dess nu fasta 3h gräns som ger lite onödig överladdning!
Ger ny intressant kunskap med en batterimonitor som mäter med så hög precision!
Så ger bra input till laddcykelstyrningen hos Nordic PV-controller.

Uppmätta verkningsgrader vid grund urladdning 1,5-7% DOD.

Absorptions-laddning - Volt, Amp & SOC / Discharge stämmer med varandra vid 100% SOC batteri!
Tail-current 0,015C (1,5%) 44Ah = 0,66A då Absorptions-laddning ska avbrytas.
Här kör PWM-regulatorn med fast 3h absorptions laddtid så laddar onödigt länge.
I höst skulle Volvos nya elbil EX90 börja produceras, men så blir det inte:
"– Volvo Cars behöver ytterligare tid i mjukvaruutveckling och testning och justerar den planerade produktionsstarten. Produktionen beräknas nu påbörjas under första halvåret 2024, uppger bolaget i ett pressmeddelande.
Även andra tillverkar har haft kraftiga förseningar pga tid som mjukvaruutvecklingen tar!
Nu har jag inför fälttest i mitt riktiga off-grid solcellssystem kvar att införa en meny för reset av statistikdata, två mindre funktioner som behöver en lätt optimering samt att skapa det elektriska informationsutbytet mellan befintlig PWM-regulators driftsmode och batterimonitorn. Så förhållandevis lite kvar :-)
Och även att bygga ett exemplar till av hårdvaran, men det går rätt fort!
Mätningen / utvärderingen av batteriverkningsgrad fungerar bra nu:

Uppmätta verkningsgrader vid grund urladdning 1,5-7% DOD.
Hittade intressant data om nominal float-laddström för AGM-blybatterier hos Float Current Monitoring: a complete overview "Remote monitoring expertise for over four decades", samt även en lista med "Float Current behaviors to monitor"!
A good rule of thumb for VRLA is 10mA of float current for each 100Ah capacity (float at 13,5V).
Vid 13,8V och +25°C gäller enligt dem:
Nominal AGM Float-current = 1.6mA/Ah ±33%, så 160±53mA/100Ah.
Eftersom AGM-blykol har något lägre laddspänning så gäller det nog för lite lägre float-spänning hos dem.
Även hittat en Ultra-High Precision Coulometry för cyklisk mätning / utvärdering av battericeller. What Coulombic Efficiency (CE) measurements mean and how they can be used to quantify cell performance.
Exploring Coulombic Inefficiency Per Hour (CIE/HR): "There´s no denying the usefulness and importance of Coulombic Efficiency. However, when comparing cells cycled under different conditions, to have a direct comparison, there´s a few things that must be considered since cell degradation depends on both time and cycle number. Things like reactions of electrolyte components will occur even if a cell is sitting on a shelf not being cycled.
The time dependence of reactions within a lithium-ion cell are challenging for meaningful comparisons of CE – which measures these reactions – where cycles take a different amount of time to complete; cells with cycles that take more time will experience more reactions per cycles. In this way, CE is understood to be a function of both cycle number and time."
Ger mig en tanke att jag kanske skulle addera till en antagen (uppmätt?) självurladdning för än bättre långtidsstabilitet i mätningen av SOC/Ah-laddnivå i batteribanken? Men utvärderar först från lite testdrift i mitt riktiga off-grid solcellssystem. Jag har inte någon data på blybatteriers cykliska drift från en ultra-precis batterimonitor och ej hittat någon sådan data på Internet.
Båda dessa ger en kvittens på att jag är rätt på det med tankar kring att utvärdera olika dynamiska driftsparametrar för att få en indikation på när något blybatteri i batteribanken börjar få problem i sin batterikemi!
Dels: "Superkondensatorer kombinerat med blybatterier" (vilket man även har integrerat i blykol-batterikemin) som även har en del resonemang kring batteriverkningsgrad och Peukerts effekt.
Dels den jag läste redan för något år sedan och som även refereras till i rapporten ovan, där Trojan djupurladdnings flooded kvalitetsblybatterier cyklas med strömbelastningar aktuella i off-grid solcellssystem (C/30): "A Study of Lead-Acid Battery Efficiency Near Top-of-Charge and the Impact on PV System Design"
Det verkar vanligt att man anger 85% blybatteriverkningsgrad i en batterimonitor men för den typiska cyklingen i ett sunt dimensionerat off-grid solcellssystem blir det ofta signifikant fel enligt dessa rapporter!
"Notice also that the overall efficiency shows high values, with full charge represented by approximately 85% efficiency, a commonly used value for battery charge efficiency. More importantly, notice the dramatically lower efficiencies for the increments above about 80% state of charge, where most values are below 60% efficiency, and full charge is represented by less than 50% efficiency."
Så har man då den typiska grunda blybattericyklingen det blir i ett sunt dimensionerat off-grid solcellssystem så är 85% verkningsgrad på tok för högt för batterimonitorn, som med den då ger felvisning.
Nu tror jag att AGM-blybatterier är något lite bättre än öppna flooded blysyrabatterier på detta, men har inte sett några fakta på det.
Verkningsgraden hos ett blysyrabatteri varierar väldigt mycket beroende på omständigheterna.
Tre viktiga variabler är laddstatus, temperatur och strömbelastning, men även typ av laddning har stor inverkan.
Enligt rapporten ger en grund cykling på 3-4% DOD en blybatteriverkningsgrad (Ah) på 45-50% bara! När jag nu cyklat mitt gamla blykol-startbatteri i mitt lilla experiment solcellssystem med 3-4% DOD har min batterimonitor mätt upp en batteriverkningsgrad (Ah) på 70-73%! Dvs ca 1,55ggr / 55% bättre batteriverkningsgrad!
Sannolikt är det från kombinationen strömpulsad laddning via PWM-regulator (som är förstärkt av mig) samt att det är blykol-batteri. Men jag tror att det är den strömpulsade laddningen som bidrar mest till den bra blybatteriverkningsgraden!
Vid sådan grund blybattericykling ger strömpulsad laddning markant bättre batteriverkningsgrad, så det enligt mina erfarenheter i stort uppväger att PWM-regulatorn inte kan utnyttja de extra 15-25% ström som en MPPT-regulator får ut från solpanelerna under bulk-laddfasen då den typiska battericyklingen sker inom 70-100% SOC i ett off-grid solcellssystem.
Min batterimonitor jag utvecklar som ett hobbyprojekt utvärderar löpande batteriverkningsgraden vid den aktuella cyklingen man har i sitt batterisystem, så inverkan av olika laddstatus, temperatur och strömbelastning samt även laddsätt kommer med från den verkliga driften. På så sätt räknar jag med att kunna få riktigt bra precision i den, samt jag slipper en besvärlig inställning.
De delar av Peukerts effekt som eventuellt påverkar lite även vid cyklisk drift kommer då till stor del med som del av den utvärderade batteriverkningsgraden, så även den slipper jag ha som ett inställningsvärde.
Sedan varierar blybatteriverkningsgraden med hur djupt batteribanken cyklas, så är den utvärderad för rätt grund cykling i bra väder så kommer den inte stämma fullt ut för de mer sällsynta djupa urladdningarna i längre dåligt väder. Men bör ändå bli hyfsat bra, speciellt med tanke på att batteriverkningsgraden blir något högre vid djupare urladdningscykel så man kommer då att ha något större marginaler än batterimonitorn visar. Så utvärdering av batteriverkningsgraden vid grundare cykling kommer aldrig leda till någon kritisk överraskning för driften vid en mer sällsynt djupare urladdning!
I princip skulle man kunna utvärdera den biten också efterhand som ens blybatteribank cyklas olika djupt, men just nu känner jag mig tveksam till om det är värt att kompliceras programkoden med det samt att lägga energi på hur det skulle hanteras.


Batterimonitorn använder två metoder för att synkronisera 100% SOC fulladdat till verkligt fulladdad blybatteribank, dels via tail-current under aktiv float-reglering, dels en annan speciell utvecklad mätmetod bara utifrån sina egna mätdata som blir lite som en reservmetod.
Denna reservmetod är nu testad en tid och fungerar riktigt bra! Ska optimera den lite ytterligare för att bli mer oberoende av batteribankens kapacitet (Ah) samt av hur aktuell drift är. Ger en hög precision i synkningen samt kräver inga inställningar för aktuell installation!
Tail-current metoden behövs fortfarande för att få en mer likartad utvärdering av batteriverkningsgrad, då det är blybatterierna som direkt själva talar om när de precis är 100% SOC fulladdade.
Länkar: 2022-07-17
- How to post JSON data to a HTTP server endpoint [https://] from your ESP32 development board with ArduinoJson
- arduino-esp32/libraries/HTTPClient/
- BVR-M-R001-1.0 - Motstånd, ytmontering 4W, 1mOhm, 1%, Isabellenhütte, (pdf)
- PBV-R001-F1-1.0 - Effektmotstånd 3W 1mOhm 1 %, Isabellenhütte
- BLOCK SHUNT 100A/50MV - Shunt 100 A, 50 mV class 1.0, Fujita
- PWR220T-20-10R0F - Strömavkänningsmotstånd, Bourns, 10Ω, 20W, TO-220
- Mouser: DC-shunt
- NorthStar NSB Blue+ Battery® lead-carbon Application Manual, 100Ah: Exceptional PSoC cyclic performance, Design life 12+ years, Ultra fast recharge (no charge max current limit), Operating temperature range -40°C to +65°C, Impedance (1Khz) 2.6 mΩ, 34kg, har en coulomb-verkningsgrad på 94% - 99,5% angivet, varierande med temperatur och hur djup urladdningen varit - "The higher the DOD and the higher the temperature is the higher this overcharge need to be to fully charge the battery."
Lägre temperatur = högre coulomb-verkningsgrad. - The overall (charge/discharge) coulomb (current*time efficiency) of prismatic LFP batteries is around 99%. From my logged data over a period of around eighteen months I have 99.4%. The overall power efficiency which is a combination of the coulomb efficiency and the voltage efficiency for my battery is around 95%. This matches the figure I have seen in allot of literature on the subject.
- Making Your Battery Monitor More Accurate, Marine How To
- Testing the Balmar SG200 Self-Learning Battery Monitor, Marine How To
- Balmar SG200 Battery Monitor
- Balmar Smartgauge Battery Monitoring Unit, Marine How To
- Balmar Smartgauge™ Battery Monitor
- An effect similar to Peukert´s effect during charging, Smartgauge
- A-BMS – Active Battery Management System (lead-acid)
- Simarine PICO, Redefining Smart Battery Monitors
- TAO Performance: A complete Energy Management System
- TAO Performance: Keeping your LiFePO4 battery healthy Learn about the optimal conditions and a few simple precautions to keep your LiFePO battery healthy for a long life. Med det TAO rekommenderar så har man i princip samma prestanda från LiFePO4 och bra AGM-blykol batterier med bl.a. max laddström ≤0,3C.
Beskrivs även här: Most LiFePO4 manufacturers specify a maximum charge rate of 0.3C. Låter allvarligare att överskrida max laddström för LiFePO4 än för blybatterier!
För AGM-blykol (lead carbon) ser en max laddström på ≤0,5C ut att vara vanligt! - TAO Performance: What reduces the life of a LiFePO4 battery? Never recharge a LiFePO4 cell when it´s voltage as gone below 2.0 volt. It could create an internal short-circuit and a risk of fire. Allowing a LiFePO4 cell to drop below 2.5V will not only damage the cell but it converts the cell into a timebomb.
- TAO Performance: LiFePO4 Charge Cycle Management TAO BMS has a new feature to manage the LiFePO4 charge cycles and extend battery life.
- TAO Performance: New local and Cloud dashboard
- X2 BMS introduces five new BMS technologies
- LiFePO4 - Blybatteri hybrid
- OpenHybridBMS, ESP8266 based. This project was started because I was not satisfied with the commercial Battery Management Systems available.
- OpenHybridBMS Example status webpage via WiFi
- OpenHybridBMS, GitHub
- Lithium (LiFePO4) management - How to keep Lithium cells safe and healthy
- LiFePO4 - Approaching and exceeding the limits
- Studer Innotec: A year of solar autarky
- Studer Innotec: The next3 latest software release allows now the installation of 2 next3 in parallel, with the same or independent batteries ??.
- Studer Innotec Facebook