Xwork's Blog

The lord is waiting to take your hand.

Bienvenido el 2021

No hay comentarios.

 Hola de nuevo a todos, el dia de hoy solo escribo para desearles a todos un buen año 2021, es cierto que el 2020 fue un año complicado, pero si nos sirve de consuelo a todos, el 2021 podrá ser peor (o no). Cómo es costumbre, continua visitando el blog de XWork y disfrutemos del tiempo que tenemos porque en un instante se puede acabar.


Saludos y nos seguimos leyendo.

No hay comentarios. :

Publicar un comentario

Vamos a programar #92 - El triangulo de Pascal (ver. C)

No hay comentarios.

 Hola de nuevo a todos, el día de hoy vamos a ver cómo hacer un programa en C que calcule el triangulo de Pascal.


Cómo podrás recordar, hace unos día publiqué una version en Python; y tal cómo lo prometí justo antes de acabar el 2020, les traigo la versión en C. Cómo la explicación de que es el triangulo de Pascal se incluye en ese post (además de cómo hacer los cálculos a mano), simplemente pasaremos al código fuente. Al igual que el código en Python, vamos a calcular el triangulo de Pascal de manera recursiva y si surgen dudas las resolveremos en los próximos post

El código en C que sirve para calcular el triangulo de Pascal es el siguiente ():


// Prueba del triangulo de pascal en C

#include <stdio.h>
#include <stdlib.h>

int *CalculateLevel(int Level)
{
    int *Result;
    Result  = (int *)malloc(Level * sizeof(int));
        
    if (Level == 0)
         *Result = 1;
    if (Level == 1)
    {
        *Result = 1;
        *(Result + 1) = 1;
    }
    if (Level > 1)
    {
        int *ResultP = CalculateLevel(Level - 1);
        for (int i = 0; i < Level; i++)
        {
            if (i == 0 || i == Level - 1)
                *(Result + i) = 1;
            else
                *(Result + i) = *(ResultP + i) + *(ResultP + i - 1);
        }
    }
    return(Result);
    
}

void DrawPascalTriangle(int Number)
{

    if (Number > 20)
    {
        printf("Solo se admiten 20 niveles");
    }
    else
    {
        for (int i = 0; i < (Number + 1); i++)
        {
            int *Result = CalculateLevel(i);
            for (int j = 0; j < i; j++)
            {
                printf( " %5d ", *(Result + j));
            }
        printf("\n");
        }

    }
}


int main()
{
    int Levels;
    printf("Numero de niveles\n");
    scanf("%d", &Levels);
    DrawPascalTriangle(Levels);

    return 0;
}



Y bien, cómo podrás notar, resulta un poco sencillo portar programas de un lenguaje a otro, si tienes dudas de cómo funciona el programa puedes escribir aquí o en mi twitter. Cómo de costumbre puedes descargar el código fuente de mi Dropbox para que lo pruebes, pero ademas puedes verlo funcionar en linea gracias a los compiladores web.

Los leo luego.

No hay comentarios. :

Publicar un comentario

Vamos a programar #91 - EL triangulo de Pascal (ver. Python)

No hay comentarios.

 Hola de nuevo a todos, el día de hoy vamos a ver cómo hacer el triangulo de pascal usando Python.




Hace unos días mientras leía los comentarios, alguien sugirió que hiciera un programa que calculara el triangulo de pascal y ya que ando un poco corto de ideas, decidí hacerlo. Pero antes de continuar, veamos que es el triangulo de pascal.

En las matemáticas, el triángulo de Pascal es una representación de los coeficientes binomiales ordenados en forma de triángulo. Es llamado así en honor al filósofo y matemático francés Blaise Pascal, quien introdujo esta notación en 1654, en su Traité du triangle arithmétique.1​ Si bien las propiedades y aplicaciones del triángulo fueron conocidas con anterioridad al tratado de Pascal por matemáticos indios, chinos, persas, alemanes e italianos, fue Pascal quien desarrolló muchas de sus aplicaciones y el primero en organizar la información de manera conjunta.2​


El triángulo de Pascal se puede generalizar a dimensiones mayores. La versión de tres dimensiones se llama pirámide de Pascal o tetraedro de Pascal, mientras que las versiones más generales son llamadas simplex de Pascal.

Wikipedia/Triangulo De Pascal

 La composición del triangulo de pascal es realmente simple, en la cima del triangulo, siempre ubicaremos un uno, de hecho en todas las orillas pondremos un uno de modo que en cada nivel haya tantos número cómo el nivel en el que estamos. Para el nivel dos, ya que solo hay extremos en ambos se pondrá un uno.

Para calcular los números del tercer nivel, imaginemos que tenemos tres lugares, los extremos deben de llevar el número uno, por lo que solo nos hace falta determinar el que esta en el lugar dos. Para hacerlo de manera "sencilla" debemos de revisar el nivel anterior y debemos de sumar el numero que esta en la misma posición que el numero que queremos saber (DEL NIVEL ANTERIOR), y sumarlo con el que inmediatamente antes. Para darnos una idea, miremos la siguiente imagen.


Si revisamos bien, nos ubicamos en el nivel tres, pero el numero que queremos saber es el que esta en el segundo lugar del tercer nivel (marcado con una X), entonces tenemos que tomar el numero del nivel anterior que esta en las misma posición que nuestro numero, en la imagen podemos apreciar que el número que esta en la segunda posición del nivel dos es uno y el numero que esta antes en el nivel dos, también es uno, por lo que tendríamos que el segundo numero del tercer nivel es igual a uno mas uno, por lo tanto su valor es dos.


Ahora a manera de ejemplo calculemos el valor de los números en el nivel 4, para eso imaginemos que tenemos algo cómo la imagen que sigue.


Solo tendríamos que determinar X y Y. Para X ya que está en la posición dos del cuarto nivel, tomaríamos los números en la posición dos y uno del tercer nivel y tendríamos cómo resultado 3




Para calcular el numero Y, simplemente hacemos lo mismo. Tomamos el tercer y segundo número del nivel tres y simplemente lo sumamos obteniendo otro tres.


Así podemos calcular cualquier nivel.


Entonces en python podemos crear código cómo el que sigue:


# Prueba del triangulo de pascal en python
def CalculateLevel(Level):
    Result = {}
    if Level == 1:
        Result[0] = 1
    if Level == 2:
        Result[0] = 1
        Result[1] = 1
    if Level > 2:
        ResultP = CalculateLevel(Level - 1)
        for i in range(Level):
            if (i == 0) or (i == Level - 1):
                Result[i] = 1
            else:
                Result[i] = ResultP[i - 1] + ResultP[i]
    return Result
 
def DrawPascalTriangle(Number):
    if Number > 20:
        print("Solo se admiten 20 Niveles")
    else:
        for i in range(Number + 1):
            Result = CalculateLevel(i)
            for j in range(len(Result)):
                print(Result[j], end = '  ')
            print()
    


if __name__ == "__main__":
    import sys
    DrawPascalTriangle(int(sys.argv[1]));


El código consta de dos funciones, la primera de ellas es "CalculateLevel(Level)" y cómo su nombre lo sugiere, calcula los valores para el nivel actual, recibe un parámetro numérico que indica cual es el nivel que queremos calcular. En el algoritmo anterior, vimos que cuando el triangulo consta de un nivel, el valor es uno por lo que creamos una condición y si el nivel solicitado es uno, en un arreglo agregamos un valor de uno. Si la variable "Level" es dos, hacemos lo mismo, solo que agregamos otro valor de uno. Para cuando el valor es mayor que dos, lo primero que hacemos es llamar de forma recursiva a "CalculateLevel" pero usando cómo parámetro el valor de "Level" menos uno así obtenemos el nivel anterior, después hacemos un iterador para recorrer todos las posiciones del nivel y dentro de el primero hacemos una comparación y si el valor del iterador corresponde al primer o al ultimo elemento le asignamos el valor de uno, en caso contrario hacemos los calculo usando el valor del iterador para asignar el valor a la posición actual usando los valores del nivel anterior (cómo explicamos antes). Finalmente devolvemos el valor de la variable "Result" que es donde almacenamos los valores

Después creamos la función "DrawPascalTriangle(Number)" que sirve para "dibujar" el triangulo, ya que la consola suele ser pequeña, si el parámetro "Number" es mayor a 20 escribimos un mensaje diciendo que solo se admiten 20 niveles en caso contrario, hacemos dos iteradores, uno que va a recorrer de uno hasta el nivel dado y a su vez calculará cada nivel y el otro que imprimirá en pantalla todos los valores en cada nivel.

Cómo podrás ver el código es realmente sencillo, para usarlo, simplemente debes de ejecutarlo desde la consola pasando cómo parámetro el valor del nivel hasta el cual quieres calcular
pascaltri.py 20
Y bien por ahora es todo, cómo de costumbre puedes descargar el código de mi dropbox para que lo pruebes antes de que acabe el año voy a publicar las versiones en pascal, en c y probablemente en C# o Javascript.

Los leo luego.

No hay comentarios. :

Publicar un comentario

Vamos a programar #90 - La sucesión de Fibonacci y la función de Ackerman (ver. Python)

No hay comentarios.

 Hola de nuevo a toos, el dia de hoy vamos a ver un poco de Python. En días anteriores, mientras revisaba algunos comentarios en twitter, aalgunas personas me preguntaron sobre el estado del blog, pese al que el estado actual ha empeorado un poco debido a cierto bicho, el hecho fue que un par de "accidentes" me impidieron crear nuevos post. Pero dejando eso de lado, mucha gente pidio que si les podia ayudar con python (si hacemos memoria, casi no hay programas hechos en éste lenguaje), y la razon principal es debido a que simplemente lo olvide (conste que ya lo habia mencionado en algun post). Para probar que aun estoy al pendiente, decidi hacer un par de programas con (segun google) las busquedas mas gfrecuentes relacionadas a python que conducian a mi blog.



Los números de Fibonacci.

La version en C del los número de fibonacci la puedes encontrar en el siguiente post. Además incluye una pequeña anotación sobre que es. Ambas versiones son similares y sirven para hacer énfasis en cómo es posivble traducir de un lenguaje a otro cuando se trata de programas simples.
El programa en pyton que calcula la sucesión de Fibonacci es el siguiente.

def CalcFibonacci(Number):
    v1 = 0
    v2 = 1
    v3 = 0
    
    while v1 < Number:
        print(v1)
        v3 = v1 + v2
        v1 = v2
        v2 = v3


if __name__ == "__main__":
    import sys
    CalcFibonacci(int(sys.argv[1]))

Cómo podrás observar, el código es realmente sencillo y mucho mas practico que la versión que C ya que no hay que compilarlo cada vez. Para ejecutarlo, solamente deberás de ejecutarlo desde una consola escribiendo el nombre del script seguido del parámetro (que será el número hasta donde queremos llegar)

Fibonacci.py 200

La funcion de Ackerman.

La versión en C de la función de Ackerman la podemos encontrar en el siguiente post. Al igual que la sucesión, incluye una pequeña descripción. El programa en pyton que calcula la función de Ackerman es el siguiente
def AckermanFunction(Number1, Number2):
    if Number1 == 0:
        return Number2 + 1
    else:
        if Number2 == 0:
            return (AckermanFunction(Number1 - 1, 1))
        return (AckermanFunction(Number1 - 1, AckermanFunction(Number1, Number2 - 1)))

if __name__ == "__main__":
    import sys
    try:
        for i in range(4):
            for j in range(5):
                print(AckermanFunction(i, j),end='  ')
            print()
    except RecursionError:
        print("Error: Se alcanzo el maximo de recursion permitido")
Para la implementación en Python use de forma recursiva la función "AckermanFunction"  para demostrar que algunas veces es mas conveniente usar o no otro lenguaje, en este caso python ofrece protección para las llamadas recursivas, si por ejemplo en los ciclos "for" en cada rango usamos 10 y 5 por ejemplo, el programa nos dirá que se alcanzo el máximo de recursión permitida (cosa que en c no ocurre).

Y bien, por ahora es todo, en post siguientes continuaremos con mas de Python, pero al igual que todos los programas aquí hechos, no son con la intención de que la gente que sepa programar aprenda (excepto Pascal). El código fuente para la sucesión de fibonacci la puedes descargar de aqui y el código fuente de la funcion de Ackerman la puedes descargar de acá.

Los leo luego.

No hay comentarios. :

Publicar un comentario

Back to basics #10 - Control de LED's (con transistores) - Camino a Spedometer v. Final

No hay comentarios.

 Hola de nuevo a todos, el día de hoy vamos a ver cómo instalar una mejora a las luces del velocímetro y además, veremos cómo es que los transistores nos pueden ayudar a manejar algunas cosas que no podríamos directamente desde el arduino.

 

Si hacemos memoria la primera vez que construimos el velocímetro, usábamos un par de diodos LED para hacernos visibles a la hora de manejar en la noche, pero los diodos que se usan al ser de 20mA @ 3.1v solo funcionaban en lugares pequeños (llámese calle promedio), pero cuando se trata de recorridos por caminos más amplio, la idea es ser visible desde la mayor distancia posible, por lo que se hace necesario usar un fuente luminosa mas intensa.

Cuando controlamos los diodos LED directamente desde el arduino, disponemos de una cantidad limitada de potencia. Normalmente el arduino UNO es capaz de suministrar un voltaje de 5v en los pines, pero tienen un limite de corriente de solo 40mA, si conectamos algo que requiera más corriente las cosas pueden ponerse feas.

Por los lugares que suelo andar en bicicleta, los diodos antes mencionados cumplen con su trabajo, pero me llegaron algunas peticiones a mi twitter preguntando por la posibilidad de agregar algo mas fuerte. La mayoría quería agregar los módulos que consisten de tres (o seis) diodos LED 5050.


Si conectamos uno de estos módulos al arduino, simplemente nada pasará, ya que requieren un voltaje de 12V (si hago bien memoria cuando es un solo led 5050 de color blanco consume 60mA a 3.2v), para poder agregar uno de estos módulos, primero que nada, necesitaremos agregar un elevador de voltaje y para controlarlas el transistor.

Para este caso voy a usar un transistor TIP31c (que era lo que tenía a la mano) pero el siguiente diagrama aplica a cualquier transistor NPN. Pero primero que nada ¿Que es un transistor?.

El transistor es un dispositivo electrónico semiconductor utilizado para entregar una señal de salida en respuesta a una señal de entrada. Cumple funciones de amplificador, oscilador, conmutador o rectificador. El término «transistor» es la contracción en inglés de transfer resistor («resistor de transferencia»). Actualmente se encuentra prácticamente en todos los aparatos electrónicos de uso diario tales como radios, televisores, reproductores de audio y video, relojes de cuarzo, computadoras, lámparas fluorescentes, tomógrafos, teléfonos celulares, aunque casi siempre dentro de los llamados circuitos integrados.

https://es.wikipedia.org/wiki/Transistor

Tal y cómo lo dice la definición, necesitamos una señal de entrada para obtener una señal de salida, por lo que en este ejemplo el transistor lo usaremos cómo un apagador (se puede usar para más muchas más aplicaciones pero por ahora solo esto). Antes de continuar, quiero resaltar que usaremos un transistor NPN, existen de más tipos (que eventualmente veremos) pero por ahora y cómo el objetivo no es aprender a usarlos, bastará con usar un transitor del mismo tipo y con las caracteristicas que veremos un poco más adelante.

Para el transistor TIP31c los pines son de la siguiente manera:

  1. Base
  2. Colector
  3. Emisor

.Para hacer las conexiones solo deberás de identificar cual corresponde a cada pin del transistor que elijas y todo debería de funcionar.


Y el diagrama correspondiente sería:


SI todo salió bien las luces deberían de encender cuando el PIN de arduino este en "HIGH".


Cabe aclarar que lo mas recomendable para está situación, sería usar una fuente de energía adicional, puesto que el velocímetro es alimentado por una pila, agregar dos elevadores de voltaje podría reducir la durabilidad de esta de forma drástica. En cambio si agregamos otra pila aparte si se agota el velocímetro podría seguir operando con normalidad.

Aunque la idea me agrado, está no es la solución que agregué a mi bicicleta, la solución que yo le puse la veremos en el siguiente post. Por cierto, se que al inicio del año prometí post cada quincena, pero por razones que son difíciles de entender (aun para mi) los post saldrán pero no de forma periódica.

Los leo luego.

No hay comentarios. :

Publicar un comentario

Vamos a programar #89 - Midiendo voltajes con arduino - Camino a Spedometer v. Final

2 comentarios
Hola de nuevo a todos, el día de hoy vamos a ver cómo medir voltajes usando arduino. Todo esto para agregarlo a "Spedometer M" (y de una vez por todas decir que está terminado). Uno de los principales puntos a tratar, es la presentación de la batería, haciendo memoria en el código habían 5 situaciones diferente para mostrar el estado de la batería, pero algo importante que olvide mencionar, es que eran meramente ilustrativas. Uno podría pensar que al haber 5 "iconos" diferentes, cada uno representaría al 20%, pero en este caso no es así.


El primero de los problemas es que no tenemos una lectura precisa del nivel de la batería, anteriormente ya habíamos hecho un post en el cual mostraba cómo es que se hace la lectura de un voltaje, pero ¿podemos ser mas precisos? Para entender cómo podemos ganar precision, primero hay que recordar cómo es que se hacen las lecturas (y recomiendo que leas un post donde hablamos un poco).

Para medir el voltaje, lo que hacemos es ingresarlo por un pin del arduino, internamente, este posee un mecanismo que traslada el voltaje un valor digital. Cuando conectamos 0v a un pin analogo del arduino y hacemos la lectura con "analogread()" está devolverá un valor de 0. EN cambio si conectamos 5v esta devolverá un valor de 1023. ¿Por que ocurre esto? Simple arduino cuenta con convertidor análogo-digital con una resolución de 8 bits por lo que cada valor entre 0 y 1023 sera igual a un valor de 0v a 5v. Para saber que valor le corresponde a cada voltaje, bastará con mirar la siguiente formula:
donde "n" es el valor de la lectura que "analogread()" regresa . Para entender un poco lo que pasa, supongamos que toamos la lectura usando arduino y este nos regreso un valor de 155.
al sustituirlo tenemos:
Y si lo medimos usando un multimetro tenemos:

Que es bastante acertado. Pero ahora lo que nos interesa hacer es ganar mas definición. Cuando arduino "mide" un voltaje en realidad lo que hace es compararlo con otro, por default este es de 5v, pero se puede elegir otro.

Para indicar que queremos usar un voltaje externo de referencia, podemos usar la función "analogReference()" que recibe un parámetro que puede ser cualquiera de los siguientes:


  • DEFAULT (el valor de la alimentación, si se usan 5v, esta sera la referencia, si se usan 3.3v esta lo será).
  • INTERNAL (Usa un voltaje interno de 1.1v pero solo en el modelo uno, en otros modelos es de 2.56v y elgunos no esta disponible).
  • EXTERNAL (Usa el PIN AREF y se puede usar un valor mayor a cero y menor o igual a 5v)

Existen otros parámetros, pero por ahora nos centraremos en estos.

Primero usaremos el parámetro "INTERNAL" y para que pruebes, puedes usar el siguiente código:

int ValIn = 0;
int CurVal = 0;
float CurVolt =0;

void setup()
{
	analogReference(INTERNAL);
	Serial.begin(9600);
}

void loop()
{
	CurVal=analogRead(ValIn);
	Serial.println(CurVal);
	CurVolt=CurVal*1.1; 
	Serial.print("Valor");
	Serial.print(CurVal);
	Serial.print("mV:");
	Serial.println(CurVolt);
	Serial.println("Done");
	delay(2000);
}

Una vez que lo subas a tu arduino, deberás de conectar el voltaje positivo de tu voltaje (una pila por ejemplo) al pin A0 y el voltaje negativo a tierra. Yo al hacer la medición de la misma pila me da un valor de 710 que al reemplazarlo en la formula (actualizando los valores) no da:
Que es un valor mas cercano al que nos dio el multímetro.

Y sabiendo lo anterior ahora podemos hacer que la referencia sea la indicada para el nivel de la batería. Primero modificaremos un poco el código para hacer uso de la referencia externa, para eso prueba copiar el siguiente código:
int ValIn = 0;
int CurVal = 0;
float CurVolt =0;

void setup()
{
	analogReference(EXTERNAL);
	Serial.begin(9600);
}

void loop()
{
	CurVal=analogRead(ValIn);
	Serial.println(CurVal);
	CurVolt=CurVal*1.1; 
	Serial.print("Valor");
	Serial.print(CurVal);
	Serial.print("mV:");
	Serial.println(CurVolt);
	Serial.println("Done");
	delay(2000);
}

Ahora deberás de conectar un voltaje de 4.2v al pin "AREF" del arduino y conectar el lado positivo de la pila al pin "A0" y el negativo a tierra. Es importante tener nuestro voltaje de referencia estable. Si has seguido los post sobre el velocímetro, sabrás que hacemos uso de un boost converter para obtener un voltaje estable de 5v, si no te quieres complicar la vida, simplemente puedes usar un divisor resistivo con una resistencia de 1.2 kohm junto co una de 6.3 kohm (si tienes 5v exactos te dará 4.2v a la salida).

Algo que es importante aclarar para finalizar el post, es que para mostrar el porcentaje de batería no podemos simplemente usar la formula del porcentaje ya que todas las pilas son diferentes y a pesar de que la capacidad de una pila se puede medir de acuerdo al voltaje que esta nos da, depende meramente del fabricante cómo es "la curva de descarga" (que veremos en otro post) cómo dije al inicio, en el caso del velocímetro, los iconos son meramente ilustrativos de "la pila recien se cargo", "Está medio vacía" y "ya hace falta una recarga".

Y bien, por ahora es todo, lo ejemplos de código cómo son sencillos puedes simplemente copiarlos y pegarlos para probarlos y hago énfasis en que al pin "AREF" del arduino SIEMPRE se le debe aplicar un voltaje mayor a cero y menor o igual a 5.

Los leo luego.

2 comentarios :

Publicar un comentario

Vamos a programar #88 - KeyRemap M (beta)

No hay comentarios.
Hola de nuevo a todos, el día de hoy vamos a ver cómo es que funciona un programa al que decidí llamar "KeyRemap M" (en su versión beta).


Cómo el programa aun está en modo beta, solo voy a explicar un poco su funcionamiento y ya que mucho del código va a cambiar, en cuanto libere la versión 1 explicare cada una de las partes del código (y también liberare el código fuente).

Para empezar, debes de descargar el programa (cómo es costumbre de mi dropbox). Y la forma de usarlo es realmente simple. Para empezar debemos de hacer clic en la caja de texto que dice "tecla a re-programar", cuando presionemos una tecla, aparecerá un número y lo debemos de dejar tal y cómo está (si presionas otra tecla, aparecerá un código diferente). Para la tecla de destino, podemos hacer dos cosas, la primera: revisar esta tabla que contiene algunos códigos o en el mismo programa vienen algunos.



Si queremos averiguar cual es el código de una de las teclas por ejemplo la tecla "e", puedes presionar la tecla cuando el la caja de texto "tecla a re-programar" está seleccionada y el código que resulte lo copias y lo pegas en la caja siguiente una vez hecho, vuelves a la caja de texto "tecla a re-programar"y presionas la tecla que quieres re-programar. Cuando hayas configurado las teclas que quires reasignar, debes de hacer clic en el botón que dice "Agregar" y con eso la combinación de teclas se agregará a la lista.


Cuando hayas agregado todas las combinaciones de teclas, en el menú "archivo" deberás de hacer clic en "Exportar REG" y se abrirá un cuadro de dialogo para guardar el archivo. Guarda el archivo y dale doble clic


Con eso se agregará la información al registro; solo para ver si se agrego de forma correcta, presiona la tecla de windows  + r y en el cuadro "ejecutar" escribe "Regedit"

y busca la ruta "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]"

Tras reiniciar la computadora, la teclas debería de hacer su nueva función. Pero antes, he de aclarar que algunos códigos no funcionaran dependido de la configuración de algunos programas, por ejemplo; muchos juegos ignoran la configuración de windows y manejan por si mismos las pulsaciones. En otros casos, algunas teclas especiales no se pueden re-configurar y el ejemplo mas claro de ello es la tecla "Pausa-Inter" esta no es posible re asignarla usando este método (aunque muchos teclados ya ni la tienen).

Si todo salio bien, para re-establecer las teclas a su función normal, bastara con eliminar la clave "scancode map" del registro y reiniciar la computadora.


Y bien por ahora es todo. Cómo podrás ver, la aplicación aun no es fácil de usar, pero por eso es una versión beta, en el siguiente post trataremos de hacerla mas amigable con el usuario para que cualquiera sea capaz de usarla sin problema.

Los leo luego

No hay comentarios. :

Publicar un comentario

Vamos a programar #87 - Camino a KeyRemap, MessageTextBox .

No hay comentarios.
Hola de nuevo a todos, el día de hoy vamos a empezar un programa que nos sirva para re- configurar las teclas de nuestro teclado.


En el post anterior vimos que es posible re-asignar algunas teclas, todo bien si conocemos cual es el código de la tecla que queremos cambiar (tanto la actual cómo la objetivo) pero actualmente existen teclados que tienen tantas teclas que no están dentro del estandar, que resulta difícil determinar el código buscando en Internet.

En este post veremos cómo es posible determinar el código de cada tecla usando un programa que escribiremos en C# (Si no te interesa, en el siguiente post veremos la versión final de este programa lista para usarse).

Para empezar, primero hay que saber cómo es que se "crean" las pulsaciones. En C# (y probablemente en windows) cuando presionamos una tecla, ocurren los siguientes tres:
  1. KeyDown
  2. KeyPress
  3. KeyUp
KeyDown es el momento en que presionamos la tecla, KeyPress ocurre el tiempo que mantenemos la tecla (usualmente una fracción de segundo pero cuenta aun) y KeyUp que es cuando soltamos la tecla. Windows envía un mensaje diciendo: "Se presiono la tecla con el código XXXX, ahora se mantiene la tecla con el código XXXX y se acaba de soltar la tecla con el código XXXX", cómo son mensajes del sistema operativo, es posible leerlos desde C#, para eso disponemos de dos formas. La primera de ellas es usando lo eventos "_KeyDown", "_KeyPress" y "_KeyUp", muchos de los controles que se pueden añadir a c# disponen de ellos, pero es mas común usarlos en controles "TextBox". Cuando se crea el procedimiento que maneja el evento, se usan dos parámetros, el primero del tipo "object" llamado "sender" y el segundo del tipo "KeyEventArgs" llamado "e"; en este, hay varios procedimientos que nos podrían ser de utilidad, uno de ellos llamado "KeyCode".

Supongamos que tenemos un control "ComboBox" llamado "MsCboKeyOut" al crear el manejador para el evento tendríamos algo cómo lo que sigue:
		private void MsCboKeyOut_KeyDown(object sender, KeyEventArgs e)
		{
			MessageBox.Show(e.KeyCode.ToString());
			e.SuppressKeyPress = true;
		}


Si accedemos al procedimiento "KeyCode" y presionamos la tecla de silencio (mute), esta nos devolverá un valor de 173. Si hacemos memoria, en el post anterior vimos que el código de esa tecla era E020 hexadecimal o 57376 decimal que dista mucho de lo que nos entrego. Incluso haciendo pruebas con varias teclas, el valor maximo que obtuve fue 255 decimal (FF hexadecimal) por lo que si queremos usar este procedimiento para saber el código de las teclas "no normales" simplemente no nos sera posible.

La manera correcta de  de saber el valor real de la tecla, es leyendo directamente el mensaje  lo lleva. En C#, podemos sobrecargar el procedimiento "WndProc" que básicamente sirve para leer los mensajes. Pero cómo queremos ser capaces de utilizar el valor cuando el formulario tiene el foco (que es lo mas común), crearemos un control sencillo con la sobrecarga para que asi podamos utilizarlo.


using System;
using System.Windows.Forms;

namespace KeyRemap
{
	class MessageTextBox : TextBox
	{
		public const int WM_KEYDOWN = 0x0100;
		private uint TheValue = 0;

		public string GetHexValue
		{
			get
			{
				return Convert.ToString(TheValue, toBase: 16);
			}
		}
		public uint ShowKeyCode(uint TheNumber)
		{
			uint KeyValue = TheNumber;
			uint KeyCode = ((KeyValue >> 16) % 256);
			uint IsExtendedKey = ((KeyValue >> 24) % 2);
			if (IsExtendedKey == 1)
			{
				KeyCode = FrmMain.EXTENDED_KEY_VALUE | KeyCode;
				return KeyCode;
			}
			else
				return KeyCode;
		}

		[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
		protected override void WndProc(ref Message m)
		{
			switch (m.Msg)
			{
				case WM_KEYDOWN:
					base.Text = "";
					base.Text = Convert.ToString(ShowKeyCode((uint)m.LParam));
					TheValue = (uint)m.LParam;
					break;
			}
			base.WndProc(ref m);
		}
	}
}



Con este control será mas sencillo interceptar el mensaje que contiene el código de la tecla. Para usarlo, simplemente agrega una nueva clase a tu proyecto y  el evento "_KeyDown" del parámetro "e" , la propiedad "SuppressKeyPress" se debe de establecer el valor de "true" para que el texto que se escriba en el cuadro de texto, corresponda solamente al código de la tecla, si no se suprime la pulsación, si por ejemplo presionamos la tecla "u", en la caja de texto diría "uxx" (donde xx es el código de la tecla u).

Por ahora solo veremos esto y cómo aun falta implementar mucho código, la explicacion detallada vendrá en el siguiente post (junto con la versión ultra beta de "KeyRemap M"), por ahora si sabes programar en C# puede probar el control (y si algo anda mal me pueden avisar).

Los leo luego.

No hay comentarios. :

Publicar un comentario

Vamos a programar #86 - Reasignando teclas del teclado.

No hay comentarios.
Hola de nuevo a todos, el día de hoy vamos a ver cómo reasignar algunas botones de nuestro teclado para que hagan otra cosa.

Hace unos días en la eterna lucha del hombre contra la máquina, mi teclado simplemente decidió que 15 años de uso eran suficientes y simplemente ya no quiso funcionar. Mi teclado compaq 5185 fue el primero que tuve y lo use de forma bastante extenuante.
Algo paso que simplemente ya no quiso reconocer las pulsaciones. Cómo siempre que "reparo" algo hay una enorme tendencia a que me "sobren" piezas, simplemente decidí guardarlo. Para su reemplazo, saque un teclado que un amigo me regaló hace mucho (cómo el de la primer imagen), es más compacto y mas viejo que el mio pero totalmente funcional salvo por unos cuantos botones.

Mi primer teclado tenía la ventaja que tenia varios botones adicionales; los mas importantes (para mi) eran: volumen arriba, volumen abajo, silencio y calculadora. El reemplazo también tiene unos botones extra (seis para ser exacto), pero al conectarlo y presionarlos, ninguna hizo nada. Busqué los controladores pero no encontré ninguno para mi sistema operativo. Las teclas "normales" funcionan cómo deben, pero las "especiales" no.

Para solucionar mi problema busque en internet y encontré que todas las pulsaciones del teclado son gestionadas por el sistema operativo, es decir, si presionamos una tecla, está genera un código pero nuestro amigo Windows es el responsable de que pasa después y no solo eso, posee la capacidad de reasignar las pulsaciones.

Tomando en cuenta lo anterior, vamos a buscar una forma de re-asignar una tecla, pero hay una advertencia, vamos a modificar el registro de Windows (el registro prácticamente es un lugar donde se guardan las configuraciones de una computadora con ese sistema operativo), si sigues los pasos que voy a mostrar no habrá ningún problema, pero si mueves más "cosillas" puedes hacer que el PC no inicie correctamente.

Antes que nada veamos unos cuantos códigos para algunas teclas.

   
US   key assignment   
   
Base   Make   
   
Insert   
   
E0   52   
   
Delete   
   
E0   53   
   
Left   Arrow   
   
E0   4B   
   
Home   
   
E0   47   
   
End   
   
E0   4F   
   
Up   Arrow   
   
E0   48   
   
Dn   Arrow   
   
E0   50   
   
Page   Up   
   
E0   49   
   
Page   Down   
   
E0   51   
   
Right   Arrow   
   
E0   4D   

Para nuestra demostración vamos a usar la tecla "Page Up" y la vamos a reasignar para silenciar el volumen del sistema. La siguiente tabla muestra  algunos de los códigos de teclas multimedia.

CODEALIAS
E0 6AVK_BROWSER_BACK
E0 69VK_BROWSER_FORWARD
E0 67VK_BROWSER_REFRESH
E0 68VK_BROWSER_STOP
E0 65VK_BROWSER_SEARCH
E0 66VK_BROWSER_FAVORITES
E0 32VK_BROWSER_HOME
E0 20VK_VOLUME_MUTE
E0 2EVK_VOLUME_DOWN
E0 30VK_VOLUME_UP
E0 19VK_MEDIA_NEXT_TRACK
E0 10VK_MEDIA_PREV_TRACK
E0 24VK_MEDIA_STOP
E0 22VK_MEDIA_PLAY_PAUSE
E0 6CVK_LAUNCH_MAIL
E0 6DVK_LAUNCH_MEDIA_SELECT
E0 6BVK_LAUNCH_APP1
E0 21VK_LAUNCH_APP2

El código de la tecla que queremos usar es "E0 20" y el código de la tecla "Page UP" es "E0 49" pero ¿y después? Cómo ya mencione antes, Windows es el encargado de gestionar las pulsaciones y guarda esta configuración en el registro. Para acceder a ella, necesitamos encontrar la siguiente clave:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]

Ahí crearemos un nuevo valor binario.


La estructura que debe de tener el valor es de la siguiente forma:

  • 00,00,00,00 > encabezado
  • 00,00,00,00 > flags
  • 02,00,00,00 > número de entradas más uno
  • xx,xx,xx,xx > el código de las teclas a reasignar empezando por el código que queremos que se aplique seguido por el código de la tecla
  • 00,00,00,00 > terminación.
Entonces si sustituimos los valores de nuestras teclas, tenemos algo cómo de la imagen:


Hay que notar que cada código tiene los valores "invertidos", es decir, la tecla de silencio tiene el código "E0 20" pero al momento de escribir el valor en el registro, lo ponemos cómo "20 E0" y lo mismo va para todas las teclas, la tecla "Page Up" tiene el codigo "E0 49" pero lo escribimos cómo "49 E0". Al reiniciar la computadora y presionamos la tecla "Page Up", el sistema se debería de silenciar (en caso contrario algo salio mal). Si quieres hacer el proceso de forma automática, puedes copiar el siguiente texto y guardarlo cómo "key.reg" usando el bloc de notas.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,02,00,00,00,20,E0,49,E0,00,00,00,00

Cada vez que hagas un cambio se debe de reiniciar la computadora.
Finalmente y a manera de ejemplo, supongamos que queremos cambiar las teclas que ya cambiamos, pero ademas queremos que la tecla numérica 7 suba el volumen, tendríamos algo cómo lo que sigue:

  • 00,00,00,00 > encabezado
  • 00,00,00,00 > flags
  • 03,00,00,00 > número de entradas más uno
  • 20,e0,49,e0 > el código del primer juego de teclas
  • 30,e0,47,00 > el código del segundo juego de teclas
  • 00,00,00,00 > terminación.
Cómo podrás ver, hay una gama amplia de posibilidades, solo ten en cuenta que los cambios son solo validos para teclas simples, si intentas crear combinaciones de teclas (ctrl + shift +supr) estas no funcionaran. En el siguiente post continuaremos con mas de esto y aprenderemos a detectar cuales son los códigos de cualquiera de las teclas de nuestro teclado.

Los leo luego.

No hay comentarios. :

Publicar un comentario

Cumplimos 4 Años!!!!!!

No hay comentarios.
Hola de nuevo a todos, el día de hoy solo escribo para recordar que un día cómo hoy pero de hace cuatro años, surgió el blog de Xwork.


Si bien ha sido una historia de sube y bajas, actualmente la cosa se ha mantenido por el piso. Al inicio del año supuse que al menos iba a publicar un par de entradas al mes, pero entre batallas de diferentes índoles y me puesta de atención a unas cosas que me la exigen, poco a poco el contenido a ido disminuyendo. Cómo político en campaña prometo hacer post, pero no especificaré el número para no quedar mal así que siempre te puedes dar una vuelta para ver si hay algo nuevo.

Al igual que el tema anterior, este se va a mantener un buen rato, aún me quedan algunos detalles por arreglar para que este listo totalmente.

Cómo los músicos del Titanic me despido por ahora mientras el blog se hunde, pero no lo dejaré hundir totalmente, pues me lo debo (e indirectamente a la persona que fue la que me dio la idea) y les recuerdo que si alguien quiere colaborar a crear contenido acorde a lo que trata el blog, con gusto acepto.

Nos seguimos leyendo.

No hay comentarios. :

Publicar un comentario

Learning machine #15 - Operaciones a nivel del bits.

No hay comentarios.
Hola de nuevo a todos, el día de hoy vamos a ver cómo es que se realizan las operaciones a nivel de bit usando cómo referencia a los operadores de C#. Hay que tener en cuenta que dependiendo de la plataforma y del lenguaje que se use, las operaciones pueden variar un poco, pero el concepto sigue siendo el mismo.



Para empezar, hay que tomar en cuenta que este tipo de operador solo se aplica a los números enteros "int", por lo que podemos decir que aplicar cierta operación puede producir un resultado no esperado si no tomamos en consideración lo anterior.

Operadores de desplazamiento (<< y >>)

El operador "<<" o "operador de desplazamiento a la izquierda" (Left shift para los cuates). Sirve para desplazar los bits a la izquierda, es decir mueve el valor de un bit. Para poder observar un poco mejor a lo que me refiero, tomemos el número 101 en base dos, si desplazamos un bit a la izquierda, tendremos el número 1010. Hay que tener en cuenta lo que mencione al inicio, las operaciones se hacen en número enteros, si el número está definido cómo "int" tendríamos en memoria algo cómo la imagen que sigue:


Si lo desplazamos un lugar a la izquierda tendremos:


En c# podemos indicar cuantos "lugares" queremos desplazar nuestro número. Si por ejemplo desplazamos nuestro número ocho lugares, tendremos:


Nuestro número original era 5, cuando lo desplazamos un lugar obtuvimos 10 y cuando lo desplazamos 8 obtuvimos 1280.

¿Pero que pasa si lo desplazamos 29 lugares? Simple, obtenemos lo siguiente:


Y no parece nada del otro mundo, pero que pasa si le pedimos a c# que nos diga cual es el valor de este número, nos dirá que es ‭-1610612736‬ que está bien pero si no esperamos un número negativo podría sorprendernos un poco (hace un tiempo en un post, mas o menos expliqué por que pasa, sientete libre de revisarlo).

Si desplazamos el número 30 lugares tendremos:



El desplazamiento es realmente intuitivo, solo hay que tener las consideraciones necesarias.

El operador ">>" o "operador de desplazamiento hacia la derecha" (right shift) sirve para desplazar los bits a la derecha. Al igual que el operador "<<" se aplica a los números enteros y sirve para "mover" los números. Tomemos cómo ejemplo el mismo número; es decir 5 o 101 en base dos; tendremos:


Si desplazamos un lugar a la derecha tendremos:

Es muy fácil ver que en efecto se "movió" a la derecha y ahora en lugar de ser el número cinco, es el número dos. Si al número cinco lo desplazamos tres lugares a la derecha, tendremos;

Por lo que la variable si es que le asignamos el mismo valor pero con el desplazamiento habremos perdido nuestro valor y si aplicamos el desplazamiento contrario no lo podemos recuperar. Por eso lo que yo hago es siempre asignar una variable auxiliar para solo modificar el valor en ella y dejar intacta la variable original.

Operador Not (~).

Dependiendo del lenguaje que se use varia un poco cómo se especifica este operador. En C# el operador "not" se escribe usando "~". Su función es la de invertir los bits de un número. Para demostrar con mayor claridad tomemos de nueva cuenta al número cinco;



Si usamos el operador "~" obtenemos:

Ahora tenemos que si le aplicamos el operador "~" al número 5 nos resulta el valor de -6 (recordatorio amable, el tipo "int" usa un bit para indicar el signo).

Operador AND (&).

El operador "and" aplica la operación and a dos números. Hay que recordar  que "and" solo produce un uno cuando ambas valores son uno, en cualquier otro caso devuelve cero. Cómo ejemplo tomemos el número diez decimal o 1010 en binario y el número dos o 10 en binario.



Cómo podrás observar, al aplicar la operación al número diez junto con el número dos obtenemos el número dos.

Operador Or (|).

El operador " Or" aplica la operación or a dos números. Tomemos cómo ejemplo los números cinco decimal o 101 en binario y el número diez decimal o 1010 en binario, tendremos lo siguiente.

Recordemos que la operación or devuelve un uno cuando cualquiera de los dos valores es uno, por lo que al aplicar la operación or al número cinco y diez en decimal, nos resulta quince.

Y bien, por ahora es todo, en el siguiente post veremos unos ejemplos en c# donde haremos uso de los operadores para agilizar nuestro trabajo. Recuerda que en este mes cumplimos años por lo que espero publicar unos cuantos post mas para "celebrar".

Los leo luego.

No hay comentarios. :

Publicar un comentario

Back to basics #10 - Reguladores de voltaje

No hay comentarios.
Hola de nuevo a todos, el día de hoy vamos a ver el uso del regulador de voltaje.



A veces cuando trabajamos con algunos componentes, es necesario tener una fuelte de voltaje que nos suministre un voltaje constante. Por lo regular, la mayoria de las aplicaciones del blog necesitan un voltaje de 5v. Si trabajamos con una fuente de voltaje de laboratorio, podemos confiar que tendremos siempre disponible "la energia necearia", pero que pasa si queremos usar un eliminador y solo tenemos uno de 12v? Simple, no podremos usarlo o no de forma directa (al menos que nos guste ver el mundo arder).

Este tipo de eliminador es bastante barato.

En la medida de lo posible deberíamos de usar componentes que soporten un rango amplio de operación, pero el caso de que queramos  combinar componentes que usen 5v y 12v es donde surgirá un problema.

El circuito LM7805 (o simplemente 7805) sirve para regular un voltaje, éste modelo en especifico sirve para regularizar el voltaje a un nivel de 5v. Existen mas variantes del integrado; el 7809 y el 7812 y el voltaje de regulación de cada uno es 9v y 12v respectivamente. Su uso es realmente sencillo y si miramos la siguiente imagen, veremos el diagrama de conexión.

Físicamente el regulador puede tener alguno de los siguientes aspectos:
Y nosotros por ahora usaremos el T0-220.  La pata uno será por donde conectaremos el voltaje a regular; 12V en este caso. La para 2 es tierra y la pata 3 es por donde saldrá el voltaje ya regulado.Si observamos bien el diagrama, solamente necesitaremos un capacitor a la entrada y uno más a la salida y obtendremos un voltaje. Los valores de estos dependerán en gran medida de la corriente que el regulador deberá suministrar. En la hoja de datos para el integrado LM7805 se indica que dependiendo de la lejanía de la entrada con respecto a la fuente de alimentación, el capacitor C1 puede ser omitido, mientras que el capacitor C2 ayuda a mantener un valor estable. Cómo recomendación puedes probar con distintos valores o solo usar los valores recomendados en la hoja de datos que son: C1 = 0.22µf y C2= 0.1µf. Personalmente he probado con valores de 2µf en la entrada y salida para cuando uso una carga de 400mA.

Una de las consideraciones que debemos de tomar en cuenta, es que el regulador va a disipar todo el exceso de voltaje en calor por lo que si queremos hacer uso de este y le vamos a exigir corrientes superiores a 500mA, debemos de utilizar un disipador de calor.(aunque se supone que tiene protección contra sobre-corriente y sobre-calentamiento probablemente los vecinos sufran si no hay una buena disipación)

Las cosas se pueden poner "calientes" si la disipacion adecuda

Para recapitular. El integrado lm7805 (y todos sus amigos) pueden ser una alternativa realmente rápida y sencilla para obtener un voltaje regulado, pero está por demás decir que debido a que todo el "voltaje extra" se convierte en calor, no es la manera más eficiente para hacerlo pero si la corriente que usamos no es tan alta sin duda es una buena alternativa , para corrientes mayores existen otro tipo de reguladores (que eventualmente veremos) pero si no queremos complicarnos, está sin duda es una buena alternativa.

Y bien, por ahora es todo. La cuarentena lejos de permitirme crear cosas para el blog, me alejo de él, pero aprovechando que en este mes cumplimos un año más, trataré de subir algunos post útiles

No hay comentarios. :

Publicar un comentario