====== ESP8266 - Displej OLED 0.91" 128x32 ====== |**Project owner:**| [[user:Cyberian]] | |**Interested:** | ... | |**Related:**| | | **License:** | [[https://creativecommons.org/licenses/by-sa/3.0/|Uveďte původ-Zachovejte licenci CC BY-SA]] | ===== Úvod ===== Cílem je připojit výše zmíněný displej. Popsat první zkušenosti pro lidi, kteří teprve začínají, zkusit si vyrobit bitmapu a úspěšně ji zobrazit. Předpokladem je základní znalost jazyka Cpp a elementární znalost elektroniky. Nemusíte umět vyloženě základy číslicových obvodů, ale měli by jste vědět, základní info o součástkách a neodpálit si ESP8266 hned při prvním zapojení. Arduino IDE, by jse měli mít již nastaveno na správnou desku. Co bude potřeba: * ESP8266 (Nodemcu nebo např. Wemos mini D1) * 2x 2K7 rezistor * OLED-091 diymore 128x32 I2C dispej * nepájivé kontaktní pole, případně pájitelné Prakticky všechny zapojení, která jsem našel, byli bez pull up rezistorů. Pokud o nich nic nevíte doporučuji si něco načíst. Pull up rezistory (4K7) jsou v našem případě již na spodku desky OLED displeje. Bohužel však nestačili, což jsme zjistili v Labce na osciloskopu, kde místo obdélníkového signálu byla pila. V našem případě vedou pull up rezisotry napětí 3,3 V na D1 a D2, kde D1 vede na hodiny displeje(SCL) a D2 na data(SDA). V počtu pochých dvou linek je výhoda v I2C sběrnici narozdíl od SPI sběrnice, kde potřebujete na samotnou komunikaci více pinů. ===== Zapojení obvodu ===== Kapacitor, který vidíte u napájecí větve není potřeba. Mívám ho standardně ze zvyku u všeho u čeho mám podezření, že by mohlo spičkově odebírat proud, což není tento případ, ale zvyk je zvyk :) {{ :project:esp8266_nodemcu_v0.9_oled_web.jpg?400 |}} ===== Vytvoření bitmapy ===== Některé konvertory mají problém s určitými rozměry obrázků. Obrázek je nutno zmenšit ještě před koverzí a ideální je převést ho na stupně šedi nebo monochromatický taktéž před vlastní konverzí. Jako na potvoru pro konverzi malého obrázku 32x29 px fungoval jen Image2Code, který je trochu obtížnější získat Seznam konvertorů: * GIMP [[https://www.gimp.org/downloads/]] * LCD Assisant [[http://en.radzio.dxp.pl/bitmap_converter/]] * Image2Code https://github.com/adafruit/Adafruit-GFX-Library#useful-resources Konvertory krom gimpu jsem prověřil na virustotal.com, nicméně i tak doporučuji překontrolovat je znovu. Image2Code je nástroj poskytnutý v sekci použitelných zdrojů ke knihovně Adafruit GFX napsaný v javě. Je nutno ho zkompilovat přes příkaz "gradle build". Pokud vám to nepůjde, mohu vám v případě windows poslat již sestavenou verzi Pokud se nepovede konverze z nějakého důvodu ani tak, pak vložte do pole tento obsah: { 0x20,0x0,0x0,0x20, 0x70,0x0,0x0,0x70, 0x50,0x0,0x0,0x50, 0xd8,0x0,0x0,0xd8, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x1,0xc0,0x0,0x0, 0x3,0x60,0x0,0x0, 0x2,0x20,0x78,0x0, 0x2,0x20,0x48,0x0, 0x2,0x20,0x48,0x0, 0x3,0x60,0x48,0x0, 0x1,0xc0,0x38,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x1,0x0,0x8,0x0, 0x1,0x80,0x8,0x0, 0x0,0x88,0x98,0x0, 0x0,0xc5,0x10,0x0, 0x0,0x42,0x10,0x0, 0x0,0x65,0x30,0x0, 0x0,0x28,0xa0,0x0, 0x0,0x20,0x20,0x0 }; ===== Kód programu ===== Na začátku je nutno nainstalovat si v Arduino IDE v menu: Nástroje/Spravovat knihovny následující knihovny: * SSD1306 by adafruit(v mé době ver. 1.28) * Adafruit GFX by adafruit (v mé době ver. 1.36) V kódu je komentář "ZDE VLOZIT hexaznaky bitmapy". Pro zkopírování kód stačí dvojklik na kód a ctrl+c /* This is an example for our Monochrome OLEDs based on SSD1306 drivers Pick one up today in the adafruit shop! ------> http://www.adafruit.com/category/63_98 This example is for a 128x32 pixel display using I2C to communicate 3 pins are required to interface (two I2C and one reset). Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! Written by Limor Fried/Ladyada for Adafruit Industries, with contributions from the open source community. BSD license, check license.txt for more information All text above, and the splash screen below must be included in any redistribution. */ #include #include #include #define SCREEN_WIDTH 128 // šírka OLED displeje v pixelech #define SCREEN_HEIGHT 32 // výška OLED displeje // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) // vytvoreni instance objektu typu display jmenem display Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); //definice velikosti bitmapy #define MARI_WIDTH 128 #define MARI_HEIGHT 64 //bitmapa static const unsigned char PROGMEM Mari_pole [] = { // ZDE VLOZIT hexaznaky bitmapy }; void setup() { // v setup() je zvykem nastavit vše potřebné, než skočíme do loop() Serial.begin(9600); //Wire.pins(4,5); není nutno nastavovat komunikaci na piny 4 a 5 (D1, D2) Wire.begin(); // Defaultně Wire.begin použije piny 4 a 5 delay(2000); if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { //náš displej má def. adresu 0x3C, pozor pro 128x64 je to 0x3D Serial.println(F("SSD1306 alokace selhala")); for(;;); // prasecký druh věčné smyčky } } void loop() { display.clearDisplay(); //vymaže buffer displeje. Po startu tam bývají náhodné pixely // na pozici 0,0 vykresli bitmapu Mari_pole o dané šírce a výšce s hloubkou barev 1 bit. display.drawBitmap(0,0,Mari_pole, MARI_WIDTH, MARI_HEIGHT, 1); display.display(); //pošle obsah bufferu displeje do zobrazení na displeji delay(1000); //scrolling obrazu. Provádí je sám HW displeje, my zadáváme pouze parametry display.startscrollright(0x00, 0x0F); delay(2000); display.stopscroll(); delay(1000); display.startscrollleft(0x00, 0x0F); delay(2000); display.stopscroll(); delay(1000); display.startscrolldiagright(0x00, 0x07); delay(2000); display.startscrolldiagleft(0x00, 0x07); delay(2000); display.stopscroll(); delay(1000); /* zde jsem vám nechal na hraní zakomentované různé funkce, které knihovna Adafruit GFX nabízí * rozhodně doporučuji se podívat do manuálu nebo si zkusit příklad v menu Soubor/Příklady/Adafruit SSD1306/SSD1306_128x32_i2c */ // Draw a single pixel in white /* display.drawPixel(10, 10, WHITE); // Show the display buffer on the screen. You MUST call display() after // drawing commands to make them visible on screen! display.display(); delay(2000); // display.display() is NOT necessary after every single drawing command, // unless that's what you want...rather, you can batch up a bunch of // drawing operations and then update the screen all at once by calling // display.display(). These examples demonstrate both approaches... testdrawline(); // Draw many lines display.display(); delay(2000); testdrawrect(); // Draw rectangles (outlines) testfillrect(); // Draw rectangles (filled) testdrawcircle(); // Draw circles (outlines) testfillcircle(); // Draw circles (filled) testdrawroundrect(); // Draw rounded rectangles (outlines) testfillroundrect(); // Draw rounded rectangles (filled) testdrawtriangle(); // Draw triangles (outlines) testfilltriangle(); // Draw triangles (filled) testdrawchar(); // Draw characters of the default font testdrawstyles(); // Draw 'stylized' characters testscrolltext(); // Draw scrolling text testdrawbitmap(); // Draw a small bitmap image // Invert and restore display, pausing in-between display.invertDisplay(true); delay(1000); display.invertDisplay(false); delay(1000); testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT); // Animate bitmaps */ } //zde jsou definice funkcí výše zakomentovaných void testdrawline() { int16_t i; display.clearDisplay(); // Clear display buffer for(i=0; i=0; i-=4) { display.drawLine(0, display.height()-1, display.width()-1, i, WHITE); display.display(); delay(1); } delay(250); display.clearDisplay(); for(i=display.width()-1; i>=0; i-=4) { display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE); display.display(); delay(1); } for(i=display.height()-1; i>=0; i-=4) { display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE); display.display(); delay(1); } delay(250); display.clearDisplay(); for(i=0; i0; i-=3) { // The INVERSE color is used so circles alternate white/black display.fillCircle(display.width() / 2, display.height() / 2, i, INVERSE); display.display(); // Update screen with each newly-drawn circle delay(1); } delay(2000); } void testdrawroundrect(void) { display.clearDisplay(); for(int16_t i=0; i0; i-=5) { // The INVERSE color is used so triangles alternate white/black display.fillTriangle( display.width()/2 , display.height()/2-i, display.width()/2-i, display.height()/2+i, display.width()/2+i, display.height()/2+i, INVERSE); display.display(); delay(1); } delay(2000); } void testdrawchar(void) { display.clearDisplay(); display.setTextSize(1); // Normal 1:1 pixel scale display.setTextColor(WHITE); // Draw white text display.setCursor(0, 0); // Start at top-left corner display.cp437(true); // Use full 256 char 'Code Page 437' font // Not all the characters will fit on the display. This is normal. // Library will draw what it can and the rest will be clipped. for(int16_t i=0; i<256; i++) { if(i == '\n') display.write(' '); else display.write(i); } display.display(); delay(2000); } void testdrawstyles(void) { display.clearDisplay(); display.setTextSize(1); // Normal 1:1 pixel scale display.setTextColor(WHITE); // Draw white text display.setCursor(0,0); // Start at top-left corner display.println(F("Hello, world!")); display.setTextColor(BLACK, WHITE); // Draw 'inverse' text display.println(3.141592); display.setTextSize(2); // Draw 2X-scale text display.setTextColor(WHITE); display.print(F("0x")); display.println(0xDEADBEEF, HEX); display.display(); delay(2000); } void testscrolltext(void) { display.clearDisplay(); display.setTextSize(2); // Draw 2X-scale text display.setTextColor(WHITE); display.setCursor(10, 0); display.println(F("scroll")); display.display(); // Show initial text delay(100); // Scroll in various directions, pausing in-between: display.startscrollright(0x00, 0x0F); delay(2000); display.stopscroll(); delay(1000); display.startscrollleft(0x00, 0x0F); delay(2000); display.stopscroll(); delay(1000); display.startscrolldiagright(0x00, 0x07); delay(2000); display.startscrolldiagleft(0x00, 0x07); delay(2000); display.stopscroll(); delay(1000); }