Communicating Wiring and your C++ program

by Andres Burbano, University of California Santa Barbara.

This tutorial shows how to read serial data from the Wiring hardware coding in C/C++ in UNIX based machines (OSX and Linux), the examples read data from a Wiring board where an ultrasonic ping sensor or a potentiometer is connected.

Equipment:

You will need the parallax ultrasonic ping (digital) or the potentiometer (analog). This hasn´t been tested on Windows.

 

Process:

Step 0. Plug the Wiring I/O board using a USB cable to your computer, connect the ultrasonic ping sensor and/or the variable resistor to the Wiring I/O board. The Ultrasonic ping goes to the digital pin one, and the potentiometer goes to the analog pin one. Step one: Program the Wiring I/O board with the Wiring language, the easiest way is to use the examples that are already published in the Learning section to read the data from the ping or the potentiometer (there are different).

Parallax ping reader example
Potentiometer example

Code for the Ultrasonic Ping Sensor / Parallax PING Sensor

Step 2. Identify in your computer the Serial port created when the Wiring i/o board is plugged. It is possible just checking the Tools / Serial Port menu before and after plugging the board to see identify the corresponding port, select the appropriate one from the list. It should be something like this: tty.usbserial-0000103D

Step 3. Start your routine in C/C++ including the following libraries:

#include <iostream> 
#include <fcntl.h> 
#include <termios.h> 


#define USB_SERIAL_PORT "/dev/tty.usbserial-0000103D" // (OSX Power Book) 
//#define USB_SERIAL_PORT  "/dev/cu.usbserial-3B1" // (OSX Mac Book) 
//#define USB_SERIAL_PORT "/dev/tty.usbserial-0000103D" // (Linux Ubuntu Mac Book) 
//#define USB_SERIAL_PORT "/dev/tty.usbserial-0000103D" 
    

Step 4. Create a function like this to read the data and parse information from the serial: For the Ultrasonic ping like this:

int port_fd; 
int init_serial_input (char * port) {   
  int fd = 0;   
  struct termios options;   

  fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);   
  if (fd == -1)     
    return fd;   
    fcntl(fd, F_SETFL, 0);    // clear all flags on descriptor, enable direct I/O   
    tcgetattr(fd, &options);   // read serial port options   
    // enable receiver, set 8 bit data, ignore control lines   
    options.c_cflag |= (CLOCAL | CREAD | CS8);    
    // disable parity generation and 2 stop bits   
    options.c_cflag &= ~(PARENB | CSTOPB);  
    // set the new port options   
    tcsetattr(fd, TCSANOW, &options);      
    return fd; 
}
    

Step 5. Transform the info that you receive from ASCII to another type, in this case to an integer

int read_serial_int (int fd) {     
  char ascii_int[8] = {0};     
  char c = NULL;     
  int i = 0;     

  read(fd, &c, 1);         
  //while (c != '\n')     
  while (c != ' ')  {         
    ascii_int[i++] = c;         
    read(fd, &c, 1);     
  }     
  return atoi(ascii_int); 
} 
    

NOTE: There is a small difference between the Potentiometer and the Ultrasonic Ping in the line : while (c != ' ') For ultrasonic ping is : while (c != '\n') For the potentiometer is: while (c != ' ')

Step 6. Then you can do operations to get your the specific values that you need, this is only an example:

void sound() {              
  data.val = read_serial_int(port_fd);                                     
  if (data.val >= 0 && data.val <= 8000)  {                          
    if (data.val > 2000)                              
      data.val2 = -((8000 - data.val) / 10000.0f);                          
    else                          
      data.val2 = (data.val) / 1000.0f;                                         
    data.val3 = (data.val) / 10000.0f;                          
    cout << data.val3 << endl;                      
  }                      
}                            
    

Step 7. Finally inside the main function must be the next code that actually initializes the serial input

port_fd = init_serial_input(USB_SERIAL_PORT);                 
// serial is checked              
if (port_fd == -1)  {                  
  cout << "Couldn't open USB port" << endl;              
}                       
    

Enjoy, and contribute!!! see the examples here:

Paradiso a basic 3D model in OpenGL of "Paradiso" structure as is described in the "Divina Commedia" by Dante Alighieri (The order of the Spheres of "Paradiso" is: Moon, Mercury, Venus, Sun, Mars, Jupiter, Saturn, Stars, Primum Mobile and Empyrean). Paradiso is also an attempt to explore the possibility to translate the experience to fly using a virtual scene and external input, because it works with an ultrasonic ping sensor that measures the differences in motion of the hand-harm distance of the user respect to the sensor. The sensor is not invasive so the user can interact only with his/her movement. Paradiso is a sketch for an interactive installation.

Square_Rot a sketch for an interactive real time performance tool (audio and video). The goal of the project is using C++ to integrate serial input and microphone input transforming elements in Opengl also generating a basic audio synthesys using PortAudio. Actualy its noise.

Special thanks to: amar, newman, shear and villegas