Acerca de:

Este blog contiene los códigos, ejemplos y bases de datos que he usado cuando aprendía acerca de algún tema específico. En lugar de borrarlos (una vez dominado ya el tema), he decidido publicarlos :)

lunes, 1 de abril de 2019

Probando los SCRs

(esta entrada estaba originalmente en Electrónica a Martillazos, como tener un hosting gratuito se volvió una pesadilla, he decidido copiar las viejas entradas aquí y mandar la web original al olvido).

Sucedió que encontré varios SCRs ("Rectificadores Controlados de Silicio" como son los triacs y tiristores) los que ya daban por dañados. Después de tenerlos guardados algunos meses decidí probar si funcionaban o no. Al no tener plena confianza en el método de prueba con el multímetro que nos enseñó el profesor decidí buscar en internet otro método más confiable.
No lo encontré.
Bueno, había webs acerca de usar el multímetro para comprobar si los SCRs están operativos o no, pero cuando al aplicar estos métodos en los míos me salía que todos estaban dañados. Fue cuando perdí la paciencia y decidí que la mejor manera de probarlos de una vez por todas era armar el circuito básico con el que se los hace funcionar, y hacerlos funcionar.

El circuito es éste, y es de lo más sencillo:



Que no es más que el circuito básico de disparo de un SCR. En el caso de los tiristores, éstos poseen 3 terminales: ánodo ("A", la terminal positiva), cátodo ("K" o la terminal negativa) y la compuerta (Gate). 
Los SCRs funcionan como switches que se cierran si reciben un pulso de corriente a través de la compuerta Gate y seguirán permitiendo el paso de la corriente por las otras dos terminales aunque ya no haya corriente de compuerta (en la jerga de electrónica se dice que se quedan "clavados" o "enganchados", y a la corriente de compuerta se le llama "corriente de disparo"). Para saber la corriente mínima que se necesita para "disparar" el SCR, y la máxima que puede soportar, es necesario leer el datasheet. En mi caso usé los tiristores de la serie BT151 y triacs de la serie BT136.
Los Triacs también poseen 3 terminales: uno de ellos es la compuerta y los otros dos se llaman Terminal 1 y Terminal 2, siendo intercambiables entre sí pues un triac puede conducir la corriente en ambos sentidos (es muy útil si se emplea voltaje alterno), al contrario de un tiristor que sólo conduce en un sentido al igual que un diodo en polarización directa.
Con respecto al cátodo, un tiristor sólo puede dispararse si recibe una corriente de disparo positiva. Un triac puede dispararse con corriente tanto negativa como positiva (o corriente en ambos sentidos, considerando que un triac no tiene un cátodo propiamente dicho).
Para probar los triacs y tiristores usé el mismo circuito, lo único se que hace es intercambiar los SCRs (la ventaja de las series BT151 y BT136 es que tienen la compuerta en el mismo lugar).
El circuito que armé es el siguiente:


Aquí quiero recalcar que es mejor usar un pequeño motor DC a un led, la batería es de 9 voltios y eso es demasiado para un led (que generalmente soportan menos de 5 voltios) por lo que quemé un par de ellos al probar este circuito, incluso al ponerle la resistencia en serie con el led, ésta se calentaba bastante. Pero para fines de demostración está bien (y si no se les tiene mucho cariño a los leds, por supuesto). El valor de la resistencia depende de la corriente que entrega la fuente, para una corriente mínima 10 mA y considerando un led de 3 voltios (los más comunes) y una fuente de 9 voltios:

0.01=(9-3)/R
R=700 ohmios

El cual se considera un valor máximo para la resistencia. En la práctica resulta ser demasiado alto si se usa una pila o batería gastada como la que yo usé. A veces con 200 ohmios el led apenas se enciende. El valor de la resistencia se irá bajando hasta un valor adecuado, donde el led se encienda sin quemarse.
En el caso de un motor no es necesaria la resistencia. La fuente tampoco debe tener un valor muy pequeño ya que existe un voltaje mínimo que debe haber entre las otras dos terminales del SCR para que éste se dispare, en este punto también recomiendo leer el datasheet.
Para no hacer confusión al led (o el motor) se le llamara "carga" que es el nombre genérico de las cosas que se conectan a un circuito y que se desean hacer funcionar.
El cable cocodrilo rojo va conectado a la compuerta (cuidando que no toque las otras patas del SCR) y funciona como el switch que va del polo positivo de la fuente a la compuerta. Mientras esté desconectado la carga debe estar apagada o desactivada. Si se enciende significa que el SCR está cruzado y debe descartarse.
Luego lo que se hace es tocar por un instante (apenas un pequeño toque) el polo positivo de la fuente (en este caso la batería) con el cable cocodrilo rojo:



En este caso la carga debe activarse y quedarse activada aunque el cable cocodrilo rojo ya no esté tocando la fuente. Si esto sucede así el SCR se ha quedado "clavado" y significa que está en buen estado. Si la carga se apaga al quitar el cable cocodrilo rojo el SCR no "engancha" y también debe descartarse.
En el caso de un tiristor, si se intercambian el ánodo con el cátodo y se hace la prueba de disparo también se puede comprobar la polaridad

martes, 19 de febrero de 2019

Usando el viejo Conexión a Escritorio Remoto de Windows 7 en Windows 10

Windows 10 viene con su versión de Conexión a Escritorio Remoto, pero le faltan varias opciones de configuración, y a mí personalmente no me funcionaba el copiar/pegar archivos (a pesar que la pc remota también era Windows).
Felizmente el viejo Conexión a Escritorio Remoto que usaba en Windows7 sigue presente en Windows 10, pero escondido.

Primero nos vamos a inicio y tipeamos "mstsc":



Éste es el viejo Conexión a Escritorio Remoto, yo quise anclarlo al inicio:



Aquí se ve la diferencia entre La Conexión a Escritorio Remoto de Windows 10 con el heredado de Windows 7:



Me gusta La Conexión a Escritorio Remoto de Window 7 porque es muy personalizable, algo que le  falta a la versión de Windows 10:

 Con esta opción puedo copiar y pegar desde mi pc a la pc remota.


Presionando el botón "Más" se abre esta ventanita. Eligiendo esta opción puedo hacr que la pc remota vea mis discos duros locales como unidades de red compartidas.


Estas y otras opciones no las he encontrado en la versión para Windows 10. Si Microsoft las ha escondido, lo ha hecho muy bien.

viernes, 18 de enero de 2019

Usar el visualizador de imágenes antiguo de Windows en Windows 10

Tengo un Windows 10 bastante cutre, y extraño a rabiar el viejo visualizador de imágenes de Windows 7. Luego de leer varias webs supe que este visualizador aún existe en Windows 10, pero está escondido. Siguiendo los pasos de esta web https://www.tenforums.com/tutorials/14312-restore-windows-photo-viewer-windows-10-a.html he logrado usarlo aunque no como el visor de imágenes predeterminado, pero algo es algo :)

Primero hay que guardar el siguiente texto como un archivo de registro de windows (es decir, con extensión .reg):


Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Applications\photoviewer.dll]

[HKEY_CLASSES_ROOT\Applications\photoviewer.dll\shell]

[HKEY_CLASSES_ROOT\Applications\photoviewer.dll\shell\open]
"MuiVerb"="@photoviewer.dll,-3043"

[HKEY_CLASSES_ROOT\Applications\photoviewer.dll\shell\open\command]
@=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,\
00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,72,00,75,00,\
6e,00,64,00,6c,00,6c,00,33,00,32,00,2e,00,65,00,78,00,65,00,20,00,22,00,25,\
00,50,00,72,00,6f,00,67,00,72,00,61,00,6d,00,46,00,69,00,6c,00,65,00,73,00,\
25,00,5c,00,57,00,69,00,6e,00,64,00,6f,00,77,00,73,00,20,00,50,00,68,00,6f,\
00,74,00,6f,00,20,00,56,00,69,00,65,00,77,00,65,00,72,00,5c,00,50,00,68,00,\
6f,00,74,00,6f,00,56,00,69,00,65,00,77,00,65,00,72,00,2e,00,64,00,6c,00,6c,\
00,22,00,2c,00,20,00,49,00,6d,00,61,00,67,00,65,00,56,00,69,00,65,00,77,00,\
5f,00,46,00,75,00,6c,00,6c,00,73,00,63,00,72,00,65,00,65,00,6e,00,20,00,25,\
00,31,00,00,00

[HKEY_CLASSES_ROOT\Applications\photoviewer.dll\shell\open\DropTarget]
"Clsid"="{FFE2A43C-56B9-4bf5-9A79-CC6D4285608A}"

[HKEY_CLASSES_ROOT\Applications\photoviewer.dll\shell\print]

[HKEY_CLASSES_ROOT\Applications\photoviewer.dll\shell\print\command]
@=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,\
00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,72,00,75,00,\
6e,00,64,00,6c,00,6c,00,33,00,32,00,2e,00,65,00,78,00,65,00,20,00,22,00,25,\
00,50,00,72,00,6f,00,67,00,72,00,61,00,6d,00,46,00,69,00,6c,00,65,00,73,00,\
25,00,5c,00,57,00,69,00,6e,00,64,00,6f,00,77,00,73,00,20,00,50,00,68,00,6f,\
00,74,00,6f,00,20,00,56,00,69,00,65,00,77,00,65,00,72,00,5c,00,50,00,68,00,\
6f,00,74,00,6f,00,56,00,69,00,65,00,77,00,65,00,72,00,2e,00,64,00,6c,00,6c,\
00,22,00,2c,00,20,00,49,00,6d,00,61,00,67,00,65,00,56,00,69,00,65,00,77,00,\
5f,00,46,00,75,00,6c,00,6c,00,73,00,63,00,72,00,65,00,65,00,6e,00,20,00,25,\
00,31,00,00,00

[HKEY_CLASSES_ROOT\Applications\photoviewer.dll\shell\print\DropTarget]
"Clsid"="{60fd46de-f830-4894-a628-6fa81bc0190d}"


Luego hay que hacerle al archivo .reg doble click y aceptar. Es probable que en casos como el mío este paso no sea necesario, pues mi Visor de Imágenes nunca apareció entre los visores predeterminados del sistema, así que para hallarlo y usarlo hay que realizar lo siguiente:

Click derecho sobre la imagen deeada, elegir "Abrir con" y elegir "Otra Aplicación":




En la ventana que nos aparece, escoger "Más Aplicaciones":



Y aquí está mi visor:






Y este es el resultado:




En mi caso, por más que selecciono este visor como la aplicación predeterminada para ver imágenes, Windows insiste en usar la aplicación Fotos, la cual no me gusta porque al minimizarla no mantiene el zoom que elijo para ver imágenes.

sábado, 27 de octubre de 2018

La Tortuga de Python

Buscando tutoriales, llegué a esta web:
http://elclubdelautodidacta.es/wp/2014/12/python-una-tortuga-de-brocha-fina/

Yo no sabía que Python tenía una tortuga al mismo estilo Logo. Luego de experimentar un poco con el código, llegué a esto:

import turtle

turtle.showturtle()
turtle.shape("turtle")

for i in range (0, 36):
    turtle.penup()
    turtle.left(10)
    turtle.forward(80)
    turtle.pendown()
    turtle.circle(50)
    turtle.penup()
    turtle.forward(-80)
   
turtle.mainloop()
turtle.done()
turtle.exitonclick()


El resultado es:



Haciendo unos pequeños cambios:

import turtle

turtle.showturtle()
turtle.shape("turtle")

for i in range (0, 36):
    turtle.penup()
    turtle.left(10)
    turtle.forward(25)
    turtle.pendown()
    turtle.circle(90)
    turtle.penup()
    turtle.forward(-25)
   

turtle.hideturtle()
turtle.mainloop()
turtle.done()
turtle.exitonclick()


Se obtiene:


Más info se puede hallar en la documentación oficial (en inglés).

martes, 18 de septiembre de 2018

El colador o la criba de Eratóstenes con Linq y recursivo

Ya antes había jugado con el colador de Eratóstenes, pero ahora toca hacerlo más pretencioso, menos legible y más recursivo :D
En total son tres intentos nada prácticos pero muy instructivos, pues voy a jugar un poco con funciones lambda recursivas:

// primer intento
Func<int, int> colador = null;
int[] nums = Enumerable.Range(2, 48).ToArray();

colador = n =>
{
    if (n == 8)
        return 0;
    else
    {
        nums = nums.Where(c => c == n || c % n != 0).ToArray();
        return colador(n + 1);
    }
};

colador(2);
nums.ToList().ForEach(c => Console.Write(c.ToString() + " "));

// el primer intento es una shit, modifica un array que está fuera de la función lambda.

// Acá viene el segundo intento:
Func<int, IEnumerable<int>, IEnumerable<int>> colador2 = null;
IEnumerable<int> nums2 = Enumerable.Range(2, 48);

colador2 = (n, x) =>
{
    if (n == 8)
        return x;
    else
    {
        x = x.Where(c => c == n || c % n != 0);
        return colador2(n + 1, x);
    }
};

nums2 = colador2(2, nums2);
Console.WriteLine();
nums2.ToList().ForEach(c => Console.Write(c.ToString() + " "));

// el segundo intento aún es demasiado legible.

// Acá va el tercer intento:
Func<int, IEnumerable<int>, IEnumerable<int>> colador3 = null;
IEnumerable<int> nums3 = Enumerable.Range(2, 48);

colador3 = (n, x) =>
{
    x = x.Where(c => c == n || c % n != 0);
    return (n < 8) ? colador3(n + 1, x) : x;
};

nums3 = colador3(2, nums3);
Console.WriteLine();
nums2.ToList().ForEach(c => Console.Write(c.ToString() + " "));

Console.ReadLine();



El resultado es:

viernes, 6 de julio de 2018

Cómo obtener información de la Distro de Linux

Más de una vez me ha pasado necesitar saber la versión y el nombre de una distro de Linux, y si es de 32 o 64 bits. Luego de probar con varios comandos, encontré dos que son fáciles de recordar:

>cat /etc/lsb-release
Me da el nombre y la versión de la distro.

>uname -a
Me dice si es de 32 o 64 bits.


A continuación muestro la información que dan estos comandos en distintos Ubuntus gracias a la magia de VirtualBox :D

Si dice "x86_64" es de 64 bits. Este Ubuntu vino con Unity.


Otra de 64 bits. Éste es Ubuntu Mate.


Este es un Ubuntu de 32 bits con xfce. Si es de 32 bits, uname sólo mostrará "i686".


Este es un Xubuntu 14 de 32 bits.


Debo añadir que estos comandos no dan información acerca del entorno de escritorio que se está usando.

viernes, 25 de mayo de 2018

Beamer: Error "Missign $ insert" al dejar líneas en blanco dentro de las etiquetas para ecuaciones

Tengo el siguiente archivo en Latex el cual estaba editando en Texmaker:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Beamer Presentation
% LaTeX Template
% Version 1.0 (10/11/12)
%
% This template has been downloaded from:
% http://www.LaTeXTemplates.com
%
% License:
% CC BY-NC-SA 3.0 (http://creativecommons.org/licenses/by-nc-sa/3.0/)
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\documentclass{beamer}
\mode {
\usetheme{Madrid}
}

\usepackage[utf8]{inputenc}
\usepackage{graphicx} % Allows including images
\usepackage{booktabs} % Allows the use of \toprule, \midrule and \bottomrule in tables
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{geometry}

\title[Sample1]{This is a sample Title}
\author{Y0} % Your name
\institute[LOL] % Your institution as it will appear on the bottom of every slide, may be shorthand to save space
{
LOL University \\ % Your institution for the title page
\medskip
\textit{mail@mail.com} % Your email address
}
\date{\today} % Date, can be changed to a custom date

\begin{document}
\begin{frame}
\frametitle{A Title}
Texto texto texto

\[
\frac{\partial u}{\partial t} + \frac{\partial^{2}u}{\partial x^{2}}
\]

\begin{equation}
f_{i} + \sum\limits_{k=k_{min}}^{k=k_{max}} a_k f_{i+k}
\end{equation}

\begin{align}
f_{i} + \sum\limits_{k=k_{min}}^{k=k_{max}} a_k f_{i+k}
\end{align}

\end{frame}
\end{document}


Y, mientras lo editaba, de pronto el compilador de latex empezó a protestar con el error "Missign $ insert". Aparentemente el documento no tenían errores. Me tomó buen rato encontrar que se generaba con las líneas en blanco que había dejaado donde latex no las admite.

Para generar el error "Missign $ insert" se deben dejar líneas en blanco en las siguientes secciones (las que contienen ecuaciones):


He aquí el error:



Esto es discutido en los foros de Latex desde hace tiempo, y hasta ahora no parece haber solución más que eliminar todas las líneas en blanco entre las etiquedas que usen modo matemático.

viernes, 20 de abril de 2018

Cómo darle privilegios de sudo a un usuario en Centos 7

Esto es un resumen de 5 páginas web que explicaban cómo darle privilegios de sudo a un usuario con la terminal, a qué grupo añadirlo (no hay grupo "sudo" o "sudoers" en Centos) y cómo trabajar con el visudo, el editor que nos permitirá modificar los privilegios sin que haya condiciones de carrera con otros usuarios logueados.

En Centos, el grupo equivalente al "sudoers" es "wheel". Tengo un usuario llamado "pc" el cual quiero que pueda ejecutar comandos de "sudo", pero en mi instalación de Centos por defecto "pc" no tiene privilegios, y tampoco los tiene el grupo "wheels".

Para empezar a dar privilegios, primero hay que loguearse en la terminal como root con el comando su root, y luego ejecutar visudo:




Una vez dentro del visudo, con las teclas del cursos buscamos la línea donde dice "allows people in group wheel to run all commands", la siguiente línea es la que le da privilegios al grupo "wheel". Si empieza con el caracter #, está comentada y debemos borrarlo:



 Yo prefiero ir hasta el final del archivo para guardar y salir, esto se hace con el comando :wq



Luego se ejecuta el comando usermod -aG wheel pc el cual añadirá el usuario "pc" al grupo wheel:


Y eso es todo! Si el usuario sigue sin poder ejecutar comandos de sudo se debe reiniciar el sistema.
Lo he probado en Centos 7, pero también debería funcionar en Centos 6.

sábado, 31 de marzo de 2018

Generar archivos .pyc en Python para Windows

La pregunta original la hice aquí.

En python 2.7 genero mis archivos .pyc con esta línea:

python -m compileall C:\una_ruta\myscript.py

y hasta me hice un script para compilar todos los archivos .py en una carpeta determinada:

import sys;
import subprocess;
from os import listdir
from os.path import isfile, join

[subprocess.call('python -m compileall ' + p, shell=True) for p in listdir('
D:\una_ruta') if isfile(join('D:\una_ruta', p)) and p.endswith('.py')]

Esto no funciona en Python 2.6. En python 2.6 los genero con:

C:\Python26\python -m py_compile C:\una_ruta\myscript.py

El script para compilar todos los archivos .py en una carpeta determinada sería:

import sys;
import subprocess;
from os import listdir
from os.path import isfile, join

[subprocess.call('C:\Python26\python -m py_compile ' + p, shell=True) for p in listdir('
D:\una_ruta') if isfile(join('D:\una_ruta', p)) and p.endswith('.py')]


En este enlace, explican qué significa Shell=True y en la documentación advierten sobre su uso.

domingo, 28 de enero de 2018

Abrir y pasarle parámetros a una ventana secundaria desde Java swing en Netbeans

Lo que se necesita en esta ocasión es que al presionar un botón de una ventana en Java Swing, se abra una ventana secundaria una sola vez sin importar cuántas veces se presione el botón, que al cerrar sólo la ventana secundaria la ventana pricipal continúe ejecutandose, y que ambas ventanas se cierren y el programa finalice al cerrar la ventana principal. Además tengo que pasarle parámetros desde la ventana principal a la ventana secundaria al abrirse ésta:


Hacerlo es bastante fácil, se deben crear dos ventanas, la principal frmMain y la secundaria frmOther, ambas del tipo JFrame:


En la ventana principal se declara a nivel de clase:

frmOther formOther;

Y en el listener del botón que abre la ventana secundaria se ingresa el siguiente código:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)                                        
{                                            
    if (formOther == null || !formOther.isVisible())
    {
        formOther = new frmOther("Nuevo ", "Título");
        formOther.setVisible(true);
    }
    else
        formOther.setExtendedState(JFrame.NORMAL);
}  


En este caso la ventana secundaria recibe dos parámetros tipo String, pero se puede hacer que reciba cualquier cantidad  y tipo de parámetros, para esto basta sobrecargar el constructor en la clase de la ventana secundaria (en este caso sólo voy a cambiar el título):

public frmOther(String param1, String param2)
{
    initComponents();
    this.setTitle(param1 + param2);
}


Por último, en la propiedad DefaultCloseOperation  de la ventana secundaria se escoge DISPOSE.



Y eso es todo!
El proyecto en Netbeans 8.0.2 se puede descargar de aquí.