Puerto Serie

Se usa para la comunicación entre la placa Arduino y una computadora u otros dispositivos. Todas las placas Arduino tienen al menos un puerto serie (también conocido como UART). La comunicación es vía los pines digitales 0 (Rx) y 1 (Tx), así como con la computadora a través de USB. Por lo tanto, si requiere usar USB no puede usar los pines 0 y 1 para entrada o salida digital. Puede usar el monitor serie integrado del entorno Arduino para comunicarse con una placa Arduino. Haga clic en el botón del monitor de serie en la barra de herramientas y seleccione la misma velocidad en baudios.

En el IDE hay una pantalla que se llama el Monitor serie donde se puede hacer que Arduino escriba cosas (vía Serial.print() o Serial.write()), pero también se puede enviar datos hacia Arduino (desde la primera linea) que luego se puede capturar en Arduino con Serial.read().

La comunicación serial en los pines Tx / Rx usa niveles lógicos TTL (5V o 3.3V dependiendo de la placa). No conecte estos pines directamente a un puerto serial RS232; funcionan a +/- 12V y pueden dañar su placa Arduino.

1. Serial.begin()

Abre el puerto serie y fija la velocidad en baudios para la transmisión de datos en serie. El valor típico de velocidad para comunicarse con una computadora es 9600, aunque otras velocidades pueden ser soportadas: 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600 o 115200.

No obstante, puede especificar otras velocidad de comunicación a través de los pines 0 y 1, por ejemplo con un componente que requiere una velocidad en baudios particular.

El valor predeterminado es 8N1 (8 bits de datos, sin paridad, un bit de parada). Pero con este parámetros se pueden configurar otras opciones.

Configuración serie
CódigoDatosParidadParada
5N15Sin1
6N16
7N17
8N18
5N252
6N26
8N28
5E15Con1
6E16
7E17
8E18
5E252
6E26
8E28
void setup(){
	Serial.begin(baudios [, configuracion]);
}

Cuando se usa la comunicación serie los puertos digital 0 (RX) y 1 (TX) no puede usarse al mismo tiempo.

Luego de iniciar la comunicación es posible comprobar si existe el puerto serie que devolverá una verdadero o falso según el caso.

void setup(){
	Serial.begin(9600);
   while (!Serial){
      ;   //Espera a que se conecte el pueto serie. Necesario para USB nativo
   }
}

2. Serial.available()

Obtiene un número entero con el número de bytes (caracteres) disponibles para leer o capturar desde el puerto serie. Equivaldría a la función serialAvailable(). Se usa para vigilar si el usuario ingreso datos.

byte lee;
if (Serial.available()){
	lee = Serial.read();
	Serial.print(lee, DEC); //Imprime el ASCCI de lo que se recibió
}

Recuerde que 0 es sinonimo de falso y cualquier otro numero es verdadero.

Vea serialEvent() que es mas eficiente.

3. Serial.availableForWrite()

Obtenga la cantidad de bytes (caracteres) disponibles para escribir en el búfer en serie sin bloquear la operación de escritura.

if (Serial.availableForWrite()){};

4. Serial.print(data [, data type])

Vuelca o envía un dato (número o cadena), al puerto serie. Dicho comando puede tomar diferentes formas, dependiendo de los parámetros que usemos para definir el formato de volcado de los datos.

Serial.print(val [,formato]);

data type: determina el formato de salida de los valores numéricos (decimal, octal, binario, etc...) DEC (default), OCT, BIN, HEX, BYTE, si no especifica nada vuelve un valor ASCII en decimal.

Serial.print("Hola");
Serial.print(analogRead(A0));
Serial.print("\t Azul:");
Serial.print('A', HEX); //41
Caracteres de control
CódigoASCII HexDescripción
\r0DRetorno de carro (CR = 13)
\n0ASalto de linea (LF = 10)
\t09Tab (Tab = 9)
int b = 79;
Serial.print(b); //Imprime 79
Serial.print(b, HEX); //Imprime 4F
Serial.print(b, OCT); //Imprime 117
Serial.print(b, BIN); //Imprime 1001111

5. Serial.println()

Vuelca o envía un número o una cadena de carateres al puerto serie, seguido de un caracter de retorno de carro "CR" (ASCII 13, or '\r') y un carácter de salto de línea "LF"(ASCII 10, or '\n'). Toma la misma forma que el comando Serial.print()

Serial.println(val [,formato]);

Algunos ejemplos:

Serial.println(analogRead(0));
float n = 1.23456;
Serial.println(n); //Imprime 1.23456
Serial.println(n, 0); //Imprime 1
Serial.println(n, 2); //Imprime 1.23
Serial.println(n, 4); //Imprime 1.2345

6. Serial.Read()

Lee o captura un byte (un carácter) desde el puerto serie. Equivaldría a la función serialRead(). Devuelve: El siguiente byte (carácter) desde el puerto serie, o -1 si no hay ninguno.

7. Serial.readBytes()

Lee los caracteres del puerto serie en un búfer. La función finaliza si la longitud determinada se ha leído, o se agota (vea Serial.setTimeout()).

Serial.readBytes(buffer, largo);

8. Serial.readBytesUntil()

Lee los caracteres del búfer en serie en una matriz. La función finaliza si se detecta el carácter del terminador, si se ha leído la longitud determinada o se agota el tiempo de espera (vea Serial.setTimeout()). La función devuelve los caracteres hasta el último carácter antes del terminador suministrado. El terminador en sí no se devuelve en el búfer.

9. Serial.write()

Envia datos binarios al puerto serie. Esta información se envía como un byte o serie de bytes. Retorna el numero de bytes escritos.

Serial.write(val); //Valor como un solo byte.
Serial.write(str); //Cadena como una serie de bytes.
Serial.write(buf, len); //Matriz enviada como una serie de bytes.

Aqui algunos ejemplos.

Serial.write(65); //A
Serial.write('Hola mundo'); //Hola mundo
n = Serial.write('Hola mundo'); //Retorna el largo de cadena

Para enviar los caracteres que representan los dígitos de un número, use la función Serial.print() en su lugar.

10. Serial.peek()

Devuelve el siguiente byte (carácter) de los datos en serie entrantes sin eliminarlo del buffer serie interno. Es decir, las llamadas sucesivas a Serial.peek() devolverán el mismo carácter, al igual que la próxima llamada a Serial.read(). Serial.peek() hereda de la clase Stream. Si no hay dato disponible devuelve -1.

Serial.peek();

11. Serial.flush()

Espera a que se complete la transmisión de los datos en serie salientes.

Serial.flush();

12. Serial.find()

Lee datos del buffer serial hasta que se encuentra la cadena objetivo de longitud dada. La función devuelve verdadero si se encuentra la cadena objetivo, falsa si se agota el tiempo. Lo que devuelve es un boleano.

Serial.find(cadena);

13. Serial.findUntil()

Lee los datos del búfer en serie hasta que se encuentra una cadena de destino de longitud dada o cadena de terminación. La función devuelve verdadero si se encuentra la cadena objetivo, falso si se agota el tiempo. Lo que devuelve es un boleano.

Serial.findUntil(cadena_ini, cadena_fin);

14. Serial.parseInt()

Busca el siguiente número entero válido en la serie entrante stream.parseInt()hereda de la clase de utilidad Stream.

Serial.parseInt();

15. Serial.parseFloat()

Devuelve el primer número válido de punto flotante del búfer en serie. Los caracteres que no son dígitos (o el signo menos) se ignoran. parseFloat() es terminado por el primer carácter que no es un número de coma flotante.

Serial.parseFloat();

16. Serial.setTimeout()

Establece los milisegundos máximos para esperar datos en serie al usar: Serial.readBytes() o Serial.readBytesUntil(). Por defecto es 1000 milisegundos.

Serial.setTimeout();

17. serialEvent()

Llamado cuando los datos están disponibles en pin Rx. Use Serial.read() para capturar esos datos.

void serialEvent(){
	...
}

18. Serial.end()

Desactiva la comunicación serial, permitiendo que los pines RX y TX se usen para entrada y salida general. Para volver a habilitar la comunicación en serie, llame a Serial.begin().

Serial.end();

19. Ejemplos...

A continuación algunos ejemplos interesantes del uso del puerto serie para enviar datos hacia el Arduino.

19.1 Ejemplo 1

Recibir caracteres de manera directa y manipularlos.

void setup() {
   Serial.begin(115200);
   delay(100);
   while (!Serial){
	   ;
	}
   Serial.println("*** Estamos listo ***");
}

void loop() {
   if (Serial.available()){
      int ent = Serial.read();
      Serial.print("El caracter enviado fue: ");
      Serial.write(ent);
      Serial.print(" y su codigo ASCCI es: ");
      Serial.print(ent);
      Serial.print(" en HEXADECIMAL es: ");
      Serial.println(ent, HEX);
   }
}

Poner el monitor serie a 115200 o veras caracteres raros.

19.2 Ejemplo 2

Cuando llegan nuevos datos por el puerto serie, este boceto los concatena en una cadena llamada entrada. Cuando se recibe el salto de linea, se imprime la cadena y se borra su contenido. Es muy útil para un receptor GPS que envía códigos NMEA. La función de usuario serialEvent() ocurre cada vez que aparece una nueva información en el pin Rx. Múltiples bytes de datos pueden estar disponibles.

String entrada = "";       //String para guardar datos que llegan
boolean completo = false;  //Datos completos (fin de linea)

void setup() {
   Serial.begin(9600);
   entrada.reserve(200);
}

void loop() {
   if (completo) {
      Serial.println(entrada);
      entrada = "";
      completo = false;
   }
}

void serialEvent() {
   while (Serial.available()) {
      char caracter = (char)Serial.read();
      entrada += caracter;
      //Detectar fin de linea
      if (carater == '\n') {
         completo = true;
      }
   }
}