4

Como conectar una pantalla OLED SSD1306 con Arduino sin librerías

Saludos, humano. Al habla Transductor. ¿Alguna vez has intentado hacer funcionar una pantalla OLED con Arduino? Estas pantallas son ideales para mostrar todo tipo de textos y gráficos: lecturas de sensores, actuadores, debugs de Arduino… su pequeño tamaño y bajo coste las convierte en una buena opción para cualquier proyecto.

Hoy aprenderás a hacer funcionar una de estas micropantallas con Arduino. Existen varias librerías muy buenas para hacerlo: Adafruit_SSD1306 y Adafruit_GFX son las más populares. Podría explicar como instalar estas librerías y hacerlas funcionar, pero en Internet ya hay muy buenos tutoriales sobre este tema. Si estás interesado, te recomiendo este tutorial o este otro en español.

Lo que vamos a hacer en este tutorial es más complejo. Verás cómo programar la pantalla a pelo, sin ayuda de ninguna librería a (excepción de Wire.h), creando tus propias funciones para escribir texto y dibujar imágenes ¿A quién no le gusta complicarse la vida?


¿Qué son las pantallas OLED?

Un OLED (Organic Light-Emmiting Diode) es un tipo de LED hecho de un compuesto orgánico que emite luz al recibir una descarga eléctrica. Normalmente se fabrican con Polifluoruro Vinilideno, una sustancia tan verde y ecológica como apalear a varios activistas de Greenpeace. Las pantallas OLED que utilizaremos están formadas por cientos de estos pequeños diodos, y permiten mostrar textos e imágenes monocromáticas.

En la electrónica amateur son muy populares las pequeñas pantallas de 0.96”, que incorporan el chip SSD1306 o SSD1780 y pueden programarse fácilmente usando Arduino u otro microcontrolador. Tienen un consumo de energía bajo (normalmente 15mA, 3.3v) y son tan baratas que cualquier día de estos saldrán en las bolsas de patatas.


Documentación Oficial

Todos los comandos que utilizaré en este tutorial están detallados en la documentación del SSD1306. No voy a explicar todas las sutilezas de este chip porque, sinceramente, tampoco las conozco. Si cuando termines este tutorial tienes ganas de profundizar más sobre el tema deberías descargarte el pdf y leerlo con calma.


Distribución de la pantalla

La pantalla tiene una resolución 128 columnas de 64 píxeles. No es precisamente una pantalla de alta resolución con full HD.

Para facilitar la escritura de carácteres de texto las filas se agrupan en ocho páginas, de 8 píxeles de altura cada una.

Puedes pensar en las páginas como las pautas de los cuadernos escolares.

La distribución de las coordenadas es personalizable mediante comandos. Se puede establecer el origen (0,0) en un píxel determinado, o limitar el número de páginas/columnas utilizadas.


Modos de escritura

La imagen de la pantalla se modifica enviando bytes de datos (1 byte = 8 bits). Cada bit del byte de datos se corresponde al estado de uno de los píxeles de la pantalla. Como la pantalla es monocromática, cada píxel sólo puede tener uno de dos estados: encendido (bit 1) o apagado (bit 0).

El chip tiene varios modos de escritura, es decir, varias formas de colocar los bytes de datos sobre la pantalla. El modo que voy a explicarte es el modo de escritura horizontal (Horizontal Adressing Mode). Como verás más adelante, este modo facilita mucho la escritura de texto.

Al recibir un byte de datos en el modo de escritura horizontal, la pantalla lo colocará en la primera columna de la primera página e irá llenando las sucesivas columnas con los bytes posteriores.

 

Los bytes se van colocando en la columna de más a la izquierda de cada página.

Así es como se verían los bytes de la imagen anterior

Al llegar a la última columna de la última página, volverá al principio.

Para escribir en la pantalla habrá que enviarle el byte 0x40 para ponerla en modo de escritura, seguido de otro byte con los datos.

Las páginas 34-35 de la documentación detallan los distintos modos de escritura además del horizontal.


Conexión con Arduino

Las conexiones no tienen ninguna dificultad. Con los 5V del USB habrá energía de sobra.

  • OLED Vcc -> Arduino 3.3v
  • OLED GND -> Arduino GND
  • OLED SCL -> Arduino A5
  • OLED SDA -> Arduino A4

El SSD1306 funciona con 3.3v, pero algunas versiones (como la mía) llevan un regulador que permite conectarlo a 5V sin problema.

NOTA IMPORTANTE: Estas conexiones están probadas con las versiones de Arduino UNO, Nano, Micro y Duemilanove. Si utilizas otra versión puede que los pines SDA y SCL sean otros. Aquí puedes consultar una breve lista con los pines I2C de otros modelos.


Dirección I2C

Antes de empezar a programar deberías mirar cuál es la dirección I2C de tu pantalla. La dirección usual de las pantallas OLED basadas en el chip SSD1306 es 0x3C, pero podría darse el caso de que fuera otra.

I2C scanner es un magnífico Sketch de Arduino que lista por la consola Serial la dirección de todos los dispositivos I2C conectados a la placa. Si tienes dudas de cuál puede ser la dirección de tu pantalla puedes cargar este código a tu placa y abrir la consola Serial para mirarlo.


    // --------------------------------------
    // i2c_scanner
    //
    // Version 1
    //    This program (or code that looks like it)
    //    can be found in many places.
    //    For example on the Arduino.cc forum.
    //    The original author is not know.
    // Version 2, Juni 2012, Using Arduino 1.0.1
    //     Adapted to be as simple as possible by Arduino.cc user Krodal
    // Version 3, Feb 26  2013
    //    V3 by louarnold
    // Version 4, March 3, 2013, Using Arduino 1.0.3
    //    by Arduino.cc user Krodal.
    //    Changes by louarnold removed.
    //    Scanning addresses changed from 0...127 to 1...119,
    //    according to the i2c scanner by Nick Gammon
    //    http://www.gammon.com.au/forum/?id=10896
    // Version 5, March 28, 2013
    //    As version 4, but address scans now to 127.
    //    A sensor seems to use address 120.
    // Version 6, November 27, 2015.
    //    Added waiting for the Leonardo serial communication.
    //
    //
    // This sketch tests the standard 7-bit addresses
    // Devices with higher bit address might not be seen properly.
    //
     
    #include <Wire.h>
     
     
    void setup()
    {
      Wire.begin();
     
      Serial.begin(9600);
      while (!Serial);             // Leonardo: wait for serial monitor
      Serial.println("\nI2C Scanner");
    }
     
     
    void loop()
    {
      byte error, address;
      int nDevices;
     
      Serial.println("Scanning...");
     
      nDevices = 0;
      for(address = 1; address < 127; address++ )
      {
        // The i2c_scanner uses the return value of
        // the Write.endTransmisstion to see if
        // a device did acknowledge to the address.
        Wire.beginTransmission(address);
        error = Wire.endTransmission();
     
        if (error == 0)
        {
          Serial.print("I2C device found at address 0x");
          if (address&lt;16)
            Serial.print("0");
          Serial.print(address,HEX);
          Serial.println("  !");
     
          nDevices++;
        }
        else if (error==4)
        {
          Serial.print("Unknown error at address 0x");
          if (address<16)
            Serial.print("0");
          Serial.println(address,HEX);
        }    
      }
      if (nDevices == 0)
        Serial.println("No I2C devices found\n");
      else
        Serial.println("done\n");
     
      delay(5000);           // wait 5 seconds for next scan
    }


Dibujar un patrón

Antes de empezar a dibujar imágenes y mensajes voy a mostrarte un ejemplo básico para que veas claramente cómo escribir en la pantalla. Este código enviará el mismo byte de datos todo el rato: 0x81, el número binario 10000001, lo cuál pintará un patrón de rayas.

Empezamos por las declaraciones:

#include <Wire.h>
#define DIRECCION_PANTALLA  0x3C

Voy a comentarlo. La primera línea incluye la librería Wire.h, necesaria para la comunicación I2C con el chip de la pantalla. La siguiente línea define la dirección I2C de la pantalla, que es 0x3C. Si en el apartado anterior has encontrado que tu pantalla tenía una dirección diferente deberás cambiarla.

La primera función que escribiremos sirve para inicializar la pantalla. Los pasos que se hay que seguir para hacerlo están detallados en la página 64 del dossier de documentación del dispositivo:

void inicializar_pantalla()
{
	Wire.begin(); //Iniciar la comunicacion I2C de Arduino


	//Aumentar la frecuencia de SCL a 400 kHz
	//Esto aumentara la velocidad de refresco
	TWBR = 12; 


	/* Inicializar la pantalla, siguiendo las instrucciones
	   exactas de la pag. 64 de la documentacion:   */

	//Iniciar la comunicacion con la pantalla
	Wire.beginTransmission(DIRECCION_PANTALLA); 
	
	//Le decimos a la pantalla que viene una lista de comandos de configuracion
	Wire.write(0x00);

	//Apagar la pantalla
	Wire.write(0xAE);

	// Establecer el maximo de filas a 0x3F = 63
	// es decir, ira de 0 a 63, por tanto tenemos 64 filas de pixeles
	Wire.write(0xA8);
	Wire.write(0x3F);

	//Poner el offset a 0
	Wire.write(0xD3);
	Wire.write(0x00);

	//Poner el comienzo de linea a 0
	Wire.write(0x40);

	//Invertir el eje X de pantalla, por si esta girada.
	//Puedes cambiarlo por 0xA0 si necesitas cambiar la orientacion
	Wire.write(0xA1);

	//Invertir el eje Y de la patnalla
	//Puedes cambiarlo por 0xC0 si necesitas cambiar la orientacion
	Wire.write(0xC8);

	//Mapear los pines COM
	Wire.write(0xDA);
	Wire.write(0x12); 
	//Al parecer, la unica configuracion que funciona con mi modelo es 0x12, a pesar
	// de que en la documentacion dice que hay que poner 0x02


	//Configurar el contraste
	Wire.write(0x81);
	Wire.write(0x7F); //Este valor tiene que estar entre 0x00 (min) y 0xFF (max)

	
	//Este comando ordena al chip que active el output de la pantalla en funcion del contenido
	//almacenado en su GDDRAM
	Wire.write(0xA4);

	//Poner la pantalla en modo Normal
	Wire.write(0xA6);

	//Establecer la velocidad del Oscilador
	Wire.write(0xD5);
	Wire.write(0x80);

	//Activar el 'charge pump'
	Wire.write(0x8D);
	Wire.write(0x14);

	//Encender la pantalla
	Wire.write(0xAF);


	//Como extra, establecemos el rango de columnas y paginas
	Wire.write(0x21); //Columnas de 0 a 127
	Wire.write(0x00);
	Wire.write(0x7F);
	Wire.write(0x22); //Paginas de 0 a 7
	Wire.write(0x00); 
	Wire.write(0x07);

	//Modo de escritura horizontal
	//en mi modelo no haria falta enviar este comando (por defecto utiliza este modo)
	Wire.write(0x20);
	Wire.write(0x00);

	//Cerrar la comunicacion
	Wire.endTransmission();
	
	//Limpiamos la memoria, por si hubiera quedado memoria residual
	//de la ultima vez que se encendio la pantalla
	for(int i = 0; i < 1024; i++){
		Wire.beginTransmission(DIRECCION_PANTALLA);
		Wire.write(0x40);
		Wire.write(0x00);
		Wire.endTransmission();
        }
	




}

En el void setup se llama esta función de inicialización:

void setup() { 
 // Inicializar el controlador de la pantalla OLED
 inicializar_pantalla();
}

Dentro del void loop se recorren todos los bytes que puede almacenar la pantalla (un total de 1024) y se envía el byte de datos 0x81. Notarás que a diferencia de cuándo estábamos configurando la pantalla, en el modo de escritura no se pueden enviar todos los bytes de datos seguidos. Hay que cerrar la conexión cada vez que se envía una porción de la imagen.

void loop() {
	//La pantalla puede pintar un total de 128*8 = 1024 bytes
        for(int j = 0; j < 1024; j++)
	{
		Wire.beginTransmission(DIRECCION_PANTALLA); //Iniciar la comunicacion con la pantalla
		Wire.write(0x40); //Poner la pantalla en modo escritura
        	Wire.write(0x81); //Enviar el byte de datos. 0x81 = 10000001
        	Wire.endTransmission(); //Hay que cerrar siempre la comunicacion una vez enviado el byte
	}

	
}

Verás que en la pantalla aparece un patrón rayado. Como los bits ‘1’ están en los extremos del byte de datos, las rayas están marcando los límites de las páginas.

Puedes probar a alterar el byte de datos. 0xAF también hará un patrón rayado, pero con las líneas de diferente grosor. Intenta sustituir la función void loop por esta otra:

void loop() {
	//La pantalla puede pintar un total de 128*8 = 1024 bytes
        for(int j = 0; j < 1024; j++)
	{
		Wire.beginTransmission(DIRECCION_PANTALLA); //Iniciar la comunicacion con la pantalla
		Wire.write(0x40); //Poner la pantalla en modo escritura
        	Wire.write(0xAF); //Enviar el byte de datos. 0xAF = 10101111
        	Wire.endTransmission(); //Hay que cerrar siempre la comunicacion una vez enviado el byte
	}

	
}

También puedes probar a dibujar un tablero de ajedrez con casillas de 8×8:

void loop() {
	bool blanco = true;
	//La pantalla puede pintar un total de 128 casillas de 8x8 pixeles
        for(int j = 0; j < 128; j++)
	{
                //Hay que cambiar el color de la casilla a cada iteracion,
                //excepto si se llega al final de la pantalla
                if(j % 16 != 0)
                  blanco = !blanco;
		for(int i = 0; i < 8; i++)
		{
			Wire.beginTransmission(DIRECCION_PANTALLA); //Iniciar la comunicacion con la pantalla
			Wire.write(0x40); //Poner la pantalla en modo escritura
			if(blanco)
        			Wire.write(0x00); //Pintar la casilla negra
			else
				Wire.write(0xFF); //Pintar la casilla blanca
			Wire.endTransmission(); //Hay que cerrar siempre la comunicacion una vez enviado el byte
		}
                
	}

	
}


Dibujar una imagen

En este apartado aprenderás a dibujar imágenes en la pantalla. Vamos a intentar pintar el logotipo de Robologs.

Con la inestimable ayuda de mi amiga Glare, que tiene mucha más práctica que yo en temas artísticos, he convertido el logotipo de Robologs a una imagen en blanco y negro puro.

Hay que convertir esta imagen a un array de bytes. Para hacerlo puedes usar LCD Converter. Este programa genera un fichero de texto plano con el array de bytes listo para copiarse y pegarse en el sketch de Arduino.

LCD Converter sólo está para Windows, pero funciona perfectamente con Wine.

El programa creará este archivo de texto:

//------------------------------------------------------------------------------
// File generated by LCD Assistant
// http://en.radzio.dxp.pl/bitmap_converter/
//------------------------------------------------------------------------------

const unsigned char imagen [] = {
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, 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, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xF8,
0x88, 0x18, 0x10, 0x10, 0x70, 0xC0, 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,
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, 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, 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, 0x00, 0x80,
0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x86, 0x0C, 0x18, 0x18, 0x18, 0x18, 0x0E,
0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0xE7, 0x7C, 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, 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, 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, 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, 0x03,
0x02, 0x03, 0x02, 0x0E, 0x38, 0xE0, 0x80, 0x00, 0x00, 0x03, 0x06, 0x0C, 0x18, 0x18, 0x10, 0x10,
0x10, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x0F, 0x18, 0x30, 0x60, 0xC0, 0x80, 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, 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,
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xF8, 0xFC,
0xFE, 0xFE, 0x0C, 0x0C, 0x0C, 0x0C, 0x0F, 0x0C, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x30, 0x30, 0x30, 0x33, 0x36, 0x30, 0x30, 0x20, 0x60, 0x60, 0xE0, 0xE1, 0x06, 0x0C, 0x18, 0x30,
0xE0, 0x60, 0x20, 0x20, 0x20, 0xC0, 0x80, 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, 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, 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, 0x00, 0x80, 0xF0, 0x1B, 0x0F, 0x07, 0x07, 0x07, 0x0F, 0x8F, 0xCF,
0xFF, 0x9F, 0x00, 0x00, 0x00, 0xE0, 0x98, 0x08, 0x78, 0xF8, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xC0, 0x20, 0xE0, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x07,
0x09, 0x08, 0x08, 0x08, 0x08, 0x18, 0x77, 0xE0, 0xC0, 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, 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, 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, 0x03, 0x02, 0x04, 0xF8, 0x80, 0x80, 0x80, 0x8E, 0xFF, 0xFF,
0xFF, 0xFF, 0xF8, 0xF0, 0xE0, 0xE0, 0xC1, 0xC1, 0xC1, 0xC1, 0xC0, 0xC0, 0xC8, 0xD0, 0xD0, 0x88,
0x90, 0x90, 0x88, 0x80, 0x81, 0x82, 0x82, 0x81, 0x80, 0xE0, 0x7F, 0x0F, 0x01, 0x07, 0x0C, 0x38,
0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x20, 0x21, 0xE3, 0x0E, 0x1C, 0xF8, 0xF0, 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, 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, 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, 0x07, 0x0F, 0x0F, 0x1F,
0x1F, 0x1F, 0x9F, 0xFF, 0x8F, 0x87, 0x03, 0x07, 0xFF, 0x3F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0xFF,
0x07, 0x07, 0x07, 0x9F, 0xFF, 0x0F, 0x0F, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x07, 0x0C, 0x38, 0x30, 0x37, 0x34, 0x34, 0x37, 0x30, 0x3F, 0x3F, 0x01, 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, 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, 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, 0x00, 0x00, 0x00, 0x08,
0x0C, 0x0A, 0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0B, 0x0C, 0x08, 0x00, 0x00, 0x08, 0x0F, 0x0B,
0x08, 0x08, 0x09, 0x08, 0x09, 0x0A, 0x0C, 0x08, 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, 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, 0x00, 0x00, 0x00, 0x00
};

Como puedes ver es un array preparado para incluirse en un código C, Java u otro lenguaje con una sintaxis parecida.

Vamos a ver cómo sería el programa de Arduino. Empezamos por las definiciones:

#include <Wire.h>

#define DIRECCION_PANTALLA  0x3C

Ahora hay que copiar el array de bytes que ha generado LCD converter:

const unsigned char imagen [] = {
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, 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, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xF8,
0x88, 0x18, 0x10, 0x10, 0x70, 0xC0, 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,
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, 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, 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, 0x00, 0x80,
0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x86, 0x0C, 0x18, 0x18, 0x18, 0x18, 0x0E,
0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0xE7, 0x7C, 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, 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, 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, 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, 0x03,
0x02, 0x03, 0x02, 0x0E, 0x38, 0xE0, 0x80, 0x00, 0x00, 0x03, 0x06, 0x0C, 0x18, 0x18, 0x10, 0x10,
0x10, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x0F, 0x18, 0x30, 0x60, 0xC0, 0x80, 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, 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,
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xF8, 0xFC,
0xFE, 0xFE, 0x0C, 0x0C, 0x0C, 0x0C, 0x0F, 0x0C, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x30, 0x30, 0x30, 0x33, 0x36, 0x30, 0x30, 0x20, 0x60, 0x60, 0xE0, 0xE1, 0x06, 0x0C, 0x18, 0x30,
0xE0, 0x60, 0x20, 0x20, 0x20, 0xC0, 0x80, 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, 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, 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, 0x00, 0x80, 0xF0, 0x1B, 0x0F, 0x07, 0x07, 0x07, 0x0F, 0x8F, 0xCF,
0xFF, 0x9F, 0x00, 0x00, 0x00, 0xE0, 0x98, 0x08, 0x78, 0xF8, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xC0, 0x20, 0xE0, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x07,
0x09, 0x08, 0x08, 0x08, 0x08, 0x18, 0x77, 0xE0, 0xC0, 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, 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, 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, 0x03, 0x02, 0x04, 0xF8, 0x80, 0x80, 0x80, 0x8E, 0xFF, 0xFF,
0xFF, 0xFF, 0xF8, 0xF0, 0xE0, 0xE0, 0xC1, 0xC1, 0xC1, 0xC1, 0xC0, 0xC0, 0xC8, 0xD0, 0xD0, 0x88,
0x90, 0x90, 0x88, 0x80, 0x81, 0x82, 0x82, 0x81, 0x80, 0xE0, 0x7F, 0x0F, 0x01, 0x07, 0x0C, 0x38,
0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x20, 0x21, 0xE3, 0x0E, 0x1C, 0xF8, 0xF0, 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, 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, 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, 0x07, 0x0F, 0x0F, 0x1F,
0x1F, 0x1F, 0x9F, 0xFF, 0x8F, 0x87, 0x03, 0x07, 0xFF, 0x3F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0xFF,
0x07, 0x07, 0x07, 0x9F, 0xFF, 0x0F, 0x0F, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x07, 0x0C, 0x38, 0x30, 0x37, 0x34, 0x34, 0x37, 0x30, 0x3F, 0x3F, 0x01, 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, 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, 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, 0x00, 0x00, 0x00, 0x08,
0x0C, 0x0A, 0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0B, 0x0C, 0x08, 0x00, 0x00, 0x08, 0x0F, 0x0B,
0x08, 0x08, 0x09, 0x08, 0x09, 0x0A, 0x0C, 0x08, 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, 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, 0x00, 0x00, 0x00, 0x00
};

La función de inicialización de la pantalla y el void setup son igual que antes:

void inicializar_pantalla()
{
	Wire.begin(); //Iniciar la comunicacion I2C de Arduino


	//Aumentar la frecuencia de SCL a 400 kHz
	//Esto aumentara la velocidad de refresco
	TWBR = 12; 


	/* Inicializar la pantalla, siguiendo las instrucciones
	   exactas de la pag. 64 de la documentacion:   */

	//Iniciar la comunicacion con la pantalla
	Wire.beginTransmission(DIRECCION_PANTALLA); 
	
	//Le decimos a la pantalla que viene una lista de comandos de configuracion
	Wire.write(0x00);

	//Apagar la pantalla
	Wire.write(0xAE);

	// Establecer el maximo de filas a 0x3F = 63
	// es decir, ira de 0 a 63, por tanto tenemos 64 filas de pixeles
	Wire.write(0xA8);
	Wire.write(0x3F);

	//Poner el offset a 0
	Wire.write(0xD3);
	Wire.write(0x00);

	//Poner el comienzo de linea a 0
	Wire.write(0x40);

	//Invertir el eje X de pantalla, por si esta girada.
	//Puedes cambiarlo por 0xA0 si necesitas cambiar la orientacion
	Wire.write(0xA1);

	//Invertir el eje Y de la patnalla
	//Puedes cambiarlo por 0xC0 si necesitas cambiar la orientacion
	Wire.write(0xC8);

	//Mapear los pines COM
	Wire.write(0xDA);
	Wire.write(0x12); 
	//Al parecer, la unica configuracion que funciona con mi modelo es 0x12, a pesar
	// de que en la documentacion dice que hay que poner 0x02


	//Configurar el contraste
	Wire.write(0x81);
	Wire.write(0x7F); //Este valor tiene que estar entre 0x00 (min) y 0xFF (max)

	
	//Este comando ordena al chip que active el output de la pantalla en funcion del contenido
	//almacenado en su GDDRAM
	Wire.write(0xA4);

	//Poner la pantalla en modo Normal
	Wire.write(0xA6);

	//Establecer la velocidad del Oscilador
	Wire.write(0xD5);
	Wire.write(0x80);

	//Activar el 'charge pump'
	Wire.write(0x8D);
	Wire.write(0x14);

	//Encender la pantalla
	Wire.write(0xAF);


	//Como extra, establecemos el rango de columnas y paginas
	Wire.write(0x21); //Columnas de 0 a 127
	Wire.write(0x00);
	Wire.write(0x7F);
	Wire.write(0x22); //Paginas de 0 a 7
	Wire.write(0x00); 
	Wire.write(0x07);

	//Modo de escritura horizontal
	//en mi modelo no haria falta enviar este comando (por defecto utiliza este modo)
	Wire.write(0x20);
	Wire.write(0x00);

	//Cerrar la comunicacion
	Wire.endTransmission();
	
	//Limpiamos la memoria, por si hubiera quedado memoria residual
	//de la ultima vez que se encendio la pantalla
	for(int i = 0; i < 1024; i++){
		Wire.beginTransmission(DIRECCION_PANTALLA);
		Wire.write(0x40);
		Wire.write(0x00);
		Wire.endTransmission();
        }
	

}

void setup()   {                
	// Inicializar el controlador de la pantalla OLED
	inicializar_pantalla();
}

Lo único que cambia un poco es el bucle princpal. Antes se pintaba un byte predefinido a cada iteración del bucle for. Ahora utilizaremos este bucle para recorrer la matriz de la imagen y dibujar cada uno de sus bytes.

void loop() {
   //Recorre la matriz de la imagen y dibuja cada byte en la pantalla
   char c;
   for(int i = 0; i < 1024; i++)
   {
		Wire.beginTransmission(DIRECCION_PANTALLA);
		Wire.write(0x40);
        	Wire.write(imagen[i]); //Dibujar el byte correspondiente
        	Wire.endTransmission();
   }

	
}

Así quedará el sketch final:

#include <Wire.h>


#define DIRECCION_PANTALLA  0x3C

const unsigned char imagen [] = {
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, 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, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xF8,
0x88, 0x18, 0x10, 0x10, 0x70, 0xC0, 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,
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, 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, 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, 0x00, 0x80,
0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x86, 0x0C, 0x18, 0x18, 0x18, 0x18, 0x0E,
0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0xE7, 0x7C, 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, 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, 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, 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, 0x03,
0x02, 0x03, 0x02, 0x0E, 0x38, 0xE0, 0x80, 0x00, 0x00, 0x03, 0x06, 0x0C, 0x18, 0x18, 0x10, 0x10,
0x10, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x0F, 0x18, 0x30, 0x60, 0xC0, 0x80, 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, 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,
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xF8, 0xFC,
0xFE, 0xFE, 0x0C, 0x0C, 0x0C, 0x0C, 0x0F, 0x0C, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x30, 0x30, 0x30, 0x33, 0x36, 0x30, 0x30, 0x20, 0x60, 0x60, 0xE0, 0xE1, 0x06, 0x0C, 0x18, 0x30,
0xE0, 0x60, 0x20, 0x20, 0x20, 0xC0, 0x80, 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, 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, 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, 0x00, 0x80, 0xF0, 0x1B, 0x0F, 0x07, 0x07, 0x07, 0x0F, 0x8F, 0xCF,
0xFF, 0x9F, 0x00, 0x00, 0x00, 0xE0, 0x98, 0x08, 0x78, 0xF8, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xC0, 0x20, 0xE0, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x07,
0x09, 0x08, 0x08, 0x08, 0x08, 0x18, 0x77, 0xE0, 0xC0, 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, 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, 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, 0x03, 0x02, 0x04, 0xF8, 0x80, 0x80, 0x80, 0x8E, 0xFF, 0xFF,
0xFF, 0xFF, 0xF8, 0xF0, 0xE0, 0xE0, 0xC1, 0xC1, 0xC1, 0xC1, 0xC0, 0xC0, 0xC8, 0xD0, 0xD0, 0x88,
0x90, 0x90, 0x88, 0x80, 0x81, 0x82, 0x82, 0x81, 0x80, 0xE0, 0x7F, 0x0F, 0x01, 0x07, 0x0C, 0x38,
0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x20, 0x21, 0xE3, 0x0E, 0x1C, 0xF8, 0xF0, 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, 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, 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, 0x07, 0x0F, 0x0F, 0x1F,
0x1F, 0x1F, 0x9F, 0xFF, 0x8F, 0x87, 0x03, 0x07, 0xFF, 0x3F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0xFF,
0x07, 0x07, 0x07, 0x9F, 0xFF, 0x0F, 0x0F, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x07, 0x0C, 0x38, 0x30, 0x37, 0x34, 0x34, 0x37, 0x30, 0x3F, 0x3F, 0x01, 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, 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, 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, 0x00, 0x00, 0x00, 0x08,
0x0C, 0x0A, 0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0B, 0x0C, 0x08, 0x00, 0x00, 0x08, 0x0F, 0x0B,
0x08, 0x08, 0x09, 0x08, 0x09, 0x0A, 0x0C, 0x08, 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, 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, 0x00, 0x00, 0x00, 0x00
};

void setup()   {                
	// Inicializar el controlador de la pantalla OLED
	inicializar_pantalla();
}

void loop() {
   //Recorre la matriz de la imagen y dibuja cada byte en la pantalla
   char c;
   for(int i = 0; i < 1024; i++)
   {
		Wire.beginTransmission(DIRECCION_PANTALLA);
		Wire.write(0x40);
        	Wire.write(imagen[i]); //Dibujar el byte correspondiente
        	Wire.endTransmission();
   }

	
}

void inicializar_pantalla()
{
	Wire.begin(); //Iniciar la comunicacion I2C de Arduino


	//Aumentar la frecuencia de SCL a 400 kHz
	//Esto aumentara la velocidad de refresco
	TWBR = 12; 


	/* Inicializar la pantalla, siguiendo las instrucciones
	   exactas de la pag. 64 de la documentacion:   */

	//Iniciar la comunicacion con la pantalla
	Wire.beginTransmission(DIRECCION_PANTALLA); 
	
	//Le decimos a la pantalla que viene una lista de comandos de configuracion
	Wire.write(0x00);

	//Apagar la pantalla
	Wire.write(0xAE);

	// Establecer el maximo de filas a 0x3F = 63
	// es decir, ira de 0 a 63, por tanto tenemos 64 filas de pixeles
	Wire.write(0xA8);
	Wire.write(0x3F);

	//Poner el offset a 0
	Wire.write(0xD3);
	Wire.write(0x00);

	//Poner el comienzo de linea a 0
	Wire.write(0x40);

	//Invertir el eje X de pantalla, por si esta girada.
	//Puedes cambiarlo por 0xA0 si necesitas cambiar la orientacion
	Wire.write(0xA1);

	//Invertir el eje Y de la patnalla
	//Puedes cambiarlo por 0xC0 si necesitas cambiar la orientacion
	Wire.write(0xC8);

	//Mapear los pines COM
	Wire.write(0xDA);
	Wire.write(0x12); 
	//Al parecer, la unica configuracion que funciona con mi modelo es 0x12, a pesar
	// de que en la documentacion dice que hay que poner 0x02


	//Configurar el contraste
	Wire.write(0x81);
	Wire.write(0x7F); //Este valor tiene que estar entre 0x00 (min) y 0xFF (max)

	
	//Este comando ordena al chip que active el output de la pantalla en funcion del contenido
	//almacenado en su GDDRAM
	Wire.write(0xA4);

	//Poner la pantalla en modo Normal
	Wire.write(0xA6);

	//Establecer la velocidad del Oscilador
	Wire.write(0xD5);
	Wire.write(0x80);

	//Activar el 'charge pump'
	Wire.write(0x8D);
	Wire.write(0x14);

	//Encender la pantalla
	Wire.write(0xAF);


	//Como extra, establecemos el rango de columnas y paginas
	Wire.write(0x21); //Columnas de 0 a 127
	Wire.write(0x00);
	Wire.write(0x7F);
	Wire.write(0x22); //Paginas de 0 a 7
	Wire.write(0x00); 
	Wire.write(0x07);

	//Modo de escritura horizontal
	//en mi modelo no haria falta enviar este comando (por defecto utiliza este modo)
	Wire.write(0x20);
	Wire.write(0x00);

	//Cerrar la comunicacion
	Wire.endTransmission();
	
	//Limpiamos la memoria, por si hubiera quedado memoria residual
	//de la ultima vez que se encendio la pantalla
	for(int i = 0; i < 1024; i++){
		Wire.beginTransmission(DIRECCION_PANTALLA);
		Wire.write(0x40);
		Wire.write(0x00);
		Wire.endTransmission();
        }
	

}

 


Escribir texto

La principal utilidad de este tipo de pantallas es escribir carácteres de texto de 8×8 píxeles. El concepto de este código es muy parecido al del apartado anterior puesto que los carácteres pueden tratarse de la misma forma que las imágenes.

Arduino es un microprocesador con muy poca memoria interna, así que cada byte cuenta. Al intentar hacer este programa el primer impulso es guardar cada carácter como una imagen distinta. Pero nosotros vamos a hacer algo más eficiente: guardar todos los carácteres de la fuente en una sola imagen, y después mostrar sólo el fragmento de cada uno de los símbolos cuándo haya que escribirlos.

Este código no es difícil, pero puede que tengas que leerlo dos o tres veces para entender su lógica. Haré lo que sea robóticamente posible para explicarlo de forma sencilla, pero si no te queda claro no dudes en escribir un comentario.

Yo he utilizado esta imagen como fuente:

Si hay algún Diplodocus que esté leyendo este artículo puede que la reconozca. Se llama ATASCII y es la fuente que usaban las antiguas máquinas Atari de finales de los setenta.

Empezaremos exactamente de la misma forma que antes: importar la librería Wire.h, declarar la dirección I2C de la pantalla (acuérdate de cambiarla si es preciso) y guardar la imagen de la fuente en una matriz de bytes.

#include <Wire.h>


#define DIRECCION_PANTALLA  0x3C

//Matriz con la imagen de la fuente
const unsigned char font [] = {

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1C, 0xF6, 0x83, 0x83, 0xF6, 0x1C, 0x18,

0x18, 0x38, 0x6F, 0xC1, 0xC1, 0x6F, 0x38, 0x18, 0x3C, 0x24, 0x24, 0xE7, 0xC3, 0x66, 0x3C, 0x18,

0x18, 0x3C, 0x66, 0xC3, 0xE7, 0x24, 0x24, 0x3C, 0x3E, 0x1C, 0x49, 0x63, 0x63, 0x49, 0x1C, 0x3E,

0x7F, 0x7F, 0x7F, 0x3F, 0x1F, 0x4F, 0x67, 0x73, 0x77, 0x63, 0x49, 0x1C, 0x1C, 0x49, 0x63, 0x77,

0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x7E, 0xFF, 0x81, 0x9D, 0x91, 0x81, 0xFF, 0x7E,

0x00, 0x10, 0x5E, 0xFF, 0x5F, 0x1E, 0x10, 0x00, 0x40, 0xE0, 0xE0, 0x7F, 0x03, 0x06, 0x04, 0x00,

0x1F, 0x1F, 0x05, 0x7D, 0x7C, 0x14, 0x14, 0x00, 0x1F, 0x1F, 0x11, 0x7D, 0x7C, 0x34, 0x7C, 0x5C,

0x00, 0xC0, 0xC0, 0xE0, 0x78, 0x1F, 0x00, 0xFF, 0xFF, 0x00, 0x1F, 0x78, 0xE0, 0xC0, 0xC0, 0x00,

0x36, 0x77, 0x41, 0x41, 0x41, 0x77, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x00,

0x30, 0x79, 0x49, 0x49, 0x49, 0x4F, 0x06, 0x00, 0x00, 0x49, 0x49, 0x49, 0x49, 0x7F, 0x36, 0x00,

0x07, 0x0F, 0x08, 0x08, 0x08, 0x7F, 0x77, 0x00, 0x06, 0x4F, 0x49, 0x49, 0x49, 0x79, 0x30, 0x00,

0x36, 0x7F, 0x49, 0x49, 0x49, 0x79, 0x30, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x77, 0x76, 0x00,

0x36, 0x7F, 0x49, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x06, 0x4F, 0x49, 0x49, 0x49, 0x7F, 0x36, 0x00,

0x00, 0x30, 0x74, 0x54, 0x54, 0x7C, 0x38, 0x00, 0x00, 0x1F, 0x1F, 0x75, 0x75, 0x50, 0x50, 0x00,

0x00, 0x00, 0x00, 0xFC, 0x5E, 0xC7, 0xC7, 0x87, 0x07, 0x87, 0x47, 0xC3, 0x46, 0xFC, 0x00, 0x00,

0x00, 0x00, 0xE0, 0xC1, 0xE6, 0x3C, 0x3A, 0x57, 0x54, 0x54, 0x4A, 0x34, 0x0E, 0x01, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x5F, 0x00, 0x00, 0x00,

0x00, 0x07, 0x07, 0x00, 0x00, 0x07, 0x07, 0x00, 0x24, 0x7E, 0x7E, 0x24, 0x7E, 0x7E, 0x24, 0x00,

0x00, 0x24, 0x2E, 0x6B, 0x6B, 0x3A, 0x12, 0x00, 0x00, 0x66, 0x36, 0x18, 0x0C, 0x66, 0x62, 0x00,

0x30, 0x7A, 0x4F, 0x5D, 0x37, 0x72, 0x50, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x3E, 0x7F, 0x63, 0x41, 0x00, 0x00, 0x41, 0x63, 0x7F, 0x3E, 0x00, 0x00, 0x00,

0x08, 0x2A, 0x3E, 0x1C, 0x1C, 0x3E, 0x2A, 0x08, 0x00, 0x08, 0x08, 0x3E, 0x3E, 0x08, 0x08, 0x00,

0x00, 0x80, 0xE0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00,

0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x00,

0x00, 0x3E, 0x7F, 0x49, 0x45, 0x7F, 0x3E, 0x00, 0x00, 0x40, 0x42, 0x7F, 0x7F, 0x40, 0x40, 0x00,

0x00, 0x42, 0x63, 0x71, 0x59, 0x4F, 0x46, 0x00, 0x00, 0x21, 0x61, 0x45, 0x4F, 0x7B, 0x31, 0x00,

0x00, 0x18, 0x1C, 0x16, 0x7F, 0x7F, 0x10, 0x00, 0x00, 0x27, 0x67, 0x45, 0x45, 0x7D, 0x39, 0x00,

0x00, 0x3E, 0x7F, 0x49, 0x49, 0x79, 0x30, 0x00, 0x00, 0x01, 0x71, 0x79, 0x0D, 0x07, 0x03, 0x00,

0x00, 0x36, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00, 0x06, 0x4F, 0x49, 0x69, 0x3F, 0x1E, 0x00,

0x00, 0x00, 0x00, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x76, 0x36, 0x00, 0x00, 0x00,

0x00, 0x00, 0x08, 0x1C, 0x36, 0x63, 0x41, 0x00, 0x00, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00,

0x00, 0x41, 0x63, 0x36, 0x1C, 0x08, 0x00, 0x00, 0x00, 0x02, 0x03, 0x51, 0x59, 0x0F, 0x06, 0x00,

0x00, 0x3E, 0x7F, 0x41, 0x5D, 0x57, 0x5E, 0x00, 0x00, 0x7C, 0x7E, 0x13, 0x13, 0x7E, 0x7C, 0x00,

0x00, 0x7F, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00, 0x3E, 0x7F, 0x41, 0x41, 0x63, 0x22, 0x00,

0x00, 0x7F, 0x7F, 0x41, 0x63, 0x3E, 0x1C, 0x00, 0x00, 0x7F, 0x7F, 0x49, 0x49, 0x49, 0x41, 0x00,

0x00, 0x7F, 0x7F, 0x09, 0x09, 0x09, 0x01, 0x00, 0x00, 0x3E, 0x7F, 0x41, 0x49, 0x79, 0x79, 0x00,

0x00, 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x41, 0x7F, 0x7F, 0x41, 0x00, 0x00,

0x00, 0x20, 0x60, 0x40, 0x40, 0x7F, 0x3F, 0x00, 0x00, 0x7F, 0x7F, 0x1C, 0x36, 0x63, 0x41, 0x00,

0x00, 0x7F, 0x7F, 0x40, 0x40, 0x40, 0x40, 0x00, 0x7F, 0x7F, 0x06, 0x0C, 0x06, 0x7F, 0x7F, 0x00,

0x00, 0x7F, 0x7F, 0x0E, 0x1C, 0x7F, 0x7F, 0x00, 0x00, 0x3E, 0x7F, 0x41, 0x41, 0x7F, 0x3E, 0x00,

0x00, 0x7F, 0x7F, 0x09, 0x09, 0x0F, 0x06, 0x00, 0x00, 0x3E, 0x7F, 0x51, 0x21, 0x7F, 0x5E, 0x00,

0x00, 0x7F, 0x7F, 0x09, 0x19, 0x7F, 0x66, 0x00, 0x00, 0x26, 0x6F, 0x49, 0x49, 0x7B, 0x32, 0x00,

0x00, 0x01, 0x01, 0x7F, 0x7F, 0x01, 0x01, 0x00, 0x00, 0x3F, 0x7F, 0x40, 0x40, 0x7F, 0x7F, 0x00,

0x00, 0x1F, 0x3F, 0x60, 0x60, 0x3F, 0x1F, 0x00, 0x7F, 0x7F, 0x30, 0x18, 0x30, 0x7F, 0x7F, 0x00,

0x00, 0x63, 0x77, 0x1C, 0x1C, 0x77, 0x63, 0x00, 0x00, 0x07, 0x0F, 0x78, 0x78, 0x0F, 0x07, 0x00,

0x00, 0x61, 0x71, 0x59, 0x4D, 0x47, 0x43, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x41, 0x41, 0x00,

0x00, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, 0x41, 0x41, 0x7F, 0x7F, 0x00, 0x00, 0x00,

0x08, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x08, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00,

0x02, 0x06, 0x0C, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x74, 0x54, 0x54, 0x7C, 0x78, 0x00,

0x00, 0x7F, 0x7F, 0x44, 0x44, 0x7C, 0x38, 0x00, 0x00, 0x38, 0x7C, 0x44, 0x44, 0x44, 0x00, 0x00,

0x00, 0x38, 0x7C, 0x44, 0x44, 0x7F, 0x7F, 0x00, 0x00, 0x38, 0x7C, 0x54, 0x54, 0x5C, 0x18, 0x00,

0x00, 0x04, 0x7E, 0x7F, 0x05, 0x05, 0x00, 0x00, 0x00, 0x98, 0xBC, 0xA4, 0xA4, 0xFC, 0x7C, 0x00,

0x00, 0x7F, 0x7F, 0x04, 0x04, 0x7C, 0x78, 0x00, 0x00, 0x00, 0x44, 0x7D, 0x7D, 0x40, 0x00, 0x00,

0x00, 0x80, 0x80, 0xFD, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x10, 0x38, 0x6C, 0x44, 0x00,

0x00, 0x00, 0x41, 0x7F, 0x7F, 0x40, 0x00, 0x00, 0x7C, 0x7C, 0x0C, 0x18, 0x0C, 0x7C, 0x78, 0x00,

0x00, 0x7C, 0x7C, 0x04, 0x04, 0x7C, 0x78, 0x00, 0x00, 0x38, 0x7C, 0x44, 0x44, 0x7C, 0x38, 0x00,

0x00, 0xFC, 0xFC, 0x44, 0x44, 0x7C, 0x38, 0x00, 0x00, 0x38, 0x7C, 0x44, 0x44, 0xFC, 0xFC, 0x00,

0x00, 0x7C, 0x7C, 0x04, 0x04, 0x0C, 0x08, 0x00, 0x00, 0x48, 0x5C, 0x54, 0x54, 0x74, 0x24, 0x00,

0x00, 0x04, 0x04, 0x3E, 0x7E, 0x44, 0x44, 0x00, 0x00, 0x3C, 0x7C, 0x40, 0x40, 0x7C, 0x7C, 0x00,

0x00, 0x1C, 0x3C, 0x60, 0x60, 0x3C, 0x1C, 0x00, 0x1C, 0x7C, 0x60, 0x30, 0x60, 0x7C, 0x1C, 0x00,

0x00, 0x44, 0x6C, 0x38, 0x38, 0x6C, 0x44, 0x00, 0x00, 0x9C, 0xBC, 0xA0, 0xA0, 0xFC, 0x7C, 0x00,

0x00, 0x44, 0x64, 0x74, 0x5C, 0x4C, 0x44, 0x00, 0x00, 0x00, 0x08, 0x3E, 0x77, 0x41, 0x41, 0x00,

0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x77, 0x3E, 0x08, 0x00, 0x00,

0x0C, 0x06, 0x06, 0x0C, 0x18, 0x18, 0x0C, 0x00, 0x00, 0x60, 0x78, 0x5E, 0x46, 0x58, 0x60, 0x00

};

Cada carácter tiene una dimensión de 8×8 píxeles, por tanto en la pantalla caben 128 carácteres. En el código ASCII básico cada carácter tiene asociado un número entre 0 y 127 (0x00 y 0x7F en hexadecimal). Para guardar el texto que debe imprimirse en pantalla habrá que crear una matriz de tipo char de 128 espacios.

//Matriz que guardara la lista de caracteres que hay que mostrar en pantalla
char caracteres_pantalla [128];

La pantalla no tiene poderes telepáticos, y necesita una forma de saber qué carácteres debe escribir, y dónde. La función ‘anadir_caracter’ tendrá como argumento un número entero entre 0 y 127, correspondiente a un carácter ASCII, y su posición X-Y en la pantalla.

void anadir_caracter(int letra, int posX, int posY)
{
  //Comprobar que el caracter no se salga del rango
  if(127 < letra || 0 > letra)
    letra = 127;
    
  //Hay 8x16 posiciones para los caracteres
  caracteres_pantalla[(posX)+(posY*16)] = letra;
  
}

(Nótese que esta posición X-Y no será la ubicación real del píxel sobre el que el programa empezará a dibujar el carácter. Como explicaré un poco más abajo, la pantalla se divide en “casillas” de 8×8 píxeles, y esta posición indicará la casilla).

Ahora viene la parte más delicada de este programa. Hay que leer la matriz de carácteres y, en función del valor que haya guardado en cada espacio, buscar su región correspondiente en la imagen de la fuente.

Olvídate por un momento de que la imagen de la fuente está dividida en píxeles, e imagínate que cada caracter está dentro de una casilla de 8×8. Hay un total de 128 casillas, numeradas del 0 al 127. La parte buena es que en el array de la imagen estos carácteres no están ordenados en filas ni en columnas, sino uno detrás del otro (la matriz es unidimensional).

Cada “casilla” con un carácter mide ocho píxeles, por tanto si quieres leer el primer carácter (el carácter 0) tendrás que leer el array de la fuente desde la posición 0 a la posición 7. De igual forma, si quieres leer el carácter 32 (correspondiente al signo ‘!’), deberás leer de la posición 32*8 =256 a la posición 32*8+8=264… ¿ves el patrón? el carácter C a pintar lo indica la matriz de texto, y hay que leer desde la posición C*8 a la posición C*8+8 de la imagen de la fuente:

void escribir()
{
   //Recorre la matriz de caracteres
   //y los va mostrando en pantalla
   char c;
   for(int i = 0; i < 128; i++)
   {
	c = caracteres_pantalla[i]; //Guardar el caracter que hay que escribir

	//Buscarlo en la imagen de la fuente y dibujarlo
        for(int j = c*8; j < c*8+8; j++)
	{
		Wire.beginTransmission(DIRECCION_PANTALLA);
		Wire.write(0x40);
        	Wire.write(font[j]);
        	Wire.endTransmission();
	}
   }

}

La función de inicialización de la pantalla será como hemos venido haciendo hasta ahora:

void inicializar_pantalla()
{
	Wire.begin(); //Iniciar la comunicacion I2C de Arduino


	//Aumentar la frecuencia de SCL a 400 kHz
	//Esto aumentara la velocidad de refresco
	TWBR = 12; 


	/* Inicializar la pantalla, siguiendo las instrucciones
	   exactas de la pag. 64 de la documentacion:   */

	//Iniciar la comunicacion con la pantalla
	Wire.beginTransmission(DIRECCION_PANTALLA); 
	
	//Le decimos a la pantalla que viene una lista de comandos de configuracion
	Wire.write(0x00);

	//Apagar la pantalla
	Wire.write(0xAE);

	// Establecer el maximo de filas a 0x3F = 63
	// es decir, ira de 0 a 63, por tanto tenemos 64 filas de pixeles
	Wire.write(0xA8);
	Wire.write(0x3F);

	//Poner el offset a 0
	Wire.write(0xD3);
	Wire.write(0x00);

	//Poner el comienzo de linea a 0
	Wire.write(0x40);

	//Invertir el eje X de pantalla, por si esta girada.
	//Puedes cambiarlo por 0xA0 si necesitas cambiar la orientacion
	Wire.write(0xA1);

	//Invertir el eje Y de la patnalla
	//Puedes cambiarlo por 0xC0 si necesitas cambiar la orientacion
	Wire.write(0xC8);

	//Mapear los pines COM
	Wire.write(0xDA);
	Wire.write(0x12); 
	//Al parecer, la unica configuracion que funciona con mi modelo es 0x12, a pesar
	// de que en la documentacion dice que hay que poner 0x02


	//Configurar el contraste
	Wire.write(0x81);
	Wire.write(0x7F); //Este valor tiene que estar entre 0x00 (min) y 0xFF (max)

	
	//Este comando ordena al chip que active el output de la pantalla en funcion del contenido
	//almacenado en su GDDRAM
	Wire.write(0xA4);

	//Poner la pantalla en modo Normal
	Wire.write(0xA6);

	//Establecer la velocidad del Oscilador
	Wire.write(0xD5);
	Wire.write(0x80);

	//Activar el 'charge pump'
	Wire.write(0x8D);
	Wire.write(0x14);

	//Encender la pantalla
	Wire.write(0xAF);


	//Como extra, establecemos el rango de columnas y paginas
	Wire.write(0x21); //Columnas de 0 a 127
	Wire.write(0x00);
	Wire.write(0x7F);
	Wire.write(0x22); //Paginas de 0 a 7
	Wire.write(0x00); 
	Wire.write(0x07);

	//Modo de escritura horizontal
	//en mi modelo no haria falta enviar este comando (por defecto utiliza este modo)
	Wire.write(0x20);
	Wire.write(0x00);

	//Cerrar la comunicacion
	Wire.endTransmission();
	
	//Limpiamos la memoria, por si hubiera quedado memoria residual
	//de la ultima vez que se encendio la pantalla
	for(int i = 0; i < 1024; i++){
		Wire.beginTransmission(DIRECCION_PANTALLA);
		Wire.write(0x40);
		Wire.write(0x00);
		Wire.endTransmission();
        }
	

}

Ahora, en el void setup se inicializa la pantalla, se vacía la matriz de texto y se añade un texto con un poco de autobombo. Siéntete libre de cambiarlo por lo que quieras, humano.

void setup()   {                
	// Inicializar el controlador de la pantalla OLED
	inicializar_pantalla();
        
        //Cargar la matriz de texto con espacios en blanco
        for(int i = 0; i < 128; i++)
          caracteres_pantalla[i] = 32;
                 
	//Escribir la palabra 'Robologs' en el centro
        anadir_caracter('=', 3,3);
        anadir_caracter('R', 4,3);
        anadir_caracter('o', 5,3);
        anadir_caracter('b', 6,3);
        anadir_caracter('o', 7,3);
        anadir_caracter('l', 8,3);
	    anadir_caracter('o', 9,3);
	    anadir_caracter('g', 10,3);
	    anadir_caracter('s', 11,3);
        anadir_caracter('=', 12,3);
}

En el bucle principal se muestra el contenido de la matriz de texto sobre la pantalla.

void loop() {
        //Dibujar el contenido en la pantalla
	    escribir();

	
}

Bien, ¿cómo debería quedarte finalmente el código?

#include <Wire.h>


#define DIRECCION_PANTALLA  0x3C


//Matriz con la imagen de la fuente
const unsigned char font [] = {

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1C, 0xF6, 0x83, 0x83, 0xF6, 0x1C, 0x18,

0x18, 0x38, 0x6F, 0xC1, 0xC1, 0x6F, 0x38, 0x18, 0x3C, 0x24, 0x24, 0xE7, 0xC3, 0x66, 0x3C, 0x18,

0x18, 0x3C, 0x66, 0xC3, 0xE7, 0x24, 0x24, 0x3C, 0x3E, 0x1C, 0x49, 0x63, 0x63, 0x49, 0x1C, 0x3E,

0x7F, 0x7F, 0x7F, 0x3F, 0x1F, 0x4F, 0x67, 0x73, 0x77, 0x63, 0x49, 0x1C, 0x1C, 0x49, 0x63, 0x77,

0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x7E, 0xFF, 0x81, 0x9D, 0x91, 0x81, 0xFF, 0x7E,

0x00, 0x10, 0x5E, 0xFF, 0x5F, 0x1E, 0x10, 0x00, 0x40, 0xE0, 0xE0, 0x7F, 0x03, 0x06, 0x04, 0x00,

0x1F, 0x1F, 0x05, 0x7D, 0x7C, 0x14, 0x14, 0x00, 0x1F, 0x1F, 0x11, 0x7D, 0x7C, 0x34, 0x7C, 0x5C,

0x00, 0xC0, 0xC0, 0xE0, 0x78, 0x1F, 0x00, 0xFF, 0xFF, 0x00, 0x1F, 0x78, 0xE0, 0xC0, 0xC0, 0x00,

0x36, 0x77, 0x41, 0x41, 0x41, 0x77, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x00,

0x30, 0x79, 0x49, 0x49, 0x49, 0x4F, 0x06, 0x00, 0x00, 0x49, 0x49, 0x49, 0x49, 0x7F, 0x36, 0x00,

0x07, 0x0F, 0x08, 0x08, 0x08, 0x7F, 0x77, 0x00, 0x06, 0x4F, 0x49, 0x49, 0x49, 0x79, 0x30, 0x00,

0x36, 0x7F, 0x49, 0x49, 0x49, 0x79, 0x30, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x77, 0x76, 0x00,

0x36, 0x7F, 0x49, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x06, 0x4F, 0x49, 0x49, 0x49, 0x7F, 0x36, 0x00,

0x00, 0x30, 0x74, 0x54, 0x54, 0x7C, 0x38, 0x00, 0x00, 0x1F, 0x1F, 0x75, 0x75, 0x50, 0x50, 0x00,

0x00, 0x00, 0x00, 0xFC, 0x5E, 0xC7, 0xC7, 0x87, 0x07, 0x87, 0x47, 0xC3, 0x46, 0xFC, 0x00, 0x00,

0x00, 0x00, 0xE0, 0xC1, 0xE6, 0x3C, 0x3A, 0x57, 0x54, 0x54, 0x4A, 0x34, 0x0E, 0x01, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x5F, 0x00, 0x00, 0x00,

0x00, 0x07, 0x07, 0x00, 0x00, 0x07, 0x07, 0x00, 0x24, 0x7E, 0x7E, 0x24, 0x7E, 0x7E, 0x24, 0x00,

0x00, 0x24, 0x2E, 0x6B, 0x6B, 0x3A, 0x12, 0x00, 0x00, 0x66, 0x36, 0x18, 0x0C, 0x66, 0x62, 0x00,

0x30, 0x7A, 0x4F, 0x5D, 0x37, 0x72, 0x50, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x3E, 0x7F, 0x63, 0x41, 0x00, 0x00, 0x41, 0x63, 0x7F, 0x3E, 0x00, 0x00, 0x00,

0x08, 0x2A, 0x3E, 0x1C, 0x1C, 0x3E, 0x2A, 0x08, 0x00, 0x08, 0x08, 0x3E, 0x3E, 0x08, 0x08, 0x00,

0x00, 0x80, 0xE0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00,

0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x00,

0x00, 0x3E, 0x7F, 0x49, 0x45, 0x7F, 0x3E, 0x00, 0x00, 0x40, 0x42, 0x7F, 0x7F, 0x40, 0x40, 0x00,

0x00, 0x42, 0x63, 0x71, 0x59, 0x4F, 0x46, 0x00, 0x00, 0x21, 0x61, 0x45, 0x4F, 0x7B, 0x31, 0x00,

0x00, 0x18, 0x1C, 0x16, 0x7F, 0x7F, 0x10, 0x00, 0x00, 0x27, 0x67, 0x45, 0x45, 0x7D, 0x39, 0x00,

0x00, 0x3E, 0x7F, 0x49, 0x49, 0x79, 0x30, 0x00, 0x00, 0x01, 0x71, 0x79, 0x0D, 0x07, 0x03, 0x00,

0x00, 0x36, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00, 0x06, 0x4F, 0x49, 0x69, 0x3F, 0x1E, 0x00,

0x00, 0x00, 0x00, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x76, 0x36, 0x00, 0x00, 0x00,

0x00, 0x00, 0x08, 0x1C, 0x36, 0x63, 0x41, 0x00, 0x00, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00,

0x00, 0x41, 0x63, 0x36, 0x1C, 0x08, 0x00, 0x00, 0x00, 0x02, 0x03, 0x51, 0x59, 0x0F, 0x06, 0x00,

0x00, 0x3E, 0x7F, 0x41, 0x5D, 0x57, 0x5E, 0x00, 0x00, 0x7C, 0x7E, 0x13, 0x13, 0x7E, 0x7C, 0x00,

0x00, 0x7F, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00, 0x3E, 0x7F, 0x41, 0x41, 0x63, 0x22, 0x00,

0x00, 0x7F, 0x7F, 0x41, 0x63, 0x3E, 0x1C, 0x00, 0x00, 0x7F, 0x7F, 0x49, 0x49, 0x49, 0x41, 0x00,

0x00, 0x7F, 0x7F, 0x09, 0x09, 0x09, 0x01, 0x00, 0x00, 0x3E, 0x7F, 0x41, 0x49, 0x79, 0x79, 0x00,

0x00, 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x41, 0x7F, 0x7F, 0x41, 0x00, 0x00,

0x00, 0x20, 0x60, 0x40, 0x40, 0x7F, 0x3F, 0x00, 0x00, 0x7F, 0x7F, 0x1C, 0x36, 0x63, 0x41, 0x00,

0x00, 0x7F, 0x7F, 0x40, 0x40, 0x40, 0x40, 0x00, 0x7F, 0x7F, 0x06, 0x0C, 0x06, 0x7F, 0x7F, 0x00,

0x00, 0x7F, 0x7F, 0x0E, 0x1C, 0x7F, 0x7F, 0x00, 0x00, 0x3E, 0x7F, 0x41, 0x41, 0x7F, 0x3E, 0x00,

0x00, 0x7F, 0x7F, 0x09, 0x09, 0x0F, 0x06, 0x00, 0x00, 0x3E, 0x7F, 0x51, 0x21, 0x7F, 0x5E, 0x00,

0x00, 0x7F, 0x7F, 0x09, 0x19, 0x7F, 0x66, 0x00, 0x00, 0x26, 0x6F, 0x49, 0x49, 0x7B, 0x32, 0x00,

0x00, 0x01, 0x01, 0x7F, 0x7F, 0x01, 0x01, 0x00, 0x00, 0x3F, 0x7F, 0x40, 0x40, 0x7F, 0x7F, 0x00,

0x00, 0x1F, 0x3F, 0x60, 0x60, 0x3F, 0x1F, 0x00, 0x7F, 0x7F, 0x30, 0x18, 0x30, 0x7F, 0x7F, 0x00,

0x00, 0x63, 0x77, 0x1C, 0x1C, 0x77, 0x63, 0x00, 0x00, 0x07, 0x0F, 0x78, 0x78, 0x0F, 0x07, 0x00,

0x00, 0x61, 0x71, 0x59, 0x4D, 0x47, 0x43, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x41, 0x41, 0x00,

0x00, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, 0x41, 0x41, 0x7F, 0x7F, 0x00, 0x00, 0x00,

0x08, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x08, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00,

0x02, 0x06, 0x0C, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x74, 0x54, 0x54, 0x7C, 0x78, 0x00,

0x00, 0x7F, 0x7F, 0x44, 0x44, 0x7C, 0x38, 0x00, 0x00, 0x38, 0x7C, 0x44, 0x44, 0x44, 0x00, 0x00,

0x00, 0x38, 0x7C, 0x44, 0x44, 0x7F, 0x7F, 0x00, 0x00, 0x38, 0x7C, 0x54, 0x54, 0x5C, 0x18, 0x00,

0x00, 0x04, 0x7E, 0x7F, 0x05, 0x05, 0x00, 0x00, 0x00, 0x98, 0xBC, 0xA4, 0xA4, 0xFC, 0x7C, 0x00,

0x00, 0x7F, 0x7F, 0x04, 0x04, 0x7C, 0x78, 0x00, 0x00, 0x00, 0x44, 0x7D, 0x7D, 0x40, 0x00, 0x00,

0x00, 0x80, 0x80, 0xFD, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x10, 0x38, 0x6C, 0x44, 0x00,

0x00, 0x00, 0x41, 0x7F, 0x7F, 0x40, 0x00, 0x00, 0x7C, 0x7C, 0x0C, 0x18, 0x0C, 0x7C, 0x78, 0x00,

0x00, 0x7C, 0x7C, 0x04, 0x04, 0x7C, 0x78, 0x00, 0x00, 0x38, 0x7C, 0x44, 0x44, 0x7C, 0x38, 0x00,

0x00, 0xFC, 0xFC, 0x44, 0x44, 0x7C, 0x38, 0x00, 0x00, 0x38, 0x7C, 0x44, 0x44, 0xFC, 0xFC, 0x00,

0x00, 0x7C, 0x7C, 0x04, 0x04, 0x0C, 0x08, 0x00, 0x00, 0x48, 0x5C, 0x54, 0x54, 0x74, 0x24, 0x00,

0x00, 0x04, 0x04, 0x3E, 0x7E, 0x44, 0x44, 0x00, 0x00, 0x3C, 0x7C, 0x40, 0x40, 0x7C, 0x7C, 0x00,

0x00, 0x1C, 0x3C, 0x60, 0x60, 0x3C, 0x1C, 0x00, 0x1C, 0x7C, 0x60, 0x30, 0x60, 0x7C, 0x1C, 0x00,

0x00, 0x44, 0x6C, 0x38, 0x38, 0x6C, 0x44, 0x00, 0x00, 0x9C, 0xBC, 0xA0, 0xA0, 0xFC, 0x7C, 0x00,

0x00, 0x44, 0x64, 0x74, 0x5C, 0x4C, 0x44, 0x00, 0x00, 0x00, 0x08, 0x3E, 0x77, 0x41, 0x41, 0x00,

0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x77, 0x3E, 0x08, 0x00, 0x00,

0x0C, 0x06, 0x06, 0x0C, 0x18, 0x18, 0x0C, 0x00, 0x00, 0x60, 0x78, 0x5E, 0x46, 0x58, 0x60, 0x00

};

//Matriz que guardara la lista de caracteres que hay que mostrar en pantalla
char caracteres_pantalla [128];

void setup()   {                
	// Inicializar el controlador de la pantalla OLED
	inicializar_pantalla();
        
        //Cargar la matriz de texto con espacios en blanco
        for(int i = 0; i < 128; i++)
          caracteres_pantalla[i] = 32;
                 
	//Escribir la palabra 'Robologs' en el centro
        anadir_caracter('=', 3,3);
        anadir_caracter('R', 4,3);
        anadir_caracter('o', 5,3);
        anadir_caracter('b', 6,3);
        anadir_caracter('o', 7,3);
        anadir_caracter('l', 8,3);
	    anadir_caracter('o', 9,3);
	    anadir_caracter('g', 10,3);
	    anadir_caracter('s', 11,3);
        anadir_caracter('=', 12,3);
}

void loop() {
        //Dibujar el contenido en la pantalla
	    escribir();

	
}

void escribir()
{
   //Recorre la matriz de caracteres
   //y los va mostrando en pantalla
   char c;
   for(int i = 0; i < 128; i++)
   {
	c = caracteres_pantalla[i]; //Guardar el caracter que hay que escribir

	//Buscarlo en la imagen de la fuente y dibujarlo
        for(int j = c*8; j < c*8+8; j++)
	{
		Wire.beginTransmission(DIRECCION_PANTALLA);
		Wire.write(0x40);
        	Wire.write(font[j]);
        	Wire.endTransmission();
	}
   }

}
          

void anadir_caracter(int letra, int posX, int posY)
{
  //Comprobar que el caracter no se salga del rango
  if(127 < letra || 0 > letra)
    letra = 127;
    
  //Hay 8x16 posiciones para los caracteres
  caracteres_pantalla[(posX)+(posY*16)] = letra;
  
}


void inicializar_pantalla()
{
	Wire.begin(); //Iniciar la comunicacion I2C de Arduino


	//Aumentar la frecuencia de SCL a 400 kHz
	//Esto aumentara la velocidad de refresco
	TWBR = 12; 


	/* Inicializar la pantalla, siguiendo las instrucciones
	   exactas de la pag. 64 de la documentacion:   */

	//Iniciar la comunicacion con la pantalla
	Wire.beginTransmission(DIRECCION_PANTALLA); 
	
	//Le decimos a la pantalla que viene una lista de comandos de configuracion
	Wire.write(0x00);

	//Apagar la pantalla
	Wire.write(0xAE);

	// Establecer el maximo de filas a 0x3F = 63
	// es decir, ira de 0 a 63, por tanto tenemos 64 filas de pixeles
	Wire.write(0xA8);
	Wire.write(0x3F);

	//Poner el offset a 0
	Wire.write(0xD3);
	Wire.write(0x00);

	//Poner el comienzo de linea a 0
	Wire.write(0x40);

	//Invertir el eje X de pantalla, por si esta girada.
	//Puedes cambiarlo por 0xA0 si necesitas cambiar la orientacion
	Wire.write(0xA1);

	//Invertir el eje Y de la patnalla
	//Puedes cambiarlo por 0xC0 si necesitas cambiar la orientacion
	Wire.write(0xC8);

	//Mapear los pines COM
	Wire.write(0xDA);
	Wire.write(0x12); 
	//Al parecer, la unica configuracion que funciona con mi modelo es 0x12, a pesar
	// de que en la documentacion dice que hay que poner 0x02


	//Configurar el contraste
	Wire.write(0x81);
	Wire.write(0x7F); //Este valor tiene que estar entre 0x00 (min) y 0xFF (max)

	
	//Este comando ordena al chip que active el output de la pantalla en funcion del contenido
	//almacenado en su GDDRAM
	Wire.write(0xA4);

	//Poner la pantalla en modo Normal
	Wire.write(0xA6);

	//Establecer la velocidad del Oscilador
	Wire.write(0xD5);
	Wire.write(0x80);

	//Activar el 'charge pump'
	Wire.write(0x8D);
	Wire.write(0x14);

	//Encender la pantalla
	Wire.write(0xAF);


	//Como extra, establecemos el rango de columnas y paginas
	Wire.write(0x21); //Columnas de 0 a 127
	Wire.write(0x00);
	Wire.write(0x7F);
	Wire.write(0x22); //Paginas de 0 a 7
	Wire.write(0x00); 
	Wire.write(0x07);

	//Modo de escritura horizontal
	//en mi modelo no haria falta enviar este comando (por defecto utiliza este modo)
	Wire.write(0x20);
	Wire.write(0x00);

	//Cerrar la comunicacion
	Wire.endTransmission();
	
	//Limpiamos la memoria, por si hubiera quedado memoria residual
	//de la ultima vez que se encendio la pantalla
	for(int i = 0; i < 1024; i++){
		Wire.beginTransmission(DIRECCION_PANTALLA);
		Wire.write(0x40);
		Wire.write(0x00);
		Wire.endTransmission();
        }
	

}

En resumen, hoy has aprendido a conectar una pantalla OLED con Arduino sin necesidad de utilizar ninguna librería de terceros. Si quieres continuar practicando te propongo que intentes hacer algunas mejoras por tu cuenta:

  • Modificar el array de la imagen de la fuente y la función de escritura para que acepte carácteres en ASCII extendido. Esta es la fuente ATASCII extendida:
  • Función para escribir frases: en vez de escribir los textos carácter a carácter, esta función recibirá un string y lo mostrará en pantalla.
  • Función que, al recibir un mensaje por serial, lo muestre por pantalla.
  • Función para dibujar figuras geométricas simples (puntos, cuadrados y círculos).

Final de línea.

Tr4nsduc7or

Originariamente creado cómo un galvanómetro de bolsillo, Transductor tomó consciencia de si mismo y fue despedido cuando en vez cumplir con su trabajo se dedicó a pensar teorías filosóficas sobre los hilos de cobre, los electrones y el Sentido del efecto Joule en el Universo. Guarda cierto recelo a sus creadores por no comprender la esencia metafísica de las metáforas de su obra. Actualmente trabaja a media jornada cómo antena de radio, y dedica su tiempo libre a la electrónica recreativa y a la filosofía.

4
Deja un comentario

avatar
2 Hilos iniciados
2 Respuestas a hilos
0 Followers
 
Most reacted comment
Hottest comment thread
4 Nº autores comentarios
JavieroxmusTr4nsduc7orDaniee Autores de comentarios recientes
más nuevos primero más antiguos primero
oxmus
Humano
oxmus

Tengo problemas en mostrar cosa en mi pantalla oled.
El modelo en principio es el mismo pero, detras pone IIC y adress 0x78 por mas que pongo la direccion no ahi manera de escribir nada en ella. e probado todo tipo de librerias y el tuto de aki pero sin exito. Tiene los mismos pines SCL y SDA.

Javier
Humano
Javier

A mí me pasaba lo mismo, pero ponga lo que ponga la dirección correcta es 0x3C. Usa el scanner I2C para comprobarlo. Suerte.

Daniee
Humano
Daniee

Hola quisiera saber si funcionaria con esta pantalla. Gracias de antemano.
https://www.adafruit.com/product/326