NordicOffGrid´ Logo
Off-grid solcellssystem.
I Nordiskt klimat!
 by Bosse
By AutonomTech.se Frittliv webbplats

 Webbsidan är senast uppdaterad:  

PWM-solladd­regulator

Anpassad för Nordiskt kli­mat & sol­energi

Skapad: 2022-06-02

Det Nordiska klimatet med korta dagar av dagsljus runt midvinter och perioder med låg solinstrålning ställer lite speciella krav på en solladdregulator för att ge ett välfungerande standalone off-grid solcellssystem. Speciellt ihop med blybatterier, men även med LiFePO4.
Beskrivet här som Nordisk solladd­regulator.
Ska bli en hybrid av PWM-regulator och batterimonitor integrerade ihop.
Batterimonitor-delen har en egen webbsida: BatteriMonitor
Kommer uppdatera här efterhand som jag utvecklar regulatorn.

Projektsammanfattning:

PWM-regulatorn kommer byggas kring en ESP32 som kodas i C/C++ ovanpå FreeRTOS, med ström- / effekt-sensorerna INA260 / INA226 samt med Olimex Shield-LCD 16x2.
Kommer koda ESP32-projektet med framework-arduinoespressif32 då det ger stöd för många bibliotek till sensorer, LCD-display, etc samt i sig är byggt på FreeRTOS så blir ingen extra overhead med det, samt koda med IDE PlatformIO i VSCode.
Övrig elektronikhårdvara utvecklar och konstruerar jag själv.

Utvärdering av FreeRTOS´s möjligheter och funktion på ESP32:

Har läst på om FreeRTOS samt kodat lite experimentellt i en WeMOS ESP32 för att testa, lära och få insikt i möjligheterna med FreeRTOS. Känns superbra för vad jag vill kunna uppnå!
2022-05-30
Lite testande av flera Task i båda kärnorna, med olika prioritet, med styrd exekveringsfrekvens samt med Mutex-låsning vid användning av gemensamma systemresurser:
Kör nu tre Task parallellt multitaskande på två olika kärnor där alla tre skriver till Serial.print(). De får då begära tillgång till Serial.print() och via Mutex låsa den för sin skrivning och sedan släppa den fri igen så en annan Task som kanske väntar på sin tur kan låsa den och skriva sitt. Fungera otroligt bra!
Den ena Task har jag satt till att exekvera 1ggr/1000ms via vTaskDelayUntil(), vilket styrs med en upplösning på ±1ms! Funkar också otroligt bra. Kan bli några ms fördröjning då den väntar på sin tur att kunna få skriva till Serial.print(), men när inte det påverkar så blir det i regel 1000±1ms här. Är extremt användbart!

Tänker ha en Task som uppdaterar LCD-displayen 1ggr/1000ms med låg prioritet, en Task som läser av knapparna på displaymodulen 1ggr/200ms samt en Task för solladdregulatorns reglerloop som troligen får exekvera 1ggr/200ms med lite högre prioritet så den får lite högre precision i det. Samt en Task som hämtar tiden från Internet 1ggr/dygn och synkar den interna RTC från en NTP Client-Server på Internet. Och en Task som sköter webbservern och webbsidan med driftsdata för PWM-regulatorn för lokal visning via wifi.
Och säkert någon mer Task.
Kräver bara så lite kod att få till så avancerad funktion i koden med hjälp av FreeRTOS funktionalitet, så känns riktigt häftigt Kodar då i VSCode med PlatformIO, vilket är väldigt trevligt och smidigt!
Och framework-arduinoespressif32 är byggt på FreeRTOS, så blir ingen extra overhead att använda FreeRTOS i min kod.

Exempel på utskrift via Serial.print() från den Task som exekverar 1ggr/1000ms:
Core0TaskTimed_Begin_ZZZZZZZZZZZZZZZZZZZZZZZZZ
Task0 looptime xTaskDelayUntil(1000) (ms): 1000
Task running on core 0
Today date / time: 2022-05-30 14:04:47
Task0 looptime within Serial.print() (ms): 1000
xWasDelayed: 1
Core0TaskTimed_End_ZZZZZZZZZZZZZZZZZZZZZZZZZZZ

Har nu följt den loggade looptiden (TaskDelayUntil-tid) för den Task som exekverar 1ggr/1000ms via vTaskDelayUntil() en hel del och är imponerande med vilken precision det sker.
De allra flesta hamnar på en looptid på exakt 1000ms!
När inte den rätt glesa väntan på att tillgången till Serial.print släpps fri via Mutex från annan Task fördröjer så hamnar uppskattningsvis minst 95% av gångerna på 1000ms och övriga på 999ms!
Ser även att den något högre prioritet (5) jag gav denna Task verkligen prioriterar den före en annan Task med lägre prioritet (3) som arbetar snarlikt men med vTaskDelay() istället.
Skapar väldigt bra och kodmässigt enkla möjligheter för mig att realisera den avancerade funktion jag planerar att uppnå i min ESP32 PWM-solladdregulator.

2022-06-02
Kodade in en 4:e Task som pinnades till kärna 1 med vTaskDelayUntil() 200ms, så nu är det 4 Tasks som körs multitaskande parallellt, två på vardera kärna. På kärna 1 körs även main Task, Arduinos loop(), där det mesta görs med mycket Serial.print() som belastar. Koden består av 619 kodrader.
I denna 4:e Task skriver jag bara var 20:e exekvering till Serial.print() för att få bra statistik på hur exakt vTaskDelayUntil() arbetar utan att störas för mycket på att vänta in ledig Serial.print(), så även kodat en statistikdel där.
Fick följande statistik för med vilka tidsmellanrum denna Task exekveras under ca 13000ggr, för två olika prioritet för den (prioritet 1, 3 & 5 hos övriga Task):
Resultat: Min 198ms, Max 221ms, 199ms 225(1%), 200ms 13695(98%), 201ms 9(0%), Priority 7 of the task.
Resultat: Min 0ms, Max 729ms, 199ms 394(3%), 200ms 12437(96%), 201ms 68(0%), Priority 1 of the task samma som Arduino loop().
Man ser tydligt skillnaden en högre prioritet gör, där prioritet 7 ger som resultat att denna 4:e Task´s tidsmellanrum för exekvering blir 200ms i 98% av fallen, 199ms i 1% samt övriga tider mellan 198-221ms i 1% av fallen, där sannolikt omkring 221ms dominerar som en fördröjning i väntan på att få tillgång till Serial.print(). Är intressant och imponerande tycker jag!
FreeRTOS tillför verkligen en väldigt värdefull funktionalitet för kodandet av mina ESP32-projekt, som samtidigt är lätt greppbar att utnyttja i koden!

Blockschema över kodens funktion i ESP32:

2022-06-02
Ett första utkast till blockschema över kodens uppbyggnad i ESP32, baserad på FreeRTOS:
Se även info om Inter-Task Communication, Deferred interrupt samt vTaskDelayUntil().

Code flow-schart
ESP32 kod blockschema - första utkast 2022-06-02



Xxxx:

SOC = State Of Charge, laddningsstatus
DOD = Depth Of Discharge, urladdningsdjup
Solcellsström vid svagt ljus är ett viktig tillskott!
Webpage: server time: 93.7 ms, (incl. log: 73.1 ms) ||