Archivo de la categoría: Arduino

Cosas varias relacionadas con Arduino

Control de un servomotor con arduino

Para controlar un servomotor con arduino, este nos lo pone muy fácil. A la facilidad de uso de estos dispositivos, se suma el de disponer de una librería nativa en el propio IDE de arduino.

Que es un servomotor o servo?

Servomotor MG90Los servomotores son simples motores DC con una caja de engranajes para reducir la velocidad de giro de este, y sumado a una electrónica para el control de la posición.

Como todo en esta vida, los hay de diferentes tipos, fuerzas, tamaños y como no colores.

El precio de los servos varían desde poco más de 1€, se pueden encontrar en Aliexpress o Amazon, hasta de varios cientos de euros, para sistemas industriales.

Para el uso que normalmente se hace de ellos, tanto en robótica “domestica”, como para pequeños proyectos donde el coste del prototipo no queremos que se nos salga de madre, con los baratos nos es más que de sobra.

Servomotores más habituales.

El modelos más habitual en el montaje de pequeños robot, o brazos articulados el servo más habitual es el modelo SG90, también se le conoce como 9g, creo que porque su peso es ese. Este servomotor nos ofrece tanto una calidad más que aceptable para nuestros proyectos, como un precio muy contenido, este suele estar por los poco más de 1€. Este tiene una caga de engranajes de plástico, por lo que si nuestro proyecto va a necesitar que desarrolle mucha fuerce, sera mejor utilizar otro tipo de servomotor. El tamaño de este es muy contenido y la mayoría de chasis, ya sea de vehículos, robots o brazos articulados, suele venir diseñados para albergar este tipo de servos. Otro modelo muy utilizado es el MG90 de tamaño y forma idéntico al SG90, pero con la caja de engranajes en metal. Al tener los engranajes de metal del par de fuerza que puede aguantar es mayor.

Que necesito?

Para trabajar con un servo y arduino, los materiales que vamos ha necesitar son los siguientes.

Materiales usados

Arduino UNO Arduino UNO r3
Servomotor MG90

o

Servomotor SG90

protoboard Protoboard
cables_union Cables de conexión

Esquema de montaje de un servomotor controlado con Arduino.

El esquema de montaje de un servomotor controlado con arduino es muy simple. Los cables de los que dispone el servo son muy simples, un cable de color rojo, para el positivo, este suele estar alimentado entre 4,8v hasta los 7v. Por que si no tenemos muchos dispositivos conectados a nuestro arduino, lo podremos alimentar con el sin ningun problema. Cable de color negro, como es normal el negativo del servo, si alimentamos nuestro servo con una alimentación externa al arduino no debemos que olvidarnos de unir todos las masas del proyecto, para homogeneizar esta. Y por ultimo es el cable de color amarillo, este es el de control del servo. Este cable de control lo conectaremos a cualquier pin PWD de nuestro arduino.

Esquema de montaje.

Codificación del servomotor con arduino

Para programar el servo con muestro arduino no tiene mayor complejidad. El propio IDE de Arduino dispone de una librería para el control de estos aparatos. Solo tendremos que ir a la opción de “Programa” –> “Incluir libreria” –> “Servo” o directamente escribir en nuestro código.

#include <Servo.h>

Una vez agregada la librería, solo tenemos que crear un objeto el cual controlara nuestro servo.

Servo controlServo;

Lo siguiente que deberemos hacer sera indicarle a nuestro objeto, en que pin esta conectado nuestro servo, esta operación se hace mediante el comando attach, este comando tiene dos versiones. La versión simple, a la cual solo le pasaremos como parametro el numero del pin al cual tenemos conectado nuestro servomotor.

controlServo.attach(4);

Y la versión extendida, en esta versión, ademas de pasar el pin donde esta conectado el servo, tambien le pasaremos el valor mínimo y máximo de tamaño de la onda de control del servo.

controlServo.attach(4, 200, 2100);

En el 99,9% de los casos, con pasarle el pin donde esta conectado el servo en el arduino sera más que suficiente.

Si queremo “desenlazarnos” de el la librería Servo de Arduino nos ofrece la posibilidad de hacerlo mediante el comando detach(). Solo con llamarlo nos desconectaremos del servomotor.

controlServo.detach()

Para comprobar que estamos conectados a un servo, contamos con el siguiente comando attached(), este nos devolverá “True” si estamos conectados o “False” si no lo estamos.

if (controlServo.attached() == true)
  {
    Serial.print('Estamos conectados al servo');
  }
  else
  {
    controlServo.attach(4);
  }

Para poder situar el servo en el ángulo que deseemos utilizaremos el comando write(). Ha este comando le pasaremos como parámetro el angulo en el que queremos posicionar nuestro servo.

controlServo.write(90);

Si queremos saber en que posición se encuentro nuestro servo utilizaremos el comando read(). Este nos devuelve el angulo en el que se encuentra nuestro servomotor.

int posServo;
posServo = controlServo.read();

Y con estos simples comando tendremos un control absoluto sobre los servomotores que tengamos conectados a nuestro Arduino.

Ejemplo completo del uso de servomotores con arduino.

#include <Servo.h>

Servo controlServo;
int pinServo = 4;
int posServo = 0;

void setup() {
  // put your setup code here, to run once:
  
  // Paramentros de Servo.attach(pin, min, max)
  // pin -> pin donde esta conectado la señal de servo
  // min -> Valor minimo de la onda del servo
  // max -> Valor maximo de la onda del servo
  controlServo.attach(pinServo);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (controlServo.attached() == false)
  {
    controlServo.attach(pinServo);
  }
  
  posServo = controlServo.read();
  if (posServo != 90)
  {
    // Posicionamos el servo en los 90 grados
    controlServo.write(90);
    // Esperamos 1 segundo
    delay(1000);
  }
  else
  {
    // Lo posicionamos en los 180 grados
    controlServo.write(180);
    // Volvemos a esperar otro segundo
    delay(1000);
  }

  controlServo.detach();
}

Si tienes alguna duda o sugerencia, no dudes en dejarnos tu comentario.

Añadir conexión Wifi a nuestro Arduino

El Internet de la cosas (IoT) a puesto de moda el conectar cualquier cosa a internet. Y nuestros proyectos con arduino no iban a ser menos.

esp8266En el mercado, hay multitud de shield que nos dan la posibilidad de añadir conexión wifi a nuestro arduino, pero estas placas tienen un precio demasiado alto, la mayoría de ellos ha un precio elevado. Estos precios de los sistemas wifi contrastan con el precio habitual que suelen tener los demás accesorios para arduino.

Modulo wifi ESP8266

Pero además de los shield tenemos otros método de poder añadir conectividad wifi a nuestro proyectos de arduino. Este es el modulo Wifi ESP8266 nos ofrece conexión wifi de una manera sencilla y barata.

Ademas de la conexión wifi, este modulo permite una configuración muy fácil mediante el uso de comandos AT, dispone a su vez de un pequeño servidor web, que nos facilitara la conexión a él mediante el uso de un simple navegador.

Conectar el modulo wifi ESP8266 con arduino

La conexión del modulo ESP8266 con arduino es muy simple, solo tendremos que conectar los pines RX y TX del modulo, a los pines RC y TX de muestro arduino, si lo preferimos, como es mi caso, los podemos conectar a cualquier otros pines y utilizar la librería de emulación de comunicaciones serie.

Luego tendremos que conectar el pin marcado como RST a la alimentación de 3.3v de muestro arduino. La alimentación del modulo la tendremos que realizar utilizando un fuente de 3.3 v externa.

La salida de voltaje del arduino solo ofrece una alimentación de 50 mAmp, el modulo wifi ESP8266, en el arranque consume un poco más. Para pruebas podemos conectarlo a la salida de 3.3 v del arduino, pero si tienes la posibilidad de contar con una fuente externa, es mejor que lo conectes a ella. Solo queda conectar el pin GND a la fuente externa o a uno de los pines GND del arduino.

Alimentación mediante arduino del modulo wifi ESP8266
Alimentación a través de Arduino del modulo ESP8266

Circuito con alimentación exterior del modulo wifi.

Conexión modulo wifi ESP8266 con fuente externa
Alimentación del modulo ESP8266 mediante fuente externa

Configuración del modulo wifi ESP8266

La configuración de este modulo es muy parecida a la configuración de los módulos de bluetooth HC-06 o HC-05. Incluso podemos utilizar parte del código que se ha utilizado para conectarse con estos módulos para conectarse con el wifi ESP8266.

Código para leer los datos desde el puesto serie del módulo ESP8266 y escribirlos al puerto serie de la consola, y viceversa.

#include <SoftwareSerial.h>
// Creamos un puerto serie virtual para la conexión con el modulo Wifi
SoftwareSerial Wifi(3, 2); // Pin RX, Pin TX

void setup()
{  
    // Creamos la conexion serie para el control desde la consola
    Serial.begin(9600);
    // Creamos la conexión con el modulo Wifi
    Wifi.begin(115200);
}

void loop()
{
    // Si hay datos desde el modulo Wifi
    if (Wifi.available())
    {
        // Leemos un caracter
        char c = BT1.read() ;
        // Y lo escribimos en el puerto de la consola
        Serial.print(c);
    }
    // Si Hay datos disponibles desde la consola
    if (Serial.available())
    {
        // Leemos un caracter
        char c = Serial.read();
        // Y lo escribimos en el modulo Wifi
        Wifi.print(c);
     }
}

Es simple código nos va ha permitir comprobar el estado de nuestro modulo ESP8266 y realizar las configuraciones básicas.

Comprobar el funcionamiento del modulo Wifi ESP8266

Al arrancar el modulo, este nos tiene que devolver un mensaje de “Ready”

[Vendedor:www.ai-thinker.com Version:0.9.2.4]

ready

Para verificar que tenemos conexión con el modulo, desde la ventana de consola, escribimos AT, si todo es correcto y tenemos conexión con el modulo. Este nos devolverá un “OK”

[Vendedor:www.ai-thinker.com Version:0.9.2.4]

ready AT OK

Este modulo permite 3 modos de funcionamiento:

  • Modo 1: Modo estandar, en este modo de funcionamiento, el módulo se comporta como si fuera un router. Modo servidor.
  • Modo 2: Modo dispositivo / AP, en cambio en este modo, es módulo se comporta como si fuera un dispositivo que se va ha conectar con un router. Modo cliente.
  • Modo 3: Esta forma de funcionamiento, es la mezcla de los dos anteriores. Funciona lo mismo de cliente como de servidor.

Para ver en que modo esta funcionando nuestro ESP8266, le enviamos el siguiente comando AT.

AT+CWMODE?

+CWMODE:3

OK

En este caso, nos indica que esta funcionando en el modo 3. Si no sabemos muy bien como queremos que funcione nuestro modulo ESP8266, lo podemos dejar en este modo para asegurarnos su correcto funcionamiento.

Para cambiar el modo de funcionamiento, le tendremos que enviar el siguiente comando AT.

AT+CWMODE=3

no change

En este caso, como ya estaba en este modo de funcionamiento, no indica que no se ja producido ninguna cambio. Si el modo de funcionamiento no fuese el ya establecido, no devolvería un “OK”.

Conexión con la red wifi con el ESP8266

Mediante otro comando AT, podemos obtener la lista de conexiones wifi al alcance del modulo.

AT+CWLAP
+CWLAP:(1, "MOVISTAR_ASWD", -34, "AA:BB:CC:DD:EE:FF",3)
+CWLAP:(2, "Mi_Conexion", -54, "AA:BB:CC:DD:EE:FF",5)

La información que nos aparece es, posición en la lista, el SSID de la conexión wifi, potencia de la señal, y la MAC del router.

Para conectar el modulo ESP8266, a nuestra red wifi, utilizaremos otro comando AT. En este caso,  el comando AT+CWJAP=”SSID_nuestra_conexión”, “contraseña”

AT+CWJAP="SSID_nuestra_conexión", "contraseña"

OK

Si la conexión se ha realizado con existo, nos devolverá como siempre un “OK”.

Obtener información de nuestra conexión con ESP8266

Al establecer conexión, con nuestro router o el servidor de DHCP que tengamos instalado en nuestra, este le tiene que asignar una dirección IP a nuestro modulo. Para conocer la ip asignado a nuestro modulo wifi utilizaremos el siguiente comando AT.

AT*CIFSR
192.168.1.1
192.168.1.201

OK

Este comando AT nos devolverá, en una primera linea, la dirección ip del router, y en una segunda, la dirección ip que se le ha asignado al modulo.

Activar servidor TCP en el modulo wifi ESP8266

Con esto, ya podríamos conectarnos al ESP8266, pero para poder interactuar con el debemos activar el servidor disponible en modulo. Para activar este servidor volvemos a tirar de comando AT.

AT+CIPSERVER=1, 80

OK

Esto activara el servidor TCP en el puerto 80.

Para desactivar el servidor solo tendremos que repetir el mismo comando cambiado el 1 por un 0.

AT+CIPSERVER=0, 512

OK

Una vez que tengamos el servidor TCP activado en el modulo, podremos interactuar con el estableciendo una conexión en la dirección ip asignada y mediante el puerto activado.

Tabla con los comandos AT disponibles en el modulo wifi ESP8266

Comandos Descripción Tipo Configuración / Ejecución Estado Prueba Parámetros y ejemplos
AT general test basic
AT+RST restart the module basic
AT+GMR check firmware version basic
AT+CWMODE wifi mode wifi AT+CWMODE=<mode> AT+CWMODE? AT+CWMODE=? 1= Sta, 2= AP, 3=both, Sta is the default mode of router, AP is a normal mode for devices
AT+CWJAP join the AP wifi AT+ CWJAP =<ssid>,< pwd > AT+ CWJAP? ssid = ssid, pwd = wifi password
AT+CWLAP list the AP wifi AT+CWLAP
AT+CWQAP quit the AP wifi AT+CWQAP AT+CWQAP=?
AT+ CWSAP set the parameters of AP wifi AT+ CWSAP= <ssid>,<pwd>,<chl>, <ecn> AT+ CWSAP? ssid, pwd, chl = channel, ecn = encryption; eg. Connect to your router: AT+CWJAP=”www.electrodragon.com”,”helloworld”; and check if connected: AT+CWJAP?
AT+CWLIF check join devices’ IP wifi AT+CWLIF
AT+ CIPSTATUS get the connection status TCP/IP AT+ CIPSTATUS <id>,<type>,<addr>,<port>,<tetype>= client or server mode
AT+CIPSTART set up TCP or UDP connection TCP/IP 1)single connection (+CIPMUX=0) AT+CIPSTART= <type>,<addr>,<port>; 2) multiple connection (+CIPMUX=1) AT+CIPSTART= <id><type>,<addr>, <port> AT+CIPSTART=? id = 0-4, type = TCP/UDP, addr = IP address, port= port; eg. Connect to another TCP server, set multiple connection first: AT+CIPMUX=1; connect: AT+CIPSTART=4,”TCP”,”X1.X2.X3.X4″,9999
AT+CIPMODE set data transmission mode TCP/IP AT+CIPMODE=<mode> AT+CIPSEND? 0 not data mode, 1 data mode; return “Link is builded”
AT+CIPSEND send data TCP/IP 1)single connection(+CIPMUX=0) AT+CIPSEND=<length>; 2) multiple connection (+CIPMUX=1) AT+CIPSEND= <id>,<length> AT+CIPSEND=? eg. send data: AT+CIPSEND=4,15 and then enter the data.
AT+CIPCLOSE close TCP or UDP connection TCP/IP AT+CIPCLOSE=<id> or AT+CIPCLOSE AT+CIPCLOSE=?
AT+CIFSR Get IP address TCP/IP AT+CIFSR AT+ CIFSR=?
AT+ CIPMUX set mutiple connection TCP/IP AT+ CIPMUX=<mode> AT+ CIPMUX? 0 for single connection 1 for multiple connection
AT+ CIPSERVER set as server TCP/IP AT+ CIPSERVER= <mode>[,<port> ] mode 0 to close server mode, mode 1 to open; port = port; eg. turn on as a TCP server: AT+CIPSERVER=1,8888, check the self server IP address: AT+CIFSR=?
AT+ CIPSTO Set the server timeout AT+CIPSTO=<time> AT+CIPSTO? <time>0~28800 in second
+IPD received data For Single Connection mode(CIPMUX=0): + IPD, <len>:
For Multi Connection mode(CIPMUX=1): + IPD, <id>, <len>: <data>

Más información sobre el modulo wifi ESP8266: https://www.itead.cc/wiki/ESP8266_Serial_WIFI_Module

Con esto ya tendríamos nuestro arduino conectado a nuestra red wifi, accesible desde cualquier lugar.

Si tienes cualquier sugerencia o duda no tengas ningún reparo en dejarnos tu comentario.

Trabajar con arduino y una pantalla Nokia 5110

Como trabajar con la pantalla Nokia 5110 LCD y el arduino

Cuando queremos que nuestro arduino nos muestre información, la opción más habitual es instalarle una pantalla. Y la pantalla que traía los modelos Nokia 5110 es una buena alternativa, tiene un tamaño ni muy grande, ni muy pequeño, nos permite mostrar información en pantalla nokia 5110 LCDmodo gráfico, lo que nos permitirá una gran flexibilidad a la hora de presentar nuestros resultados. Y además, para mi principalmente el precio es muy asequible, por poco más de 3€ podemos hacernos con una.

Ya con todos los conectores y configuración para montarla con nuestro arduino.

Otra de las principales características importantes de esta pantalla LCD, es la de disponer de multitud de librerías que que nos facilitaran enormemente su programación.

Materiales usados

Arduino UNO Arduino UNO
pantalla nokia 5110 Pantalla Nokia 5110
protoboard Protoboard
cables_union Cables de conexión

Montaje de la pantalla LCD Nokia 5110 con

arduino

Para conectar la pantalla del nokia 5110
con nuestro arduino conectaremos los siguientes pines del arduino a los conectores de la pantalla. Dependiendo del fabricante de la pantalla la posición de los pines puede variar, he incluso algún nombre también.

Pin Pantalla Pin Arduino Descripción
Rst 3 Reinicio de la pantalla
CE | SCE 4 Chip selection ( Selección del chip)
DC | D/C 5 Data / Commands choice (Envío de datos o comandos)
Din | DN | MOSI 6 Serial data in (Envío de datos serial)
CLK | SCLK 7 Serial Clock ( señal de sincronización)
Vcc +3,3 Alimentación a la pantalla de 3,3 ( Esta pantalla funciona con un rango de voltaje de 2,7 a 3,3, NO CONECTAR A 5V
LIght GND Retroiluminación de la pantalla, le podemos poner un potenciómetro para regular la iluminación.
GND GND Alimentación negativa de la pantalla

En algunos montaje he visto que intercalan resistencias en los pines de datos (los pines de la pantalla del 1 al 5), yo lo he probado, tanto con resistencias como sin ellas y la pantalla funciona perfectamente, Puede ser que el montaje de mi pantalla ya estén instaladas, lo desconozco.

Programación de la pantalla LCD Nokia 5110

Gracias a la popularidad de esta pantalla existe multitud de librerías, después de probar varias yo me quedo con la de Adafruit PCD8544 Nokia 5110 LCD. Es muy sencilla es su manejo, es compatible con las ultimas versiones de Arduino IDE, y trae un ejemplo que facilita su uso, para poder utilizar las funciones gráficas de la librería tenemos que instalar esta otra librería, la librería gráfica GFX, que sera la que nos permita mostrar gráficos en nuestra pantalla.

Inicialización de la pantalla Nokia 5110

Creamos el objetos que manejara la pantalla, aquí le pasamos como parámetros los pines donde están los pines de datos de la pantalla.

// Software SPI (slower updates, more flexible pin options):
// pin 7 - Serial clock out (SCLK)
// pin 6 - Serial data out (DIN)
// pin 5 - Data/Command select (D/C)
// pin 4 - LCD chip select (CS)
// pin 3 - LCD reset (RST)
Adafruit_PCD8544 Pantalla = Adafruit_PCD8544(7, 6, 5, 4, 3);

Arrancamos la pantalla

  Pantalla.begin();

Ajustamos el contraste, no confundir con la retroiluminación, esto configura el negro de la pantalla, lo situamos a la mitad, podemos ajustarlo a nuestro gusto.

display.setContrast(50);

Mostrar texto en la pantalla Nokia 5110

Para mostrar cadena de caracteres simplemente le tenemos que indicar la posición donde queremos que se muestre el texto, el color, aunque la pantalla es de blanco y negro podemos jugar con invertir el color, escribir el negro o en blanco, y el tamaño de la fuente a utilizar.

// text display tests
Pantalla.setTextSize(1);
Pantalla.setTextColor(BLACK);
Pantalla.setCursor(0,0);
Pantalla.println("Hello, world!");
Pantalla.setTextColor(WHITE, BLACK); // 'inverted' text
Pantalla.println(3.141592);
Pantalla.setTextSize(2);
Pantalla.setTextColor(BLACK);
Pantalla.print("0x"); 
Pantalla.println(0xDEADBEEF, HEX);
Pantalla.display();

El ultimo comando “Pantalla.display()”  es la que mostrara el texto, los comandos anteriores cargan la información en el buffer, hasta que no pongamos el comando display no se mostrara en la pantalla.

Mostrar gráficos en la pantalla Nokia 5110

Si queremos mostrar gráficos en la pantalla lo mejor es cargar el ejemplo de la librería, en el encontramos como dibujar una linea

void testfillrect(void) {
  uint8_t color = 1;
  for (int16_t i=0; i<display.height()/2; i+=3) {
    // alternate colors
    display.fillRect(i, i, display.width()-i*2, display.height()-i*2, color%2);
    display.display();
    color++;
  }
}

Círculos, rectángulos, múltiples lineas, imágenes bitmap, etc.

Por ultimo un pequeño video del funcionamiento de la pantalla nokia 5110 y el arduino con la librería de Adafruit.

Gracias ha esta pequeña pantalla y a la librería de Adafruit el mostrar información con nuestro arduino sera muy fácil y sencillo.

Si tienes alguna duda o algún comentario, no dudes en escribirnos.

Como escribir en un tarjeta SD con Arduino

Como escribir en un tarjeta SD con Arduino

como escribir en un tarjeta SD
Adaptador SD para arduino

En nuestros proyectos muchas veces necesitamos como escribir en un tarjeta SD con Arduino para almacenar la información que nos devuelve los sensores en algún lugar para después poderlos descargar y procesarlos en nuestro equipo.

 

Materiales usados

Arduino UNO Arduino UNO
 Arduino Shield SD Shield para SD
protoboard Protoboard
cables_union Cables de conexión

Escribir y leer en una tarjeta SD desde arduino

La mejor forma para realizar eso, es aprovechas la multitud de accesorios que hay para Arduino  que incorpora ranuras para tarjetas SD (Arduino Wireless SD Shield).

Para trabajar con tarjetas SD, Arduino (Arduino Uno R3) dispone de una librería que nos facilita el trabajo de como escribir en un tarjeta SD. La librería que tenemos que incluir en nuestros programas es

#include <SD.h>

Esta librería, aparte de incorporar las funciones básicas para escribir y leer fichero, también dispone de varias funciones para el manejo de la tarjeta, como puede ser espacio disponible, formato de la tarjeta, manejo de fichero (creación y eliminación de ficheros), lectura y escritura de ficheros, etc.

Conexión del lector de tarjetas SD con Arduino

Para la comunicación del lector de tarjeta SD (SD Card Reader Module Slot Socket For Arduino ARM MCU) y el microcontrolador se utilizan 4 puertos digitales, lo habitual, por lo menos en los accesorios que he podido manejar, los puertos que manejan son los siguientes:

  • En el pin digital 4: SD_CS.
  • Pin 11: SD_DI.
  • En el 12 conectar: SD_DO.
  • y en el pin 13: SD_CLK.

Se podrían usan otros y configurarlos, pero la mayoría de los accesorias que soportan tarjetas SD (Samsung Evo MB-MP16DA/EU – Tarjeta de memoria Micro SDHC de 16 GB (UHS-I Grade 1 Clase 10, con adaptador SD)), suelen ser shield, tarjetas que se conectan directamente en los pines del Arduino. No pudiendo modificar los pines que utilizan.

El formato de archivos que soporta el Arduino es FAT16 o FAT32, y el el tamaño máximo de la tarjeta SD que suele soportar es de hasta 16Gb (Samsung Evo MB-MP16DA/EU – Tarjeta de memoria Micro SDHC de 16 GB (UHS-I Grade 1 Clase 10, con adaptador SD)).

Leer un fichero en la tarjeta SD desde Arduino

Para como escribir en un tarjeta SD tendremos que crear un objeto que sera el que se encargue de realizar las operaciones de escritura y lectura.

Declaración del objeto para el maneje de fichero.

File miFichero;

Una vez que hemos declaro el objeto, le asignaremos el fichero con el que queremos trabajar y el modo de apertura, podemos indicar la apertura en modo “FILE_WRITE”, este modo nos permitirá abrir el fichero en modo lectura y escritura, si el fichero no existiera, Arduino lo crearía y lo abriría, si por el contrario, el fichero ya existiera, Arduino lo abriría y las escrituras que realicemos, las haría al final del archivo.

MiFichero = SD.open(“Nombre_Fichero.ext”, FILE_WRITE);

Leer un fichero desde la tarjeta SD desde Arduino

Si lo que queremos es solo abrirlo para lectura solo los tendremos que abrir de esta otra forma.

MiFichero = SD.open(“Nombre_Fichero.ext”);

Si el fichero no existe, esta operación provocara un error. Para comprobar que un fichero existe la librería de SD de Arduino nos proporciona la siguiente función.

SD.exists(“Nombre_Fichero.ext”)

Nos devolverá true, su el fichero existe, por lo contrario, si no existe, nos devolverá false. Una vez que hemos abierto el fichero, solo nos queda escribir o leer de el. Para leer solo tenemos que utilizar la función “println” de la siguiente forma.

MiFichero.println(“Información a guardar en el fichero”);

Pero si lo que queremos es leer del fichero, utilizaremos esta otra función.

MiFichero.read();

Esta función nos devolverá un byte leído desde el fichero.

Si lo que queremos es leer una linea, por ejemplo, los haríamos de la siguiente manera.

Byte byteLeido;
String Cadena = “”;
while (miFichero.available())
{
    byteLeido = miFichero.read();
    if (byteLeido == 13)
    {
        break;
    }
    else
    {
        Cadena = Cadena + char(byteLeido);
    }
}

Después de terminar nuestras operaciones con el fichero, solo nos queda nada mas que cerrarlo. Para ello utilizaciones la función “close”.

MiFichero.close();

Esto hará que cerremos todas operaciones con el fichero.

Estas son solo una pocas funciones disponibles para  la lectura/escritura de como escribir en un tarjeta SD con Arduino (Arduino Uno R3), pero muchas otras disponibles, para obtener más información sobre la librería SD de Arduino puede consultar este enlace. https://www.arduino.cc/en/Reference/SD

Personalizar la serialización de tipos en XML

Serialización con XML
Serialización con XML

Cuando queremos guardar en fichero XML alguna estructura de datos podemos recurrir a la serialización.

Con las funciones actuales disponibles para el manejo de XML en C# la serialización de estructuras de datos es relativamente sencilla. Pero el problema nos surge cuando en la estructura de datos hay algún tipo de objeto que, o no nos interesa el modo en que hace la conversión, por la razón que sea, o por que la serialización de ese objeto no esta soportada.

Para solucionar este problema C# nos proporciona los atributos [XMLIgnore], para indicarle al proceso de serialización que ignore ese objeto, y [XmlElement], donde le indicamos como se va ha convertir ese objeto.

Para indicar al proceso de serialización del XML que ese objeto lo ignore, solo tendremos que anteponer el atributo [XMLIgnore] delante del objeto que queremos. Por ejemplo:

[XmlIgnore]
public Image Imagen { get; set; }

En este caso el tipo “Image” no soporta serialización, por lo que la conversión la tendremos que realizar nosotros mismos.

Una que le hemos dicho que ignore ese objeto le tenemos que indicar como vamos a convertirlo. Para ello tendremos que crear nuestra función de conversión he indicarle que la use en para ese elemento. Para indicarle que objeto vamos a utilizar solo tenemos que utilizar el atributo [XmlElement(“Nombre_del_objeto”], le indicamos el nombre que le hemos dado al objeto, no el tipo. Por ejemplo:

[XmlElement("Imagen")]
public byte[] ConvertImageToByte
{
    // Devolvemos una cadena de byte cuando nos pasan la imagen
    get
        {
            byte[] ImagenByte = null;
            // Si el valor pasado es distinto a null, pasamos la conversión, sino pasamos null
            if (Imagen != null)
            {
                // Convertimos la imagen en un array de byte[]
                ImageConverter ConvertirImagen = new ImageConverter();
                ImagenByte = (byte[])ConvertirImagen.ConvertTo(Imagen, typeof(byte[]));
            }
        return ImagenByte;
    }

    // Devolvemos una imagen cuando nos pasan una cadena de byte[]
    set
    {
        // Si el valor pasado es null
        if (value == null)
        {
            // Devolvemos otro null
            Imagen = null;
        }
        else
        {
            // Convertimos el array de bytes[] en una imagen
            ImageConverter ConvertirImagen = new ImageConverter();
            Imagen = (Image)ConvertirImagen.ConvertFrom(value);
        }
    }
}

En el ejemplo se utiliza el objeto “Imagen” del ejemplo anterior que es de tipo “Image”, que no esta soportado por la serialización de XML. Lo que hacemos es convertilo en un array de byte para poderlo guardar en el fichero.

La parte del “get” la serialización de XML la utilizara cuando va ha grabar los datos, leeremos desde el objeto “Imagen” la imagen que queremos y con ayuda de la función “ImageConverter” la convertimos en un array de byte, le indicamos el formato que vamos a utilizar en el segundo parámetro que le pasamos a la función en este caso “typeof(byte[]).

ImageConverter ConvertirImagen = new ImageConverter();

ImagenByte = (byte[])ConvertirImagen.ConvertTo(Imagen, typeof(byte[]));

La parte del “set” la serialización de XML la usa cuando lee los datos desde el fichero de XML. Le pasara la cadena de byte que tiene grabada y cargara en la variable “Imagen” la imagen es su formato correcto, tipo “Image”. Para la conversión volvemos a utilizar la función “ImageConverter”, en este caso nos devolverá un objeto, para pasárselo a la variable solo tenemos que indicar que ese objeto es de tipo “Image”

ImageConverter ConvertirImagen = new ImageConverter();
Imagen = (Image)ConvertirImagen.ConvertFrom(value);

Si lo aplicamos a un objeto que es de un tipo soportado por la serialización de XML, lo que hará, sera ignorar su método de serialización y utilizar el que le indiquemos.

Si tienes alguna sugerencia sera bienvenida, deja un comentario.

OPC el idioma de los sistemas industriales

La comunicación de los sistemas industriales siempre a sido un tema muy complicado. Cada fabricante de plc’s utilizaba un sistema de comunicación propio, sin ofreces ningún tipo de información a tercera partes para poder realizar productos que pudieran trabajar con el. Esto hacia que el montaje de un sistema fuera complicado, ya que te tenias que basar en los productos que el fabricante elegido te ofrecía.

PROBLEOPC

Pero esto, se terminó con la aparición del sistema OPC, (OLE for Process Control, por sus siglas en ingles) es un sistema creado en un principio por Microsoft para la comunicación de sistemas industriales. En la actualidad este estándar esta gestionado por la fundación OPC Foundation. La aparición de este protocolo ha permitido una comunicación mas fácil entre los sistemas de control, sistemas SCADA, HMI, etc. con los sistemas de control, PLC’s.

SOLUCIOPC

En un principio este estándar se basó en la tecnología de Microsoft, Este, se baso en la tecnologia OLE, que emplea el formato COM/DCOM, que Micorosft desarrolo para el intercambio de innfomarcion entre aplicaciones y sistemas, como es normal, pero con el traspaso de la gestión a la fundación, esta ha impulsado un sistema libre, sin basarse en ninguna tecnología propietaria.

Por eso en la actualidad, con la versión UA, se puede encontrar desarrollos de sistemas OPC para cualquier sistema, ya se Windows, Linux, OsX, etc. Aunque el sistema principal, y el que dispone de un mayor catalogo de productos para el desarrollo sigue siendo Windows. Esto es debido en parte utilización de este sistema por parte de la industria de equipos industriales.

RTEmagicC_oemgatewayproxy_08.png

En la actualidad podemos encontrar librerías para el desarrollo para cualquier sistema, .Net, Python, Java, etc.

 

 

Crear gráficos de datos en c#

graph_fixed_x_rangeLa mejor formar de ver y entender los datos que capturamos desde nuestros sensores, es mediante la utilización de gráficos.

Si trabajamos con C# esta tarea es relativamente sencilla, gracias al controlador que por defecto trae el Visual C#. Este controlador nos permite crear gráficos de diferentes formas, de lineas, tarta, columnas,  puntos, etc.

Los datos se los podemos facilitar tanto en tiempo real añadiéndolos directamente los valores al gráfico, o mediante una base de datos.

Para añadir el gráfico a nuestro formulario solo tendremos que añadir el controlador “Chart” que se encuentra dentro de la sección “Datos”.

Con esto, ya podríamos empezar a mostrar nuestros datos, el tipo de gráfico por defecto es un gráfico de columnas. para añadir los datos solo tendríamos que utilizar el siguiente comando.

chart1.Series[0].Points.addXY(ValorX, ValorY);

Pero el sistema de gráficos de columnas no es que sea el más idóneo para mostrar la información de sensores, lo normal sera utilizar un gráfico de lineas, para cambiar el tipo de gráficos tendremos que ir  a:

  1. Propiedades del gráfico
  2. Series, Seleccionar la serie que queremos modificar (por defecto “Series1”.
  3.   En la sección “Gráfico”, en “ChartType”, seleccionar el tipo de gráfico.
  4.  Pulsar en “Aceptar”, y listo ya tenemos cambiado nuestro tipo de gráfico.

Si lo queremos hacer mediante código, tendremos que introducir la siguiente instrucción:

chart1.Series["Series1"].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;

En la parte de “Series[“Series1″]”, en este caso hacemos la llamada utilizando el nombre de la serie, en este caso es el de por defecto “Series1”, también podemos hacer la llamada utilizando su posición en la lista de las series, acordándose que toda lista empiezan en el “0” (cero). Esto “Series[“Series1″]”, y esto “Series[0]”, seria lo mismo.

Y con esto ya tendríamos creado nuestro gráfico y seleccionado el tipo de gráfico para la muestra de datos básica, pero funcional.

Ejemplo simple de lo descrito en el artículo, ejemplo creado con Visual Studio Express 2012:

Como mandar un correo mediante Python

Enviar correo con Python y Gmail
Enviar correos mediante smtplib de python y una cuenta de gmail

En algunas ocasiones necesito enviar los resultados que me devuelve el arduino a mi teléfono para avisarme de alguna anomalía. Lo primero que se le viene a la cabeza a uno es hacer un programa para el móvil para recibir los datos, ahora que se ha puesto de moda hacer “app’s” para todo ( ya no son programas o aplicaciones ahora son “app’s”).

Pero yo no necesito un programa que me este ocupando espacio y memoria en el teléfono para recibir una alerta una vez al mes a lo sumo. Aprovechando que el “android” te pide una dirección de correo para poder acceder a “Google Play” y que además, esta en todo momento mirando el contenido de esa cuenta, lo mas fácil es que el arduino mande un correo a esa cuenta.  Por ello le he implementado una opción al programa que gestiona el arduino para que me mande el correo.

Para poder enviar un correo a través de Python, lenguaje con el que gestiono el arduino,  solo tenemos que hacer uso de la librería “smtplib”, esta librería nos proporciona todas la funciones necesarias para poder enviar el correo.

Lo primero que haremos el importar la función desde la librería.

from smtplib import SMTP

Una vez que ya podemos utilizar la librería, creamos la variable que gestionara el envío.

EnviarCorreo = SMTP()

Nos conectamos al servidor de correo saliente de gmail, smtp.gmail.com que esta a la escucha en el puerto 587, para utilizar cualquier otro servidor tendremos que cambiar el servidor y el puerto por el que este escuchando.

EnviarCorreo.connect("smtp.gmail.com", 587)

El servidor de gmail necesita que habilitemos el modo TTL, esto es uno de los métodos de enviar el correo de forma segura, el otro modo seria utilizar SSL.

EnviarCorreo.starttls()

Esto me ha dado problemas algunas veces, buscando por internet he visto que varia gente utiliza esta forma para activar el TTL.

EnviarCorreo.ehlo()
EnviarCorreo.starttls()
EnviarCorreo.ehlo()

Lo que hace la función “.ehlo()” es decirle a “EnviarCorreo” que se ponga en modo de enviar un correo. Es decir, ponemos la función en modo de enviar correo, le decimos que vamos ha enviar el correo utilizando TTL, y volvemos a indicarle que se vuelva poner modo de enviar un correo, esta vez, si para enviar el correo.

Antes de enviar el correo, nos identificamos en el servidor de la siguiente forma.

EnviarCorreo.login(usuario@gmail.com, contraseña_de_la_cuenta)

Ahora solo nos queda montar el correo que queremos enviar. Para ello tenemos que crear tanto la cabecera del mensaje, donde ira la dirección de quien lo envía, la dirección de quien lo recibe, el asunto del mensaje, y demás información que podemos incluir en la cabecera, y por ultimo crear el cuerpo del mensaje.

Cabecera = 'To:' + Direccion_Desti + '\n'      
Cabecera += 'From: ' + Direccion_Remi + '\n'
Cabecera += 'Subject: ' + Asunto_Mensaje + '\n'+'\n'

Esta seria una cabecera básica, al final del cuerpo incluimos dos saltos de linea, porque? no lo se aun.

Para crear el cuerpo solo tenemos que pasar el contenido del mensaje a una variable del tipo string.

CuerpoMensaje = "Esto es el cuerpo del mensaje" + '\n' + '\n'

Como en la cabecera, terminamos el cuerpo del mensaje con dos salto de linea, la explicación no la se todavía.

Y ya tenemos todo listo para enviar el correo.

EnviarCorreo.sendmail(Direccion_Remi, Direccion_Desti, Cabecera + CuerpoMensaje)

Y con esto, y si todo esta bien, ya hemos enviado el correo. Ahora solo nos queda cerrar la comunicación con el servidor SMTP.

smtpserver.close()

Y listo, ya hemos mando la alerta a nuestro teléfono móvil, y sin tener que instalar ninguna aplicación nueva y sin tener que hacer nada en el teléfono.

Que te ha parecido?

 

Temperatura con Arduino, DHT11 y python (II)

modulo-sensor-de-tempertura-y-humedad-dht11-para-arduino_MEC-O-3277967849_102012Una vez que ya hemos hecho que nuestro arduino nos “hable”, ya solo nos queda “escuchar” lo que nos dice. Para ello vamos a utilizar Python para obtener la temperatura con Arduino.

Lo primero que tenemos que hacer es conectarnos con nuestro arduino (Arduino Uno R3), para ello, lo primero que haremos es descubrir en que puerto esta conectado nuestro arduino, este método esta explicado en un por anterior, así que no me detendré el ello.

Temperatura con Arduino

Una vez que ya sabemos en que puerto esta el arduino, pasamos a leer los datos que nos esta trasmitiendo. para la lectura de estos datos utilizaremos la librería PySerial. como con la búsqueda de puerto del arduino, ya esta explicado en otro post, por lo que tampoco me detendré en ello. Como siga así no explico nada :-).

Bueno, ahora es cuando llega la hora de saber lo que nos dice nuestro arduino. Como ya dije en la otra parte de este post, lo que nos envía el arduino es un registro formateado con los datos que nosotros queremos, por lo que solo tendremos que dividir el registro leído en los diferentes campos en que se compone el registro.

Cuando leamos el registro lo primero que hacemos es comprobar que el registro esta completo. Esto lo hago comprobando que los últimos caracteres del registros son los que establecimos como final de este “|f|” y que la longitud es la que definimos.

if sArduino.endswith("|f|") and len(sArduino) == cTamanoRegistro:

Si todo esta bien, pasamos a trocear el registro, si esta mal, pasamos de los datos leídos y volvemos a leer un nuevo registro. Si el sistema fuera para el control de sistemas críticos, este método no nos valdría, debido a la perdida de datos. Para mi caso me sobra, ya que esto va ha controlar la temperatura y humedad de un invernadero.

Para dividir el registro utilizamos el carácter que hemos utilizado en el arduino como separador de campos, en mi caso el carácter “|”, y el numero de campos de que consta nuestro registro, en mi proyecto 2, uno para la temperatura y otro para la humedad (Módulo de Sensor de Humedad Módulo de Temperatura Digital). Y lo guardamos en sus correspondientes variables. El resto del registro lo podemos guardar en una variable temporal, pero hay que pasarle una variable, sino, nos daría error.

sHumedad, sTemp, sFin = sArduino.split("|", 2)

Con esto ya tenemos nuestro campos guardados en sus respectivas variables para poder procesarlas como queramos. Y ya esta, hemos escuchado al arduino y sabemos lo que nos esta diciendo.

Este es el proceso completo que he utilizado.

# Abrimos el puerto del arduino a 9600
    PuertoSerie = serial.Serial(str(self.pPuerto), 9600)
    PuertoSerie.timeout = 1 

    while not self.Terminar:
        sArduino = PuertoSerie.read(PuertoSerie.inWaiting())
	time.sleep(1)

	# leemos hasta que encontarmos el final de linea
	sArduino = PuertoSerie.readline()
	sArduino = sArduino.strip()

	if sArduino.endswith("|f|") and len(sArduino) == cTamanoRegistro:
	# Separamos los datos recibidos mediante el seprador "|"
	sHumedad, sTemp, sFin = sArduino.split("|", 2) 
	global tTempMax
	global tTempMin

	global tHumeMax
	global tHumeMin

	if int(sTemp) > tTempMax: 
            tTempMax = int(sTemp)
	if int(sTemp) < tTempMin:
	    tTempMin = int(sTemp)

	if int(sHumedad) > tHumeMax:
	    tHumeMax = int(sHumedad)
	if int(sHumedad) < tHumeMin:
	    tHumeMin = int(sHumedad)

    else:
        PuertoSerie.close()
        time.sleep(5)

Y esto es todo para obtener la temperatura con Arduino, si tienes alguna duda, o si ves que se puede mejorar, que se puede mejorar y mucho, no te cortes y deja tu comentario.

Temperatura con Arduino, sensor DHT11 y python (I)

modulo-sensor-de-tempertura-y-humedad-dht11-para-arduino_MEC-O-3277967849_102012El sensor DHT11 (Módulo de Sensor de Humedad Módulo de Temperatura Digital), y sus variantes, es uno de los sensores más fáciles de manejar para obtener la temperatura con arduino. Gracias a la librería disponible para el, solo tenemos que pedir la temperatura o la humedad y ya la tenemos, sin hacer ninguna otra operación.

Materiales usados

Arduino UNO Arduino UNO
 Sensor DHT 11 Sensor DHT11
protoboard Protoboard
cables_union Cables de conexión

Sensor DHT11

Para conectarlo al arduino es muy sencillo, alimentamos el pin vcc, primero por la izquierda, con 5v desde unos de los pines del arduino, conectamos la masa al más a la derecha, y desde un pin analogico del arduino al 2 pin del sensor, empezando por la izquierda, el 3 pin no hay que conectarlo a nada.

Montaje de un sensor DHT11 en una placa Arduino UNO
Montaje de un sensor DHT11 en una placa Arduino UNO

El código como he dicho antes es muy fácil gracias a la librería existente, solo tenemos que inicializar una variable que nos permita manejar en sensor y poco mas.

Importamos la libreria

#include <DHT.h>

Inicializamos la variable para manejar el sensor DHT11

#define DHTPIN A0     // Indicamos el pin donde conectaremos la patilla data de nuestro sensor DHT11

#define DHTTYPE DHT11   // modelo del sensor que vamos a usar DHT 11 

// Inicializamos la variable
DHT dht(DHTPIN, DHTTYPE);  //Indica el pin con el que trabajamos y el tipo de sensor

Ahora solo tenemos que leer los datos del sensor DHT11 tanto de temperatura como de humedad de la siguiente forma

int iHumedad = dht.readHumidity();  // Guarda la humedad en iHumedad
int iTemepratura = dht.readTemperature(); // guarda la temepratura en iTemperatura

y con esto ya tendríamos tanto el % de la humedad con los grados de temperatura en la escala Celsius.

Pero ahora me queda mandar la información por el puerto serie para luego poderla leer en python.

Para esto creo un registro de 30 caracteres formateado, donde incluyo los dos valores leídos, una cadena variable de caracteres para ajustar la longitud del registro, un carácter separador de los campos “|”  y un campo “|f|” indicando que es el final del registro. quedando de la siguiente forma

HH|TT|XXXXXXXXXXXXXXXXXXXXX|f|

  1. HH seria el valor de la humedad, puede ser 1 0 2 caracteres dependiendo de la humedad que haya.
  2. TT valor de la temperatura, como la humedad el tamaño de este campo puede ser de 1 o 2 caracteres.
  3. X cadena variable, que dependiendo de la longitud de humedad o temperatura puede variar su longitud.
  4. |f| indica que es el final del registro. Para comprobar luego mediante python, que hemos leído correctamente la información enviada.

Si queremos enviar mas información solo tenemos que añadirla incluyendo los separadores. El tamaño del registro lo he establecido en 30 caracteres pero lo podemos variar cambiando la configuración del programa.

// Tamaño del registro a enviar al puerto serie 
int iTamanoCadena = 30;

Y el código seria el siguiente

    // añadimos la humedad y la temperatura, añadiendo al final de cada uno el caracter "|" 
    sResultado = String(h) + "|" + String(t) + "|";
    sEspacios = "";
    / Calculamos cuantos espacios tenemos que crear
    // Le restamos 3 que es el tamaño del campo final
    if (sResultado.length() < (iTamanoCadena - 3))
    {      
      // Creamos la cadena
      for (iContador = 0; iContador < ((iTamanoCadena - 3) - sResultado.length()); iContador ++)
      {
        // le añadimos el caracter que queramos, no vale para nada
        sEspacios += "X";
      }
    }
    // Añadimos el campo de fin de registro
    sResultado = sResultado + sEspacios + "|f|";
    // lo enviamos al puerto serie
    Serial.println(sResultado);
  }

Y con esto ya hemos leído la temperatura y la humedad desde el sensor DHT11 (Módulo de Sensor de Humedad Módulo de Temperatura Digital), y enviada al puerto serie para ser leída por nuestro programa en python.

Código completo.

#include <DHT.h>

#define DHTPIN A0     // Indicamos el pin donde conectaremos la patilla data de nuestro sensor

// Descomenta el tipo de sensor que vas a emplear. En este caso usamos el DHT11
#define DHTTYPE DHT11   // DHT 11 
//#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

// Conecta el pin 1 (el de la izquierda) del sensor a +5V
// Conecta el pin 2 del sensor al pin que has elegido para DHTPIN
// Conecta el pin 4 (el de la derecha) del sensor a GROUND

DHT dht11(DHTPIN, DHTTYPE);  // indicamos en que pin esta conectado el data, y el tipo de sensor

String sResultado, sEspacios;
int iContador;
int iTamanoCadena = 30;

void setup() 
{
  //Inicio comunicacion serie para ver los datos en el ordenador
  Serial.begin(9600); 
  //Iniciamos el sensor
  dht11.begin();
}

void loop() 
{
  int iHumedad = dht11.readHumidity();  //Guarda la lectura de la humedad
  int iTemperatura = dht11.readTemperature();  //Guarda la lectura de la temperatura

  // Comprobamos si lo que devuelve el sensor es valido, si no son numeros algo esta fallando
  if (isnan(iHumedad) || isnan(iTemperatura)) // funcion que comprueba si son numeros las variables indicadas 
  {
    Serial.println("Fallo al leer del sensor DHT 11"); //Mostramos mensaje de fallo si no son numeros
  } 
  else 
  {
    // añadimos la humedad y la temperatura, añadiendo al final de cada uno el caracter "|" 
    sResultado = String(iHumedad) + "|" + String(iTemperatura) + "|";
    sEspacios = "";
    // Calculamos cuantos espacios tenemos que crear
    // Le restamos 3 que es el tamaño del campo final
    if (sResultado.length() < (iTamanoCadena - 3))
    {      
      // Creamos la cadena
      for (iContador = 0; iContador < ((iTamanoCadena - 3) - sResultado.length()); iContador ++)
      {
        // le añadimos el caracter que queramos, no vale para nada
        sEspacios += "X";
      }
    }
    // Añadimos el campo de fin de registro
    sResultado = sResultado + sEspacios + "|f|";
    // lo enviamos al puerto serie
    Serial.println(sResultado);
  }
  // y esperamos 1 segundo para volver a leer los datos del sensor.
  delay(1000);
}

Y con eso terminamos la primera entrega. en la segunda, la lectura de los datos en Python.