fbpx

Ostatni wpis na temat OLEDa z SSD1327 zakończyłem na tym, że aby używać biblioteki GFX trzeba wprowadzić do niej kilka modyfikacji. Zajmę się dzisiaj tymi modyfikacjami i będziemy mieli już pełną funkcjonalność naszego wyświetlacza z 16-stopniową skalą szarości. Na koniec sprawdzimy jak wyglądają prędkości, które można osiągnąć na takim OLED z I²C.

Spis treści całego cyklu o OLED na SSD1327:

OLED ze skalą szarości na SSD1327 cz.1
OLED ze skalą szarości na SSD1327 cz.2
Jak przygotować obraz dla wyświetlacza LCD lub TFT?
OLED ze skalą szarości na SSD1327 cz.3

Modyfikacja GFX lib

Biblioteka, którą zaciągnąłem z innego OLED – tego na SSD1306 – współpracuje z obrazami o jednobitowym pikselu. Tam w niej jeszcze było tak napisane rysowanie piksela, że jak miał on kolor tła(które było podawane w argumencie), to mógł nawet go nie rysować tworząc transparentne tło.

No i de facto można było jej używać tak, że obrazek byłby rysowany w jednym kolorze z zakresu 0-15, ale po co nam wtedy taka skala szarości? My chcemy przecież rysować ładne rzeczy. Takie, które będą posiadały głębię oraz na przykład ładnie wyrysują nam GUI, co nie?

Dlatego trzeba leciutko zmodyfikować GFX BW tak, aby obsługiwała nam obrazy zapisane w formacie 4-bitowego piksela. Gdzie te zmiany wprowadzić? Ano właśnie w funkcji rysowania obrazków!

Po pierwsze musimy znaleźć którą komórkę tablicy z obrazem chcemy przypisać do naszego bufora. To już wiesz jak zrobić, bo pisałem o tym w poprzednim wpisie. Jeśli jedziemy po wysokości obrazu jako j, a po szerokości jako i, komórka w tablicy, która nas interesuje to SelectedCell = img[i/2 + j*(w/2)] – w to szerokość obrazu, którą podajemy w argumencie.

Tak jeszcze odbiegając od tematu to fajnie byłoby zmodyfikować rysowanie obrazu tak, że funkcja sama by pobierała wysokość i szerokość z nagłówka obrazka, który tworzy nam Img2Lcd, o którym pisałem w tym wpisie. Może zrobisz fork mojego projektu na GitHub i takie coś napiszesz? 🙂

Wracając do głównego tematu… mając teraz wybraną komórkę musimy przypisać odpowiednią wartość piksela do naszego piksela w buforze RAM dla wyświetlanego obrazu. W jednym bajcie mamy do wyboru tylko dwa piksele. W poprzednim wpisie zauważyliśmy też, że zawsze parzyste są z tej samej strony bajtu. Trzeba to wykorzystać!

Procedura wybrania odpowiedniej wartości piksela i wpisania go do RAMu OLED wygląda tak.

if(i % 2)
{
	SelectedCell &= 0x0F;
}
else
{
	SelectedCell >>= 4;
}
GFX_DrawPixel(x+i, y+j, SelectedCell);

Wygląda prosto, prawda? Tak naprawdę to tyle! Cała funkcja rysowania obrazu na buforze wygląda więc tak.

void GFX_Image(int x, int y, const uint8_t *img, uint8_t w, uint8_t h)
{
	uint8_t i, j;
	uint8_t SelectedCell;

	for(j = 0; j < h; j++)
	{
		for(i = 0; i < w; i++)
		{
			SelectedCell = img[i/2 + j*(w/2)];

			 if(i % 2)
			 {
				 SelectedCell &= 0x0F;
			 }
			 else
			 {
				 SelectedCell >>= 4;
			 }

			GFX_DrawPixel(x+i, y+j, SelectedCell);
		}
	}
}

Zrobiłem jeszcze kilka drobnych zmian jak nazwa biblioteki i tak dalej, aby to ładnie współgrało z tym wyświetlaczem od strony nazewnictwa. Efekt? Piękne obrazki z głębią kolorów 🙂

Jak szybko to działa?

Mamy tutaj o wiele więcej danych niż przy wysłaniu do monochromatycznego wyświetlacza. Nie dość, że rozdzielczość jest delikatnie większa, to jeszcze każdy piksel ma 4x więcej danych. Czy jesteśmy więc uzyskać zadowalające efekty na I²C. W pierwszej części robiłem pewne wyliczenia teoretyczne. Jak to wygląda w praktyce? Już sprawdzam!

Całość na 100 kHz zegarze, czyli przepisanie obrazu zajmującego cały obszar OLED oraz wysłanie tego do kontrolera trwa aż 573 ms. Wieczność!

Rozbijmy to na atomy. Samo przepisanie obrazu z tablicy do bufora OLED to niecałe 23 ms. Lepiej, ale nadal sporo, co nie? Pamiętaj, że to przepisanie wykorzystuje funkcje DrawPixel, a nie jest to ślepe przepisanie komórek. Wprowadza to trochę liczenia, którego pewnie dałoby się częściowo uniknąć.

Wychodzi na to, że wysyłanie jest okrutnie długie co zresztą widać po przebiegach. Trwa ono ok. 550 ms.

Pracując na 100 kHz I²C oznacza to, że nie wyciągniesz więcej niż 2 FPS. Żenada! Przejdźmy na 400 kHz, czyli maks to ten OLED może teoretycznie przyjąć. Powinno być w teorii 4 razy lepiej.

Kopiowanie obrazu + transfer to 182 ms. Wyszłoby jakieś 5,5 FPS. Nadal marnie… Będzie widać przerysowanie przy animacjach pełnokranowych.

Kopiowanie obrazu powinien trwać tyle samo, czyli ~23 ms. W tym zakresie nic nie powinno się zmienić.

Natomiast transfer do OLED to 159 ms.

Możliwości przyśpieszenia.

Można spróbować jeszcze podkręcić I²C. SSD1327 powinien spokojnie chodzić na zegarze 1 MHz tak jak SSD1306. Jednak to już wykracza poza dokumentację, więc jest to takie życie na krawędzi.

O wiele lepszym rozwiązaniem byłoby podłączenie tego samego OLEDa przez SPI. Tam może iść aż 10 MHz! To już nadaje się naprawdę na szybką i niezauważalną podmianę obrazu.

Tylko… mój model nie ma SPI na PCB ani nie umożliwia zmiany interfejsu żadnymi zworkami. Trzeba by szukać takiego OLED w wersji z SPI, a z tym bywa ciężko. Z gotowych na PCB ma chyba tylko Waveshare.

Można zrobić swoje PCB! Wziąć sam moduł OLED i odpowiednio połączyć zworki, aby wybrać SPI. Wiąże się to również z zaprojektowaniem przetwornicy dla zasilania matrycy, więc jest to raczej dla osób bardziej zaawansowanych.

Pozostając przy I²C nie zostaje nic innego niż opracować interfejs, który nie ma szybkich animacji. Nie trzeba przecież zawsze odświeżać wszystkich pikseli, a przerysowanie tych samych nie będzie widoczne.

Innym sposobem może być zrezygnowanie z buforowania i rysowanie jedynie w obszarach, które się zmieniają. W kontrolerze takim można ograniczyć obszar rysowania w kontrolerze, a później już po prostu wysyłać piksele. Możliwości jest całkiem sporo!

Podsumowanie

Przeróbka biblioteki GFX okazała się banalnie prosta! Teraz możesz z łatwością wrzucać piękne obrazy na OLED 😉

Gorzej ma się sprawa z prędkością działania… Musisz niestety ograniczyć się do wolnozmiennej treści. Jednak z tego, co widzę w Internecie to raczej większość projektów ma wolnozmienne GUI 🙂

Jeśli artykuł Ci się spodobał, kup coś u mnie! ? https://sklep.msalamon.pl/

Pełny projekt wraz z biblioteką znajdziesz jak zwykle na moim GitHubie: LINK

Jeśli zauważyłeś jakiś błąd, nie zgadzasz się z czymś, chciałbyś coś dodać istotnego lub po prostu uważasz, że chciałbyś podyskutować na ten temat, napisz komentarz. Pamiętaj, że dyskusja ma być kulturalna i zgodna z zasadami języka polskiego.

Spis treści całego cyklu o OLED na SSD1327:

OLED ze skalą szarości na SSD1327 cz.1
OLED ze skalą szarości na SSD1327 cz.2
Jak przygotować obraz dla wyświetlacza LCD lub TFT?
OLED ze skalą szarości na SSD1327 cz.3

Podobne artykuły

.

1 komentarz

bdgr · 04/09/2020 o 23:44

Z innej beczki: od jakiegoś czasu zacząłem używać sw4stm32 i żeby nie zwariować po przesiadce z każdego innego IDE polecam plugin
https://marketplace.eclipse.org/content/debug-perspective-auto-closer
Z Cube IDE też powinno działać.

Dodaj komentarz

Avatar placeholder

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *