Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Last revision Both sides next revision
project:esp8266_oledx32 [2019/03/05 21:03]
cyberian úvodní pokec
project:esp8266_oledx32 [2019/03/07 08:11]
cyberian [Kód programu]
Line 7: Line 7:
  
 ===== Úvod ===== ===== Ú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 ​C++ 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í.+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: 
 +<​code>​ 
 +
 +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 
 +}; 
 +</​code>​ 
 + 
 + 
 +===== 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 
 + 
 +<sxh cpp>/* 
 +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 <​Wire.h>​ 
 +#include <​Adafruit_GFX.h>​ 
 +#include <​Adafruit_SSD1306.h>​ 
 + 
 +#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<​display.width();​ i+=4) { 
 +    display.drawLine(0,​ 0, i, display.height()-1,​ WHITE); 
 +    display.display();​ // Update screen with each newly-drawn line 
 +    delay(1); 
 +  } 
 +  for(i=0; i<​display.height();​ i+=4) { 
 +    display.drawLine(0,​ 0, display.width()-1,​ i, WHITE); 
 +    display.display();​ 
 +    delay(1); 
 +  } 
 +  delay(250);​ 
 + 
 +  display.clearDisplay();​ 
 + 
 +  for(i=0; i<​display.width();​ i+=4) { 
 +    display.drawLine(0,​ display.height()-1,​ i, 0, WHITE); 
 +    display.display();​ 
 +    delay(1); 
 +  } 
 +  for(i=display.height()-1;​ 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; i<​display.height();​ i+=4) { 
 +    display.drawLine(display.width()-1,​ 0, 0, i, WHITE); 
 +    display.display();​ 
 +    delay(1); 
 +  } 
 +  for(i=0; i<​display.width();​ i+=4) { 
 +    display.drawLine(display.width()-1,​ 0, i, display.height()-1,​ WHITE); 
 +    display.display();​ 
 +    delay(1); 
 +  } 
 + 
 +  delay(2000);​ // Pause for 2 seconds 
 +
 + 
 +void testdrawrect(void) { 
 +  display.clearDisplay();​ 
 + 
 +  for(int16_t i=0; i<​display.height()/​2;​ i+=2) { 
 +    display.drawRect(i,​ i, display.width()-2*i,​ display.height()-2*i,​ WHITE); 
 +    display.display();​ // Update screen with each newly-drawn rectangle 
 +    delay(1); 
 +  } 
 + 
 +  delay(2000);​ 
 +
 + 
 +void testfillrect(void) { 
 +  display.clearDisplay();​ 
 + 
 +  for(int16_t i=0; i<​display.height()/​2;​ i+=3) { 
 +    // The INVERSE color is used so rectangles alternate white/​black 
 +    display.fillRect(i,​ i, display.width()-i*2,​ display.height()-i*2,​ INVERSE); 
 +    display.display();​ // Update screen with each newly-drawn rectangle 
 +    delay(1); 
 +  } 
 + 
 +  delay(2000);​ 
 +
 + 
 +void testdrawcircle(void) { 
 +  display.clearDisplay();​ 
 + 
 +  for(int16_t i=0; i<​max(display.width(),​display.height())/​2;​ i+=2) { 
 +    display.drawCircle(display.width()/​2,​ display.height()/​2,​ i, WHITE); 
 +    display.display();​ 
 +    delay(1); 
 +  } 
 + 
 +  delay(2000);​ 
 +
 + 
 +void testfillcircle(void) { 
 +  display.clearDisplay();​ 
 + 
 +  for(int16_t i=max(display.width(),​display.height())/​2;​ i>0; 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; i<​display.height()/​2-2;​ i+=2) { 
 +    display.drawRoundRect(i,​ i, display.width()-2*i,​ display.height()-2*i,​ 
 +      display.height()/​4,​ WHITE); 
 +    display.display();​ 
 +    delay(1); 
 +  } 
 + 
 +  delay(2000);​ 
 +
 + 
 +void testfillroundrect(void) { 
 +  display.clearDisplay();​ 
 + 
 +  for(int16_t i=0; i<​display.height()/​2-2;​ i+=2) { 
 +    // The INVERSE color is used so round-rects alternate white/​black 
 +    display.fillRoundRect(i,​ i, display.width()-2*i,​ display.height()-2*i,​ 
 +      display.height()/​4,​ INVERSE); 
 +    display.display();​ 
 +    delay(1); 
 +  } 
 + 
 +  delay(2000);​ 
 +
 + 
 +void testdrawtriangle(void) { 
 +  display.clearDisplay();​ 
 + 
 +  for(int16_t i=0; i<​max(display.width(),​display.height())/​2;​ i+=5) { 
 +    display.drawTriangle( 
 +      display.width()/​2 ​ , display.height()/​2-i,​ 
 +      display.width()/​2-i,​ display.height()/​2+i,​ 
 +      display.width()/​2+i,​ display.height()/​2+i,​ WHITE); 
 +    display.display();​ 
 +    delay(1); 
 +  } 
 + 
 +  delay(2000);​ 
 +
 + 
 +void testfilltriangle(void) { 
 +  display.clearDisplay();​ 
 + 
 +  for(int16_t i=max(display.width(),​display.height())/​2;​ i>0; 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);​ 
 +
 +</​sxh>​
  
  
  • project/esp8266_oledx32.txt
  • Last modified: 2019/03/07 10:20
  • by cyberian