Compare commits

..

6 commits

Author SHA1 Message Date
ladyada
9c63ee9bd9 Merge branch 'spitft' of github.com:adafruit/Adafruit-SSD1331-OLED-Driver-Library-for-Arduino into spitft 2018-07-14 16:22:03 -04:00
ladyada
1d0c5a4a73 better speed, tested with esp8266, m0, 328p 2018-07-14 16:21:39 -04:00
Limor "Ladyada" Fried
7097afb14a
Merge pull request #16 from adavidzh/patch-2
Add delay to avoid resets
2018-06-19 15:08:12 -07:00
André David
521daecd91
Add delay to avoid resets
Per discussion in #6, this adds a `delay(0)` call to avoid watchdog timer resets in the ESP8266 when not using the SPI hardware pins.
2018-06-19 23:58:22 +02:00
ladyada
47c83e929a fixed bitmap n tested 2018-06-19 08:25:19 -04:00
ladyada
cd4ff4fd25 test passes 2018-06-19 08:16:33 -04:00
17 changed files with 482 additions and 1768 deletions

View file

@ -1,46 +0,0 @@
Thank you for opening an issue on an Adafruit Arduino library repository. To
improve the speed of resolution please review the following guidelines and
common troubleshooting steps below before creating the issue:
- **Do not use GitHub issues for troubleshooting projects and issues.** Instead use
the forums at http://forums.adafruit.com to ask questions and troubleshoot why
something isn't working as expected. In many cases the problem is a common issue
that you will more quickly receive help from the forum community. GitHub issues
are meant for known defects in the code. If you don't know if there is a defect
in the code then start with troubleshooting on the forum first.
- **If following a tutorial or guide be sure you didn't miss a step.** Carefully
check all of the steps and commands to run have been followed. Consult the
forum if you're unsure or have questions about steps in a guide/tutorial.
- **For Arduino projects check these very common issues to ensure they don't apply**:
- For uploading sketches or communicating with the board make sure you're using
a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes
very hard to tell the difference between a data and charge cable! Try using the
cable with other devices or swapping to another cable to confirm it is not
the problem.
- **Be sure you are supplying adequate power to the board.** Check the specs of
your board and plug in an external power supply. In many cases just
plugging a board into your computer is not enough to power it and other
peripherals.
- **Double check all soldering joints and connections.** Flakey connections
cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints.
- **Ensure you are using an official Arduino or Adafruit board.** We can't
guarantee a clone board will have the same functionality and work as expected
with this code and don't support them.
If you're sure this issue is a defect in the code and checked the steps above
please fill in the following fields to provide enough troubleshooting information.
You may delete the guideline and text above to just leave the following details:
- Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE**
- Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO
VERSION HERE**
- List the steps to reproduce the problem below (if possible attach a sketch or
copy the sketch code in too): **LIST REPRO STEPS BELOW**

View file

@ -1,26 +0,0 @@
Thank you for creating a pull request to contribute to Adafruit's GitHub code!
Before you open the request please review the following guidelines and tips to
help it be more easily integrated:
- **Describe the scope of your change--i.e. what the change does and what parts
of the code were modified.** This will help us understand any risks of integrating
the code.
- **Describe any known limitations with your change.** For example if the change
doesn't apply to a supported platform of the library please mention it.
- **Please run any tests or examples that can exercise your modified code.** We
strive to not break users of the code and running tests/examples helps with this
process.
Thank you again for contributing! We will try to test and integrate the change
as soon as we can, but be aware we have many GitHub repositories to manage and
can't immediately respond to every request. There is no need to bump or check in
on a pull request (it will clutter the discussion of the request).
Also don't be worried if the request is closed or not integrated--sometimes the
priorities of Adafruit's GitHub code (education, ease of use) might not match the
priorities of the pull request. Don't fret, the open source community thrives on
forks and GitHub makes it easy to keep your changes in a forked repo.
After reviewing the guidelines above you can delete this text from the pull request.

View file

@ -1,32 +0,0 @@
name: Arduino Library CI
on: [pull_request, push, repository_dispatch]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-python@v4
with:
python-version: '3.x'
- uses: actions/checkout@v3
- uses: actions/checkout@v3
with:
repository: adafruit/ci-arduino
path: ci
- name: pre-install
run: bash ci/actions_install.sh
- name: test platforms
run: python3 ci/build_platform.py main_platforms
- name: clang
run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r .
- name: doxygen
env:
GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }}
PRETTYNAME : "Adafruit SSD1331 Arduino Library"
run: bash ci/doxy_gen_and_deploy.sh

5
.gitignore vendored
View file

@ -1,5 +0,0 @@
# Our handy .gitignore for automation ease
Doxyfile*
doxygen_sqlite3.db
html
.DS_Store

View file

@ -1,247 +1,126 @@
/*!
* @file Adafruit_SSD1331.cpp
*
* @mainpage Adafruit SSD1331 Arduino Library
*
* @section intro_sec Introduction
*
* This is a library for the 0.96" 16-bit Color OLED with SSD1331 driver chip
*
* Pick one up today in the adafruit shop!
* ------> http://www.adafruit.com/products/684
*
* These displays use SPI to communicate, 4 or 5 pins are required to
* interface
* Adafruit invests time and resources providing this open source code,
* please support Adafruit and open-source hardware by purchasing
* products from Adafruit!
*
* @section author Author
*
* Written by Limor Fried/Ladyada for Adafruit Industries.
*
* @section license License
*
* BSD license, all text above must be included in any redistribution
*/
#include "Adafruit_SSD1331.h"
/***********************************/
#define ssd1331_swap(a, b) \
(((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b))) ///< No-temp-var swap operation
/*!
@brief SPI displays set an address window rectangle for blitting pixels
@param x Top left corner x coordinate
@param y Top left corner x coordinate
@param w Width of window
@param h Height of window
*/
void Adafruit_SSD1331::setAddrWindow(uint16_t x, uint16_t y, uint16_t w,
uint16_t h) {
uint8_t x1 = x;
uint8_t y1 = y;
if (x1 > _width - 1)
x1 = _width - 1;
if (y1 > _height - 1)
y1 = _height - 1;
uint8_t x2 = (x + w - 1);
uint8_t y2 = (y + h - 1);
if (x2 > _width - 1)
x2 = _width - 1;
if (y2 > _height - 1)
y2 = _height - 1;
if (x1 > x2) {
ssd1331_swap(x1, x2);
}
if (y1 > y2) {
ssd1331_swap(y1, y2);
}
if (rotation & 1) { // Vertical address increment mode
ssd1331_swap(x1, y1);
ssd1331_swap(x2, y2);
}
SPI_DC_LOW(); // Command mode
spiWrite(SSD1331_CMD_SETCOLUMN); // Column addr set
spiWrite(x1);
spiWrite(x2);
spiWrite(SSD1331_CMD_SETROW); // Row addr set
spiWrite(y1);
spiWrite(y2);
SPI_DC_HIGH(); // Exit Command mode
}
/**************************************************************************/
/*!
@brief Initialize SSD1331 chip
Connects to the SSD1331 over SPI and sends initialization procedure commands
@param freq Desired SPI clock frequency
*/
/**************************************************************************/
void Adafruit_SSD1331::begin(uint32_t freq) {
initSPI(freq);
// Initialization Sequence
sendCommand(SSD1331_CMD_DISPLAYOFF); // 0xAE
sendCommand(SSD1331_CMD_SETREMAP); // 0xA0
sendCommand(SSD1331_CMD_STARTLINE); // 0xA1
sendCommand(0x0);
sendCommand(SSD1331_CMD_DISPLAYOFFSET); // 0xA2
sendCommand(0x0);
sendCommand(SSD1331_CMD_NORMALDISPLAY); // 0xA4
sendCommand(SSD1331_CMD_SETMULTIPLEX); // 0xA8
sendCommand(0x3F); // 0x3F 1/64 duty
sendCommand(SSD1331_CMD_SETMASTER); // 0xAD
sendCommand(0x8E);
sendCommand(SSD1331_CMD_POWERMODE); // 0xB0
sendCommand(0x0B);
sendCommand(SSD1331_CMD_PRECHARGE); // 0xB1
sendCommand(0x31);
sendCommand(SSD1331_CMD_CLOCKDIV); // 0xB3
sendCommand(0xF0); // 7:4 = Oscillator Frequency, 3:0 = CLK Div Ratio
// (A[3:0]+1 = 1..16)
sendCommand(SSD1331_CMD_PRECHARGEA); // 0x8A
sendCommand(0x64);
sendCommand(SSD1331_CMD_PRECHARGEB); // 0x8B
sendCommand(0x78);
sendCommand(SSD1331_CMD_PRECHARGEC); // 0x8C
sendCommand(0x64);
sendCommand(SSD1331_CMD_PRECHARGELEVEL); // 0xBB
sendCommand(0x3A);
sendCommand(SSD1331_CMD_VCOMH); // 0xBE
sendCommand(0x3E);
sendCommand(SSD1331_CMD_MASTERCURRENT); // 0x87
sendCommand(0x06);
sendCommand(SSD1331_CMD_CONTRASTA); // 0x81
sendCommand(0x91);
sendCommand(SSD1331_CMD_CONTRASTB); // 0x82
sendCommand(0x50);
sendCommand(SSD1331_CMD_CONTRASTC); // 0x83
sendCommand(0x7D);
sendCommand(SSD1331_CMD_DISPLAYON); //--turn on oled panel
_width = TFTWIDTH;
_height = TFTHEIGHT;
setRotation(0);
}
/**************************************************************************/
/*!
@brief Instantiate Adafruit SSD1331 driver with software SPI
@param cs Chip select pin #
@param dc Data/Command pin #
@param mosi SPI MOSI pin #
@param sclk SPI Clock pin #
@param rst Reset pin # (optional, pass -1 if unused)
*/
/**************************************************************************/
Adafruit_SSD1331::Adafruit_SSD1331(int8_t cs, int8_t dc, int8_t mosi,
int8_t sclk, int8_t rst)
: Adafruit_SPITFT(TFTWIDTH, TFTHEIGHT, cs, dc, mosi, sclk, rst, -1) {}
/**************************************************************************/
/*!
@brief Instantiate Adafruit SSD1331 driver with hardware SPI
@param cs Chip select pin #
@param dc Data/Command pin #
@param rst Reset pin # (optional, pass -1 if unused)
*/
/**************************************************************************/
Adafruit_SSD1331::Adafruit_SSD1331(int8_t cs, int8_t dc, int8_t rst)
: Adafruit_SPITFT(TFTWIDTH, TFTHEIGHT, cs, dc, rst) {}
/**************************************************************************/
/*!
@brief Instantiate Adafruit SSD1331 driver with hardware SPI
@param spi Pointer to an existing SPIClass instance (e.g. &SPI, the
microcontroller's primary SPI bus).
@param cs Chip select pin #
@param dc Data/Command pin #
@param rst Reset pin # (optional, pass -1 if unused)
*/
/**************************************************************************/
Adafruit_SSD1331::Adafruit_SSD1331(SPIClass *spi, int8_t cs, int8_t dc,
int8_t rst)
:
#if defined(ESP8266)
Adafruit_SPITFT(TFTWIDTH, TFTHEIGHT, cs, dc, rst) {
#else
Adafruit_SPITFT(TFTWIDTH, TFTHEIGHT, spi, cs, dc, rst) {
#endif
}
/**************************************************************************/
/*!
@brief Change whether display is on or off
@param enable True if you want the display ON, false OFF
*/
/**************************************************************************/
void Adafruit_SSD1331::enableDisplay(boolean enable) {
sendCommand(enable ? SSD1331_CMD_DISPLAYON : SSD1331_CMD_DISPLAYOFF);
}
/**************************************************************************/
/*!
@brief Set origin of (0,0) and orientation of OLED display
@param r
The index for rotation, from 0-3 inclusive
@return None (void).
@note SSD1331 works differently than most (all?) other SPITFT
displays. With certain rotation changes the screen contents
may change immediately into a peculiar format (mirrored, not
necessarily rotated) (other displays, this only affects new
drawing -- rotation combinations can apply to different
areas). Therefore, it's recommend to clear the screen
(fillScreen(0)) before changing rotation.
*/
/**************************************************************************/
void Adafruit_SSD1331::setRotation(uint8_t r) {
// madctl bits:
// 6,7 Color depth (01 = 64K)
// 5 Odd/even split COM (0: disable, 1: enable)
// 4 Scan direction (0: top-down, 1: bottom-up)
// 3 Left-Right swapping on COM (0: disable, 1: enable)
// 2 Color remap (0: A->B->C, 1: C->B->A)
// 1 Column remap (0: 0-95, 1: 95-0)
// 0 Address increment (0: horizontal, 1: vertical)
#if defined SSD1331_COLORORDER_RGB
uint8_t madctl = 0b01100000; // 64K, enable split, ABC
#else
uint8_t madctl = 0b01100100; // 64K, enable split, CBA
#endif
rotation = r & 3; // Clip input to valid range
switch (rotation) {
case 0:
madctl |= 0b00010010; // Scan bottom-up, column remap 95-0
_width = WIDTH;
_height = HEIGHT;
break;
case 1:
madctl |= 0b00000011; // column remap 95-0, vertical
_width = HEIGHT;
_height = WIDTH;
break;
case 2:
madctl |= 0b00000000; // None
_width = WIDTH;
_height = HEIGHT;
break;
case 3:
madctl |= 0b00010001; // Scan bottom-up, Vertical
_width = HEIGHT;
_height = WIDTH;
break;
}
sendCommand(SSD1331_CMD_SETREMAP);
sendCommand(madctl);
}
/***************************************************
This is a library for the 0.96" 16-bit Color OLED with SSD1331 driver chip
Pick one up today in the adafruit shop!
------> http://www.adafruit.com/products/684
These displays use SPI to communicate, 4 or 5 pins are required to
interface
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.
BSD license, all text above must be included in any redistribution
****************************************************/
#include "Adafruit_SSD1331.h"
#include "pins_arduino.h"
#include "wiring_private.h"
/***********************************/
void Adafruit_SSD1331::setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
uint8_t x1 = x;
uint8_t y1 = y;
if (x1 > 95) x1 = 95;
if (y1 > 63) y1 = 63;
uint8_t x2 = (x+w-1);
uint8_t y2 = (y+h-1);
if (x2 > 95) x2 = 95;
if (y2 > 63) y2 = 63;
if (x1 > x2) {
uint8_t t = x2;
x2 = x1;
x1 = t;
}
if (y1 > y2) {
uint8_t t = y2;
y2 = y1;
y1 = t;
}
startWrite();
writeCommand(0x15); // Column addr set
writeCommand(x1);
writeCommand(x2);
endWrite();
startWrite();
writeCommand(0x75); // Column addr set
writeCommand(y1);
writeCommand(y2);
endWrite();
startWrite();
}
void Adafruit_SSD1331::begin(uint32_t freq) {
initSPI(freq);
startWrite();
// Initialization Sequence
writeCommand(SSD1331_CMD_DISPLAYOFF); // 0xAE
writeCommand(SSD1331_CMD_SETREMAP); // 0xA0
#if defined SSD1331_COLORORDER_RGB
writeCommand(0x72); // RGB Color
#else
writeCommand(0x76); // BGR Color
#endif
writeCommand(SSD1331_CMD_STARTLINE); // 0xA1
writeCommand(0x0);
writeCommand(SSD1331_CMD_DISPLAYOFFSET); // 0xA2
writeCommand(0x0);
writeCommand(SSD1331_CMD_NORMALDISPLAY); // 0xA4
writeCommand(SSD1331_CMD_SETMULTIPLEX); // 0xA8
writeCommand(0x3F); // 0x3F 1/64 duty
writeCommand(SSD1331_CMD_SETMASTER); // 0xAD
writeCommand(0x8E);
writeCommand(SSD1331_CMD_POWERMODE); // 0xB0
writeCommand(0x0B);
writeCommand(SSD1331_CMD_PRECHARGE); // 0xB1
writeCommand(0x31);
writeCommand(SSD1331_CMD_CLOCKDIV); // 0xB3
writeCommand(0xF0); // 7:4 = Oscillator Frequency, 3:0 = CLK Div Ratio (A[3:0]+1 = 1..16)
writeCommand(SSD1331_CMD_PRECHARGEA); // 0x8A
writeCommand(0x64);
writeCommand(SSD1331_CMD_PRECHARGEB); // 0x8B
writeCommand(0x78);
writeCommand(SSD1331_CMD_PRECHARGEA); // 0x8C
writeCommand(0x64);
writeCommand(SSD1331_CMD_PRECHARGELEVEL); // 0xBB
writeCommand(0x3A);
writeCommand(SSD1331_CMD_VCOMH); // 0xBE
writeCommand(0x3E);
writeCommand(SSD1331_CMD_MASTERCURRENT); // 0x87
writeCommand(0x06);
writeCommand(SSD1331_CMD_CONTRASTA); // 0x81
writeCommand(0x91);
writeCommand(SSD1331_CMD_CONTRASTB); // 0x82
writeCommand(0x50);
writeCommand(SSD1331_CMD_CONTRASTC); // 0x83
writeCommand(0x7D);
writeCommand(SSD1331_CMD_DISPLAYON); //--turn on oled panel
endWrite();
_width = TFTWIDTH;
_height = TFTHEIGHT;
}
/********************************* low level pin initialization */
Adafruit_SSD1331::Adafruit_SSD1331(uint8_t cs, uint8_t dc, uint8_t mosi, uint8_t sclk, uint8_t rst) : Adafruit_SPITFT(TFTWIDTH, TFTHEIGHT, cs, dc, mosi, sclk, rst, -1) {
}
Adafruit_SSD1331::Adafruit_SSD1331(uint8_t cs, uint8_t dc, uint8_t rst) : Adafruit_SPITFT(TFTWIDTH, TFTHEIGHT, cs, dc, rst) {
}

View file

@ -1,76 +1,81 @@
/*!
* @file Adafruit_SSD1331.h
*/
/***************************************************
This is a library for the 0.96" 16-bit Color OLED with SSD1331 driver chip
#ifndef ADAFRUIT_SSD1331_H
#define ADAFRUIT_SSD1331_H
Pick one up today in the adafruit shop!
------> http://www.adafruit.com/products/684
These displays use SPI to communicate, 4 or 5 pins are required to
interface
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.
BSD license, all text above must be included in any redistribution
****************************************************/
#include "Arduino.h"
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
/*!
* @brief Select one of these defines to set the pixel color order
*/
// Select one of these defines to set the pixel color order
#define SSD1331_COLORORDER_RGB
// #define SSD1331_COLORORDER_BGR
#if defined SSD1331_COLORORDER_RGB && defined SSD1331_COLORORDER_BGR
#error "RGB and BGR can not both be defined for SSD1331_COLORORDER."
#error "RGB and BGR can not both be defined for SSD1331_COLORODER."
#endif
// Timing Delays
#define SSD1331_DELAYS_HWFILL (3) //!< Fill delay
#define SSD1331_DELAYS_HWLINE (1) //!< Line delay
#define SSD1331_DELAYS_HWFILL (3)
#define SSD1331_DELAYS_HWLINE (1)
// SSD1331 Commands
#define SSD1331_CMD_DRAWLINE 0x21 //!< Draw line
#define SSD1331_CMD_DRAWRECT 0x22 //!< Draw rectangle
#define SSD1331_CMD_FILL 0x26 //!< Fill enable/disable
#define SSD1331_CMD_SETCOLUMN 0x15 //!< Set column address
#define SSD1331_CMD_SETROW 0x75 //!< Set row adress
#define SSD1331_CMD_CONTRASTA 0x81 //!< Set contrast for color A
#define SSD1331_CMD_CONTRASTB 0x82 //!< Set contrast for color B
#define SSD1331_CMD_CONTRASTC 0x83 //!< Set contrast for color C
#define SSD1331_CMD_MASTERCURRENT 0x87 //!< Master current control
#define SSD1331_CMD_SETREMAP 0xA0 //!< Set re-map & data format
#define SSD1331_CMD_STARTLINE 0xA1 //!< Set display start line
#define SSD1331_CMD_DISPLAYOFFSET 0xA2 //!< Set display offset
#define SSD1331_CMD_NORMALDISPLAY 0xA4 //!< Set display to normal mode
#define SSD1331_CMD_DISPLAYALLON 0xA5 //!< Set entire display ON
#define SSD1331_CMD_DISPLAYALLOFF 0xA6 //!< Set entire display OFF
#define SSD1331_CMD_INVERTDISPLAY 0xA7 //!< Invert display
#define SSD1331_CMD_SETMULTIPLEX 0xA8 //!< Set multiplex ratio
#define SSD1331_CMD_SETMASTER 0xAD //!< Set master configuration
#define SSD1331_CMD_DISPLAYOFF 0xAE //!< Display OFF (sleep mode)
#define SSD1331_CMD_DISPLAYON 0xAF //!< Normal Brightness Display ON
#define SSD1331_CMD_POWERMODE 0xB0 //!< Power save mode
#define SSD1331_CMD_PRECHARGE 0xB1 //!< Phase 1 and 2 period adjustment
#define SSD1331_CMD_CLOCKDIV \
0xB3 //!< Set display clock divide ratio/oscillator frequency
#define SSD1331_CMD_PRECHARGEA 0x8A //!< Set second pre-charge speed for color A
#define SSD1331_CMD_PRECHARGEB 0x8B //!< Set second pre-charge speed for color B
#define SSD1331_CMD_PRECHARGEC 0x8C //!< Set second pre-charge speed for color C
#define SSD1331_CMD_PRECHARGELEVEL 0xBB //!< Set pre-charge voltage
#define SSD1331_CMD_VCOMH 0xBE //!< Set Vcomh voltge
#define SSD1331_CMD_DRAWLINE 0x21
#define SSD1331_CMD_DRAWRECT 0x22
#define SSD1331_CMD_FILL 0x26
#define SSD1331_CMD_SETCOLUMN 0x15
#define SSD1331_CMD_SETROW 0x75
#define SSD1331_CMD_CONTRASTA 0x81
#define SSD1331_CMD_CONTRASTB 0x82
#define SSD1331_CMD_CONTRASTC 0x83
#define SSD1331_CMD_MASTERCURRENT 0x87
#define SSD1331_CMD_SETREMAP 0xA0
#define SSD1331_CMD_STARTLINE 0xA1
#define SSD1331_CMD_DISPLAYOFFSET 0xA2
#define SSD1331_CMD_NORMALDISPLAY 0xA4
#define SSD1331_CMD_DISPLAYALLON 0xA5
#define SSD1331_CMD_DISPLAYALLOFF 0xA6
#define SSD1331_CMD_INVERTDISPLAY 0xA7
#define SSD1331_CMD_SETMULTIPLEX 0xA8
#define SSD1331_CMD_SETMASTER 0xAD
#define SSD1331_CMD_DISPLAYOFF 0xAE
#define SSD1331_CMD_DISPLAYON 0xAF
#define SSD1331_CMD_POWERMODE 0xB0
#define SSD1331_CMD_PRECHARGE 0xB1
#define SSD1331_CMD_CLOCKDIV 0xB3
#define SSD1331_CMD_PRECHARGEA 0x8A
#define SSD1331_CMD_PRECHARGEB 0x8B
#define SSD1331_CMD_PRECHARGEC 0x8C
#define SSD1331_CMD_PRECHARGELEVEL 0xBB
#define SSD1331_CMD_VCOMH 0xBE
/// Class to manage hardware interface with SSD1331 chipset
class Adafruit_SSD1331 : public Adafruit_SPITFT {
public:
Adafruit_SSD1331(int8_t cs, int8_t dc, int8_t mosi, int8_t sclk, int8_t rst);
Adafruit_SSD1331(int8_t cs, int8_t dc, int8_t rst);
// 3-4 args using hardware SPI (must specify peripheral) (reset optional)
Adafruit_SSD1331(SPIClass *spi, int8_t cs, int8_t dc, int8_t rst = -1);
public:
Adafruit_SSD1331(uint8_t _CS, uint8_t _DC, uint8_t _MOSI, uint8_t _SCLK, uint8_t _RST);
Adafruit_SSD1331(uint8_t _CS, uint8_t _DC, uint8_t _RST);
// commands
void begin(uint32_t begin = 8000000);
void setRotation(uint8_t r);
void setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
void begin(uint32_t begin=8000000);
void enableDisplay(boolean enable);
void setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
uint8_t readcommand8(uint8_t reg, uint8_t index = 0);
static const int16_t TFTWIDTH = 96; ///< The width of the display
static const int16_t TFTHEIGHT = 64; ///< The height of the display
static const int16_t TFTWIDTH = 96;
static const int16_t TFTHEIGHT = 64;
private:
private:
};
#endif // ADAFRUIT_SSD1331_H

View file

@ -1,4 +1,3 @@
# Adafruit SSD1331 Arduino Library [![Build Status](https://github.com/adafruit/Adafruit-SSD1331-OLED-Driver-Library-for-Arduino/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit-SSD1331-OLED-Driver-Library-for-Arduino/actions)[![Documentation](https://github.com/adafruit/ci-arduino/blob/master/assets/doxygen_badge.svg)](http://adafruit.github.io/Adafruit-SSD1331-OLED-Driver-Library-for-Arduino/html/index.html)
This is a library for the 0.96" 16-bit Color OLED with SSD1331 driver chip
Pick one up today in the adafruit shop!
@ -21,4 +20,4 @@ Place the Adafruit_SSD1331 library folder your <arduinosketchfolder>/libraries/
You will also have to download the Adafruit GFX Graphics core which does all the circles, text, rectangles, etc. You can get it from
https://github.com/adafruit/Adafruit-GFX-Library
and download/install that library as well
and download/install that library as well

View file

@ -1,751 +0,0 @@
// GFX Demo for multiple backends
// By Marc MERLIN <marc_soft@merlins.org>
// Contains code (c) Adafruit, license BSD
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1331.h>
#include <SPI.h>
#define show endWrite
#define clear() fillScreen(0)
#define mw 96
#define mh 64
#include "smileytongue24.h"
#define BM32
#include "google32.h"
/*
SD1331 Pin Arduino ESP8266 rPi
1 GND
2 VCC
3 SCL/SCK/CLK/D0 13 GPIO14/D5 GPIO11/SPI0-SCLK
4 SDA/MOSI/D1 11 GPIO13/D7 GPIO10/SPI0-MOSI
5 RES/RST 9 GPIO15/D8 GPIO24
6 DC/A0 (data) 8 GPIO05/D1 GPIO23
7 CS 10 GPIO04/D2 GPIO08
*/
// You can use any (4 or) 5 pins
// hwspi hardcodes those pins, no need to redefine them
#define sclk 14
#define mosi 13
#define cs 5
#define rst 9
#define dc 6
// Option 1: use any pins but a little slower
//#pragma message "Using SWSPI"
//Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, mosi, sclk, rst);
// Option 2: must use the hardware SPI pins
// (for UNO thats sclk = 13 and sid = 11) and pin 10 must be
// an output. This is much faster - also required if you want
// to use the microSD card (see the image drawing example)
#pragma message "Using HWSPI"
Adafruit_SSD1331 display = Adafruit_SSD1331(&SPI, cs, dc, rst);
// This could also be defined as display.color(255,0,0) but those defines
// are meant to work for adafruit_gfx backends that are lacking color()
#define LED_BLACK 0
#define LED_RED_VERYLOW (3 << 11)
#define LED_RED_LOW (7 << 11)
#define LED_RED_MEDIUM (15 << 11)
#define LED_RED_HIGH (31 << 11)
#define LED_GREEN_VERYLOW (1 << 5)
#define LED_GREEN_LOW (15 << 5)
#define LED_GREEN_MEDIUM (31 << 5)
#define LED_GREEN_HIGH (63 << 5)
#define LED_BLUE_VERYLOW 3
#define LED_BLUE_LOW 7
#define LED_BLUE_MEDIUM 15
#define LED_BLUE_HIGH 31
#define LED_ORANGE_VERYLOW (LED_RED_VERYLOW + LED_GREEN_VERYLOW)
#define LED_ORANGE_LOW (LED_RED_LOW + LED_GREEN_LOW)
#define LED_ORANGE_MEDIUM (LED_RED_MEDIUM + LED_GREEN_MEDIUM)
#define LED_ORANGE_HIGH (LED_RED_HIGH + LED_GREEN_HIGH)
#define LED_PURPLE_VERYLOW (LED_RED_VERYLOW + LED_BLUE_VERYLOW)
#define LED_PURPLE_LOW (LED_RED_LOW + LED_BLUE_LOW)
#define LED_PURPLE_MEDIUM (LED_RED_MEDIUM + LED_BLUE_MEDIUM)
#define LED_PURPLE_HIGH (LED_RED_HIGH + LED_BLUE_HIGH)
#define LED_CYAN_VERYLOW (LED_GREEN_VERYLOW + LED_BLUE_VERYLOW)
#define LED_CYAN_LOW (LED_GREEN_LOW + LED_BLUE_LOW)
#define LED_CYAN_MEDIUM (LED_GREEN_MEDIUM + LED_BLUE_MEDIUM)
#define LED_CYAN_HIGH (LED_GREEN_HIGH + LED_BLUE_HIGH)
#define LED_WHITE_VERYLOW (LED_RED_VERYLOW + LED_GREEN_VERYLOW + LED_BLUE_VERYLOW)
#define LED_WHITE_LOW (LED_RED_LOW + LED_GREEN_LOW + LED_BLUE_LOW)
#define LED_WHITE_MEDIUM (LED_RED_MEDIUM + LED_GREEN_MEDIUM + LED_BLUE_MEDIUM)
#define LED_WHITE_HIGH (LED_RED_HIGH + LED_GREEN_HIGH + LED_BLUE_HIGH)
static const uint8_t PROGMEM
mono_bmp[][8] =
{
{ // 0: checkered 1
B10101010,
B01010101,
B10101010,
B01010101,
B10101010,
B01010101,
B10101010,
B01010101,
},
{ // 1: checkered 2
B01010101,
B10101010,
B01010101,
B10101010,
B01010101,
B10101010,
B01010101,
B10101010,
},
{ // 2: smiley
B00111100,
B01000010,
B10100101,
B10000001,
B10100101,
B10011001,
B01000010,
B00111100 },
{ // 3: neutral
B00111100,
B01000010,
B10100101,
B10000001,
B10111101,
B10000001,
B01000010,
B00111100 },
{ // 4; frowny
B00111100,
B01000010,
B10100101,
B10000001,
B10011001,
B10100101,
B01000010,
B00111100 },
};
static const uint16_t PROGMEM
// These bitmaps were written for a backend that only supported
// 4 bits per color with Blue/Green/Red ordering while neomatrix
// uses native 565 color mapping as RGB.
// I'm leaving the arrays as is because it's easier to read
// which color is what when separated on a 4bit boundary
// The demo code will modify the arrays at runtime to be compatible
// with the neomatrix color ordering and bit depth.
RGB_bmp[][64] = {
// 00: blue, blue/red, red, red/green, green, green/blue, blue, white
{ 0x100, 0x200, 0x300, 0x400, 0x600, 0x800, 0xA00, 0xF00,
0x101, 0x202, 0x303, 0x404, 0x606, 0x808, 0xA0A, 0xF0F,
0x001, 0x002, 0x003, 0x004, 0x006, 0x008, 0x00A, 0x00F,
0x011, 0x022, 0x033, 0x044, 0x066, 0x088, 0x0AA, 0x0FF,
0x010, 0x020, 0x030, 0x040, 0x060, 0x080, 0x0A0, 0x0F0,
0x110, 0x220, 0x330, 0x440, 0x660, 0x880, 0xAA0, 0xFF0,
0x100, 0x200, 0x300, 0x400, 0x600, 0x800, 0xA00, 0xF00,
0x111, 0x222, 0x333, 0x444, 0x666, 0x888, 0xAAA, 0xFFF, },
// 01: grey to white
{ 0x111, 0x222, 0x333, 0x555, 0x777, 0x999, 0xAAA, 0xFFF,
0x222, 0x222, 0x333, 0x555, 0x777, 0x999, 0xAAA, 0xFFF,
0x333, 0x333, 0x333, 0x555, 0x777, 0x999, 0xAAA, 0xFFF,
0x555, 0x555, 0x555, 0x555, 0x777, 0x999, 0xAAA, 0xFFF,
0x777, 0x777, 0x777, 0x777, 0x777, 0x999, 0xAAA, 0xFFF,
0x999, 0x999, 0x999, 0x999, 0x999, 0x999, 0xAAA, 0xFFF,
0xAAA, 0xAAA, 0xAAA, 0xAAA, 0xAAA, 0xAAA, 0xAAA, 0xFFF,
0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, },
// 02: low red to high red
{ 0x001, 0x002, 0x003, 0x005, 0x007, 0x009, 0x00A, 0x00F,
0x002, 0x002, 0x003, 0x005, 0x007, 0x009, 0x00A, 0x00F,
0x003, 0x003, 0x003, 0x005, 0x007, 0x009, 0x00A, 0x00F,
0x005, 0x005, 0x005, 0x005, 0x007, 0x009, 0x00A, 0x00F,
0x007, 0x007, 0x007, 0x007, 0x007, 0x009, 0x00A, 0x00F,
0x009, 0x009, 0x009, 0x009, 0x009, 0x009, 0x00A, 0x00F,
0x00A, 0x00A, 0x00A, 0x00A, 0x00A, 0x00A, 0x00A, 0x00F,
0x00F, 0x00F, 0x00F, 0x00F, 0x00F, 0x00F, 0x00F, 0x00F, },
// 03: low green to high green
{ 0x010, 0x020, 0x030, 0x050, 0x070, 0x090, 0x0A0, 0x0F0,
0x020, 0x020, 0x030, 0x050, 0x070, 0x090, 0x0A0, 0x0F0,
0x030, 0x030, 0x030, 0x050, 0x070, 0x090, 0x0A0, 0x0F0,
0x050, 0x050, 0x050, 0x050, 0x070, 0x090, 0x0A0, 0x0F0,
0x070, 0x070, 0x070, 0x070, 0x070, 0x090, 0x0A0, 0x0F0,
0x090, 0x090, 0x090, 0x090, 0x090, 0x090, 0x0A0, 0x0F0,
0x0A0, 0x0A0, 0x0A0, 0x0A0, 0x0A0, 0x0A0, 0x0A0, 0x0F0,
0x0F0, 0x0F0, 0x0F0, 0x0F0, 0x0F0, 0x0F0, 0x0F0, 0x0F0, },
// 04: low blue to high blue
{ 0x100, 0x200, 0x300, 0x500, 0x700, 0x900, 0xA00, 0xF00,
0x200, 0x200, 0x300, 0x500, 0x700, 0x900, 0xA00, 0xF00,
0x300, 0x300, 0x300, 0x500, 0x700, 0x900, 0xA00, 0xF00,
0x500, 0x500, 0x500, 0x500, 0x700, 0x900, 0xA00, 0xF00,
0x700, 0x700, 0x700, 0x700, 0x700, 0x900, 0xA00, 0xF00,
0x900, 0x900, 0x900, 0x900, 0x900, 0x900, 0xA00, 0xF00,
0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xF00,
0xF00, 0xF00, 0xF00, 0xF00, 0xF00, 0xF00, 0xF00, 0xF00, },
// 05: 1 black, 2R, 2O, 2G, 1B with 4 blue lines rising right
{ 0x000, 0x200, 0x000, 0x400, 0x000, 0x800, 0x000, 0xF00,
0x000, 0x201, 0x002, 0x403, 0x004, 0x805, 0x006, 0xF07,
0x008, 0x209, 0x00A, 0x40B, 0x00C, 0x80D, 0x00E, 0xF0F,
0x000, 0x211, 0x022, 0x433, 0x044, 0x855, 0x066, 0xF77,
0x088, 0x299, 0x0AA, 0x4BB, 0x0CC, 0x8DD, 0x0EE, 0xFFF,
0x000, 0x210, 0x020, 0x430, 0x040, 0x850, 0x060, 0xF70,
0x080, 0x290, 0x0A0, 0x4B0, 0x0C0, 0x8D0, 0x0E0, 0xFF0,
0x000, 0x200, 0x000, 0x500, 0x000, 0x800, 0x000, 0xF00, },
// 06: 4 lines of increasing red and then green
{ 0x000, 0x000, 0x001, 0x001, 0x002, 0x002, 0x003, 0x003,
0x004, 0x004, 0x005, 0x005, 0x006, 0x006, 0x007, 0x007,
0x008, 0x008, 0x009, 0x009, 0x00A, 0x00A, 0x00B, 0x00B,
0x00C, 0x00C, 0x00D, 0x00D, 0x00E, 0x00E, 0x00F, 0x00F,
0x000, 0x000, 0x010, 0x010, 0x020, 0x020, 0x030, 0x030,
0x040, 0x040, 0x050, 0x050, 0x060, 0x060, 0x070, 0x070,
0x080, 0x080, 0x090, 0x090, 0x0A0, 0x0A0, 0x0B0, 0x0B0,
0x0C0, 0x0C0, 0x0D0, 0x0D0, 0x0E0, 0x0E0, 0x0F0, 0x0F0, },
// 07: 4 lines of increasing red and then blue
{ 0x000, 0x000, 0x001, 0x001, 0x002, 0x002, 0x003, 0x003,
0x004, 0x004, 0x005, 0x005, 0x006, 0x006, 0x007, 0x007,
0x008, 0x008, 0x009, 0x009, 0x00A, 0x00A, 0x00B, 0x00B,
0x00C, 0x00C, 0x00D, 0x00D, 0x00E, 0x00E, 0x00F, 0x00F,
0x000, 0x000, 0x100, 0x100, 0x200, 0x200, 0x300, 0x300,
0x400, 0x400, 0x500, 0x500, 0x600, 0x600, 0x700, 0x700,
0x800, 0x800, 0x900, 0x900, 0xA00, 0xA00, 0xB00, 0xB00,
0xC00, 0xC00, 0xD00, 0xD00, 0xE00, 0xE00, 0xF00, 0xF00, },
// 08: criss cross of green and red with diagonal blue.
{ 0xF00, 0x001, 0x003, 0x005, 0x007, 0x00A, 0x00F, 0x000,
0x020, 0xF21, 0x023, 0x025, 0x027, 0x02A, 0x02F, 0x020,
0x040, 0x041, 0xF43, 0x045, 0x047, 0x04A, 0x04F, 0x040,
0x060, 0x061, 0x063, 0xF65, 0x067, 0x06A, 0x06F, 0x060,
0x080, 0x081, 0x083, 0x085, 0xF87, 0x08A, 0x08F, 0x080,
0x0A0, 0x0A1, 0x0A3, 0x0A5, 0x0A7, 0xFAA, 0x0AF, 0x0A0,
0x0F0, 0x0F1, 0x0F3, 0x0F5, 0x0F7, 0x0FA, 0xFFF, 0x0F0,
0x000, 0x001, 0x003, 0x005, 0x007, 0x00A, 0x00F, 0xF00, },
// 09: 2 lines of green, 2 red, 2 orange, 2 green
{ 0x0F0, 0x0F0, 0x0FF, 0x0FF, 0x00F, 0x00F, 0x0F0, 0x0F0,
0x0F0, 0x0F0, 0x0FF, 0x0FF, 0x00F, 0x00F, 0x0F0, 0x0F0,
0x0F0, 0x0F0, 0x0FF, 0x0FF, 0x00F, 0x00F, 0x0F0, 0x0F0,
0x0F0, 0x0F0, 0x0FF, 0x0FF, 0x00F, 0x00F, 0x0F0, 0x0F0,
0x0F0, 0x0F0, 0x0FF, 0x0FF, 0x00F, 0x00F, 0x0F0, 0x0F0,
0x0F0, 0x0F0, 0x0FF, 0x0FF, 0x00F, 0x00F, 0x0F0, 0x0F0,
0x0F0, 0x0F0, 0x0FF, 0x0FF, 0x00F, 0x00F, 0x0F0, 0x0F0,
0x0F0, 0x0F0, 0x0FF, 0x0FF, 0x00F, 0x00F, 0x0F0, 0x0F0, },
// 10: multicolor smiley face
{ 0x000, 0x000, 0x00F, 0x00F, 0x00F, 0x00F, 0x000, 0x000,
0x000, 0x00F, 0x000, 0x000, 0x000, 0x000, 0x00F, 0x000,
0x00F, 0x000, 0xF00, 0x000, 0x000, 0xF00, 0x000, 0x00F,
0x00F, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x00F,
0x00F, 0x000, 0x0F0, 0x000, 0x000, 0x0F0, 0x000, 0x00F,
0x00F, 0x000, 0x000, 0x0F4, 0x0F3, 0x000, 0x000, 0x00F,
0x000, 0x00F, 0x000, 0x000, 0x000, 0x000, 0x00F, 0x000,
0x000, 0x000, 0x00F, 0x00F, 0x00F, 0x00F, 0x000, 0x000, },
};
// Convert a BGR 4/4/4 bitmap to RGB 5/6/5 used by Adafruit_GFX
void fixdrawRGBBitmap(int16_t x, int16_t y, const uint16_t *bitmap, int16_t w, int16_t h) {
uint16_t RGB_bmp_fixed[w * h];
for (uint16_t pixel=0; pixel<w*h; pixel++) {
uint8_t r,g,b;
uint16_t color = pgm_read_word(bitmap + pixel);
//Serial.print(color, HEX);
b = (color & 0xF00) >> 8;
g = (color & 0x0F0) >> 4;
r = color & 0x00F;
//Serial.print(" ");
//Serial.print(b);
//Serial.print("/");
//Serial.print(g);
//Serial.print("/");
//Serial.print(r);
//Serial.print(" -> ");
// expand from 4/4/4 bits per color to 5/6/5
b = map(b, 0, 15, 0, 31);
g = map(g, 0, 15, 0, 63);
r = map(r, 0, 15, 0, 31);
//Serial.print(r);
//Serial.print("/");
//Serial.print(g);
//Serial.print("/");
//Serial.print(b);
RGB_bmp_fixed[pixel] = (r << 11) + (g << 5) + b;
//Serial.print(" -> ");
//Serial.println(RGB_bmp_fixed[pixel], HEX);
}
display.drawRGBBitmap(x, y, RGB_bmp_fixed, w, h);
}
// In a case of a tile of neomatrices, this test is helpful to make sure that the
// pixels are all in sequence (to check your wiring order and the tile options you
// gave to the constructor).
void count_pixels() {
display.clear();
for (uint16_t i=0; i<mh; i++) {
for (uint16_t j=0; j<mw; j++) {
display.drawPixel(j, i, i%3==0?LED_BLUE_HIGH:i%3==1?LED_RED_HIGH:LED_GREEN_HIGH);
// depending on the matrix size, it's too slow to display each pixel, so
// make the scan init faster. This will however be too fast on a small matrix.
if (!(j%7)) display.show();
}
}
}
// Example that shows how to push entire lines at a time faster than
// writing pixels one by one as in count_pixels
void count_writePixels() {
uint16_t line[mw+3];
for (uint8_t i=0; i<mw+3; i++) {
line[i] = i%3==0?LED_BLUE_HIGH:i%3==1?LED_RED_HIGH:LED_GREEN_HIGH;
}
display.startWrite();
display.setAddrWindow(0, 0, mw, mh);
for (uint8_t j=0; j<mh; j++) {
display.writePixels(line + (j%3), mw);
}
display.endWrite();
}
// Fill the screen with multiple levels of white to gauge the quality
void display_four_white() {
display.clear();
display.fillRect(0,0, mw,mh, LED_WHITE_HIGH);
display.drawRect(1,1, mw-2,mh-2, LED_WHITE_MEDIUM);
display.drawRect(2,2, mw-4,mh-4, LED_WHITE_LOW);
display.drawRect(3,3, mw-6,mh-6, LED_WHITE_VERYLOW);
display.show();
}
void display_bitmap(uint8_t bmp_num, uint16_t color) {
static uint16_t bmx,bmy;
// Clear the space under the bitmap that will be drawn as
// drawing a single color pixmap does not write over pixels
// that are nul, and leaves the data that was underneath
display.fillRect(bmx,bmy, bmx+8,bmy+8, LED_BLACK);
display.drawBitmap(bmx, bmy, mono_bmp[bmp_num], 8, 8, color);
bmx += 8;
if (bmx >= mw) bmx = 0;
if (!bmx) bmy += 8;
if (bmy >= mh) bmy = 0;
display.show();
}
void display_rgbBitmap(uint8_t bmp_num) {
static uint16_t bmx,bmy;
fixdrawRGBBitmap(bmx, bmy, RGB_bmp[bmp_num], 8, 8);
bmx += 8;
if (bmx >= mw) bmx = 0;
if (!bmx) bmy += 8;
if (bmy >= mh) bmy = 0;
display.show();
}
void display_lines() {
display.clear();
// 4 levels of crossing red lines.
display.drawLine(0,mh/2-2, mw-1,2, LED_RED_VERYLOW);
display.drawLine(0,mh/2-1, mw-1,3, LED_RED_LOW);
display.drawLine(0,mh/2, mw-1,mh/2, LED_RED_MEDIUM);
display.drawLine(0,mh/2+1, mw-1,mh/2+1, LED_RED_HIGH);
// 4 levels of crossing green lines.
display.drawLine(mw/2-2, 0, mw/2-2, mh-1, LED_GREEN_VERYLOW);
display.drawLine(mw/2-1, 0, mw/2-1, mh-1, LED_GREEN_LOW);
display.drawLine(mw/2+0, 0, mw/2+0, mh-1, LED_GREEN_MEDIUM);
display.drawLine(mw/2+1, 0, mw/2+1, mh-1, LED_GREEN_HIGH);
// Diagonal blue line.
display.drawLine(0,0, mw-1,mh-1, LED_BLUE_HIGH);
display.drawLine(0,mh-1, mw-1,0, LED_ORANGE_MEDIUM);
display.show();
}
void display_boxes() {
display.clear();
display.drawRect(0,0, mw,mh, LED_BLUE_HIGH);
display.drawRect(1,1, mw-2,mh-2, LED_GREEN_MEDIUM);
display.fillRect(2,2, mw-4,mh-4, LED_RED_HIGH);
display.fillRect(3,3, mw-6,mh-6, LED_ORANGE_MEDIUM);
display.show();
}
void display_circles() {
display.clear();
display.drawCircle(mw/2,mh/2, 2, LED_RED_MEDIUM);
display.drawCircle(mw/2-1-min(mw,mh)/8, mh/2-1-min(mw,mh)/8, min(mw,mh)/4, LED_BLUE_HIGH);
display.drawCircle(mw/2+1+min(mw,mh)/8, mh/2+1+min(mw,mh)/8, min(mw,mh)/4-1, LED_ORANGE_MEDIUM);
display.drawCircle(1,mh-2, 1, LED_GREEN_LOW);
display.drawCircle(mw-2,1, 1, LED_GREEN_HIGH);
if (min(mw,mh)>12) display.drawCircle(mw/2-1, mh/2-1, min(mh/2-1,mw/2-1), LED_CYAN_HIGH);
display.show();
}
void display_resolution() {
display.setTextSize(1);
// not wide enough;
if (mw<16) return;
display.clear();
// Font is 5x7, if display is too small
// 8 can only display 1 char
// 16 can almost display 3 chars
// 24 can display 4 chars
// 32 can display 5 chars
display.setCursor(0, 0);
display.setTextColor(LED_RED_HIGH);
if (mw>10) display.print(mw/10);
display.setTextColor(LED_ORANGE_HIGH);
display.print(mw % 10);
display.setTextColor(LED_GREEN_HIGH);
display.print('x');
// not wide enough to print 5 chars, go to next line
if (mw<25) {
if (mh==13) display.setCursor(6, 7);
else if (mh>=13) {
display.setCursor(mw-11, 8);
} else {
// we're not tall enough either, so we wait and display
// the 2nd value on top.
display.show();
delay(2000);
display.clear();
display.setCursor(mw-11, 0);
}
}
display.setTextColor(LED_CYAN_HIGH);
display.print(mh/10);
display.setTextColor(LED_CYAN_MEDIUM);
display.print(mh % 10);
// enough room for a 2nd line
if ((mw>25 && mh >14) || mh>16) {
display.setCursor(0, mh-7);
display.setTextColor(LED_CYAN_LOW);
if (mw>16) display.print('*');
display.setTextColor(LED_RED_HIGH);
display.print('R');
display.setTextColor(LED_GREEN_HIGH);
display.print('G');
display.setTextColor(LED_BLUE_HIGH);
display.print("B");
display.setTextColor(LED_PURPLE_HIGH);
// this one could be displayed off screen, but we don't care :)
display.print("*");
// We have a big array, great, let's assume 32x32 and add something in the middle
if (mh>24 && mw>25) {
for (uint16_t i=0; i<mw; i+=8) fixdrawRGBBitmap(i, mh/2-7+(i%16)/8*6, RGB_bmp[10], 8, 8);
}
}
display.show();
}
void display_scrollText() {
uint8_t size = max(int(mh/10), 1);
display.clear();
display.setTextWrap(false); // we don't wrap text so it scrolls nicely
display.setTextSize(1);
display.setRotation(0);
for (int8_t x=7; x>=-42; x--) {
display.clear();
display.setCursor(x,0);
display.setTextColor(LED_GREEN_HIGH);
display.print("Hello");
if (mh>11) {
display.setCursor(-20-x,mh-7);
display.setTextColor(LED_ORANGE_HIGH);
display.print("World");
}
display.show();
// delay(50);
}
display.setRotation(1);
display.setTextSize(size);
display.setTextColor(LED_BLUE_HIGH);
for (int16_t x=8*size; x>=-6*8*size; x--) {
display.clear();
display.setCursor(x,mw/2-size*4);
display.print("Rotate");
display.show();
// note that on a big array the refresh rate from show() will be slow enough that
// the delay become irrelevant. This is already true on a 32x32 array.
// delay(50/size);
}
display.setRotation(0);
display.setCursor(0,0);
display.show();
}
// Scroll within big bitmap so that all if it becomes visible or bounce a small one.
// If the bitmap is bigger in one dimension and smaller in the other one, it will
// be both panned and bounced in the appropriate dimensions.
void display_panOrBounceBitmap (uint8_t bitmapSize, bool clear = true) {
// keep integer math, deal with values 16 times too big
// start by showing upper left of big bitmap or centering if the display is big
int16_t xf = max(0, (mw-bitmapSize)/2) << 4;
int16_t yf = max(0, (mh-bitmapSize)/2) << 4;
// scroll speed in 1/16th
int16_t xfc = 6;
int16_t yfc = 3;
// scroll down and right by moving upper left corner off screen
// more up and left (which means negative numbers)
int16_t xfdir = -1;
int16_t yfdir = -1;
uint16_t frames = 200;
long time1 = millis();
for (uint16_t i=1; i<frames; i++) {
yield();
bool updDir = false;
// Get actual x/y by dividing by 16.
int16_t x = xf >> 4;
int16_t y = yf >> 4;
if (clear) display.clear();
// bounce 8x8 tri color smiley face around the screen
if (bitmapSize == 8) fixdrawRGBBitmap(x, y, RGB_bmp[10], 8, 8);
// pan 24x24 pixmap
if (bitmapSize == 24) display.drawRGBBitmap(x, y, (const uint16_t *) bitmap24, bitmapSize, bitmapSize);
#ifdef BM32
if (bitmapSize == 32) display.drawRGBBitmap(x, y, (const uint16_t *) bitmap32, bitmapSize, bitmapSize);
#endif
display.show();
// Only pan if the display size is smaller than the pixmap
// but not if the difference is too small or it'll look bad.
if (bitmapSize-mw>2) {
xf += xfc*xfdir;
if (xf >= 0) { xfdir = -1; updDir = true ; };
// we don't go negative past right corner, go back positive
if (xf <= ((mw-bitmapSize) << 4)) { xfdir = 1; updDir = true ; };
}
if (bitmapSize-mh>2) {
yf += yfc*yfdir;
// we shouldn't display past left corner, reverse direction.
if (yf >= 0) { yfdir = -1; updDir = true ; };
if (yf <= ((mh-bitmapSize) << 4)) { yfdir = 1; updDir = true ; };
}
// only bounce a pixmap if it's smaller than the display size
if (mw>bitmapSize) {
xf += xfc*xfdir;
// Deal with bouncing off the 'walls'
if (xf >= (mw-bitmapSize) << 4) { xfdir = -1; updDir = true ; };
if (xf <= 0) { xfdir = 1; updDir = true ; };
}
if (mh>bitmapSize) {
yf += yfc*yfdir;
if (yf >= (mh-bitmapSize) << 4) { yfdir = -1; updDir = true ; };
if (yf <= 0) { yfdir = 1; updDir = true ; };
}
if (updDir) {
// Add -1, 0 or 1 but bind result to 1 to 1.
// Let's take 3 is a minimum speed, otherwise it's too slow.
xfc = constrain(xfc + random(-1, 2), 3, 16);
yfc = constrain(xfc + random(-1, 2), 3, 16);
}
//delay(10);
}
uint16_t elapsed = millis() - time1;
uint16_t fps = 1000 * frames / elapsed;
Serial.print("Scroll test number of ms: ");
Serial.println(elapsed);
Serial.print("FPS: ");
Serial.println(fps);
}
void loop() {
// clear the screen after X bitmaps have been displayed and we
// loop back to the top left corner
// 8x8 => 1, 16x8 => 2, 17x9 => 6
static uint8_t pixmap_count = ((mw+7)/8) * ((mh+7)/8);
// ESP8266 HWSPI: 34 fps, SWSPI: 6 fps
// If you change SPI frequency to 80Mhz in display.begin, you can get 64fps
uint16_t frames = 20;
long time1 = millis();
for (uint8_t i=0; i<frames; i++) {
display.fillScreen(LED_BLUE_LOW);
display.show();
display.fillScreen(LED_RED_LOW);
display.show();
}
uint16_t elapsed = millis() - time1;
float fps = 1000.0 * frames*2 / elapsed;
Serial.print("Speed test number of ms: ");
Serial.println(elapsed);
Serial.print("FPS: ");
Serial.println(fps);
/* ESP8266 HWSPI speeds 80Mhz
bounce 32 bitmap FPS: 18
bounce 32 bitmap no clear FPS: 25
pan/bounce 24 bitmap FPS: 26
pan/bounce 24 bitmap no clear FPS: 44
pan/bounce 8 bitmap FPS: 63
pan/bounce 8 bitmap FPS: 3174
*/
#ifdef BM32
Serial.println("bounce 32 bitmap");
display_panOrBounceBitmap(32);
Serial.println("bounce 32 bitmap no clear");
display_panOrBounceBitmap(32, false);
#endif
// pan a big pixmap
Serial.println("pan/bounce 24 bitmap");
display_panOrBounceBitmap(24);
Serial.println("pan/bounce 24 bitmap no clear");
display_panOrBounceBitmap(24, false);
// bounce around a small one
Serial.println("pan/bounce 8 bitmap");
display_panOrBounceBitmap(8);
Serial.println("pan/bounce 8 bitmap");
display_panOrBounceBitmap(8, false);
// this is more helpful on displays where each show refreshes
// the entire display. With SSD1331, it's a single pixel being pushed,
// so it's near instant, so we run it 100 times
// At 80Mhz, on ESP8266, I get 3.68fps (2.99fps at 40Mhz)
frames = 10;
Serial.println("\nCount pixels");
time1 = millis();
for (uint8_t i=0; i<frames; i++) count_pixels();
elapsed = millis() - time1;
fps = 1000.0 * frames / elapsed;
Serial.print("Speed test number of ms: ");
Serial.println(elapsed);
Serial.print("FPS: ");
Serial.println(fps);
Serial.println("Count pixels done");
delay(3000);
// Benchmark against count_writePixels
// At 80Mhz, on ESP8266, I get 86.96fps (42.74fps at 40Mhz)
Serial.println("\nCount_writePixels");
time1 = millis();
for (uint8_t i=0; i<frames; i++) count_writePixels();
elapsed = millis() - time1;
fps = 1000.0 * frames / elapsed;
Serial.print("Speed test number of ms: ");
Serial.println(elapsed);
Serial.print("FPS: ");
Serial.println(fps);
Serial.println("Count_writePixels done");
delay(5000);
Serial.print("\nDiplay whites: ");
display_four_white();
delay(3000);
Serial.print("Screen pixmap capacity: ");
Serial.println(pixmap_count);
// multicolor bitmap sent as many times as we can display an 8x8 pixmap
for (uint8_t i=0; i<=pixmap_count; i++)
{
display_rgbBitmap(0);
}
delay(1000);
Serial.println("Display Resolution");
display_resolution();
delay(3000);
Serial.println("Display bitmaps");
// Cycle through red, green, blue, display 2 checkered patterns
// useful to debug some screen types and alignment.
uint16_t bmpcolor[] = { LED_GREEN_HIGH, LED_BLUE_HIGH, LED_RED_HIGH };
for (uint8_t i=0; i<3; i++)
{
display_bitmap(0, bmpcolor[i]);
delay(500);
display_bitmap(1, bmpcolor[i]);
delay(500);
}
Serial.println("Display smileys");
// Display 3 smiley faces.
for (uint8_t i=2; i<=4; i++)
{
display_bitmap(i, bmpcolor[i-2]);
// If more than one pixmap displayed per screen, display more quickly.
delay(mw>8?500:1500);
}
// If we have multiple pixmaps displayed at once, wait a bit longer on the last.
delay(mw>8?1000:500);
Serial.println("Display lines, boxes and circles");
display_lines();
delay(3000);
display_boxes();
delay(3000);
display_circles();
delay(3000);
display.clear();
Serial.println("Display RGB bitmaps");
for (uint8_t i=0; i<=(sizeof(RGB_bmp)/sizeof(RGB_bmp[0])-1); i++)
{
display_rgbBitmap(i);
delay(mw>8?500:1500);
}
// If we have multiple pixmaps displayed at once, wait a bit longer on the last.
delay(mw>8?1000:500);
Serial.println("Scrolltext");
display_scrollText();
Serial.println("Demo loop done, starting over");
}
void setup() {
delay(1000);
Serial.begin(115200);
// Default is 40Mhz
display.begin();
Serial.println("For extra speed, try 80Mhz, may be less stable");
//display.begin(80000000);
display.setTextWrap(false);
display.setAddrWindow(0, 0, mw, mh);
// Test full bright of all LEDs. If brightness is too high
// for your current limit (i.e. USB), decrease it.
display.fillScreen(LED_WHITE_HIGH);
display.show();
delay(3000);
display.clear();
}
// vim:sts=4:sw=4

View file

@ -1,17 +0,0 @@
This is a hello world GFX demo written and ported to multiple GFX supported backends.
It is not fully optimized for SD1331 but simply meant to show how it works on that backend, including the issue of clear() being slow. Pixmap sync was changed to work with and without full frame clear. In real life, code for these panels should be rewritten to only clear an area around the area being redrawn to avoid flashing and slower refreshes (HWSPI at full 80Mhz speed on ESP8266 can reach over 80fps but still shows noticeable flashing if you clear the whole screen before displaying the next frame).
A lot of the demo code was meant for lower resolution displays (down to 8x8 or 16x8), see http://marc.merlins.org/perso/arduino/post_2017-04-24_Adafruit-GFX-on-NeoMatrix-and-RGB-Matrix-Panel-Demo.html , but it's interesting to see how the code and the GFX library scales from 8x8 to 96x64.
![image](https://user-images.githubusercontent.com/1369412/57587320-32682000-74b8-11e9-92c0-577df34d4447.png)
![image](https://user-images.githubusercontent.com/1369412/57587336-50ce1b80-74b8-11e9-9020-043a0eeaa01d.png)
This same demo is already present in these trees:
* https://github.com/adafruit/Adafruit_NeoMatrix/tree/master/examples/MatrixGFXDemo
* https://github.com/adafruit/RGB-matrix-Panel/blob/master/examples/PanelGFXDemo_16x32/PanelGFXDemo_16x32.ino
* https://github.com/marcmerlin/FastLED_NeoMatrix/tree/master/examples/MatrixGFXDemo
* https://github.com/marcmerlin/LED-Matrix/blob/master/examples/directmatrix8x8_tricolor_direct_sr/directmatrix8x8_tricolor_direct_sr.ino
* https://github.com/mrfaptastic/ESP32-RGB64x32MatrixPanel-I2S-DMA/blob/master/examples/PanelGFXDemo/PanelGFXDemo.ino
* https://github.com/marcmerlin/SmartMatrix_GFX/tree/master/examples/MatrixGFXDemo

View file

@ -1,210 +0,0 @@
// Generated by : UTFTConverter v0.1
// Generated from : google.jpg
// Time generated : 2018-02-08 06:09:41.424425 UTC
// Image Size : 32x32 pixels
// Memory usage : 2048 bytes
#if defined(__AVR__)
#include <avr/pgmspace.h>
#elif defined(__PIC32MX__)
#define PROGMEM
#elif defined(__arm__)
#define PROGMEM
#endif
const unsigned short
bitmap32[1024] PROGMEM =
{
0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFDF, 0xFFDF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
0xFFFF, 0xFFFF, 0xFFDF, 0xFFDF, // 0x0010 (16) pixels
0xFFFF, 0xFFFF, 0xFFDE, 0xFFDE, 0xFFFF, 0xFFFF,
0xFFDF, 0xFFFF, 0xFFFE, 0xFFDE, 0xFFFE, 0xFFFE,
0xFFFF, 0xFFFF, 0xFFBF, 0xFFDF, // 0x0020 (32) pixels
0xFFFE, 0x0840, 0x0820, 0x0841, 0x0040, 0x0020,
0x1020, 0x0800, 0x0040, 0x0060, 0x0020, 0x0840,
0x0000, 0x0040, 0x1022, 0x0821, // 0x0030 (48) pixels
0x0861, 0x0020, 0x1020, 0x0800, 0x0820, 0x0820,
0x0001, 0x0821, 0x0800, 0x1020, 0x0820, 0x1040,
0x0041, 0x0021, 0x0821, 0xFFDF, // 0x0040 (64) pixels
0xFFFF, 0x0021, 0x0042, 0x1926, 0x343A, 0x1B98,
0x02F7, 0x0318, 0x031A, 0x033A, 0x43F8, 0x8E7F,
0xF7DF, 0xEF9F, 0xEF9D, 0xEFBD, // 0x0050 (80) pixels
0xEBF0, 0x9966, 0xE801, 0xE001, 0xD821, 0xD800,
0xE001, 0xE000, 0xD820, 0xD000, 0xD001, 0xC000,
0x3020, 0x2800, 0x0861, 0xF7FF, // 0x0060 (96) pixels
0xFFFF, 0x0021, 0x10E5, 0xB5D8, 0x2BF9, 0x0B36,
0x02F7, 0x0338, 0x031A, 0x031A, 0x2315, 0x54BB,
0xE75E, 0xF7FF, 0xF7FE, 0xFFFF, // 0x0070 (112) pixels
0xFE9B, 0xCAEC, 0xE801, 0xE801, 0xD821, 0xD800,
0xE801, 0xE001, 0xD800, 0xE040, 0xD042, 0xD022,
0x5964, 0x2800, 0x0020, 0xFFFF, // 0x0080 (128) pixels
0xFFFD, 0x0880, 0xB63C, 0x9D58, 0x0BBB, 0x0339,
0x0B1B, 0x02DB, 0x02F8, 0x0B39, 0x031B, 0x139C,
0x9E1B, 0xE7FF, 0xFFFF, 0xFFDE, // 0x0090 (144) pixels
0xFFDE, 0xC5B5, 0xF863, 0xE000, 0xE001, 0xE001,
0xD821, 0xD821, 0xE020, 0xD800, 0xF000, 0xF000,
0xC801, 0xC800, 0x0040, 0xFFFE, // 0x00A0 (160) pixels
0xFFFD, 0x10C0, 0xD71F, 0xA59A, 0x0B9A, 0x0339,
0x0B3C, 0x02FB, 0x0B39, 0x0B19, 0x02FA, 0x0B7C,
0x6C95, 0xD7DF, 0xFFFF, 0xFFDE, // 0x00B0 (176) pixels
0xFFDE, 0xEEDA, 0xF8C4, 0xE801, 0xE001, 0xE001,
0xE041, 0xD821, 0xE020, 0xE000, 0xF801, 0xF801,
0xD022, 0xC801, 0x0860, 0xFFFD, // 0x00C0 (192) pixels
0xFFFF, 0x62EB, 0xCF5E, 0x9597, 0x1BB9, 0x1337,
0x02D9, 0x031A, 0x0319, 0x0319, 0x031B, 0x033B,
0x4396, 0xB71F, 0xFFFE, 0xFFFE, // 0x00D0 (208) pixels
0xFFBF, 0xFF1C, 0xF924, 0xE041, 0xF000, 0xF000,
0xE820, 0xE000, 0xF000, 0xF800, 0xE000, 0xD800,
0xD801, 0xD801, 0x4947, 0xFF9F, // 0x00E0 (224) pixels
0xFFFF, 0x738D, 0xCF7F, 0xAE7B, 0x23B9, 0x0B37,
0x02FA, 0x0B1A, 0x0339, 0x0339, 0x033C, 0x031B,
0x3B76, 0x963F, 0xFFFE, 0xFFFE, // 0x00F0 (240) pixels
0xFF9E, 0xFF3D, 0xF945, 0xD820, 0xF801, 0xF800,
0xE800, 0xE820, 0xF800, 0xF800, 0xE821, 0xE020,
0xE001, 0xD800, 0x5167, 0xFF7F, // 0x0100 (256) pixels
0xFFFF, 0x6B8F, 0xE71D, 0xE6FD, 0x4439, 0x2335,
0x033A, 0x035A, 0x0317, 0x0B58, 0x0319, 0x0319,
0x2B76, 0x7E1F, 0xF7FF, 0xFFFF, // 0x0110 (272) pixels
0xFF7E, 0xFE7A, 0xE904, 0xD021, 0xB8C2, 0xB8C2,
0xA8C0, 0xB101, 0xC881, 0xC880, 0xF001, 0xF001,
0xE000, 0xD800, 0x5166, 0xFF9E, // 0x0120 (288) pixels
0xF7BF, 0x73B0, 0xEF3E, 0xF79F, 0x655E, 0x2356,
0x037B, 0x033A, 0x0B58, 0x0316, 0x0319, 0x033A,
0x2356, 0x7E1F, 0xFFFF, 0xF7FF, // 0x0130 (304) pixels
0xFF9E, 0xCCF4, 0xE0A3, 0xD862, 0xB8C2, 0xC0E2,
0xB942, 0xB101, 0xC8A1, 0xC8A1, 0xF001, 0xF001,
0xD800, 0xD800, 0x5166, 0xFFBF, // 0x0140 (320) pixels
0xFFFE, 0x6B6C, 0xFEFC, 0xFF7E, 0xAEFF, 0x3B94,
0x039D, 0x033B, 0x0358, 0x0379, 0x033C, 0x035C,
0x3B74, 0x963E, 0xFFFF, 0xFFFF, // 0x0150 (336) pixels
0xD7FC, 0x5C6D, 0x13C6, 0x1C07, 0x1407, 0x1407,
0x04C8, 0x0487, 0x1BE7, 0x1BE7, 0x3B45, 0x3324,
0xA101, 0xA0C0, 0x4984, 0xFFDD, // 0x0160 (352) pixels
0xFFFE, 0x73AD, 0xFF1C, 0xFF9E, 0xD7FF, 0x85DD,
0x03BE, 0x039D, 0x0358, 0x0358, 0x035C, 0x035C,
0x5437, 0xBF9F, 0xFFFF, 0xFFBE, // 0x0170 (368) pixels
0x7D72, 0x3B49, 0x1C07, 0x1C07, 0x1448, 0x1448,
0x04A8, 0x04A8, 0x1C28, 0x1C28, 0x4386, 0x3B86,
0xB142, 0xA101, 0x4984, 0xFFDD, // 0x0180 (384) pixels
0xFFFF, 0x6350, 0xDFBC, 0xEFFD, 0xFFDE, 0xF77D,
0x853A, 0x4B53, 0x2375, 0x2355, 0x3B34, 0x5C18,
0xC63A, 0xFFFF, 0xCFFC, 0x6E11, // 0x0190 (400) pixels
0x04A8, 0x0467, 0x04A7, 0x0487, 0x0466, 0x0C86,
0x0486, 0x04A6, 0x0467, 0x0488, 0x04A7, 0x04C7,
0x0447, 0x03E6, 0x41A8, 0xFFDF, // 0x01A0 (416) pixels
0xFFFF, 0x422B, 0xCF19, 0xEFFD, 0xFFFF, 0xFFFF,
0xE7FF, 0xB69F, 0x6D9E, 0x655D, 0x95DF, 0xC75F,
0xFFDF, 0xFFBF, 0x5D8F, 0x23A8, // 0x01B0 (432) pixels
0x0487, 0x04A8, 0x04A7, 0x04A7, 0x0466, 0x0C86,
0x04C7, 0x04A6, 0x0488, 0x0488, 0x04A7, 0x04A7,
0x0467, 0x0406, 0x49C8, 0xFFDF, // 0x01C0 (448) pixels
0xF7FF, 0x2968, 0x3C5B, 0x7E7F, 0xD7DF, 0xE7FF,
0xEFFF, 0xEFFF, 0xFFFF, 0xF7DF, 0xFFFF, 0xFFBF,
0xD7FC, 0x652F, 0x0487, 0x04A7, // 0x01D0 (464) pixels
0x1447, 0x1447, 0x04A8, 0x0488, 0x0467, 0x0467,
0x0C68, 0x0447, 0x0489, 0x0489, 0x0468, 0x0488,
0x0448, 0x0407, 0x3227, 0xF7FF, // 0x01E0 (480) pixels
0xFFFF, 0x2127, 0x1336, 0x1B97, 0x6433, 0x74D6,
0x9539, 0x9D9A, 0xE75E, 0xFFFF, 0xFFBF, 0xFFFF,
0xAF57, 0x3388, 0x0487, 0x04A8, // 0x01F0 (496) pixels
0x1427, 0x1427, 0x04A8, 0x0488, 0x04A8, 0x0467,
0x0C68, 0x0C68, 0x0469, 0x0469, 0x0468, 0x0488,
0x0448, 0x0407, 0x3227, 0xF7FF, // 0x0200 (512) pixels
0xEFFF, 0x1147, 0x02D9, 0x033A, 0x0B1A, 0x0B1A,
0x137A, 0x349E, 0xF79D, 0xFFFE, 0xFFDF, 0xFFDF,
0x9F9A, 0x23CB, 0x0467, 0x0488, // 0x0210 (528) pixels
0x0C48, 0x0C47, 0x0487, 0x04A7, 0x04A7, 0x04A7,
0x0488, 0x0488, 0x0488, 0x0488, 0x0488, 0x04A8,
0x0428, 0x03E7, 0x3227, 0xF7FF, // 0x0220 (544) pixels
0xEFFF, 0x1167, 0x02D9, 0x02F9, 0x0B1A, 0x02FA,
0x0B39, 0x2C3D, 0xF7DD, 0xFFFE, 0xFFBE, 0xFFDF,
0xC7FF, 0x7E55, 0x0467, 0x0467, // 0x0230 (560) pixels
0x0C68, 0x0C68, 0x04A7, 0x0466, 0x04C7, 0x0486,
0x0467, 0x04A8, 0x0488, 0x0488, 0x0488, 0x04A8,
0x0428, 0x03E7, 0x3227, 0xF7FF, // 0x0240 (576) pixels
0xEFFF, 0x1948, 0x02F7, 0x02F7, 0x0338, 0x0338,
0x0337, 0x243A, 0xCE9D, 0xF7FF, 0xFFFF, 0xFFFF,
0xFFFD, 0xFFFD, 0x9674, 0x43EA, // 0x0250 (592) pixels
0x0447, 0x0488, 0x04A7, 0x04E8, 0x0446, 0x0487,
0x0CA8, 0x0467, 0x0C67, 0x0C67, 0x0487, 0x0487,
0x0468, 0x0427, 0x3A26, 0xFFFE, // 0x0260 (608) pixels
0xF7FF, 0x1948, 0x02F7, 0x0338, 0x0B99, 0x13BA,
0x1BD9, 0x2C7C, 0xA558, 0xF7DF, 0xFFFF, 0xFFFF,
0xFFFD, 0xFFFD, 0xDFFD, 0xB758, // 0x0270 (624) pixels
0x1D8C, 0x0488, 0x0487, 0x0487, 0x0CA8, 0x0467,
0x0C88, 0x0467, 0x0C67, 0x0C67, 0x0487, 0x0487,
0x0468, 0x0427, 0x3A26, 0xFFFE, // 0x0280 (640) pixels
0xEFFF, 0x1186, 0x5336, 0x743A, 0x9558, 0xB63B,
0xCF1A, 0xD75B, 0xFF9A, 0xFFDB, 0xFFFD, 0xFFFD,
0xFFFF, 0xFFDF, 0xFFFF, 0xFFFF, // 0x0290 (656) pixels
0xD79B, 0x640D, 0x0C48, 0x0C69, 0x0447, 0x0447,
0x0C68, 0x0447, 0x0467, 0x0467, 0x0487, 0x0487,
0x0448, 0x0407, 0x3227, 0xF7FF, // 0x02A0 (672) pixels
0xE7FF, 0x3ACB, 0xAE1F, 0xDF7F, 0xEFFF, 0xEFFF,
0xEFFE, 0xE7BD, 0xFF58, 0xF738, 0xF73A, 0xFF9C,
0xF7DF, 0xFFFF, 0xFFFF, 0xFFFF, // 0x02B0 (688) pixels
0xEFFE, 0xDFBC, 0x1CEB, 0x0428, 0x0C68, 0x0447,
0x0447, 0x0C68, 0x0467, 0x0467, 0x0487, 0x0487,
0x0448, 0x0407, 0x3227, 0xF7FF, // 0x02C0 (704) pixels
0xFFFF, 0x738F, 0xF736, 0xFF98, 0xFF0D, 0xFE6B,
0xF646, 0xF625, 0xFDA3, 0xFE04, 0xEDC4, 0xFE66,
0xFF34, 0xFFB6, 0xFFDE, 0xFFFF, // 0x02D0 (720) pixels
0xFFBF, 0xFFDF, 0x9F78, 0x23A9, 0x0468, 0x04CA,
0x0448, 0x0489, 0x04A8, 0x04A8, 0x0487, 0x0487,
0x0448, 0x0407, 0x3227, 0xF7FF, // 0x02E0 (736) pixels
0xFFDF, 0x736F, 0xE6B4, 0xD653, 0xEDE8, 0xE5A7,
0xE5C4, 0xEDE4, 0xFD82, 0xF582, 0xEDC4, 0xEDE4,
0xE5AE, 0xFEB2, 0xFFFF, 0xFFFF, // 0x02F0 (752) pixels
0xFFDF, 0xFFBF, 0xC7FD, 0x552F, 0x0488, 0x0468,
0x0488, 0x0468, 0x04A8, 0x04A8, 0x0487, 0x0487,
0x0448, 0x0407, 0x3227, 0xF7FF, // 0x0300 (768) pixels
0xFFFD, 0x734A, 0xE584, 0xEDC5, 0xF5C1, 0xF5C1,
0xEDC0, 0xEDC0, 0xED82, 0xF5A2, 0xE5E1, 0xE5E1,
0xFDC1, 0xFDE2, 0xE6B2, 0xFFF7, // 0x0310 (784) pixels
0xFFFF, 0xF7FF, 0xEFFE, 0xA5D4, 0x0448, 0x0C89,
0x0468, 0x0468, 0x0487, 0x04A7, 0x0447, 0x0447,
0x0469, 0x03E7, 0x2A27, 0xEFFF, // 0x0320 (800) pixels
0xFFDD, 0x5AA8, 0xDD43, 0xDD64, 0xED80, 0xF5C1,
0xF5E0, 0xEDC0, 0xF5A2, 0xF5A3, 0xE5E1, 0xE5C1,
0xF5A1, 0xF5A1, 0xD60F, 0xF713, // 0x0330 (816) pixels
0xF7FF, 0xFFFF, 0xF7FE, 0xB656, 0x0427, 0x0448,
0x0488, 0x0468, 0x0487, 0x04C8, 0x0C88, 0x0426,
0x0468, 0x03E6, 0x21E6, 0xF7FF, // 0x0340 (832) pixels
0xF7FF, 0x00A2, 0xE501, 0xED62, 0xFD81, 0xFD81,
0xF562, 0xFDA3, 0xE5C0, 0xEDE0, 0xEDC1, 0xEDA0,
0xF5C0, 0xF5C0, 0xEDE3, 0xFE65, // 0x0350 (848) pixels
0xFFDE, 0xFFDE, 0xE7FC, 0xA634, 0x0487, 0x04A8,
0x0488, 0x0467, 0x04C7, 0x0487, 0x0466, 0x0487,
0x1408, 0x0BC7, 0x08A1, 0xFFFE, // 0x0360 (864) pixels
0xF7FF, 0x0060, 0xC420, 0xE542, 0xFD81, 0xFDA2,
0xFDA3, 0xF562, 0xEDE1, 0xEDE1, 0xF5E1, 0xEDC1,
0xF5C0, 0xF5C0, 0xEDC3, 0xFE24, // 0x0370 (880) pixels
0xFFBD, 0xFFDE, 0xEFFD, 0x8551, 0x0487, 0x04A7,
0x0488, 0x0488, 0x04A7, 0x04A7, 0x0487, 0x0487,
0x0BE7, 0x0345, 0x0040, 0xFFFE, // 0x0380 (896) pixels
0xFFDF, 0x0823, 0x3120, 0xACEC, 0xED83, 0xE542,
0xE582, 0xEDA3, 0xF564, 0xED64, 0xF561, 0xF561,
0xF561, 0xF561, 0xDDA7, 0xEE29, // 0x0390 (912) pixels
0xFF5C, 0xFFDF, 0xB7FB, 0x3C4B, 0x0448, 0x0489,
0x1429, 0x1429, 0x0C28, 0x0C69, 0x1408, 0x13E7,
0x3308, 0x0161, 0x0800, 0xFFFF, // 0x03A0 (928) pixels
0xFFDF, 0x0002, 0x1880, 0x3120, 0xC460, 0xDD22,
0xEDA3, 0xDD41, 0xED43, 0xE523, 0xED41, 0xED41,
0xED41, 0xED41, 0xDDA7, 0xEE29, // 0x03B0 (944) pixels
0xFF7D, 0xFF7D, 0x7E73, 0x23A9, 0x0428, 0x0448,
0x0BE8, 0x0BE8, 0x0428, 0x0408, 0x1407, 0x0345,
0x0100, 0x0080, 0x1020, 0xFFFF, // 0x03C0 (960) pixels
0xFFFE, 0x0020, 0x0802, 0x0802, 0x0040, 0x0080,
0x0020, 0x0840, 0x0840, 0x0820, 0x0801, 0x0801,
0x0020, 0x0020, 0x0040, 0x0060, // 0x03D0 (976) pixels
0x0000, 0x1062, 0x0040, 0x0060, 0x1820, 0x1000,
0x0020, 0x0040, 0x0040, 0x0060, 0x0060, 0x00A0,
0x0841, 0x0800, 0x0042, 0xF7FF, // 0x03E0 (992) pixels
0xFFFE, 0xFFFE, 0xFFDF, 0xFFBF, 0xF7FF, 0xF7FF,
0xFFFE, 0xFFFF, 0xFFFE, 0xFFFD, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xF7FF, // 0x03F0 (1008) pixels
0xFFFF, 0xFFDF, 0xEFFF, 0xF7FF, 0xFFBE, 0xFFDF,
0xFFFF, 0xFFFF, 0xF7FF, 0xF7FE, 0xF7FF, 0xF7FE,
0xFFFF, 0xFFFF, 0xF7FF, 0xFFFF, // 0x0400 (1024) pixels
};

View file

@ -1,126 +0,0 @@
// Generated by : UTFTConverter v0.1
// Generated from : smiley_tongue_24.jpg
// Time generated : 2017-04-24 16:31:50.352856 UTC
// Image Size : 24x24 pixels
// Memory usage : 1152 bytes
#if defined(__AVR__)
#include <avr/pgmspace.h>
#elif defined(__PIC32MX__)
#define PROGMEM
#elif defined(__arm__)
#define PROGMEM
#endif
const unsigned short
bitmap24[576] PROGMEM =
{
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, // 0x0010 (16) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, // 0x0020 (32) pixels
0x0000, 0x0000, 0x4207, 0xFFDD, 0xCE57, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, // 0x0030 (48) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0xFFBB, 0xFF56, 0xE501, 0xE501, 0xE501,
0xE501, 0xE501, 0xE564, 0xFF99, // 0x0040 (64) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0xAD33, 0xF6D1, 0xE501, // 0x0050 (80) pixels
0xE501, 0xE501, 0xE501, 0xE501, 0xE501, 0xE501,
0xE501, 0xE501, 0xE501, 0xFF9A, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, // 0x0060 (96) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0xFFBB, 0xE501,
0xE501, 0xE501, 0xE501, 0xE501, 0xE501, 0xE501,
0xE501, 0xE501, 0xE501, 0xE501, // 0x0070 (112) pixels
0xE501, 0xE501, 0xFF57, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFDC,
0xE501, 0xE501, 0xDD01, 0xE501, // 0x0080 (128) pixels
0xE501, 0xE501, 0xE501, 0xE501, 0xE501, 0xE501,
0xE501, 0xE501, 0xDD01, 0xE501, 0xE501, 0xFF78,
0x0000, 0x0000, 0x0000, 0x0000, // 0x0090 (144) pixels
0x0000, 0x0000, 0x0000, 0xE501, 0xDD01, 0xE501,
0xE501, 0xE501, 0xE501, 0xE501, 0xE502, 0xE501,
0xE501, 0xDD01, 0xDD01, 0xE501, // 0x00A0 (160) pixels
0xE501, 0xDD01, 0xE501, 0xE501, 0xE501, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0xFF99, 0xE501,
0xE502, 0xE501, 0x4A69, 0x4A6A, // 0x00B0 (176) pixels
0xE501, 0xE501, 0xE501, 0xE501, 0xE501, 0xE501,
0xE502, 0xE501, 0xE501, 0xE501, 0xE501, 0xE501,
0xDD01, 0x0000, 0x0000, 0x0000, // 0x00C0 (192) pixels
0x0000, 0x0000, 0xE501, 0xE501, 0xE501, 0x0000,
0x0000, 0x0000, 0x0000, 0x94B2, 0xE501, 0xE502,
0xE501, 0xE501, 0xE501, 0xE501, // 0x00D0 (208) pixels
0xDD01, 0xE501, 0xE501, 0xE501, 0xE501, 0xE501,
0x0000, 0x0000, 0x0000, 0xFFDC, 0xE501, 0xE501,
0xE501, 0x0000, 0x4A69, 0xE502, // 0x00E0 (224) pixels
0x4A69, 0x0000, 0xE501, 0xE501, 0xE501, 0xE501,
0xE501, 0x4A69, 0x0000, 0x0000, 0xE501, 0xE501,
0xE501, 0xFF58, 0x0000, 0x0000, // 0x00F0 (240) pixels
0x0000, 0xFF9A, 0xE501, 0xE501, 0xE501, 0xE501,
0xE501, 0xE501, 0xE501, 0x94B3, 0xE501, 0xE501,
0xE501, 0xE502, 0x0000, 0x0000, // 0x0100 (256) pixels
0x4A69, 0x0000, 0x0000, 0xE501, 0xE501, 0xE5A7,
0x0000, 0x0000, 0x0000, 0xFF79, 0xE501, 0xE501,
0xE501, 0xE501, 0xE501, 0xDD01, // 0x0110 (272) pixels
0xE501, 0xE501, 0xE501, 0xE501, 0xE501, 0xE502,
0x94B2, 0xE501, 0xE501, 0xE501, 0x0000, 0xDD01,
0xDD01, 0xE501, 0x0000, 0x0000, // 0x0120 (288) pixels
0x0000, 0xFF79, 0xE501, 0xE501, 0xFE31, 0xFD91,
0xF5B0, 0xF5F1, 0xF5EC, 0xE501, 0xDD01, 0xE501,
0xE501, 0xE501, 0xE501, 0xE501, // 0x0130 (304) pixels
0xE501, 0xE501, 0xE501, 0xE502, 0xE501, 0xE501,
0x0000, 0x0000, 0x0000, 0xFF9A, 0xE501, 0xE501,
0xFE31, 0xF4D0, 0xF800, 0xF800, // 0x0140 (320) pixels
0xF800, 0xDC4D, 0xE4AE, 0xE50F, 0xED90, 0xFE52,
0xE501, 0xE501, 0xE502, 0xE501, 0xE501, 0xE501,
0xE501, 0xEDA7, 0x0000, 0x0000, // 0x0150 (336) pixels
0x0000, 0xFFDC, 0xE501, 0xE501, 0xED66, 0xE48E,
0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xDBAC,
0xE40D, 0xF4F0, 0xF4F0, 0xF530, // 0x0160 (352) pixels
0xFD91, 0xE501, 0xE501, 0xE501, 0xE501, 0xFF57,
0x0000, 0x0000, 0x0000, 0x0000, 0xE501, 0xE501,
0xE501, 0xF800, 0xF800, 0xF800, // 0x0170 (368) pixels
0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800,
0xF800, 0xF4F0, 0xFDB1, 0xDD01, 0xE501, 0xE501,
0xE501, 0xE501, 0x0000, 0x0000, // 0x0180 (384) pixels
0x0000, 0x0000, 0xFF78, 0xE501, 0xED70, 0xF800,
0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800,
0xF800, 0xF800, 0xF800, 0xF550, // 0x0190 (400) pixels
0xE501, 0xE501, 0xDD01, 0xE501, 0xE501, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE501,
0xE50E, 0xF800, 0xF800, 0xF800, // 0x01A0 (416) pixels
0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF4F0,
0xF550, 0xE501, 0xE501, 0xE501, 0xE501, 0xE501,
0xE501, 0x0000, 0x0000, 0x0000, // 0x01B0 (432) pixels
0x0000, 0x0000, 0x0000, 0xFFBC, 0xED90, 0xDC0D,
0xE30A, 0xF800, 0xF800, 0xDC0C, 0xE46E, 0xF510,
0xF570, 0xFE11, 0xE501, 0xE502, // 0x01C0 (448) pixels
0xDD01, 0xE501, 0xE501, 0xFF77, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0xFF7A, 0xE4AE, 0xE3CB, 0xE36A, // 0x01D0 (464) pixels
0xDBCC, 0xDC8E, 0xE501, 0xE501, 0xE501, 0xE501,
0xE501, 0xE501, 0xE501, 0xE501, 0xFF57, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, // 0x01E0 (480) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFF9C,
0xEDD2, 0xED2F, 0xEDB0, 0xDD01, 0xE501, 0xE501,
0xDD01, 0xE501, 0xE521, 0xE501, // 0x01F0 (496) pixels
0xE501, 0xFF99, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0xFFBB, // 0x0200 (512) pixels
0xFF55, 0xE501, 0xE501, 0xE501, 0xE501, 0xE502,
0xE501, 0xFF79, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, // 0x0210 (528) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0xEF5B, 0xE501,
0xE501, 0x2103, 0x0000, 0x0000, // 0x0220 (544) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, // 0x0230 (560) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, // 0x0240 (576) pixels
};

249
examples/bmp/bmp.ino Normal file
View file

@ -0,0 +1,249 @@
/***************************************************
This is a example sketch demonstrating bitmap drawing
capabilities of the SSD1331 library for the 0.96"
16-bit Color OLED with SSD1331 driver chip
Pick one up today in the adafruit shop!
------> http://www.adafruit.com/products/684
These displays use SPI to communicate, 4 or 5 pins are required to
interface
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.
BSD license, all text above must be included in any redistribution
The Adafruit GFX Graphics core library is also required
https://github.com/adafruit/Adafruit-GFX-Library
Be sure to install it!
****************************************************/
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1331.h>
#include <SD.h>
#include <SPI.h>
// If we are using the hardware SPI interface, these are the pins (for future ref)
#define sclk 13
#define mosi 11
#define cs 10
#define rst 9
#define dc 8
// Color definitions
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
// to draw images from the SD card, we will share the hardware SPI interface
Adafruit_SSD1331 tft = Adafruit_SSD1331(cs, dc, rst);
// For Arduino Uno/Duemilanove, etc
// connect the SD card with MOSI going to pin 11, MISO going to pin 12 and SCK going to pin 13 (standard)
// Then pin 4 goes to CS (or whatever you have set up)
#define SD_CS 4 // Set the chip select line to whatever you use (4 doesnt conflict with the library)
// the file itself
File bmpFile;
// information we extract about the bitmap file
int bmpWidth, bmpHeight;
uint8_t bmpDepth, bmpImageoffset;
void setup(void) {
Serial.begin(9600);
pinMode(cs, OUTPUT);
digitalWrite(cs, HIGH);
// initialize the OLED
tft.begin();
Serial.println("init");
tft.fillScreen(BLUE);
delay(500);
Serial.print("Initializing SD card...");
if (!SD.begin(SD_CS)) {
Serial.println("failed!");
while(1);
}
Serial.println("SD OK!");
bmpDraw("violet.bmp", 0, 0);
}
void loop() {
}
// This function opens a Windows Bitmap (BMP) file and
// displays it at the given coordinates. It's sped up
// by reading many pixels worth of data at a time
// (rather than pixel by pixel). Increasing the buffer
// size takes more of the Arduino's precious RAM but
// makes loading a little faster. 20 pixels seems a
// good balance.
#define BUFFPIXEL 20
void bmpDraw(char *filename, int16_t x, int16_t y) {
File bmpFile;
int bmpWidth, bmpHeight; // W+H in pixels
uint8_t bmpDepth; // Bit depth (currently must be 24)
uint32_t bmpImageoffset; // Start of image data in file
uint32_t rowSize; // Not always = bmpWidth; may have padding
uint8_t sdbuffer[3*BUFFPIXEL]; // pixel buffer (R+G+B per pixel)
uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbuffer
boolean goodBmp = false; // Set to true on valid header parse
boolean flip = true; // BMP is stored bottom-to-top
int w, h, row, col, x2, y2, bx1, by1;
uint8_t r, g, b;
uint32_t pos = 0, startTime = millis();
if((x >= tft.width()) || (y >= tft.height())) return;
Serial.println();
Serial.print(F("Loading image '"));
Serial.print(filename);
Serial.println('\'');
// Open requested file on SD card
if ((bmpFile = SD.open(filename)) == NULL) {
Serial.print(F("File not found"));
return;
}
// Parse BMP header
if(read16(bmpFile) == 0x4D42) { // BMP signature
Serial.print(F("File size: ")); Serial.println(read32(bmpFile));
(void)read32(bmpFile); // Read & ignore creator bytes
bmpImageoffset = read32(bmpFile); // Start of image data
Serial.print(F("Image Offset: ")); Serial.println(bmpImageoffset, DEC);
// Read DIB header
Serial.print(F("Header size: ")); Serial.println(read32(bmpFile));
bmpWidth = read32(bmpFile);
bmpHeight = read32(bmpFile);
if(read16(bmpFile) == 1) { // # planes -- must be '1'
bmpDepth = read16(bmpFile); // bits per pixel
Serial.print(F("Bit Depth: ")); Serial.println(bmpDepth);
if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed
goodBmp = true; // Supported BMP format -- proceed!
Serial.print(F("Image size: "));
Serial.print(bmpWidth);
Serial.print('x');
Serial.println(bmpHeight);
// BMP rows are padded (if needed) to 4-byte boundary
rowSize = (bmpWidth * 3 + 3) & ~3;
// If bmpHeight is negative, image is in top-down order.
// This is not canon but has been observed in the wild.
if(bmpHeight < 0) {
bmpHeight = -bmpHeight;
flip = false;
}
// Crop area to be loaded
x2 = x + bmpWidth - 1; // Lower-right corner
y2 = y + bmpHeight - 1;
if((x2 >= 0) && (y2 >= 0)) { // On screen?
w = bmpWidth; // Width/height of section to load/display
h = bmpHeight;
bx1 = by1 = 0; // UL coordinate in BMP file
if(x < 0) { // Clip left
bx1 = -x;
x = 0;
w = x2 + 1;
}
if(y < 0) { // Clip top
by1 = -y;
y = 0;
h = y2 + 1;
}
if(x2 >= tft.width()) w = tft.width() - x; // Clip right
if(y2 >= tft.height()) h = tft.height() - y; // Clip bottom
// Set TFT address window to clipped image bounds
tft.startWrite(); // Requires start/end transaction now
tft.setAddrWindow(x, y, w, h);
for (row=0; row<h; row++) { // For each scanline...
// Seek to start of scan line. It might seem labor-
// intensive to be doing this on every line, but this
// method covers a lot of gritty details like cropping
// and scanline padding. Also, the seek only takes
// place if the file position actually needs to change
// (avoids a lot of cluster math in SD library).
if(flip) // Bitmap is stored bottom-to-top order (normal BMP)
pos = bmpImageoffset + (bmpHeight - 1 - (row + by1)) * rowSize;
else // Bitmap is stored top-to-bottom
pos = bmpImageoffset + (row + by1) * rowSize;
pos += bx1 * 3; // Factor in starting column (bx1)
if(bmpFile.position() != pos) { // Need seek?
tft.endWrite(); // End TFT transaction
bmpFile.seek(pos);
buffidx = sizeof(sdbuffer); // Force buffer reload
tft.startWrite(); // Start new TFT transaction
}
for (col=0; col<w; col++) { // For each pixel...
// Time to read more pixel data?
if (buffidx >= sizeof(sdbuffer)) { // Indeed
tft.endWrite(); // End TFT transaction
bmpFile.read(sdbuffer, sizeof(sdbuffer));
buffidx = 0; // Set index to beginning
tft.startWrite(); // Start new TFT transaction
}
// Convert pixel from BMP to TFT format, push to display
b = sdbuffer[buffidx++];
g = sdbuffer[buffidx++];
r = sdbuffer[buffidx++];
tft.writePixel(tft.color565(r,g,b));
} // end pixel
} // end scanline
tft.endWrite(); // End last TFT transaction
} // end onscreen
Serial.print(F("Loaded in "));
Serial.print(millis() - startTime);
Serial.println(" ms");
} // end goodBmp
}
}
bmpFile.close();
if(!goodBmp) Serial.println(F("BMP format not recognized."));
}
// These read 16- and 32-bit types from the SD card file.
// BMP data is stored little-endian, Arduino is little-endian too.
// May need to reverse subscript order if porting elsewhere.
uint16_t read16(File &f) {
uint16_t result;
((uint8_t *)&result)[0] = f.read(); // LSB
((uint8_t *)&result)[1] = f.read(); // MSB
return result;
}
uint32_t read32(File &f) {
uint32_t result;
((uint8_t *)&result)[0] = f.read(); // LSB
((uint8_t *)&result)[1] = f.read();
((uint8_t *)&result)[2] = f.read();
((uint8_t *)&result)[3] = f.read(); // MSB
return result;
}

BIN
examples/bmp/violet.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View file

@ -1,197 +0,0 @@
/*
* This is an example sketch that shows how to toggle the SSD1331 OLED display
* on and off at runtime to avoid screen burn-in.
*
* The sketch also demonstrates how to erase a previous value by re-drawing the
* older value in the screen background color prior to writing a new value in
* the same location. This avoids the need to call fillScreen() to erase the
* entire screen followed by a complete redraw of screen contents.
*
* Written by Phill Kelley. BSD license.
*/
#include <Arduino.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1331.h>
#include <SPI.h>
#define SerialDebugging true
// The SSD1331 is connected like this (plus VCC plus GND)
const uint8_t OLED_pin_scl_sck = 13;
const uint8_t OLED_pin_sda_mosi = 11;
const uint8_t OLED_pin_cs_ss = 10;
const uint8_t OLED_pin_res_rst = 9;
const uint8_t OLED_pin_dc_rs = 8;
// connect a push button to ...
const uint8_t Button_pin = 2;
// SSD1331 color definitions
const uint16_t OLED_Color_Black = 0x0000;
const uint16_t OLED_Color_Blue = 0x001F;
const uint16_t OLED_Color_Red = 0xF800;
const uint16_t OLED_Color_Green = 0x07E0;
const uint16_t OLED_Color_Cyan = 0x07FF;
const uint16_t OLED_Color_Magenta = 0xF81F;
const uint16_t OLED_Color_Yellow = 0xFFE0;
const uint16_t OLED_Color_White = 0xFFFF;
// The colors we actually want to use
uint16_t OLED_Text_Color = OLED_Color_Black;
uint16_t OLED_Backround_Color = OLED_Color_Blue;
// declare the display
Adafruit_SSD1331 oled =
Adafruit_SSD1331(
OLED_pin_cs_ss,
OLED_pin_dc_rs,
OLED_pin_sda_mosi,
OLED_pin_scl_sck,
OLED_pin_res_rst
);
// assume the display is off until configured in setup()
bool isDisplayVisible = false;
// declare size of working string buffers. Basic strlen("d hh:mm:ss") = 10
const size_t MaxString = 16;
// the string being displayed on the SSD1331 (initially empty)
char oldTimeString[MaxString] = { 0 };
// the interrupt service routine affects this
volatile bool isButtonPressed = false;
// interrupt service routine
void senseButtonPressed() {
if (!isButtonPressed) {
isButtonPressed = true;
}
}
void displayUpTime() {
// calculate seconds, truncated to the nearest whole second
unsigned long upSeconds = millis() / 1000;
// calculate days, truncated to nearest whole day
unsigned long days = upSeconds / 86400;
// the remaining hhmmss are
upSeconds = upSeconds % 86400;
// calculate hours, truncated to the nearest whole hour
unsigned long hours = upSeconds / 3600;
// the remaining mmss are
upSeconds = upSeconds % 3600;
// calculate minutes, truncated to the nearest whole minute
unsigned long minutes = upSeconds / 60;
// the remaining ss are
upSeconds = upSeconds % 60;
// allocate a buffer
char newTimeString[MaxString] = { 0 };
// construct the string representation
sprintf(
newTimeString,
"%lu %02lu:%02lu:%02lu",
days, hours, minutes, upSeconds
);
// has the time string changed since the last oled update?
if (strcmp(newTimeString,oldTimeString) != 0) {
// yes! home the cursor
oled.setCursor(0,0);
// change the text color to the background color
oled.setTextColor(OLED_Backround_Color);
// redraw the old value to erase
oled.print(oldTimeString);
// home the cursor
oled.setCursor(0,0);
// change the text color to foreground color
oled.setTextColor(OLED_Text_Color);
// draw the new time value
oled.print(newTimeString);
// and remember the new value
strcpy(oldTimeString,newTimeString);
}
}
void setup() {
// button press pulls pin LOW so configure HIGH
pinMode(Button_pin,INPUT_PULLUP);
// use an interrupt to sense when the button is pressed
attachInterrupt(digitalPinToInterrupt(Button_pin), senseButtonPressed, FALLING);
#if (SerialDebugging)
Serial.begin(115200); while (!Serial); Serial.println();
#endif
// settling time
delay(250);
// ignore any power-on-reboot garbage
isButtonPressed = false;
// initialise the SSD1331
oled.begin();
oled.setFont();
oled.fillScreen(OLED_Backround_Color);
oled.setTextColor(OLED_Text_Color);
oled.setTextSize(1);
// the display is now on
isDisplayVisible = true;
}
void loop() {
// unconditional display, regardless of whether display is visible
displayUpTime();
// has the button been pressed?
if (isButtonPressed) {
// yes! toggle display visibility
isDisplayVisible = !isDisplayVisible;
// apply
oled.enableDisplay(isDisplayVisible);
#if (SerialDebugging)
Serial.print("button pressed @ ");
Serial.print(millis());
Serial.print(", display is now ");
Serial.println((isDisplayVisible ? "ON" : "OFF"));
#endif
// confirm button handled
isButtonPressed = false;
}
// no need to be in too much of a hurry
delay(100);
}

View file

@ -1,18 +1,18 @@
/***************************************************
/***************************************************
This is a example sketch demonstrating the graphics
capabilities of the SSD1331 library for the 0.96"
capabilities of the SSD1331 library for the 0.96"
16-bit Color OLED with SSD1331 driver chip
Pick one up today in the adafruit shop!
------> http://www.adafruit.com/products/684
These displays use SPI to communicate, 4 or 5 pins are required to
These displays use SPI to communicate, 4 or 5 pins are required to
interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
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.
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
@ -21,7 +21,7 @@
#include <SPI.h>
// You can use any (4 or) 5 pins
// You can use any (4 or) 5 pins
#define sclk 13
#define mosi 11
#define cs 10
@ -36,17 +36,17 @@
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
// Option 1: use any pins but a little slower
//Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, mosi, sclk, rst);
//Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, mosi, sclk, rst);
// Option 2: must use the hardware SPI pins
// (for UNO thats sclk = 13 and sid = 11) and pin 10 must be
// Option 2: must use the hardware SPI pins
// (for UNO thats sclk = 13 and sid = 11) and pin 10 must be
// an output. This is much faster - also required if you want
// to use the microSD card (see the image drawing example)
Adafruit_SSD1331 display = Adafruit_SSD1331(&SPI, cs, dc, rst);
Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, rst);
float p = 3.1415926;
@ -59,13 +59,13 @@ void setup(void) {
uint16_t time = millis();
display.fillScreen(BLACK);
time = millis() - time;
Serial.println(time, DEC);
delay(500);
lcdTestPattern();
delay(1000);
display.fillScreen(BLACK);
display.setCursor(0,0);
display.print("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa");
@ -74,19 +74,19 @@ void setup(void) {
// tft print function!
tftPrintTest();
delay(2000);
//a single pixel
display.drawPixel(display.width()/2, display.height()/2, GREEN);
delay(500);
// line draw test
testlines(YELLOW);
delay(500);
delay(500);
// optimized lines
testfastlines(RED, BLUE);
delay(500);
delay(500);
testdrawrects(GREEN);
delay(1000);
@ -100,10 +100,10 @@ void setup(void) {
testroundrects();
delay(500);
testtriangles();
delay(500);
Serial.println("done");
delay(1000);
}
@ -119,7 +119,7 @@ void testlines(uint16_t color) {
for (int16_t y=0; y < display.height()-1; y+=6) {
display.drawLine(0, 0, display.width()-1, y, color);
}
display.fillScreen(BLACK);
for (int16_t x=0; x < display.width()-1; x+=6) {
display.drawLine(display.width()-1, 0, x, display.height()-1, color);
@ -129,7 +129,7 @@ void testlines(uint16_t color) {
}
// To avoid ESP8266 watchdog timer resets when not using the hardware SPI pins
delay(0);
delay(0);
display.fillScreen(BLACK);
for (int16_t x=0; x < display.width()-1; x+=6) {
@ -146,7 +146,7 @@ void testlines(uint16_t color) {
for (int16_t y=0; y < display.height()-1; y+=6) {
display.drawLine(display.width()-1, display.height()-1, 0, y, color);
}
}
void testdrawtext(char *text, uint16_t color) {
@ -159,7 +159,7 @@ void testdrawtext(char *text, uint16_t color) {
display.write(i);
if ((i > 0) && (i % 21 == 0))
display.println();
}
}
}
void testfastlines(uint16_t color1, uint16_t color2) {
@ -192,7 +192,7 @@ void testfillcircles(uint8_t radius, uint16_t color) {
for (uint8_t y=radius; y < display.height()-1; y+=radius*2) {
display.fillCircle(x, y, radius, color);
}
}
}
}
void testdrawcircles(uint8_t radius, uint16_t color) {
@ -200,7 +200,7 @@ void testdrawcircles(uint8_t radius, uint16_t color) {
for (int16_t y=0; y < display.height()-1+radius; y+=radius*2) {
display.drawCircle(x, y, radius, color);
}
}
}
}
void testtriangles() {
@ -211,7 +211,7 @@ void testtriangles() {
int x = display.height();
int y = 0;
int z = display.width();
for (t = 0 ; t <= 15; t+=1) {
for(t = 0 ; t <= 15; t+=1) {
display.drawTriangle(w, y, y, x, z, x, color);
x-=4;
y+=4;
@ -245,7 +245,7 @@ void testroundrects() {
void tftPrintTest() {
display.fillScreen(BLACK);
display.setCursor(0, 5);
display.setTextColor(RED);
display.setTextColor(RED);
display.setTextSize(1);
display.println("Hello World!");
display.setTextColor(YELLOW, GREEN);
@ -297,7 +297,7 @@ void mediabuttons() {
}
/**************************************************************************/
/*!
/*!
@brief Renders a simple test pattern on the LCD
*/
/**************************************************************************/
@ -305,26 +305,19 @@ void lcdTestPattern(void)
{
uint8_t w,h;
display.setAddrWindow(0, 0, 96, 64);
for (h = 0; h < 64; h++) {
for (w = 0; w < 96; w++) {
if (w > 83) {
display.writePixel(w, h, WHITE);
} else if (w > 71) {
display.writePixel(w, h, BLUE);
} else if (w > 59) {
display.writePixel(w, h, GREEN);
} else if (w > 47) {
display.writePixel(w, h, CYAN);
} else if (w > 35) {
display.writePixel(w, h, RED);
} else if (w > 23) {
display.writePixel(w, h, MAGENTA);
} else if (w > 11) {
display.writePixel(w, h, YELLOW);
} else {
display.writePixel(w, h, BLACK);
}
for(h=0; h<64; h++)
{
for(w=0; w<96; w++)
{
if(w>83){display.writePixel(WHITE);}
else if(w>71){display.writePixel(BLUE);}
else if(w>59){display.writePixel(GREEN);}
else if(w>47){display.writePixel(CYAN);}
else if(w>35){display.writePixel(RED);}
else if(w>23){display.writePixel(MAGENTA);}
else if(w>11){display.writePixel(YELLOW);}
else {display.writePixel(BLACK);}
}
}
display.endWrite();

View file

@ -1,5 +1,5 @@
name=Adafruit SSD1331 OLED Driver Library for Arduino
version=1.3.0
version=1.0.2
author=Adafruit
maintainer=Adafruit <info@adafruit.com>
sentence=For 0.96" OLEDs in the Adafruit shop
@ -7,4 +7,3 @@ paragraph=For 0.96" OLEDs in the Adafruit shop
category=Display
url=https://github.com/adafruit/Adafruit-SSD1331-OLED-Driver-Library-for-Arduino
architectures=*
depends=Adafruit GFX Library