martes, 26 de mayo de 2020

Argumentos de programa C en Linux


Cuando un programa Linux  escrito en C se ejecuta, comienza con la función main. En estos el main es:

 int main(int argc, char*argv[])

donde argc es un rencuentro de los argumentos del programa y argv es un array de cadena de caracteres que representa a los propios argumentos. 

Nota: Hay también programas en C para Linux que simplemente declaren main como main(). Esta opción también es válida, porque el tipo de retorno será, por defecto, int y los parámetros formales que no se usen en una función han de ser declarados. argc y argv siguen ahí, pero si no los declara, no podrá usarlos.

Siempre que el sistema operativo inicia un nuevo programa, los parámetros argc y argv se establecen y se transmiten a main. Dichos parámetros los suelen proporcionar otros programas, a menudo la shell que ha pedido que el sistema operativo inicie el nuevo programa. La shell adopta la línea de comando proporcionada, la divide en palabras individuales, y las usa para la matriz argv. Recuerde que una shell Linux suele ejecutar la expansión con comodines de los argumentos del nombre de archivo antes de que acepten los argumentos con comodines y a que ejecuten su propia expansión con comodines.

Por ejemplo, si proporcionamos a la shell el siguiente comando:

~$ MiPrograma izquierda derecha 'y centro'

el programa MiPrograma comenzará en main con parámetros:

argc: 4
argv: {"MiPrograma", "izquierda", "derecha", "y centro"}

Hay que tener en cuenta que el recuento de argumentos incluye el nombre del propio programa y la matriz argv contiene el nombre del programa como primer elemento, argv[0]. Como usamos comillas en el comando shell, el cuarto argumento está compuesto por una cadena con espacios.

Los argumentos de la línea de comandos son útiles para transmitir información a los programas. Por ejemplo, podría usarlos en una aplicación de base de datos para transmitir el nombre de la base de datos que desea usar, lo cual le permitirá usar el mismo programa en más de una base de datos. Algunos programas de prestación también utiliza los argumentos de la línea de comandos para modificar su comportamiento o para configurar ciertas opciones. Normalmente, configurará los denominados indicadores o los intercambiadores usando argumentos de línea de comandos que contienen un guión. Por ejemplo, el programa sort adopta un intercambiador para invertir el orden normal:

~$ sort -r archivo

Las opciones de línea de comando son muy comunes y si se usa coherentemente le serán de gran ayuda a los usuarios de su programa. Antes, cada programa de prestaciones adoptaba su propio enfoque sobre las opciones de la línea de comando, lo cual generaba cierta confusión. Por ejemplo:

~$ tar cvFB /tmp/archivo.tar 1024
~$ dd if=/dev/fd0 of=/tmp/archivo.dd bs=18k
~$ ps ax
~$ gcc --help
~$ ls -lstr
~$ ls -l -s -t -r

Actualmente se recomienda que los intercambiadores de línea de comandos comiencen con un guión y que estén formados por una única letra o número. Si fuese necesario, las opciones que no adoptan más argumentos se pueden agrupar tras un solo guión.

La especificación X/Open (disponible en: http://opengroup.org/) d0efine un uso estándar para las opciones de línea de comando (Utility Sintax Guideline) así como una interfaz de programación estándar para proporcionar intercambiadores de línea de comandos en los programas C. También definido por los estándares GNU.
 

Como en el caso de los ejemplos ls que cumplen las pautas de actuación. Cada opción debería ir seguida por cualquier valor necesario a modo de argumento independiente.

~$ ls -lstr
~$ ls -l -s -t -r

El ejemplo dd rompe nuestra regla usando opciones multi-carácter que no comienzan con guiones.

~$ dd if=/dev/fd0 of=/tmp/archivo.dd bs=18k

El ejemplo tar separa las opciones y sus valores por completo.

~$ tar cvFB /tmp/archivo.tar 1024

Es aconsejable añadir nombres de intercambio  más largos y con mayor significado a modo de alternativa para las versiones de caracteres únicos y usar un guión doble para distinguirlos. Podemos usar -h y --help como opciones para obtener ayuda.

~$ gcc --help

Otra pequeña debilidad de algunos programas es hacer que la opción +x (por ejemplo) ejecute la función contraria a -x. Podemos usar set -o xtrace para configurar el trazado de ejecución de la shell, y set +o xtrace para desactivarlo.

Como podemos imaginar, recordar el orden y el significado de todas estas opciones de programas es bastante difícil ya, sin tener que preocuparse de los formatos idiosincráticos. A menudo, la única opción es usar la opción -h (ayuda) o una página man si el programador la proporciona. 

A continuación presentamos el programa argumentos.c, que examina sus propios argumentos:

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int arg;
for (arg = 0; arg < argc; arg++) {
if(argv[arg][0] == '-'){
printf("opcion: %s\n", argv[arg]+1);
} else {
printf("argumento: %d: %s\n",arg,  argv[arg]);
}
}
exit(0);
}
Compilamos:

$ gcc argumentos.c -o argus

Cuando ejecutemos este programa, mostrará únicamente sus argumentos y detectará la presencia de opciones. La intención es que el programa adopte un argumento de cadena y un argumento de nombre de archivo opcional introducido por una opción -f. 
También podemos definir otras opciones.

$ ./argus -i -lr -a 'hola amigo' -a 'nos vemos en' -f salida.txt
argumento: 0: ./argus
opcion: i
opcion: lr
opcion: a
argumento: 4: hola amigo
opcion: a
argumento: 6: nos vemos en
opcion: f
argumento: 8: salida.txt

El programa usa únicamente el cómputo de argumentos argc, para configurar un bucle que examine todos los argumentos del programa.
 
for (arg = 0; arg < argc; arg++) {

Detecta la presencia de opciones buscando un guión inicial.

if(argv[arg][0] == '-'){


Podemos realizar unas pequeñas modifiaciones para que realice acciones diferentes para cada opciones del programa. Por Ejemplo:
#include <stdio.h>
#include <stdlib.h>
#include <string.h> int main(int argc, char *argv[])
{
int arg;
char texto[512];
char archivo[50];
int flagArchivo = 0;
int flagAdd = 0; for (arg = 1; arg < argc; arg++) {
if(argv[arg][0] == '-'){
switch (argv[arg][1]) {
case 'i':
printf("Programa: %s\n", argv[0]);
break;
case 'l':
printf("La cantidad de opciones pasadas es de: %d\n", argc-1);
break;
case 'a':
arg++;
strcat( texto, " " );
strcat( texto, argv[arg] );
flagAdd = 1;
break;
case 'f':
arg++;
strcpy( archivo, argv[arg] );
flagArchivo = 1;
break;
default:
printf("Parametro %s no soportado\n", argv[arg]);
break;
}
}
} if(flagArchivo==1){
printf("Se guardaria toda la informacion en: %s\n", archivo);
} if(flagAdd==1){
printf("Los datos agregados quedaron de la siguiente manera: %s\n", texto);
}
exit(0);
}
Ejecutando el programa quedaría algo así:

$ ./argumentos -i -l -a 'hola amigo' -a 'nos vemos en otro lado' -f salida.txt
Programa: ./argumentos
La cantidad de opciones pasadas es de: 8
Se guardaria toda la informacion en: salida.txt
Los datos agregados quedaron de la siguiente manera: hola amigo nos vemos en otro lado

De esta forma se ve el funcionamiento básico del uso de parámetros del programa. Cabe aclarar que hay funciones preestablecidas para el uso de estas opciones que podremos ver mas adelante.


lunes, 25 de mayo de 2020

Cómo programar C en Linux

Vamos a compilar y ejecutar programas C en Linux. Para ello primero vamos a asegurarnos de tener instaladas las librerías necesarias:
Se abre una consola y ejecuta el siguiente comando:

sudo apt-get install build-essential

Una vez instalado todo, ya tienes el entorno listo para compilar tus proyectos.

Crea un archivo en texto plano pero guárdalo con la extensión “.c“.

Vamos a  ejecutar el viejo y querido Hola Mundo. Simplemente tienes que abrir un fichero de texto y escribir las siguientes lineas.
#include <stdio.h>

int main()
{
    printf("Hola mundo");
    printf("\n");
    system("pause");
    return 0;
}

Ahora, en la terminal, ejecuta:
gcc holaMundo.c -o saludo // compila el archivo holaMundo.c y le llamamos “saludo ”

Luego ejecutamos el programa con el comando:
./saludo 

Como tiene un printf, lo único que hace es mostrar por pantalla la cadena de texto hola mundo (en la consola) y luego, deja un salto de línea.

Con esto ya sabes cómo compilar codigo C en Linux. Ya ves que instalando el anterior paquete desde la consola, te servirá para cualquier distribución de Linux. 

lunes, 4 de mayo de 2020

Control de un LED RGB

Visión general

En esta lección, programaremos el control de un LED RGB, y haremos que emita luz de varios colores.

Requisito

  •  1 x ESP8266 NodeMCU LoLin (La cual usaremos para todos nuestros experimentos)
  •  1 x Protoboard
  •  1 x LED RGB
  •  8 x resistencias de 220Ω.
  •  Cables para conectar todo.

Principio

Los LED RGB constan de tres LED. Cada LED tiene uno rojo, uno verde y uno azul. Estos tres LED de colores son capaces de producir cualquier color.
Los LED con emisores rojo, verde y azul, en general utilizan un cable de cuatro hilos como conexión con un cable común (ánodo o cátodo). Estos LED pueden tener ya sea ánodo común o cables de cátodo común.



Lo que usamos en este experimento es el LED RGB de ánodo común (el mas largo)
El pin es el ánodo común de tres LED. El pin está conectado a la salida de corriente de la placa, y los tres pines restantes están conectados a los pines digitales a través de una resistencia limitadora de corriente.


De esta manera, podemos controlar el color del LED RGB mediante una señal PWM de 3 canales.

Los colores del Led RGB vienen representados con números comprendidos entre el valor 0 y el valor 255. De esta forma, para componer el color rojo ponemos el valor máximo del rojo y el valor mínimo de los otros colores, es decir, el rojo equivale a «R=255; G=0; B=0». Y así sucesivamente con el resto de colores.



Ahora bien, para poder «seleccionar» un color, lo que debemos es darle más intensidad a un color que otro para el ojo humano haga el resto del trabajo y esto se logra utilizando PWM con unos 555 o con un microcontrolador.


Procedimientos

1. Construimos el circuito de la siguiente manera.









2. Programa


/***********************************************************
  File name: led_rgb.ino
  Description:Controlamos un led rgb para que cambie de colores.

*************************************************************/
int redPin = 0; // Pata R del LED RGB esta conectada al pin digital 0
int greenPin = 4; // Pata G del LED RGB esta conectada al pin digital 4
int bluePin = 5; // Pata B del LED RGB esta conectada al pin digital  5
void setup()
{
  //Seteamos los pines como salida
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);

  analogWrite(redPin, 1023);
  analogWrite(greenPin, 1023);
  analogWrite(bluePin, 1023);
}

void loop()
{
  // Colores basicos
  color(255, 0, 0); // enciende el LED RGB Rojo
  delay(1000); // delay de 1 segundo
  color(0, 255, 0); // enciende el LED RGB verde
  delay(1000); // delay de 1 segundo
  color(0, 0, 255); // enciende el LED RGB azul
  delay(1000); // delay de 1 segundo

  // Example blended colors:
  color(255, 255, 0); // enciende el LED RGB amarillo
  delay(1000); // delay de 1 segundo
  color(255, 0, 255); // enciende el LED RGB magenta
  delay(1000); // delay de 1 segundo
  color(0, 255, 255); // enciende el LED RGB cian
  delay(1000); // delay de 1 segundo
  color(255, 255, 255); // enciende el LED RGB blanco
  delay(1000); // delay de 1 segundo
  color(0, 0, 0); // apaga el LED RGB
  delay(2000); // delay de 1 segundo*/
}

// funcion de generacion del color
void color (unsigned char red, unsigned char green, unsigned char blue)
{
  analogWrite(redPin, 1023 - (red * 4)); // PWM signal output
  analogWrite(greenPin, 1023 - (green * 4)); // PWM signal output
  analogWrite(bluePin, 1023 - (blue * 4)); // PWM signal output
}


3. Compile el programa y cárguelo a la placa

Ahora, puede ver que el LED RGB emite rojo, verde, azul, amarillo, magenta, cían, blanco y luego se apaga, cada estado continúa 1s, después
repitiendo el procedimiento anterior.



Resumen

Aprendimos el principio de programación de un LED RGB y su funcionamiento.


Tabla con columnas con prioridad de ocultación

Vamos a crear una tabla responsive con la característica ocultar sus columnas automáticamente utilizando únicamente HTML y CSS.
Para lograr esto utilizaremos clases CSS para definir la prioridad de la columna de forma que: priority-1 y priority-2... Estas columnas se visualizarán basándose en el tamaño de la pantalla. 
Utilizaremos Media-queries para que a diferentes tamaños de pantalla estén habilitados diferentes prioridades.

El siguiente código HTML lo utilizaremos para mostrar tablas responsive y en ellas aplicaremos las clases mencionadas antes. En esa clase definiremos la prioridad para gestionar si queremos mostrarlas en dispositivos más pequeños o no. Es decir, cuando la pantalla se haga más y más pequeña, las columnas se ocultarán gracias al código de las clases prioritys.

<table id="libros-detail" class="tutorial-table" cellspacing="0" width="100%">
    <thead>
        <tr>
            <th class="priority-1" width="15%">Titulo</th>
            <th class="priority-2" width="15%">Autor</th>
            <th class="priority-3" width="15%">Orden</th>
            <th class="priority-4" width="10%">ISBN</th>
            <th class="priority-5" width="15%">Datos</th>
        </tr>
    </thead>
        
    <tbody>
        <tr>
            <td class="priority-1">El ojo del mundo</td>
            <td class="priority-2">Rigney</td>
            <td class="priority-3">1</td>
            <td class="priority-4">2211335566</td>
            <td class="priority-5">Cosas</td>
        </tr>
        ...
        ...
        <tr>
            <td class="priority-1">Un mago de Terramar</td>
            <td class="priority-2">Le Guin</td>
            <td class="priority-3">1</td>
            <td class="priority-4">9788435004084</td>
            <td class="priority-5">Mas cosas</td>
        </tr>
    </tbody>
</table>

Utilizaremos el siguiente código CSS para implementar la ocultación de columnas automáticamente con ayuda de las media queries. Como podrás ver, las media queries hacen referencia a cuatro tamaños de pantalla distintos. Cuando el tamaño de la pantalla concuerde con alguno de las media queries, se aplicarán sus estilos a las columnas de la tabla.

@media screen and (max-width: 1225px) and (min-width: 1045px) {
    .priority-5{
        display:none;
    }
}
        
@media screen and (max-width: 1045px) and (min-width: 835px) {
    .priority-5{
    display:none;
    }
    .priority-4{
        display:none;
    }
}
        
@media screen and (max-width: 565px) and (min-width: 300px) {
    .priority-5{
        display:none;
    }
    .priority-4{
        display:none;
    }
    .priority-3{
        display:none;
    }
}
        
@media screen and (max-width: 300px) {
    .priority-5{
        display:none;
    }
    .priority-4{
        display:none;
    }
    .priority-3{
        display:none;
    }
    .priority-2{
        display:none;
    }     
}

Con esto, a medida que se achica el tamaño de la pantalla van a ir desapareciendo las columnas por orden de prioridad.

viernes, 1 de mayo de 2020

Luces LED que fluyen

Ya hemos aprendido cómo hacer que un LED parpadee programando.
Hoy, controlaremos 8 LED, de modo que fluyan.

Los elementos que vamos a necesitar son
  •  1 x ESP8266 NodeMCU LoLin (La cual usaremos para todos nuestros experimentos)
  •  1 x Protoboard
  •  8 x LED 3mm de distintos colores
  •  8 x resistencias de 220Ω.
  •  Cables para conectar todo.

Principio

El principio de este experimento es muy simple. Se basa en el encendido y apagado secuencial de los LEDs.

Funciones: 

ciclos for
El bucle for es una estructura de control en programación en la que se puede indicar de antemano el número mínimo de iteraciones.​ Un contador de incremento se usa generalmente para incrementar y terminar el ciclo. Es una declaración útil para cualquier operación repetitiva, y a menudo se usa
en combinación con matrices para operar en colecciones de datos / pines.

Hay tres partes en el encabezado del bucle for:
for(inicialización; condición; incremento) {
// declaración (s);
}

La inicialización ocurre primero y exactamente una vez. Cada vez a través del bucle, la condición se prueba; si es cierto, el bloque de instrucciones y el incremento es ejecutado, entonces la condición se prueba nuevamente. Cuando la condición se vuelve falsa, el ciclo termina.

Procedimientos

1. Construye el circuito

La construcción del modelo es sencilla, a cada uno de los pines digitales que vallamos a usar se conecta el positivo de un diodo y cada negativo se conecta a una resistencia conectada a su vez al neutro del circuito.



2. El Programa

/***********************************************************
  File name: LedsQueFluyen.ino
  Description: Controlando encendido y apagado de los leds
***********************************************************/

int ledPin[] = {2, 5, 4, 0, 14, 12, 13, 15}; // Creamos un array con los pines que vamos a usar

void setup()
{
  for (int i = 0; i < 8; i = i + 1) {   // Usamos un ciclo for para recorrer el array
    pinMode(ledPin[i], OUTPUT);         // Establecemos los pines como de salida
  }
}
void loop()
{
  for (int i = 0; i < 8; i = i + 1) {
    digitalWrite(ledPin[i], HIGH);      // Recorremos el array y encendemos cada LED
    delay(200); //Delay 200 ms);        // Espereamos 200 milisegundos para seguir al siguiente
  }

  for (int i = 0; i < 8; i = i + 1) {
    digitalWrite(ledPin[i], LOW);       // Recorremos el array y apagamos cada LED
    delay(200); //Delay 200 ms);        // Espereamos 200 milisegundos para seguir al siguiente
  }
}

3. Compile el programa y cárguelo

Ahora, debería ver 8 LED encendidos en secuencia desde la derecha hasta la izquierda. Y luego repite lo anterior fenómeno.


Resumen

A través de este experimento simple y divertido, hemos aprendido más habilidades programación. Además, también puedes modificar el circuito y el código que proporcionamos para lograr un efecto aún más deslumbrante.

jueves, 30 de abril de 2020

Controlando un led con un boton

Visión general

En esta lección, aprenderemos cómo detectar el estado de un botón y luego alternar el estado de un LED basado en el del botón.

Vamos a requerir:
  •  1 x ESP8266 NodeMCU LoLin
  •  1 x Protoboard
  •  1 x Led 3mm
  •  1 x botón pulsador 
  •  1 x resistencias de 220Ω.
  •  1 x resistencias de 10KΩ.
  •  Cables para conectar todo.

Conceptos básicos

1. Botón

Los botones son un componente común utilizado para controlar dispositivos electrónicos. Generalmente se usan como interruptores para conectar o desconectar circuitos. 
Aunque los botones vienen en una variedad de tamaños y formas, la utilizada en este experimento será un botón de 12 mm como se muestra en las siguientes imágenes. Pines señalados por el las flechas del mismo color están destinadas a estar conectadas.
 


El botón que usamos es un botón de tipo normalmente abierto. Los contactos del botón están apagado en las condiciones normales, solo cuando el botón está presionados están cerrados.

El diagrama esquemático que utilizamos es el siguiente:


El jitter (o fluctuación) del botón debe ocurrir en el proceso de uso. La forma de onda de este es como la imagen siguiente:


Cada vez que presione el botón, la placa pensará que ha presionado el botón botón muchas veces debido al jitter del botón. Debemos tratar con el
de botones antes de usar el botón. Podemos eliminar la fluctuación a través de la programación de los botones, o por medio de un capacitor para hacerlo de forma fisica. Para hacerlo por software rimero, detectamos si el nivel de la interfaz del botón es bajo o alto. Cuando el nivel que detectamos es bajo, se necesita un retraso de 5 ~ 10 MS, y luego detecte si el nivel de la interfaz del botón es bajo o alto. Si la señal es bajo, podemos confirmar que el botón se presiona una vez. También puede usar un capacitor de 0.1 uF para limpiar el jitter de botones. 

Diagrama esquematico

2. Interrupción

Se introdujeron interrupciones de hardware como una forma de reducir el desperdicio de valioso tiempo del procesador en bucles de sondeo, esperando eventos externos. Ellos puede implementarse en hardware como un sistema distinto con líneas de control, o pueden integrarse en el subsistema de memoria.

3. Funciones clave

attachInterrupt (interrupción, ISR, modo)
Especifica una rutina de servicio de interrupción (ISR) para llamar cuando se produce una interrupción. Reemplaza cualquier función anterior que se adjuntó a la interrupción.
La mayoría de las placas tienen dos interrupciones externas: números 0 (en el pin digital 2) y 1 (en el pin digital 3).
En general, un ISR debe ser lo más corto y rápido posible. Si tu boceto usa ISR múltiples, solo uno puede ejecutarse a la vez, otras interrupciones serán ignoradas (apagado) hasta que finalice el actual. como delay () y millis () ambos confían en interrupciones, no funcionarán mientras se ejecuta un ISR. delayMicroseconds (), que no depende de interrupciones, funcionará como se espera.

Sintaxis
attachInterrupt (pin, ISR, modo)
Parámetros
pin: el número de pin
ISR: se llamará al ISR cuando ocurra la interrupción; esta función debe tomar sin parámetros y no devuelve nada. Esta a veces se denomina: rutina de servicio de interrupción.
modo: define cuándo se debe activar la interrupción. Cuatro constantes son predefinidos como valores válidos:
  • LOW para activar la interrupción siempre que el pin esté bajo,
  • CHANGE para activar la interrupción cada vez que el pin cambia de valor
  • RISING para disparar cuando el pin va de bajo a alto,
  • FALLING para cuando el pin va de mayor a menor.
 
digitalRead ()
Lee el valor de un pin digital especificado, ya sea ALTO o BAJO.
Sintaxis
digitalRead (pin)
Parámetros
pin: el número del pin digital que desea leer (int)
Devoluciones
Alto o bajo

delayMicroseconds (us)
Pausa el programa por la cantidad de tiempo (en microsegundos) especificado como parámetro. Hay mil microsegundos en un milisegundo y un millón microsegundos en un segundo.
Actualmente, el valor más grande que producirá un retraso preciso es 16383. Esto podría cambiar en futuros lanzamientos de Arduino. Para retrasos de más de unos pocos miles microsegundos, debería usar delay () en su lugar.
Sintaxis
delayMicroseconds (us)
Parámetros
nosotros: el número de microsegundos para pausar (unsigned int)
Devoluciones
Ninguna


Procedimientos

1. Construcción del circuito

Vamos a utilizar los pines digitales  D2 - GPIO 4 ara conectar el LED y D1 - GPIO 5 para el pulsador. Al negativo del diodo conectaremos una resistencia de 220Ω que ira al neutro. La pata del pulsador que hace contacto con el pin D1 se conecta ademas al vivo (3V) por medio de una resistencia de 10KΩ, la otra pata se conecta al neutro.


2. Programa

/***********************************************************
  Descripcion: Cuando precione el boton, podra verse como cambia el estado del LED. (ON->OFF,OFF->ON).
***********************************************************/

int led_pin = 4;          // definimos el pin digital 2 (GPIO 4) como el controlador del LED
int btn_pin = 5;          // definimos el pin digital 1 (GPIO 5) para la interface del boton

volatile int state = LOW; // Definimes el estado inicial del LED

void setup()
{
  pinMode(led_pin, OUTPUT); // Seteamos el pin del LED, lo dejamos en modo de salida OUTPUT
  pinMode(btn_pin, INPUT);  // Seteamos el pin del BOTON, lo ponemos en modo entrada INPUT
}

void loop()
{
  if (digitalRead(btn_pin) == LOW)        // Detectamos la bajada del boton
  {
    delay(10);                            // Esperamos 10ms para eliminar el jitter del pulsador
    if (digitalRead(btn_pin) == LOW)      // Confirmamos que el boton este precionado
    {
      while (digitalRead(btn_pin) == LOW);
      delay(10);
      while (digitalRead(btn_pin) == LOW);
      state = !state;                     // Invertimos el valor de state.
      digitalWrite(led_pin, state);       // Asignamos el valor de state a LED
    }
  }
}

3. Compile el programa y cárguelo 

Cuando presiona el botón, puede ver que el estado del LED se activará.


Resumen

A través de esta lección, debería haber aprendido a detectar el estado de un botón externo y luego alternar el estado de un LED.

miércoles, 29 de abril de 2020

Semáforo

Como primer proyecto, realizaremos un semáforo con unos Leds. 
Es ideal para iniciarnos en la programación y el montaje de circuitos porque, como se vera, es muy fácil.
Los elementos que vamos a necesitar son
  •  1 x ESP8266 NodeMCU LoLin (La cual usaremos para todos nuestros experimentos)
  •  1 x Protoboard
  •  1 x Led rojo 3mm
  •  1 x Led amarillo 3mm
  •  1 x Led verde 3mm
  •  3 x resistencias de 220Ω.
  •  Cables para conectar todo.
Una vez que tenemos todo, hacemos nuestro montaje siguiendo el siguiente esquema.

Esquema de montaje del semáforo

Utilizaremos los pines digitales D3 - GPIO 0 (rojo), D2 - GPIO 4 (amarillo) y D1 - GPIO 5 (verde). Al conectar los Leds debéis tener en cuenta que tienen polaridad, por lo que tenéis que colocarlos bien para que funcionen. En los Leds la patilla corta, o el lado que está achatado, es el negativo e irá conectado a tierra (GND en la placa) a través de una resistencia. La patilla larga, o lado redondeado, es el positivo y se conectará al pin de la placa correspondiente.


Una vez montado, abriremos nuestro IDE Arduino y escribiremos el programa (sketch).
/*************/
/*  SEMAFORO */
/*************/
//** Definiciones **//
int rojo = 0;    //definimos el valor del pin para el led rojo
int amarillo = 4; //definimos el valor del pin para el led amarillo
int verde = 5;   //definimos el valor del pin para el led verde
//** Programa **//
void setup() {
 pinMode(verde, OUTPUT);  //declaramos el pin verde como salida
 pinMode(amarillo, OUTPUT); //declaramos el pin amarillo como salida
 pinMode(rojo, OUTPUT);   //declaramos el pin rojo como salida
}
void loop() {
 digitalWrite(verde, HIGH); //encendemos el led rojo
 delay(2000);             //esperamos 2 segundos
 digitalWrite(verde, LOW); //apagamos el led rojo
 delay(500);              //esperamos medio segundo
 digitalWrite(amarillo, HIGH); //encendemos el led amarillo
 delay(2000);                 //esperamos 2 segundos
 digitalWrite(amarillo, LOW); //apagamos el led amarillo
 delay(500);                  //esperamos medio segundo
 digitalWrite(rojo, HIGH); //encendemos el led verde
 delay(2000);              //esperamos 2 segundos
 digitalWrite(rojo, LOW); //apagamos el led verde
 delay(500);               //esperamos medio segundo
}

Con la sentencia int estamos declarando una variable numérica entera, para poderla usar después en nuestro código.

El comando delay hace que el programa pare un tiempo determinado. Éste lo definiremos, en milisegundos, dentro de los paréntesis.




ln - crear un enlace simbólico

Con ln -s creamos enlaces simbólicos a ficheros o directorios. Un enlace simbólico es un acceso a un fichero o directorio que se encuentra en otro sitio del disco sin copiar el fichero o directorio.

Para crear un enlace simbólico lo haremos de la siguiente forma:

ln -s ORIGEN DESTINO

Si por ejemplo tenemos el fichero /var/www/index.html y queremos crear un enlace simbólico en /home/web haremos lo siguiente

ln -s /var/www/index.html /home/web/index.html

Y con los directorios pasa lo mismo

ln -s /var/www/ /home/web/www

Se crearía un enlace simbólico al directorio /var/www en el directorio /home/web/

En la siguiente imagen se muestra un ls -l con dos directorios que son enlaces simbolicos:




Como vemos lock y run son enlaces simbólicos, lock apunta al directorio run/lock /, y para saber donde esta el directorio lock  realmente entramos dentro del directorio y ejecutamos el comando pwd veremos la ruta del enlace simbólico y si ejecutamos el comando pwd -P vemos la ruta real del directorio.

Se puede ver la ayuda del comando que tiene mas opciones

ln --help




miércoles, 18 de marzo de 2020

Conectar por VPN sin perder la conexión a Internet

Conectar por VPN sin perder la conexión a Internet


Cada vez es más habitual el HomeOffice, ya sea ocasional y continuadamente. En muchos casos pasa por configurar y conectar al puesto de trabajo a través de una conexión VPN, lo que hace que otros recursos pierdan su conexión, como puede ser el correo electrónico o la navegación Web y, casi siempre, hay alguna forma de evitar que esto ocurra.

Nosotros nos vamos a ocupar del método que nos resulta mas interesante, desactivar el cambio de la puerta de enlace predeterminada.

En este caso, lo que se pretende es que las direcciones que pertenecen a la empresa se enruten a través de la VPN y el resto de direcciones se dirijan directamente a nuestra puerta de enlace predeterminada (la que actualmente nos da acceso a Internet).

Cuando creamos una conexión VPN y conectamos a través de ella, la puerta de enlace predeterminada se suele cambiar por la puerta de enlace de la red a la que nos hemos conectado, de modo que todo el tráfico que generemos se dirigirá hacia dicha dirección. Por regla general, las redes a las tenemos acceso a través de la VPN no nos darán acceso a Internet, ya que esto haría que todo el trafico que generásemos pasase por el servidor VPN e incrementaría al tráfico desmesuradamente, pudiendo ralentizar la conexión de todos los usuarios que se conectan a la misma. Para que no se cambie la puerta de enlace predeterminada por la de la red remota debemos entrar en las propiedades de la conexión VPN realizar los siguientes pasos:

1-Vamos a la pestaña "Funciones de red"
2-Seleccionamos el "Protocolo de Internet versión 4 (TCP/IPv4)"
3-Pinchamos en "Propiedades".
4-En la nueva ventana pinchamos en "Opciones avanzadas..."
5-En la ventana "Configuración avanzada de TCP/IP" desmarcamos el check "Usar la puerta de enlace predeterminada en la red remota".



Esta es la opción que sólo nos permitía acceder a la red conectada a través de la VPN.

Ahora es momento de probar en que punto estamos, para ello, si tenemos la VPN conectada la desconectamos y la volvemos a conectar, ya que la configuración establecida no se aplica a la conexión actual, sino a la próxima que se establezca. Con los cambios realizados se debería acceder sin problemas a Internet, pero ¿puedes acceder a la red conectada a través de la VPN?

Si en este punto ya puedes acceder tanto a la VPN como a Internet ya está todo resuelto (no es habitual, pero puede ser que no haya que realizar el resto de pasos en función de la configuración actual de la red), si ahora lo que no tienes es conexión a la red conectada a través de la VPN tendrás que enrutar las conexiones convenientemente.

Enrutando las conexiones a través de la VPN

Al dejar de usar la puerta de enlace predeterminada en la red VPN a la que nos hemos conectado, es posible que las conexiones no se envíen a través de la VPN cuando es necesario, de modo que habrá que decirle explícitamente que conexiones han de enviarse a través de la conexión VPN.

Para ello, conectamos con la VPN y comprobamos la dirección IP que se nos ha asignado, ejecutando el comando ipconfig en una ventana de línea de comandos.

Nota: Se puede arrancar la "Línea de comandos" poniendo cmd en el cuadro ejecutar en Windows XP, o en el cuadro de texto del menú Inicio de Windows 7/Vista, aunque también lo puedes encontrar en el menú Accesorios del menú Inicio, con el nombre de "Símbolo del sistema".

La dirección IP que nos ha asignado el servidor VPN es la que se indica como "Dirección IPv4" en el resultado del ipconfig (OJO: comprobar que el apartado se llama "Adaptador PPP <Nombre nuestra VPN>") o como "Dirección IPv4 del cliente" en la ventana de "Estado de <Conexión VPN>".

Si la dirección IP que nos ha asignado el servidor VPN es 192.168.X.X podemos hacer que todas las conexiones con direcciones IP que empiecen por 192.168. se envíen a través de la conexión VPN ejecutando el siguiente comando en una ventana de comandos con permisos de administrador.
route add 192.168.0.0 mask 255.255.0.0 192.168.X.X
Es decir, enrutamos todas las conexiones a direcciones IP que empiecen por 192.168. a través de la dirección IP que nos ha asignado el servidor VPN.


Route

Manipula tablas de enrutamiento de red.

ROUTE [-f] [-p] [-4|-6] comando [destino] [MASK máscara_red] [puerta_enlace] [METRIC métrica] [IF interfaz]

  -f               Borra las tablas de enrutamiento de todas las entradas de puerta de enlace. Si se usa junto  con uno de los comandos, se borrarán las tablas antes de ejecutarse el comando.

  -p               Cuando se usa con el comando ADD, hace una ruta persistente en los arranques del sistema. De manera predeterminada, las rutas no se conservan cuando se reinicia el sistema. Se pasa por alto para todos los demás comandos, que siempre afectan a las rutas persistentes apropiadas.

  -4               Forzar el uso de IPv4.

  -6               Forzar el uso de IPv6.

comando          Alguno de los siguientes:

  •                      PRINT     Imprime una ruta
  •                      ADD       Agrega una ruta
  •                      DELETE    Elimina una ruta
  •                      CHANGE    Modifica una ruta existente

 
destino            Especifica el host.

MASK             Especifica que el siguiente parámetro es el valor de 'máscara_red'.

máscara_red   Especifica un valor de máscara de subred para esta entrada de ruta. Si no se especifica, se usa de forma predeterminada el valor 255.255.255.255.

puerta_enlace  Especifica la puerta de enlace.

interfaz             El número de interfaz para la ruta especificada.

METRIC           Especifica la métrica; por ejemplo, costo para el destino.

Todos los nombres simbólicos usados para el destino se consultan en el archivo de base de datos de red, NETWORKS. Los nombres simbólicos para la puerta de enlace se consultan en el archivo de base de datos de nombre de host, HOSTS.

Si el comando es PRINT o DELETE, destino o puerta_enlace pueden ser un carácter comodín, (se especifica como un asterisco '*') o se puede omitir el argumento puerta_enlace.

Si destino contiene un carácter * o ?, se tratará como un modelo del shell y solo se imprimirán las rutas de destino coincidentes. El carácter '*' coincide con cualquier cadena y '?' coincide con cualquier carácter.

Ejemplos: 157.*.1, 157.*, 127.*, *224*.

La coincidencia de patrones solo se permite en el comando PRINT.
Notas de diagnóstico:
    Si MASK no es válido se genera un error, como cuando (DEST & MASK) != DEST
    Ejemplo> route ADD 157.0.0.0 MASK 155.0.0.0 157.55.80.1 IF 1
            Error al agregar la ruta: El parámetro de máscara especificado no es válido. (Destino & Máscara) != Destino.

Ejemplos:

    > route PRINT
    > route PRINT -4
    > route PRINT -6
    > route PRINT 157*          .... solo imprime lo que coincida con 157*

    > route ADD 157.0.0.0 MASK 255.0.0.0  157.55.80.1 METRIC 3 IF 2
                 destino^                            ^máscara   ^puerta de  métrica^    ^enlace         interfaz^

      Si no se proporciona IF, intenta buscar la mejor interfaz para una puerta de enlace específica.
    > route ADD 3ffe::/32 3ffe::1
    > route CHANGE 157.0.0.0 MASK 255.0.0.0 157.55.80.5 METRIC 2 IF 2

      CHANGE solo se usa para modificar la puerta de enlace o la métrica.

    > route DELETE 157.0.0.0
    > route DELETE 3ffe::/32



Rizando el rizo


Es habitual que tanto los routers ADSL domésticos como otros equipos concentradores o enrutadores utilicen un rango de direcciones IP que empiecen por 192.168. de modo que, al enrutar con el comando anterior puede haberse perdido la conexión a la red local, es decir, a otros equipos que tengamos en caso conectados al router ADSL, por ejemplo.

En este caso, puedes cambiar el rango de direcciones de la red local al rango 10.X.X.X o, si ambas redes no disponen de algún rango distinto aprovecharlo para enrutar un rango de direcciones IP más pequeño. Por ejemplo, si las direcciones de nuestra red local empiezan por 192.168.2.X y las de la red a la que conectamos por VPN empiezan por 192.168.8.X, podemos enrutar todas las direcciones que se correspondan con dicho intervalo con el comando:

route add 192.168.8.0 mask 255.255.255.0 192.168.X.X
Si las direcciones de la red accesible a través de la VPN empiezan por 192.168.8.X o por 192.168.9.X, es decir, 192.168.8.0 con la máscara 255.255.254.0, podríamos indicarlo de dicho modo:
route add 192.168.8.0 mask 255.255.254.0 192.168.X.X

En este sentido puede ser interesante conocer el rango de direcciones de la red a la que conectamos por la VPN para definir un enrutado más exacto, aunque no es imprescindible. Dicho rango de direcciones se define por una dirección IP de la red (por ejemplo, la dirección de la puerta de enlace y la máscara de red). Si solamente tenemos acceso a algunos recursos esta información nos la tendrá que dar el administrador del sistema (si es que nos la quiere dar), pero si tenemos acceso a algún ordenador remoto (ya sea una máquina física o una máquina real), podemos ejecutar el comando ipconfig en la máquina remota para obtener esta información.

Y, si el servidor de VPN nos asigna una dirección IP cada vez que nos conectamos (no es habitual, pero puede configurarse de dicho modo), entonces podemos utilizar el comando route con la conexión VPN ya establecida, ya que el enrutado se puede aplicar sobre la marcha sin problemas.

Dejándolo todo como estaba


Si haciendo pruebas has dejado la tabla de rutas IP inservible, puedes ver la pinta que tiene con:
route print
 y eliminar las que no sean necesarias o estorben con:
route delete <direccion> mask <máscara>
por ejemplo, para eliminar el primer enrutado que hicimos se podría ejecutar el comando (fíjate que no aparece el 192.168.X.X al final):
route delete 192.168.0.0 mask 255.255.0.0
Pero tampoco tienes que preocuparte demasiado, ya que todos los enrutados que hemos definido desaparecerán al reiniciar el equipo. Si ya has probado la configuración y va bien puedes hacerla definitiva utilizando el parámetro "route print -p", en el comando de enrutado, como en el siguiente ejemplo:
route -p add 192.168.0.0 mask 255.255.0.0 192.168.X.X