From 861589438f6afb2a186064497c7cc2013c93f96f Mon Sep 17 00:00:00 2001 From: Daniel Eichhorn <dani.eichhorn@squix.ch> Date: Tue, 22 Dec 2015 09:17:11 +0100 Subject: [PATCH] Updated documentation --- README.md | 21 +++++++++++++++------ resources/FontTool.png | Bin 0 -> 14052 bytes 2 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 resources/FontTool.png diff --git a/README.md b/README.md index eb175a5..13b950c 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,10 @@ This is a driver for the SSD1306 based 128x64 pixel OLED display running on the You can either download this library as a zip file and unpack it to your Arduino/libraries folder or (once it has been added) choose it from the Arduino library manager. +## Credits +Many thanks go to Fabrice Weinberg (@FWeinb) for optimizing and refactoring the UI library. +The init sequence for the SSD1306 was inspired by Adafruits library for the same display. + ## Usage The SSD1306Demo is a very comprehensive example demonstrating the most important features of the library. @@ -24,7 +28,11 @@ The SSD1306Demo is a very comprehensive example demonstrating the most important ## Fonts -Fonts are defined in a proprietary but open format. I wrote a program that converts any TrueType font into this format. Once the code is useful enough I will publish it or make it available as Webapplication (SaaS), where you can make any font you like available to the library. +Fonts are defined in a proprietary but open format. You can create new font files by choosing from a given list +of open sourced Fonts from this web app: http://oleddisplay.squix.ch +Choose the font family, style and size, check the preview image and if you like what you see click the "Create" button. This will create the font array in a text area form where you can copy and paste it into a new or existing header file. + + ## API @@ -84,10 +92,10 @@ void drawRect(int x, int y, int width, int height); void fillRect(int x, int y, int width, int height); // Draw a bitmap with the given dimensions -void drawBitmap(int x, int y, int width, int height, const char *bitmap); +void drawBitmap(int x, int y, int width, int height, const char ∗bitmap); // Draw an XBM image with the given dimensions -void drawXbm(int x, int y, int width, int height, const char *xbm); +void drawXbm(int x, int y, int width, int height, const char ∗xbm); // Sets the color of all pixel operations void setColor(int color); @@ -116,17 +124,18 @@ void setTextAlignment(int textAlignment); // Sets the current font. Available default fonts // defined in SSD1306Fonts.h: // ArialMT_Plain_10, ArialMT_Plain_16, ArialMT_Plain_24 -void setFont(const char *fontData); +// Or create one with the font tool at http://oleddisplay.squix.ch +void setFont(const char ∗fontData); ``` ## Frame Transition Functions -The Frane Transition functions are a set of functions on top of the basic library. They allow you to easily write frames which will be shifted in regular intervals. The frame animation (including the frame indicators) will only be activated if you define callback functions with setFrameCallacks(..). If no callback methods are defined no indicators will be displayed. +The Frame Transition functions are a set of functions on top of the basic library. They allow you to easily write frames which will be shifted in regular intervals. The frame animation (including the frame indicators) will only be activated if you define callback functions with setFrameCallacks(..). If no callback methods are defined no indicators will be displayed. ```C++ // Sets the callback methods of the format void method(x,y). As soon as you define the callbacks // the library is in "frame mode" and indicators will be drawn. -void setFrameCallbacks(int frameCount, void (*frameCallbacks[])(int x, int y)); +void setFrameCallbacks(int frameCount, void (∗frameCallbacks[])(SSD1306 ∗display, SSD1306UiState∗ state,int x, int y)); // Tells the framework to move to the next tick. The // current visible frame callback will be called once diff --git a/resources/FontTool.png b/resources/FontTool.png new file mode 100644 index 0000000000000000000000000000000000000000..c7bb222bed6067b921d8a3e479b56e4981a185d4 GIT binary patch literal 14052 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 EUrx=8H~;_u literal 0 HcmV?d00001 -- GitLab