Como instalar um display LCD em seu servidor Linux

Este artigo traz um breve resumo de como instalar um display LCD de 4x20 caracteres em seu sistema operacional Linux. Este display é muito útil para visualizar o estado de um terminado serviço e/ou hardware sem a necessidade de ter um monitor ligado à CPU. Podemos também usá-lo para o desenvolvimento de produtos embarcados usando o Linux.

[ Hits: 55.376 ]

Por: Alessandro de Oliveira Faria (A.K.A. CABELO) em 07/12/2003 | Blog: http://assuntonerd.com.br


Instalação do software



O software foi escrito em C++, muito simples de se entender. Precisaremos de apenas 3 arquivos, 2 para compilação e o outro é um arquivo texto lcd.conf, que deverá ser copiado na pasta /etc. Os arquivos poder ser baixados nos seguinte links:

# mkdir lcd
# cd lcd
# wget http://cabelo.neti.vila.bol.com.br/lcd.cc
# wget http://cabelo.neti.vila.bol.com.br/lcd.h
# wget http://cabelo.neti.vila.bol.com.br/lcd.conf

# wget http://cabelo.neti.vila.bol.com.br/conio.h

O arquivo lcd.h possui apenas constantes do comandos do lcd, agora o lcd.conf é o arquivo que contem o endereço em hexadecimal que indica onde sua paralela está instalada. Por padrão o endereço é 0x0278 e 0x027A.

O conteúdo do arquivo lcd.conf deve ser algo assim:

0x378 0x37A

Segue abaixo o fonte do lcd.cc:

// LCD.cpp : Defines the entry point for the console application.

#include <iostream>
#include <fstream>
#include <string>
#include <conio.h>
#include <unistd.h>
#include <sys/io.h>
#include "lcd.h"

using namespace std;


// Classe de Objeto LCD
class LCD
{
   public:
      unsigned long mPorta1;
      unsigned long mPorta2;
      void Mostra_LCD(char RET );
      void WritePort(unsigned long portid, unsigned long value);
      void INICIALIZA(void);
      void CURSOR( bool T );
      void POSICAO(int L, int C , string Texto);
      void CLS(void);
};


// Método abaixo usa função outb para escrever no endereço da paralela
void LCD::WritePort(unsigned long portid, unsigned long value)
{
   outb(value,portid);
}


// Método de inicialização do Display
// As seqüencias de instruções foi extraída na documentação do hardware

void LCD::INICIALIZA(void)
{
   // Function set
   WritePort(mPorta2, INSTRUCAO );
   WritePort(mPorta1, FUNCTION_SET );
   WritePort(mPorta2, FIM_INSTRUCAO);
   usleep(2);

   // Display on/off control
   WritePort(mPorta2, INSTRUCAO );
   WritePort(mPorta1, DISPLAY_CONTROL);
   WritePort(mPorta2, FIM_INSTRUCAO );
   usleep(1);

   // Clear Display
   WritePort(mPorta2, INSTRUCAO );
   WritePort(mPorta1, CLEAR_DISPLAY);
   WritePort(mPorta2, FIM_INSTRUCAO);
   usleep(1);
    
   // Return Home
   WritePort(mPorta2, INSTRUCAO );
   WritePort(mPorta1, RETURN_HOME );
   WritePort(mPorta2, FIM_INSTRUCAO);
   usleep(1);
    
   // Entry Mode set
   WritePort(mPorta2, INSTRUCAO );
   WritePort(mPorta1, ENTRY_MODE );
   WritePort(mPorta2, FIM_INSTRUCAO);
   usleep(1);
}


// Método para desligar e ligar o Cursor
void LCD::CURSOR( bool T )
{
   WritePort(mPorta2, INSTRUCAO);
   if(T) WritePort(mPorta1, 14);
   else WritePort(mPorta1, 12);
   WritePort(mPorta2, FIM_INSTRUCAO);
   usleep(1);
}

// Método que envia os dados para o Display
void LCD::Mostra_LCD(char RET )
{
   WritePort(mPorta2, DADO);
   switch (RET) {
      case '|' : WritePort(mPorta1, 255); break;
      case '~' : WritePort(mPorta1, 223); break;
      default : WritePort(mPorta1, RET);
   }

   WritePort(mPorta2, FIM_INSTRUCAO);
   usleep(1);
}


// Método que posiciona o cursor na coordenada especificada
void LCD::POSICAO(int L, int C , string Texto)
{
   int x,i;

   x = 0;
   switch (L) {
      case 1 : x = 00; break;
      case 2 : x = 64; break;
      case 3 : x = 20; break;
      case 4 : x = 84; break;
   }
    
   x = 128 + ((x + C)-1);
   WritePort(mPorta2, INSTRUCAO );
   WritePort(mPorta1, x );
   WritePort(mPorta2, FIM_INSTRUCAO);
   usleep(1);
   for (i = 0;i <= Texto.length()-1 ; i++)
      Mostra_LCD(Texto[i]);
   gotoxy(C,L);std::cout<<Texto<<std::endl;
}


// Método para limpar o LCD
void LCD::CLS(void)
{
   WritePort(mPorta2, INSTRUCAO );
   WritePort(mPorta1, I_CLEAR );
   WritePort(mPorta2, FIM_INSTRUCAO);
   clrscr();
   sleep(1);
}


int main( int argc, char** argv)
{
   string mComando;
   unsigned long mParametro;
    
   LCD VISOR01;
    
   // Lê o arquivo de configuração
   fstream input_file("/etc/lcd.conf", ios::in);
   input_file>>hex>>mParametro;
   VISOR01.mPorta1 = mParametro;
   input_file>>hex>>mParametro;
   VISOR01.mPorta2 = mParametro;
   input_file.close();
  
   // Libera a permissão de acesso físico ao endereços da porta paralela
   ioperm(VISOR01.mPorta1, 1, 1);
   ioperm(VISOR01.mPorta2, 1, 1);

   // Executa o comando cls dependendo do parâmetro recebido
   mComando=argv[1];
   if(mComando == "cls")
   {
      VISOR01.INICIALIZA();
      VISOR01.CURSOR( false );
      VISOR01.CLS();
   }


   // Executa o comando display dependendo do parâmetro recebido
   if((mComando == "display"))
   {
      mComando = argv[4];
      VISOR01.POSICAO(atoi(argv[2]),atoi(argv[3]),mComando);
   }
   return 0;
}

Para compilar o programa devemos ter instalado o compilador GNU C++ e executar os seguintes comandos:

# g++ lcd.cc -o lcd
# cp lcd.conf /etc
# cp lcd /bin


Pronto, agora podemos escrever scripts para mostrar informação do sistema no display lcd:

# vi teste_lcd

lcd cls
lcd display 1 1 "www.br-linux.org"
lcd display 2 1 "www.vivaolinux.com.br"
lcd display 3 1 "www.revistadolinux.com"
lcd display 4 1 "LOGADO SYS=$USERNAME"

# chmod 770 teste_lcd
# ./teste


Pronto, agora é a sua imaginação que vai determinar onde aplicar este recurso.

Este programa tem muito para evoluir, vou cadastrá-lo no codigolivre.org.br para melhorá-lo como um todo (gerar um rpm, documentação, man e help).

Qualquer dúvida entre em contato. [email protected] ou [email protected]


SOU LIVRE, USO LINUX!!!!

Página anterior    

Páginas do artigo
   1. Hardware
   2. Instalação do software
Outros artigos deste autor

Xtraceroute: O traceroute tridimensional

ARCore: SDK para realidade aumentada da Google

Blu-ray: Reproduzindo, copiando, ripando e assistindo no GNU/Linux

OwnCloud : Crie a sua própria nuvem - Alternativa ao Dropbox

Como fazer um viciante e cativante servidor de Quake2 CTF

Leitura recomendada

Placa de vídeo Nvidia no Ubuntu Hardy

Configurando placa 3D nVidia 6200 com TV-out no Kurumin 7

Como testar distribuições GNU/Linux sem instalar

Como gravar o som da sua Zoom G2.1u

Configure seu modem SmartAx MT810 no Ubuntu

  
Comentários
[1] Comentário enviado por fabio em 07/12/2003 - 15:50h

Cabelo, show de bola o artigo, me amarrei neste recurso. Você sabe informar qual é o custo aproximado da confecção de um LCD similar ao seu? Ou até mesmo quanto custa um pronto?

[2] Comentário enviado por jeffestanislau em 07/12/2003 - 19:46h

Muito maneiro cabelo, muito interessante mesmo!!!
O seu uso atual destes LCD está sendo para que fins? (espécie de trabalhos).
Ah... parabéns pelo artigo, como sempre inovando!!!


[3] Comentário enviado por wilbil em 08/12/2003 - 02:17h

no escricorio tem mas de 20X2
pelo que li ai nos htmls no inicio do artigo nao parece nada complicado e sim somente questao de solda

este artigo e bem inovador e legal nunca fiquei tao curioso em fazer algo

[4] Comentário enviado por cabelo em 08/12/2003 - 08:50h

Fala Galera:

Com relação ao custo e onde encontrar, entre em contato com o Junior([email protected]) aqui na empresa (pode usar o meu nome para contato). Pois ele está adquirindo 3 unidades, e ele pois passar todos os parametros ref. a custo.

Agora sobre dúvidas técnicas entre em contato como o Indio ([email protected]). O cara é ninja pois foi ele que soldou os cabos para a minha máquina.

Até mais.

[5] Comentário enviado por repolho em 09/12/2003 - 08:53h

no site www.casemodbr.com tem uns lcds prontos para vender quem quiser de uma olhada... outra coisa
SHOW DE BOLA Cabelo, pelo seu programa, e o que eh muito legal mesmo ele ser bem simples e vc estar abrindo ele para comunidade software livre desenvolver com vc :DD

como vou instalar um lcd aki em casa, nas ferias estarei dando uma olhada no seu codigo e quem sabe dar um implementada ;)

Grato
REPOLHO
www.repolho.org

[6] Comentário enviado por juca_tigre em 10/12/2003 - 13:59h

Não existe o #include <conio.h> no Linux. Como você compilou o código?

[7] Comentário enviado por cabelo em 10/12/2003 - 21:23h

Galera o Indio ([email protected]) montou o cabo no padráo do site CASEMODBR ( http://www.casemodbr.com/tutoriais/index.php )

Por questäo de compartibilidade com outros softwares.

E o tutorial está muito bem explicado. Não compensa refazer um novo tutorial.

Graças a ele (pois eu sou leigo em eletrônica) foi possível adptar este tutorial com facilidade para o padrão da CASEMODBR.

Basta substituir as seguintes linhas no arquivo lcd.h:

-------------| ANTIGA LINHAS |---------------------
//#define INSTRUCAO 7 // $37A - 0111
//#define FIM_INSTRUCAO 12 // $37A - 1100
//#define DADO 6 // $37A - 0110

-------------| NOVAS LINHAS |---------------------

#define INSTRUCAO 0 // $37A - 0111
#define FIM_INSTRUCAO 5 // $37A - 1100
#define DADO 4 // $37A - 0110

----------------------------------------------------
Pronto!! basta recompilar o software.

PS: Fabio e comunidade mande um e-mail agradecendo o Alexandre, pois o numero de e-mails que recebi referente a duvidas sobre o cabo foi impressionante.

Até mais!!!






CD ..





[8] Comentário enviado por skun em 17/12/2003 - 11:32h

juca_tigre, basta vc trocar o <conio.h> dentro do arquivo lcd.cc para "conio.h"

**************** .''`.
* Sandro Cória * : :' :
* GNU/Linux Debian * `. `'`
**************** `-

[9] Comentário enviado por dcarva em 18/12/2003 - 12:59h

Eu fiz a compilação mas não funcionou. Por exemplo, quando digito lcd cls, ele limpa a tela do meu micro e o lcd nem responde, se digito lcd display 1 1 "teste" ele imprime na tela ao invés de imprimir no lcd.

Alguém tem idéia de como resolver isso.

Valeu.

[10] Comentário enviado por fabiogil em 19/12/2003 - 20:57h

dcarva, siga os passos do comentario do "cabelo" que tudo dara certo, pois eu passei por isso tb com o codigo-fonte original.

Abracos,

[]'s Fabio Gil

[11] Comentário enviado por Grillo em 31/05/2004 - 20:52h

Cara!!! sem comentarios... tava querendo isso, me amarro em casamodding!!

[12] Comentário enviado por Sysop_Kristo em 19/09/2004 - 18:47h

Infelizmente qualquer instrução que eu mando imprimir no meu LCD ele só retorna a mensagem:

Segmentation fault

Isso no Slackware 10

[13] Comentário enviado por tr3t4 em 10/12/2004 - 14:38h

Cabelo, seu artigo ficou ótimo, fiz aq eu deu tudo certo, adicionei o comentario do skun e mudei o "conio.h" mas o meu LCD eh de 16X4 e na hora que eu rodo o script ele imprimi caracteres estranhos, vc podeira me ajudar??? valeus

[14] Comentário enviado por oberdan.soares em 21/12/2004 - 17:10h

Eu segui tudo passo a passo, compilei o programa, mas na hora de executar ele limpa a tela e nao da mensagem nenhuma e se eu executo o lcd que esta em /bin/lcd é retornado a seguinte mensagem: SEGMENTATION FAULT

[15] Comentário enviado por _Ne0 em 27/03/2005 - 17:56h

ai o site com os arquivos pra download tah fora do ar cara como faço pra downlodea eles agora =/ fikei sabendo ke os da LCD da telefonica(tem uns malandros ke rancam do orelhao) fikei sabendo ke eles funcionam tb mais nao sei nao ele parece diferente desse ke vendem xD~~

[16] Comentário enviado por pagjunior em 16/04/2005 - 09:19h

Muito bom o artigo, só que quando fui compilar deu o seguinte erro, como não muito bom em programação, não sei o que está dando errado.

[[email protected] lcd]# g++ lcd.cc -o lcd
lcd.cc:4:20: iostream: Arquivo ou diretório não encontrado
lcd.cc:5:19: fstream: Arquivo ou diretório não encontrado
In file included from lcd.cc:7:
conio.h:9:19: stdio.h: Arquivo ou diretório não encontrado
In file included from lcd.cc:7:
conio.h: In function `void textbkground(char*)':
conio.h:33: error: `printf' undeclared (first use this function)
conio.h:33: error: (Each undeclared identifier is reported only once for each
function it appears in.)
conio.h: In function `void textcolor(char*)':
conio.h:38: error: `printf' undeclared (first use this function)
conio.h: In function `void clrscr()':
conio.h:42: error: `printf' undeclared (first use this function)
conio.h: In function `void gotoxy(int, int)':
conio.h:47: error: `printf' undeclared (first use this function)
lcd.cc:8:48: unistd.h: Arquivo ou diretório não encontrado
lcd.cc:9:20: sys/io.h: Arquivo ou diretório não encontrado
lcd.cc: At global scope:
lcd.cc:25: error: type specifier omitted for parameter `string'
lcd.cc:25: error: parse error before `)' token
lcd.cc: In member function `void LCD::WritePort(long unsigned int, long
unsigned int)':
lcd.cc:33: error: `outb' undeclared (first use this function)
lcd.cc: In member function `void LCD::INICIALIZA()':
lcd.cc:43: error: `usleep' undeclared (first use this function)
lcd.cc: In member function `void LCD::CURSOR(bool)':
lcd.cc:77: error: `usleep' undeclared (first use this function)
lcd.cc: In member function `void LCD::Mostra_LCD(char)':
lcd.cc:91: error: `usleep' undeclared (first use this function)
lcd.cc: At global scope:
lcd.cc:96: error: type specifier omitted for parameter `string'
lcd.cc:96: error: parse error before `)' token
lcd.cc: In member function `void LCD::POSICAO(...)':
lcd.cc:101: error: `L' undeclared (first use this function)
lcd.cc:113: error: `C' undeclared (first use this function)
lcd.cc:117: error: `usleep' undeclared (first use this function)
lcd.cc:118: error: `Texto' undeclared (first use this function)
lcd.cc:121: error: `cout' undeclared in namespace `std'
lcd.cc:121: error: `endl' undeclared in namespace `std'
lcd.cc: In member function `void LCD::CLS()':
lcd.cc:132: error: `sleep' undeclared (first use this function)
lcd.cc: In function `int main(int, char**)':
lcd.cc:141: error: `string' undeclared (first use this function)
lcd.cc:141: error: parse error before `;' token
lcd.cc:146: error: `fstream' undeclared (first use this function)
lcd.cc:146: error: parse error before `(' token
lcd.cc:147: error: `input_file' undeclared (first use this function)
lcd.cc:147: error: `hex' undeclared (first use this function)
lcd.cc:155: error: `ioperm' undeclared (first use this function)
lcd.cc:158: error: `mComando' undeclared (first use this function)
lcd.cc:168: error: `atoi' undeclared (first use this function)

[17] Comentário enviado por xevandro em 03/12/2005 - 10:17h

Cabelo pode me ajudar, fiz tudo de acordo com o artigo mas quando executo o arquivo de teste ele imprime na tela.
Se somente executar o arquivo lcd e da a seguinte mensagem:
[[email protected] lcd]# lcd
Falha de segmentação

Estou usando CL10 com kernel 2.6.11

Abraços Evandro Silva

[18] Comentário enviado por gregorye em 26/09/2006 - 11:22h

afeee link quebrado! aonde acho isso ?

[19] Comentário enviado por CABELO em 26/09/2006 - 11:59h

na mão

https://codigolivre.org.br/projects/lcd/

[20] Comentário enviado por glecio em 12/10/2006 - 19:00h

Veja Também: http://www2.fateb.br/marcelo/esquema_pcinfo.html

[21] Comentário enviado por troliveira em 17/04/2008 - 23:32h

Cabelo..sei que este artigo é antigo...mas se puder me ajudar eu agradeço. No meu caso ele fica imprimindo tudo na tela, assim como outros colegas relataram nos comentarios. Eu baixei os arquivos lá do codigolivre, que já estão modificados para o cabo do casemodbr...Será que tem algo que falta configurar???

Agradeço desde já

[22] Comentário enviado por troliveira em 19/04/2008 - 03:00h

Olha só Alessandro... uma coisa que notei: se eu executo o comando lcd display 1 1 "" (string vazia) ele imprime um quadradinho na tela, e o programa entra em loop. Agora se eu executo lcd display 1 1 "aaa" ele imprime na tela......e não no LCD.


Contribuir com comentário