Sensor de consumo con display Nokia 5110

En proyectos antiguos   de un doble voltímetro y amperímetro para una fuente de laboratorio es habitual disponer de una tensión positiva y otra negativa, lo que nos obliga al uso de amplificadores operacionales para adaptar la señal y poder medirla con Arduino. Lo normal para mostrar las tensiones y corrientes es emplear un LCD monocromo de 16 caracteres x 2 filas de texto, que se suele quedar un poco justo para mostrar toda la información.

Pues bien, en el siguiente proyecto vamos a simplificar el circuito de medida del voltímetro y vamos a sustituir el LCD de 16×2 caracteres por un display gráfico Nokia 5110.

En una primera parte vamos a hacer el voltímetro y en un segundo circuito añadiremos el amperímetro.

EL FAMOSO DISPLAY LCD NOKIA 5110

Utilizaremos 5 pines digitales ademas de la retroiluminación, VCC y GND.

LIBRERIAS ARDUINO

Hay varias librerías disponibles para trabajar con LCDs, siendo la mas interesante la Adafruit-PCD8544-Nokia-5110-LCD-library.

Descargue la librería desde aquí, la PCD8544 necesita a su vez la Adafruit-GFX-Library que puede descargar aquí.

Con las libs en local, abre Arduino y añada las librerías, menú Programa/Incluir Libreria/Añadir Libreria Zip…

Una vez añadidas puede ir a Ejemplos/Librerías personalizadas y abrir el ejemplo pcdtest.

ESQUEMA DE CONEXIONES ARDUINO

Podemos conectar de dos formas, por SPI o sin el.

SIN SPI, CONEXIÓN ESTANDAR.

Funcionará en todos los dispositivos aunque el rendimiento no es tan eficiente como por SPI. De cualquier modo para la mayoría de proyectos es suficiente.

pin 3 – Serial clock out (CLK)
pin 4 – Serial data out (DIN)
pin 5 – Data/Command select (D/C)
pin 6 – LCD chip select (CE)
pin 7 – LCD reset (RST)

Código de inicialización:

 Adafruit_PCD8544 display = Adafruit_PCD8544(3, 4, 5, 6, 7);

CON SPI

Hardware SPI más rápido pero deben usarse ciertos pines por defecto y solo lo soportan algunas placas:
SCK is LCD serial clock (SCLK) – this is pin 13 on Arduino Uno
MOSI is LCD DIN – this is pin 11 on an Arduino Uno
pin 5 – Data/Command select (D/C)
pin 6 – LCD chip select (CS)
pin 7 – LCD reset (RST)

Para Inicializar con SPI:

Adafruit_PCD8544 display = Adafruit_PCD8544(5, 6, 7);

Respecto al código es la única diferencia, solo afecta a los pines y una vez establecidos el resto del código es común.

EL CÓDIGO, ESCRIBIENDO TEXTO EN EL LCD

El siguiente código muestra un texto simple por el display.

Modifica la inicialización al principio del código según conectes los pines con o sin SPI:

  • Con SPI: Adafruit_PCD8544 display = Adafruit_PCD8544(5, 6, 7);
  • Sin SPI: Adafruit_PCD8544 display = Adafruit_PCD8544(3, 4, 5, 6, 7);
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>

// *****  Inicialización por SPI, *****
Adafruit_PCD8544 display = Adafruit_PCD8544(5, 6, 7);
// **** Inicialización sin SPI, pines 3 y 4 ***
//Adafruit_PCD8544 display = Adafruit_PCD8544(3, 4, 5, 6, 7);

#define ledRETROILUM 12

void InitDisplay(){
  pinMode(ledRETROILUM, OUTPUT);  
  display.begin();
  display.setContrast(50);
  display.display();
  digitalWrite(ledRETROILUM, HIGH); 
}

void testTXT1(){
  display.clearDisplay();   // clears the screen and buffer
  setFont(1, WHITE, BLACK);  
  drawTXT(0,0," altaruru.com ");
  setFont(1,BLACK);
  drawTXT(0,8,"lcd nokia 5110");
  drawTXT(0,16,"-");
  drawTXT(0,24,"-");
  drawTXT(0,32,"-");
  drawTXT(0,40,"(c) 2019-03-20");  
  display.display(); // actualiza/refresca display  
}

void setup()   {
  Serial.begin(9600);
  InitDisplay();  
  testTXT1();
}

void loop() {
}

void setFont(int isize, int Color1){
  setFont(isize, Color1, WHITE);
  
}
void setFont(int isize, int Color1, int Color2){
  display.setTextSize(isize);
  display.setTextColor(Color1, Color2);
  // altura de fuente size 1: 8 pixels
  // 6 lineas
  // 14 letras por linea  
}
void drawTXT(int x, int y, String smsg){
  display.setCursor(x,y);
  display.println(smsg);    
}

La función InitDisplay() incluye el código necesario para inicializar el Display y testTXT1() es un ejemplo que escribe varias palabras.

Funciones principales de Adafruit_PCD8544 display:

  • display.setTextSize(isize) establece tamaño de la fuente.
  • display.setTextColor(letra, fondo) establece color de la fuente y el fondo.
  • display.setCursor(x, y) posiciona el cursor para escribir.
  • display.println(mensaje) escribe el texto donde esta el cursor.
  • display.display() refresca/actualiza pantalla.
  • display.clearDisplay() limpia/borra pantalla

Con fuente de tamaño 1, tenemos capacidad para 6 lineas y hasta 14 caracteres por linea.

La función drawTXT(int x, int y, String smsg) unifica en una sola llamada posicionamiento de cursor y escritura del texto.

FUNCIONES DE DIBUJO

Puedes dibujar figuras geométricas o bitmaps, algunas funciones de dibujo:

  • display.drawLine()
  • display.drawRect()
  • display.drawCircle()
  • display.fillRect()
  • display.drawTriangle()
  • display.fillTriangle()
  • display.drawRoundRect()
  • display.fillRoundRect()
  • display.drawBitmap()

Algunos ejemplos directamente sacados del ejemplo pcdtest que facilita la librería:

void testdrawcircle(void) {
  for (int16_t i=0; i<display.height(); i+=2) {
    display.drawCircle(display.width()/2, display.height()/2, i, BLACK);
    display.display();
  }
}

void testfillrect(void) {
  uint8_t color = 1;
  for (int16_t i=0; i<display.height()/2; i+=3) {
    // alternate colors
    display.fillRect(i, i, display.width()-i*2, display.height()-i*2, color%2);
    display.display();
    color++;
  }
}

void testdrawtriangle(void) {
  for (int16_t i=0; i<min(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, BLACK);
    display.display();
  }
}

Como hemos visto es relativamente fácil incluir un LCD en vuestros proyectos. Ahora veamos como conectar este display a una fuente variable de alimentación clásica basada en un regulador típico.

1. Voltímetro con Arduino y LCD Nokia 5110

El voltímetro aquí descrito únicamente lo vamos a usar para medir tensiones positivas.

Solo necesitamos un atenuador de señal a la entrada del pin A0 del Arduino.

El funcionamiento del sketch es muy sencillo. Simplemente conectamos el pin A0 al divisor de tensión formado por las resistencias R1 y R2. Debido al valor escogido para R1 y R2, el divisor de tensión funciona como un atenuador x6 de la tensión que queremos medir, y como la máxima tensión en los pines del Arduino es de 5V, significa que la máxima tensión que podemos medir es de 30V. Todo esto, está explicado con más detalle en el Proyecto 28.2.

Bien, al tener una atenuación x6, la variación entre 0 y 5V en el pin A0 corresponde con una tensión entre 0 y 30V en la fuente de alimentación.

En la variable RawVCC almacenamos el valor de analogRead(A0). Con la función map(RawVCC, 0, 1023, 0, 3000); convertimos los 0-1023 valores posibles de RawVCC en 0-3000, que se corresponden con la variación entre 0 y 30V de la fuente. Luego sólo hay que dividir entre 100 para obtener el valor real de tensión en la fuente de alimentación.

Sketch

/*********************************************************************
This is an example sketch for our Monochrome Nokia 5110 LCD Displays
  Pick one up today in the adafruit shop!
  ------> http://www.adafruit.com/products/338
These displays use SPI to communicate, 4 or 5 pins are required to
interface
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.
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/
// Easy Voltmeter with Arduino & Nokia 5110 LCD Display 
// https://sites.google.com/site/angmuz/
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
// Software SPI (slower updates, more flexible pin options):
// pin 7 - Serial clock out (SCLK)
// pin 6 - Serial data out (DIN)
// pin 5 - Data/Command select (D/C)
// pin 4 - LCD chip select (CS)
// pin 3 - LCD reset (RST)
Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 4, 3);
int RawVCC = 0;
float VCC = 0;
float auxVCC = 0;
void setup()   {
 
  // Iniciamos comunicacion serie 
  Serial.begin(9600);
 
  // Iniciamos comunicacion con la pantalla
  display.begin();
 
  // Establecemos el contraste
  display.setContrast(50);
  // Mostramos la pantalla de inicio durante 2 segundos
  //display.display(); 
  delay(2000);
  display.clearDisplay();   
}
void loop()
{
 
  RawVCC = analogRead(A0);
  auxVCC = map(RawVCC, 0, 1023, 0, 3000);
  VCC = (auxVCC / 100.0);
 
  // text display tests
  display.clearDisplay();
  display.setTextSize(2);
  display.setCursor(0,0);
  display.print("V=");
  display.println(VCC,1);
 
  display.setTextSize(1);
  display.setCursor(0,20);
  display.println("Arduino");
  display.print("Easy Voltmeter");
  display.println("sites@angmuz");
  display.display();
  delay(100);  
 
}

2. Voltímetro y Amperímetro con Arduino y LCD Nokia 5110

El sensor de corriente ACS712 es una solución económica para medir corriente, internamente trabaja con un sensor de efecto Hall que detecta el campo magnético que se produce por inducción de la corriente que circula por la línea que se está midiendo. EL  sensor nos entrega una salida de voltaje proporcional a la corriente, dependiendo la aplicación podemos usar el ACS712-05A, ACS712-20A o el ACS712-30A, para rangos de 5, 20 o 30 amperios respectivamente

El ACS712 podemos encontrarlo en módulos, los cuales nos facilitan sus conexión, traen una bornera para conectar la línea que queremos medir y 3 pines, dos para conectar la alimentación y un pin para la salida analógica.

Para medir la corriente vamos a usar un sensor ACS712. Se conecta como en el esquema, se alimenta entre +5V y GND y la salida la llevamos al pin A3.

Partiendo del código del voltímetro, añadimos las líneas correspondientes al amperímetro.

También la parte correspondiente al cálculo del offset, ya estos módulos tienen un error apreciable. Así conseguimos afinar bastante la medida.

Sketch

// Voltímetro y Amperímetro con Nokia 5110 LCD Display
// https://sites.google.com/site/angmuz/
/*********************************************************************
This is an example sketch for our Monochrome Nokia 5110 LCD Displays
  Pick one up today in the adafruit shop!
  ------> http://www.adafruit.com/products/338
These displays use SPI to communicate, 4 or 5 pins are required to
interface
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.
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
// Software SPI (slower updates, more flexible pin options):
// pin 7 - Serial clock out (SCLK)
// pin 6 - Serial data out (DIN)
// pin 5 - Data/Command select (D/C)
// pin 4 - LCD chip select (CS)
// pin 3 - LCD reset (RST)
Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 4, 3);
// Variables para el voltímetro
int RawVCC = 0;
float VCC = 0;
float auxVCC = 0;
//Variables para el amperímetro
float ICC = 0;
float offset1 = 0;
boolean ofst = 0;
void setup()   {
 
 
  // Iniciamos comunicacion serie 
  Serial.begin(9600);
 
  // Iniciamos comunicacion con la pantalla
  display.begin();
 
  // Establecemos el contraste
  display.setContrast(50);
  // Mostramos la pantalla de inicio durante 2 segundos
  //display.display(); 
  delay(2000);
  display.clearDisplay();   
}
// Función para calcular el offset de la corriente ICC
float offset1Adj()
{
 
  display.clearDisplay();
  display.setTextSize(1);
  display.setCursor(0,0);
  display.println("Calculando");
  display.println("offset");
  display.println("No conectar");
  display.println("ninguna carga");
  display.println("Por favor");
  display.println("espere...");
  display.display();
  delay(2000);  // to allow time for stabilizing offset
  for(int i = 0; i < 1000; i++) {
  offset1 = offset1 + (.0264 * analogRead(A3) -13.51);
  delay(2);
  }
 
  digitalWrite(2, LOW);
  ofst = 1;
  return offset1;
}
void loop()
{
  if (ofst == 0) 
    {
    offset1 = offset1Adj();
    }
 
  float average1 = 0;
  for(int i = 0; i < 1000; i++) {
  average1 = average1 + (.0264 * analogRead(A3) -13.51);
  delay(1);
  }
 
  RawVCC = analogRead(A0);
  auxVCC = map(RawVCC, 0, 1023, 0, 3000);
  VCC = (auxVCC / 100.0);
 
  ICC = (average1 - offset1) ; // offset adjust
 
  // text display tests
  display.clearDisplay();
  display.setTextSize(1);
  display.setCursor(0,0);
  display.print("VCC=");
  display.print(VCC,1);
  display.println("V");
  display.print("ICC=");
  display.print(ICC,0);
  display.println("mA");
  display.print("offset=");
  display.println(offset1,0);
  display.println("");
  display.print("Volt-Amp Meter");
  display.println("sites@angmuz");
  display.display();
  delay(100); 
 
}

Este seria por tanto el esquema final del montaje:

Links

Adafruit: Nokia 5110 Monochrome LCD

Deja una respuesta