Comunicación con arduino en C++

No es muy complicado comunicar nuestra placa arduino mediante el puerto serial con C++ usando la librería LibSerial. Esta librería tiene una clase, SerialStream, que nos abstrae de la "complejidad" de la estructura termios. Para usarla es necesario instalarla. En Ubuntu lo podemos encontrar en los repositorios. Si no, aquí está el enlace: http://sourceforge.net/projects/libserial/files/

Instalación de la librería (en Ubuntu)

$ sudo apt-get install libserial-dev

API de LibSerial

En la siguiente URL, se encuentra el API bien documentada.

Ahora veremos cómo hacer las operaciones básicas (desde abrir el puerto, hasta la lectura/escritura).

Abrir un puerto
_________________________________________
#include <SerialStream.h>
SerialStream serial_port("/dev/ttyUSB0");
_________________________________________

Asignación de baudios
 _________________________________________
serial_port.SetBaudRate(SerialStreamBuf::BAUD_9600);
 _________________________________________

El ejemplo es para el caso de 9600 baudios (suele ser habitual). Pero asignarle otras (ver en este enlace). 

Número de bits a transmitir

Se hace con la llamada al método SetCharSize().
_________________________________________
serial_port.SetCharSize( SerialStreamBuf::CHAR_SIZE_8) ;
_________________________________________

CHAR_SIZE_X, la X puede variar entre 5 y 8

Lecturas y escrituras

//Escritura (mandar un dato)
char c;
cin >> c;
serial_port << c;

//Lectura: recibir un dato
char c;
serial_port >> c;

Ejemplo completo

/* 
   Author: Juan José Fumero Alfonso
   Date: Fri May  7 19:48:06 WEST 2010
   Note: To compile is necesary install libserial: Serial port 
         programming in C++ under POSIX operating system
            $ sudo apt-get install libserial-dev
   Doc : http://libserial.sourceforge.net/doxygen
   Compile:
     \_ $ g++ ejemplo.cpp -o ejemplo -lserial
*/

#include <iostream>
#include <string>
#include <unistd.h>
#include <SerialStream.h>

using namespace std;
using namespace LibSerial;

int main (int argc, char **argv) {

    int oc; 
    string dev;
    bool dsp = false;
    while ((oc = getopt(argc, argv, ":d:")) != -1) {
        switch(oc) {
            case 'd':
                //device
                cout << "Dispositivo: ";
                dev = optarg;
                cout << " :: " << dev << endl;
                dsp = true;
                break;
            case ':':
                cerr << "Missing argument " << endl;
                return -1;
                break;
        }
    }    
    
    if (!dsp) {
        dev = "/dev/ttyUSB0";
    }
    SerialStream serial_port(dev);
    serial_port.SetBaudRate(SerialStreamBuf::BAUD_9600);
    serial_port.SetCharSize( SerialStreamBuf::CHAR_SIZE_8);
    char num;
    while (1) {
        cout << "Number of blinks? : ";
        cin >> num;
        serial_port << num;
    }
    return 0;
}

Para probarlo, se puede hacer el típico ejemplo blink (conectando un LED al pin 13) y enviar un número entre 0 y 9 que indicará el número de parpadeos que debe realizar el LED en el arduino. El correspondiente código pde es el siguiente: (cogido de http://todbot.com/, aunque no es nada del otro mundo).

/*
 * Serial Read Blink
 * -----------------
 * Turns on and off a light emitting diode(LED) connected to digital  
 * pin 13. The LED will blink the number of times given by a 
 * single-digit ASCII number read from the serial port.
 *
 * Created 18 October 2006
 * copyleft 2006 Tod E. Kurt <tod@todbot.com>
 * http://todbot.com/
 * 
 * based on "serial_read_advanced" example
 */
int ledPin = 13;   // select the pin for the LED
int val = 0;       // variable to store the data from the serial port

void setup() {
  pinMode(ledPin,OUTPUT);    // declare the LED's pin as output
  Serial.begin(9600);        // connect to the serial port
}

void loop () {
  val = Serial.read();      // read the serial port
  // if the stored value is a single-digit number, blink the LED that number
  if (val > '0' && val <= '9' ) {
    val = val - '0';          // convert from character to number
    for (int i=0; i<val; i++) {
      digitalWrite(ledPin,HIGH);
      delay(150);
      digitalWrite(ledPin, LOW);
      delay(150);
    }
  }
}

Esta Clase (SerialStream) tiene más métodos como establecer los bits de parada, control de paridad, etc. Se puede ver en la documentación de la clase.

Más información

2 comentarios:

loja7389 dijo...

Hola que tal, me interesa usar esta librería, como la puedo instalar para Dev C++ de windows?

snatverk dijo...

Hola, libserial es una librería de POSIX por lo que no podrás ejecutarla en windows. Quizás en un emulador como cygwin (http://www.cygwin.com/) , pero lo desconozco

Publicar un comentario en la entrada