Objetivos
Material requerido
WIFI CC3000 |
El chip CC300 de Texas Instruments
No es la primera vez que comentábamos en estas páginas, el problema que la conexión WIFI suponía en el mundo Arduino. Podíamos usar un modelo como el YUN, que no está mal, pero que cuesta 70€ o podíamos adquirir un WIFI Shield cuyo precio no andaba muy lejos.
No he probado el WIFI Shield oficial de Arduino principalmente porque su precio siempre me ha parecido absurdo (Aunque sí que tengo un YUN del que hablaremos en algún momento) y por eso hicimos pruebas con módulos de bajo coste como el ESP8266 o el HLK-RM04.
Ambos módulos son muy interesantes de por sí, y permiten montar soluciones WIFI por muy poco dinero que nos resuelven la papeleta, pero que naturalmente, vienen con sus propios problemas o complicaciones, y para quienes siguen estas humildes paginas son ya viejos conocidos.
Por eso cuando Texas Instruments anunció que iba a presentar un chip llamado CC3000 que iba implementar el protocolo WIFI de modo nativo y además que lo iba a hacer por unos pocos dólares, a duras penas podíamos esperar a probarlo y ver qué resultado nos da.
Este chip está diseñado como base para la famosa IOT (Internet Of Things) y promete resolver todo el problema de comunicaciones WIFI de forma eficaz y barata. Está además, pensado para integrarse en multitud de entornos o productos incluyendo micro controladores y similares mediante SPI, así que iros apuntando el nombre, si no lo conocíais, porque va a aparecer hasta en la sopa (Literalmente)
Poco a poco, van apareciendo Shields WIFI para Arduino que incorporan el CC3000 a un precio mas razonable que los anteriores, y como yo acabo de recibir mi flamante Shield WIFI basado en este chip, vamos a probarlo a fondo para ver si es la solución que esperábamos en el mundo Arduino.
El Shield WIFI CC3000
El Shield que he recibido es una variante del de Adafruit que incluye además un lector de tarjetas micro SD y que se maneja mediante las Librerías CC3000 que han desarrollado los chicos de Adafruit, y a quienes nunca les daremos suficientemente las gracias.
El CC3000 usa SPI para comunicarse con el exterior (O sea nuestro Arduino, por ejemplo) y no UART (Que es la forma pedante de llamar a las puertas series: Universal Asynchronous Receiver-Transmitter) por lo que la velocidad no está determinada por una serie de velocidades prefijadas, y puede modificarse en función de las necesidades mediante el uso del bus SPI.
El CC3000 soporta 802.11b/g, open/WEP/WPA/WPA2 security, TKIP, and AES. Incorpora un stack TCP/IP complete tanto como cliente y como servidor, permitiendo un máximo de 4 conexiones concurrentes.
El CC3000 WIFI Shield es compatible con al menos los modelos de Arduino UNO, MEGA y Leonardo pero parece que no va a funcionar con mi favorito el DUE.
Características básicas del WIFI Shield
Consideraciones previas con WIFI Shield CC3000
Antes de que vayáis corriendo a conectar vuestros WIFI Shield os conviene saber que hay una serie de advertencias importantes a tener en cuenta.
La primera es que como ya viene siendo habitual en los módulos WIFI que hemos probado, el consumo de corriente de estos chips, CC30000 incluido, superan sobradamente la capacidad que Arduino puede proporcionar incluso conectado a través del USB
Recordad que el USB puede proporcionar un máximo de 500 mA y parece que esto no va ser suficiente, especialmente en los arranques, por lo que hay que usar un alimentador externo de al menos 600 o 700 mA
Por si acaso lo necesitáis en algún momento, este Shield, utiliza los siguientes pines:
CC3000 WIFI Shield | |||||||
---|---|---|---|---|---|---|---|
Señal | SCK | MISO | MOSI | CS CC3000 | VBAT_EN | CS SD | IRQ |
Pin | 13 | 12 | 11 | 10 | 5 | 4 | 3 |
En mi caso además, como estoy lejos de mi punto de acceso WIFI he usado una antena externa para mejorar la señal, aprovechando que el Shield dispone de un conector para ello.
Usando el WIFI Shield CC3000
Lo primero como siempre es descargar la librería Adafruit_CC3000_Library-master o bien descargarla de Github, e instalarla por el procedimiento habitual que ya tenemos bien conocido.
La librería de Adafruit incluye unos cuantos ejemplos extensos de uso, lo que resulta de agradecer, ya que dispone de muchos métodos internos y procedimientos que requieren una cierta explicación.
Y uno de esos ejemplos se llama buildtest y es el que nos recomiendan correr primero, para ir cogiendo confianza al Shield, y nosotros vamos a hacer esto obedientemente, aunque voy a presentaros aquí, una versión reducida del mismo, para que podamos ir describiendo la forma de usar las librerías.
Como siempre empezamos incluyendo las librerías necesarias, y algunos defines para establecer los pines de control: Prog_110_1
#include <Adafruit_CC3000.h> #include <SPI.h> #define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin! #define ADAFRUIT_CC3000_VBAT 5 #define ADAFRUIT_CC3000_CS 10
Así, ya podemos crear una instancia de la controladora del CC3000:
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, SPI_CLOCK_DIVIDER);
Como vamos a conectarnos a una red WIFI necesitamos saber el nombre SSID de la red y una contraseña válida, que necesitamos definir aquí:
#define WLAN_SSID "charly" // Maximo 32 caracteres! #define WLAN_PASS "contrase" #define WLAN_SECURITY WLAN_SEC_WPA2
Yo estoy usando seguridad WP2, pero también están disponibles otros modos:
WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
Tenemos ahora que inicializar el chip WIFI mediante cc3000.begin() y comprobar que ha sido correcto:
Serial.begin(115200); Serial.println("Buscando CC3000!"); Serial.print("Inicializando CC3000 ..."); if (!cc3000.begin()) { Serial.println("\nImposible inicializar el CC3000!" ); Serial.flush(); exit(0); }
En caso negativo, forzamos un mensaje de error y salimos del programa, y si hemos tenido éxito, buscamos un listado de redes WIFI disponibles mediante:
listSSIDResults();
Esta funcion, simplemente busca e imprime las redes disponibles, más o menos encolumnadas, mediante la función cc3000.startSSIDscan(), y no creo que tengáis problema en seguir su código que es auto explicativo.
El chip recuerda los últimos datos de conexión obtenidos a una red, por lo que si ya se ha conectado previamente no sería necesario solicitar una nueva dirección, pero como esto es un tutorial vamos a hacer una primera conexión limpia a modo de ejemplo.
El manual del CC3000 recomienda que antes de conectar a una red, limpiemos los datos de las conexiones previas, por lo que nosotros que somos muy ordenaditos (Si, da asco) vamos a hacerlo así mediante:
Serial.println("Limpiando datos de conexiones previas"); cc3000.deleteProfiles();
Y ahora tenemos que reconectar, claro, mediante la función cc3000.connectToAP, para enganchar con el punto de acceso especificado en ssid:
char *ssid = WLAN_SSID; /* Max 32 chars */ Serial.println("Intentando conectar a "); Serial.print(ssid); if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) { Serial.println("Imposible conectar.."); Serial.flush(); exit(0); } Serial.print("...OK.\nConectado. Esperando DHCP...");
Si no podemos, lanzamos un mensaje de error y largo del programa que no tiene sentido seguir. En caso de éxito, vamos a solicitar al DHCP del chip unos datos de conexión, y eso va a requerir algo de tiempo, por lo que hay que esperar al resultado.
Si todo va bien, llamamos a la función displayConnectionDetails() para imprimir la IP asignada así como los DNSs y demás.
Serial.print("...OK.\nConectado. Esperando DHCP..."); while (!cc3000.checkDHCP()) delay(100); // ToDo: Insert a DHCP timeout! Serial.println("OK."); while (! displayConnectionDetails()) delay(1000);
Por último, el manual recomienda cerrar la sesión al acabar so pena de que el CC3000 se lie la próxima vez que conectemos (Yo solo os digo lo que hay)
Serial.println("\nCerrando la conexion")); cc3000.disconnect();
La función cc3000.getIPAddress() en la que se basa displayConnectionDetails, utiliza el DHCP para conseguir los valores necesarios de conexión y el resto de la función simplemente imprime esos valores de forma legible en la consola.
cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv)
Usando una dirección IP estática en lugar de DHCP
Naturalmente podemos usar una IP estática a mano, en lugar de usar el DHCP, y para ello podríamos usar un código como este:
uint32_t ipAddress = cc3000.IP2U32(192, 168, 1, 19); uint32_t netMask = cc3000.IP2U32(255, 255, 255, 0); uint32_t defaultGateway = cc3000.IP2U32(192, 168, 1, 1); uint32_t dns = cc3000.IP2U32(8, 8, 4, 4); if (!cc3000.setStaticIPAddress(ipAddress, netMask, defaultGateway, dns)) { Serial.println(F("Failed to set static IP!")); Serial.flush(); Exit(0); } else Serial.println(“IP asignada con éxito”);
Si corréis este código en el Shield WIFI obtendréis una salida similar a esta:
En la proxima sesion seguiremos jugando con este shield que promete bastante.
Resumen de la sesión