Code:
/*********************************************************************
This is a library for our Monochrome OLEDs based on SSD1306h drivers
Pick one up today in the adafruit shop!
------> http://www.adafruit.com/category/63_98
These displays use SPI to communicate, 4 or 5 pins are required to
interface
http://forum.arduino.cc/index.php/topic,108542
You also need to add this to the start of your sketch:
Code:
#include <SPI.h>
You also need to use different pin-outs to use the hardware SPI. Replace the defines at the top of the sketch with these ones:
Code:
#define OLED_DC 8 // pin 9 on CD4050B (output: pin 10)
#define OLED_CS 10 // pin 5 on CD4050B (output: pin 4)
#define OLED_CLK 13 // pin 11 on CD4050B (output: pin 12)
#define OLED_MOSI 11 // pin 14 on CD4050B (output: pin 15)
#define OLED_RESET 7 // pin 3 on CD4050B (output: pin 2)
The wiring now needs to be:
Code:
Signal Chip out --> Arduino pin
Reset 3 --> 7 (was 13)
CS 5 --> 10 (was 12)
D/C 9 --> 8 (was 11)
CLK 11 --> 13 (was 10)
DAT/MOSI 14 --> 11 (was 9)
*********************************************************************/
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <stdlib.h>
#include <Wire.h>
#include <SPI.h>
#include "Adafruit_GFX.h"
#include "Adafruit_SSD1306h.h"
//#include "glcdfont.c"
// a 5x7 font table
extern uint8_t PROGMEM font[];
// the memory buffer for the LCD
static uint8_t buffer[SSD1306h_LCDHEIGHT * SSD1306h_LCDWIDTH / 8] = {
0x00, 0x7C, 0x7C, 0xEC, 0x8C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C, 0xFC, 0xF0,
0xE0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xC0, 0xF0, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xCC, 0xFC, 0xFC, 0x7C,
0x3C, 0x3C, 0x7C, 0xFC, 0xCC, 0x8C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xCC, 0xFC,
0x7C, 0x7C, 0x3C, 0x3C, 0x7C, 0xFC, 0x8C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1C, 0x38, 0x70, 0xE0,
0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC,
0xFC, 0x1C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x8C, 0xFC, 0xFC, 0x7C, 0x7C, 0x7C, 0x7C,
0xFC, 0xDC, 0x8C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1C, 0x1C, 0x1C, 0x1C, 0xDC, 0xFC, 0xFC, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
0x0F, 0x1F, 0x7E, 0xF8, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xF0, 0x3C,
0x0F, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x03, 0x07, 0x0E, 0x1C, 0x38, 0xF0, 0xE0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x07, 0x1F, 0x7F, 0xFC, 0xF0, 0xE0, 0xF0, 0x7C, 0x1F, 0x07, 0x00, 0x00,
0x00, 0x80, 0xF0, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFC, 0xF0,
0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0E, 0x1C, 0x38, 0x78, 0xF8, 0xFF,
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFE, 0x7C, 0x70,
0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x07, 0x01, 0x00, 0x00, 0x80, 0xE0, 0xF8,
0xFE, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x01,
0x01, 0x01, 0x07, 0x0F, 0x1E, 0x3C, 0x78, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0xC0, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x01, 0x07, 0x1E, 0x38, 0xE0, 0x80, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xF8, 0xFE, 0x3F, 0x1F, 0x03,
0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xC0, 0x80,
0x80, 0x80, 0xC0, 0xE0, 0x7F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xC0,
0x80, 0x80, 0x80, 0x80, 0xC0, 0xF0, 0x7F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0E, 0x3C, 0x78, 0xF0, 0xE0,
0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0xC0, 0x80, 0x80, 0xC0, 0xC0,
0xF0, 0x7F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x80, 0x00, 0x00,
0x00, 0x0F, 0x0F, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0E, 0x0F, 0x0F, 0x0F, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0E, 0x0C, 0x0C, 0x0F, 0x0F, 0x0B, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0F, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0x0F, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0C, 0x0C, 0x0C, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x03, 0x0F, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x0F, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0x30, 0x10,
0x10, 0xFC, 0xFC, 0x00, 0x00, 0xE8, 0xE8, 0x00, 0x60, 0xF0, 0x90, 0xF0, 0x70, 0x10, 0x00, 0xE8,
0xE8, 0x00, 0x10, 0xF8, 0xF8, 0x10, 0x10, 0x80, 0x90, 0xD0, 0x50, 0xF0, 0xE0, 0x00, 0xFC, 0xFC,
0x00, 0x00, 0x00, 0xFC, 0xFC, 0x10, 0x10, 0xF0, 0xE0, 0x00, 0x00, 0xE8, 0xE8, 0x00, 0xF0, 0xF0,
0x30, 0x10, 0x10, 0x00, 0x10, 0xF8, 0xF8, 0x10, 0x10, 0x00, 0xFC, 0xFC, 0x30, 0xF0, 0xE0, 0x00,
0x00, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0xB0, 0x10, 0x10, 0x10, 0x00, 0xE0, 0xF0, 0x10, 0x10, 0x10,
0xF0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0xFC, 0xFC,
0xF0, 0x90, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x05, 0x07, 0x02, 0x00, 0x01,
0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01,
0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00,
0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// the most basic function, set a single pixel
void Adafruit_SSD1306h::drawPixel(int16_t x, int16_t y, uint16_t color) {
if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
return;
// check rotation, move pixel around if necessary
switch (getRotation()) {
case 1:
swap(x, y);
x = WIDTH - x - 1;
break;
case 2:
x = WIDTH - x - 1;
y = HEIGHT - y - 1;
break;
case 3:
swap(x, y);
y = HEIGHT - y - 1;
break;
}
// x is which column
if (color == WHITE)
buffer[x+ (y/8)*SSD1306h_LCDWIDTH] |= _BV((y%8));
else
buffer[x+ (y/8)*SSD1306h_LCDWIDTH] &= ~_BV((y%8));
}
Adafruit_SSD1306h::Adafruit_SSD1306h(int8_t SID, int8_t SCLK, int8_t DC, int8_t RST, int8_t CS) {
cs = CS;
rst = RST;
dc = DC;
sclk = SCLK;
sid = SID;
}
// initializer for I2C - we only indicate the reset pin!
Adafruit_SSD1306h::Adafruit_SSD1306h(int8_t reset) {
sclk = dc = cs = sid = -1;
rst = reset;
}
void Adafruit_SSD1306h::begin(uint8_t vccstate, uint8_t i2caddr) {
#ifdef SSD1306h_128_64
constructor(128, 64);
#endif
#ifdef SSD1306h_128_32
constructor(128, 32);
#endif
_i2caddr = i2caddr;
// set pin directions
if (sid != -1)
{
// SPI
pinMode(sid, OUTPUT);
pinMode(sclk, OUTPUT);
pinMode(dc, OUTPUT);
pinMode(cs, OUTPUT);
clkport = portOutputRegister(digitalPinToPort(sclk));
clkpinmask = digitalPinToBitMask(sclk);
mosiport = portOutputRegister(digitalPinToPort(sid));
mosipinmask = digitalPinToBitMask(sid);
csport = portOutputRegister(digitalPinToPort(cs));
cspinmask = digitalPinToBitMask(cs);
dcport = portOutputRegister(digitalPinToPort(dc));
dcpinmask = digitalPinToBitMask(dc);
SPI.begin ();
//SPI.setClockDivider (SPI_CLOCK_DIV2);
}
else
{
// I2C Init
Wire.begin(); // Is this the right place for this?
}
// Setup reset pin direction (used by both SPI and I2C)
pinMode(rst, OUTPUT);
digitalWrite(rst, HIGH);
// VDD (3.3V) goes high at start, lets just chill for a ms
delay(1);
// bring reset low
digitalWrite(rst, LOW);
// wait 10ms
delay(10);
// bring out of reset
digitalWrite(rst, HIGH);
// turn on VCC (9V?)
#if defined SSD1306h_128_32
// Init sequence for 128x32 OLED module
ssd1306h_command(SSD1306h_DISPLAYOFF); // 0xAE
ssd1306h_command(SSD1306h_SETDISPLAYCLOCKDIV); // 0xD5
ssd1306h_command(0x80); // the suggested ratio 0x80
ssd1306h_command(SSD1306h_SETMULTIPLEX); // 0xA8
ssd1306h_command(0x1F);
ssd1306h_command(SSD1306h_SETDISPLAYOFFSET); // 0xD3
ssd1306h_command(0x0); // no offset
ssd1306h_command(SSD1306h_SETSTARTLINE | 0x0); // line #0
ssd1306h_command(SSD1306h_CHARGEPUMP); // 0x8D
if (vccstate == SSD1306h_EXTERNALVCC)
{ ssd1306h_command(0x10); }
else
{ ssd1306h_command(0x14); }
ssd1306h_command(SSD1306h_MEMORYMODE); // 0x20
ssd1306h_command(0x00); // 0x0 act like ks0108
ssd1306h_command(SSD1306h_SEGREMAP | 0x1);
ssd1306h_command(SSD1306h_COMSCANDEC);
ssd1306h_command(SSD1306h_SETCOMPINS); // 0xDA
ssd1306h_command(0x02);
ssd1306h_command(SSD1306h_SETCONTRAST); // 0x81
ssd1306h_command(0x8F);
ssd1306h_command(SSD1306h_SETPRECHARGE); // 0xd9
if (vccstate == SSD1306h_EXTERNALVCC)
{ ssd1306h_command(0x22); }
else
{ ssd1306h_command(0xF1); }
ssd1306h_command(SSD1306h_SETVCOMDETECT); // 0xDB
ssd1306h_command(0x40);
ssd1306h_command(SSD1306h_DISPLAYALLON_RESUME); // 0xA4
ssd1306h_command(SSD1306h_NORMALDISPLAY); // 0xA6
#endif
#if defined SSD1306h_128_64
// Init sequence for 128x64 OLED module
ssd1306h_command(SSD1306h_DISPLAYOFF); // 0xAE
ssd1306h_command(SSD1306h_SETDISPLAYCLOCKDIV); // 0xD5
ssd1306h_command(0x80); // the suggested ratio 0x80
ssd1306h_command(SSD1306h_SETMULTIPLEX); // 0xA8
ssd1306h_command(0x3F);
ssd1306h_command(SSD1306h_SETDISPLAYOFFSET); // 0xD3
ssd1306h_command(0x0); // no offset
ssd1306h_command(SSD1306h_SETSTARTLINE | 0x0); // line #0
ssd1306h_command(SSD1306h_CHARGEPUMP); // 0x8D
if (vccstate == SSD1306h_EXTERNALVCC)
{ ssd1306h_command(0x10); }
else
{ ssd1306h_command(0x14); }
ssd1306h_command(SSD1306h_MEMORYMODE); // 0x20
ssd1306h_command(0x00); // 0x0 act like ks0108
ssd1306h_command(SSD1306h_SEGREMAP | 0x1);
ssd1306h_command(SSD1306h_COMSCANDEC);
ssd1306h_command(SSD1306h_SETCOMPINS); // 0xDA
ssd1306h_command(0x12);
ssd1306h_command(SSD1306h_SETCONTRAST); // 0x81
if (vccstate == SSD1306h_EXTERNALVCC)
{ ssd1306h_command(0x9F); }
else
{ ssd1306h_command(0xCF); }
ssd1306h_command(SSD1306h_SETPRECHARGE); // 0xd9
if (vccstate == SSD1306h_EXTERNALVCC)
{ ssd1306h_command(0x22); }
else
{ ssd1306h_command(0xF1); }
ssd1306h_command(SSD1306h_SETVCOMDETECT); // 0xDB
ssd1306h_command(0x40);
ssd1306h_command(SSD1306h_DISPLAYALLON_RESUME); // 0xA4
ssd1306h_command(SSD1306h_NORMALDISPLAY); // 0xA6
#endif
ssd1306h_command(SSD1306h_DISPLAYON);//--turn on oled panel
}
void Adafruit_SSD1306h::invertDisplay(uint8_t i) {
if (i) {
ssd1306h_command(SSD1306h_INVERTDISPLAY);
} else {
ssd1306h_command(SSD1306h_NORMALDISPLAY);
}
}
void Adafruit_SSD1306h::ssd1306h_command(uint8_t c) {
if (sid != -1)
{
// SPI
//digitalWrite(cs, HIGH);
*csport |= cspinmask;
//digitalWrite(dc, LOW);
*dcport &= ~dcpinmask;
//digitalWrite(cs, LOW);
*csport &= ~cspinmask;
fastSPIwrite(c);
//digitalWrite(cs, HIGH);
*csport |= cspinmask;
}
else
{
// I2C
uint8_t control = 0x00; // Co = 0, D/C = 0
Wire.beginTransmission(_i2caddr);
Wire.write(control);
Wire.write(c);
Wire.endTransmission();
}
}
// startscrollright
// Activate a right handed scroll for rows start through stop
// Hint, the display is 16 rows tall. To scroll the whole display, run:
// display.scrollright(0x00, 0x0F)
void Adafruit_SSD1306h::startscrollright(uint8_t start, uint8_t stop){
ssd1306h_command(SSD1306h_RIGHT_HORIZONTAL_SCROLL);
ssd1306h_command(0X00);
ssd1306h_command(start);
ssd1306h_command(0X00);
ssd1306h_command(stop);
ssd1306h_command(0X01);
ssd1306h_command(0XFF);
ssd1306h_command(SSD1306h_ACTIVATE_SCROLL);
}
// startscrollleft
// Activate a right handed scroll for rows start through stop
// Hint, the display is 16 rows tall. To scroll the whole display, run:
// display.scrollright(0x00, 0x0F)
void Adafruit_SSD1306h::startscrollleft(uint8_t start, uint8_t stop){
ssd1306h_command(SSD1306h_LEFT_HORIZONTAL_SCROLL);
ssd1306h_command(0X00);
ssd1306h_command(start);
ssd1306h_command(0X00);
ssd1306h_command(stop);
ssd1306h_command(0X01);
ssd1306h_command(0XFF);
ssd1306h_command(SSD1306h_ACTIVATE_SCROLL);
}
// startscrolldiagright
// Activate a diagonal scroll for rows start through stop
// Hint, the display is 16 rows tall. To scroll the whole display, run:
// display.scrollright(0x00, 0x0F)
void Adafruit_SSD1306h::startscrolldiagright(uint8_t start, uint8_t stop){
ssd1306h_command(SSD1306h_SET_VERTICAL_SCROLL_AREA);
ssd1306h_command(0X00);
ssd1306h_command(SSD1306h_LCDHEIGHT);
ssd1306h_command(SSD1306h_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL);
ssd1306h_command(0X00);
ssd1306h_command(start);
ssd1306h_command(0X00);
ssd1306h_command(stop);
ssd1306h_command(0X01);
ssd1306h_command(SSD1306h_ACTIVATE_SCROLL);
}
// startscrolldiagleft
// Activate a diagonal scroll for rows start through stop
// Hint, the display is 16 rows tall. To scroll the whole display, run:
// display.scrollright(0x00, 0x0F)
void Adafruit_SSD1306h::startscrolldiagleft(uint8_t start, uint8_t stop){
ssd1306h_command(SSD1306h_SET_VERTICAL_SCROLL_AREA);
ssd1306h_command(0X00);
ssd1306h_command(SSD1306h_LCDHEIGHT);
ssd1306h_command(SSD1306h_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL);
ssd1306h_command(0X00);
ssd1306h_command(start);
ssd1306h_command(0X00);
ssd1306h_command(stop);
ssd1306h_command(0X01);
ssd1306h_command(SSD1306h_ACTIVATE_SCROLL);
}
void Adafruit_SSD1306h::stopscroll(void){
ssd1306h_command(SSD1306h_DEACTIVATE_SCROLL);
}
void Adafruit_SSD1306h::ssd1306h_data(uint8_t c) {
if (sid != -1)
{
// SPI
//digitalWrite(cs, HIGH);
*csport |= cspinmask;
//digitalWrite(dc, HIGH);
*dcport |= dcpinmask;
//digitalWrite(cs, LOW);
*csport &= ~cspinmask;
fastSPIwrite(c);
//digitalWrite(cs, HIGH);
*csport |= cspinmask;
}
else
{
// I2C
uint8_t control = 0x40; // Co = 0, D/C = 1
Wire.beginTransmission(_i2caddr);
Wire.write(control);
Wire.write(c);
Wire.endTransmission();
}
}
void Adafruit_SSD1306h::display(void) {
ssd1306h_command(SSD1306h_SETLOWCOLUMN | 0x0); // low col = 0
ssd1306h_command(SSD1306h_SETHIGHCOLUMN | 0x0); // hi col = 0
ssd1306h_command(SSD1306h_SETSTARTLINE | 0x0); // line #0
if (sid != -1)
{
// SPI
*csport |= cspinmask;
*dcport |= dcpinmask;
*csport &= ~cspinmask;
for (uint16_t i=0; i<(SSD1306h_LCDWIDTH*SSD1306h_LCDHEIGHT/8); i++) {
fastSPIwrite(buffer[i]);
//ssd1306h_data(buffer[i]);
}
// i wonder why we have to do this (check datasheet)
if (SSD1306h_LCDHEIGHT == 32) {
for (uint16_t i=0; i<(SSD1306h_LCDWIDTH*SSD1306h_LCDHEIGHT/8); i++) {
//ssd1306h_data(0);
fastSPIwrite(0);
}
}
*csport |= cspinmask;
}
else
{
// save I2C bitrate
//uint8_t twbrbackup = TWBR;
//TWBR = 12; // upgrade to 400KHz!
//Serial.println(TWBR, DEC);
//Serial.println(TWSR & 0x3, DEC);
// I2C
for (uint16_t i=0; i<(SSD1306h_LCDWIDTH*SSD1306h_LCDHEIGHT/8); i++) {
// send a bunch of data in one xmission
Wire.beginTransmission(_i2caddr);
Wire.write(0x40);
for (uint8_t x=0; x<16; x++) {
Wire.write(buffer[i]);
i++;
}
i--;
Wire.endTransmission();
}
// i wonder why we have to do this (check datasheet)
if (SSD1306h_LCDHEIGHT == 32) {
for (uint16_t i=0; i<(SSD1306h_LCDWIDTH*SSD1306h_LCDHEIGHT/8); i++) {
// send a bunch of data in one xmission
Wire.beginTransmission(_i2caddr);
Wire.write(0x40);
for (uint8_t x=0; x<16; x++) {
Wire.write((uint8_t)0x00);
i++;
}
i--;
Wire.endTransmission();
}
}
//TWBR = twbrbackup;
}
}
// clear everything
void Adafruit_SSD1306h::clearDisplay(void) {
memset(buffer, 0, (SSD1306h_LCDWIDTH*SSD1306h_LCDHEIGHT/8));
}
inline void Adafruit_SSD1306h::fastSPIwrite(uint8_t d){
SPI.transfer (d);
}
inline void Adafruit_SSD1306h::slowSPIwrite(uint8_t d) {
for (int8_t i=7; i>=0; i--) {
digitalWrite(sclk, LOW);
if (d & _BV(i)) {
digitalWrite(sid, HIGH);
} else {
digitalWrite(sid, LOW);
}
digitalWrite(sclk, HIGH);
}
}
the great thing with the new max31855 library is that you can use multiple devices as i have a quad board.