Arduino 101: (IoT) Servidor Telnet con Arduino y Adafruit Wifi Shield CC3000

Hoy en este tutorial de Arduino 101, voy a enseñar a utilizar un servidor Telnet para comunicarnos desde computadores, macs, smartphones Android y iPhone con nuestro Arduino, de una manera sencilla y fácilmente personalizable, gracias a la comunicación Telnet, un wifi Shield CC3000 de Adafruit y Arduino.

Para seguir este tutorial necesitaremos:

El sensor puede ser lo cualquier cosa, lo único que queremos es tener una señal que mandar. Podríamos generar números aleatorios y enviarlos, aunque ya que vamos a realizar este proyecto, que tenga utilidad.

En primer lugar, el protocolo telnet:

Telnet (TELecommunication NETwork) es el nombre de un protocolo de red que nos permite viajar a otra máquina para manejarla remotamente como si estuviéramos sentados delante de ella. También es el nombre del programa informático que implementa el cliente. Para que la conexión funcione, como en todos los servicios de Internet, la máquina a la que se acceda debe tener un programa especial que reciba y gestione las conexiones. El puerto que se utiliza generalmente es el 23. Wikipedia

Como se comenta en wikipedia, tiene algunos problemas en comparación con otros sistemas avanzados, pero puesto que nosotros lo queremos para realizar una comunicación en red local con Arduino no le daremos importancia.

Para implementar el protocolo Telnet con el Shield Wifi CC3000 de Adafruit, tendremos que soldar la placa siguiendo las indicaciones recomendadas en la guía de Adafruit para cada modelo. Si utilizáis la placa IcsStation Uno R3 de nuestro patrocinador, tendréis que soldar siguiendo las instrucciones correspondientes a Arduino Mega, puesto que tiene conector ICSP. Tenemos que bajar e instalar la librería incluida en dicha guía.

Una vez que ya tenemos listos los preparativos, montaremos el circuito siguiendo lo explicado en el tutorial de Sensor de Temperatura, proporcionado por ComponentesOnline.es.

Ahora veremos el código, en el que enviaremos, a petición del usuario, la temperatura medida por el sensor y controlaremos el estado de un LED:

#include <Adafruit_CC3000.h>
#include <SPI.h>
#include "utility/debug.h"
#include "utility/socket.h"

// These are the interrupt and control pins
#define ADAFRUIT_CC3000_IRQ   3  // MUST be an interrupt pin!
// These can be any two pins
#define ADAFRUIT_CC3000_VBAT  5
#define ADAFRUIT_CC3000_CS    10
// Use hardware SPI for the remaining pins
// On an UNO, SCK = 13, MISO = 12, and MOSI = 11
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
                         SPI_CLOCK_DIV2); // you can change this clock speed

#define WLAN_SSID       "SSID WIFI"           // cannot be longer than 32 characters!
#define WLAN_PASS       "PASS WIFI"
// Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
#define WLAN_SECURITY   WLAN_SEC_WPA2

#define LISTEN_PORT           7    // What TCP port to listen on for connections.  The echo protocol uses port 7.

Adafruit_CC3000_Server server(LISTEN_PORT);

int pinLed = 6, pinTemp = A5;
float temp;

uint8_t ch;
void setup(void)
{

  pinMode(pinLed, OUTPUT);
  pinMode(pinTemp, INPUT);
  digitalWrite(pinLed, HIGH);
  delay(500);
  digitalWrite(pinLed, LOW);

  Serial.begin(115200);

  /* Initialise the module */
  Serial.println(F("nInitializing..."));
  if (!cc3000.begin())
  {
    Serial.println(F("Couldn't begin()! Check your wiring?"));
    while (1);
  }

  if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) {
    Serial.println(F("Failed!"));
    while (1);
  }

  Serial.println(F("Connected!"));

  Serial.println(F("Request DHCP"));
  while (!cc3000.checkDHCP())
  {
    delay(100); // ToDo: Insert a DHCP timeout!
  }

  /* Display the IP address DNS, Gateway, etc. */
  while (! displayConnectionDetails()) {
    delay(1000);
  }

  // Start listening for connections
  server.begin();

  Serial.println(F("Listening for connections..."));
}

void loop() {

  temp = temperatura();

  // Try to get a client which is connected.
  Adafruit_CC3000_ClientRef client = server.available();
  if (client) {
    // Check if there is data available to read.
    if (client.available() > 0) {
      // Read a byte and write it to all clients.
      ch = client.read();

      switch (ch) {
        case '?':
          client.print(">La temperatura es:");
          client.print(temp);
          client.println(" C");
          break;

        case 'l':
        Serial.println("l");
          if (digitalRead(pinLed) == HIGH) {
            Serial.println("High to LOW");
            digitalWrite(pinLed, LOW);
          } else {
            Serial.println("LOW to HIgh");
            digitalWrite(pinLed, HIGH);
          }
          break;

      }
    }
  }
}
bool displayConnectionDetails(void)
{
  uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv;

  if (!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv))
  {
    Serial.println(F("Unable to retrieve the IP Address!rn"));
    return false;
  }
  else
  {
    Serial.print(F("nIP Addr: ")); cc3000.printIPdotsRev(ipAddress);
    Serial.print(F("nNetmask: ")); cc3000.printIPdotsRev(netmask);
    Serial.print(F("nGateway: ")); cc3000.printIPdotsRev(gateway);
    Serial.print(F("nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv);
    Serial.print(F("nDNSserv: ")); cc3000.printIPdotsRev(dnsserv);
    Serial.println();
    return true;
  }
}

float temperatura() {

  float Vout;
  float res = 0.010; // en V/ºC

  Vout = analogRead(pinTemp) * 0.00488758553275; // step * V/step = V
  temp = (Vout / res ) - 2.5; // V/(V/ºC) = ºC
  return temp;

}

Y como siempre, a continuación tenéis una explicación detallada en vídeo del proyecto:

¡Hasta la próxima sesión! Recordad que podéis ver todos los tutoriales de Arduino en la categoría tutoriales o bajo el tag Arduino 101.

20 comentarios


  1. Me intereso mucho tu post y quisiera saber mas sobre unas cosas de la shiel:) espero comunicarme contigo muy bueno por cierto

    Responder

    1. Hola, gracias por tu comentario. Puedes encontrar más información suscribiendote a la web o siguiendonos en las redes sociales. Tengo planeados algunos tutoriales más utilizando el cc3000

      Responder

  2. Hola que tal, quisiera saber si me puedo conectar desde mi pc al servidor telnet pero por medio del cmd de windows, y si es asi como se hace? gracias, saludos.

    Responder

    1. ¡Hola!

      No tengo ningún ordenador con Windows al que pueda acceder en este momento, por lo que no puedo darte una respuesta segura al 100% pero según tengo entendido, a traves de cmd en windows no se puede acceder al servidor telnet, tendrías que descargar un programa que tenga esa característica. El único programa del que tengo conocimiento que permite utilizar telnet en windows es Putty, puedes descargarlo desde aquí: http://www.chiark.greenend.org.uk/~sgtatham/putty/

      Por otra parte, hay multitud de clientes para smartphones y tablets, tanto basadas en Android como en iOS.

      Si tienes cualquier otra problema no dudes en preguntar.

      ¡Saludos!

      Responder

      1. Gracias por tu respuesta, ya lo logre hacer en windows, solo tuve que activar el servicio de telnet dese el panel de control para poder usarlo en cmd.

        Responder

          1. Que tal, en esta coneccion, que dispositivo toma el papel de servidor y cual el de server? Hablando del Shield y el ordenador, ya que quiero implementar este programa para mandar datos desde una aplicación de Visual C# hacia el arduino.

            Responder

          2. Otra pregunta…
            En todos los ejemplos de servidores telnet que encuentro en la red, utilizan un usuario y contrasena para acceder, por que en este ejemplo no e usa?

            Responder

            1. Hola, el servidor es Arduino y el Wifi shield, y el cliente es desde donde te conectas. En cuanto al usuario y la contraseña, no utilicé este método para simplicar el conjunto, pero puedes pedir una autentificación y si el usuario y la contraseña coinciden, puedes dar acceso al resto de la información en el código.

              ¡Un saludo!

              Responder

  3. Disculpa, sabes alguna forma de que el arduino avise que se perdio la conexion con el modem?

    Responder

  4. Buenas tardes,
    Tengo la shield cc3000 desde hace un tiempo la hago funcionar, sin embargo depues de una hora de estar funcionando la shield se queda completamente bloqueada y solo puedo volver a seguir haciendo cosas con ella reiniciandola, ¿alguien sabe a que puede deberse?
    Gracias de antemano.

    Responder

    1. Hola Alan,

      Yo también he sufrido ese problema y no he encontrado ninguna solución buena. Al final lo que hice fue resetear por software Arduino cada cierto tiempo (además de hacer que tuviera siempre la misma IP para que fuera más fácil acceder)

      Un saludo.

      Responder

      1. Buenas tardes Luis tenia la intencion de hacer un proyecto domotico con esta shield y se me esta haciendo muy difícil si pudieras ayudarme te lo agradecería

        Responder

  5. El problema es el tema del bloqueo he estado viendo lo del reset por software
    #define RESTART asm(“jmp 0x0000”)
    y ahora puede usar el macro RESTART; en tu código.
    Imagino que es esto lo que tu usas. No hay ningun modo de que con este shield no se quede bloqueado al tiempo? Yo quiero tenerlo conectado todo el tiempo y se apaguen y enciendan las luces cuando no estoy en casa. Lo de la ip fija como lo hiciste mirando en la web de adafruit vi un codigo para poner fija la ip pero no consegui hacerlo funcionar en mi shield. Gracias por contestar.

    Responder

    1. Hola, Si necesitas que se enciendan y apaguen las luces no te hace falta para nada el wifi shield, simplemente con un rtc puedes solucionarlo.

      Llevo mucho sin trabajar con el wifi shield, por lo que no puedo confirmarte que haya mejoras en el código o firmware.

      un saludo

      Responder

  6. Hola Luis,
    Gran post. Me gustaría saber si es posible servir imagenes guardadas en la tarjeta SD del wifi shield y como hacer referencia a ellas en el código html.
    Muchas gracias

    Responder

    1. Hola Rodrigo,

      Me parece bastante complejo hacer lo que comentas. Puedes utilizar el código normal que esté para acceder a datos desde la sd e intentar combinarlo con el código del servidor web.

      Por otra parte, el wifi shield cuando trabajé con el no tenía la posibilidad de hacer de servidor para webs.

      Un saludo.

      Responder

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *