Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision Next revision Both sides next revision | ||
project:esp8266_oledx32 [2019/03/06 09:11] cyberian |
project:esp8266_oledx32 [2019/03/07 07:59] cyberian |
||
---|---|---|---|
Line 23: | Line 23: | ||
{{ :project:esp8266_nodemcu_v0.9_oled_web.jpg?400 |}} | {{ :project:esp8266_nodemcu_v0.9_oled_web.jpg?400 |}} | ||
- | Kód programu: | + | ===== Vytvoření bitmapy ===== |
- | Na začátku je nutno nainstalovat si v Arduino IDE v menu: Nástroje/Spravovat knihovny následující knihovny: | + | Některé konvertory mají problém s určitými rozměry obrázků. |
- | * SSD1306 by adafruit(v mé době ver. 1.28) | + | 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 |
- | * Adafruit GFX by adafruit (v mé době ver. 1.36) | + | |
- | Kód je upraveným příkladem pro SSD1306. | + | 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> | <code> | ||
- | /************************************************************************** | ||
- | 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 <SPI.h> | ||
- | #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 mé ženy | ||
- | static const unsigned char PROGMEM Mari_pole [] = | ||
{ | { | ||
- | 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x1c,0x18,0x0,0x0,0x1f,0xff,0xff, | + | 0x20,0x0,0x0,0x20, |
- | 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x0,0x0,0x0,0x0,0x7,0xff,0xff, | + | 0x70,0x0,0x0,0x70, |
- | 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x0,0x0,0x0,0x0,0x3,0xff,0xff, | + | 0x50,0x0,0x0,0x50, |
- | 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x0,0xc0,0x80,0x0,0x1,0xff,0xff, | + | 0xd8,0x0,0x0,0xd8, |
- | 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x3,0xc0,0x0,0x0,0x0,0xff,0xff, | + | 0x0,0x0,0x0,0x0, |
- | 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x17,0x80,0x0,0x0,0x0,0x7f,0xff, | + | 0x0,0x0,0x0,0x0, |
- | 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xa0,0x13,0x80,0x18,0x0,0x0,0x3f,0xff, | + | 0x0,0x0,0x0,0x0, |
- | 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x3,0x80,0x3e,0x0,0x0,0x1f,0xff, | + | 0x0,0x0,0x0,0x0, |
- | 0xff,0xff,0xff,0xff,0xff,0xfd,0xff,0xff,0x0,0x3,0x80,0x7f,0x0,0x0,0x7,0xff, | + | 0x0,0x0,0x0,0x0, |
- | 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1,0x3,0xc0,0xff,0xc0,0x0,0x7,0xff, | + | 0x0,0x0,0x0,0x0, |
- | 0xff,0xff,0xff,0xff,0xff,0xdf,0xef,0xfe,0x1f,0x63,0xc0,0xff,0xe0,0x0,0x3,0xff, | + | 0x0,0x0,0x0,0x0, |
- | 0xff,0xff,0xff,0xff,0xff,0xbf,0xff,0xfe,0xff,0xc3,0xe1,0xff,0xe0,0x0,0x3,0xff, | + | 0x0,0x0,0x0,0x0, |
- | 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdd,0xff,0xc7,0xf1,0xff,0xe0,0x0,0x3,0xff, | + | 0x1,0xc0,0x0,0x0, |
- | 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfb,0xff,0xcf,0xf0,0xff,0xe0,0x0,0x3,0xff, | + | 0x3,0x60,0x0,0x0, |
- | 0xff,0xff,0xff,0xff,0xf7,0xff,0xff,0xb7,0xff,0xff,0xf8,0xff,0xe0,0x0,0x1,0xff, | + | 0x2,0x20,0x78,0x0, |
- | 0x31,0xff,0xff,0xff,0xfe,0x7d,0xff,0x77,0xff,0xff,0xfc,0xff,0xc0,0x0,0x1,0xff, | + | 0x2,0x20,0x48,0x0, |
- | 0x0,0x1,0xff,0xff,0xe1,0xf3,0xfe,0xef,0xff,0xff,0x9e,0x3f,0xc0,0x0,0x1,0xff, | + | 0x2,0x20,0x48,0x0, |
- | 0x0,0x0,0x67,0xf8,0xf,0xff,0xff,0xff,0xff,0xff,0xcf,0x1f,0x0,0x0,0x1,0xff, | + | 0x3,0x60,0x48,0x0, |
- | 0x0,0x0,0x3,0xc1,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x6,0x0,0x0,0x0,0xff, | + | 0x1,0xc0,0x38,0x0, |
- | 0x0,0x0,0x0,0x7,0xff,0xff,0xff,0xff,0xff,0xff,0xe7,0x0,0x0,0x0,0x0,0xff, | + | 0x0,0x0,0x0,0x0, |
- | 0x0,0x0,0x0,0x7f,0xff,0xff,0xff,0xfe,0x7f,0xff,0x13,0x0,0x0,0x0,0x0,0xff, | + | 0x0,0x0,0x0,0x0, |
- | 0x0,0x0,0x1,0xff,0xbf,0xff,0xff,0xfe,0x3f,0xfe,0xf,0x0,0x0,0x0,0x0,0xff, | + | 0x0,0x0,0x0,0x0, |
- | 0x0,0x0,0x7,0xff,0xfe,0x7b,0xff,0xef,0xbf,0xff,0xcd,0x0,0x0,0x0,0x0,0xff, | + | 0x0,0x0,0x0,0x0, |
- | 0x0,0x0,0x3f,0xff,0xf0,0xc7,0xff,0xc7,0xff,0xff,0xcc,0x0,0x0,0x0,0x0,0xff, | + | 0x0,0x0,0x0,0x0, |
- | 0x0,0x0,0x7f,0xff,0x81,0x1f,0xee,0x87,0xff,0xff,0x86,0x0,0x0,0x0,0x0,0xff, | + | 0x1,0x0,0x8,0x0, |
- | 0x0,0x0,0xff,0xff,0x0,0x7f,0xc1,0x83,0xff,0xff,0x86,0x0,0x0,0x0,0x0,0xff, | + | 0x1,0x80,0x8,0x0, |
- | 0x0,0x3,0xff,0xfe,0x1,0xfe,0x3,0x83,0xff,0xff,0x86,0x0,0x4,0x0,0x0,0xff, | + | 0x0,0x88,0x98,0x0, |
- | 0x0,0x7,0xff,0xfc,0x7,0xf8,0x7,0x89,0xff,0xff,0x80,0x0,0x0,0x0,0x0,0xff, | + | 0x0,0xc5,0x10,0x0, |
- | 0x0,0x1f,0xff,0xe0,0x1b,0x0,0xf,0x89,0xff,0xff,0xc0,0x0,0x0,0x80,0x0,0xff, | + | 0x0,0x42,0x10,0x0, |
- | 0x0,0x3f,0xff,0xc0,0x0,0x0,0xf,0xfc,0xff,0xff,0xe0,0x0,0x7,0xe0,0x1,0xff, | + | 0x0,0x65,0x30,0x0, |
- | 0x0,0xff,0xff,0xe0,0x0,0x2,0xf,0xfe,0xff,0xff,0xf8,0x0,0xf,0xf0,0x1,0xff, | + | 0x0,0x28,0xa0,0x0, |
- | 0x1,0xff,0xff,0xe0,0x0,0x0,0xf,0xfe,0x7f,0xff,0xf8,0x0,0x1f,0xf0,0x3,0xff | + | 0x0,0x20,0x20,0x0 |
}; | }; | ||
+ | </code> | ||
- | 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 | + | ===== Kód programu ===== |
- | Serial.println(F("SSD1306 alokace selhala")); | + | Na začátku je nutno nainstalovat si v Arduino IDE v menu: Nástroje/Spravovat knihovny následující knihovny: |
- | for(;;); // prasecký druh věčné smyčky | + | * SSD1306 by adafruit(v mé době ver. 1.28) |
- | } | + | * Adafruit GFX by adafruit (v mé době ver. 1.36) |
- | } | + | |
- | 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); | ||
- | } | ||
- | |||
- | </code> |