jueves, 13 de agosto de 2020

ARDUINO - C - ¿Encender led's de un circuito al pulsar teclas?

    En el código que detallo a continuación se encienden ciertos led's al pulsar la tecla que corresponde al puerto digital al que hemos conectado cada uno de los led. Por ejemplo si pulsamos el 0, se encenderá o se apagará el led conectado al puerto 10 digital de nuestro arduino. Y si pulsamos el 3, pues el led conectado al puerto 13.


   Este es nuestro código en C ...

 // Array del 0 al 3 para usar los puertos digitales del 10 al 13
bool   puerto[4];


// Variable que usaremos para capturar el teclado 
char   Captura;


// Para convertir el Char en String
String capturaS;


void setup()
{
  // Preparamos los puertos digitales del 10 al 13 para ser de salida
  for (int i = 10; i <= 13; i++)
  {
    pinMode(i, OUTPUT);
  }
  
  // Se abre la comunicación tipo Puerto Serie a 9600 baudios
  Serial.begin(9600);
}


void loop()
{
  // Vaciamos la tecla capturada
  Captura = ' ';
  capturaS = "";
  
  if (Serial.available() > 0) 
  { 
    // Si la librería Serial mediante available es mayor que 0, entonces es que está funcionando el puerto serie
    // Leemos el puerto Serie para ver si han pulsado algo
    Captura = Serial.read();
    
    // Convierto el char en String para luego poderlo convertir en entero
    capturaS = Captura; 


    // Avisamos si no ha pulsado la tecla correcta
    if (    (Captura != '0')
         && (Captura != '1')
         && (Captura != '2')
         && (Captura != '3') )
    {
      // Como tenemos la comunicación serial abierta con la terminal
      // presentamos mensaje de elección incorrecta
      Serial.println("No es correcto, elija entre 0-3");
    }
  }


  for (long i = 10; i <= 13; i++) // Recorro los puertos digitales del 10 al 13
  {
    if (
         // Convierto el valor de la tecla pulsada en entero
         // y le sumo 10 para ver a que puerto digital relaciono
         ((capturaS.toInt() + 10) == i) && 


         // El puerto serie nos puede devolver algo sin pulsar
         ((capturaS) != "" )
       )
    {
      // Guardamos el On/Off del puerto
      puerto[(i - 10)] = not puerto[(i - 10)];
      // Le decimos al puerto que se ponga en On o en Off
      digitalWrite(i, puerto[(i - 10)]);
    }
  } 
 
}

   Este sería el esquema del circuito que deberíamos de crear para que este código funcionara ...



ARDUINO - C - ¿Cómo convertir un Char a un String?

    Imaginemos que capturamos por el puerto serie del arduino algo pulsado desde la terminal o enviado al puerto serie. Lo que recibimos lo podemos capturar como si fuera un Char, pero luego necesitaríamos convertirlo a String para trabajarlo. ¿Cómo lo haríamos? ...

   Pues tan sencillo como este código que a continuación os presento ...

char Captura; 
String capturaS;


void setup()
  // Se abre la comunicación tipo Puerto Serie
  // Estamos usando una librería de Arduino que abre su puerto serie a 9600 baudios
  Serial.begin(9600);
}


void loop()
{
  Captura = ' ';
  
  if (Serial.available() > 0) 
  { 
    // Si la librería Serial mediante available es mayor que 0, entonces es que está funcionando el puerto serie
     // Leemos el puerto Serie para ver si han pulsado algo
    Captura  = Serial.read();


     // Convierto el char en String, así podría convertir el string a entero con toInt()
    capturaS = Captura;
}


ARDUINO - C - ¿Cómo convertir un String a un entero ó a un Float?

   La clase string dispone de las funciones toInt() y toFloat() que convierten, respectivamente, la cadena de texto a un número entero o flotante.

   Así, el código siguiente muestra la conversión de String a Int ...

#define DEBUG(a) Serial.println(a);
String var_Text = "-98765";


void setup() 
{
  Serial.begin(9600);
  long valor;
   valor = var_Text.toInt();
   DEBUG(valor);
}
 
void loop()
{
}

   Pero la conversión de String a Float sería la siguiente ...

#define DEBUG(a) Serial.println(a);
String var_Text = "-987.65"; 
void setup() 
{
  Serial.begin(9600);
  float valor;
   valor = var_Text.toFloat();
   DEBUG(valor);
}
 
void loop()
{
}

   La conversión a través de la clase String es una clase muy ligera para que no nos penalice su uso. Pero debemos de controlar que no existan caracteres no numéricos a la hora de convertir a entero o float para que no tengamos procesos no controlados.

   Existen otros métodos, pero de momento este es el que más uso.

viernes, 8 de mayo de 2020

Como obtener la hora ó fecha actual en Firebird

De primeras he de deciros que una de las fuentes de donde he sacado esta documentación ha sido de este link.


En Firebird tenemos varias formas de obtener las fechas y las horas actuales, ellas son:
  • CURRENT_TIMESTAMP
  • CURRENT_DATE
  • CURRENT_TIME
  • ‘NOW’

Con CURRENT_TIMESTAMP se obtienen la fecha y la hora. Por ejemplo:
FECHAHORA01Captura 1. 

Con CURRENT_DATE obtenemos la fecha actual, por ejemplo:
FECHAHORA02
Captura 2. 

Con CURRENT_TIME obtenemos la hora actual, por ejemplo:
FECHAHORA03Captura 3.

Fíjate que la precisión es de segundos, de la forma anterior podemos obtener la hora, los minutos, y los segundos, ¿pero y si necesitamos mayor precisión? Para eso a la variable de contexto CURRENT_TIME le podemos enviar entre paréntesis un número entre 0 y 3, significando la cantidad de decimales que queremos obtener. Por ejemplo:
FECHAHORA04
Captura 4. 

FECHAHORA05
Captura 5.

FECHAHORA06
Captura 6. 

Si observas las capturas 4, 5, y 6 notarás que la cantidad de decimales significativos va aumentando, de acuerdo al parámetro que se le envió a la variable de contexto CURRENT_TIME.
1 = 1 decimal (o sea, una precisión de décimas de segundo)
2= 2 decimales (o sea, una precisión de centésimas de segundo)
3 = 3 decimales (o sea, una precisión de milésimas de segundo)

Con ‘NOW’ podemos obtener la fecha, la hora, o la fecha y hora, actuales. Por ejemplo:
FECHAHORA07
Captura 7. 

FECHAHORA08
Captura 8.

FECHAHORA09
Captura 9.

Como puedes ver, la precisión de la hora con ‘NOW’ siempre es de milisegundos.

Usando las fechas y horas dentro de un stored proceduretrigger o execute block
Si necesitamos utilizar los valores de las fechas u horas actuales dentro del código fuente, entonces podemos obtener sus valores de la misma manera a como lo haríamos con las columnas de las tablas, algo como:
FECHAHORA10
Captura 10. 

Desde luego que también podríamos obtener el valor de ‘NOW’ de la forma anterior.


Diferencias entre CURRENT_TIMESTAMP, CURRENT_DATE, CURRENT_TIME y ‘NOW’
Quizás te hayas preguntado ¿para qué existe la palabra ‘NOW’ siendo que las fechas y las horas podemos obtenerlas con las variables de contexto?
Bien, la diferencia es que dentro de un stored proceduretrigger o execute block las variables de contexto siempre devolverán el mismo valor. Por ejemplo, si en la primera línea de un stored procedure la variable de contexto CURRENT_TIME devolvía ’14:24:57′ y ese stored procedure demoró en finalizar 40 segundos, en la última línea de ese stored procedure la variable de contexto CURRENT_TIME seguirá devolviendo ’14:24:57′
No cambió su valor. Dentro de un stored proceduretrigger, o execute block, las variables de contexto siempre tienen exactamente el mismo valor.
Pero ‘NOW’ sí cambia su valor dentro de un stored proceduretrigger o execute block. Y con ‘NOW’ siempre tenemos una precisión de milisegundos.

viernes, 1 de mayo de 2020

Crear un bat para windows de copias de seguridad automáticas usando mysql y 7z

La idea es usar un fichero .bat (BATCH ó CMD) para hacer todo el proceso automáticamente.

Para hacer las cosas más fáciles, es mejor que creemos una carpeta en un directorio sin restricciones, como MIS DOCUMENTOS o en el ESCRITORIO. Allí colocaremos/crearemos nuestro fichero de copias de seguridad, en mi caso lo he llamado copias_seguridad.bat

De primeras tenemos que tener instalado en el equipo la base de datos de donde haremos la copia de seguridad y el programa de compresión 7z. En mi caso tengo instalado mysql y por eso parte de las líneas de comando del fichero .bat son específicas para esta BD. El usuario que tenga otro tipo de BD tendrá que cambiarlas.

Las líneas específicas para mysql son las que empiezan por mysqldump. Y son algo así ...
mysqldump --opt --password=1234 --user=root --port=3306 nombreBD1 > nombreBD1.sql
Donde mysqldump es el comando de copias de seguridad de mySql o mariaDB y el path o ruta donde esté este comando debe de estar puesto dentro del contenido de la variable de entorno del sistema PATH de windows. 

La parte que pone password, user o port, son evidentes, son los datos necesarios para conectarse con la BD

Lo que hay después del puerto es el nombre de la BD y lo que hay después del signo > es el nombre del fichero que generará mysqldump con la copia de seguridad.

Para poder hacer uso del compresor 7z, deberíamos de tener en cuanta los siguientes pasos a realizar:

Lo primero es descargar la aplicación, bien en su versión x86 o en su versión x64. Puedes descargar la versión estable más reciente  ...  Haciendo clic aquí

No es necesario que 7z esté instalado, solamente necesitas los archivos 7z.exe y 7z.dll. Estos ficheros varían en su tamaño según la versión descargada y deben de estar en el mismo directorio donde pongamos nuestro fichero .bat de copias de seguridad. Si no sabemos como extraer los archivos del instalador que descarguemos para 7z, instálalo y podrás obtenerlos en el directorio en el que hayamos instalado esta aplicación.

Otra solución sería, ya que hemos instalado bajo windows el programa 7z y sabemos el path/ruta de su instalación, pues incluirlo en la variable de entorno del sistema de windows llamada PATH. Así podríamos usar el comando 7z.exe desde cualquier parte

No debemos de olvidar, algo que ya hemos dicho anteriormente, cuando vayamos a utilizar el comando 7z.exe, como compresor o descompresor, es necesario que el ejecutable 7z.exe esté junto al archivo 7z.dll.

Bien, es el momento de que conozcamos los comandos que utiliza 7z.exe. 

Y para ello es justo decir que el material que adjunto a continuación lo he copiado del siguiente blog ... https://www.taringa.net/+hazlo_tu_mismo/usando-7z-exe-en-comandos-de-un-bat-cmd_12oejh


Sintaxis utilizada por el 7z.exe

En primer lugar, tenemos que familiarizarnos con la sintaxis necesaria por el 7z

Comienza tu línea indicando el sitio en donde se encuentra el 7z; si lo tienes junto al BATCH (o puesto en la variable de sistema PATH), inicia la línea con 7z.exe.

Comenzada la línea, quedará así:
7z.exe ComandoAUtilizar -FunciónParaElComando NombreDelArchivoDeSalida

El ComandoAUtilizar está entre:
a Agregar archivos. Si usamos el Switch -ai, podremos incluir una lista de archivos incluida en un .txt.
b Benchmark (Es algo como referencias)
d Borrar archivos
e Extraer archivos
l Lista
t Probar
u Actualizar
x Extraer archivos con las rutas completas

La -FunciónParaElComando (También llamado Switch) sirve para especificar lo que hará el comando; de esta forma podemos agregar archivos específicos a un comprimido, o extraer alguno en específico. Siempre debe comenzar con un - (Guíon)

Entre ellos están:
-ao Modo de autorenombramiento.
-i Incluir archivos específicos.
-mx Nivel de compresión.
-o Establecer directorio de salida.
-p Establecer contraseña.
-sfx Crear un archivo SFX.
-t Tipo de compresión a utilizar.
-v Partir en tamaños de Kb, Mb y Gb.
-w Indicar el directorio dónde se trabajará.
-x Excluir archivos. Para excluir varios archivos desde otro archivo -ax
-y Responder que sí a cualquier evento.

El NombreDelArchivoDeSalida puede tener la terminación en la que queremos que quede el archivo, o si bien la dejamos en blanco, el archivo que resulte de la operación será .7z a menos que usemos el switch -t cambiando el formato del archivo; pero aun cambiando el método de compresión, podemos indicar la terminación del archivo si la especificamos. 
De esta forma si en NombreDelArchivoDeSalida escribimos: "Tuto7z.taringa" la terminación de nuestro archivo será ".taringa" y el lenguaje de compresión será el especificado (o no) si usamos el switch -t.

Estas son las funciones más importantes; pueden ver la lista de los comandos completos (En inglés) si ejecutan el 7z.exe desde el CMD



Comandos más utilizados y algunos ejemplos con Switches

-Añadir archivos a un comprimido: Supongamos que queremos añadir a un comprimido todos los archivos existentes en el directorio donde está el 7z.exe, el comando que usariamos en el BATCH quedaría así: 7z.exe A MiArchivo.taringa.

Si queremos crear un archivo excluyendo algun archivo presente usamos el switch -x, luego un ! y finalmente el nombre del archivo. Ej: 7z.exe A -x!7z.exe MiArchivo.taringa.

Podemos concatenar varias exclusiones, así como excluir toda una serie de archivos indicando *.TerminaciónDeLosArchivos (Ej .JPG); así no se añadiría a nuestro comprimido ninguna fotografía formato en .jpg.

-Extraer archivos de un comprimido: Para extraer todos archivos usamos los comandos E y X
Si queremos extraer sólo unos cuantos, los especificamos al final del comando. 

Algunos ejemplos:
7z.exe E MiArchivo.taringa. Este comando extraería todos los archivos contenidos en MiArchivo.taringa EXCLUYENDO LOS DIRECTORIOS INCLUÍDOS EN EL COMPRIMIDO, es decir, si el comprimido contiene las carpetas "Tuto1tuto1.htm | Tuto2tuto2.htm" y usamos el comando E, las carpetas "Tuto1" y "Tuto2" no se crearán y su contenido (El de dichas carpetas) se extraerá en el mismo directorio que los demás archivos.

Veamos otro ejemplo:
7z.exe X MiArchivo.taringa. Es igual que el anterior, con la diferencia de que este sí creará las carpetas contenidas en MiArchivo.taringa.

7z.exe X -y MiArchivo.taringa Tuto1tuto1.htm. Extraerá solamente el archivo tuto1.htm, creando la carpeta que lo contiene. Si queremos que extraiga solamente algún archivo debemos especificarlo al final del comando tal como se hizo con "tuto1.htm".


Combinando los Switches

En definitiva los comandos más utilizados son los de Extraer y Añadir a un comprimido, y para automatizar nuestro BATCH tendremos que indicar todas las funciones que necesita el comando según nuestros requerimientos.

-Extraer rutas completas en una carpeta: Cuando necesitamos actualizar una serie de archivos sea cual sea el motivo (Actualizar, arreglar un bug, etc), podemos agregar el SWITCH -y a la línea de comandos, de manera que el 7z.exe diga que sí a cualquier advertencia que nos intente dar el programa.
Si solamente queremos reemplazar archivos existentes, agregamos "-aoa", donde "-ao" se refiere a las opciones de sobreescritura, y la "a" final es para que reescriba todos los archivos que ya existen sin necesidad de preguntar.

-Métodos de compresión: Como se ha dicho, si no especificamos el tipo de compresión que queremos utilizar, 7z.exe usará el diccionario de compresión del archivo que estemos utilizando, y el formato o terminación dependerá del que nosotros le indiquemos en NombreDelArchivo. 

Para especificar el diccionario de compresión añadiremos el SWITCH -t seguido del formato que queremos. Podemos usar entre: .zip, .rar, .tar, split, gzip, bzip2, etc. Si queremos saber cuáles formatos soporta la versión del 7z que estamos usando, te recomiendo que visites la página oficial de 7z: 7-Zip.Org

En cuanto al nivel de la compresión, usaremos el SWITCH -mx seguido de un número entre 1/3/5/7/9; donde obviamente mientras más cerca del 1 estemos menos será la compresión y viceversa.

Ejemplo:
7z.exe A -TZip -mx9 MiArchivo.taringa. Con este comando estaríamos creando un archivo con terminacion .taringa pero comprimido con el diccionario de archivos .ZIP con el máximo algoritmo de compresión; esto nos da mucha utilidad por la amplia compatibilidad de los archivos .ZIP.

-Creando un archivo autoextraible (SFX): Para crear un archivo autoextraible necesitamos usar el SWITCH -sfx seguido del nombre final del archivo, y luego los archivos a añadir.

Para extraer archivos de un sfx creado en 7z, comenzamos la línea de nuestro BATCH invocando al autoextraible y él hara su trabajo. Si no queremos que nos pregunte la ruta de extraccion, agregamos el SWITCH -y, lo que extraerá los archivos en el directorio en el que esté el archivo SFX.

[NOTA: Para hacer un SFX tenemos que añadir los archivos 7zCon.sfx y 7z.sfx junto al 7z.dll y 7z.exe; luego de crear tu SFX no son necesarios para extraer algún SFX existente.]

Creando un ejemplo de fichero de copias de seguridad

Bien, esta parte ya vuelve a ser de propiedad del que redacta este artículo. Pero debo de dejar en constancia que el fichero .bat que usaremos para copias de seguridad, se ha creado usando un script para windows 7, por lo que es posible que algún comando sea algo diferente en otras versiones de windows.

Este es el contenido que tiene el fichero copias_seguridad.bat que hemos creado de muestra para realizar las copias de seguridad. En cada setencia que empieza por rem describimos brévemente lo que hacen las líneas que van a continuación. Su contenido lo podeis copiar porque ha sido creado para su libre divulgación y en breve lo subiré a gitHub por si se hiciera alguna modificación/mejora posterior.
@echo off
rem ** nos ponemos en el directorio donde está el fichero .bat **cd C:\socger\COPIAS
rem ** nos quedamos con la fecha del sistema **SET fecha="%date:~6,4%%date:~3,2%%date:~0,2%"
rem ** nos quedamos con la hora del sistema **set hora=%TIME:~,2%
set min=%TIME:~3,2%
set seg=%TIME:~6%
rem ** creo todos los ficheros de copia de las diferentes Bd de MySQL **echo Se crean las copias de mySQL
mysqldump --opt --password=1234 --user=root --port=3306 nombreBD1 > nombreBD1.sql
mysqldump --opt --password=1234 --user=root --port=3306 nombreBD2 > nombreBD2.sql
rem ** renombramos los ficheros .sql creados para ponerles la fecha y hora del sistema **ren "nombreBD1.sql" "%fecha%_%hora%%min%_nombreBD1.sql"
ren "nombreBD2.sql" "%fecha%_%hora%%min%_nombreBD2.sql"

rem ** Comprimimos los ficheros sql con el compresor 7z **7z.exe a -x!7z.exe -x!7z.dll %fecha%_%hora%%min%_copia.7z *.sql
rem ** se borra la siguiente linea porque ocupa mucho espacio en formato zip **rem 7z.exe a -x!7z.exe -x!7z.dll -tZip -mx9 %fecha%_%hora%%min%_copia.zip *.sql
rem ** copiamos la copia de seguridad en dos respaldos o rutas diferentes **rem ** una de ellas es una carpeta preparada para ser llevada a la nube de DropBox **xcopy C:\socger\COPIAS\*.7z C:\Users\Federico\Dropbox\copias /h /c
xcopy C:\socger\COPIAS\*.7z C:\socger\COPIAS\yaenInternet /h /c
rem ** borro todos los ficheros de copia de seguridad de MySQL **del "C:\socger\COPIAS\*.sql"
del "C:\socger\COPIAS\*.7z"
Sería interesante, como lo muestran las líneas comentadas, tener instalado algún sistema de copias de contenido en la nube. En mi caso he usado dropBox, pero podemos usar también OneDrive, Drive o algún sistema de ftp. La idea es tener algún otro respaldo de copias de seguridad aparte de cualquier formato físico.

Por supuesto también podemos modificar el .bat anterior para que creara copias de seguridad en varios sistemas físicos a la vez. De hecho podríamos realizar las copias en un NAS conectado en la red, en varios pendrive conectados al equipo, en carpetas compartidas en otros ordenadores de nuestra red interna, etc.

Ya el paso siguiente sería crear una tarea, en herramientas del sistema de windows, para que llamara automáticamente a nuestro fichero .bat todos los días a cierta hora y se ejecutara nuestra copia de seguridad. Llegado a este punto no olvidemos que cuando estemos creando la tarea nos preguntará por un usuario/contraseña que tenga permisos suficientes para realizarla, como podría ser una administrador del sistema.

Para su mayor difusión hemos creado en LinkedIn la siguiente publicación ...
https://www.linkedin.com/pulse/crear-un-bat-para-windows-de-copoias-seguridad-usando-s%25C3%25A1nchez