App inventor 2 en español
Cómo programar los teléfonos móviles con Android.
Bluetooth, Arduino y App inventor 2 - Juan Antonio Villalpando
-- Tutorial de iniciación de App Inventor 2 en español --
Volver al índice del tutorial
___________________________
9L2.- Enviar archivo por Bluetooth a Arduino. Tarjeta SdCard.
- Se trata de enviar un archivo, en este caso una imagen.jpg a Arduino por Bluetooth. La imagen se guardará en una tarjeta SdCard insertada en un lector SdCard de Arduino.
- Consulta este tutorial que trata sobre Arduino y tarjeta SdCard.
- Los archivos de imagen tienen caracteres especiales que dan errores al enviarlos por Bluetooth. Para corregirlo se pasa todo el archivo a un código denominado Base64, que codifica el archivo y convierte todos los caracteres en "enviables" por Bluetooth.
- Cuando el archivo llegue al Arduino, se debera de decodificar en Base64 para que tenga los mismos caracteres que el original.
- Para codificar un archivo en Base64, utilizaremos mi extensión: com.KIO4_Base64.aix: 277_extension_imagen_string.htm
- Vamos a ver el proceso poco a poco...
- Trabajaremos con esta imagen: pozo_grande.jpg (pulsa)
- Resulta que esa imagen es bastante grande, ocupa 553 KB, vamos a reducirle el tamaño hasta los 3 KB, además también reduciremos sus dimensiones a 200 x 150 pixels, será más pequeñas y con peor resolución, pero será más fácil de enviar.
- Aquí la tenemos pozo.jpg, tamaño 3 KB (4037 bytes), dimensiones 200x150
- Para cambiar su tamaño podemos utilizar la siguiente web:
https://www.imgonline.com.ua/eng/compress-image-size.php
____________________________
1.- Convertir una imagen.jpg a Base64 y mostrar sus códigos en una Etiqueta de App Inventor.
p9L2_Convertir_Base64.aia
- Al pulsar el Botón, se obtendrá el código Base64 de la imagen y se irá presentando en la Etiqueta2.
- La lentitud del proceso es debido principalmente a la escritura en la Etiqueta2, no en la generación del código que es rápido.
____________________________
- Diseño.
- El Intervalo del Reloj lo he puesto a 1 milisegundo.
____________________________
- Bloques.
____________________________
2.- Convertir una imagen.jpg a Base64 y enviarla mediante Bluetooth al Arduino. Monitor Serie.
p9L2_Bluetooth_Base64_1.aia
- Vamos a convertir la imagen a Base64 y enviarla por Bluetooth al Arduino. Visualizaremos los códigos en el Monitor Serie.
____________________________
- Diseño.
____________________________
- Bloques.
- He puesto 4 archivos: de 4k, 20k y 50k para realizar pruebas de subida.
____________________________
- Arduino.
_______________________
- Código del Arduino.
- En el Monitor Serie obtendremos los 5241 bytes que componen el código Base64 de esta imagen.
- El Monitor Serie realiza cambios de líneas, en este caso 69 cambios de líneas, que sumados a los 5241 dará unos 5310 caracteres.
- También puedo ocurrir que la información salga duplicada, es decir que repita dos veces la subida.
enviar_base64_1.ino |
// Juan A. Villalpando
// http://kio4.com/arduino/9L2_enviar_archivo_BT.htm
char caracter;
void setup()
{
Serial.begin(9600);
}
void loop() {
if(Serial.available())
{
caracter = Serial.read();
Serial.print(caracter);
}
}
|
|
|
___________________________________________________________
3.- Enviar código Base64 por Bluetooth al Arduino y guardar esa información en un archivo mediante una tarjeta y lector SdCard.
p9L2_Bluetooth_Base64_2.aia
- La información Base64 que llega al Arduino la vamos a guardar en un archivo en una tarjeta SdCard.
- Convertiremos el archivo a Base64, enviamos su string por Bluetooth como EnviarTexto.
- El Arduino irá tomando cada uno de los caracteres y los irá guardando en el archivo pozo_4.txt
- Cuando reciba el asterisco *, indicará que ha acabado el grabación del archivo.
- IMPORTANTE: es necesario que inicies el Monitor Serie del Arduino cada vez que vayas a grabar un archivo.
- El archivo quedará pozo_4.txt quedará guardado en la SdCard en formato Base64. No se podrá leer como imagen. Si lo quieres leer como imagen, debes decodificarlo en Base64, por ejemplo con esta página:
https://www.motobit.com/util/base64-decoder-encoder.asp
- Una vez decodificado en Base64, le cambias la extensión base64.bin a imagen.jpg y podrás volver a ver la imagen.
____________________________
- Diseño.
- He puesto 4 archivos: de 4k, 20k y 50k para realizar pruebas de subida.
____________________________
- Bloques.
- La aplicación es similar a la anterior, he añadido un asterisco *, al final del texto para indicar fin del envío:
____________________________
- Arduino. Lector de SdCard.
- Necesitaremos un lector de SdCard y una tarjeta SdCard.
- Consulta este tutorial: Arduino y tarjeta SdCard.
_________________
- Conexiones.
-
_________________
- Código del Arduino.
- Según van llegando los caracteres se van guardando en el archivo pozo_4.txt.
- Va recibiendo caracteres hasta que llegue el asterisco *, indicando fin del archivo.
enviar_base64_codigo_2.ino |
// Juan A. Villalpando
// http://kio4.com/arduino/9L2_enviar_archivo_BT.htm
#include <SD.h>
// const int CS = D8; // Para el NodeMcu
const int CS = 4; // Para el Arduino y Wemos ESP32
File miarchivo;
char rx_byte = 0;
void setup() {
Serial.begin(9600);
Serial.println("Iniciando SdCard...");
if (!SD.begin(CS)) {
Serial.println("Error al iniciar.");
return;
}
Serial.println("SdCard iniciada.");
miarchivo = SD.open("pozo_4.txt", FILE_WRITE); // Abre el archivo.
}
void loop() {
if(Serial.available()) {
rx_byte = Serial.read(); // Toma el caracter.
if (rx_byte != '*') {
miarchivo.print(rx_byte); // Guarda caracter.
} else {
miarchivo.close(); // Cierra el archivo.
Serial.println("Grabado.");
}
}
}
|
- Así tendríamos los archivos subidos a la SdCard.
|
Tamaño del archivo en .jpg |
Tamaño del archivo Base64 en .txt |
Tiempo que tardan en subir... |
pozo_4.jpg |
3.879 |
5.241 |
9 segundos |
pozo_20.jpg |
18.192 |
24.576 |
50 segundos |
pozo_50.jpg |
42.983 |
58.067 |
120 segundos |
________________________________
- Otro código para probar:
- En este código van llegando caracteres hasta alcanzar el número de 200, en ese momento se guardan en el archivo escribir.txt eso 200 caracteres, reinicia la k = 0 y vuelve a captar otros 200 caracteres, así hasta que llegue el asterisco.
enviar_base64_codigo_2.ino |
// Juan A. Villalpando
// http://kio4.com/arduino/9L2_enviar_archivo_BT.htm
#include <SD.h>
// const int CS = D8; // Para el NodeMcu
const int CS = 4; // Para el Arduino y Wemos ESP32
File miarchivo;
int k =0;
void setup() {
Serial.begin(9600);
Serial.println("Iniciando SdCard...");
if (!SD.begin(CS)) {
Serial.println("Error al iniciar.");
return;
}
Serial.println("SdCard iniciada.");
miarchivo = SD.open("pozo_4.txt", FILE_WRITE); // Abre el archivo.
}
char rx_byte = 0;
String rx_str = "";
void loop() {
if(Serial.available()) {
k = k + 1;
rx_byte = Serial.read(); // Toma el caracter.
rx_str += rx_byte; // Va uniendo los caracteres escritos.
if (k == 200 || rx_byte == '*') {
if (rx_byte == '*') {
rx_str = rx_str.substring(0, rx_str.length()-1); // Quita el *
}
miarchivo.print(rx_str);
rx_str = "";
k = 0;
}
}
if (rx_byte == '*') {
miarchivo.close(); // Cierra el archivo.
Serial.println("Grabado.");
rx_byte = 0;
}
|
___________________________________________________________
4.- Tenemos en la Sdcard un archivo en Base64, queremos enviarlo a la aplicación por Bluetooth. En la aplicación se descodificará y se mostrará la imagen.
p9L2_Bluetooth_Base64_3.aia
pozo_4.txt
- Esto es, tenemos en la SdCard el archivo POZO_4.TXT, que está codificado en Base64. Lo vamos a enviar por Bluetooth a la aplicación.
- También puedes realizarlo con POZO_20.TXT y POZO_50.TXT, para ello deberás modificar esos nombres en el código del Arduino.
- Cuando llegue a la aplicación, se descodificara (mediante una extensión), se guardará en un archivo en /mnt/sdcard del móvil y se mostrará en un componente Imagen.
- El siguiente Diseño lo he realizado ampliando la aplicación anterior, he añadido un Botón para obtener el archivo y un componente Imagen2 para visualizar la imagen.
- Para realizar la prueba, suponemos que existe un archivo llamado POZO_4.TXT en la SdCard del Arduino y que contiene la codificación Base64 de una imagen.
- Al pulsar el Botón de obtener, se enviará el caracter k. Cuando el Arduino reciba ese caracter enviará a la aplicación los códigos Base64 del archivo POZO_4.TXT.
- La aplicación recibirá esos códigos y los convertirá a archivo en /mnt/sdcard/el_pozo.jpg
- El Arduino enviará como último caracter el asterisco *
- Serial.print("*");
- Esto le indicará a la aplicación que ya ha terminado de enviar todo el archivo.
- En App Inventor, en las Propiedades del Bluetooth, debemos poner ByteDelimitador = 42, ya que el 42 es el código del asterisco *. Esto indicará que cuando llegue el asterisco habrá terminado de recibir el archivo completo.
- Observaremos que para enviar el archivo pozo_4.txt desde Arduino a la Aplicación tarda unos 6 segundos.
____________________________
- Diseño.
____________________________
- Bloques.
____________________________
- Código del Arduino.
- Observa que envía el asterisco como último caracter, para indicarle a la App que ha llegado al fin de archivo.
- En la App, en la Propiedades del Bluetooth, debemos poner ByteDelimitador = 42, ya que ese número es el código del asterisco *.
enviar_base64_codigo_3.ino |
// Juan A. Villalpando
// http://kio4.com/arduino/9L2_enviar_archivo_BT.htm
#include <SD.h>
// const int CS = D8; // Para el NodeMcu
const int CS = 4; // Para el Arduino y Wemos ESP32
File miarchivo;
char caracter;
void setup() {
Serial.begin(9600);
Serial.println("Iniciando SdCard...");
if (!SD.begin(CS)) {
Serial.println("Error al iniciar.");
return;
}
Serial.println("SdCard iniciada.");
}
void loop() {
if(Serial.available()) {
caracter = Serial.read();
if(caracter == 'k'){
miarchivo = SD.open("pozo_4.txt"); // Abre el archivo lectura.
if (miarchivo) {
while (miarchivo.available()) {
Serial.write(miarchivo.read());
// delay(2);
}
Serial.print("*");
miarchivo.close();
}
else {
Serial.println("Error al abrir el archivo.");
}
}
}
}
|
___________________________________________________________
5.- Cambiar los baudios del HC-06.
- El módulo Bluetooth HC-06 viene configurado con 9600 baudios (bits/s), vamos a cambiarlo a 115200 mediante los comandos AT.
- Para facilitar la carga de programas al Arduino he cambiado las conexiones del módulo a los pines 2 y 3 del Arduino.
____________________________
- Código del Arduino.
comandos_AT.ino |
// Juan A. Villalpando
// http://kio4.com/arduino/9L2_enviar_archivo_BT.htm
#include <SoftwareSerial.h>
SoftwareSerial BT(2,3);
void setup()
{
BT.begin(9600);
Serial.begin(9600);
// BT.begin(115200);
// Serial.begin(115200);
}
void loop(){
if(BT.available()) {Serial.write(BT.read());}
if(Serial.available()){BT.write(Serial.read());}
}
|
- Vamos al Monitor Serie, lo ponemos a 9600 y vamos escribiendo los comandos AT
AT obtendremos OK
- Para cambiar la velocidad a 115200 escribimos:
AT+BAUD8
obtendremos: OK115200
AT+BAUD1 ——— 1200
AT+BAUD2 ——— 2400
AT+BAUD3 ——— 4800
AT+BAUD4 ———9600 (Default)
AT+BAUD5 ——— 19200
AT+BAUD6 ——— 38400
AT+BAUD7 ——— 57600
AT+BAUD8 ——— 115200
- Ya lo tenemos configurado a 115200.
IMPORTANTE, ten en cuenta que ahora funciona con 115200, si quieres volver a poner la velocidad de 9600, debes volver a cargar el comandos_AT.ino, pero cambiando estas líneas:
// BT.begin(9600);
// Serial.begin(9600);
BT.begin(115200);
Serial.begin(115200);
Además deberás poner el Monitor Serie a 115200
Escribe AT+BAUD4 y se volverá a configurar a 9600.
___________________________________________________________
6.- Repetir ejemplo 4, pero ahora a 115200.
- Seguimos utilizando el mismo ejemplo de aplicación que vimos en el punto 4: p9L2_Bluetooth_Base64_3.aia
- Modificamos un poco el código de Arduino que vimos en el ejemplo 4.
- Al cambiar la conexión del módulo a los terminales 2 y 3, tenemos que cambiar la forma de conexión.
- Incluimos la librería SoftwareSerial y llamamos BT a la conexión de Bluetooth.
- Además observa que he cambiado la velocidad a 115200.
enviar_base64_codigo_3B.ino |
#include <SoftwareSerial.h>
SoftwareSerial BT(2,3);
#include <SD.h>
// const int CS = D8; // Para el NodeMcu
const int CS = 4; // Para el Arduino y Wemos ESP32
File miarchivo;
char caracter;
void setup() {
Serial.begin(115200);
BT.begin(115200);
Serial.println("Iniciando SdCard...");
if (!SD.begin(CS)) {
Serial.println("Error al iniciar.");
return;
}
Serial.println("SdCard iniciada.");
}
void loop() {
if(BT.available()) {
caracter = BT.read();
if(caracter == 'k'){
miarchivo = SD.open("pozo_4.txt"); // Abre el archivo lectura.
if (miarchivo) {
while (miarchivo.available()) {
BT.write(miarchivo.read());
// delay(2);
}
BT.print("*");
miarchivo.close();
}
else {
Serial.println("Error al abrir el archivo.");
}
}
}
}
|
- Realizamos la llamada al archivo y observamos que ahora la carga del archivo pozo_4.txt ahora tarda 1 segundos, cuando la velocidad la teníamos a 9600 tardaba 6 segundos.
___________________________
- Vamos a repetir el ejemplo con un archivo de 800 k
- Cargamos este archivo pu_re.txt en la SdCard. Es una imagen convertida a Base 64.
- Modificamos el archivo del código de Arduino, simplemente cambiamos:
miarchivo = SD.open("pu_re.txt"); // Abre el archivo lectura.
- El archivo se trasferirá a la aplicación y se convertirá en imagen.
- Con 115200 baudios tardará 110 segundos en transferise del Arduino a la aplicación.
- Si quisiéramos enviar el archivo desde la aplicación al Arduino, tendríamos que volver a cambiar los baudios a 9600, ya que esa transmisión es más lenta. Comprueba que si pone los baudios a un número mayor, no se transmite bien.
- Otra cosa importante, los baudios (bits/s) es la velocidad de transmisión entre el Arduino y el módulo Bluetooth. Una vez que la información llega al módulo, éste lo modula en GPSK y lo transmite con una portadora de 2,4 GHz, es decir los baudios que establecemos no es la velocidad a la que va al Android, es la velocidad de la conexión entre el Arduino y el módulo Bluetooth.
___________________________________________________________
7.- Codificar y decodificar Base64 en Arduino.
- Podemos utilizar los siguientes códigos para codificar y decodificar Base64 en Arduino:
https://platformio.org/lib/show/582/Base64/examples
- Con la librería <Base64.h>, podemos codificar y decodificar en Base64.
- Pero hay un problema importante: codifica String, es decir cadena de caracteres, no codifica directamente archivos. Tendríamos que pasar todo el archivo a String y luego codificar ese String.
- Pero continua el problema: el tamaño de memoria del Arduino. Los String en Arduino UNO tienen un límite de unos 2048 bytes, por lo cual no podemos pasar un archivo grande, de por ejemplo 3KB, a String. Lo mismo ocurre en la decodificación.
- Aquí tenemos otra librería <base64.hpp>, pero tiene el mismo problema que la anterior, codifica String.
<base64.hpp> |
https://www.arduinolibraries.info/libraries/base64
unsigned char binary[] = {133, 244, 117, 206, 178, 195};
unsigned char base64[9];
unsigned int base64_length = encode_base64(binary, 6, base64);
Serial.println(base64_length); // Prints "8"
Serial.println((char *) base64); // Prints "hfR1zrLD"
////////////////////////////////////////////
unsigned char base642[] = "hfR1zrLD";
unsigned char binary2[6];
unsigned int binary_length = decode_base64(base642, binary2);
Serial.println(binary2[1]);
// Prints "[133, 244, 117, 206, 178, 195]"
Serial.println(binary_length); // Prints "6" |
_________________
- Comentarios.
- Otras posibilidades:
- En vez de utilizar el Arduino UNO, podemos utilizar la tarjeta D1 R32 ESP32, que tiene más velocidad y más memoria, además dispone de Bluetooth.
- Observa la comparativa:
_________________
- Propuesta.
- Cambia el tamaño de los archivos en los ejemplos que hemos visto, para comprobar el tiempo de finalización del proceso.
------------------------
- Bloques en inglés.
__________________________________
|