InicioHazlo Tu MismoControlar el puerto paralelo hoy

Controlar el puerto paralelo hoy

Hazlo Tu Mismo4/19/2013


#******************************************************************************
# _B i e n v e n i d o s__a__m i__p o s t_
#******************************************************************************

Puede pasar que quieras hacer un circuito para controlar las luces de la casa, un robot, un juego de luces, etc, normalmente usaba un par de ejecutables que venían con Linux que se llamaban inb y outb, el primero se usaba para leer desde el puerto paralelo (usando pulsadores por ej) y el segundo para escribir señales de salida, con el paso del tiempo dejaron de estar presentes y (como en el caso mío) se complicó todo ya que había escrito un envoltorio en Perl para que haga distintas tareas.
Entonces tuve que escribir un sustituto de los ejecutables mencionados (ya que estaba le daba algo más de funcionalidad) y el código resultante es el siguiente:


/**
lpcontrol-1.120802 - controla el puerto paralelo
Copyright (C) 2012 Abel Sendon - [email protected]

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public Licens./be for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**/


#include <iostream>
#include <fstream>
#include <unistd.h>
#include <sys/io.h>
#include <stdlib.h>
#include <stdio.h>


using namespace std;

class puerto
{
private:
int base1_out; // Pines de salida estandard (2..9)
int base2_out; // Pines de salida secundarios (1, 14, 16, 17)
int base1_in; // Pines de entrada
int read_error; // Error en la lectura inicial
int write_error; // Error en la escritura inicial

public:
puerto();
void o1(int valor);
void o2(int valor);
int i1();
void info();
void test();
};


class utils
{
private:

public:
void ayuda();
void version();
void dly(int valor);
void read_data(char name_file[]);
};


puerto::puerto()
{
// El viejo puerto lp usaba esta base, en caso de usar adaptador
// o una placa separada, habrá que cambiar este valor
////////////////////////////////////////////////////////////////
base1_out = 0x378;
////////////////////////////////////////////////////////////////


base2_out = base1_out + 2;
base1_in = base1_out + 1;

if (ioperm(base1_out, 1, 1))
{
write_error = 1;
}

if (ioperm(base1_in, 1, 1))
{
read_error = 1;
}
}

void puerto::info()
{
cout << "Salidas estandar en " << hex << showbase << uppercase << base1_out << endl;
cout << "Salidas extendidas en " << hex << showbase << uppercase << base2_out << endl;
cout << "Entrada en " << hex << uppercase << showbase << base1_in << endl;

if (write_error == 1)
{
cout << "El puerto no pudo ser escrito en " << hex << showbase << uppercase << base1_out << endl;
}

if (read_error == 1)
{
cout << "El puerto no pudo ser leido en " << hex << showbase << uppercase << base1_in << endl;
}
}

void puerto::o1(int valor)
{
outb(valor, base1_out);
}

void puerto::o2(int valor)
{
outb(valor, base2_out);
}

int puerto::i1()
{
return inb(base1_in);
}

void puerto::test()
{
o1(0);
cout << "n0 ";
usleep(250000);
o1(1);
cout << "1 " ;
usleep(250000);
o1(2);
cout << "2 " ;
usleep(250000);
o1(4);
cout << "4 " ;
usleep(250000);
o1(8);
cout << "8 " ;
usleep(250000);
o1(16);
cout << "16 " ;
usleep(250000);
o1(32);
cout << "32 " ;
usleep(250000);
o1(64);
cout << "64 " ;
usleep(250000);
o1(128);
cout << "128 " ;
usleep(250000);
o1(255);
cout << "255 " ;
usleep(250000);
o1(0);
cout << "0 na" ;
}

void utils::ayuda()
{
cout << "nModo de uso: lpcontrol64 <opción>na" << endl;
cout << "v Muestra la versión y sale" << endl;
cout << "h Muestra esta ayuda y sale" << endl;
cout << "i Detalla información de los recursos utilizados" << endl;
cout << "w <0..255> Escribe en el puerto" << endl;
cout << "r Lee desde el puerto" << endl;
cout << "t Realiza un test de las salidas" << endl;
cout << "f Lee los datos desde un archivo" << endl;
cout << "d <valor> Establece un delay, donde valor es:" << endl;
cout << "t0 = 10ms" << endl;
cout << "t1 = 20ms" << endl;
cout << "t2 = 50ms" << endl;
cout << "t3 = 100ms" << endl;
cout << "t4 = 200ms" << endl;
cout << "t5 = 500ms" << endl;
cout << "t6 = 1s" << endl;
cout << "t7 = 2s" << endl;
cout << "t8 = 5s" << endl;
cout << "t9 = 10s" << endl;
cout << "tUn valor distinto establece una espera de 750ms" << endl;
exit(0);
}

void utils::version()
{
cout << "nlpcontrol64 - controla el puerto paralelo" << endl;
cout << "2012(C) - Abel Sendon <[email protected]>" << endl;
cout << "Este programa es software libre, puede usarlo, modificarlo " << endl;
cout << "o distribuirlo bajo los términos de la GNU versión 2 o posteriorn" << endl;
exit(0);
}

void utils::dly(int valor)
{
// Por algún motivo que desconozco no funciona
// la sentencia switch :-(

if (valor == 0) {
usleep(10000);
}
else if (valor == 1) {
usleep(20000);
}
else if (valor == 2) {
usleep(50000);
}
else if (valor == 3) {
usleep(100000);
}
else if (valor == 4) {
usleep(200000);
}
else if (valor == 5) {
usleep(500000);
}
else if (valor == 6) {
usleep(1000000);
}
else if (valor == 7) {
usleep(2000000);
}
else if (valor == 8) {
usleep(5000000);
}
else if (valor == 9) {
usleep(10000000);
}
else {
usleep(750000);
}
}

void utils::read_data(char name_file[])
{
int to_port = 0;
int delay = 0;
puerto lptmp;
const int SIZE = 16;
char line[SIZE];

ifstream file_input(name_file);
while(file_input.getline(line, SIZE))
{
file_input >> to_port;
file_input >> delay;
cout << "Delay: " << delay << endl;
cout << "To port: " << to_port << endl;
usleep(delay * 1000);
lptmp.o1(to_port);
}
file_input.close();
}


int main(int argc, char **argv)
{
puerto p;
utils u;
int sw;

// Quitar los espacios en la siguiente linea
while( ( sw = getopt(argc, argv, "irhvt : : b : w : W : d : f : " ) ) != -1 )
{
switch(sw)
{
case 'r':
cout << p.i1();
return p.i1();
break;

case 'i':
p.info();

case 'w':
if(optarg)
{
p.o1(atoi(optarg));
}
break;

case 'd':
if(optarg)
{
u.dly(atol(optarg));
}
break;

case 'W':
if (optarg)
{
p.o2(atoi(optarg));
}
break;

case 'h':
u.ayuda();
break;

case 'v':
u.version();
break;

case 't':
p.test();
break;

case 'f':
if (optarg)
{
u.read_data(optarg);
}
break;

default:
u.ayuda();
exit(0);

} // switch
} // while
} // main



El código fuente está escrito en C++, para compilarlo se abre una terminal y se escribe c++ lpcontrol.cpp -o lpcontrol, escribiendo ./lpcontrol -h tendremos la siguiente salida:


Modo de uso: lpcontrol64 <opción>

v           Muestra la versión y sale
h           Muestra esta ayuda y sale
i           Detalla información de los recursos utilizados
w <0..255>  Escribe en el puerto
r           Lee desde el puerto
t           Realiza un test de las salidas
f           Lee los datos desde un archivo
d <valor>   Establece un delay, donde valor es:
    0 = 10ms
    1 = 20ms
    2 = 50ms
    3 = 100ms
    4 = 200ms
    5 = 500ms
    6 = 1s
    7 = 2s
    8 = 5s
    9 = 10s
    Un valor distinto establece una espera de 750ms


Nótese que una función interesante es la de escribir en el puerto desde los datos de un archivo, éste tiene un formato muy simple (usado para un juego de luces):


80
129
80
66
80
36
80
24
80
48
80
96
80
192
80
96
80
48
80
24
80
12
80
6
80
3
80
1
80
0
100
255
80
0
70
255
60
0
50
255
40
0
30
255
20
0
10
255
1


La primer linea define el delay antes de escribir el primer valor (que se encuentra en la linea siguiente) que en este caso es 129, en las siguientes 2 lineas se establecen el siguiente delay y valor respectivamente, y así hasta que la imaginación se agote, por si no se entendió la sintaxis es la siguiente:


delay
valor
delay
valor
delay
valor


No es necesario que el delay sea el mismo (80 ms en éste caso), la parte principal de este post es el programa descripto, pero dejo una pequeña referencia para quienes no sepan como armar una interface entre este puerto y el mundo exterior.


#******************************************************************************



Los datos se escriben en los pines del 2 a 9 y se leen desde los 10,11, 12,13 y 15



Típica interface para utilizar con leds (escritura)



Lectura desde el puerto.



#******************************************************************************


Esto es todo por hoy espero que les sea de utilidad y disfrútenlo


#******************************************************************************
# _Fin__del__post_
#******************************************************************************
Datos archivados del Taringa! original
55puntos
729visitas
0comentarios
Actividad nueva en Posteamelo
0puntos
3visitas
0comentarios
Dar puntos:

Dejá tu comentario

0/2000

Autor del Post

a
Usuario
Puntos0
Posts203
Ver perfil →
PosteameloArchivo Histórico de Taringa! (2004-2017). Preservando la inteligencia colectiva de la internet hispanohablante.

CONTACTO

18 de Septiembre 455, Casilla 52

Chillán, Región de Ñuble, Chile

Solo correo postal

© 2026 Posteamelo.com. No afiliado con Taringa! ni sus sucesores.

Contenido preservado con fines históricos y culturales.