Lopaka Basics 05: Z przeglądarki na płytkę

Narysowałeś ekran, wgrałeś kod, a wyświetlacz pozostaje czarny. Wyświetlacz rzadko jest zepsuty. Zazwyczaj chodzi o jedną z pięciu rzeczy, a gdy naprawisz właściwą, ekran się zapala.
W tym odcinku przeniesiesz poranny pulpit z odcinka 2 z przeglądarki na płytkę: zainstalujesz bibliotekę w Arduino IDE, zbudujesz szkic wokół kodu Lopaka i sprawdzisz, ile pamięci używa. Następnie przejdziesz przez pięć powodów, dla których nowy wyświetlacz pozostaje czarny, oraz poprawkę dla każdego z nich.
Co zbudujesz: szkic Arduino pokazujący ekrany Morning i Night z odcinka 2 na OLED SSD1306 128×64 oraz listę kontrolną dla czarnego ekranu. Czego potrzebujesz: przeglądarki, darmowego Arduino IDE i projektu Morning Dashboard z odcinka 2. Arduino UNO i moduł OLED są opcjonalne; uruchamiamy szkic w symulatorze z odcinka 1.
Jak płytka komunikuje się z ekranem
Cztery przewody: zasilanie, zegar i dane
Mały OLED taki jak nasz potrzebuje czterech przewodów. Dwa to zasilanie: VCC i GND. Pozostałe dwa to magistrala zwana I2C:
- SCL to zegar. Płytka wysyła na nim stałe tykanie.
- SDA przenosi dane, jeden bit na tyknięcie.

Każda wiadomość zaczyna się od adresu
Inne części mogą współdzielić te same dwa przewody: czujnik temperatury, zegar czasu rzeczywistego i wyświetlacz mogą wisieć na SCL i SDA. Dlatego każda wiadomość zaczyna się od adresu, a odpowiada tylko część o tym adresie.
Większość tych wyświetlaczy odpowiada na 0x3C. Niektóre odpowiadają na 0x3D. Na wielu modułach malutki rezystor z tyłu ustawia adres, obok etykiety takiej jak „IIC ADDRESS SELECT 0x78 / 0x7A”. Te dwie liczby to te same adresy podwojone: 0x3C × 2 = 0x78 i 0x3D × 2 = 0x7A. Miej to na uwadze przy powodzie 2 poniżej.

Większe kolorowe ekrany używają SPI
Kolorowe ekrany, takie jak TFT z odcinka 4, zazwyczaj używają zamiast tego SPI: więcej przewodów (MOSI, SCK, CS, DC i RST), znacznie szybciej, oraz przewód wyboru CS zamiast adresu.

Krok 1: skopiuj kod z Lopaka
Otwórz Morning Dashboard z odcinka 2: OLED 128×64 z biblioteką U8g2 i dwoma ekranami, Morning i Night.
Lopaka pisze funkcje rysowania, po jednej na ekran: drawMorning() i drawNight(). Szkic wokół nich, z konfiguracją wyświetlacza i loop(), piszesz raz w Arduino IDE.
Kliknij Kopiuj na karcie Morning panelu kodu, a następnie przełącz się na kartę Night i skopiuj ją też. Kopiuj pobiera kod otwartej karty. Wygenerowany kod jest taki sam jak w odcinku 2.

Krok 2: zainstaluj U8g2
W Arduino IDE otwórz Library Manager (ikona książek po lewej), wyszukaj U8g2 i kliknij INSTALL przy bibliotece U8g2 autorstwa oliver. Odcinek używał wersji 2.36.19.
Krok 3: wybierz płytkę
Kliknij Select Board u góry, wybierz Select other board and port, wpisz uno i wybierz Arduino UNO. Bez podłączonej płytki IDE nadal może skompilować szkic; port jest potrzebny tylko do wgrania.
Krok 4: zbuduj szkic
Nowy szkic ma już setup() i loop(). Wklej kod Lopaka na górze, a następnie dodaj trzy linie: dołącz bibliotekę, utwórz wyświetlacz i uruchom go w setup(). W loop() wyczyść bufor, narysuj i wyślij bufor na ekran:
#include <U8g2lib.h>
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
// Paste the Lopaka code here: drawMorning() and drawNight()
void setup() {
// put your setup code here, to run once:
u8g2.begin();
}
void loop() {
// put your main code here, to run repeatedly:
u8g2.clearBuffer();
if (millis() / 3000 % 2) drawNight(); else drawMorning();
u8g2.sendBuffer();
}setup() uruchamia się raz, gdy płytka startuje. loop() uruchamia się w kółko. Linia if pokazuje każdy ekran przez trzy sekundy, jak w odcinku 2, a kolejność wyczyść, narysuj, wyślij to bufor ramki z odcinka 1.

Linia konstruktora opisuje twój wyświetlacz
Długa linia pod #include to konstruktor. Opisuje twój wyświetlacz, a każda część jego nazwy coś znaczy:
- SSD1306: chip kontrolera na module.
- 128X64: rozmiar w pikselach.
- NONAME: moduł generyczny, a nie konkretna marka.
- F: tryb bufora.
Fto pełny bufor ramki, 1024 bajty RAM.1rysuje ekran w stronach i potrzebuje tylko 128 bajtów. - HW_I2C: okablowanie, sprzętowe I2C na pinach SDA i SCL płytki.
U8G2_R0 oznacza brak rotacji, a U8X8_PIN_NONE mówi, że żaden pin reset nie jest podłączony. Biblioteka U8g2 ma konstruktor dla każdej kombinacji chipa, rozmiaru, bufora i okablowania. Wybierz niewłaściwy, a ekran pozostanie czarny.

Krok 5: zweryfikuj i uruchom
Zweryfikuj
Kliknij Verify, znacznik wyboru w lewym górnym rogu. IDE kompiluje szkic i raportuje:
Sketch uses 15394 bytes (47%) of program storage space. Maximum is 32256 bytes.
Global variables use 1600 bytes (78%) of dynamic memory, leaving 448 bytes for local variables. Maximum is 2048 bytes.Szkic zajmuje mniej niż połowę flash i ponad trzy czwarte RAM. Sam bufor ramki to 1024 z 2048 bajtów UNO; wszystko inne zajmuje 576. Miej oko na te 78%: wróci to przy powodzie 5.

Wgraj albo uruchom w symulatorze
Przy podłączonej płytce wybierz jej port w tym samym oknie Select Board i kliknij Upload, strzałkę obok Verify.
Nie masz płytki? Otwórz projekt symulatora z odcinka 1: Arduino UNO z wyświetlaczem SSD1306 podłączonym GND do GND, VCC do 5V, SDA do A4 i SCL do A5 oraz biblioteką U8g2. Wklej szkic i naciśnij Play. Wyświetlacz pokazuje ekran Morning i co trzy sekundy przełącza się na Night.

Pięć powodów, dla których ekran pozostaje czarny
Sprawdzenia idą od zewnątrz do wewnątrz: przewody, adres, chip, kod i pamięć. W każdym z nich psujemy działającą konfigurację w symulatorze, obserwujemy, jak ekran staje się czarny, i naprawiamy to.
1. Przewody
Na UNO SDA trafia do A4, a SCL do A5. Zamień je, a płytka rozmawia z nikim: ekran pozostaje czarny.
Sprawdź też zasilanie i masę. Inne płytki używają innych pinów: na większości płytek ESP32 SDA to pin 21, a SCL to pin 22.

2. Adres
Większość modułów odpowiada na 0x3C, niektóre na 0x3D. U8g2 rozmawia z 0x3C, chyba że powiesz mu inaczej. Jeśli moduł jest ustawiony na 0x3D, nic nie odpowiada, a ekran pozostaje czarny.
Aby dowiedzieć się, który masz, uruchom szkic skanera I2C. Pyta każdy adres na magistrali i wypisuje te, które odpowiadają:
#include <Wire.h>
void setup() {
Wire.begin();
Serial.begin(9600);
Serial.println("Scanning I2C...");
for (byte a = 1; a < 127; a++) {
Wire.beginTransmission(a);
if (Wire.endTransmission() == 0) {
Serial.print("Found a device at 0x");
Serial.println(a, HEX);
}
}
Serial.println("Done.");
}
void loop() {}Wgraj go i otwórz Serial Monitor na 9600 baud.

Następnie ustaw adres w swoim szkicu pulpitu, przed begin():
void setup() {
u8g2.setI2CAddress(0x3D * 2);
u8g2.begin();
}U8g2 chce adresu podwojonego, więc 0x3D staje się 0x3D * 2, 0x7A: tej samej liczby wydrukowanej z tyłu modułu.

3. Chip
Dwa moduły mogą wyglądać identycznie, a używać różnych kontrolerów. Większość małych ekranów 0,96 cala używa SSD1306. Wiele ekranów 1,3 cala używa SH1106. Uruchom kod SSD1306 na SH1106, a otrzymasz pusty ekran lub pasek szumu wzdłuż krawędzi.
Poprawką jest nazwa chipa w konstruktorze:
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
4. Kod
U8g2 rysuje do bufora w pamięci, a tylko sendBuffer() przenosi obraz na ekran. Zapomnij tej linii albo zapomnij u8g2.begin() w setup(), a ekran pozostanie ciemny. Szkic nadal kompiluje się bez błędu, więc najpierw sprawdź te linie:
u8g2.begin(); // in setup()
u8g2.clearBuffer(); // in loop()
drawMorning();
u8g2.sendBuffer();
5. Pamięć
Pamiętasz te 78%? UNO ma 2048 bajtów RAM, a bufor ramki zajmuje połowę.
Lopaka przechowuje obrazy we flash za pomocą PROGMEM: przełącznik Deklaruj jako PROGMEM obok kodu jest domyślnie włączony, a tablice otrzymują U8X8_PROGMEM. Wyłącz go, a obrazy przeniosą się do RAM. Sam księżyc to 48 × 48 / 8 = 288 bajtów, a cztery obrazy pulpitu zajmują 416. Teraz szkic używa 2016 bajtów, 98% RAM, przy 32 bajtach wolnych na wszystko, co program robi podczas działania. Nadal się kompiluje, ale ekran się rozpada: w symulatorze tekst znika, a obrazki się psują.

Pozostaw PROGMEM włączony. Jeśli nadal brakuje ci RAM, przełącz się na tryb stron: umieść 1 zamiast F w konstruktorze, a bufor skurczy się z 1024 bajtów do 128.
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);W trybie stron biblioteka rysuje ekran w ośmiu paskach, jeden po drugim, więc loop() też się zmienia. Zamiast clearBuffer() i sendBuffer() rysowanie odbywa się wewnątrz pętli firstPage() / nextPage():
void loop() {
u8g2.firstPage();
do {
if (millis() / 3000 % 2) drawNight(); else drawMorning();
} while (u8g2.nextPage());
}W trybie stron ten sam pulpit używa 704 bajtów, 34% RAM.

Podsumowanie
- Lopaka rysuje ekran, IDE buduje szkic wokół niego: zainstaluj U8g2, wybierz płytkę, wklej funkcje rysowania i dodaj dyrektywę include, konstruktor,
begin()oraz pętlę wyczyść, narysuj, wyślij. - Jedna linia konstruktora opisuje twój wyświetlacz: chip, rozmiar, bufor i okablowanie.
- Czarny ekran? Sprawdź pięć rzeczy: przewody, adres, chip, kod i pamięć.
Następny odcinek: Ekrany i menu. Więcej niż jeden ekran, z menu i przyciskiem. Przeczytaj odcinek 6 lub obejrzyj go na YouTube.
Gotowy, aby spróbować? Otwórz Lopaka i umieść swój ekran na prawdziwej płytce.