lunes, 18 de mayo de 2015

Video Juego de Ping Pong en Processing

Como Hacer Un Video Juego Básico Con Processing

En la presente publicación trata de aplicar varios de los conceptos que se aprenden en los cursos básicos de programación mediante un video juego tipo Ping Pong.

Ejemplo 1
Como desplazar una bola en pantalla y hacer que esta rebote.

Codigo Empleado En Ejemplo 1
int BolaX = 0;
int BolaY = 10;
int IncX = 1;
int IncY = 1;
int AnchoPantalla = 100;
int AltoPantalla = 100;
void setup() {
  size(AnchoPantalla, AltoPantalla);
  frameRate(10);
}
void draw() {
  background(255);
  ellipse(BolaX, BolaY, 10, 10);
  BolaX=BolaX+IncX;
  BolaY=BolaY+IncY;
  println("Posicion Bola X = "+BolaX);
  println("Posicion Bola Y = "+BolaY);
  if (BolaX<=0 || BolaX>=AnchoPantalla) {
    IncX=IncX*(-1);
  }
  if (BolaY<=0 || BolaY>=AltoPantalla) {
    IncY=IncY*(-1);
  }
}  

lunes, 11 de mayo de 2015

Comunicacion serial con Processing y Arduino


Lectura De Datos Seriales Desde Processing

Elaboración básica de un programa en Processing para leer datos enviados desde un microcontrolador, en este ejemplo Arduino.
En este ejemplo solo se hace lectura de datos tipo entero desde Processing.



Instrucciones Empleadas Para La Comunicación
import processing.serial.* : Importa la librería para la comunicación, esta librería ya esta incluida en processing.

Serial MiPuerto: Instancia o declara un objeto que se empleara para el manejo del puerto serial.

Serial.list() : Da un listado de los puertos seriales disponibles en el computador, sirve para determinar en que posición del listado esta el puerto que se empleara en la comunicación

new Serial(this, ListaPuertos[0], 9600): Inicializa el objeto puerto serial, en este ejemplo el puerto que esta en la posición 0 del listado a una velocidad de comunicación de 9600 baudios.

MiPuerto.read() : Instrucción para la lectura de datos enviados por el puerto serial, la lectura se hace del buffer o pila que almacena los datos enviados. El buffer o pila puede almacenar muchos datos que son leídos uno a uno.

MiPuerto.clear() : Limpia el buffer o pila que almacena los datos seriales recibidos, es útil para una lectura inmediata del dato enviado por el microcontrolado a costa de la perdida de datos.

Más informacion se puede consultar en:

Código en Processing

import processing.serial.*;
String ListaPuertos[];
Serial MiPuerto;
int DatoLeido;
float VoltajeLeido;
void setup() {
  println(Serial.list());
  ListaPuertos=Serial.list();
  println(ListaPuertos[0]);
  MiPuerto=new Serial(this, ListaPuertos[0], 9600);
  println(MiPuerto);
}
void draw() {
  DatoLeido=MiPuerto.read();
  println("Dato = "+DatoLeido);
  VoltajeLeido=(float(DatoLeido))*0.019607843;
  println("Voltaje = "+VoltajeLeido);
  MiPuerto.clear();
}
 

Envío de una cadena de caracteres desde Arduino

Processing tiene la clase String que permite hacer manejo de cadena de caracteres lo que facilita el envío y recepción de estas por medio del puerto serial.
En el siguiente ejemplo el envío de la cadena se hace desde la tarjeta Arduino y la recepción se hace en Processing.
La cadena ser recibe desde processing con la instrucción

CadenaRecibida = MiPuerto.readStringUntil('\n');
 
El metodo readStringUntil indica que se hace la lectura hasta que encontrar un salto de linea que se indica con  '\n'  en Arduino se emplea la instrucción
 
Serial.println("Hola Mundo");
 
Para enviar una cadena de caracteres con salto de linea

Código de Arduino

void setup(){
  Serial.begin(9600);
}
void loop(){
  Serial.println("Hola Mundo");
  delay(100);
} 

Código de Processing

import processing.serial.*;
String ListaPuertos[];

String CadenaRecibida;
Serial MiPuerto;
int DatoLeido;
void setup() {
  println(Serial.list());
  ListaPuertos=Serial.list();
  println(ListaPuertos[0]);
  MiPuerto=new Serial(this, ListaPuertos[0], 9600);
  println(MiPuerto);
}

void draw(){
  if ( myPort.available() > 0){
    CadenaRecibida = MiPuerto.readStringUntil('\n');
  } 
  println(CadenaRecibida);
}

Envío de un dato desde Processing a Arduino

En este caso se emplea la instrucción MiPuerto.write() para enviar una dato de byte que puede ser un valor entero o carácter.
En este ejemplo se envía el carácter '1' o su equivalente entero en ASCII que es 49 para encender un led de la tarjeta Arduino.

Código de Arduino

char Dato; 
void setup() {
   pinMode(13, OUTPUT);
   Serial.begin(9600);
 }
void loop() {
   if (Serial.available()){
     Dato = Serial.read();
   }
   if (val == '1') { 
     digitalWrite(ledPin, HIGH);
   } else {
     digitalWrite(ledPin, LOW);
   }
   delay(10);
}  
 

Código de Processing

import processing.serial.*;
String ListaPuertos[];

String CadenaRecibida;
Serial MiPuerto;
void setup() {
  println(Serial.list());
  ListaPuertos=Serial.list();
  println(ListaPuertos[0]);
  MiPuerto=new Serial(this, ListaPuertos[0], 9600);
  println(MiPuerto);
}

void draw() {
  if (mousePressed == true){                          
    myPort.write('1');
  }else {                           
    myPort.write('0');
  }   
}
 

Envío y recepción Processing a Arduino

En este caso se hace tanto envío como recepción de datos entre las dos plataformas.
Se hace el uso de la función establecerComunicacion para garantizar que se ha establecido la comunicación entre las dos plataformas. 

Código de Arduino

char Dato;
boolean EstableComunicacion; 
void setup() {
   pinMode(13, OUTPUT);
   Serial.begin(9600);
   establecerComunicacion();
   EstadoLed=false; 
   EstableComunicacion =false;
 }

void loop()
{
  if (Serial.available() > 0) { 
    Dato = Serial.read();
    if(val == '1'){
       ledState = !ledState; //Cambia de estado
       digitalWrite(13, ledState); 
    }
    delay(100);
  } else {
    Serial.println("Listo para recibir");
    delay(50);
   }
}
void establecerComunicacion() {
  while (Serial.available() <= 0) {
    Serial.println("A");//Envia el caracter A procurando establecer comunicacion 
    delay(300);
  }
} 

Código de Processing

import processing.serial.*;
String ListaPuertos[];

String CadenaRecibida;
Serial MiPuerto;

boolean EstableComunicacion = false; 
void setup() {
  println(Serial.list());
  ListaPuertos=Serial.list();
  println(ListaPuertos[0]);
  MiPuerto=new Serial(this, ListaPuertos[0], 9600);
  println(MiPuerto);

 MiPuerto.bufferUntil('\n');//Envia el evento hasta detectar un fin de linea
}
void draw() {
 //Nada de momento
}
void serialEvent( Serial myPort) {
  CadenaRecibida = myPort.readStringUntil('\n');
  if (CadenaRecibida != null) {//Verifica que la cadena no este vacia
    CadenaRecibida = trim(CadenaRecibida);//Elimina espacios y saltos de linea de cadena
    println(CadenaRecibida);//Muestra en la consola la cadena recibida
    if (EstableComunicacion == false) {//Si no se ha establecido por primera vez la comunicacion
      if (CadenaRecibida.equals("A")) {//Si la cadena recibida es la letra A
        MiPuerto.clear();//Limpia buffer
        EstableComunicacion = true;//Indica que se estableció comunicacion
        MiPuerto.write("A");//Envia el caracter A la la tarjeta Arduino
        println("Se estableció comunicacion");//Muestra en la consola que ya hay comunicacion
      }
    } else {//Ya hay comunicacion con la tarjeta
      println(CadenaRecibida);//Muestra en consola la cadena recibida
      if (mousePressed == true) {//Si el raton es presionado                           
        MiPuerto.write('1');//Envia el caracter 1        
        println("1");//Muestra en consola que se envio el 1
      }
      MiPuerto.write("A");//Envia el caracter A procurando establecer comunicacion
    }
  }
}