- zakres pomiarowy: 0…8 A,
- praca w systemach o napięciu szyny zasilającej 0…36 V,
- rozdzielczość pomiaru: 1 mA,
- dokładność pomiaru: 1% (zależna od klasy dokładności zastosowanego bocznika)
- zakres ustawień dla funkcji alarmowania: 0…10 A,
- rozdzielczość ustawień dla funkcji alarmowania: 1 mA,
- częstotliwość odświeżania ekranu: 10 razy/sek.,
- zasilanie: 4,5…10 V/10 mA.
W urządzeniu zastosowano specjalizowany układ przeznaczony do pomiaru prądu, napięcia i mocy urządzeń zasilanych napięciem stałym. Jest to element dość wyjątkowy, warto choćby skrótowo zaznajomić się z jego specyfikacją. Układ INA226, produkcji firmy Texas Instruments, jest specjalizowanym, bardzo dokładnym, 16-bitowym, różnicowym przetwornikiem pomiarowym ADC przeznaczonym do zastosowania w układach pomiaru prądu i mocy z wykorzystaniem bocznika rezystancyjnego. Układ ten wyróżnia się następującymi, wybranymi cechami użytkowymi:
- szeroki zakres napięć zasilania 2,7...5,5 V,
- bardzo duża dokładność pomiaru rzędu 0,1%,
- możliwość pracy w systemach o szerokim zakresie napięć szyny zasilającej 0…36 V,
- możliwość pracy w konfiguracji Low-side i High-side,
- bezpośredni pomiar napięcia, prądu i mocy,
- konfigurowalny czas przetwarzania wbudowanego przetwornika ADC,
- konfigurowalna funkcja uśredniania pomiarów,
- dwa tryby pracy wbudowanego przetwornika ADC: ciągły i wyzwalany na żądanie,
- możliwość alarmowania po przekroczeniu zadanego poziomu prądu, napięcia szyny zasilającej odbiornik bądź mocy pobieranej przez odbiornik.
Układ INA226 idealnie wpisuje się w wymagania naszej aplikacji oferując niespotykaną dotąd funkcjonalność i dokładność pomiarów. Schemat blokowy tego peryferium pokazano na rysunku 1.
Budowa i działanie
Schemat ideowy urządzenia pokazano na rysunku 2. Zaprojektowano bardzo prosty system mikroprocesorowy, którego „sercem” jest niewielki mikrokontroler firmy Microchip (dawniej Atmel) typu ATtiny44, odpowiedzialny za programową implementację interfejsu I2C, przy użyciu którego mikrokontroler realizuje obsługę układu INA226 oraz obsługę niewielkiego acz bardzo efektownego wyświetlacza OLED o rozdzielczości 128×32 piksele stanowiącego element graficznego interfejsu użytkownika. Wspomniany wcześniej, specjalizowany przetwornik ADC mierzy spadek napięcia na rezystorze szeregowym R1 (10 mΩ), dzięki czemu możliwe jest wyznaczenie prądu pobieranego przez badane urządzenie.
Układ INA226 dokonuje ciągłego (lub wyzwalanego manualnie przez aplikację użytkownika) pomiaru dwóch wartości napięć: napięcia szyny zasilającej odbiornik (VBUS) oraz napięcia na zaciskach bocznika rezystancyjnego (VSHUNT) włączonego w szereg z odbiornikiem. Na podstawie tych dwóch wielkości i zawartości rejestru konfiguracyjnego CALIBRATION (którego wartość zależy od wymaganej rozdzielczości pomiaru i parametrów zastosowanego bocznika rezystancyjnego) układ oblicza następujące wielkości elektryczne: prąd oraz moc pobieraną przez odbiornik i udostępnia je aplikacji użytkownika ładując obliczone wielkości do stosownych rejestrów konfiguracyjnych jak również ustawiając dedykowane flagi zakończenia konwersji.
Ponadto, dzięki wyposażeniu go w grupę specjalnych rejestrów konfiguracyjnych odpowiedzialnych za porównywanie zmierzonych i obliczonych wartości z wartościami progowymi, jak również dedykowane wyprowadzenie oznaczone jako ALERT, umożliwia generowanie alarmów po przekroczeniu zdefiniowanych przez użytkownika progów dotyczących: napięcia szyny zasilającej, napięcia na boczniku pomiarowym i mocy pobieranej przez odbiornik.
Producent tego peryferium wyposażył je w możliwość niezależnej konfiguracji czasu przetwarzania przetwornika ADC, oddzielnie dla napięcia szyny zasilającej i napięcia bocznika rezystancyjnego, jak również możliwość uśredniania pomiarów tychże wielkości spośród wielu, kolejnych pomiarów. Dzięki takiemu podejściu zwiększono wydatnie funkcjonalność użytkową układu i możliwość dostosowania trybu jego pracy do wymagań konkretnej aplikacji. Należy jedynie pamiętać, że wydłużenie czasu przetwarzania wbudowanego przetwornika ADC wydatnie zwiększa uzyskaną dokładność pomiaru, zaś uśrednianie większej liczby próbek zdecydowanie polepsza odstęp sygnału od szumu, w związku z czym w rzeczywistych aplikacjach należy dobierać maksymalne i możliwe do zaakceptowania wartości tychże parametrów kierując się dla przykładu szybkością zmian badanych przebiegów, jako kryterium wyjściowym.
Aby poznać wszystkie możliwości „drzemiące” w układzie INA226 należałoby sięgnąć do jego noty aplikacyjnej lub do… mojego artykułu prezentującego urządzenie USBtester opublikowanego na łamach naszego miesięcznika w maju 2019 roku, gdzie szczegółowo omawiam wszelkie zagadnienia implementacyjne, więc nie będę ich powielał w tym miejscu, tym bardziej że jest to dość obszerna lektura.
Kilka słów uwagi poświęcę natomiast programowej implementacji interfejsu I2C, dzięki któremu mikrokontroler współpracuje z układem INA226 (jak i wyświetlaczem OLED). Wykorzystałem programową implementację wspomnianego sprzęgu z dwóch powodów.
Po pierwsze, mikrokontroler ATtiny44 nie został wyposażony przez producenta w pełnoprawny kontroler interfejsu I2C (w tym wypadku TWI – Two Wire Interface), lecz tylko w jego uproszczoną wersję o nazwie USI (Uniwersal Serial Interface), która nie zapewnia całkowicie sprzętowego wsparcia medium transmisyjnego przez co w moim przekonaniu programowa implementacja jest w pełni uzasadniona i na dodatek prostsza. Po drugie w przypadku programowego wsparcia interfejsu I2C do wyboru mamy dowolne piny mikrokontrolera, co ułatwia zaprojektowanie obwodu drukowanego urządzenia. Z tych właśnie powodów zdecydowałem się zaimplementować sprzęg I2C na drodze czysto programowej. Inną sprawą jest fakt, że tego typu implementacja jest bardzo prosta, gdyż wspomniane medium transmisyjne jest dobrze udokumentowane i proste w swoich założeniach. Co istotne, nie będę w tym miejscu opisywał wszystkich, szczegółowych cech standardu, gdyż łatwo znaleźć stosowne informacje w sieci a skupię się jedynie na mojej, uproszczonej acz wystarczającej implementacji programowej.
#define I2C_BUS_FREQ 400000
#define SDA_PORT_REG PORTA
#define SDA_PIN_REG PINA
#define SDA_DDR_REG DDRA
#define SDA_PIN_NR PA6
#define SCL_PORT_REG PORTA
#define SCL_PIN_REG PINA
#define SCL_DDR_REG DDRA
#define SCL_PIN_NR PA4
#define SDA_LOW SDA_PORT_REG &= ~(1<<SDA_PIN_NR)
#define SDA_HIGH SDA_PORT_REG |= (1<<SDA_PIN_NR)
#define SDA_AS_INPUT SDA_DDR_REG &= ~(1<<SDA_PIN_NR)
#define SDA_AS_OUTPUT SDA_DDR_REG |= (1<<SDA_PIN_NR)
#define SDA_IS_LOW (!(SDA_PIN_REG & (1<<SDA_PIN_NR)))
#define SCL_LOW SCL_PORT_REG &= ~(1<<SCL_PIN_NR)
#define SCL_HIGH SCL_PORT_REG |= (1<<SCL_PIN_NR)
#define SCL_AS_INPUT SCL_DDR_REG &= ~(1<<SCL_PIN_NR)
#define SCL_AS_OUTPUT SCL_DDR_REG |= (1<<SCL_PIN_NR)
#define SCL_IS_LOW (!(SCL_PIN_REG & (1<<SCL_PIN_NR)))
#define CLK_BITWAIT (F_CPU/I2C_BUS_FREQ/2)
#define NACK 0
#define ACK 1
Plik nagłówkowy implementacji definiujący wszystkie, niezbędne cechy sprzętowe pokazano na listingu 1. Na listingu 2 pokazano z kolei prostą funkcję inicjującą porty magistrali I2C, której zadaniem jest ustawienie stanów spoczynkowych.
void i2cInit(void){
//Porty SDA i SCL
//jako wyjściowe ze stanem 1
SDA_HIGH;
SCL_HIGH;
SDA_AS_OUTPUT;
SCL_AS_OUTPUT;
}
Dwie, podstawowe funkcje standardu I2C generujące sygnał Start i Stop, pokazano na listingach 3 i 4.
void i2cStart(void){
//Generujemy sygnał START: SDA z 1 na 0
//w czasie gdy SCL=1
SDA_LOW;
_delay_us(CLK_BITWAIT);
//SCL z 1 na 0 - przygotowanie do transmisji
SCL_LOW;
_delay_us(CLK_BITWAIT);
}
void i2cStop(void){
//Generujemy sygnał STOP:
//SDA z 0 na 1, w czasie gdy SCL=1
SDA_LOW;
_delay_us(CLK_BITWAIT);
SCL_HIGH;
_delay_us(CLK_BITWAIT);
SDA_HIGH;
_delay_us(CLK_BITWAIT);
}
Na listingach 5 i 6 pokazano kolejne, dwie proste funkcje umożliwiające wysłanie i odebranie bajta na magistrali I2C. Funkcja wysyłająca, jako rezultat swojego działania zwraca wartość bitu potwierdzenia po stronie odbiornika danych (w tym przypadku układu Slave), zaś funkcja pozwalająca na odbiór bajta przyjmuje, jako argument wywołania wartość bitu potwierdzenia po stronie odbiornika danych (w tym przypadku układu Master).
uint8_t i2cWriteByte(uint8_t Byte){
uint8_t Ack;
for(uint8_t i=0; i<8; ++i){
//SCL jest w stanie niskim
if(Byte & 0x80) SDA_HIGH; else SDA_LOW;
Byte <<= 1;
//Układ Slave zatrzaskuje bieżący bit
SCL_HIGH;
//Obsługa „clock stretching”
SCL_AS_INPUT;
//Czekamy, aż Slave zwolni szynę zegara
while(SCL_IS_LOW);
SCL_AS_OUTPUT;
_delay_us(CLK_BITWAIT);
SCL_LOW;
_delay_us(CLK_BITWAIT);
}
//Odczytujemy 9. bit
//potwierdzenia z układu Slave
SDA_HIGH;
SDA_AS_INPUT;
SCL_HIGH;
_delay_us(CLK_BITWAIT);
Ack = (SDA_PIN_REG & (1<<SDA_PIN_NR))>>SDA_PIN_NR;
SCL_LOW;
_delay_us(CLK_BITWAIT);
SDA_AS_OUTPUT;
return Ack;
}
uint8_t i2cReadByte(uint8_t Ack){
uint8_t Byte = 0;
SDA_HIGH;
SDA_AS_INPUT;
for(uint8_t i=0; i<8; ++i) {
Byte <<= 1;
SCL_HIGH;
//Obsługa „clock stretching”
SCL_AS_INPUT;
//Czekamy, aż Slave zwolni szynę zegara
while(SCL_IS_LOW);
SCL_AS_OUTPUT;
_delay_us(CLK_BITWAIT);
if(!SDA_IS_LOW) Byte++;
SCL_LOW;
_delay_us(CLK_BITWAIT);
}
//Transmitujemy 9-ty bit Ack
SDA_AS_OUTPUT;
if(Ack) SDA_LOW; else SDA_HIGH;
SCL_HIGH;
_delay_us(CLK_BITWAIT);
SCL_LOW;
_delay_us(CLK_BITWAIT);
SDA_HIGH;
return Byte;
}
Urządzenie wyposażono w niewielki acz efektowny wyświetlacz OLED, którego obsługę mikrokontroler realizuje także dzięki programowej implementacji interfejsu I2C. Powodem wybrania tego typu wyświetlacza jest jego doskonała widoczność nawet w warunkach światła słonecznego jak i bardzo atrakcyjna cena. W tym momencie, podobnie jak poprzednio, po szczegóły implementacyjne dotyczące tegoż peryferium odsyłam ponownie do wspomnianego wcześniej artykułu, gdzie drobiazgowo opisano zagadnienia programowe związane z obsługą tego rodzaju wyświetlacza OLED.
Montaż i uruchomienie
Schemat montażowy naszego urządzenia pokazano na rysunku 3. Zaprojektowano bardzo „zgrabną”, dwustronną, niewielką płytkę drukowaną, która swoim rozmiarem jest zbliżona do zastosowanego wyświetlacza OLED udostępniając dodatkowo niezbędne otwory montażowe. Warto również podkreślić, iż dla zminimalizowania rozmiaru obwodu drukowanego przewidziano tutaj montaż elementów po obu stronach laminatu. Aplikację urządzenia rozpoczynamy od przylutowania układu INA226. Najprostszym sposobem montażu elementów o tak dużym zagęszczeniu wyprowadzeń, niewymagającym jednocześnie posiadania specjalistycznego sprzętu, jest użycie zwykłej stacji lutowniczej, dobrej jakości cyny z odpowiednią ilością topnika oraz dość cienkiej plecionki rozlutowniczej, która umożliwi usunięcie nadmiaru cyny spomiędzy wyprowadzeń układu. Należy przy tym uważać by nie uszkodzić termicznie tegoż elementu.
Dalej lutujemy pozostałe elementy półprzewodnikowe, potem rezystory i kondensatory jak i inne elementy bierne, a na końcu mikroprzełączniki PLUS i MINUS, buzzer piezoelektryczny oraz gniazdo podłączeniowe LOAD. Z uwagi na zagęszczenie wyprowadzeń układów scalonych przed pierwszym podłączeniem układu do zasilania należy jeszcze raz sprawdzić jakość wykonanych połączeń, aby nie dopuścić do ewentualnych zwarć. Wspomniana kontrola będzie znacznie łatwiejsza, jeśli zmontowaną płytkę przemyjemy alkoholem izopropylowym w celu wypłukania nadmiaru kalafonii lutowniczej. Na samym końcu montujemy wyświetlacz OLED, lutując jego wyprowadzenia w przeznaczone do tego celu pola lutownicze (należy sprawdzić polaryzację zasilania), gdyż połączenia elektryczne zapewniają mu jednocześnie wystarczająco stabilny montaż mechaniczny. Poprawnie zmontowany układ powinien działać tuż po włączeniu zasilania. Na fotografii 1 pokazano zmontowane urządzenie (od strony TOP) przed przylutowaniem wyświetlacza OLED.
Obsługa
Po włączeniu zasilania (zaciski +/– na obwodzie drukowanym) urządzenie pracuje w trybie pokazywania wartości mierzonego prądu (rozdzielczość 1 mA), przy czym ekran w tym trybie odświeżany jest 10 razy na sekundę. Każdorazowe wciśnięcie klawiszy PLUS/MINUS powoduje chwilowe (2 s) przełączenie urządzenia w tryb pokazywania wartości alarmu dla mierzonego prądu co symbolizowane jest poprzez wyświetlenie symbolu dzwoneczka po lewej stronie wartości prądu. W trybie tym, krótkie naciśnięcie wspomnianych klawiszy powoduje każdorazową regulację wartości prądu alarmowania o 1 mA, długie naciśnięcie o 10 mA, zaś naciśnięcie i przytrzymanie o 100 mA. Ustawiona wartość progu alarmowania zapamiętywana jest każdorazowo w nieulotnej pamięci EEPROM mikrokontrolera i wczytywana podczas włączania urządzenia. Przekroczenie ustawionej wartości alarmowania (a dokładnie jej wartości bezwzględnej) przez mierzony prąd powoduje generowanie pojedynczych dźwięków poprzez wbudowany buzzer piezoelektryczny. Wygląd graficznego interfejsu użytkownika urządzenia Ampera pokazano na rysunku rysunku 4.
Robert Wołgajew, EP
- CKSEL3...0: 0010
- SUT1...0: 10
- CKDIV8: 0
- CKOUT: 1
- DWEN: 1
- EESAVE: 0
- R1: pomiarowy 10 mΩ 1 W 1% SMD2010
- R2, R3: 4,7 kΩ SMD 0805
- C1…C3: ceramiczny X7R 100 nF SMD 0805
- C4: ceramiczny X7R 1 μF SMD 0805
- U1: ATtiny44 (SOIC14)
- U2: INA226A (MSOP-10)
- U3: TS9011SCX (SOT23)
- OLED: wyświetlacz OLED 128×32 px, 0,91”, SSD1306, magistrala I2C, wymiary 38×12 mm
- PLUS, MINUS: mikroprzełącznik SMD typu DTSM31NB
- BUZZ: przetwornik piezoelektryczny typu LPT9018BS-HL-03-4.0-12-R
- LOAD: złącze śrubowe AK500/2