Introduction: Small E-reader With Oled + Arduino, Test

About: Married to Domestic_Engineer (but I call her Meghan).

This is my first pass at a very small e-reader using an oled screen and an arduino. The goal is to read any text file from an SD card with a form factor < 1 square inch.

This instructable is only the very basic setup, it does not include the SD card.

Step 1: Parts

Oled screen from with board from Tindie:

https://www.tindie.com/products/miker/096-oled-spi...

(screen only here:

http://www.buydisplay.com/default/datasheet-128x64...

Arduino UNO -- I also used an Arduino MEGA

Arduino Libraries from Adafruit Ind:

-Adafruit_SSD1306

Adafruit_GFX

https://learn.adafruit.com/monochrome-oled-breakou...

Step 2: Wiring

Here is the wiring from the OLED to Arduino UNO or MEGA

OLED to Arduino

CS -----D9 (slave select)

MOSI---D11 (spi bus)

SCK---D13 (spi bus)

Reset---D8

DC ----D6

note - D10 set to output for ArduinoUNO (D53 to output on MEGA)

Here is the compatible wiring to add an SD card (I HAVE NOT TRIED THIS YET 1/11/15)

SD ---- Arduino UNO ------TQFP Physical Pin

CS -- D10 (slave select) ------- P14

MOSI -- D11 (spi bus) -------P15

SCK -- D13 (spi bus) --------P 17

MISO - D12 (spi bus) --------P16

CD - D2 -------------P25

note - D10 set to output

Step 3: Code for OLED Reader

This sketch loads the adafruit oled and graphix library.

If loaded on an arduinoUNO, including the SD.h libarary will screw it up. It uses too much SRAM. This problem can be fixed by:

1 - Writing efficient code (yeah..... no)

2 - Using an Arduino mega (works, and confirms that it is a memory problem)

3 - Adding more SRAM (you will need the SpiRAM library http://playground.arduino.cc/Main/SpiRAM and a physical chip with more SRAM

http://ww1.microchip.com/downloads/en/DeviceDoc/22... at digikey

http://www.digikey.com/product-detail/en/23A256-I%...

4 - Comment out the SD.h libary for now.

5 - Replace SD.h with SdFat.h (

https://github.com/greiman/SdFat )

6 - run on Teensey 3.1 -- plenty of memory, code compiles and loads but have not tested with OLED

Here is the code for the UNO without the SD.h libary:

<span style="color: rgb(126,126,126);">///note - D10 set to output</span>

<span style="color: rgb(126,126,126);">//for sd</span>
<span style="color: rgb(126,126,126);">//#include <SD.h></span>

#include <<span style="color: rgb(204,102,0);">SPI</span>.h>
#include <<span style="color: rgb(204,102,0);">Wire</span>.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>



<span style="color: rgb(126,126,126);">//////////////MPC New PINS /////////////</span>
<span style="color: rgb(126,126,126);">// If using software SPI (the default case):</span>
#define OLED_MOSI   11
#define OLED_CLK    13
#define OLED_DC     6
#define OLED_CS     9
#define OLED_RESET  8
Adafruit_SSD1306 <span style="color: rgb(204,102,0);">display</span>(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);


<span style="color: rgb(204,102,0);">void</span> <span style="color: rgb(204,102,0);"><b>setup</b></span>()   {                
  <span style="color: rgb(204,102,0);"><b>Serial</b></span>.<span style="color: rgb(204,102,0);">begin</span>(9600);
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">begin</span>(SSD1306_SWITCHCAPVCC);  <span style="color: rgb(126,126,126);">// internal 3.3V line</span>
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">display</span>();
  <span style="color: rgb(204,102,0);">delay</span>(2000);
  <span style="color: rgb(204,102,0);">display</span>.clearDisplay();
  
  <span style="color: rgb(204,102,0);">pinMode</span>(10,<span style="color: rgb(0,102,153);">OUTPUT</span>);
 
  
 
}

<span style="color: rgb(204,102,0);">void</span> <span style="color: rgb(204,102,0);"><b>loop</b></span>(){  
  <span style="color: rgb(126,126,126);">//FlashRead Test</span>
  <span style="color: rgb(204,102,0);">int</span> t = 55;
  <span style="color: rgb(204,102,0);">int</span> x = 0;
  <span style="color: rgb(204,102,0);">int</span> y = 20;
  <span style="color: rgb(204,102,0);">int</span> s = 2; <span style="color: rgb(126,126,126);">//text scale</span>
  <span style="color: rgb(204,102,0);">int</span> w =12; <span style="color: rgb(126,126,126);">//pixel width of one letter</span>
  <span style="color: rgb(204,102,0);">display</span>.setTextSize(s);
  <span style="color: rgb(204,102,0);">display</span>.setTextColor(WHITE);  <span style="color: rgb(126,126,126);">//is this needed?</span>
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">setCursor</span>(0,0);       
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">print</span>(<span style="color: rgb(0,102,153);">"t="</span>);
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">print</span>(t);
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">println</span>(<span style="color: rgb(0,102,153);">","</span>);
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">print</span>(<span style="color: rgb(0,102,153);">"Size="</span>);
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">print</span>(s);
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">display</span>();
   <span style="color: rgb(204,102,0);">delay</span>(1000);
   <span style="color: rgb(204,102,0);">display</span>.clearDisplay();
   <span style="color: rgb(204,102,0);">delay</span>(2000);
   
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">setCursor</span>(64-1.5*w,y); <span style="color: rgb(126,126,126);">// x = screen width - letter count x letter width</span>
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">print</span>(<span style="color: rgb(0,102,153);">"Now, "</span>);
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">display</span>();
  <span style="color: rgb(204,102,0);">delay</span>(3*t);
  <span style="color: rgb(204,102,0);">delay</span>(2*t);             <span style="color: rgb(126,126,126);">//punctuations get 2t</span>
  <span style="color: rgb(204,102,0);">display</span>.clearDisplay();
  
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">setCursor</span>(64-1*w,y);  
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">print</span>(<span style="color: rgb(0,102,153);">"is "</span>);
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">display</span>();
  <span style="color: rgb(204,102,0);">delay</span>(3*t);           <span style="color: rgb(126,126,126);">//minimum is 3t</span>
  <span style="color: rgb(204,102,0);">display</span>.clearDisplay();
  
 <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">setCursor</span>(64-1.5*w,y);  
 <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">print</span>(<span style="color: rgb(0,102,153);">"the "</span>);
<span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">display</span>();
  <span style="color: rgb(204,102,0);">delay</span>(3*t);
  <span style="color: rgb(204,102,0);">display</span>.clearDisplay();
  
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">setCursor</span>(64-3*w,y);  
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">print</span>(<span style="color: rgb(0,102,153);">"winter "</span>);
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">display</span>();
  <span style="color: rgb(204,102,0);">delay</span>(5*t);
  <span style="color: rgb(204,102,0);">display</span>.clearDisplay();
  
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">setCursor</span>(64-1*w,y);  
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">print</span>(<span style="color: rgb(0,102,153);">"of "</span>);
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">display</span>();
  <span style="color: rgb(204,102,0);">delay</span>(3*t);        <span style="color: rgb(126,126,126);">//minimum is 3t</span>
  <span style="color: rgb(204,102,0);">display</span>.clearDisplay();
  
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">setCursor</span>(64-1.5*w,y);  
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">print</span>(<span style="color: rgb(0,102,153);">"our "</span>);
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">display</span>();
  <span style="color: rgb(204,102,0);">delay</span>(3*t);
  <span style="color: rgb(204,102,0);">display</span>.clearDisplay();
  
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">setCursor</span>(64-5*w,y);  
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">print</span>(<span style="color: rgb(0,102,153);">"discontent "</span>);
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">display</span>();
  <span style="color: rgb(204,102,0);">delay</span>(10*t);
  <span style="color: rgb(204,102,0);">display</span>.clearDisplay();
  
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">setCursor</span>(64-2*w,y);  
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">print</span>(<span style="color: rgb(0,102,153);">"made "</span>);
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">display</span>();
  <span style="color: rgb(204,102,0);">delay</span>(4*t);
  <span style="color: rgb(204,102,0);">display</span>.clearDisplay();
  
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">setCursor</span>(64-4*w,y);  
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">print</span>(<span style="color: rgb(0,102,153);">"glorious "</span>);
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">display</span>();
  <span style="color: rgb(204,102,0);">delay</span>(8*t);
  <span style="color: rgb(204,102,0);">display</span>.clearDisplay();
  
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">setCursor</span>(64-3*w,y);  
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">print</span>(<span style="color: rgb(0,102,153);">"summer "</span>);
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">display</span>();
  <span style="color: rgb(204,102,0);">delay</span>(6*t);
  <span style="color: rgb(204,102,0);">display</span>.clearDisplay();
  
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">setCursor</span>(64-1*w,y);  
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">print</span>(<span style="color: rgb(0,102,153);">"by "</span>);
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">display</span>();
  <span style="color: rgb(204,102,0);">delay</span>(3*t);        <span style="color: rgb(126,126,126);">//minimum is 3t</span>
  <span style="color: rgb(204,102,0);">display</span>.clearDisplay();
  
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">setCursor</span>(64-2*w,y);  
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">print</span>(<span style="color: rgb(0,102,153);">"this "</span>);
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">display</span>();
  <span style="color: rgb(204,102,0);">delay</span>(4*t);
  <span style="color: rgb(204,102,0);">display</span>.clearDisplay();
  
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">setCursor</span>(64-1.5*w,y);  
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">print</span>(<span style="color: rgb(0,102,153);">"son "</span>);
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">display</span>();
  <span style="color: rgb(204,102,0);">delay</span>(3*t);        
  <span style="color: rgb(204,102,0);">display</span>.clearDisplay();
  
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">setCursor</span>(64-1*w,y);  
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">print</span>(<span style="color: rgb(0,102,153);">"of "</span>);
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">display</span>();
  <span style="color: rgb(204,102,0);">delay</span>(3*t);        <span style="color: rgb(126,126,126);">//minimum is 3t        //minimum is 3t        //minimum is 3t</span>
  <span style="color: rgb(204,102,0);">display</span>.clearDisplay();
  
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">setCursor</span>(64-2*w,y);  
   <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">print</span>(<span style="color: rgb(0,102,153);">"York. "</span>);
  <span style="color: rgb(204,102,0);">display</span>.<span style="color: rgb(204,102,0);">display</span>();
  <span style="color: rgb(204,102,0);">delay</span>(5*t);
  <span style="color: rgb(204,102,0);">display</span>.clearDisplay();
  <span style="color: rgb(204,102,0);">delay</span>(2000);
}






Step 4: About the Code

The code on the previous step does NOT read from SD card. The text is simply included in the body of the code. This is only useful for testing.

Here are the basic parameters that determine how the text is diplayed:

int t = 55; // Time in milliseconds that each letter is displayed (so, I five letter word is shown for 5*55 milliseconds)

int x = 0; // Starting X coordinate

int y = 20; // Strating Y coordinate (about halfway down the screen)

int s = 2; //text scale (this is ASCII 5x7 pixel times doubled)

int w =12; //pixel width of one letter, used to offset each word so it is in the center of the screen.

Here is the code that displays the word ¨summer¨. This will be made fancier when text is pulled from an SD card.

display.setCursor(64-3*w,y);

//centers word on screen, X=64-3*w (64 is half the width of the screen, 3 is half the number of letters in the word, w is the width of one letter), Y = 20, this about halfway down the screen.

display.print("summer "); //loads the word that will be displayed

display.display(); // displays the loaded word on the screen

delay(6*t);

//pause, while the word is displayed on the screen (time = number of letters * time that each letter is displayed)

display.clearDisplay();

//clears the display, so the word is no longer shown (if this was not done all the

display.setCursor(64-1.5*w,y);
display.print("Now, "); display.display(); delay(3*t); delay(2*t); //punctuations get 2t display.clearDisplay();

words would just pile up until the screen was all white)

Other rules:

For readability I made a two additional rules:

Rule 1 - the miniumum time any word is displayed is 3*t

Rule 2 - a puncutation adds 2*t

Example of rule one:

display.setCursor(64-1*w,y);
display.print("is ");

display.display();

delay(3*t); //minimum is 3t

display.clearDisplay();

Example of rule Two

display.setCursor(64-1.5*w,y);
display.print("Now, ");

display.display();

delay(3*t);

delay(2*t); //punctuations get 2t

display.clearDisplay();

Step 5: Video

Here is video running on the arduino Mega:

Step 6: Teensy 3.1 to OLED

OLEN can be esily connected to Teensy 3.1 with this pin map:

//////////////MPC New PINS for TEENSY DIRECT //////////// If using software SPI (the default case):
#define OLED_MOSI   19
#define OLED_CLK    20
#define OLED_DC     21
#define OLED_CS     23    
#define OLED_RESET  22
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);