Ciljevi učenja
- Provjeriti da OLED modul odgovara referentnom SSD1306 profilu i naponu od 3,3 V.
- Povezati SDA i SCL i protumačiti rezultat skeniranja I2C adresa.
- Razlikovati odgovor uređaja od identifikacije njegovog kontrolera.
- Prikazati ADC očitavanje kao tekst i traku pomoću grafičkog bafera.
- Promijeniti raspored osvježavanja i dodati relativni procenat.
Prije početka
Kursevi 01 i 05: priprema Arduino okruženja, Serial Monitor, analogno očitavanje i potenciometar.
Referentna postavka
- Ploča u Arduino IDE-u
- ESP32 Dev Module
- Arduino-ESP32
- 3.3.12
- Serial Monitor
- 115200 baud
Ovo je referentni profil, a ne identifikacija ploče sa fotografije. Za ESP32-C3/S2/S3 ili drugačije označenu ploču treba prilagoditi GPIO i provjeriti šemu prije spajanja.
Šta ćemo napraviti
Napravićemo mali ekran koji prikazuje vrijednost potenciometra kao broj i horizontalnu traku. Podaci će biti vidljivi i bez otvorenog Serial Monitora. Ovo je priprema za naredni kurs, u kojem na isti ekran dodajemo temperaturu i vlažnost vazduha.
Šta ćeš naučiti
- Povezati odgovarajući OLED preko I2C veze.
- Pronaći adresu uređaja i razlikovati adresu od tipa kontrolera.
- Nacrtati tekst i traku pomoću grafičke biblioteke.
- Pretvoriti analogno očitavanje u dužinu grafičkog elementa.
- Odvojiti osvježavanje ekrana od serijskog ispisa.
Predznanje
Završi kurseve 01 i 05: instalacija ESP32 paketa, Serial Monitor i povezivanje potenciometra. Koristimo klasični ESP32/ESP32-WROOM-32. Oznake GPIO21, GPIO22 i GPIO34 označavaju električne funkcije, a ne redne brojeve nožica. Za C3, S2 ili S3 treba prilagoditi profil ploče.
Potrebna oprema i provjera ekrana
| Komponenta | Količina | Specifikacija i napomene |
|---|---|---|
| ESP32 razvojna ploča sa klasičnim ESP32-WROOM-32 modulom | 1 | GPIO nazivi moraju odgovarati referentnom profilu; fizički položaj izvoda provjeriti na ploči. |
| USB kabl za podatke i napajanje | 1 | Priključak prilagoditi ploči; komplet na slici navodi Micro-USB. |
| Eksperimentalna ploča | 1 | Komplet navodi 830 kontaktnih tačaka. Provjeriti eventualni prekid naponskih vodova. |
| OLED displej 0,96″ — referentni I2C SSD1306 128×64 | 1 | VCC/GND/SDA/SCL, napajanje 3,3 V, pull-up otpornici na modulu prema 3V3. Kontroler, interfejs i rezolucija sa fotografije nisu potvrđeni. |
| Potenciometar 10 kΩ | 1 | Dva krajnja izvoda i klizač W; raspored utvrditi prema stvarnoj komponenti. |
| Spojni kablovi | 8 | M-M ili F-M prema priključcima ploče. Okvirna količina, zavisno od rasporeda i tipa priključaka. |
Referentni ekran je četvoropinski I2C OLED, SSD1306, 128 × 64 piksela, deklarisan za 3,3 V. Natpis „0,96 inča“ ne potvrđuje kontroler, rezoluciju, interfejs ili redoslijed priključaka. Provjeri dokumentaciju konkretnog modula. SH1106 traži odgovarajući drugi drajver; promjena I2C adrese ne pretvara ga u SSD1306. Adafruit: SSD1306, SH110x drajver
Kako rade I2C i grafički prikaz
I2C koristi SDA za podatke i SCL za takt, uz zajedničku masu. Uređaj odgovara na svoju adresu. Skener ispituje adrese i prijavljuje ACK, odnosno potvrdu odgovora. Time saznajemo da je uređaj odgovorio, ali ne i koji kontroler sadrži.
SDA i SCL zahtijevaju pull-up otpornike. Referentni OLED modul ima ih prema svom napajanju od 3,3 V; potvrdi to u njegovoj dokumentaciji. Ako nedostaju, vezu treba dopuniti prema specifikaciji konkretnog modula. Ne koristi modul koji ove vodove podiže na 5 V. Espressif: I2C
SSD1306 biblioteka čuva sliku u memorijskom baferu. Naredbe za tekst i pravougaonike mijenjaju bafer, a display.display() šalje pripremljenu sliku ekranu. Samo crtanje bez slanja ne mijenja vidljivu sliku.
Šema i povezivanje
Šema povezivanja
Referenca je četvoropinski I2C SSD1306 128×64 sa pull-up otpornicima prema 3,3 V. Fotografija ne potvrđuje kontroler ili raspored priključaka. SH1106 zahtijeva drugi drajver. OLED_ADDRESS je 0x3C; 0x3D koristi samo kada skeniranje i dokumentacija to potvrde.
| Od | Do | Opis veze |
|---|---|---|
ESP32.3V3 | OLED1.VCC | I2C SSD1306 modul 128×64, napajanje i pull-up otpornici za 3,3 V. |
ESP32.GND | OLED1.GND | Zajednička masa. |
ESP32.GPIO21 | OLED1.SDA | I2C podaci; pratiti oznaku SDA. |
ESP32.GPIO22 | OLED1.SCL | I2C takt; pratiti oznaku SCL. |
ESP32.3V3 | RV1.END_A | Jedan krajnji izvod potenciometra 10 kΩ. |
ESP32.GND | RV1.END_B | Drugi krajnji izvod potenciometra. |
RV1.W | ESP32.GPIO34 | Klizač na analogni ulaz ADC1. |
- Isključi USB i pronađi oznake VCC, GND, SDA i SCL na OLED modulu.
- Poveži VCC na 3V3, GND na GND, SDA na GPIO21 i SCL na GPIO22.
- Krajeve potenciometra od 10 kΩ poveži na 3V3 i GND, a njegov klizač na GPIO34.
- Provjeri da klizač nije zamijenjen sa krajnjim priključkom i da naponske šine eksperimentalne ploče nisu prekinute na sredini.
- Provjeri zajedničku masu, odvojene redove i napajanje od 3,3 V, pa priključi USB.
Ako okretanje potenciometra povećava vrijednost u neželjenom smjeru, kasnije zamijeni njegova dva krajnja spoja uz isključeno napajanje. Klizač ostaje na GPIO34.
Arduino okruženje i biblioteke
Koristi Arduino IDE 2.x, esp32 by Espressif Systems 3.3.12 i ESP32 Dev Module. U Library Manageru instaliraj Adafruit SSD1306 2.5.17, Adafruit GFX Library 1.12.6 i Adafruit BusIO 1.17.4. Prihvati potrebne zavisnosti i provjeri njihove verzije. Wire dolazi sa ESP32 paketom.
Raspakuj Arduino ZIP, otvori oled_display.ino iz istoimenog foldera, izaberi port i pokreni Verify, zatim Upload. Serial Monitor postavi na 115200 baud. Instalacija ESP32 paketa
| Biblioteka i izdanje | Verzija | Zavisnosti |
|---|---|---|
| Adafruit SSD1306 | 2.5.17 | Adafruit GFX Library 1.12.6 |
| Adafruit GFX Library | 1.12.6 | Adafruit BusIO 1.17.4 |
| Adafruit BusIO | 1.17.4 | Nema |
Wire je uključen u ESP32 core; ne instalira se zasebno kroz Library Manager.
Kompletan program
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
constexpr uint8_t SDA_PIN = 21;
constexpr uint8_t SCL_PIN = 22;
constexpr uint8_t POT_PIN = 34;
constexpr uint8_t OLED_ADDRESS = 0x3C; // Use 0x3D only if the scan confirms it.
constexpr uint16_t OLED_WIDTH = 128;
constexpr uint16_t OLED_HEIGHT = 64;
constexpr uint32_t UPDATE_MS = 100;
constexpr uint32_t REPORT_MS = 500;
Adafruit_SSD1306 display(OLED_WIDTH, OLED_HEIGHT, &Wire, -1, 100000UL, 100000UL);
bool ready = false;
uint32_t lastUpdateAt = 0;
uint32_t lastReportAt = 0;
uint16_t rawAdc = 0;
uint16_t barPixels = 0;
void scanI2CBus() {
Serial.println("I2C scan (an ACK alone does not identify the display controller):");
uint8_t found = 0;
for (uint8_t address = 1; address < 127; ++address) {
Wire.beginTransmission(address);
if (Wire.endTransmission() == 0) {
Serial.print("ACK at 0x"); Serial.println(address, HEX);
++found;
}
}
if (found == 0) Serial.println("No I2C device acknowledged.");
}
bool initializeDisplay() {
if (!Wire.begin(SDA_PIN, SCL_PIN)) {
Serial.println("OLED ERROR: I2C bus initialization failed.");
return false;
}
Wire.setClock(100000);
Wire.setTimeOut(50);
scanI2CBus();
Wire.beginTransmission(OLED_ADDRESS);
if (Wire.endTransmission() != 0) {
Serial.println("OLED ERROR: configured address did not ACK. Check wiring/address; reset to retry.");
return false;
}
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS, false, false)) {
Serial.println("OLED ERROR: display buffer initialization failed; reset to retry.");
return false;
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setTextWrap(false);
return true;
}
void drawReading() {
display.clearDisplay();
display.setCursor(0, 0); display.print("WB Maker Bridge");
display.setCursor(0, 16); display.print("ADC: "); display.print(rawAdc);
display.setCursor(0, 28); display.print("Turn potentiometer");
display.drawRect(3, 42, 122, 14, SSD1306_WHITE);
display.fillRect(4, 43, barPixels, 12, SSD1306_WHITE);
display.display();
}
void setup() {
Serial.begin(115200);
analogReadResolution(12);
analogSetPinAttenuation(POT_PIN, ADC_11db);
ready = initializeDisplay();
if (!ready) return;
lastUpdateAt = millis();
lastReportAt = lastUpdateAt;
drawReading();
Serial.println("OLED ready for this SSD1306 profile. Potentiometer is not a calibrated voltmeter.");
}
void loop() {
if (!ready) return;
const uint32_t now = millis();
if (static_cast<uint32_t>(now - lastUpdateAt) >= UPDATE_MS) {
lastUpdateAt = now;
rawAdc = analogRead(POT_PIN);
barPixels = static_cast<uint32_t>(rawAdc) * 120U / 4095U;
drawReading();
}
if (static_cast<uint32_t>(now - lastReportAt) >= REPORT_MS) {
lastReportAt = now;
Serial.print("ADC="); Serial.print(rawAdc);
Serial.print(" bar_pixels="); Serial.println(barPixels);
}
}
Kod koristi zajedničke ASCII natpise na ekranu. Tekst kursa je preveden, dok program ostaje isti u obje jezičke verzije.
Adresa i pokretanje ekrana
scanI2CBus() ispituje adrese od 1 do 126. Postavka OLED_ADDRESS je podrazumijevano 0x3C. Ako skener prijavi OLED na 0x3D, promijeni postavku i ponovo pošalji program. Ne mijenjaj adresu nasumično i ne zaključuj da odgovor na njoj potvrđuje SSD1306.
initializeDisplay() podešava SDA/SCL, takt od 100 kHz i konačno vrijeme čekanja od 50 ms, zatim provjerava odgovor na izabranoj adresi. Tek potom pokreće biblioteku. Posljednji argument false u display.begin(...) znači da je Wire već pokrenut. Ako provjera ili inicijalizacija ne uspije, ready ostaje netačan i redovni prikaz se ne pokreće. Razlog potraži u Serial Monitoru. Izvorni kod biblioteke
Od potenciometra do trake
ADC je podešen na 12 bita i ADC_11db. Očitavanje je broj od 0 do 4095; nije automatski napon niti precizno mjerenje položaja. Na krajevima hoda moguće je zasićenje. Espressif: ADC
Program čuva očitavanje u rawAdc i skalira ga u barPixels, ispunu dužine najviše 120 piksela. UPDATE_MS iznosi 100 ms, a REPORT_MS 500 ms. Brže pomjeranje trake zato ne zahtijeva jednako čest serijski ispis. Cjelobrojno skaliranje odbacuje dio piksela.
Pokretanje i bilježenje rezultata
Prvo prati skeniranje na računaru. Zatim polako okreni potenciometar i uporedi broj, traku i Serial Monitor. Naslov ekrana je WB Maker Bridge. Početna nula je privremena vrijednost do prvog očitavanja nakon 100 ms.
| Položaj ili zadato očitavanje | Očekivani prikaz |
|---|---|
| Blizu minimuma | Mali broj i kratka ispuna |
| Očitavanje približno 2048 | Približno polovina trake |
| Očitavanje 4095 | Maksimalna ispuna |
| Potenciometar miruje | Uglavnom stabilan broj, uz moguća mala ADC odstupanja |
To su očekivanja za provjeru, a ne unaprijed izmjereni rezultati tvog modula. Zapiši stvarnu adresu i najmanje tri očitavanja.
Najčešći problemi
| Problem | Provjera i korekcija |
|---|---|
| Skener ne nalazi uređaj | Provjeri napajanje, masu, SDA/SCL i oznake modula. |
Skener vidi 0x3D, program staje | Postavi OLED_ADDRESS na 0x3D. |
| ACK postoji, ekran je prazan ili pomjeren | Provjeri kontroler, rezoluciju i odgovarajući drajver. |
| Broj ostaje na jednom kraju | Provjeri klizač, GPIO34 i oba krajnja spoja potenciometra. |
| Promijenjeni tekst se ne vidi | Provjeri poziv display.display() nakon crtanja. |
| Kompajler ne nalazi zaglavlje | Instaliraj navedene biblioteke i provjeri izabranu ploču. |
Samostalni izazov
Dodaj procenat položaja iznad trake. Računaj ga iz istog ADC očitavanja, bez dodatnog čitanja potenciometra. Zatim povećaj UPDATE_MS na 500 ms i opiši promjenu odziva.
Kratka provjera znanja
- Dokazuje li ACK na adresi
0x3Cda je kontroler SSD1306? - Koji poziv prenosi nacrtanu sliku na ekran?
- Da li 50% znači pouzdano izmjerenih 1,65 V?
Rješenje i objašnjenje
Izračunaj procenat izrazom rawAdc * 100UL / 4095 koristeći postojeće očitavanje. U funkciji drawReading() zamijeni red Turn potentiometer ispisom procenta i znaka %, prije slanja bafera. Očitavanja 0, 2048 i 4095 daju 0%, 50% i 100%. To su relativne vrijednosti, bez kalibracije napona.
ACK potvrđuje samo odgovor uređaja. Prenos slike obavlja display.display(). Interval od 500 ms daje približno dva osvježavanja u sekundi i vidljivo sporiji odziv od intervala 100 ms.
Preuzimanja
Sačuvaj šemu, program i zabilježenu adresu za kurs 12. Kompajliranje i fizičku probu evidentiraj odvojeno.
