Pages Menu
TwitterFacebook



BANNER2_ALT

Posted by on May 22, 2014 in Pantallas LCD/TFT | 23 comments

OLED SSD1316 por I2C con Arduino UNO R3

OLED SSD1316 por I2C con Arduino UNO R3

Pantalla OLED I2C SSD1316

Tutorial para utilizar la pantalla OLED SSD1316 con el protocolo de comunicación I2C y con un Arduino UNO. Este ejemplo se basa en las bibliotecas creadas por Adafruit para 2 tipos de pantallas, las que tienen ya el pin de I2C directo y las que tienen selector de protocolo que tienen todos los pines del controlador OLED SSD1316 externos. Para comenzar la biblioteca la podemos descargar del siguiente enlace:

https://learn.adafruit.com/monochrome-oled-breakouts/arduino-library-and-examples

OLED

Pantalla OLED I2C.

Diagrama de la pantalla OLED SSD1316.

Diagrama

Diagrama de la pantalla de 4 pines.

Diagrama de conexiones OLED SSD1316 – Arduino.

A continuación se muestra el diagrama esquemático de conexión entre la pantalla OLED SSD1316 y un Arduino, si se tiene la pantalla OLED SSD1316 que tiene mas pines ir a la parte inferior donde encontrara mas información.

DIBUJO

Diagrama esquematico de la pantalla con el Arduino en I2C.

Código de ejemplo OLED SSD1316, para Arduino.

//==========================================================//
// //
// OLED ssd1316 Test Code //
// Adafruit
// //
//==========================================================//

#include <avr/pgmspace.h>
#include <Wire.h>
//---------------Datos de la fuente y los graficos----------//
#include "data.h"
//==========================================================//

// Dirección I2C de la pantalla
#define OLED_address 0x3c

void setup()
{

 Wire.begin(); // Inicializa comunicación I2C
 init_OLED(); // Inicializa el modulo OLED
 reset_display(); // Resetea a la pantalla
}

// Loop principal
//==========================================================//
void loop()
{ 

 clear_display(); //Limpia la pantalla

 sendCharXY('A',0,0); //Escribe un caracter en la posicion fila 0, columna 0.
 sendCharXY('B',0,1);
 sendCharXY('C',0,2);
 sendCharXY('D',0,3);
 sendCharXY('E',0,4);
 sendCharXY('F',0,5);
 sendCharXY('G',0,6);
 sendCharXY('H',0,7);
 sendCharXY('I',0,8);
 sendCharXY('J',0,9);
 sendCharXY('K',0,10);
 sendCharXY('L',0,11);
 sendCharXY('L',0,12);
 sendCharXY('M',0,13);
 sendCharXY('N',0,14);
 sendCharXY('O',0,15);

 sendCharXY('1',1,0); // Escribe un caracter en la posicion fila 1 columan 0
 sendCharXY('2',1,1);
 sendCharXY('3',1,2);
 sendCharXY('4',1,3);
 sendCharXY('5',1,4);
 sendCharXY('6',1,5);
 sendCharXY('7',1,6);
 sendCharXY('8',1,7);
 sendCharXY('9',1,8);
 sendCharXY('"',1,9);
 sendCharXY('!',1,10);
 sendCharXY('$',1,11);
 sendCharXY('%',1,12);
 sendCharXY('/',1,13);
 sendCharXY('(',1,14);
 sendCharXY(')',1,15);

 sendStrXY("Herramientas Tec",2,0); // Escribe una cadena de caracteres en la fila 2 y columna 0
 sendStrXY("hetpro-store.com",3,0);
 sendStrXY("Marcelino Garcia B.",4,0);
 sendStrXY("1615-A, Guadalajara",5,0);

 sendCharXY('A',7,0);
 sendCharXY('B',7,1);
 sendCharXY('C',7,2);
 sendCharXY('D',7,3);
 sendCharXY('E',7,4);
 sendCharXY('F',7,5);
 sendCharXY('G',7,6);
 sendCharXY('H',7,7);
 sendCharXY('I',7,8);
 sendCharXY('J',7,9);
 sendCharXY('K',7,10);
 sendCharXY('L',7,11);
 sendCharXY('L',7,12);
 sendCharXY('M',7,13);
 sendCharXY('N',7,14);
 sendCharXY('O',7,15);
 delay(4000); // Retardo de 4 segundos
 reset_display(); // Reseteo del display

}

//==========================================================//
// Resets display depending on the actual mode.
static void reset_display(void)
{
 displayOff();
 clear_display();

 displayOn();
}

//==========================================================//
// Turns display on.
void displayOn(void)
{
 sendcommand(0xaf); //display on
}

//==========================================================//
// Turns display off.
void displayOff(void)
{
 sendcommand(0xae); //display off
}

//==========================================================//
// Clears the display by sendind 0 to all the screen map.
static void clear_display(void)
{
 unsigned char i,k;
 for(k=0;k<8;k++)
 {
 setXY(k,0);
 {
 for(i=0;i<128;i++) //clear all COL
 {
 SendChar(0); //clear all COL
 //delay(10);
 }
 }
 }
}

//==========================================================//
static void printBigTime(char *string)
{

 int Y;
 int lon = strlen(string);
 if(lon == 3) {
 Y = 0;
 } else if (lon == 2) {
 Y = 3;
 } else if (lon == 1) {
 Y = 6;
 }

 int X = 2;
 while(*string)
 {
 printBigNumber(*string, X, Y);

 Y+=3;
 X=2;
 setXY(X,Y);
 *string++;
 }
}

//==========================================================//
// Prints a display big number (96 bytes) in coordinates X Y,
// being multiples of 8. This means we have 16 COLS (0-15)
// and 8 ROWS (0-7).
static void printBigNumber(char string, int X, int Y)
{
 setXY(X,Y);
 int salto=0;
 for(int i=0;i<96;i++)
 {
 if(string == ' ') {
 SendChar(0);
 } else
 SendChar(pgm_read_byte(bigNumbers[string-0x30]+i));

 if(salto == 23) {
 salto = 0;
 X++;
 setXY(X,Y);
 } else {
 salto++;
 }
 }
}

//==========================================================//
// Actually this sends a byte, not a char to draw in the display.
// Display's chars uses 8 byte font the small ones and 96 bytes
// for the big number font.
static void SendChar(unsigned char data)
{
 Wire.beginTransmission(OLED_address); // begin transmitting
 Wire.write(0x40);//data mode
 Wire.write(data);
 Wire.endTransmission(); // stop transmitting
}

//==========================================================//
// Prints a display char (not just a byte) in coordinates X Y,
// being multiples of 8. This means we have 16 COLS (0-15)
// and 8 ROWS (0-7).
static void sendCharXY(unsigned char data, int X, int Y)
{
 setXY(X, Y);
 Wire.beginTransmission(OLED_address); // begin transmitting
 Wire.write(0x40);//data mode

 for(int i=0;i<8;i++)
 Wire.write(pgm_read_byte(myFont[data-0x20]+i));

 Wire.endTransmission(); // stop transmitting
}

//==========================================================//
// Used to send commands to the display.
static void sendcommand(unsigned char com)
{
 Wire.beginTransmission(OLED_address); //begin transmitting
 Wire.write(0x80); //command mode
 Wire.write(com);
 Wire.endTransmission(); // stop transmitting

}

//==========================================================//
// Set the cursor position in a 16 COL * 8 ROW map.
static void setXY(unsigned char row,unsigned char col)
{
 sendcommand(0xb0+row); //set page address
 sendcommand(0x00+(8*col&0x0f)); //set low col address
 sendcommand(0x10+((8*col>>4)&0x0f)); //set high col address
}

//==========================================================//
// Prints a string regardless the cursor position.
static void sendStr(unsigned char *string)
{
 unsigned char i=0;
 while(*string)
 {
 for(i=0;i<8;i++)
 {
 SendChar(pgm_read_byte(myFont[*string-0x20]+i));
 }
 *string++;
 }
}

//==========================================================//
// Prints a string in coordinates X Y, being multiples of 8.
// This means we have 16 COLS (0-15) and 8 ROWS (0-7).
static void sendStrXY( char *string, int X, int Y)
{
 setXY(X,Y);
 unsigned char i=0;
 while(*string)
 {
 for(i=0;i<8;i++)
 {
 SendChar(pgm_read_byte(myFont[*string-0x20]+i));
 }
 *string++;
 }
}

//==========================================================//
// Inits OLED SSD1316 and draws logo at startup
static void init_OLED(void)
{
 sendcommand(0xae); //display off
 sendcommand(0xa6); //Set Normal Display (default)
 // Adafruit Init sequence for 128x64 OLED module
 sendcommand(0xAE); //DISPLAYOFF
 sendcommand(0xD5); //SETDISPLAYCLOCKDIV
 sendcommand(0x80); // the suggested ratio 0x80
 sendcommand(0xA8); //SSD1306_SETMULTIPLEX
 sendcommand(0x3F);
 sendcommand(0xD3); //SETDISPLAYOFFSET
 sendcommand(0x0); //no offset
 sendcommand(0x40 | 0x0); //SETSTARTLINE
 sendcommand(0x8D); //CHARGEPUMP
 sendcommand(0x14);
 sendcommand(0x20); //MEMORYMODE
 sendcommand(0x00); //0x0 act like ks0108

 sendcommand(0xA0 | 0x1); //SEGREMAP //Rotate screen 180 deg
 //sendcommand(0xA0);

 sendcommand(0xC8); //COMSCANDEC Rotate screen 180 Deg
 //sendcommand(0xC0);

 sendcommand(0xDA); //0xDA
 sendcommand(0x12); //COMSCANDEC
 sendcommand(0x81); //SETCONTRAS
 sendcommand(0xCF); //
 sendcommand(0xd9); //SETPRECHARGE
 sendcommand(0xF1);
 sendcommand(0xDB); //SETVCOMDETECT
 sendcommand(0x40);
 sendcommand(0xA4); //DISPLAYALLON_RESUME
 sendcommand(0xA6); //NORMALDISPLAY 

 clear_display();
 sendcommand(0x2e); // stop scroll
 //----------------------------REVERSE comments----------------------------//
 // sendcommand(0xa0); //seg re-map 0->127(default)
 // sendcommand(0xa1); //seg re-map 127->0
 // sendcommand(0xc8);
 // delay(1000);
 //----------------------------REVERSE comments----------------------------//
 // sendcommand(0xa7); //Set Inverse Display
 // sendcommand(0xae); //display off
 sendcommand(0x20); //Set Memory Addressing Mode
 sendcommand(0x00); //Set Memory Addressing Mode ab Horizontal addressing mode
 // sendcommand(0x02); // Set Memory Addressing Mode ab Page addressing mode(RESET) 

 setXY(0,0);
 /*
 for(int i=0;i<128*8;i++) // show 128* 64 Logo
 {
 SendChar(pgm_read_byte(logo+i));
 }
 */
 sendcommand(0xaf); //display on

}

Para pantallas con los pines SSD1306 completos.

Para las pantallas que tienen todos los pines funcionan igual las mismas bibliotecas debido a que tienen el mismo controlador, solo hay que tomar varias consideraciones. En caso de utilizarla con el protocolo I2C tendremos que seguir los siguientes pasos.

  1. Soldar un puente de estaño con cautín en el jumper BS1, prestando mucha atención a que es un jumper con 3 contactos tratar de no cubrir los 3 pads si no solo el central con uno de los 2. Para I2C tiene que quedar como en la figura inferior.
  2. Conectar el pin de RST Reset, a el microcontrolador para controlarlo desde el mismo o si se desea tenerla siempre activada, podemos dejarlo conectado a 3.3V.
  3. Conectar el pin de DC para seleccionar la dirección, 0x3C cuando esta en 3.3V y 0x3D cuando esta en GND.

 

OLED SSD1316

Jumpers para I2C.

OLED SSD1316

OLED SSD1316.

OLED SSD1316

OLED SSD1316.

OLED SSD1316

OLED SSD1316 conexión con un microcontrolador.

 

 

 

 

23 Comments

  1. Después de corregir algunos detalles manda los sigiuientes errores al compilar:

    OLE_Test1.ino: In function ‘void printBigNumber(char, int, int)’:
    OLE_Test1:174: error: ‘bigNumbers’ was not declared in this scope
    OLE_Test1.ino: In function ‘void sendCharXY(unsigned char, int, int)’:
    OLE_Test1:209: error: ‘myFont’ was not declared in this scope
    OLE_Test1.ino: In function ‘void sendStr(unsigned char*)’:
    OLE_Test1:243: error: ‘myFont’ was not declared in this scope
    OLE_Test1.ino: In function ‘void sendStrXY(char*, int, int)’:
    OLE_Test1:260: error: ‘myFont’ was not declared in this scope

    • Francisco esos errores aparecen por que no tienes completa la biblioteca, checa que tengas en uno de los archivos las definiciones que te marcan como “myFon” o “bigNumbers”.

  2. buenas noches, hace unos dias adquiri 2 de sus pantallas, una es como la mostrada, la otra contiene mas pines (se puede seleccionar la comunicacion por SPI), tendra el codigo completo con librerias que uso en este ejemplo? veo que ahi selecciono la direccion 3C, pero la pantalla dice que es la 78, agradesco su ayuda

    • La que tiene mas pines es la nueva versión, lo que hace es que se puede comunicar con varios protocolos, solo cambia la dirección en tu programa y no olvides seleccionar el protocolo que necesitas con el jumper de soldadura trasero.

      • ya lo hize, e incluso probe la comunicacion serial de 4 hilos, el OLED de 4 pines si se comunica correctamente, pero el que tiene los distuintos protocolos no. ya revise los “jumpers” y todo es correcto, sin embargo no se comunica, tampoco enciende ni nada.

        • Edgar, deja checo la pantalla para I2C mándame un correo a hector.torres@hetpro.com.mx en unos días, ya que las oficinas están cerradas hasta el 2 de enero. Igual tratare de responder en este medio también.

  3. EL programa ya compila sin errores; pero al cargar manda el sig. error:

    avrdude: stk500_getsync(): not in sync: resp=0x00

    • Francisco, ese problema suele ser debido a que no esta configurado el puerto correctamente del arduino, checa el administrador de dispositivos y verifica que tengas el mismo “COM” que en el arduino.

  4. En este momento estamos así:
    *Tengo la pantalla de 16 pines
    *Los programas de Adafruit compilan sin errores, aparentemente se cargan al Arduino pero no aparece nada en la pantalla
    *El programa que está como ejemplo en la página de HETPRO, manda errores por no encontrar “printBigNumber” y “myFont”; *Estas bibliotecas no las he localizado en https://learn.adafruit.com/monochrome-oled-breakouts/arduino-library-and-examples
    *Resultado: no he logrado hacer funcionar la pantalla

  5. Hola, yo tengo el mismo problema llevo varios días leyendo los manuales y foros pero no logro resolverlo, he logrado conectar la pantalla via SPI, pero no logro hacerlo por IIC que es lo que necesito.
    Después de cambiar los jumpers no logro encender la pantalla.

    • Gonzalo, te voy a copiar los puntos más importantes del tutorial si tienes la pantalla multi-protocolo para ver si los revisaste a detalle:
      Soldar un puente de estaño con cautín en el jumper BS1, prestando mucha atención a que es un jumper con 3 contactos tratar de no cubrir los 3 pads si no solo el central con uno de los 2. Para I2C tiene que quedar como en la figura inferior.
      Conectar el pin de RST Reset, a el microcontrolador para controlarlo desde el mismo o si se desea tenerla siempre activada, podemos dejarlo conectado a 3.3V.
      Conectar el pin de DC para seleccionar la dirección, 0x3C cuando esta en 3.3V y 0x3D cuando esta en GND.

  6. Esas librerias son pesadas y se comen el 50% de la ram del arduino uno. La verdad no son buenas en lo absoluto.

    • Martín, la ventaja es que son muy fáciles de usar y funcionan con muchos dispositivos. Si tienes otras en mente nos interesaría que compartieras esa información. Saludos.

      • U8glib es una librería muy buena que consume mucho menos ram que adafruit, es excelente, fácil e intuitiva con muchos ejemplos. Solo modifique un poco para que tenga menos consumo de ram y salio funcionando.
        Como te comente adafruit consume al menos 1k de memoria y el atmega 328 uno solo tiene 2k. Con solo declarar unos sensores como dth, solo unos strings sin progem o algunos buffer la memo se llena en el acto incluso sobrepasando los 2 k. Y sabemos que si dejamos con menos de un 25-30% de ram libre es muy probable que tenga un comportamiento inadecuado.

        • Martin, muchas gracias por el dato, vamos a tomar en consideración para ver si generamos otro tutorial con esta otra librería que mencionas. Saludos y gracias por compartir ese dato.

          • Al contrario, gracias a vos por estos tutoriales de facil comprension y bien explicados!!!!

  7. Hola que puedo si me marca este tipo de error:

    #error(“Height incorrect, please fix Adafruit_SSD1306.h!”);

    espero que me ayudes, gracias

    • Hola CGG probablemente te estas saliendo de los limites en posición o tamaño de caracter para la pantalla, revisa eso!.

Post a Reply

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

Cheap Big Tits Cam Sex Girls