Individální projekty MPOA

Mikroprocesory s architekturou ARM

Uživatelské nástroje

Nástroje pro tento web


2019:accu-monitor

Monitor napětí

Vypracoval: Milan Ambrož

Zadání

Navrhněte hardware a firmware pro zařízení, které bude monitorovat napětí na dvojici čtyř sériově zapojených olověných akumulátorů. Využijte AD převodník, hodnoty napětí jednotlivých akumulátorů vypisujte na sériovou linku po příchodu impulzu na vstupní pin. Dále indikujte stav článků pomocí LED. Využijte mikrokontrolér STM32F030K6T6


Úvod

Jedná se o zařízení, modul, který slouží k monitorování napětí akumulátorů v solární elektrárně, případně kdekoliv jinde, kde je to vhodné.

Při návrhu bylo dbáno na maximální využití potenciálu zařízení, proto je zde možnost osadit deset analogových vstupů, komunikaci pomocí sběrnice RS485 a napájení i komunikace jsou galvanicky odděleny.

Software je navrhnut pro základní měření akumulátorů, viz zadání, kdy změřená napětí se odesílají po přijetí definovaného slova. Původní návrh odesílání pomocí impulzu byl vylepšen zejména z důvodu, že je možné poté vyčíst vícero hodnot včetně surových dat.

Hardware

Napájení je řešeno pomocí izolovaného zdroje z 12V na 5V. Napětí 5V je následně vyfiltrováno a stabilizováno lineárním stabilizátorem na 3,3V, kterým se dále napájí mikroprocesor. Toto řešení odstraňuje problém vzniku zemní smyčky mezi GND napájení a GND měřených akumulátorů.

Komunikace je připravena pro montáž převodníku UART- RS485, který není nutné osazovat. Toto bylo zvoleno z důvodu, kdyby bylo potřeba komunikovat po této sběrnici. Rovněž je UART opticky oddělen pomocí dvojitých digitálních optočlenů, které umožnují jak 3,3V logickou úroveň, tak 5V.

Při použití samostatné komunikace je třeba přepojit drátovýma propojkama piny pro osazení převodníku RS485. Napájení musí být připojeno vždy, protože optočleny jsou napájené.

Protože mikroprocesor zvládne měřit pouze napětí do velikosti napájecího (3,3V). z tohoto důvodu jsou zařazeny před jednotlivé vstupy děliče napětí. Tyto děliče je potřeba vypočítat pro maximální hladinu napětí, které budeme měřit. Zároveň je třeba brát v potaz rozlišení AD převodníku, 12 bitů, nebo taktéž 4096 stavů.

Při výpočtu děliče je důležité brát v potaz maximální impedanci děliče z pohledu analogového vstupu. U tohoto mikroprocesoru, kde je AD převodník vybavený vzorkovacím kondenzátorem je impedance závislá na vzorkovací frekvenci. Pro nejpomalejší vzorkování mi bylo doporučeno použít rezistor 33k. Dále je tento rezistor blokován kondenzíátorem, což opět snižuje impedanci v případě vzorkování.

Pro rezistor 33k a maximálnímu měřenému napětí 3,3V odpovídá poměr 10k na 1V. Pokud vybereme tedy druhý rezistor děliče 560k, máme na něm úbytek 56V. Celkem tedy 59,3V. Toto je napětí, které lze maximálně měřit a odpovídá to napětí 14,825V na jeden akumulátor, což je příliš vysoké napětí. Maximální provozní napětí akumulátoru je 14,4V, což odpovídá při čtyřech zapojených v sérii 57,6V.

Maximální rozlišení poté bude 59,3V / 4096 = 14,5mV. Toto rozlišení plně postačuje pro monitoring olověného akumulátoru, kde postačí měření na stovky milivoltů.

Hodnota filtračních kondenzátorů pro napěťové děliče je možná příliš vysoká, ale vzhledem ke kapacitě měřených akumulátorů (200Ah) nevadí velké zpoždění reakce na změnu. Kapacita byla zvolena jednotná pro celé zapojení

Při návrhu schematu je třeba nezapomenout na nutnost programovacího rozhraní a dané piny vyvést a hlavně nepoužít k jinému účelu.


Kompletní schema zapojení:


DPS byla navrhnuta tak, aby bylo možné jej vyrobit i základní přesností domácí výroby, mezery i spoje minimálně 0,3mm a mezera GND polygonu 0,6mm. Místy je mezera menší jak 0,3mm, spoje pod rezistory, ale zde je možné případnou nedokonalost opravit proškrábnutím.

Izolační schopnost návrhu DPS je převážně z důvodu eliminace zemních smyček. Pokud by bylo potřeba většího rozdílu potenciálů GND akumulátoru, GND napájení a komunikační linky, bude nutné návrh DPS přepracovat.


Navržená DPS:


Firmware

Celý program byl vytvořen v prostředí STM32CubeIDE, což je nástroj, který poskytuje výrobce mikroprocesoru.

Program je napsán pro vývojovou desku Nucleo-F030R8. Označení pinů odpovídá označení ve schematu, pouze z důvodu obsazení pinů PA2, PA3, PA5, PF0, PF1 HW periferiemi vývojového kitu, jsou využity alternativní piny portu C.

Komunikace

Komunikace s nadřazeným zařízením je pomocí třech základních příkazů:

změření napětí akumulátorů

Pokud do zařízení odešleme příkaz „aku“, okamžitě nám odpoví mikroprocesor výpisem hodnot napětí jednotlivých akumulátorů v milivoltech s jedním desetinným místem. Před hodnotou je uvedeno, o který akumulátor se jedná. Poslední dva vstupy se taktéž odesílají.

změření napětí vstupů

Příkazem „voltage“ naopak vyžádáme zaslání jednotlivých napětí, které mikroprocesor měří na daných deseti vstupech v milivoltech s jedním desetinným místem

vyčtení hodnot AD převodníku

Posledním příkazem je „adcvalues“. Tento příkaz je následován odesláním surových nezpracovaných dat AD převodníku a kalibrační konstantou napěťové reference.

Popis funkce Softwaru

Program je inspirován počítačovým cvičením předmětu MPOA, CV 10, kde je použita kostra komunikace prostřednictvím sériové linky. příjem znaků je proveden pomocí DMA a kruhového bufferu, kde se kontroluje přijetí znaku, tyto znaky se převedou do řetězce a následně porovnají, zdali není nalezen požadovaný příkaz. Pokud ano, ihned se vykoná.

Analogově-digitální převodník pracuje v automatickém režimu měření deseti kanálů a referenčního zdroje napětí. Změřené hodnoty jsou opět pomocí DMA zapisovány do pole hodnot „adcvalue“ AD převodník mikroprocesoru STM32 funguje tak, že při konfiguraci zvolíme, které vstupy chceme měřit a ty se měří cyklicky za sebou. Vše se děje automaticky, není potřeba ručně volit, který vstup se má změřit. vždy pokračuje na další. Jako poslední se měří vnitřní napěťová reference. Z této reference se pomocí kalibrační hodnoty, kterou do mikroprocesoru pevně nahrál výrobce, se vypočítá aktuální napájecí napětí AD převodníku. Toto napětí posléze slouží jako referenční napětí pro AD převod měřených hodnot. Tento přepočet je prováděn pomocí proměnných typu float z důvodu, že zde vychází velká čísla a výsledek dělení je desetinný. Mikroprocesor ale i s float proměnnými počítá velmi rychle, narozdíl od osmibitových mikroprocesorů. V následující ukázce kódu se vypíše na sériovou linku napětí prvního akumulátoru:

uint16_t VREFINT_CAL = (*(uint16_t*)0x1FFFF7BA);
 
printf("aku A1: %.1f mV\n\r", divider * ((float)3300 * (float)VREFINT_CAL * (float)adcvalue[9]) / ((float)adcvalue[10] * (float)4095));

Vypočtená hodnota se rovněž násobí konstantou „divider“, což je dělící poměr napěťového děliče. Pro druhý až čtvrtý akumulátor je napětí na něm vždy rozdílem ku napětí předchozího. Proto je ve výpočtu zahrnut rouzdíl jednotlivých kanálů:

printf("aku A2: %.1f mV\n\r", divider * ((float)3300 * (float)VREFINT_CAL * ((float)adcvalue[8] - (float)adcvalue[9])) / ((float)adcvalue[10] * (float)4095));

Na první pohled by se mohlo zdát, že se jedná o chybu, ale vzhledem k potřebám návrhu DPS jsou reálně číslovány vstupy opačně oproti číslování kanálů ADC. Z tohoto důvodu je první měřený vstup devátý kanál ADC.

V poslední řadě se v hlavní nekonečné smyčce programu kontroluje, zdali napětí některého z akumulátorů nevybočuje z pevně nastavených mezí. V tomto případě se rozsvítí indikační LED pro daný akumulátor.

Na začátku kódu jsou definovány hodnoty jak děliče, tak mezních napětí:

#define divider 23.0
#define max_voltage	14200.0
#define min_voltage	11000.0
 
#define max_volt	max_voltage/divider
#define min_volt	min_voltage/divider

Protože indikace stavu akumulátorů není tak důležitá, tak se převodní konstanta pro výpočet napětí počítá pouze na začátku. Jedná se o přepracování vzorců a výsledkem je hodnota napětí odpovídající LSB.

// get calibration value for int. Vref
uint16_t VREFINT_CAL = (*(uint16_t*)0x1FFFF7BA);
 
// calculate voltage for LSB from int. Vref
float ADCconst = ((float)3300 * (float)VREFINT_CAL) / ((float)adcvalue[10])/(float)4095;

Následně se testuje, zdali je napětí v toleranci, či nikoliv. Dle toho se rozsvítí příslušná LED.

// SET LED for aku 1
if( ((((float)adcvalue[9])*ADCconst) < min_volt ) || ((((float)adcvalue[9])*ADCconst) > max_volt ))
{
  HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);
}
else
{
  HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);
}

Toto se následně provede pro zbylých sedm vstupů

Celý kód je psán pouze do hlavního souboru main.c, další soubory projektu nejsou modifikovány.

Závěr

Při výrobě DPS v domácích podmínkách se mi nepodařilo vyvolat kvalitní předlohu pro výrobu, pravděpodobně mám už staré zásoby fotocitlivého kuprextitu a z tohoto důvodu jsem sestavil zařízení pomocí vývojového kitu a nepájivého pole.

Při výrobě finálního výrobku je také třeba v programu změnit hodnotu dělícího poměru, aktuální hodnota je vztažená k děliči 680k/33k, protože dané rezistory byly k dispozici ve vývodovém pouzdru.

Funkce SW byla otestována na nepájivém kontaktním poli a pracuje spolehlivě. Na ukázkách jsou sice využity čtyři vstupy, ale postupně byly ověřeny všechny vstupy.

Zbylé dva kanály a dvě nevyužité LED jsou plánovány pro rozšíření funkce. Pomocí dvou kanálů budou měřena napětí obvodu 24V a 12V, ze kterého se napájí osvětlení. LED budou indikovat správnost těchto napětí.

Další užitečné rozšíření bude aplikace jednoduchého filtru výstupu AD převodníku. Ačkoliv jsou vstupy filtrovány, tak příležitostně je změřena špatná hodnota, pravděpodobně vlivem rušení. Tato chyba se ale může vyskytovat taktéž z důvodu dlouhých přívodů a sestavení na nepájivém kontaktním poli.

ZIP archiv se schematem a PCB v SW Eagle a zdrojovými kódy: mereni_solar_nucleo.zip

Krátké video demonstrující funkci: https://youtu.be/7ZXOgswnDS0

Zdroje

2019/accu-monitor.txt · Poslední úprava: 2020/01/19 22:17 autor: Milan Ambrož