INTRODUCCIÓN
Hace poco empecé a trabajar con los módulos ESP32, y al momento de realizar las pruebas me encontré con algunos inconvenientes:
1 | El módulo ocupa un espacio considerable en el protoboard y esto dificulta las conexiones con otros dispositivos externos |
2 | Realizar las conexiones externas toma mucho tiempo, por lo mismo de que se tiene cablear todos los dispositivos |
Debido a estos inconvenientes hoy crearemos una tarjeta entrenadora para ESP32 que incluya casi la mayoría de dispositivos y módulos básicos tales como el reloj de tiempo real, pantalla lcd de 16×2, 2 display de 7 segmentos, sensor ultrasonido, pantalla OLED, 6 entradas digitales para sensores y con pulsadores incluidos, 2 entradas analógicas con potenciómetros, led RGB, 4 salidas a transistores mosfets, 1 salida triac para controlar cargas de corriente alterna, 1 salida a relay y considero que lo más importante es poder subir cualquier programa de manera directa desde el IDE de arduino a nuestra tarjeta entrenadora.
DATOS TÉCNICOS
- Tensión de alimentación……………………….…………12VDC
- Corriente de alimentación………………….……………150mA
- Entadas digitales 5-12VDC……………………….……6
- Sensor ultrasonido………………………………………………Sí
- Entradas analógicas (voltaje) 0-3.3V “potenciometro incorporado”…………..2
- Led RGB………………………………………1
- Display de 7segmentos………………..2
- Salidas transistores MOSFETs……….……………………………4
-
- Tensión DC………………………………………………30V
- Corriente DC……………………………………………2A
-
- Salidas TRIAC………………………………………………………3
-
- Tensión AC…………..……….………………….….……250V
- Corriente AC…………………………………………….2A
-
- Salidas RLY…………………………………………………………1
-
- Tensión AC…………..……….………………….….……250V
- Corriente AC…………………………………………….5A
- Tensión DC………………………………………………30V
- Corriente DC……………………………………………5A
-
- Pantalla LCD………………………………………………………………Sí
- Pantalla OLED……………………………………………………………Sí
- Comunicación I2C…………………….……….………………1
- ESP32 (WIFI)……………………………………………………………..Sí
- ESP32 Bluetooth………………..…………………………………….Sí
- Reloj de tiempo real………………………………………..Sí
- Programación Directa………………………………………..Ordenador – Tarjeta entrenadora
- Entorno de programación………………………..………..Arduino IDE
- Condiciones ambientales min……………………….….-40°
- Condiciones ambientales max…………………..……….85°
- Dimensiones……………………………………………………….140x100mm
LISTA DE COMPONENTES ELECTRÓNICOS
Categoría | Cantidad | Referencias | Valor | PCB Package | DATASHEET |
Condensadores | 12 | C1,C2,C3,C5,C6,C7,C12, C13,C14,C15,C16,C17 |
100nF | 0603_CAP | (see & buy) |
Condensadores | 1 | C4 | 10uF | 1206_CAP | (see & buy) |
Condensadores | 1 | C8 | 470uF | CAP SMD 10.5X10MM ALUMINUM 470UF/35V | (see & buy) |
Condensadores | 2 | C9,C18 | 220uF | CAP SMD 6.3X7.7MM ALUMINUM 220UF/16V | (see & buy) |
Condensadores | 1 | C10 | 100nF | 1206_CAP | (see & buy) |
Condensadores | 1 | C11 | 1000uF | ELEC-RAD25 | (see & buy) |
Resistencias | 12 | R1,R2,R10,R11,R12,R15, R22,R23,R24,R25,R26,R27 |
10k | 0603_RES | (see & buy) |
Resistencias | 14 | R3,R4,R5,R6,R14,R17,R34, R35,R36,R37,R38,R39,R40,R63 |
1k | 0603_RES | (see & buy) |
Resistencias | 2 | R7,R8 | 10k | RES_ARRAY 0603X4 | (see & buy) |
Resistencias | 1 | R9 | 470 | 0603_RES | (see & buy) |
Resistencias | 1 | R13 | 3.3k | 0603_RES | (see & buy) |
Resistencias | 1 | R16 | 4.7k | 0603_RES | (see & buy) |
Resistencias | 17 | R18,R61,R62,R64,R65,R66,R67, R68,R69,R70,R71,R72,R73,R74, R75,R76,R77 |
120 | 0603_RES | (see & buy) |
Resistencias | 1 | R19 | 470 | 0805_RES | (see & buy) |
Resistencias | 10 | R20,R21,R42,R43,R47,R48,R52, R53,R57,R58 |
220 | 0603_RES | (see & buy) |
Resistencias | 6 | R28,R29,R30,R31,R32,R33 | 2.4k | 1206_RES | (see & buy) |
Resistencias | 8 | R41,R45,R46,R50,R51,R55, R56,R60 |
1k | 0805_RES | (see & buy) |
Resistencias | 4 | R44,R49,R54,R59 | 10k | 0805_RES | (see & buy) |
Integrados | 1 | U1 | CH340C | SO16 | (see & buy) |
Integrados | 1 | U2 | ESP-32s | ESP-32S | (see & buy) |
Integrados | 1 | U3 | AT24C512B | SO8 | (see & buy) |
Integrados | 1 | U4 | DS3232 | SO16W | (see & buy) |
Integrados | 1 | U5 | PCF8574 | SO16W | (see & buy) |
Integrados | 1 | U6 | LD1117S33 | SOT230P700X180-4 | (see & buy) |
Integrados | 1 | U7 | LM2576-3,3 | TO170P1410X464-6 | (see & buy) |
Integrados | 1 | U8 | TLP265J | SOIC250P670X300-4 | (see & buy) |
Integrados | 1 | U9 | T405Q-600 | DPAK-N | (see & buy) |
Integrados | 1 | U10 | 74HC14 | TSSOP14 | (see & buy) |
Integrados | 1 | U11 | 74HC541 | TSSOP20 | (see & buy) |
Integrados | 5 | U12,U13,U14,U16,U17 | ILD207T | SO8 | (see & buy) |
Integrados | 1 | U15 | LD1117S50 | SOT230P700X180-4 | (see & buy) |
Integrados | 2 | U18,U19 | 74HC595 | SO16 | (see & buy) |
Transistores | 3 | Q1,Q2,Q3 | PMBT3904,215 | SOT23-3 | (see & buy) |
Transistores | 4 | Q4,Q5,Q6,Q7 | NJVNJD2873T4G | D-PACK1 | (see & buy) |
Diodos | 1 | D1 | 1N4148W | SOD123 | (see & buy) |
Diodos | 1 | D2 | RR1VWM6STFTR | SOD2614X116 | (see & buy) |
Diodos | 7 | D3,D4,D6,D13,D14,D15,D16 | LED-RED | LEDC2012X120 | (see & buy) |
Diodos | 2 | D5,D20 | B330A-13-F | DIOM5226X230N | (see & buy) |
Diodos | 8 | D7,D8,D9,D10,D11,D12, D18,D19 |
LED-GREEN | LEDC1608X60 | (see & buy) |
Diodos | 1 | D17 | RGBLED-CC | LED RGB CC | (see & buy) |
Miscelánea | 2 | 1,2 | DISPLAY 7SEG | (see & buy) | |
Miscelánea | 1 | BAT1 | 3V | BAT 3V | (see & buy) |
Miscelánea | 2 | BTN1,BTN2 | RST | BUTTON SMD 2P | (see & buy) |
Miscelánea | 6 | BTN3,BTN4,BTN5,BTN6, BTN7,BTN8 |
BUTTON | BUTTON TH 2P | (see & buy) |
Miscelánea | 1 | J1 | USB TYPE C | USB TYPE C | (see & buy) |
Miscelánea | 1 | J2 | LCD PWR | LCD 16X2 PWR | (see & buy) |
Miscelánea | 1 | J3 | OLED 128X64 | OLED 128X64 | (see & buy) |
Miscelánea | 1 | J4 | TBLOCK-M3 | T-BLOCK 3PIN BLUE | (see & buy) |
Miscelánea | 1 | J5 | TBLOCK-M2 | T-BLOCK 2PIN BLUE | (see & buy) |
Miscelánea | 1 | J6 | KFM736-5_0-6P | KFM736-5.0-6P P=5.0MM | (see & buy) |
Miscelánea | 1 | J7 | CONN-SIL7 | CONN-SIL7 | (see & buy) |
Miscelánea | 1 | J8 | HC-SR04 | HC-SR04 | (see & buy) |
Miscelánea | 1 | J9 | CONN-SIL2 | CONN-SIL2 | (see & buy) |
Miscelánea | 2 | J10,J11 | TBLOCK-M3 | T-BLOCK 3PIN GREEN | (see & buy) |
Miscelánea | 1 | J12 | PWR_IN | JACK POWER 12V V3 | (see & buy) |
Miscelánea | 5 | JP1,JP2,JP3,JP4,JP8 | JUMPER | CONN-SIL2 | (see & buy) |
Miscelánea | 2 | JP5,JP6 | JUMPER2 | CONN-SIL3 | (see & buy) |
Miscelánea | 1 | L1 | 100u | SMD 12.5X12.5X5MM | (see & buy) |
Miscelánea | 1 | LCD1 | LM016L | LCD 16X2 | (see & buy) |
Miscelánea | 1 | RL1 | 12V | RL12V NORMAL | (see & buy) |
Miscelánea | 2 | RV1,RV2 | 1k | POTENCIOMETER MANU SMALL | (see & buy) |
CODIGOS(arduino) DE PRUEBA
TEST: DIGITAL INPUTS & OUTPUTS
// inputs const int in1 = 12; const int in2 = 14; const int in3 = 27; const int in4 = 26; const int in5 = 25; const int in6 = 33; // outputs const int ot1 = 15; const int ot2 = 2; const int ot3 = 23; const int ot4 = 34; const int ot5 = 13; const int ot6 = 35; void setup() { pinMode(in1, INPUT); pinMode(in2, INPUT); pinMode(in3, INPUT); pinMode(in4, INPUT); pinMode(in5, INPUT); pinMode(in6, INPUT); pinMode(ot1, OUTPUT); pinMode(ot2, OUTPUT); pinMode(ot3, OUTPUT); pinMode(ot4, OUTPUT); pinMode(ot5, OUTPUT); pinMode(ot6, OUTPUT); } void loop() { // simple test inputs and outputs if (digitalRead(in1))digitalWrite(ot1, 1); else digitalWrite(ot1, 0); if (digitalRead(in2))digitalWrite(ot2, 1); else digitalWrite(ot2, 0); if (digitalRead(in3))digitalWrite(ot3, 1); else digitalWrite(ot3, 0); if (digitalRead(in4))digitalWrite(ot4, 1); else digitalWrite(ot4, 0); if (digitalRead(in5))digitalWrite(ot5, 1); else digitalWrite(ot5, 0); if (digitalRead(in6))digitalWrite(ot6, 1); else digitalWrite(ot6, 0); }
TEST: ANALOG INPUTS & PWM OUTPUTS (led RGB)
//LEDS const int ledR = 15; const int ledG = 2; // PMW SIGNAL const int canalPWM = 0; const int canalPWM1 = 1; const int frecuencia = 500; // en Hz const int resolucion = 12; // 8-16 bits de resolución. void setup() { Serial.begin(9600); // 1) configura señal PWM ledcSetup(canalPWM, frecuencia, resolucion); ledcSetup(canalPWM1, frecuencia, resolucion); ledcAttachPin(ledR, canalPWM); ledcAttachPin(ledG, canalPWM1); } void loop() { ledcWrite(canalPWM, analogRead(A0)); // Belong to VP Serial.println (analogRead(A0)); ledcWrite(canalPWM1, analogRead(A3));// Belong to VN Serial.println (analogRead(A3)); }
TEST: 7SEG DISPLAYS (Counter 0-99)
int clockpin = 5; //Cuando ay que leer los bit SH int data = 18; //Envio datos DS int latch = 19; //indica pin de salida en el chip ST int clockpin1 = 4; //Cuando ay que leer los bit SH int data1 = 16; //Envio datos DS int latch1 = 17; //indica pin de salida en el chip ST // no cambiar el const int const int left_sen = 27; // pin 27 como entrada para el sensor izquierdo const int right_sen = 14; // pin 14 como entrada para el sensor derecho //VARIABLES PARA EL CONTADOR ASCENDIENTE // estas variables si puede ser cambiado int contador = 0; int contador1 = 0; int contadorD = 0; int total = 0; boolean go = false; int estado_coin = 0; // estado actual del pulsador int lastButtonState_coin = 0; // estado del pulsado anterior int estado_left_sen = 0; // estado del pulsado actual int lastButtonState_left = 0; // estado del pulsado anterior //VARIABLES PARA EL CONTADOR DESCENDIENTE // estas variables si puede ser cambiado int estado_right_sen = 0; // estado del pulsado actual int lastButtonState_right = 0; // estado del pulsado anterior const int alrm = 12; // alrm //Aqui esta el array que contiene todos los numeros para nuestro display //El display tiene las conexiones alcontrario ell pin 8 del 74hc595 es el primer dijito binario const int numero[] = { // display B 63, //Numero 0 en binario es : 11111100 6, //Numero 1 en binario es : 00000110 91, //Numero 2 en binario es : 11011010 79, //Numero 3 en binario es : 11110010 102, //Numero 4 en binario es : 01100110 109, //Numero 5 en binario es : 10110110 125, //Numero 6 en binario es : 10111110 7, //Numero 7 en binario es : 11100000 127, //Numero 8 en binario es : 11111110 103, //Numero 9 en binario es : 11110110 63, //Numero 0 en binario es : 11111100 }; const int numero1[] = { // display A 63, //Numero 0 en binario es : 11111100 6, //Numero 1 en binario es : 00000110 91, //Numero 2 en binario es : 11011010 79, //Numero 3 en binario es : 11110010 102, //Numero 4 en binario es : 01100110 109, //Numero 5 en binario es : 10110110 125, //Numero 6 en binario es : 10111110 7, //Numero 7 en binario es : 11100000 127, //Numero 8 en binario es : 11111110 103, //Numero 9 en binario es : 11110110 63, //Numero 0 en binario es : 11111100 }; void setup() { pinMode(left_sen, INPUT); pinMode(right_sen, INPUT); pinMode(latch, OUTPUT); pinMode(clockpin, OUTPUT); pinMode(data, OUTPUT); pinMode(latch1, OUTPUT); pinMode(clockpin1, OUTPUT); pinMode(data1, OUTPUT); pinMode (alrm, OUTPUT); contador1 = 0; digitalWrite(latch1, LOW); shiftOut(data1, clockpin1, MSBFIRST, numero1[contador1]); // lee el arreglo y pasa cada numero a lectura binaria digitalWrite(latch1, HIGH); contador = 0; digitalWrite(latch, LOW); shiftOut(data, clockpin, MSBFIRST, numero[contador]); // lee el arreglo y pasa cada numero a lectura binaria digitalWrite(latch, HIGH); } void loop() { estado_left_sen = digitalRead(left_sen); estado_right_sen = digitalRead(right_sen); if (estado_left_sen != lastButtonState_left) { // si el estado fue cambiado, incremente el conteo if (estado_left_sen == LOW) { // si el estado actual es alto, entonces // que pase de off a on: if (contador < 99) { if (contador1 >= 10) { contador1 = 0; } contador++; contador1++; delay(200); digitalWrite(latch1, LOW); shiftOut(data1, clockpin1, MSBFIRST, numero1[contador1]); // lee el arreglo y pasa cada numero a lectura binaria digitalWrite(latch1, HIGH); if (contador == 10 || contador == 20 || contador == 30 || contador == 40 || contador == 50 || contador == 60 || contador == 70 || contador == 80 || contador == 90) { contadorD++; digitalWrite(latch, LOW); shiftOut(data, clockpin, MSBFIRST, numero[contadorD]); // lee el arreglo y pasa cada numero a lectura binaria digitalWrite(latch, HIGH); } } } } lastButtonState_left = estado_left_sen; // comparar el estado del botón a su estado anterior if (estado_right_sen != lastButtonState_right ) { // si el estado fue cambiado, decrementa el conteo if (estado_right_sen == LOW) { // si el estado actual es alto, entonces // que pase de off a on: if (contador > 0) { contador--; contador1--; digitalWrite(latch1, LOW); shiftOut(data1, clockpin1, MSBFIRST, numero1[contador1]); // lee el arreglo y pasa cada numero a lectura binaria digitalWrite(latch1, HIGH); if (contador == 9 || contador == 19 || contador == 29 || contador == 39 || contador == 49 || contador == 59 || contador == 69 || contador == 79 || contador == 89) { contadorD--; digitalWrite(latch, LOW); shiftOut(data, clockpin, MSBFIRST, numero[contadorD]); // lee el arreglo y pasa cada numero a lectura binaria digitalWrite(latch, HIGH); } if (contador1 == 0) { contador1 = 10; } } } } lastButtonState_right = estado_right_sen; }
TEST: REAL TIME CLOCK “RTC” WITH LCD (16X2)
DOWNLOAD LiquidCrystal_I2C LIBRARY
DOWNLOAD RTClib.rar LIBRARY
// Date and time functions using a DS3231 RTC connected via I2C and Wire lib #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 16, 2); #include "RTClib.h" RTC_DS3231 rtc; char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; void setup () { Serial.begin(57600); lcd.init(); lcd.backlight(); lcd.clear(); lcd.setCursor(0, 0); lcd.print(" ELECTROALL..."); // Mensaje a despegar delay(3000); lcd.clear(); #ifndef ESP32 while (!Serial); // wait for serial port to connect. Needed for native USB #endif if (! rtc.begin()) { Serial.println("Couldn't find RTC"); Serial.flush(); abort(); } if (rtc.lostPower()) { Serial.println("RTC lost power, let's set the time!"); // When time needs to be set on a new device, or after a power loss, the // following line sets the RTC to the date & time this sketch was compiled rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // This line sets the RTC with an explicit date & time, for example to set // January 21, 2014 at 3am you would call: // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0)); } // When time needs to be re-set on a previously configured device, the // following line sets the RTC to the date & time this sketch was compiled // rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // This line sets the RTC with an explicit date & time, for example to set // January 21, 2014 at 3am you would call: // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0)); } void loop () { DateTime now = rtc.now(); Serial.print(now.year(), DEC); Serial.print('/'); Serial.print(now.month(), DEC); Serial.print('/'); Serial.print(now.day(), DEC); Serial.print(" ("); Serial.print(daysOfTheWeek[now.dayOfTheWeek()]); Serial.print(") "); Serial.print(now.hour(), DEC); Serial.print(':'); Serial.print(now.minute(), DEC); Serial.print(':'); Serial.print(now.second(), DEC); Serial.println(); Serial.print(" since midnight 1/1/1970 = "); Serial.print(now.unixtime()); Serial.print("s = "); Serial.print(now.unixtime() / 86400L); Serial.println("d"); // calculate a date which is 7 days, 12 hours, 30 minutes, 6 seconds into the future DateTime future (now + TimeSpan(7, 12, 30, 6)); Serial.print(" now + 7d + 12h + 30m + 6s: "); Serial.print(future.year(), DEC); Serial.print('/'); Serial.print(future.month(), DEC); Serial.print('/'); Serial.print(future.day(), DEC); Serial.print(' '); Serial.print(future.hour(), DEC); Serial.print(':'); Serial.print(future.minute(), DEC); Serial.print(':'); Serial.print(future.second(), DEC); Serial.println(); Serial.print("Temperature: "); Serial.print(rtc.getTemperature()); Serial.println(" C"); lcd.setCursor(0, 0); lcd.print(now.year(), DEC); lcd.print('/'); lcd.print(now.month(), DEC); lcd.print('/'); lcd.print(now.day(), DEC); lcd.print(" ("); lcd.print(daysOfTheWeek[now.dayOfTheWeek()]); lcd.print(") "); lcd.setCursor(0, 1); lcd.print(now.hour(), DEC); lcd.print(':'); lcd.print(now.minute(), DEC); lcd.print(':'); lcd.print(now.second(), DEC); delay(1000); }
TEST: ULTRASONIC SENSOR WITH LCD (16X2)
DOWNLOAD LiquidCrystal_I2C LIBRARY
#include <LiquidCrystal_I2C.h> // Debe descargar la Libreria que controla el I2C //#include<Wire.h> LiquidCrystal_I2C lcd(0x27, 16, 2); int trigger = 34; // declaramos la palabra trigger como un tipo entero y al mismo tiempo reemplaza al pin 34 int echo = 35; // declaramos la palabra echo como un tipo entero y al mismo tiempo reemplaza al pin 35 float tiempo_de_espera, distancia; // creamos una variable de fotante; es decir, nos puede dar resultados en decimales. void setup() { Serial.begin(9600); pinMode (trigger, OUTPUT); // declarmos el pin 34 como salida pinMode (echo, INPUT); // declaramos el 35 como entrada lcd.init(); lcd.backlight(); lcd.clear(); lcd.setCursor(0, 0); lcd.print("ELECTROALL"); // Mensaje a despegar delay(3000); lcd.clear(); } void loop() { digitalWrite (trigger, LOW); delayMicroseconds(4); digitalWrite (trigger, HIGH); delayMicroseconds (10); digitalWrite (trigger, LOW); tiempo_de_espera = pulseIn (echo, HIGH); // pulseIn, recoge la señal del sonido que emite el trigger /*La función pulseIn espera la aparición de un pulso en una entrada y mide su duración, dando como resultado la duración medida El primer parámetro (ECHO) es el pin sobre el que se realizará la medición. Y el segundo parámetro (HIGH) indica si el pulso a esperar será un 1 (HIGH) o un 0 (LOW). */ distancia = (tiempo_de_espera / 2) / 29.15; // formula para hallar la distancia lcd.setCursor(0, 0); lcd.print("distancia"); // Mensaje a despegar lcd.setCursor(0, 1); lcd.print(distancia); // Mensaje a despegar lcd.setCursor(7, 1); lcd.print("cm"); Serial.println(distancia); delay(200); // lcd.clear(); }
TEST: OLED 128×64 pixel display
DOWNLOAD Adafruit-GFX-Library-master LIBRARY
/************************************************************************** This is an example for our Monochrome OLEDs based on SSD1306 drivers Pick one up today in the adafruit shop! ------> http://www.adafruit.com/category/63_98 This example is for a 128x64 pixel display using I2C to communicate 3 pins are required to interface (two I2C and one reset). Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! Written by Limor Fried/Ladyada for Adafruit Industries, with contributions from the open source community. BSD license, check license.txt for more information All text above, and the splash screen below must be included in any redistribution. **************************************************************************/ #include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); #define NUMFLAKES 10 // Number of snowflakes in the animation example #define LOGO_HEIGHT 16 #define LOGO_WIDTH 16 static const unsigned char PROGMEM logo_bmp[] = { B00000000, B11000000, B00000001, B11000000, B00000001, B11000000, B00000011, B11100000, B11110011, B11100000, B11111110, B11111000, B01111110, B11111111, B00110011, B10011111, B00011111, B11111100, B00001101, B01110000, B00011011, B10100000, B00111111, B11100000, B00111111, B11110000, B01111100, B11110000, B01110000, B01110000, B00000000, B00110000 }; void setup() { Serial.begin(9600); // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64 Serial.println(F("SSD1306 allocation failed")); for(;;); // Don't proceed, loop forever } // Show initial display buffer contents on the screen -- // the library initializes this with an Adafruit splash screen. display.display(); delay(2000); // Pause for 2 seconds // Clear the buffer display.clearDisplay(); // Draw a single pixel in white display.drawPixel(10, 10, SSD1306_WHITE); // Show the display buffer on the screen. You MUST call display() after // drawing commands to make them visible on screen! display.display(); delay(2000); // display.display() is NOT necessary after every single drawing command, // unless that's what you want...rather, you can batch up a bunch of // drawing operations and then update the screen all at once by calling // display.display(). These examples demonstrate both approaches... testdrawline(); // Draw many lines testdrawrect(); // Draw rectangles (outlines) testfillrect(); // Draw rectangles (filled) testdrawcircle(); // Draw circles (outlines) testfillcircle(); // Draw circles (filled) testdrawroundrect(); // Draw rounded rectangles (outlines) testfillroundrect(); // Draw rounded rectangles (filled) testdrawtriangle(); // Draw triangles (outlines) testfilltriangle(); // Draw triangles (filled) testdrawchar(); // Draw characters of the default font testdrawstyles(); // Draw 'stylized' characters testscrolltext(); // Draw scrolling text testdrawbitmap(); // Draw a small bitmap image // Invert and restore display, pausing in-between display.invertDisplay(true); delay(1000); display.invertDisplay(false); delay(1000); testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT); // Animate bitmaps } void loop() { } void testdrawline() { int16_t i; display.clearDisplay(); // Clear display buffer for(i=0; i<display.width(); i+=4) { display.drawLine(0, 0, i, display.height()-1, SSD1306_WHITE); display.display(); // Update screen with each newly-drawn line delay(1); } for(i=0; i<display.height(); i+=4) { display.drawLine(0, 0, display.width()-1, i, SSD1306_WHITE); display.display(); delay(1); } delay(250); display.clearDisplay(); for(i=0; i<display.width(); i+=4) { display.drawLine(0, display.height()-1, i, 0, SSD1306_WHITE); display.display(); delay(1); } for(i=display.height()-1; i>=0; i-=4) { display.drawLine(0, display.height()-1, display.width()-1, i, SSD1306_WHITE); display.display(); delay(1); } delay(250); display.clearDisplay(); for(i=display.width()-1; i>=0; i-=4) { display.drawLine(display.width()-1, display.height()-1, i, 0, SSD1306_WHITE); display.display(); delay(1); } for(i=display.height()-1; i>=0; i-=4) { display.drawLine(display.width()-1, display.height()-1, 0, i, SSD1306_WHITE); display.display(); delay(1); } delay(250); display.clearDisplay(); for(i=0; i<display.height(); i+=4) { display.drawLine(display.width()-1, 0, 0, i, SSD1306_WHITE); display.display(); delay(1); } for(i=0; i<display.width(); i+=4) { display.drawLine(display.width()-1, 0, i, display.height()-1, SSD1306_WHITE); display.display(); delay(1); } delay(2000); // Pause for 2 seconds } void testdrawrect(void) { display.clearDisplay(); for(int16_t i=0; i<display.height()/2; i+=2) { display.drawRect(i, i, display.width()-2*i, display.height()-2*i, SSD1306_WHITE); display.display(); // Update screen with each newly-drawn rectangle delay(1); } delay(2000); } void testfillrect(void) { display.clearDisplay(); for(int16_t i=0; i<display.height()/2; i+=3) { // The INVERSE color is used so rectangles alternate white/black display.fillRect(i, i, display.width()-i*2, display.height()-i*2, SSD1306_INVERSE); display.display(); // Update screen with each newly-drawn rectangle delay(1); } delay(2000); } void testdrawcircle(void) { display.clearDisplay(); for(int16_t i=0; i<max(display.width(),display.height())/2; i+=2) { display.drawCircle(display.width()/2, display.height()/2, i, SSD1306_WHITE); display.display(); delay(1); } delay(2000); } void testfillcircle(void) { display.clearDisplay(); for(int16_t i=max(display.width(),display.height())/2; i>0; i-=3) { // The INVERSE color is used so circles alternate white/black display.fillCircle(display.width() / 2, display.height() / 2, i, SSD1306_INVERSE); display.display(); // Update screen with each newly-drawn circle delay(1); } delay(2000); } void testdrawroundrect(void) { display.clearDisplay(); for(int16_t i=0; i<display.height()/2-2; i+=2) { display.drawRoundRect(i, i, display.width()-2*i, display.height()-2*i, display.height()/4, SSD1306_WHITE); display.display(); delay(1); } delay(2000); } void testfillroundrect(void) { display.clearDisplay(); for(int16_t i=0; i<display.height()/2-2; i+=2) { // The INVERSE color is used so round-rects alternate white/black display.fillRoundRect(i, i, display.width()-2*i, display.height()-2*i, display.height()/4, SSD1306_INVERSE); display.display(); delay(1); } delay(2000); } void testdrawtriangle(void) { display.clearDisplay(); for(int16_t i=0; i<max(display.width(),display.height())/2; i+=5) { display.drawTriangle( display.width()/2 , display.height()/2-i, display.width()/2-i, display.height()/2+i, display.width()/2+i, display.height()/2+i, SSD1306_WHITE); display.display(); delay(1); } delay(2000); } void testfilltriangle(void) { display.clearDisplay(); for(int16_t i=max(display.width(),display.height())/2; i>0; i-=5) { // The INVERSE color is used so triangles alternate white/black display.fillTriangle( display.width()/2 , display.height()/2-i, display.width()/2-i, display.height()/2+i, display.width()/2+i, display.height()/2+i, SSD1306_INVERSE); display.display(); delay(1); } delay(2000); } void testdrawchar(void) { display.clearDisplay(); display.setTextSize(1); // Normal 1:1 pixel scale display.setTextColor(SSD1306_WHITE); // Draw white text display.setCursor(0, 0); // Start at top-left corner display.cp437(true); // Use full 256 char 'Code Page 437' font // Not all the characters will fit on the display. This is normal. // Library will draw what it can and the rest will be clipped. for(int16_t i=0; i<256; i++) { if(i == '\n') display.write(' '); else display.write(i); } display.display(); delay(2000); } void testdrawstyles(void) { display.clearDisplay(); display.setTextSize(1); // Normal 1:1 pixel scale display.setTextColor(SSD1306_WHITE); // Draw white text display.setCursor(0,0); // Start at top-left corner display.println(F("Hello, world!")); display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Draw 'inverse' text display.println(3.141592); display.setTextSize(2); // Draw 2X-scale text display.setTextColor(SSD1306_WHITE); display.print(F("0x")); display.println(0xDEADBEEF, HEX); display.display(); delay(2000); } void testscrolltext(void) { display.clearDisplay(); display.setTextSize(2); // Draw 2X-scale text display.setTextColor(SSD1306_WHITE); display.setCursor(10, 0); display.println(F("scroll")); display.display(); // Show initial text delay(100); // Scroll in various directions, pausing in-between: display.startscrollright(0x00, 0x0F); delay(2000); display.stopscroll(); delay(1000); display.startscrollleft(0x00, 0x0F); delay(2000); display.stopscroll(); delay(1000); display.startscrolldiagright(0x00, 0x07); delay(2000); display.startscrolldiagleft(0x00, 0x07); delay(2000); display.stopscroll(); delay(1000); } void testdrawbitmap(void) { display.clearDisplay(); display.drawBitmap( (display.width() - LOGO_WIDTH ) / 2, (display.height() - LOGO_HEIGHT) / 2, logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1); display.display(); delay(1000); } #define XPOS 0 // Indexes into the 'icons' array in function below #define YPOS 1 #define DELTAY 2 void testanimate(const uint8_t *bitmap, uint8_t w, uint8_t h) { int8_t f, icons[NUMFLAKES][3]; // Initialize 'snowflake' positions for(f=0; f< NUMFLAKES; f++) { icons[f][XPOS] = random(1 - LOGO_WIDTH, display.width()); icons[f][YPOS] = -LOGO_HEIGHT; icons[f][DELTAY] = random(1, 6); Serial.print(F("x: ")); Serial.print(icons[f][XPOS], DEC); Serial.print(F(" y: ")); Serial.print(icons[f][YPOS], DEC); Serial.print(F(" dy: ")); Serial.println(icons[f][DELTAY], DEC); } for(;;) { // Loop forever... display.clearDisplay(); // Clear the display buffer // Draw each snowflake: for(f=0; f< NUMFLAKES; f++) { display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, SSD1306_WHITE); } display.display(); // Show the display buffer on the screen delay(200); // Pause for 1/10 second // Then update coordinates of each flake... for(f=0; f< NUMFLAKES; f++) { icons[f][YPOS] += icons[f][DELTAY]; // If snowflake is off the bottom of the screen... if (icons[f][YPOS] >= display.height()) { // Reinitialize to a random position, just off the top icons[f][XPOS] = random(1 - LOGO_WIDTH, display.width()); icons[f][YPOS] = -LOGO_HEIGHT; icons[f][DELTAY] = random(1, 6); } } } }